diff --git a/lib/amd/build/str.min.js b/lib/amd/build/str.min.js
index e66c6910581..45da245b37d 100644
--- a/lib/amd/build/str.min.js
+++ b/lib/amd/build/str.min.js
@@ -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.\n\n/**\n * Fetch and render language strings.\n * Hooks into the old M.str global - but can also fetch missing strings on the fly.\n *\n * @module core/str\n * @class str\n * @package core\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\n// Disable no-restriced-properties because M.str is expected here:\n/* eslint-disable no-restricted-properties */\ndefine(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage) {\n\n var promiseCache = [];\n\n return /** @alias module:core/str */ {\n // Public variables and functions.\n /**\n * Return a promise object that will be resolved into a string eventually (maybe immediately).\n *\n * @method get_string\n * @param {string} key The language string key\n * @param {string} component The language string component\n * @param {string} param The param for variable expansion in the string.\n * @param {string} lang The users language - if not passed it is deduced.\n * @return {Promise}\n */\n // eslint-disable-next-line camelcase\n get_string: function(key, component, param, lang) {\n var request = this.get_strings([{\n key: key,\n component: component,\n param: param,\n lang: lang\n }]);\n\n return request.then(function(results) {\n return results[0];\n });\n },\n\n /**\n * Make a batch request to load a set of strings\n *\n * @method get_strings\n * @param {Object[]} requests Array of { key: key, component: component, param: param, lang: lang };\n * See get_string for more info on these args.\n * @return {Promise}\n */\n // eslint-disable-next-line camelcase\n get_strings: function(requests) {\n\n var deferred = $.Deferred();\n var results = [];\n var i = 0;\n var missing = false;\n var request;\n\n // Try from local storage. If it's there - put it in M.str and resolve it.\n\n for (i = 0; i < requests.length; i++) {\n request = requests[i];\n if (typeof request.lang === \"undefined\") {\n request.lang = $('html').attr('lang').replace(/-/g, '_');\n }\n request.cacheKey = 'core_str/' + request.key + '/' + request.component + '/' + request.lang;\n if (typeof M.str[request.component] === \"undefined\" ||\n typeof M.str[request.component][request.key] === \"undefined\") {\n // Try and revive it from local storage.\n var cached = storage.get(request.cacheKey);\n if (cached) {\n if (typeof M.str[request.component] === \"undefined\") {\n M.str[request.component] = [];\n }\n M.str[request.component][request.key] = cached;\n } else {\n // It's really not here.\n missing = true;\n }\n }\n }\n\n if (!missing) {\n // We have all the strings already.\n for (i = 0; i < requests.length; i++) {\n request = requests[i];\n\n results[i] = M.util.get_string(request.key, request.component, request.param);\n }\n deferred.resolve(results);\n } else {\n var ajaxrequests = [];\n var fetchpromises = [];\n\n // Done handler for ajax call. Must be bound to the current fetchpromise. We do this\n // to avoid creating a function in a loop.\n var doneFunc = function(str) {\n this.resolve(str);\n };\n\n var failFunc = function(reason) {\n this.reject(reason);\n };\n\n for (i = 0; i < requests.length; i++) {\n request = requests[i];\n\n // If we ever fetched this string with a promise, reuse it.\n if (typeof promiseCache[request.cacheKey] !== 'undefined') {\n fetchpromises.push(promiseCache[request.cacheKey]);\n } else {\n // Add this to the list we need to really fetch.\n var fetchpromise = $.Deferred();\n\n ajaxrequests.push({\n methodname: 'core_get_string',\n args: {\n stringid: request.key,\n component: request.component,\n lang: request.lang,\n stringparams: []\n },\n done: doneFunc.bind(fetchpromise),\n fail: failFunc.bind(fetchpromise)\n });\n\n promiseCache[request.cacheKey] = fetchpromise.promise();\n fetchpromises.push(promiseCache[request.cacheKey]);\n }\n }\n\n // Everything might already be queued so we need to check if we have real ajax requests to run.\n if (ajaxrequests.length > 0) {\n ajax.call(ajaxrequests, true, false, false, 0, M.cfg.langrev);\n }\n\n $.when.apply(null, fetchpromises).done(\n function() {\n // Turn the list of arguments (unknown length) into a real array.\n var i = 0;\n for (i = 0; i < arguments.length; i++) {\n request = requests[i];\n // Cache all the string templates.\n if (typeof M.str[request.component] === \"undefined\") {\n M.str[request.component] = [];\n }\n M.str[request.component][request.key] = arguments[i];\n storage.set('core_str/' + request.key + '/' + request.component + '/' + request.lang, arguments[i]);\n // And set the results.\n results[i] = M.util.get_string(request.key, request.component, request.param).trim();\n }\n deferred.resolve(results);\n }\n ).fail(\n function(ex) {\n deferred.reject(ex);\n }\n );\n }\n\n return deferred.promise();\n },\n /**\n * Add a list of strings to the caches.\n *\n * @method cache_strings\n * @param {Object[]} strings Array of { key: key, component: component, lang: lang, value: value }\n */\n // eslint-disable-next-line camelcase\n cache_strings: function(strings) {\n var defaultLang = $('html').attr('lang').replace(/-/g, '_');\n strings.forEach(function(string) {\n var lang = !(lang in string) ? defaultLang : string.lang;\n var key = string.key;\n var component = string.component;\n var value = string.value;\n var cacheKey = ['core_str', key, component, lang].join('/');\n\n // Check M.str caching.\n if (!(component in M.str) || !(key in M.str[component])) {\n if (!(component in M.str)) {\n M.str[component] = {};\n }\n\n M.str[component][key] = value;\n }\n\n // Check local storage.\n if (!storage.get(cacheKey)) {\n storage.set(cacheKey, value);\n }\n\n // Check the promises cache.\n if (!(cacheKey in promiseCache)) {\n promiseCache[cacheKey] = $.Deferred().resolve(value).promise();\n }\n });\n }\n };\n});\n"],"file":"str.min.js"}
\ No newline at end of file
+{"version":3,"sources":["../src/str.js"],"names":["promiseCache","get_string","key","component","param","lang","get_strings","then","results","requests","requestData","pageLang","attr","replace","getCacheKey","stringPromises","map","request","cacheKey","buildReturn","promise","M","str","Promise","resolve","cached","LocalStorage","get","reject","push","methodname","args","stringid","stringparams","done","set","fail","length","Ajax","call","cfg","langrev","$","when","apply","strings","cache_strings","defaultLang","forEach","value","join","Deferred"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Fetch and render language strings.\n * Hooks into the old M.str global - but can also fetch missing strings on the fly.\n *\n * @module core/str\n * @class str\n * @package core\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\nimport $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport LocalStorage from 'core/localstorage';\n\n// Module cache for the promises so that we don't make multiple\n// unnecessary requests.\nlet promiseCache = [];\n\n/**\n * Return a promise object that will be resolved into a string eventually (maybe immediately).\n *\n * @method get_string\n * @param {string} key The language string key\n * @param {string} component The language string component\n * @param {string} param The param for variable expansion in the string.\n * @param {string} lang The users language - if not passed it is deduced.\n * @return {Promise}\n */\nexport const get_string = (key, component, param, lang) => {\n return get_strings([{key, component, param, lang}])\n .then(results => results[0]);\n};\n\n/**\n * Make a batch request to load a set of strings\n *\n * @method get_strings\n * @param {Object[]} requests Array of { key: key, component: component, param: param, lang: lang };\n * See get_string for more info on these args.\n * @return {Promise}\n */\nexport const get_strings = (requests) => {\n let requestData = [];\n const pageLang = $('html').attr('lang').replace(/-/g, '_');\n // Helper function to construct the cache key.\n const getCacheKey = ({key, component, lang = pageLang}) => `core_str/${key}/${component}/${lang}`;\n\n const stringPromises = requests.map((request) => {\n const cacheKey = getCacheKey(request);\n const {component, key, lang} = request;\n // Helper function to add the promise to cache.\n const buildReturn = (promise) => {\n // Make sure the promise cache contains our promise.\n promiseCache[cacheKey] = promise;\n return promise;\n };\n\n // Check if we can serve the string straight from M.str.\n if (component in M.str && key in M.str[component]) {\n return buildReturn(new Promise((resolve) => {\n resolve(M.str[component][key]);\n }));\n }\n\n // Check if the string is in the browser's local storage.\n const cached = LocalStorage.get(cacheKey);\n if (cached) {\n M.str[component] = {...M.str[component], [key]: cached};\n return buildReturn(new Promise((resolve) => {\n resolve(M.str[component][key]);\n }));\n }\n\n // Check if we've already loaded this string from the server.\n if (cacheKey in promiseCache) {\n return buildReturn(promiseCache[cacheKey]);\n } else {\n // We're going to have to ask the server for the string so\n // add this string to the list of requests to be sent.\n return buildReturn(new Promise((resolve, reject) => {\n requestData.push({\n methodname: 'core_get_string',\n args: {\n stringid: key,\n stringparams: [],\n component,\n lang,\n },\n done: (str) => {\n // When we get the response from the server\n // we should update M.str and the browser's\n // local storage before resolving this promise.\n M.str[component] = {...M.str[component], [key]: str};\n LocalStorage.set(cacheKey, str);\n resolve(str);\n },\n fail: reject\n });\n }));\n }\n });\n\n if (requestData.length) {\n // If we need to load any strings from the server then send\n // off the request.\n Ajax.call(requestData, true, false, false, 0, M.cfg.langrev);\n }\n\n // We need to use jQuery here because some calling code uses the\n // .done handler instead of the .then handler.\n return $.when.apply($, stringPromises)\n .then((...strings) => strings);\n};\n\n/**\n * Add a list of strings to the caches.\n *\n * @method cache_strings\n * @param {Object[]} strings Array of { key: key, component: component, lang: lang, value: value }\n */\nexport const cache_strings = (strings) => {\n const defaultLang = $('html').attr('lang').replace(/-/g, '_');\n\n strings.forEach(({key, component, value, lang = defaultLang}) => {\n const cacheKey = ['core_str', key, component, lang].join('/');\n\n // Check M.str caching.\n if (!(component in M.str) || !(key in M.str[component])) {\n if (!(component in M.str)) {\n M.str[component] = {};\n }\n\n M.str[component][key] = value;\n }\n\n // Check local storage.\n if (!LocalStorage.get(cacheKey)) {\n LocalStorage.set(cacheKey, value);\n }\n\n // Check the promises cache.\n if (!(cacheKey in promiseCache)) {\n promiseCache[cacheKey] = $.Deferred().resolve(value).promise();\n }\n });\n};\n"],"file":"str.min.js"}
\ No newline at end of file
diff --git a/lib/amd/src/str.js b/lib/amd/src/str.js
index 93ef0a18514..e0ce6eaab16 100644
--- a/lib/amd/src/str.js
+++ b/lib/amd/src/str.js
@@ -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();
+ }
+ });
+};