From 9b022bf2ff9f47278a65843bac316f1ae7dbfbcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Geelen=20=28sge=29?= Date: Thu, 14 Apr 2022 15:07:12 +0000 Subject: [PATCH] [FIX] web_editor : fix url transform & embed in paste * Avoid auto-transforming an valid url inside an existing tag. * Ensure the current selection range is deleted before embedding an image or video. task-2604627 closes odoo/odoo#89210 X-original-commit: 070bceeadd16e0b5643b91ad583449d31c48313d Signed-off-by: David Monjoie (dmo) --- .../static/lib/odoo-editor/src/OdooEditor.js | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js b/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js index bd7792d061b..61fec6bc220 100644 --- a/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js +++ b/addons/web_editor/static/lib/odoo-editor/src/OdooEditor.js @@ -2984,6 +2984,7 @@ export class OdooEditor extends EventTarget { */ _onPaste(ev) { ev.preventDefault(); + const sel = this.document.getSelection(); const files = getImageFiles(ev.clipboardData); const clipboardHtml = ev.clipboardData.getData('text/html'); if (files.length) { @@ -2994,15 +2995,18 @@ export class OdooEditor extends EventTarget { const text = ev.clipboardData.getData('text/plain'); const splitAroundUrl = text.split(URL_REGEX); const linkAttributes = this.options.defaultLinkAttributes || {}; + const selectionIsInsideALink = !!closestElement(sel.anchorNode, 'a'); for (let i = 0; i < splitAroundUrl.length; i++) { + const url = /^https?:\/\//gi.test(splitAroundUrl[i]) + ? splitAroundUrl[i] + : 'https://' + splitAroundUrl[i]; + const youtubeUrl = YOUTUBE_URL_GET_VIDEO_ID.exec(url); + const urlFileExtention = url.split('.').pop(); + const isImageUrl = ['jpg', 'jpeg', 'png', 'gif'].includes(urlFileExtention.toLowerCase()); // Even indexes will always be plain text, and odd indexes will always be URL. - if (i % 2) { - const url = /^https?:\/\//gi.test(splitAroundUrl[i]) - ? splitAroundUrl[i] - : 'https://' + splitAroundUrl[i]; - const youtubeUrl = YOUTUBE_URL_GET_VIDEO_ID.exec(url); - const urlFileExtention = url.split('.').pop(); + // only allow images emebed inside an existing link. No other url or video embed. + if (i % 2 && (isImageUrl || !selectionIsInsideALink)) { const baseEmbedCommand = [ { groupName: 'paste', @@ -3018,6 +3022,9 @@ export class OdooEditor extends EventTarget { } link.innerText = splitAroundUrl[i]; const sel = this.document.getSelection(); + if (!sel.isCollapsed) { + this.deleteRange(sel); + } if (sel.rangeCount) { sel.getRangeAt(0).insertNode(link); sel.collapseToEnd(); @@ -3043,7 +3050,7 @@ export class OdooEditor extends EventTarget { this.historyStep(true); }; - if (['jpg', 'jpeg', 'png', 'gif'].includes(urlFileExtention)) { + if (isImageUrl) { const stepIndexBeforeInsert = this._historySteps.length - 1; this.execCommand('insertText', splitAroundUrl[i]); this.commandBar.open({ @@ -3059,6 +3066,9 @@ export class OdooEditor extends EventTarget { const img = document.createElement('IMG'); img.setAttribute('src', url); const sel = this.document.getSelection(); + if (!sel.isCollapsed) { + this.deleteRange(sel); + } if (sel.rangeCount) { sel.getRangeAt(0).insertNode(img); sel.collapseToEnd(); @@ -3103,6 +3113,9 @@ export class OdooEditor extends EventTarget { execCommandAtStepIndex(stepIndexBeforeInsert, () => { const sel = this.document.getSelection(); + if (!sel.isCollapsed) { + this.deleteRange(sel); + } if (sel.rangeCount) { sel.getRangeAt(0).insertNode(videoElement); sel.collapseToEnd(); @@ -3120,6 +3133,9 @@ export class OdooEditor extends EventTarget { } link.innerText = splitAroundUrl[i]; const sel = this.document.getSelection(); + if (!sel.isCollapsed) { + this.deleteRange(sel); + } if (sel.rangeCount) { sel.getRangeAt(0).insertNode(link); sel.collapseToEnd();