From 672b8fa1c5078d8c7dc2020d3e7a6091d612ee6b Mon Sep 17 00:00:00 2001 From: Andreas Fernandez <a.fernandez@scripting-base.de> Date: Sun, 5 Apr 2020 08:11:28 +0200 Subject: [PATCH] [BUGFIX] Preserve selection ranges in RteLinkBrowser When the RteLinkBrowser is opened, any active ranges are now backed up and reused later when an element gets linked. This fixes clashes with the browser's internal search feature that overrides the `Selection` object. Resolves: #90952 Releases: master, 9.5 Change-Id: I155157e808370cd5ff05076a6c82f09da3b0cb3c Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64078 Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Josef Glatz <josefglatz@gmail.com> Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de> Reviewed-by: Josef Glatz <josefglatz@gmail.com> --- .../Resources/Public/TypeScript/RteLinkBrowser.ts | 6 ++++++ .../Resources/Public/JavaScript/RteLinkBrowser.js | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Build/Sources/TypeScript/rte_ckeditor/Resources/Public/TypeScript/RteLinkBrowser.ts b/Build/Sources/TypeScript/rte_ckeditor/Resources/Public/TypeScript/RteLinkBrowser.ts index 7b0a6c86b127..9781e99b6409 100644 --- a/Build/Sources/TypeScript/rte_ckeditor/Resources/Public/TypeScript/RteLinkBrowser.ts +++ b/Build/Sources/TypeScript/rte_ckeditor/Resources/Public/TypeScript/RteLinkBrowser.ts @@ -23,6 +23,7 @@ import Modal = require('TYPO3/CMS/Backend/Modal'); class RteLinkBrowser { protected plugin: any = null; protected CKEditor: CKEDITOR.editor = null; + protected ranges: CKEDITOR.dom.range[] = null; protected siteUrl: string = ''; /** @@ -47,6 +48,9 @@ class RteLinkBrowser { }); } + // Backup all ranges that are active when the Link Browser is requested + this.ranges = this.CKEditor.getSelection().getRanges(); + // siteUrl etc are added as data attributes to the body tag $.extend(RteLinkBrowser, $('body').data()); @@ -111,6 +115,7 @@ class RteLinkBrowser { linkElement.setAttribute('href', link); const selection = this.CKEditor.getSelection(); + selection.selectRanges(this.ranges); if (selection && selection.getSelectedText() === '') { selection.selectElement(selection.getStartElement()); } @@ -119,6 +124,7 @@ class RteLinkBrowser { } else { linkElement.setText(linkElement.getAttribute('href')); } + this.CKEditor.insertElement(linkElement); Modal.dismiss(); diff --git a/typo3/sysext/rte_ckeditor/Resources/Public/JavaScript/RteLinkBrowser.js b/typo3/sysext/rte_ckeditor/Resources/Public/JavaScript/RteLinkBrowser.js index e813f2cf1d2d..f99d12b48a2e 100644 --- a/typo3/sysext/rte_ckeditor/Resources/Public/JavaScript/RteLinkBrowser.js +++ b/typo3/sysext/rte_ckeditor/Resources/Public/JavaScript/RteLinkBrowser.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -define(["require","exports","jquery","TYPO3/CMS/Recordlist/LinkBrowser","TYPO3/CMS/Backend/Modal","ckeditor"],(function(t,e,i,n,s){"use strict";class l{constructor(){this.plugin=null,this.CKEditor=null,this.siteUrl=""}initialize(t){let e=s.currentModal.data("ckeditor");if(void 0!==e)this.CKEditor=e;else{let e;e=void 0!==top.TYPO3.Backend&&void 0!==top.TYPO3.Backend.ContentContainer.get()?top.TYPO3.Backend.ContentContainer.get():window.parent,i.each(e.CKEDITOR.instances,(e,i)=>{i.id===t&&(this.CKEditor=i)})}i.extend(l,i("body").data()),i(".t3js-class-selector").on("change",()=>{i("option:selected",this).data("linkTitle")&&i(".t3js-linkTitle").val(i("option:selected",this).data("linkTitle"))}),i(".t3js-removeCurrentLink").on("click",t=>{t.preventDefault(),this.CKEditor.execCommand("unlink"),s.dismiss()})}finalizeFunction(t){const e=this.CKEditor.document.createElement("a"),l=n.getLinkAttributeValues();let r=l.params?l.params:"";l.target&&e.setAttribute("target",l.target),l.class&&e.setAttribute("class",l.class),l.title&&e.setAttribute("title",l.title),delete l.title,delete l.class,delete l.target,delete l.params,i.each(l,(t,i)=>{e.setAttribute(t,i)});const a=t.match(/^([a-z0-9]+:\/\/[^:\/?#]+(?:\/?[^?#]*)?)(\??[^#]*)(#?.*)$/);if(a&&a.length>0){t=a[1]+a[2];const e=a[2].length>0?"&":"?";r.length>0&&("&"===r[0]&&(r=r.substr(1)),r.length>0&&(t+=e+r)),t+=a[3]}e.setAttribute("href",t);const o=this.CKEditor.getSelection();o&&""===o.getSelectedText()&&o.selectElement(o.getStartElement()),o&&o.getSelectedText()?e.setText(o.getSelectedText()):e.setText(e.getAttribute("href")),this.CKEditor.insertElement(e),s.dismiss()}}let r=new l;return n.finalizeFunction=t=>{r.finalizeFunction(t)},r})); \ No newline at end of file +define(["require","exports","jquery","TYPO3/CMS/Recordlist/LinkBrowser","TYPO3/CMS/Backend/Modal","ckeditor"],(function(t,e,i,n,s){"use strict";class l{constructor(){this.plugin=null,this.CKEditor=null,this.ranges=null,this.siteUrl=""}initialize(t){let e=s.currentModal.data("ckeditor");if(void 0!==e)this.CKEditor=e;else{let e;e=void 0!==top.TYPO3.Backend&&void 0!==top.TYPO3.Backend.ContentContainer.get()?top.TYPO3.Backend.ContentContainer.get():window.parent,i.each(e.CKEDITOR.instances,(e,i)=>{i.id===t&&(this.CKEditor=i)})}this.ranges=this.CKEditor.getSelection().getRanges(),i.extend(l,i("body").data()),i(".t3js-class-selector").on("change",()=>{i("option:selected",this).data("linkTitle")&&i(".t3js-linkTitle").val(i("option:selected",this).data("linkTitle"))}),i(".t3js-removeCurrentLink").on("click",t=>{t.preventDefault(),this.CKEditor.execCommand("unlink"),s.dismiss()})}finalizeFunction(t){const e=this.CKEditor.document.createElement("a"),l=n.getLinkAttributeValues();let r=l.params?l.params:"";l.target&&e.setAttribute("target",l.target),l.class&&e.setAttribute("class",l.class),l.title&&e.setAttribute("title",l.title),delete l.title,delete l.class,delete l.target,delete l.params,i.each(l,(t,i)=>{e.setAttribute(t,i)});const a=t.match(/^([a-z0-9]+:\/\/[^:\/?#]+(?:\/?[^?#]*)?)(\??[^#]*)(#?.*)$/);if(a&&a.length>0){t=a[1]+a[2];const e=a[2].length>0?"&":"?";r.length>0&&("&"===r[0]&&(r=r.substr(1)),r.length>0&&(t+=e+r)),t+=a[3]}e.setAttribute("href",t);const o=this.CKEditor.getSelection();o.selectRanges(this.ranges),o&&""===o.getSelectedText()&&o.selectElement(o.getStartElement()),o&&o.getSelectedText()?e.setText(o.getSelectedText()):e.setText(e.getAttribute("href")),this.CKEditor.insertElement(e),s.dismiss()}}let r=new l;return n.finalizeFunction=t=>{r.finalizeFunction(t)},r})); \ No newline at end of file -- GitLab