From 540dcc714acacc57bd3e971c758eb7d29941398d Mon Sep 17 00:00:00 2001
From: Jinjiu Liu <jili@odoo.com>
Date: Thu, 10 Aug 2023 10:12:00 +0200
Subject: [PATCH] [FIX] web_editor: link is added inside a br element in chrome

Reproduction:
1. Create a link right after some text
2. Remove the whole line by backspace character by character(this should
give the p element a history steps id)
3. Try to create a link again
4. The new link is invisible and actually created in br when inspecting
the page

Reason: this is an edge case on Chrome that the document.getSelection()
returns a selection which has br element as the anchorNode. It may
happen when the parent element of the br has history steps and only has
this br element. However, the same steps done on Firefox return the
correct selection on the parent element.

Fix: we make a special case when the selection is a caret type and the
anchorNode is a br element, we re-select the parent element and collapse
the selection to the start. This is trying to mimic the normal case of
adding a link to an empty p element, e.g selection anchorNode is p,
offset is 0.

task-3181486

closes odoo/odoo#131509

Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
---
 addons/web_editor/static/lib/odoo-editor/src/utils/utils.js | 4 ++++
 1 file changed, 4 insertions(+)

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 cb077eddf068..95ced4bd4d2b 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
@@ -641,6 +641,10 @@ export function getSelectedNodes(editable) {
  */
 export function getDeepRange(editable, { range, sel, splitText, select, correctTripleClick } = {}) {
     sel = sel || editable.ownerDocument.getSelection();
+    // if browser wrongly return br element as anchor node, replace by its parent
+    if (sel.isCollapsed && sel.anchorNode && sel.anchorNode.nodeName === "BR") {
+        setCursorStart(sel.anchorNode.parentElement, false);
+    }
     range = range ? range.cloneRange() : sel.rangeCount && sel.getRangeAt(0).cloneRange();
     if (!range) return;
     let start = range.startContainer;
-- 
GitLab