d66c164777fb439391b0d2c575d745c1fdca1923
[moodle.git] / lib / amd / src / str.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * Fetch and render language strings.
18  * Hooks into the old M.str global - but can also fetch missing strings on the fly.
19  *
20  * @module     core/str
21  * @class      str
22  * @package    core
23  * @copyright  2015 Damyon Wiese <damyon@moodle.com>
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  * @since      2.9
26  */
27 define(['jquery', 'core/ajax', 'core/localstorage'], function($, ajax, storage) {
30     return /** @alias module:core/str */ {
31         // Public variables and functions.
32         /**
33          * Return a promise object that will be resolved into a string eventually (maybe immediately).
34          *
35          * @method get_string
36          * @param {string} key The language string key
37          * @param {string} component The language string component
38          * @param {string} param The param for variable expansion in the string.
39          * @param {string} lang The users language - if not passed it is deduced.
40          * @return {Promise}
41          */
42         get_string: function(key, component, param, lang) {
43             var deferred = $.Deferred();
45             if (typeof M.str[component] !== "undefined" &&
46                     typeof M.str[component][key] !== "undefined") {
47                 deferred.resolve(M.util.get_string(key, component, param));
48                 return deferred.promise();
49             }
51             // Try from local storage. If it's there - put it in M.str and resolve it.
52             var cached = storage.get('core_str/' + key + '/' + component + '/' + lang);
53             if (cached) {
54                 if (typeof M.str[component] === "undefined") {
55                     M.str[component] = [];
56                 }
57                 M.str[component][key] = cached;
58                 deferred.resolve(M.util.get_string(key, component, param));
59                 return deferred.promise();
60             }
62             var request = this.get_strings([{
63                 key: key,
64                 component: component,
65                 param: param,
66                 lang: lang
67             }]);
69             request.done(function(results) {
70                 storage.set('core_str/' + key + '/' + component + '/' + lang, results[0]);
71                 deferred.resolve(results[0]);
72             }).fail(function(ex) {
73                 deferred.reject(ex);
74             });
76             return deferred.promise();
77         },
79         /**
80          * Make a batch request to load a set of strings
81          *
82          * @method get_strings
83          * @param {Object[]} requests Array of { key: key, component: component, param: param, lang: lang };
84          *                                      See get_string for more info on these args.
85          * @return {Promise}
86          */
87         get_strings: function(requests) {
89             var deferred = $.Deferred();
90             var results = [];
91             var i = 0;
92             var missing = false;
93             var request;
94             // Try from local storage. If it's there - put it in M.str and resolve it.
96             for (i = 0; i < requests.length; i++) {
97                 request = requests[i];
98                 if (typeof request.lang === "undefined") {
99                     request.lang = $('html').attr('lang');
100                 }
101                 if (typeof M.str[request.component] === "undefined" ||
102                         typeof M.str[request.component][request.key] === "undefined") {
103                     // Try and revive it from local storage.
104                     var cached = storage.get('core_str/' + request.key + '/' + request.component + '/' + request.lang);
105                     if (cached) {
106                         if (typeof M.str[request.component] === "undefined") {
107                             M.str[request.component] = [];
108                         }
109                         M.str[request.component][request.key] = cached;
110                     } else {
111                         // It's really not here.
112                         missing = true;
113                     }
114                 }
115             }
117             if (!missing) {
118                 // We have all the strings already.
119                 for (i = 0; i < requests.length; i++) {
120                     request = requests[i];
122                     results[i] = M.util.get_string(request.key, request.component, request.param);
123                 }
124                 deferred.resolve(results);
125             } else {
126                 // Something is missing, we might as well load them all.
127                 var ajaxrequests = [];
129                 for (i = 0; i < requests.length; i++) {
130                     request = requests[i];
132                     ajaxrequests.push({
133                         methodname: 'core_get_string',
134                         args: {
135                             stringid: request.key,
136                             component: request.component,
137                             lang: request.lang,
138                             stringparams: []
139                         }
140                     });
141                 }
143                 var deferreds = ajax.call(ajaxrequests);
144                 $.when.apply(null, deferreds).done(
145                     function() {
146                         // Turn the list of arguments (unknown length) into a real array.
147                         var i = 0;
148                         for (i = 0; i < arguments.length; i++) {
149                             request = requests[i];
150                             // Cache all the string templates.
151                             if (typeof M.str[request.component] === "undefined") {
152                                 M.str[request.component] = [];
153                             }
154                             M.str[request.component][request.key] = arguments[i];
155                             storage.set('core_str/' + request.key + '/' + request.component + '/' + request.lang, arguments[i]);
156                             // And set the results.
157                             results[i] = M.util.get_string(request.key, request.component, request.param).trim();
158                         }
159                         deferred.resolve(results);
160                     }
161                 ).fail(
162                     function(ex) {
163                         deferred.reject(ex);
164                     }
165                 );
166             }
168             return deferred.promise();
169         }
170     };
171 });