diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js index 3e421ad2d1e..b1549809023 100644 --- a/addons/web/static/src/js/core/ajax.js +++ b/addons/web/static/src/js/core/ajax.js @@ -2,6 +2,7 @@ odoo.define('web.ajax', function (require) { "use strict"; var config = require('web.config'); +var concurrency = require('web.concurrency'); var core = require('web.core'); var utils = require('web.utils'); var time = require('web.time'); @@ -10,6 +11,10 @@ var contentdisposition = require('web.contentdisposition'); var _t = core._t; +// Create the final object containing all the functions first to allow monkey +// patching them correctly if ever needed. +var ajax = {}; + function genericJsonRpc (fct_name, params, settings, fct) { var shadow = settings.shadow || false; delete settings.shadow; @@ -486,46 +491,81 @@ var loadAsset = (function () { })(); /** - * Loads the given js and css libraries. Note that the ajax loadJS and loadCSS methods - * don't do anything if the given file is already loaded. + * Loads the given js/css libraries and asset bundles. Note that no library or + * asset will be loaded if it was already done before. * * @param {Object} libs - * @Param {Array | Array} [libs.jsLibs=[]] The list of JS files that we want to - * load. The list may contain strings (the files to load), or lists of strings. The - * first level is loaded sequentially, and files listed in inner lists are loaded in - * parallel. - * @param {Array} [libs.cssLibs=[]] A list of css files, to be loaded in - * parallel - * @param {Array} [libs.assetLibs=[]] A list of xmlId. The loaded template - * contains the script and link to be loaded + * @param {Array} [libs.assetLibs=[]] + * The list of assets to load. Each list item may be a string (the xmlID + * of the asset to load) or a list of strings. The first level is loaded + * sequentially (so use this if the order matters) while the assets in + * inner lists are loaded in parallel (use this for efficiency but only + * if the order does not matter, should rarely be the case for assets). + * @param {string[]} [libs.cssLibs=[]] + * The list of CSS files to load. They will all be loaded in parallel but + * put in the DOM in the given order (only the order in the DOM is used + * to determine priority of CSS rules, not loaded time). + * @param {Array} [libs.jsLibs=[]] + * The list of JS files to load. Each list item may be a string (the URL + * of the file to load) or a list of strings. The first level is loaded + * sequentially (so use this if the order matters) while the files in inner + * lists are loaded in parallel (use this for efficiency but only + * if the order does not matter). + * @param {string[]} [libs.cssContents=[]] + * List of inline styles to add after loading the CSS files. + * @param {string[]} [libs.jsContents=[]] + * List of inline scripts to add after loading the JS files. * * @returns {Deferred} */ -function loadLibs (libs) { - var defs = []; - _.each(libs.jsLibs || [], function (urls) { - defs.push($.when.apply($, defs).then(function () { - if (typeof(urls) === 'string') { - return ajax.loadJS(urls); - } else { - return $.when.apply($, _.map(urls, function (url) { - return ajax.loadJS(url); +function loadLibs(libs) { + var mutex = new concurrency.Mutex(); + mutex.exec(function () { + var defs = []; + var cssLibs = [libs.cssLibs || []]; // Force loading in parallel + defs.push(_loadArray(cssLibs, ajax.loadCSS).then(function () { + if (libs.cssContents && libs.cssContents.length) { + $('head').append($('