From 2002c6a599a685f4a18fc670a9f7992c8d595c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Mon, 16 Nov 2020 12:36:47 +0000 Subject: [FIX] mail: fix race conditions, especially with scroll MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `_update` of some components must take place before the `_update` of other (usually sibling) components that might directly influence their layout. This is in particular the case for `_update` that are relying on height. Prevent force save of scroll position if there are pending hints to adjust it, and prevent pending hints from overriding new scroll value. Prevent flicker with message date. This should fix all known issues related to incorrectly saving or restoring scroll position. task-2344226 task-2358066 task-2369332 task-2372339 task-2373741 closes odoo/odoo#61054 Related: odoo/enterprise#14736 Signed-off-by: Alexandre Kühn (aku) --- addons/mail/static/src/bugfix/bugfix.js | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'addons/mail/static/src/bugfix/bugfix.js') diff --git a/addons/mail/static/src/bugfix/bugfix.js b/addons/mail/static/src/bugfix/bugfix.js index 5a7474b5c59..d4128a9b236 100644 --- a/addons/mail/static/src/bugfix/bugfix.js +++ b/addons/mail/static/src/bugfix/bugfix.js @@ -8,3 +8,69 @@ odoo.define('mail/static/src/bugfix/bugfix.js', function (require) { 'use strict'; }); + +// Should be moved to its own file in master. +odoo.define('mail/static/src/component_hooks/use_update/use_update.js', function (require) { +'use strict'; + +const { Component } = owl; +const { onMounted, onPatched } = owl.hooks; + +const executionQueue = []; + +function executeNextInQueue() { + if (executionQueue.length === 0) { + return; + } + const { component, func } = executionQueue.shift(); + if (!component.__owl__.isDestroyed) { + func(); + } + executeNextInQueue(); +} + +/** + * @param {Object} param0 + * @param {Component} param0.component + * @param {function} param0.func + * @param {integer} param0.priority + */ +async function addFunctionToQueue({ component, func, priority }) { + const index = executionQueue.findIndex(item => item.priority > priority); + const item = { component, func, priority }; + if (index === -1) { + executionQueue.push(item); + } else { + executionQueue.splice(index, 0, item); + } + // Timeout to allow all components to register their function before + // executing any of them, to respect all priorities. + await new Promise(resolve => setTimeout(resolve)); + executeNextInQueue(); +} + +/** + * This hook provides support for executing code after update (render or patch). + * + * @param {Object} param0 + * @param {function} param0.func the function to execute after the update. + * @param {integer} [param0.priority] determines the execution order of the function + * among the update function of other components. Lower priority is executed + * first. If no priority is given, the function is executed immediately. + */ +function useUpdate({ func, priority }) { + const component = Component.current; + onMounted(onUpdate); + onPatched(onUpdate); + function onUpdate() { + if (priority === undefined) { + func(); + return; + } + addFunctionToQueue({ component, func, priority }); + } +} + +return useUpdate; + +}); -- cgit v1.2.3