summaryrefslogtreecommitdiff
path: root/addons/website/static/src/js
diff options
context:
space:
mode:
authorBenoit Socias <bso@odoo.com>2021-01-28 13:17:22 +0000
committerqsm-odoo <qsm@odoo.com>2021-02-15 15:49:15 +0000
commitf2fa17540e130b5cf3f70570a3a97495cfbb7499 (patch)
tree0233ff281b396df6bbccaf62bef0d6df35331f1a /addons/website/static/src/js
parent768bcf58e8dc215b96b11bafa632c07dc683e297 (diff)
[FIX] website, web_editor: ensure the loader appears on click options
Before this commit the loader did not always get displayed when switching to the options tab. After this commit the loader always gets displayed ASAP when switching to the options tab until the tab is ready and displayed. task-2439295 https://github.com/odoo/odoo/pull/65223 Co-authored-by: Samuel Degueldre <sad@odoo.com>
Diffstat (limited to 'addons/website/static/src/js')
-rw-r--r--addons/website/static/src/js/editor/snippets.editor.js71
1 files changed, 45 insertions, 26 deletions
diff --git a/addons/website/static/src/js/editor/snippets.editor.js b/addons/website/static/src/js/editor/snippets.editor.js
index c5d64e11d54..77229934eac 100644
--- a/addons/website/static/src/js/editor/snippets.editor.js
+++ b/addons/website/static/src/js/editor/snippets.editor.js
@@ -154,37 +154,56 @@ weSnippetEditor.Class.include({
*/
async _onThemeTabClick(ev) {
// Note: nothing async here but start the loading effect asap
- this._execWithLoadingEffect(async () => new Promise(resolve => setTimeout(() => resolve(), 0)), false, 0);
+ let releaseLoader;
+ try {
+ const promise = new Promise(resolve => releaseLoader = resolve);
+ this._execWithLoadingEffect(() => promise, false, 0);
+ // loader is added to the DOM synchronously
+ await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
+ // ensure loader is rendered: first call asks for the (already done) DOM update,
+ // second call happens only after rendering the first "updates"
- if (!this.topFakeOptionEl) {
- let el;
- for (const [elementName, title] of this.optionsTabStructure) {
- const newEl = document.createElement(elementName);
- newEl.dataset.name = title;
- if (el) {
- el.appendChild(newEl);
- } else {
- this.topFakeOptionEl = newEl;
+ if (!this.topFakeOptionEl) {
+ let el;
+ for (const [elementName, title] of this.optionsTabStructure) {
+ const newEl = document.createElement(elementName);
+ newEl.dataset.name = title;
+ if (el) {
+ el.appendChild(newEl);
+ } else {
+ this.topFakeOptionEl = newEl;
+ }
+ el = newEl;
}
- el = newEl;
+ this.bottomFakeOptionEl = el;
+ this.el.appendChild(this.topFakeOptionEl);
}
- this.bottomFakeOptionEl = el;
- this.el.appendChild(this.topFakeOptionEl);
- }
- // Need all of this in that order so that:
- // - the element is visible and can be enabled and the onFocus method is
- // called each time.
- // - the element is hidden afterwards so it does not take space in the
- // DOM, same as the overlay which may make a scrollbar appear.
- this.topFakeOptionEl.classList.remove('d-none');
- const editor = await this._activateSnippet($(this.bottomFakeOptionEl));
- this.topFakeOptionEl.classList.add('d-none');
- editor.toggleOverlay(false);
+ // Need all of this in that order so that:
+ // - the element is visible and can be enabled and the onFocus method is
+ // called each time.
+ // - the element is hidden afterwards so it does not take space in the
+ // DOM, same as the overlay which may make a scrollbar appear.
+ this.topFakeOptionEl.classList.remove('d-none');
+ const editorPromise = this._activateSnippet($(this.bottomFakeOptionEl));
+ releaseLoader(); // because _activateSnippet uses the same mutex as the loader
+ releaseLoader = undefined;
+ const editor = await editorPromise;
+ this.topFakeOptionEl.classList.add('d-none');
+ editor.toggleOverlay(false);
- this._updateLeftPanelContent({
- tab: this.tabs.THEME,
- });
+ this._updateLeftPanelContent({
+ tab: this.tabs.THEME,
+ });
+ } catch (e) {
+ // Normally the loading effect is removed in case of error during the action but here
+ // the actual activity is happening outside of the action, the effect must therefore
+ // be cleared in case of error as well
+ if (releaseLoader) {
+ releaseLoader();
+ }
+ throw e;
+ }
},
});