[FIX] web_editor: delete forward invisible white spaces at start

Issue:
======
Invisible whitespaces at the start gets deleted by one by one with
delete forward.

Steps to reproduce the issue:
=============================
- Go to knowledge
- Add any text
- Make sure you have an empty line before it
- Change the html of the added text and add some spaces at the start
  (this is the easiest way to reproduce it)
- Go to the line before and keep deleting forward
- The invisible spaces will be deleted one by one.

Solution:
=========
When the selection is at the start of the node and it contains
whitespaces, `parentState` whill have undefined node when deleting
forward since we are at the first leaf. We need to keep deleting forward
with the text node instead of parentElement because calling delete
forward with the parent will do a 1 delete backward call from the
specified offset and it will not propagate forward anymore.

task-3629743

closes odoo/odoo#155435

X-original-commit: 6cfe30b1f194f7c53e8f91dde3251d7ba327ec56
Signed-off-by: Geelen Sébastien (sge) <sge@odoo.com>
Signed-off-by: Mahdi Cheikh Rouhou (macr) <macr@odoo.com>
This commit is contained in:
Mahdi Cheikh Rouhou (macr)
2024-02-27 08:07:49 +00:00
parent 179f3e225e
commit 4477af4041
2 changed files with 34 additions and 3 deletions
@@ -54,15 +54,21 @@ export function deleteText(charSize, offset, direction, alreadyMoved) {
restore();
// If the removed element was not visible content, propagate the deletion.
const parentState = getState(parentElement, firstSplitOffset, direction);
if (
isZWS ||
(isSpace &&
getState(parentElement, firstSplitOffset, direction).cType !== CTYPES.CONTENT)
(parentState.cType !== CTYPES.CONTENT || parentState.node === undefined))
) {
if(direction === DIRECTIONS.LEFT) {
if (direction === DIRECTIONS.LEFT) {
parentElement.oDeleteBackward(firstSplitOffset, alreadyMoved);
} else {
parentElement.oDeleteForward(firstSplitOffset, alreadyMoved);
if (isSpace && parentState.node == undefined) {
// multiple invisible space at the start of the node
this.oDeleteForward(offset, alreadyMoved);
} else {
parentElement.oDeleteForward(firstSplitOffset, alreadyMoved);
}
}
if (isZWS) {
fillEmpty(parentElement);
@@ -433,6 +433,31 @@ X[]
contentAfter: `<p>[]&nbsp;def</p>`,
});
});
it('should remove invisible empty space at the start', async () => {
await testEditor(BasicEditor, {
contentBefore: `<p>[] def</p>`,
stepFunction: async editor => {
await deleteForward(editor);
},
contentAfter: `<p>[]ef</p>`,
});
});
it('should remove invisible empty space at the start (2)', async () => {
await testEditor(BasicEditor, {
// The first 3 spaces are invisible : considered
// formating by the browser.
// The &nbsp; is visible (space 1).
// The last 3 spaces are consider as 1 visble space and
// two formating spaces (space 2).
contentBefore: `<p>[] &nbsp; def</p>`,
stepFunction: async editor => {
await deleteForward(editor);
},
// Space 1 is deleted and space 2 should be transformed
// to a &nbsp; to stay visible.
contentAfter: `<p>[]&nbsp;def</p>`,
});
});
});
describe('white spaces', () => {
describe('no intefering spaces', () => {