[FIX] web_editor : fix url transform & embed in paste

* Avoid auto-transforming an valid url inside an existing <a> 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) <dmo@odoo.com>
This commit is contained in:
Sébastien Geelen (sge)
2022-04-21 07:59:44 +02:00
parent a538919bad
commit 9b022bf2ff
@@ -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();