[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 <Zinston@users.noreply.github.com>
This commit is contained in:
Benoit Socias
2021-09-10 16:10:47 +00:00
parent b7502e6ce6
commit b5263be24c
2 changed files with 34 additions and 11 deletions
@@ -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;
@@ -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, () => {