From 2e35193b945079cdca0539e00743efcf443be8cf Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Fri, 24 Sep 2021 08:47:28 +0000 Subject: [PATCH] [FIX] web_editor: compute deepest position offset according to used node Before this commit when computing the deepest position for a non-visible node, if that node had no next visible sibling it used the previous siblings, but it still marked the offset within that sibling as 0. Because of this, the selection sometimes got lost. E.g. in Firefox, drop an "Image - Text" block and triple click on the header text: upon changing its color the range got set to the text node but ending at offset 0. After this commit if the used node in the "previous sibling" from the evaluated element, the offset is set to the length of that node. task-2655176 closes odoo/odoo#77567 X-original-commit: 3c4426c71ebe080bcbd285e271c61bf1580c3afa Signed-off-by: Antoine Guenet Signed-off-by: Benoit Socias (bso) --- .../static/lib/odoo-editor/src/utils/utils.js | 2 +- .../lib/odoo-editor/test/spec/utils.test.js | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/addons/web_editor/static/lib/odoo-editor/src/utils/utils.js b/addons/web_editor/static/lib/odoo-editor/src/utils/utils.js index dbefdc357c7..ab65506a1bb 100644 --- a/addons/web_editor/static/lib/odoo-editor/src/utils/utils.js +++ b/addons/web_editor/static/lib/odoo-editor/src/utils/utils.js @@ -752,7 +752,7 @@ export function getDeepestPosition(node, offset) { while (!isVisible(node) && (node.previousSibling || (!reversed && node.nextSibling))) { reversed = reversed || !node.nextSibling; node = reversed ? node.previousSibling : node.nextSibling; - offset = 0; + offset = reversed ? nodeSize(node) : 0; didMove = true; } return didMove && isVisible(node) ? getDeepestPosition(node, offset) : [node, offset]; diff --git a/addons/web_editor/static/lib/odoo-editor/test/spec/utils.test.js b/addons/web_editor/static/lib/odoo-editor/test/spec/utils.test.js index 370b90d5d24..0c4b7c594eb 100644 --- a/addons/web_editor/static/lib/odoo-editor/test/spec/utils.test.js +++ b/addons/web_editor/static/lib/odoo-editor/test/spec/utils.test.js @@ -1208,6 +1208,52 @@ describe('Utils', () => { .expect([anchorNode, anchorOffset, focusNode, focusOffset]) .to.eql([p1.firstChild, 0, p1.firstChild, 11]); }); + it('should limit the selection to the title text (nested)', () => { + const [p] = insertTestHtml( + `

+ + title + +

`, + ); + const span = p.childNodes[1]; + const whiteBeforeFont = span.childNodes[0]; + const title = span.childNodes[1].firstChild; + const whiteAfterFont = span.childNodes[2]; + const range = document.createRange(); + range.setStart(whiteBeforeFont, 0); + range.setEnd(whiteAfterFont, 10); + const result = getDeepRange(p.parentElement, { range, select: true }); + const { startContainer, startOffset, endContainer, endOffset } = result; + window.chai + .expect([startContainer, startOffset, endContainer, endOffset]) + .to.eql([title, 0, title, 5]); + const { anchorNode, anchorOffset, focusNode, focusOffset } = + document.getSelection(); + window.chai + .expect([anchorNode, anchorOffset, focusNode, focusOffset]) + .to.eql([title, 0, title, 5]); + }); + it('should not limit the selection to the title text within p siblings', () => { + const [p0, p1, p2] = insertTestHtml( + `


+ title +


`, + ); + const range = document.createRange(); + range.setStart(p0, 0); + range.setEnd(p2, 0); + const result = getDeepRange(p1.parentElement, { range, select: true }); + const { startContainer, startOffset, endContainer, endOffset } = result; + window.chai + .expect([startContainer, startOffset, endContainer, endOffset]) + .to.eql([p0, 0, p2, 0]); + const { anchorNode, anchorOffset, focusNode, focusOffset } = + document.getSelection(); + window.chai + .expect([anchorNode, anchorOffset, focusNode, focusOffset]) + .to.eql([p0, 0, p2, 0]); + }); }); describe('backward', () => { it('should select the contents of an element', () => {