MDL-62497 javascript: rewrite core/str using ES6 syntax

This commit is contained in:
Ryan Wyllie 2018-07-12 09:01:13 +08:00 committed by Andrew Nicols
parent 38d4f754ca
commit 6466e89946
3 changed files with 132 additions and 187 deletions

View File

@ -1,2 +1,2 @@
define ("core/str",["jquery","core/ajax","core/localstorage"],function(a,b,c){var d=[];return{get_string:function get_string(a,b,c,d){var e=this.get_strings([{key:a,component:b,param:c,lang:d}]);return e.then(function(a){return a[0]})},get_strings:function get_strings(e){var f=a.Deferred(),g=[],h=0,j=!1,k;for(h=0;h<e.length;h++){k=e[h];if("undefined"==typeof k.lang){k.lang=a("html").attr("lang").replace(/-/g,"_")}k.cacheKey="core_str/"+k.key+"/"+k.component+"/"+k.lang;if("undefined"==typeof M.str[k.component]||"undefined"==typeof M.str[k.component][k.key]){var l=c.get(k.cacheKey);if(l){if("undefined"==typeof M.str[k.component]){M.str[k.component]=[]}M.str[k.component][k.key]=l}else{j=!0}}}if(!j){for(h=0;h<e.length;h++){k=e[h];g[h]=M.util.get_string(k.key,k.component,k.param)}f.resolve(g)}else{var m=[],n=[],o=function(a){this.resolve(a)},p=function(a){this.reject(a)};for(h=0;h<e.length;h++){k=e[h];if("undefined"!=typeof d[k.cacheKey]){n.push(d[k.cacheKey])}else{var q=a.Deferred();m.push({methodname:"core_get_string",args:{stringid:k.key,component:k.component,lang:k.lang,stringparams:[]},done:o.bind(q),fail:p.bind(q)});d[k.cacheKey]=q.promise();n.push(d[k.cacheKey])}}if(0<m.length){b.call(m,!0,!1,!1,0,M.cfg.langrev)}a.when.apply(null,n).done(function(){var a=0;for(a=0;a<arguments.length;a++){k=e[a];if("undefined"==typeof M.str[k.component]){M.str[k.component]=[]}M.str[k.component][k.key]=arguments[a];c.set("core_str/"+k.key+"/"+k.component+"/"+k.lang,arguments[a]);g[a]=M.util.get_string(k.key,k.component,k.param).trim()}f.resolve(g)}).fail(function(a){f.reject(a)})}return f.promise()},cache_strings:function cache_strings(b){var e=a("html").attr("lang").replace(/-/g,"_");b.forEach(function(b){var f=!(f in b)?e:b.lang,g=b.key,h=b.component,i=b.value,j=["core_str",g,h,f].join("/");if(!(h in M.str)||!(g in M.str[h])){if(!(h in M.str)){M.str[h]={}}M.str[h][g]=i}if(!c.get(j)){c.set(j,i)}if(!(j in d)){d[j]=a.Deferred().resolve(i).promise()}})}}});
define ("core/str",["exports","jquery","core/ajax","core/localstorage"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.cache_strings=a.get_strings=a.get_string=void 0;b=e(b);c=e(c);d=e(d);function e(a){return a&&a.__esModule?a:{default:a}}function f(a){for(var b=1;b<arguments.length;b++){var c=null!=arguments[b]?arguments[b]:{},d=Object.keys(c);if("function"==typeof Object.getOwnPropertySymbols){d=d.concat(Object.getOwnPropertySymbols(c).filter(function(a){return Object.getOwnPropertyDescriptor(c,a).enumerable}))}d.forEach(function(b){g(a,b,c[b])})}return a}function g(a,b,c){if(b in a){Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0})}else{a[b]=c}return a}var h=[];a.get_string=function get_string(a,b,c,d){return i([{key:a,component:b,param:c,lang:d}]).then(function(a){return a[0]})};var i=function(a){var e=[],i=(0,b.default)("html").attr("lang").replace(/-/g,"_"),j=function(a){var b=a.key,c=a.component,d=a.lang,e=void 0===d?i:d;return"core_str/".concat(b,"/").concat(c,"/").concat(e)},k=a.map(function(a){var b=j(a),c=a.component,i=a.key,k=a.lang,l=function(a){h[b]=a;return a};if(c in M.str&&i in M.str[c]){return l(new Promise(function(a){a(M.str[c][i])}))}var m=d.default.get(b);if(m){M.str[c]=f({},M.str[c],g({},i,m));return l(new Promise(function(a){a(M.str[c][i])}))}if(b in h){return l(h[b])}else{return l(new Promise(function(a,h){e.push({methodname:"core_get_string",args:{stringid:i,stringparams:[],component:c,lang:k},done:function done(e){M.str[c]=f({},M.str[c],g({},i,e));d.default.set(b,e);a(e)},fail:h})}))}});if(e.length){c.default.call(e,!0,!1,!1,0,M.cfg.langrev)}return b.default.when.apply(b.default,k).then(function(){for(var a=arguments.length,b=Array(a),c=0;c<a;c++){b[c]=arguments[c]}return b})};a.get_strings=i;var j=function(a){var c=(0,b.default)("html").attr("lang").replace(/-/g,"_");a.forEach(function(a){var e=a.key,f=a.component,g=a.value,i=a.lang,j=void 0===i?c:i,k=["core_str",e,f,j].join("/");if(!(f in M.str)||!(e in M.str[f])){if(!(f in M.str)){M.str[f]={}}M.str[f][e]=g}if(!d.default.get(k)){d.default.set(k,g)}if(!(k in h)){h[k]=b.default.Deferred().resolve(g).promise()}})};a.cache_strings=j});
//# sourceMappingURL=str.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -24,194 +24,139 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 2.9
*/
// Disable no-restriced-properties because M.str is expected here:
/* eslint-disable no-restricted-properties */
define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage) {
import $ from 'jquery';
import Ajax from 'core/ajax';
import LocalStorage from 'core/localstorage';
var promiseCache = [];
// Module cache for the promises so that we don't make multiple
// unnecessary requests.
let promiseCache = [];
return /** @alias module:core/str */ {
// Public variables and functions.
/**
* Return a promise object that will be resolved into a string eventually (maybe immediately).
*
* @method get_string
* @param {string} key The language string key
* @param {string} component The language string component
* @param {string} param The param for variable expansion in the string.
* @param {string} lang The users language - if not passed it is deduced.
* @return {Promise}
*/
// eslint-disable-next-line camelcase
get_string: function(key, component, param, lang) {
var request = this.get_strings([{
key: key,
component: component,
param: param,
lang: lang
}]);
/**
* Return a promise object that will be resolved into a string eventually (maybe immediately).
*
* @method get_string
* @param {string} key The language string key
* @param {string} component The language string component
* @param {string} param The param for variable expansion in the string.
* @param {string} lang The users language - if not passed it is deduced.
* @return {Promise}
*/
export const get_string = (key, component, param, lang) => {
return get_strings([{key, component, param, lang}])
.then(results => results[0]);
};
return request.then(function(results) {
return results[0];
});
},
/**
* Make a batch request to load a set of strings
*
* @method get_strings
* @param {Object[]} requests Array of { key: key, component: component, param: param, lang: lang };
* See get_string for more info on these args.
* @return {Promise}
*/
export const get_strings = (requests) => {
let requestData = [];
const pageLang = $('html').attr('lang').replace(/-/g, '_');
// Helper function to construct the cache key.
const getCacheKey = ({key, component, lang = pageLang}) => `core_str/${key}/${component}/${lang}`;
/**
* Make a batch request to load a set of strings
*
* @method get_strings
* @param {Object[]} requests Array of { key: key, component: component, param: param, lang: lang };
* See get_string for more info on these args.
* @return {Promise}
*/
// eslint-disable-next-line camelcase
get_strings: function(requests) {
const stringPromises = requests.map((request) => {
const cacheKey = getCacheKey(request);
const {component, key, lang} = request;
// Helper function to add the promise to cache.
const buildReturn = (promise) => {
// Make sure the promise cache contains our promise.
promiseCache[cacheKey] = promise;
return promise;
};
var deferred = $.Deferred();
var results = [];
var i = 0;
var missing = false;
var request;
// Try from local storage. If it's there - put it in M.str and resolve it.
for (i = 0; i < requests.length; i++) {
request = requests[i];
if (typeof request.lang === "undefined") {
request.lang = $('html').attr('lang').replace(/-/g, '_');
}
request.cacheKey = 'core_str/' + request.key + '/' + request.component + '/' + request.lang;
if (typeof M.str[request.component] === "undefined" ||
typeof M.str[request.component][request.key] === "undefined") {
// Try and revive it from local storage.
var cached = storage.get(request.cacheKey);
if (cached) {
if (typeof M.str[request.component] === "undefined") {
M.str[request.component] = [];
}
M.str[request.component][request.key] = cached;
} else {
// It's really not here.
missing = true;
}
}
}
if (!missing) {
// We have all the strings already.
for (i = 0; i < requests.length; i++) {
request = requests[i];
results[i] = M.util.get_string(request.key, request.component, request.param);
}
deferred.resolve(results);
} else {
var ajaxrequests = [];
var fetchpromises = [];
// Done handler for ajax call. Must be bound to the current fetchpromise. We do this
// to avoid creating a function in a loop.
var doneFunc = function(str) {
this.resolve(str);
};
var failFunc = function(reason) {
this.reject(reason);
};
for (i = 0; i < requests.length; i++) {
request = requests[i];
// If we ever fetched this string with a promise, reuse it.
if (typeof promiseCache[request.cacheKey] !== 'undefined') {
fetchpromises.push(promiseCache[request.cacheKey]);
} else {
// Add this to the list we need to really fetch.
var fetchpromise = $.Deferred();
ajaxrequests.push({
methodname: 'core_get_string',
args: {
stringid: request.key,
component: request.component,
lang: request.lang,
stringparams: []
},
done: doneFunc.bind(fetchpromise),
fail: failFunc.bind(fetchpromise)
});
promiseCache[request.cacheKey] = fetchpromise.promise();
fetchpromises.push(promiseCache[request.cacheKey]);
}
}
// Everything might already be queued so we need to check if we have real ajax requests to run.
if (ajaxrequests.length > 0) {
ajax.call(ajaxrequests, true, false, false, 0, M.cfg.langrev);
}
$.when.apply(null, fetchpromises).done(
function() {
// Turn the list of arguments (unknown length) into a real array.
var i = 0;
for (i = 0; i < arguments.length; i++) {
request = requests[i];
// Cache all the string templates.
if (typeof M.str[request.component] === "undefined") {
M.str[request.component] = [];
}
M.str[request.component][request.key] = arguments[i];
storage.set('core_str/' + request.key + '/' + request.component + '/' + request.lang, arguments[i]);
// And set the results.
results[i] = M.util.get_string(request.key, request.component, request.param).trim();
}
deferred.resolve(results);
}
).fail(
function(ex) {
deferred.reject(ex);
}
);
}
return deferred.promise();
},
/**
* Add a list of strings to the caches.
*
* @method cache_strings
* @param {Object[]} strings Array of { key: key, component: component, lang: lang, value: value }
*/
// eslint-disable-next-line camelcase
cache_strings: function(strings) {
var defaultLang = $('html').attr('lang').replace(/-/g, '_');
strings.forEach(function(string) {
var lang = !(lang in string) ? defaultLang : string.lang;
var key = string.key;
var component = string.component;
var value = string.value;
var cacheKey = ['core_str', key, component, lang].join('/');
// Check M.str caching.
if (!(component in M.str) || !(key in M.str[component])) {
if (!(component in M.str)) {
M.str[component] = {};
}
M.str[component][key] = value;
}
// Check local storage.
if (!storage.get(cacheKey)) {
storage.set(cacheKey, value);
}
// Check the promises cache.
if (!(cacheKey in promiseCache)) {
promiseCache[cacheKey] = $.Deferred().resolve(value).promise();
}
});
// Check if we can serve the string straight from M.str.
if (component in M.str && key in M.str[component]) {
return buildReturn(new Promise((resolve) => {
resolve(M.str[component][key]);
}));
}
};
});
// Check if the string is in the browser's local storage.
const cached = LocalStorage.get(cacheKey);
if (cached) {
M.str[component] = {...M.str[component], [key]: cached};
return buildReturn(new Promise((resolve) => {
resolve(M.str[component][key]);
}));
}
// Check if we've already loaded this string from the server.
if (cacheKey in promiseCache) {
return buildReturn(promiseCache[cacheKey]);
} else {
// We're going to have to ask the server for the string so
// add this string to the list of requests to be sent.
return buildReturn(new Promise((resolve, reject) => {
requestData.push({
methodname: 'core_get_string',
args: {
stringid: key,
stringparams: [],
component,
lang,
},
done: (str) => {
// When we get the response from the server
// we should update M.str and the browser's
// local storage before resolving this promise.
M.str[component] = {...M.str[component], [key]: str};
LocalStorage.set(cacheKey, str);
resolve(str);
},
fail: reject
});
}));
}
});
if (requestData.length) {
// If we need to load any strings from the server then send
// off the request.
Ajax.call(requestData, true, false, false, 0, M.cfg.langrev);
}
// We need to use jQuery here because some calling code uses the
// .done handler instead of the .then handler.
return $.when.apply($, stringPromises)
.then((...strings) => strings);
};
/**
* Add a list of strings to the caches.
*
* @method cache_strings
* @param {Object[]} strings Array of { key: key, component: component, lang: lang, value: value }
*/
export const cache_strings = (strings) => {
const defaultLang = $('html').attr('lang').replace(/-/g, '_');
strings.forEach(({key, component, value, lang = defaultLang}) => {
const cacheKey = ['core_str', key, component, lang].join('/');
// Check M.str caching.
if (!(component in M.str) || !(key in M.str[component])) {
if (!(component in M.str)) {
M.str[component] = {};
}
M.str[component][key] = value;
}
// Check local storage.
if (!LocalStorage.get(cacheKey)) {
LocalStorage.set(cacheKey, value);
}
// Check the promises cache.
if (!(cacheKey in promiseCache)) {
promiseCache[cacheKey] = $.Deferred().resolve(value).promise();
}
});
};