[FIX] web_editor: should preserve first element inside banner.
Before this commit: - Performing ctrl+a and backspace inside a banner would unintentionally remove its first element, which could be a block tag After this commit: - Now performing ctrl+a and backspace inside the banner will no longer remove its first element if it's a block tag. task-3432167 X-original-commit: ddc8587f8a712fdddaa714bee2931cb149c03a38 Part-of: odoo/odoo#151735
This commit is contained in:
@@ -4204,13 +4204,20 @@ export class OdooEditor extends EventTarget {
|
||||
// and the toolbar so we need to fix the selection to be based on the
|
||||
// editable children. Calling `getDeepRange` ensure the selection is
|
||||
// limited to the editable.
|
||||
const containerSelector = '#wrap>*, .oe_structure>*, [contenteditable]';
|
||||
const container =
|
||||
(selection &&
|
||||
closestElement(selection.anchorNode, containerSelector)) ||
|
||||
// In case a suitable container could not be found then the
|
||||
// selection is restricted inside the editable area.
|
||||
this.editable;
|
||||
if (
|
||||
selection.anchorNode === this.editable &&
|
||||
selection.focusNode === this.editable &&
|
||||
selection.anchorNode === container &&
|
||||
selection.focusNode === container &&
|
||||
selection.anchorOffset === 0 &&
|
||||
selection.focusOffset === [...this.editable.childNodes].length
|
||||
selection.focusOffset === [...container.childNodes].length
|
||||
) {
|
||||
getDeepRange(this.editable, {select: true});
|
||||
getDeepRange(container, {select: true});
|
||||
// The selection is changed in `getDeepRange` and will therefore
|
||||
// re-trigger the _onSelectionChange.
|
||||
return;
|
||||
|
||||
@@ -866,7 +866,7 @@ export function getDeepestPosition(node, offset) {
|
||||
// First switch direction to left if offset is at the end.
|
||||
direction = offset < node.childNodes.length;
|
||||
next = node.childNodes[direction ? offset : offset - 1];
|
||||
} else if (direction && next.nextSibling && !isBlock(next.nextSibling)) {
|
||||
} else if (direction && next.nextSibling) {
|
||||
// Invalid node: skip to next sibling (without crossing blocks).
|
||||
next = next.nextSibling;
|
||||
} else {
|
||||
|
||||
@@ -100,5 +100,32 @@ QUnit.module(
|
||||
</div><p><br></p>`,
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.module("banner selection and backspace");
|
||||
QUnit.test("preserves the first paragraph tag inside the banner", async function (assert) {
|
||||
const { editor, editable } = onMount();
|
||||
const node = editable.querySelector("p");
|
||||
setSelection(node, 0);
|
||||
insertText(editor, "Test");
|
||||
setSelection(node.firstChild, 3, node.firstChild, 3);
|
||||
insertText(editor, '/banner');
|
||||
triggerEvent(editor.editable, "keydown", { key: "Enter" });
|
||||
await nextTick();
|
||||
insertText(editor, 'Test1');
|
||||
triggerEvent(editor.editable, "input", { inputType: "insertParagraph" });
|
||||
insertText(editor, 'Test2');
|
||||
triggerEvent(editor.editable, "input", { inputType: "insertParagraph" });
|
||||
triggerEvent(editor.editable, "keydown", { key: "a", ctrlKey: true });
|
||||
await nextTick();
|
||||
triggerEvent(editor.editable, "input", { inputType: "deleteContentBackward" });
|
||||
assert.strictEqual(
|
||||
editable.innerHTML,
|
||||
`<p>Test</p><div class="o_editor_banner o_not_editable lh-1 d-flex align-items-center alert alert-info pb-0 pt-3" role="status" data-oe-protected="true" contenteditable="false">
|
||||
<i class="fs-4 fa fa-info-circle mb-3" aria-label="Banner Info"></i>
|
||||
<div class="w-100 ms-3" data-oe-protected="false" contenteditable="true">
|
||||
<p placeholder=\"Type "/" for commands\" class=\"oe-hint oe-command-temporary-hint\"><br></p></div></div><p><br></p>`,
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user