From dd19bcef84464de4d6fadc9033c240b01fd0100f Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Wed, 15 May 2019 11:21:23 +0000 Subject: [IMP] web: allow blocking DOMs section while all JS is not fully loaded Use the system in website_sale where a case where this is needed could be found. More cases can be found later during testing. Part of https://github.com/odoo/odoo/pull/32181 task-1961045 --- addons/web/static/src/js/public/lazyloader.js | 71 +++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) (limited to 'addons/web/static/src/js/public') diff --git a/addons/web/static/src/js/public/lazyloader.js b/addons/web/static/src/js/public/lazyloader.js index 7c873e1938d..4f8be8c2d65 100644 --- a/addons/web/static/src/js/public/lazyloader.js +++ b/addons/web/static/src/js/public/lazyloader.js @@ -1,6 +1,62 @@ odoo.define('web.public.lazyloader', function (require) { 'use strict'; +var blockEvents = ['submit', 'click']; +var blockFunction = function (ev) { + ev.preventDefault(); + ev.stopImmediatePropagation(); +}; + +var waitingLazy = false; + +/** + * Blocks the DOM sections which explicitely require the lazy loaded JS to be + * working (those sections should be marked with the 'o_wait_lazy_js' class). + * + * @see stopWaitingLazy + */ +function waitLazy() { + if (waitingLazy) { + return; + } + waitingLazy = true; + + document.querySelectorAll('.o_wait_lazy_js').forEach(function (element) { + blockEvents.forEach(function (evType) { + element.addEventListener(evType, blockFunction); + }); + }); +} +/** + * Unblocks the DOM sections blocked by @see waitLazy and removes the related + * 'o_wait_lazy_js' class from the whole DOM. + */ +function stopWaitingLazy() { + if (!waitingLazy) { + return; + } + waitingLazy = false; + + document.querySelectorAll('.o_wait_lazy_js').forEach(function (element) { + blockEvents.forEach(function (evType) { + element.removeEventListener(evType, blockFunction); + }); + element.classList.remove('o_wait_lazy_js'); + }); +} + +// Start waiting for lazy loading as soon as the DOM is available +if (document.readyState !== 'loading') { + waitLazy(); +} else { + document.addEventListener('DOMContentLoaded', function () { + waitLazy(); + }); +} + +// As soon as everything is fully loaded, start loading all the remaining JS +// and unblock the related DOM section when all of it have been loaded and +// executed var doResolve = null; var _allScriptsLoaded = new Promise(function (resolve) { if (doResolve) { @@ -8,12 +64,21 @@ var _allScriptsLoaded = new Promise(function (resolve) { } else { doResolve = resolve; } +}).then(function () { + stopWaitingLazy(); }); - -window.addEventListener('load', function () { +if (document.readyState === 'complete') { setTimeout(_loadScripts, 0); -}); +} else { + window.addEventListener('load', function () { + setTimeout(_loadScripts, 0); + }); +} +/** + * @param {DOMElement[]} scripts + * @param {integer} index + */ function _loadScripts(scripts, index) { if (scripts === undefined) { scripts = document.querySelectorAll('script[data-src]'); -- cgit v1.2.3