[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
This commit is contained in:
qsm-odoo
2019-06-04 07:57:20 +00:00
parent 02dab5dc88
commit dd19bcef84
4 changed files with 78 additions and 4 deletions
+68 -3
View File
@@ -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]');
@@ -0,0 +1,8 @@
// Disable buttons and links marked with the o_wait_lazy_js class or in a
// section which is marked with the o_wait_lazy_js class.
a[href], button, input[type="submit"], input[type="button"], .btn {
&.o_wait_lazy_js, .o_wait_lazy_js & {
pointer-events: none;
}
}
+1
View File
@@ -370,6 +370,7 @@
</t>
<t t-call="web._assets_bootstrap"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/lazyloader.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/navbar_mobile.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/notification.scss"/>
+1 -1
View File
@@ -85,7 +85,7 @@
<attribute name="data-display-image">true</attribute>
</xpath>
<xpath expr="//div[hasclass('input-group')]" position="replace">
<form t-attf-class="o_wsale_products_searchbar_form #{_classes}" t-att-action="action if action else '/shop'" method="get">
<form t-attf-class="o_wsale_products_searchbar_form o_wait_lazy_js #{_classes}" t-att-action="action if action else '/shop'" method="get">
<t>$0</t>
<input name="order" type="hidden" class="o_wsale_search_order_by" value=""/>
<t t-raw="0"/>