diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js index b6dbc25136d..08a75a216a0 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/OdooEditor.js @@ -405,6 +405,8 @@ export class OdooEditor extends EventTarget { }); }); // Create the table UI. + this._tableUiContainer = this.document.createElement('div'); + this._tableUiContainer.classList.add('o_table_ui_container'); const parser = new DOMParser(); for (const direction of ['row', 'column']) { // Create the containers and the menu toggler. @@ -468,8 +470,9 @@ export class OdooEditor extends EventTarget { this.addDomListener(uiMenu.querySelector('.o_reset_table_size'), 'click', () => this.execCommand('resetSize', this._tableUiTarget)); this[`_${direction}Ui`] = ui; - this.document.body.append(ui); + this._tableUiContainer.append(ui); this.addDomListener(ui.querySelector('.o_table_ui_menu_toggler'), 'click', this._onTableMenuTogglerClick); + this.editable.before(this._tableUiContainer); } // -------- @@ -674,6 +677,7 @@ export class OdooEditor extends EventTarget { this.addDomListener(this.document, 'keyup', this._onDocumentKeyup); this.addDomListener(this.document, 'mouseup', this._onDocumentMouseup); this.addDomListener(this.document, 'click', this._onDocumentClick); + this.addDomListener(this.document, 'scroll', this._onScroll, true); this.multiselectionRefresh = this.multiselectionRefresh.bind(this); this._resizeObserver = new ResizeObserver(this.multiselectionRefresh); @@ -907,10 +911,10 @@ export class OdooEditor extends EventTarget { this.options.onPostSanitize(target); } - addDomListener(element, eventName, callback) { + addDomListener(element, eventName, callback, useCapture) { const boundCallback = callback.bind(this); this._domListeners.push([element, eventName, boundCallback]); - element.addEventListener(eventName, boundCallback); + element.addEventListener(eventName, boundCallback, useCapture); } /** @@ -2905,16 +2909,11 @@ export class OdooEditor extends EventTarget { * @param {HTMLTableRowElement|HTMLTableCellElement} element */ _positionTableUi(element) { + const tableUiContainerRect = this._tableUiContainer.getBoundingClientRect(); const isRow = element.nodeName === 'TR'; const ui = isRow ? this._rowUi : this._columnUi; const elementRect = element.getBoundingClientRect(); - const tableRect = closestElement(element, 'table').getBoundingClientRect(); const wrappedUi = ui.firstElementChild; - const togglerRect = ui.querySelector('.o_table_ui_menu_toggler').getBoundingClientRect(); - const props = { - xy: {left: 'x', top: 'y'}, - size: {left: 'width', top: 'height'} - }; const table = getInSelection(this.document, 'table'); const resetTableSize = ui.querySelector('.o_reset_table_size'); if (table && !table.hasAttribute('style')) { @@ -2922,15 +2921,10 @@ export class OdooEditor extends EventTarget { } else { resetTableSize.classList.remove('d-none'); } - const side1 = isRow ? 'left' : 'top'; - ui.style[side1] = (isRow ? elementRect : tableRect)[props.xy[side1]] - togglerRect[props.size[side1]] + 'px'; - ui.style[props.size[side1]] = !isRow && togglerRect[props.size[side1]] + 'px'; + ui.style.left = elementRect.left - tableUiContainerRect.left - (isRow ? wrappedUi.clientWidth : 0) + 'px'; + ui.style.top = elementRect.top - tableUiContainerRect.top - (isRow ? 0 : wrappedUi.clientHeight) + 'px'; + wrappedUi.style[isRow ? 'height' : 'width'] = elementRect[isRow ? 'height' : 'width'] + 'px'; - const side2 = isRow ? 'top' : 'left'; - wrappedUi.style[props.size[side2]] = elementRect[props.size[side2]] + 'px'; - ui.style[side2] = tableRect[props.xy[side2]] + 'px'; - wrappedUi.style[side2] = elementRect[side2] - tableRect[side2] - 1 + 'px'; - ui.style[props.size[side2]] = tableRect[props.size[side2]] + 'px'; } // HISTORY @@ -4580,6 +4574,15 @@ export class OdooEditor extends EventTarget { } } + _onScroll(ev) { + if (this._rowUiTarget && !this._rowUi.classList.contains('o_open')) { + this._positionTableUi(this._rowUiTarget); + } + if (this._columnUiTarget && !this._columnUi.classList.contains('o_open')) { + this._positionTableUi(this._columnUiTarget); + } + } + _onDocumentKeydown(ev) { const canUndoRedo = !['INPUT', 'TEXTAREA'].includes(this.document.activeElement.tagName); diff --git a/addons/web_editor/static/src/js/editor/odoo-editor/src/style.scss b/addons/web_editor/static/src/js/editor/odoo-editor/src/style.scss index 0e0bc5b95dc..9cef14644c5 100644 --- a/addons/web_editor/static/src/js/editor/odoo-editor/src/style.scss +++ b/addons/web_editor/static/src/js/editor/odoo-editor/src/style.scss @@ -34,6 +34,12 @@ cursor: pointer !important; } } +.o_table_ui_container { + position: absolute; + visibility: hidden; + top: 0; + left: 0; +} .o_table_ui { background-color: transparent; position: absolute; @@ -46,6 +52,8 @@ } > div { position: absolute; + left: 0; + top: 0; } .o_table_ui_menu_toggler { cursor: pointer;