From 72051ad58af91922be21d01b36de9376b699cb75 Mon Sep 17 00:00:00 2001 From: Younn Olivier Date: Wed, 13 Jul 2022 15:20:53 +0000 Subject: [PATCH] [FIX] website: unblock iframe on not editable content Before this commit, following those steps: - Go to /hello.css - Create the page/file - View in page manager - Click on its row -> You're redirected to the file, with infinite loading This commit fixes this behaviour by unblocking the iframe: - on the OdooFrameContentLoaded event for frontend pages - on the load event for other pages To do that, the BlockIframe component is changed to handle process ids. Before this commit, the BlockIframe component would count the calls to block or unblock the iframe (and store it in an iframeLocks variable), so that multiple processes can block the iframe independently from each other. As an exemple, for two processes A and B, the iframe should remain blocked during those two processes, and released at the end: (A) blockIframe => (B) blockIframe => (B) unblockIframe => (A) unblockIframe. But that iframeLocks variable was fragile: a process that blocks the iframe should unblock it once, otherwise it would mess up the locks count. It was not appropriate for a process that could be ended with two events, for example loading the iframe. The first of the 'load' or 'OdooFrameContentLoaded' events should unblock it. To change that, a process can block the iframe with a processId. The first unblock call with the same processId will unblock the iframe, the other ones will be ignored. task-2687506 Part-of: odoo/odoo#95955 --- .../website_preview/website_preview.js | 26 ++++++++++++------- .../static/src/services/website_service.js | 8 +++--- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/addons/website/static/src/client_actions/website_preview/website_preview.js b/addons/website/static/src/client_actions/website_preview/website_preview.js index 1f84b1ea21c..8e1de64783b 100644 --- a/addons/website/static/src/client_actions/website_preview/website_preview.js +++ b/addons/website/static/src/client_actions/website_preview/website_preview.js @@ -18,7 +18,8 @@ class BlockIframe extends Component { blockIframe: false, showLoader: false, }); - this.iframeLocks = 0; + this.processes = []; + this.ANONYMOUS_PROCESS_ID = 'ANONYMOUS_PROCESS_ID'; this.websiteService.bus.addEventListener("BLOCK", this.block.bind(this)); this.websiteService.bus.addEventListener("UNBLOCK", this.unblock.bind(this)); } @@ -28,17 +29,18 @@ class BlockIframe extends Component { this.state.showLoader = true; }, event.detail.loaderDelay); } - if (this.iframeLocks === 0) { + if (!this.processes.length) { this.state.blockIframe = true; } - this.iframeLocks++; + this.processes.push(event.detail.processId || this.ANONYMOUS_PROCESS_ID); } - unblock() { - this.iframeLocks--; - if (this.iframeLocks < 0) { - this.iframeLocks = 0; + unblock(event) { + const processId = event.detail.processId || this.ANONYMOUS_PROCESS_ID; + const processIndex = this.processes.indexOf(processId); + if (processIndex > -1) { + this.processes.splice(processIndex, 1); } - if (this.iframeLocks === 0) { + if (this.processes.length === 0) { this.state.blockIframe = false; this.state.showLoader = false; } @@ -95,8 +97,12 @@ export class WebsitePreview extends Component { }, () => [this.props.action.context.params]); useEffect(() => { - this.websiteService.blockIframe(); - this.iframe.el.addEventListener('OdooFrameContentLoaded', () => this.websiteService.unblockIframe(), { once: true }); + this.websiteService.blockIframe(true, 0, 'load-iframe'); + this.iframe.el.addEventListener('load', () => this.websiteService.unblockIframe('load-iframe'), { once: true }); + // For a frontend page, it is better to use the + // OdooFrameContentLoaded event to unblock the iframe, as it is + // triggered faster than the load event. + this.iframe.el.addEventListener('OdooFrameContentLoaded', () => this.websiteService.unblockIframe('load-iframe'), { once: true }); }, () => []); } diff --git a/addons/website/static/src/services/website_service.js b/addons/website/static/src/services/website_service.js index 9430a8d1707..a5cc2290c10 100644 --- a/addons/website/static/src/services/website_service.js +++ b/addons/website/static/src/services/website_service.js @@ -192,11 +192,11 @@ export const websiteService = { } return Wysiwyg; }, - blockIframe(showLoader = true, loaderDelay = 0) { - bus.trigger('BLOCK', {showLoader, loaderDelay}); + blockIframe(showLoader = true, loaderDelay = 0, processId) { + bus.trigger('BLOCK', {showLoader, loaderDelay, processId}); }, - unblockIframe() { - bus.trigger('UNBLOCK'); + unblockIframe(processId) { + bus.trigger('UNBLOCK', { processId }); }, leaveEditMode() { // FIXME this does not care about if the page is dirty or not.