Initial commit

This commit is contained in:
zhongjin
2020-06-15 10:58:47 +08:00
commit 4f1dfe7564
8590 changed files with 1516878 additions and 0 deletions
@@ -0,0 +1,33 @@
module.exports = {
getAssetsVersion: function (version) {
const query = window.location.search.substring(1);
const vars = query.split('&');
let i = 0;
for (i; i < vars.length; i++) {
const pair = vars[i].split('=');
if (pair[0] === 'v') {
return pair[1];
}
}
return window.StaticConfig.assetVersion || window.CartoConfig.data.user_frontend_version || version;
},
getAssetsBaseUrl: function () {
const data = window.CartoConfig.data;
const dataAssetsHost = data.asset_host && data.asset_host + '/assets';
const assetsBaseUrl =
window.StaticConfig.assetsBaseUrl ||
dataAssetsHost ||
data.config.app_assets_base_url;
return assetsBaseUrl + '/';
},
getAssetsUrl: function (version) {
return this.getAssetsBaseUrl() + this.getAssetsVersion(version);
}
};
@@ -0,0 +1,44 @@
const queue = require('queue-async');
const _ = require('underscore');
/**
* Convenient object to do async batch processing, and don't continue until all items have successfully finished.
* In case of error it will fail immediately.
*
* Example usage:
* var batchProcess = require('../common/batch_process_items');
* batchProcess({
* items: [ ... ],
* done: function () {
* this.close();
* },
* fail: function (jqXHR, errorType, e) {
* this._errorMsg = 'Server response: '+ jqXHR.responseText;
* this.render();
* }
* });
*
* @param opts {Object}
* howManyInParallel: {Number}
* items: {Array} each item will be passed to processItem(item, ...
* processItem: {Function} given an item and a callback, should call callback() for success case, or callback(error) if something failed.
* fail: {Function}
* done: {Function} called if all items
*/
module.exports = function (opts) {
var q = queue(opts.howManyInParallel);
_.each(opts.items, function (item) {
q.defer(function (callback) {
opts.processItem(item, callback);
});
});
q.awaitAll(function (error/*, result1, ..., resultN */) {
// error and results contains outcome of the jqXHR requests above, see http://api.jquery.com/jQuery.ajax/#jqXHR
if (error) {
opts.fail(error);
} else {
opts.done();
}
});
};
@@ -0,0 +1,43 @@
/**
* Object representing human-readable version of a given number of bytes.
*
* (Extracted logic from an old dashboard view)
*
* @param bytes {Number}
* @returns {Object}
*/
const BytesToSize = function (bytes) {
if (!(this instanceof BytesToSize)) return new BytesToSize(bytes);
this.bytes = bytes;
if (bytes === 0) {
this.unit = 0;
} else {
this.unit = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
}
return this;
};
BytesToSize.prototype.size = function () {
return (this.bytes / Math.pow(1024, this.unit));
};
BytesToSize.prototype.UNIT_SUFFIXES = ['B', 'kB', 'MB', 'GB', 'TB'];
BytesToSize.prototype.suffix = function () {
return this.UNIT_SUFFIXES[this.unit];
};
BytesToSize.prototype.toString = function (decimals) {
let size = this.size();
if (decimals) {
// 1 decimal: 9.995 => 9.9
const round = Math.pow(10, decimals);
size = Math.floor(size * round) / round;
} else {
size = Math.floor(size);
}
return size + this.suffix();
};
module.exports = BytesToSize;
@@ -0,0 +1,77 @@
var _ = require('underscore');
/**
* Local storage wrapper
*
* - It should be used within 'cartodb' key, for example:
*
* var loc_sto = new cdb.common.LocalStorage();
* loc_sto.set({ 'dashboard.order': 'create_at' });
* loc_sto.get('dashboard.order');
*
*/
var LocalStorageWrapper = function (name) {
this.name = name || 'cartodb';
if (!localStorage.getItem(this.name) && this.isEnabled()) {
localStorage.setItem(this.name, '{}');
}
};
// Some browsers with private mode don't allow to use
// local storage
LocalStorageWrapper.prototype.isEnabled = function () {
try {
localStorage.setItem('checking', 'test');
localStorage.removeItem('checking');
return true;
} catch (e) {
return false;
}
};
LocalStorageWrapper.prototype.get = function (n) {
if (!this.isEnabled()) return false;
if (n === undefined) {
return JSON.parse(localStorage.getItem(this.name));
} else {
var data = JSON.parse(localStorage.getItem(this.name));
return data[n];
}
};
LocalStorageWrapper.prototype.search = function (searchTerm) {
if (!this.isEnabled()) return null;
var wholeArray = JSON.parse(localStorage.getItem(this.name));
for (var i in wholeArray) {
if (wholeArray[i][searchTerm]) {
return wholeArray[i][searchTerm];
}
}
return null;
};
LocalStorageWrapper.prototype.set = function (data) {
if (!this.isEnabled()) return null;
var d = _.extend(this.get(), data);
return localStorage.setItem(this.name, JSON.stringify(d));
};
LocalStorageWrapper.prototype.add = function (obj) {
return this.set(obj);
};
LocalStorageWrapper.prototype.remove = function (n) {
if (!this.isEnabled()) return null;
var d = _.omit(this.get(), n);
return localStorage.setItem(this.name, JSON.stringify(d));
};
LocalStorageWrapper.prototype.destroy = function () {
delete localStorage.removeItem(this.name);
};
module.exports = LocalStorageWrapper;
@@ -0,0 +1,47 @@
const $ = require('jquery');
const ConfirmPasswordModal = require('dashboard/components/password-confirmation/password-confirmation-view.js');
class PasswordValidatedForm {
static bindEventTo (formSelector, options) {
const form = $(formSelector);
const saveButton = form.find('.js-save');
saveButton.bind('click', event => {
event.preventDefault();
event.stopPropagation();
if (!options.passwordConfirmationNeeded) {
return options.onPasswordTyped ? options.onPasswordTyped() : this.addPasswordToForm(form);
}
this.showPasswordModal({
modalService: options.modals,
onPasswordTyped: options.onPasswordTyped || this.addPasswordToForm.bind(this, form)
});
});
}
static showPasswordModal (options) {
options.modalService.create(modalModel => {
return new ConfirmPasswordModal({
modalModel,
onPasswordTyped: options.onPasswordTyped,
updatePassword: options.updatePassword
});
});
}
static addPasswordToForm (form, password, options = {}) {
const passwordInput = document.createElement('input');
passwordInput.setAttribute('type', 'hidden');
passwordInput.setAttribute('name', 'password_confirmation');
passwordInput.setAttribute('value', password);
form.prepend(passwordInput);
if (!options.doNotSubmit) {
form.submit();
}
}
}
module.exports = PasswordValidatedForm;
@@ -0,0 +1,19 @@
const pluralize = function (singular, plural, count) {
if (arguments.length === 2) {
// Backward compability with prev usages, retrofit to the new params signature
// pluralize('foobar' , 3) // => foobars
return pluralize.call(this, arguments[0], arguments[0] + 's', arguments[1]);
}
return count === 1 ? singular : plural;
};
pluralize.prefixWithCount = function (singular, plural, count) {
return pluralize(
`1 ${singular}`, // e.g. 1 item
`${count} ${plural}`, // e.g. 123 items
count
);
};
module.exports = pluralize;
@@ -0,0 +1,31 @@
function getUserPathname (pathname) {
var usernameRegex = /^\/\u(?:ser)?\/([a-zA-Z0-9\-]+)/;
var matchData = usernameRegex.exec(pathname);
var userPathname = matchData && matchData[0];
var username = matchData && matchData[1]
? matchData[1]
: '';
return {
userPathname: userPathname,
username: username
};
}
module.exports = {
getBaseUrl: function (location) {
var locationObject = location || window.location;
var currentURLOrigin = locationObject.origin;
var urlData = getUserPathname(locationObject.pathname);
if (urlData.username) {
return currentURLOrigin + urlData.userPathname;
}
return currentURLOrigin;
},
needsToChangeBaseURL: function (baseURL, location) {
return baseURL !== this.getBaseUrl(location);
}
};
@@ -0,0 +1,10 @@
module.exports = function (response) {
const responseJSON = response && response.responseJSON;
let errors = responseJSON && responseJSON.message;
if (responseJSON && responseJSON.errors && responseJSON.errors.length) {
errors = responseJSON.errors.join('. ') + '. ';
}
return errors;
};
@@ -0,0 +1,17 @@
// This used to be on core-model
/**
* Listen for an event on another object and triggers on itself, with the same name or a new one
* @method retrigger
* @param ev {String} event who triggers the action
* @param obj {Object} object where the event happens
* @param obj {Object} [optional] name of the retriggered event
* @todo [xabel]: This method is repeated here and in the base view definition. There's should be a way to make it unique
*/
module.exports = function (ev, obj, retrigEvent) {
if (!retrigEvent) {
retrigEvent = ev;
}
obj.bind && obj.bind(ev, () => {
this.trigger(retrigEvent);
}, this);
};
@@ -0,0 +1,12 @@
/*
* Returns a (double) quoted table name if needed (if it contains a dash, for example).
* Coupled to backend lib/carto/table_utils.rb#safe_table_name_quoting.
* Duplicated at lib/assets/javascripts/builder/helpers/utils.js to make it available for older models.
*/
module.exports = function (table_name) {
if (table_name === undefined || table_name.indexOf('-') === -1 || table_name[0] === '"' || table_name[table_name.length - 1] === '"') {
return table_name;
} else {
return '"' + table_name + '"';
}
};
@@ -0,0 +1,43 @@
var $ = require('jquery');
var CoreView = require('backbone/core-view');
var checkAndBuildOpts = require('builder/helpers/required-opts');
var REQUIRED_OPTS = [
'el'
];
module.exports = CoreView.extend({
events: {
'click .js-foo': '_fooHandler'
},
initialize: function (opts) {
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
this._onWindowScroll = this._onWindowScroll.bind(this);
this._topBoundary = this.$el.offset().top;
this._initBinds();
},
_initBinds: function () {
this._bindScroll();
},
_onWindowScroll: function () {
this.$el.toggleClass('is-fixed', $(window).scrollTop() > this._topBoundary);
},
_unbindScroll: function () {
$(window).unbind('scroll', this._onWindowScroll);
},
_bindScroll: function () {
this._unbindScroll();
$(window).bind('scroll', this._onWindowScroll);
},
clean: function () {
this._unbindScroll();
}
});