summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/framework
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2016-11-23 17:11:16 +0100
committerqsm-odoo <qsm@odoo.com>2016-11-24 10:14:56 +0100
commit365f7e9212268c24dd5bb53ce6ea635fd11d0943 (patch)
tree4cbddbf27f663cd4583be0eb483a58c339216b18 /addons/web/static/src/js/framework
parent88912f810ffad57f9f0ac39e9690657c9ea1ba10 (diff)
[FIX] web: lazy loading the same file multiple times with loadJS
Before this commit, if the loadJS method was called two times with the same url, the associated script was effectively put in the DOM only one time. However, the second call returned deferred was immediatly resolved while the script (added by the first call) might not be fully loaded yet. Now, calling loadJS for a same url multiple times will always return the same deferred, resolved when the associated script is fully loaded.
Diffstat (limited to 'addons/web/static/src/js/framework')
-rw-r--r--addons/web/static/src/js/framework/ajax.js68
1 files changed, 44 insertions, 24 deletions
diff --git a/addons/web/static/src/js/framework/ajax.js b/addons/web/static/src/js/framework/ajax.js
index 09bcc40d918..dee6f4599b4 100644
--- a/addons/web/static/src/js/framework/ajax.js
+++ b/addons/web/static/src/js/framework/ajax.js
@@ -148,30 +148,50 @@ function loadCSS(url) {
}
}
-function loadJS(url) {
- var def = $.Deferred();
- if ($('script[src="' + url + '"]').length) {
- def.resolve();
- } else {
- var script = document.createElement('script');
- script.type = 'text/javascript';
- script.src = url;
- script.onload = script.onreadystatechange = function() {
- if ((script.readyState && script.readyState != "loaded" && script.readyState != "complete") || script.onload_done) {
- return;
- }
- script.onload_done = true;
- def.resolve(url);
- };
- script.onerror = function () {
- console.error("Error loading file", script.src);
- def.reject(url);
- };
- var head = document.head || document.getElementsByTagName('head')[0];
- head.appendChild(script);
- }
- return def;
-}
+var loadJS = (function () {
+ var urls = [];
+ var defs = [];
+
+ var load = function loadJS(url) {
+ // Check the DOM to see if a script with the specified url is already there
+ var alreadyRequired = ($('script[src="' + url + '"]').length > 0);
+
+ // If loadJS was already called with the same URL, it will have a registered deferred indicating if
+ // the script has been fully loaded. If not, the deferred has to be initialized. This is initialized
+ // as already resolved if the script was already there without the need of loadJS.
+ var index = _.indexOf(urls, url);
+ if (index < 0) {
+ urls.push(url);
+ index = defs.push(alreadyRequired ? $.when() : $.Deferred()) - 1;
+ }
+
+ // Get the script associated deferred and returns it after initializing the script if needed. The
+ // deferred is marked to be resolved on script load and rejected on script error.
+ var def = defs[index];
+ if (!alreadyRequired) {
+ var script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.src = url;
+ script.onload = script.onreadystatechange = function() {
+ if ((script.readyState && script.readyState !== "loaded" && script.readyState !== "complete") || script.onload_done) {
+ return;
+ }
+ script.onload_done = true;
+ def.resolve(url);
+ };
+ script.onerror = function () {
+ console.error("Error loading file", script.src);
+ def.reject(url);
+ };
+ var head = document.head || document.getElementsByTagName('head')[0];
+ head.appendChild(script);
+ }
+ return def;
+ };
+
+ return load;
+})();
+
/**
* Cooperative file download implementation, for ajaxy APIs.