From b5263be24c76c0e3c8afa75d55e17b49866f6d94 Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Thu, 9 Sep 2021 06:12:36 +0000 Subject: [PATCH] [FIX] web_editor: restore lost selection when updating color Before this commit if the text selection was lost while the color palette was used, the color selection was not applied on anything. After this commit if the text selection was lost, it is restored to the last selection known in history before applying (or previewing) the color selection. Also avoid to remember selections that are not part of the editable. task-2599771 closes odoo/odoo#76357 X-original-commit: 0e706d508d6e747cff566c33d34b794a321eef5c Signed-off-by: Antoine Guenet --- .../static/lib/odoo-editor/src/OdooEditor.js | 38 +++++++++++++------ .../static/src/js/wysiwyg/wysiwyg.js | 7 ++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js b/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js index bafef1486c5..aff0a3f1709 100644 --- a/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js +++ b/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js @@ -833,18 +833,23 @@ export class OdooEditor extends EventTarget { * Place the selection on the last known selection position from the history * steps. * + * @param {boolean} [limitToEditable=false] When true returns the latest selection that + * happened within the editable. * @returns {boolean} */ - historyResetLatestComputedSelection() { - if (this._latestComputedSelection && this._latestComputedSelection.anchorNode) { - const anchorNode = this.idFind(this._latestComputedSelection.anchorNode.oid); - const focusNode = this.idFind(this._latestComputedSelection.focusNode.oid) || anchorNode; + historyResetLatestComputedSelection(limitToEditable) { + const computedSelection = limitToEditable + ? this._latestComputedSelectionInEditable + : this._latestComputedSelection; + if (computedSelection && computedSelection.anchorNode) { + const anchorNode = this.idFind(computedSelection.anchorNode.oid); + const focusNode = this.idFind(computedSelection.focusNode.oid) || anchorNode; if (anchorNode) { setSelection( anchorNode, - this._latestComputedSelection.anchorOffset, + computedSelection.anchorOffset, focusNode, - this._latestComputedSelection.focusOffset, + computedSelection.focusOffset, ); } } @@ -1507,6 +1512,9 @@ export class OdooEditor extends EventTarget { focusNode: sel.focusNode, focusOffset: sel.focusOffset, }; + if (this._isSelectionInEditable(sel)) { + this._latestComputedSelectionInEditable = this._latestComputedSelection; + } return this._latestComputedSelection; } /** @@ -2188,11 +2196,7 @@ export class OdooEditor extends EventTarget { this._computeHistorySelection(); const selection = this.document.getSelection(); - const isSelectionInEditable = - !selection.isCollapsed && - this.editable.contains(selection.anchorNode) && - this.editable.contains(selection.focusNode); - this._updateToolbar(isSelectionInEditable); + this._updateToolbar(this._isSelectionInEditable(selection)); if (this._currentMouseState === 'mouseup') { this._fixFontAwesomeSelection(); @@ -2206,6 +2210,18 @@ export class OdooEditor extends EventTarget { } } + /** + * Returns true if the current selection is inside the editable. + * + * @private + * @param {Object} selection + * @returns {boolean} + */ + _isSelectionInEditable(selection) { + return !selection.isCollapsed && + this.editable.contains(selection.anchorNode) && + this.editable.contains(selection.focusNode); + } getCurrentCollaborativeSelection() { const selection = this._latestComputedSelection || this._computeHistorySelection(); if (!selection) return; diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index ebe2b979553..326d24ad1dc 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -1096,6 +1096,7 @@ const Wysiwyg = Widget.extend({ backgroundGradient = backgroundImage; } } + const hadNonCollapsedSelection = range && !selection.isCollapsed; colorpicker = new ColorPaletteWidget(this, { excluded: ['transparent_grayscale'], $editable: $(this.odooEditor.editable), // Our parent is the root widget, we can't retrieve the editable section from it... @@ -1103,10 +1104,16 @@ const Wysiwyg = Widget.extend({ withGradients: true, }); colorpicker.on('custom_color_picked color_picked', null, ev => { + if (hadNonCollapsedSelection) { + this.odooEditor.historyResetLatestComputedSelection(true); + } this._processAndApplyColor(eventName, ev.data.color); this.odooEditor.historyStep(); }); colorpicker.on('color_hover color_leave', null, ev => { + if (hadNonCollapsedSelection) { + this.odooEditor.historyResetLatestComputedSelection(true); + } this._processAndApplyColor(eventName, ev.data.color); }); colorpicker.on('enter_key_color_colorpicker', null, () => {