From c16fb0f3c11ff25884586926554e912aaa44025f Mon Sep 17 00:00:00 2001
From: Guy Sartorelli <36352093+GuySartorelli@users.noreply.github.com>
Date: Thu, 25 Jan 2024 15:46:26 +1300
Subject: [PATCH] ENH Refactor sslink slightly for easier maintenance (#1661)
---
client/dist/js/TinyMCE_sslink.js | 2 +-
client/src/legacy/TinyMCE_sslink.js | 39 +++++++++++++----------------
2 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/client/dist/js/TinyMCE_sslink.js b/client/dist/js/TinyMCE_sslink.js
index 2f6aac63e..c08260fb5 100644
--- a/client/dist/js/TinyMCE_sslink.js
+++ b/client/dist/js/TinyMCE_sslink.js
@@ -1 +1 @@
-!function(){"use strict";var t={265:function(t){t.exports=ShortcodeSerialiser},196:function(t){t.exports=TinyMCEActionRegistrar},754:function(t){t.exports=i18n},311:function(t){t.exports=jQuery}},e={};function n(i){var o=e[i];if(void 0!==o)return o.exports;var r=e[i]={exports:{}};return t[i](r,r.exports,n),r.exports}!function(){var t=r(n(196)),e=r(n(311)),i=n(265),o=r(n(754));function r(t){return t&&t.__esModule?t:{default:t}}const s={init(n){const i=navigator.platform.toUpperCase().includes("MAC")?"⌘":"Ctrl",r=o.default._t("Admin.INSERT_LINK","Insert link"),s=o.default.inject(o.default._t("Admin.INSERT_LINK_WITH_SHORTCUT","Insert link {shortcut}"),{shortcut:`[${i}+K]`});return n.addShortcut("Meta+k","Open link menu",(()=>{(0,e.default)(`[aria-label^="${r}"] > button`,n.container).first().click()})),n.ui.registry.addMenuButton("sslink",{icon:"link",tooltip:s,fetch:e=>e(t.default.getSortedActions("sslink",n.getParam("editorIdentifier"),!0).map((t=>Object.assign({},t,{onAction:()=>t.onAction(n)}))))}),n.on("preinit",(()=>{n.ui.registry.addNestedMenuItem("sslink",{icon:"link",text:r,getSubmenuItems:()=>t.default.getSortedActions("sslink",n.getParam("editorIdentifier"),!0).map((t=>Object.assign({},t,{onAction:()=>t.onAction(n)})))})})),n.ui.registry.addButton("sslink-edit",{text:o.default._t("Admin.EDIT_LINK","Edit link"),onAction:function(){const e=tinymce.activeEditor.selection.getNode().getAttribute("href");e&&n.execCommand(t.default.getEditorCommandFromUrl(e))}}),n.ui.registry.addButton("sslink-remove",{text:o.default._t("Admin.REMOVE_LINK","Remove link"),onAction:()=>this.handleRemoveLinkClick(n)}),n.ui.registry.addContextToolbar("sslink",{predicate:t=>n.dom.is(t,"a[href]"),position:"node",scope:"node",items:"sslink-edit sslink-remove"}),{getMetadata(){return{name:"Silverstripe Link",url:"https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield"}}}},handleRemoveLinkClick(t){const e=t.execCommand("unlink"),n=t.selection.getNode();return n&&void 0!==n.normalize&&n.normalize(),e}};e.default.entwine("ss",(t=>{t(".insert-link__dialog-wrapper").entwine({Element:null,Data:{},Bookmark:null,onunmatch(){this._clearModal()},_clearModal(){const t=this.getReactRoot();t&&(t.unmount(),this.setReactRoot(null))},open(){const t=this.getElement().getEditor().getInstance();this.setBookmark(t.selection.getBookmark(2,!0)),this.renderModal(!0)},close(){this.setData({}),this.renderModal(!1)},renderModal(){},checkNodeMatches(t,e){return t===e||1===e.children.length&&t===e.children[0]},linkCanWrapSelection(t,e){const n=t.getSelection()||"",i=e.getNode();if(n)return""!==n.trim();const o=document.createElement(i.nodeName);if(o.textContent="Check the outer HTML",o.outerHTML.includes("Check the outer HTML"))return!1;if(this.checkNodeMatches(i,e.getSel().focusNode)&&this.checkNodeMatches(i,e.getSel().anchorNode)){if(1===tinymce.activeEditor.dom.createFragment(`${i.outerHTML}`).childNodes.length)return!0}return!1},getRequireLinkText(){const t=this.getElement().getEditor(),e=t.getInstance().selection,n=this.linkCanWrapSelection(t,e);return"A"!==e.getNode().tagName&&!n},handleInsert(t){this.getElement().getEditor().getInstance().selection.moveToBookmark(this.getBookmark());const e=this.buildAttributes(t),n=(0,i.createHTMLSanitiser)()(t.Text);return this.insertLinkInEditor(e,n),this.close(),Promise.resolve()},buildAttributes(t){let{Anchor:e,Link:n,TargetBlank:i,Description:o}=t,r=e&&e.length?`#${e}`:"";r=r.replace(/^#+/,"#");return{href:`${n}${r}`,target:i?"_blank":"",title:o}},insertLinkInEditor(t,e){const n=this.getElement().getEditor();n.insertLink(t,null,e),n.addUndo(),n.repaint();const i=n.getInstance().selection;setTimeout((()=>i&&i.collapse()),0)},getOriginalAttributes(){const e=this.getElement().getEditor(),n=t(e.getSelectedNode()),i=(n.attr("href")||"").split("#");return{Link:i[0]||"",Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}}})})),tinymce.PluginManager.add("sslink",(t=>s.init(t)))}()}();
\ No newline at end of file
+!function(){"use strict";var t={265:function(t){t.exports=ShortcodeSerialiser},196:function(t){t.exports=TinyMCEActionRegistrar},754:function(t){t.exports=i18n},311:function(t){t.exports=jQuery}},e={};function n(i){var r=e[i];if(void 0!==r)return r.exports;var o=e[i]={exports:{}};return t[i](o,o.exports,n),o.exports}!function(){var t=o(n(196)),e=o(n(311)),i=n(265),r=o(n(754));function o(t){return t&&t.__esModule?t:{default:t}}const s={init(n){function i(){return t.default.getSortedActions("sslink",n.getParam("editorIdentifier"),!0).map((t=>Object.assign({},t,{onAction:()=>t.onAction(n)})))}const o=navigator.platform.toUpperCase().includes("MAC")?"⌘":"Ctrl",s=r.default._t("Admin.INSERT_LINK","Insert link"),l=r.default.inject(r.default._t("Admin.INSERT_LINK_WITH_SHORTCUT","Insert link {shortcut}"),{shortcut:`[${o}+K]`});return n.addShortcut("Meta+k","Open link menu",(()=>{(0,e.default)(`[aria-label^="${s}"] > button`,n.container).first().click()})),n.ui.registry.addMenuButton("sslink",{icon:"link",tooltip:l,fetch:t=>t(i())}),n.ui.registry.addNestedMenuItem("sslink",{icon:"link",text:s,getSubmenuItems:i}),n.ui.registry.addButton("sslink-edit",{text:r.default._t("Admin.EDIT_LINK","Edit link"),onAction:function(){const e=tinymce.activeEditor.selection.getNode().getAttribute("href");e&&n.execCommand(t.default.getEditorCommandFromUrl(e))}}),n.ui.registry.addButton("sslink-remove",{text:r.default._t("Admin.REMOVE_LINK","Remove link"),onAction:()=>this.handleRemoveLinkClick(n)}),n.ui.registry.addContextToolbar("sslink",{predicate:t=>n.dom.is(t,"a[href]"),position:"node",scope:"node",items:"sslink-edit sslink-remove"}),{getMetadata(){return{name:"Silverstripe Link",url:"https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/htmleditorfield"}}}},handleRemoveLinkClick(t){const e=t.execCommand("unlink"),n=t.selection.getNode();return n&&void 0!==n.normalize&&n.normalize(),e}};e.default.entwine("ss",(t=>{t(".insert-link__dialog-wrapper").entwine({Element:null,Data:{},Bookmark:null,onunmatch(){this._clearModal()},_clearModal(){const t=this.getReactRoot();t&&(t.unmount(),this.setReactRoot(null))},open(){const t=this.getElement().getEditor().getInstance();this.setBookmark(t.selection.getBookmark(2,!0)),this.renderModal(!0)},close(){this.setData({}),this.renderModal(!1)},renderModal(){},checkNodeMatches(t,e){return t===e||1===e.children.length&&t===e.children[0]},linkCanWrapSelection(t,e){const n=t.getSelection()||"",i=e.getNode();if(n)return""!==n.trim();const r=document.createElement(i.nodeName);if(r.textContent="Check the outer HTML",r.outerHTML.includes("Check the outer HTML"))return!1;if(this.checkNodeMatches(i,e.getSel().focusNode)&&this.checkNodeMatches(i,e.getSel().anchorNode)){if(1===tinymce.activeEditor.dom.createFragment(`${i.outerHTML}`).childNodes.length)return!0}return!1},getRequireLinkText(){const t=this.getElement().getEditor(),e=t.getInstance().selection,n=this.linkCanWrapSelection(t,e);return"A"!==e.getNode().tagName&&!n},handleInsert(t){this.getElement().getEditor().getInstance().selection.moveToBookmark(this.getBookmark());const e=this.buildAttributes(t),n=(0,i.createHTMLSanitiser)()(t.Text);return this.insertLinkInEditor(e,n),this.close(),Promise.resolve()},buildAttributes(t){let{Anchor:e,Link:n,TargetBlank:i,Description:r}=t,o=e&&e.length?`#${e}`:"";o=o.replace(/^#+/,"#");return{href:`${n}${o}`,target:i?"_blank":"",title:r}},insertLinkInEditor(t,e){const n=this.getElement().getEditor();n.insertLink(t,null,e),n.addUndo(),n.repaint();const i=n.getInstance().selection;setTimeout((()=>i&&i.collapse()),0)},getOriginalAttributes(){const e=this.getElement().getEditor(),n=t(e.getSelectedNode()),i=(n.attr("href")||"").split("#");return{Link:i[0]||"",Anchor:i[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}}})})),tinymce.PluginManager.add("sslink",(t=>s.init(t)))}()}();
\ No newline at end of file
diff --git a/client/src/legacy/TinyMCE_sslink.js b/client/src/legacy/TinyMCE_sslink.js
index c962c1d5c..374311cb0 100644
--- a/client/src/legacy/TinyMCE_sslink.js
+++ b/client/src/legacy/TinyMCE_sslink.js
@@ -11,6 +11,16 @@ const plugin = {
* @param {Object} editor
*/
init(editor) {
+ function getActions() {
+ // Fetch the actions whenever the fetch function is called.
+ return TinyMCEActionRegistrar.getSortedActions('sslink', editor.getParam('editorIdentifier'), true)
+ .map(action => Object.assign(
+ {},
+ action,
+ { onAction: () => action.onAction(editor) }
+ ));
+ }
+
const metaKey = navigator.platform.toUpperCase().includes('MAC') ? '⌘' : 'Ctrl';
const title = i18n._t('Admin.INSERT_LINK', 'Insert link');
const titleWithShortcut = i18n.inject(
@@ -33,33 +43,18 @@ const plugin = {
}
}
+ // Button in main toolbar
editor.ui.registry.addMenuButton('sslink', {
icon: 'link',
tooltip: titleWithShortcut,
- fetch: (callback) => callback(
- // Fetch the actions whenever the fetch function is called.
- TinyMCEActionRegistrar.getSortedActions('sslink', editor.getParam('editorIdentifier'), true)
- .map(action => Object.assign(
- {},
- action,
- { onAction: () => action.onAction(editor) }
- ))
- ),
+ fetch: (callback) => callback(getActions()),
});
- editor.on('preinit', () => {
- // Right click context menu item
- editor.ui.registry.addNestedMenuItem('sslink', {
- icon: 'link',
- text: title,
- getSubmenuItems: () => // Fetch the actions whenever the fetch function is called.
- TinyMCEActionRegistrar.getSortedActions('sslink', editor.getParam('editorIdentifier'), true)
- .map(action => Object.assign(
- {},
- action,
- { onAction: () => action.onAction(editor) }
- )),
- });
+ // Right click context menu item
+ editor.ui.registry.addNestedMenuItem('sslink', {
+ icon: 'link',
+ text: title,
+ getSubmenuItems: getActions,
});
// Context menu when a link is selected