diff options
| author | qsm-odoo <qsm@odoo.com> | 2016-11-23 17:11:16 +0100 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2016-11-24 10:14:56 +0100 |
| commit | 365f7e9212268c24dd5bb53ce6ea635fd11d0943 (patch) | |
| tree | 4cbddbf27f663cd4583be0eb483a58c339216b18 /addons/web/static/src/js/framework | |
| parent | 88912f810ffad57f9f0ac39e9690657c9ea1ba10 (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.js | 68 |
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. |
