[FIX] web_editor: prevent changing blocks on correct arrow nav near zws

If a block ends with a zero-width space, the mechanism that skips these
characters when using the arrow keys should not skip all the way to the
next block. This is because this mechanism happens before the browser
applies its own behavior for the arrow key so we want to let it skip to
the next block instead (or we'll end up navigating too far).

X-original-commit: acae237410e43e1cf97fc023568f49cc2e974db4
Part-of: odoo/odoo#116558
This commit is contained in:
Antoine Guenet
2023-03-25 02:46:58 +01:00
parent 3d89a2ff91
commit 68e09ca92d
2 changed files with 27 additions and 4 deletions
@@ -3607,13 +3607,18 @@ export class OdooEditor extends EventTarget {
// Move selection if next character is zero-width space
if (nextCharacter === '\u200B') {
focusOffset += 1;
while (focusNode && (!focusNode.textContent[focusOffset] || !closestElement(focusNode).isContentEditable)) {
focusNode = nextLeaf(focusNode);
let newFocusNode = focusNode;
while (newFocusNode && (!newFocusNode.textContent[focusOffset] || !closestElement(newFocusNode).isContentEditable)) {
newFocusNode = nextLeaf(newFocusNode);
focusOffset = 0;
}
const startContainer = ev.shiftKey ? selection.anchorNode : focusNode;
if (!focusOffset && closestBlock(focusNode) !== closestBlock(newFocusNode)) {
newFocusNode = focusNode; // Do not move selection to next block.
focusOffset = nodeSize(focusNode);
}
const startContainer = ev.shiftKey ? selection.anchorNode : newFocusNode;
const startOffset = ev.shiftKey ? selection.anchorOffset : focusOffset;
setSelection(startContainer, startOffset, focusNode, focusOffset);
setSelection(startContainer, startOffset, newFocusNode, focusOffset);
}
}
}
@@ -5478,6 +5478,24 @@ X[]
// Final state: '<p>ab<span>\u200B</span>c[]d</p>'
});
});
it('should move past a zws (collapsed at the end of a block)', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>ab[]<span>\u200B</span></p><p>cd</p>',
stepFunction: async editor => {
triggerEvent(editor.editable, 'keydown', { key: 'ArrowRight'});
},
contentAfter: '<p>ab<span>\u200B[]</span></p><p>cd</p>',
// Final state: '<p>ab<span>\u200B</span></p><p>[]cd</p>'
});
await testEditor(BasicEditor, {
contentBefore: '<p>ab<span>[]\u200B</span></p><p>cd</p>',
stepFunction: async editor => {
triggerEvent(editor.editable, 'keydown', { key: 'ArrowRight'});
},
contentAfter: '<p>ab<span>\u200B[]</span></p><p>cd</p>',
// Final state: '<p>ab<span>\u200B</span></p><p>[]cd</p>'
});
});
it('should select a zws', async () => {
await testEditor(BasicEditor, {
contentBefore: '<p>[ab]<span>\u200B</span>cd</p>',