diff --git a/client/dist/js/TinyMCE_sslink-anchor.js b/client/dist/js/TinyMCE_sslink-anchor.js index e19030319f..f01dfbc7b5 100644 --- a/client/dist/js/TinyMCE_sslink-anchor.js +++ b/client/dist/js/TinyMCE_sslink-anchor.js @@ -1 +1 @@ -!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s="./client/src/legacy/TinyMCE_sslink-anchor.js")}({"./client/src/legacy/TinyMCE_sslink-anchor.js":function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(2),o=r(i),a=n(9),c=r(a),l=n(1),s=r(l),d=n(5),u=r(d),p=n(4),f=n(6),A=n(0),E=r(A),_=n(8),C=r(_),h=n(7),g=n(3),R=n("./client/src/state/anchorSelector/AnchorSelectorActions.js");c.default.addAction("sslink",{text:o.default._t("CMS.LINKLABEL_ANCHOR","Anchor on a page"),onclick:function(e){return e.execCommand("sslinkanchor")},priority:60},editorIdentifier).addCommandWithUrlTest("sslinkanchor",/^\[sitetree_link.+]#[^#\]]+$/);var O={init:function(e){e.addCommand("sslinkanchor",function(){var t=(0,E.default)("#"+e.id).entwine("ss"),n=Number((0,E.default)("#Form_EditForm_ID").val()||0),r=e.$("[id],[name]",e.getBody()).toArray().map(function(e){return e.id||e.name});ss.store.dispatch((0,R.updatedCurrentField)(n,r,e.id)),t.openLinkAnchorDialog()})}},m="insert-link__dialog-wrapper--anchor",T=(0,g.provideInjector)((0,h.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorAnchorLink"));E.default.entwine("ss",function(e){e("textarea.htmleditor").entwine({openLinkAnchorDialog:function(){var t=e("#"+m);t.length||(t=e('
'),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e("#"+m).entwine({renderModal:function(t){var n=this,r=ss.store,i=ss.apolloClient,a=function(){return n.close()},c=function(){return n.handleInsert.apply(n,arguments)},l=this.getOriginalAttributes(),d=tinymce.activeEditor.selection,A=d.getContent()||"",E=d.getNode().tagName,_="A"!==E&&""===A.trim(),C=Number(e("#Form_EditForm_ID").val()||0);u.default.render(s.default.createElement(p.ApolloProvider,{client:i},s.default.createElement(f.Provider,{store:r},s.default.createElement(T,{isOpen:t,onInsert:c,onClosed:a,title:o.default._t("CMS.LINK_ANCHOR","Link to an anchor on a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--anchor",fileAttributes:l,identifier:"Admin.InsertLinkAnchorModal",requireLinkText:_,currentPageID:C}))),this[0])},buildAttributes:function(e){return{href:C.default.serialise({name:"sitetree_link",properties:{id:e.PageID}},!0)+(e.Anchor&&e.Anchor.length?"#"+e.Anchor:""),target:e.TargetBlank?"_blank":"",title:e.Description}},getOriginalAttributes:function(){var t=this.getElement().getEditor(),n=e(t.getSelectedNode()),r=(n.attr("href")||"").split("#");if(!r[0])return{};var i=C.default.match("sitetree_link",!1,r[0]);return i?{PageID:i.properties.id?parseInt(i.properties.id,10):0,Anchor:r[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})}),tinymce.PluginManager.add("sslinkanchor",function(e){return O.init(e)}),t.default=O},"./client/src/state/anchorSelector/AnchorSelectorActionTypes.js":function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={ANCHORSELECTOR_CURRENT_FIELD:"ANCHORSELECTOR_CURRENT_FIELD",ANCHORSELECTOR_UPDATED:"ANCHORSELECTOR_UPDATED",ANCHORSELECTOR_UPDATING:"ANCHORSELECTOR_UPDATING",ANCHORSELECTOR_UPDATE_FAILED:"ANCHORSELECTOR_UPDATE_FAILED"}},"./client/src/state/anchorSelector/AnchorSelectorActions.js":function(e,t,n){"use strict";function r(e){return{type:l.default.ANCHORSELECTOR_UPDATING,payload:{pageId:e}}}function i(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:l.default.ANCHORSELECTOR_UPDATED,payload:{pageId:e,anchors:t,cacheResult:n}}}function o(e,t,n){return{type:l.default.ANCHORSELECTOR_CURRENT_FIELD,payload:{pageId:e,anchors:t,fieldID:n}}}function a(e){return{type:l.default.ANCHORSELECTOR_UPDATE_FAILED,payload:{pageId:e}}}Object.defineProperty(t,"__esModule",{value:!0}),t.beginUpdating=r,t.updated=i,t.updatedCurrentField=o,t.updateFailed=a;var c=n("./client/src/state/anchorSelector/AnchorSelectorActionTypes.js"),l=function(e){return e&&e.__esModule?e:{default:e}}(c)},0:function(e,t){e.exports=jQuery},1:function(e,t){e.exports=React},2:function(e,t){e.exports=i18n},3:function(e,t){e.exports=Injector},4:function(e,t){e.exports=ReactApollo},5:function(e,t){e.exports=ReactDom},6:function(e,t){e.exports=ReactRedux},7:function(e,t){e.exports=InsertLinkModal},8:function(e,t){e.exports=ShortcodeSerialiser},9:function(e,t){e.exports=TinyMCEActionRegistrar}}); \ No newline at end of file +!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s="./client/src/legacy/TinyMCE_sslink-anchor.js")}({"./client/src/legacy/TinyMCE_sslink-anchor.js":function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(2),o=r(i),a=n(9),l=r(a),c=n(1),s=r(c),d=n(5),u=r(d),p=n(4),f=n(6),A=n(0),E=r(A),_=n(8),h=r(_),C=n(7),g=n(3),R=n("./client/src/state/anchorSelector/AnchorSelectorActions.js");l.default.addAction("sslink",{text:o.default._t("CMS.LINKLABEL_ANCHOR","Anchor on a page"),onAction:function(e){return e.execCommand("sslinkanchor")},priority:60},editorIdentifier).addCommandWithUrlTest("sslinkanchor",/^\[sitetree_link.+]#[^#\]]+$/);var O={init:function(e){e.addCommand("sslinkanchor",function(){var t=(0,E.default)("#"+e.id).entwine("ss"),n=Number((0,E.default)("#Form_EditForm_ID").val()||0),r=(0,E.default)(e.getBody()).find("[id],[name]").toArray().map(function(e){return e.id||e.name});ss.store.dispatch((0,R.updatedCurrentField)(n,r,e.id)),t.openLinkAnchorDialog()})}},m="insert-link__dialog-wrapper--anchor",T=(0,g.provideInjector)((0,C.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorAnchorLink"));E.default.entwine("ss",function(e){e("textarea.htmleditor").entwine({openLinkAnchorDialog:function(){var t=e("#"+m);t.length||(t=e(''),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e("#"+m).entwine({renderModal:function(t){var n=this,r=ss.store,i=ss.apolloClient,a=function(){return n.close()},l=function(){return n.handleInsert.apply(n,arguments)},c=this.getOriginalAttributes(),d=this.getElement().getEditor(),A=d.getInstance().selection,E=d.getSelection(),_=A.getNode().tagName,h="A"!==_&&""===E.trim(),C=Number(e("#Form_EditForm_ID").val()||0);u.default.render(s.default.createElement(p.ApolloProvider,{client:i},s.default.createElement(f.Provider,{store:r},s.default.createElement(T,{isOpen:t,onInsert:l,onClosed:a,title:o.default._t("CMS.LINK_ANCHOR","Link to an anchor on a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--anchor",fileAttributes:c,identifier:"Admin.InsertLinkAnchorModal",requireLinkText:h,currentPageID:C}))),this[0])},buildAttributes:function(e){return{href:h.default.serialise({name:"sitetree_link",properties:{id:e.PageID}},!0)+(e.Anchor&&e.Anchor.length?"#"+e.Anchor:""),target:e.TargetBlank?"_blank":"",title:e.Description}},getOriginalAttributes:function(){var t=this.getElement().getEditor(),n=e(t.getSelectedNode()),r=(n.attr("href")||"").split("#");if(!r[0])return{};var i=h.default.match("sitetree_link",!1,r[0]);return i?{PageID:i.properties.id?parseInt(i.properties.id,10):0,Anchor:r[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})}),tinymce.PluginManager.add("sslinkanchor",function(e){return O.init(e)}),t.default=O},"./client/src/state/anchorSelector/AnchorSelectorActionTypes.js":function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={ANCHORSELECTOR_CURRENT_FIELD:"ANCHORSELECTOR_CURRENT_FIELD",ANCHORSELECTOR_UPDATED:"ANCHORSELECTOR_UPDATED",ANCHORSELECTOR_UPDATING:"ANCHORSELECTOR_UPDATING",ANCHORSELECTOR_UPDATE_FAILED:"ANCHORSELECTOR_UPDATE_FAILED"}},"./client/src/state/anchorSelector/AnchorSelectorActions.js":function(e,t,n){"use strict";function r(e){return{type:c.default.ANCHORSELECTOR_UPDATING,payload:{pageId:e}}}function i(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return{type:c.default.ANCHORSELECTOR_UPDATED,payload:{pageId:e,anchors:t,cacheResult:n}}}function o(e,t,n){return{type:c.default.ANCHORSELECTOR_CURRENT_FIELD,payload:{pageId:e,anchors:t,fieldID:n}}}function a(e){return{type:c.default.ANCHORSELECTOR_UPDATE_FAILED,payload:{pageId:e}}}Object.defineProperty(t,"__esModule",{value:!0}),t.beginUpdating=r,t.updated=i,t.updatedCurrentField=o,t.updateFailed=a;var l=n("./client/src/state/anchorSelector/AnchorSelectorActionTypes.js"),c=function(e){return e&&e.__esModule?e:{default:e}}(l)},0:function(e,t){e.exports=jQuery},1:function(e,t){e.exports=React},2:function(e,t){e.exports=i18n},3:function(e,t){e.exports=Injector},4:function(e,t){e.exports=ReactApollo},5:function(e,t){e.exports=ReactDom},6:function(e,t){e.exports=ReactRedux},7:function(e,t){e.exports=InsertLinkModal},8:function(e,t){e.exports=ShortcodeSerialiser},9:function(e,t){e.exports=TinyMCEActionRegistrar}}); \ No newline at end of file diff --git a/client/dist/js/TinyMCE_sslink-internal.js b/client/dist/js/TinyMCE_sslink-internal.js index 52fa8e6aa3..56a6b0b468 100644 --- a/client/dist/js/TinyMCE_sslink-internal.js +++ b/client/dist/js/TinyMCE_sslink-internal.js @@ -1 +1 @@ -!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s="./client/src/legacy/TinyMCE_sslink-internal.js")}({"./client/src/legacy/TinyMCE_sslink-internal.js":function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(2),o=r(i),a=n(9),l=r(a),s=n(1),u=r(s),c=n(5),d=r(c),f=n(4),p=n(6),g=n(0),k=r(g),m=n(8),_=r(m),h=n(7),x=n(3);l.default.addAction("sslink",{text:o.default._t("CMS.LINKLABEL_PAGE","Page on this site"),onclick:function(e){return e.execCommand("sslinkinternal")},priority:90},editorIdentifier).addCommandWithUrlTest("sslinkinternal",/^\[sitetree_link.+]$/);var I={init:function(e){e.addCommand("sslinkinternal",function(){(0,k.default)("#"+e.id).entwine("ss").openLinkInternalDialog()})}},A="insert-link__dialog-wrapper--internal",C=(0,x.provideInjector)((0,h.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorInternalLink"));k.default.entwine("ss",function(e){e("textarea.htmleditor").entwine({openLinkInternalDialog:function(){var t=e("#"+A);t.length||(t=e(''),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e("#"+A).entwine({renderModal:function(e){var t=this,n=ss.store,r=ss.apolloClient,i=function(){return t.close()},a=function(){return t.handleInsert.apply(t,arguments)},l=this.getOriginalAttributes(),s=this.getRequireLinkText();d.default.render(u.default.createElement(f.ApolloProvider,{client:r},u.default.createElement(p.Provider,{store:n},u.default.createElement(C,{isOpen:e,onInsert:a,onClosed:i,title:o.default._t("CMS.LINK_PAGE","Link to a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:l,identifier:"Admin.InsertLinkInternalModal",requireLinkText:s}))),this[0])},getRequireLinkText:function(){var e=this.getElement().getEditor().getInstance().selection,t=e.getContent()||"";return"A"!==e.getNode().tagName&&""===t.trim()},buildAttributes:function(e){return{href:_.default.serialise({name:"sitetree_link",properties:{id:e.PageID}},!0)+(e.Anchor&&e.Anchor.length?"#"+e.Anchor:""),target:e.TargetBlank?"_blank":"",title:e.Description}},getOriginalAttributes:function(){var t=this.getElement().getEditor(),n=e(t.getSelectedNode()),r=(n.attr("href")||"").split("#");if(!r[0])return{};var i=_.default.match("sitetree_link",!1,r[0]);return i?{PageID:i.properties.id?parseInt(i.properties.id,10):0,Anchor:r[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})}),tinymce.PluginManager.add("sslinkinternal",function(e){return I.init(e)}),t.default=I},0:function(e,t){e.exports=jQuery},1:function(e,t){e.exports=React},2:function(e,t){e.exports=i18n},3:function(e,t){e.exports=Injector},4:function(e,t){e.exports=ReactApollo},5:function(e,t){e.exports=ReactDom},6:function(e,t){e.exports=ReactRedux},7:function(e,t){e.exports=InsertLinkModal},8:function(e,t){e.exports=ShortcodeSerialiser},9:function(e,t){e.exports=TinyMCEActionRegistrar}}); \ No newline at end of file +!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s="./client/src/legacy/TinyMCE_sslink-internal.js")}({"./client/src/legacy/TinyMCE_sslink-internal.js":function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(2),o=r(i),a=n(9),l=r(a),s=n(1),u=r(s),c=n(5),d=r(c),f=n(4),p=n(6),g=n(0),k=r(g),m=n(8),_=r(m),h=n(7),x=n(3);l.default.addAction("sslink",{text:o.default._t("CMS.LINKLABEL_PAGE","Page on this site"),onAction:function(e){return e.execCommand("sslinkinternal")},priority:90},editorIdentifier).addCommandWithUrlTest("sslinkinternal",/^\[sitetree_link.+]$/);var A={init:function(e){e.addCommand("sslinkinternal",function(){(0,k.default)("#"+e.id).entwine("ss").openLinkInternalDialog()})}},I="insert-link__dialog-wrapper--internal",v=(0,x.provideInjector)((0,h.createInsertLinkModal)("SilverStripe\\CMS\\Controllers\\CMSPageEditController","editorInternalLink"));k.default.entwine("ss",function(e){e("textarea.htmleditor").entwine({openLinkInternalDialog:function(){var t=e("#"+I);t.length||(t=e(''),e("body").append(t)),t.addClass("insert-link__dialog-wrapper"),t.setElement(this),t.open()}}),e("#"+I).entwine({renderModal:function(e){var t=this,n=ss.store,r=ss.apolloClient,i=function(){return t.close()},a=function(){return t.handleInsert.apply(t,arguments)},l=this.getOriginalAttributes(),s=this.getRequireLinkText();d.default.render(u.default.createElement(f.ApolloProvider,{client:r},u.default.createElement(p.Provider,{store:n},u.default.createElement(v,{isOpen:e,onInsert:a,onClosed:i,title:o.default._t("CMS.LINK_PAGE","Link to a page"),bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:l,identifier:"Admin.InsertLinkInternalModal",requireLinkText:s}))),this[0])},getRequireLinkText:function(){var e=this.getElement().getEditor(),t=e.getInstance().selection,n=e.getSelection();return"A"!==t.getNode().tagName&&""===n.trim()},buildAttributes:function(e){return{href:_.default.serialise({name:"sitetree_link",properties:{id:e.PageID}},!0)+(e.Anchor&&e.Anchor.length?"#"+e.Anchor:""),target:e.TargetBlank?"_blank":"",title:e.Description}},getOriginalAttributes:function(){var t=this.getElement().getEditor(),n=e(t.getSelectedNode()),r=(n.attr("href")||"").split("#");if(!r[0])return{};var i=_.default.match("sitetree_link",!1,r[0]);return i?{PageID:i.properties.id?parseInt(i.properties.id,10):0,Anchor:r[1]||"",Description:n.attr("title"),TargetBlank:!!n.attr("target")}:{}}})}),tinymce.PluginManager.add("sslinkinternal",function(e){return A.init(e)}),t.default=A},0:function(e,t){e.exports=jQuery},1:function(e,t){e.exports=React},2:function(e,t){e.exports=i18n},3:function(e,t){e.exports=Injector},4:function(e,t){e.exports=ReactApollo},5:function(e,t){e.exports=ReactDom},6:function(e,t){e.exports=ReactRedux},7:function(e,t){e.exports=InsertLinkModal},8:function(e,t){e.exports=ShortcodeSerialiser},9:function(e,t){e.exports=TinyMCEActionRegistrar}}); \ No newline at end of file diff --git a/client/src/legacy/TinyMCE_sslink-anchor.js b/client/src/legacy/TinyMCE_sslink-anchor.js index 042d3a66e8..4d12fed509 100644 --- a/client/src/legacy/TinyMCE_sslink-anchor.js +++ b/client/src/legacy/TinyMCE_sslink-anchor.js @@ -19,7 +19,7 @@ TinyMCEActionRegistrar 'sslink', { text: i18n._t('CMS.LINKLABEL_ANCHOR', 'Anchor on a page'), - onclick: (activeEditor) => activeEditor.execCommand(commandName), + onAction: (activeEditor) => activeEditor.execCommand(commandName), priority: 60, }, editorIdentifier, @@ -32,8 +32,8 @@ const plugin = { const field = jQuery(`#${editor.id}`).entwine('ss'); // Get the anchors in the current field and save them as props for AnchorSelectorField const currentPageID = Number(jQuery('#Form_EditForm_ID').val() || 0); - const validTargets = editor - .$('[id],[name]', editor.getBody()) + const validTargets = jQuery(editor.getBody()) + .find('[id],[name]') .toArray() .map((element) => element.id || element.name); ss.store.dispatch(updatedCurrentField(currentPageID, validTargets, editor.id)); @@ -74,8 +74,9 @@ jQuery.entwine('ss', ($) => { const handleHide = () => this.close(); const handleInsert = (...args) => this.handleInsert(...args); const attrs = this.getOriginalAttributes(); - const selection = tinymce.activeEditor.selection; - const selectionContent = selection.getContent() || ''; + const editor = this.getElement().getEditor(); + const selection = editor.getInstance().selection; + const selectionContent = editor.getSelection(); const tagName = selection.getNode().tagName; const requireLinkText = tagName !== 'A' && selectionContent.trim() === ''; const currentPageID = Number($('#Form_EditForm_ID').val() || 0); diff --git a/client/src/legacy/TinyMCE_sslink-internal.js b/client/src/legacy/TinyMCE_sslink-internal.js index 30290cd2ce..be1b636212 100644 --- a/client/src/legacy/TinyMCE_sslink-internal.js +++ b/client/src/legacy/TinyMCE_sslink-internal.js @@ -18,7 +18,7 @@ TinyMCEActionRegistrar 'sslink', { text: i18n._t('CMS.LINKLABEL_PAGE', 'Page on this site'), - onclick: (activeEditor) => activeEditor.execCommand(commandName), + onAction: (activeEditor) => activeEditor.execCommand(commandName), priority: 90, }, editorIdentifier, @@ -95,8 +95,10 @@ jQuery.entwine('ss', ($) => { * @return {Boolean} */ getRequireLinkText() { - const selection = this.getElement().getEditor().getInstance().selection; - const selectionContent = selection.getContent() || ''; + const editor = this.getElement().getEditor(); + const selection = editor.getInstance().selection; + const selectionContent = editor.getSelection(); + const tagName = selection.getNode().tagName; const requireLinkText = tagName !== 'A' && selectionContent.trim() === ''; diff --git a/code/Controllers/CMSMain.php b/code/Controllers/CMSMain.php index 3074b337e5..ab0a9703c1 100644 --- a/code/Controllers/CMSMain.php +++ b/code/Controllers/CMSMain.php @@ -8,6 +8,7 @@ use SilverStripe\Admin\CMSBatchActionHandler; use SilverStripe\Admin\LeftAndMain; use SilverStripe\Admin\LeftAndMainFormRequestHandler; +use SilverStripe\Admin\Navigator\SilverStripeNavigator; use SilverStripe\CMS\BatchActions\CMSBatchAction_Archive; use SilverStripe\CMS\BatchActions\CMSBatchAction_Publish; use SilverStripe\CMS\BatchActions\CMSBatchAction_Restore; @@ -1341,7 +1342,9 @@ public function getEditForm($id = null, $fields = null) // Added in-line to the form, but plucked into different view by LeftAndMain.Preview.js upon load /** @skipUpgrade */ - if ($record instanceof CMSPreviewable && !$fields->fieldByName('SilverStripeNavigator')) { + if (($record instanceof CMSPreviewable || $record->has_extension(CMSPreviewable::class)) + && !$fields->fieldByName('SilverStripeNavigator') + ) { $navField = new LiteralField('SilverStripeNavigator', $this->getSilverStripeNavigator()); $navField->setAllowHTML(true); $fields->push($navField); @@ -1392,7 +1395,7 @@ public function getEditForm($id = null, $fields = null) ]); // Announce the capability so the frontend can decide whether to allow preview or not. - if ($record instanceof CMSPreviewable) { + if ($record instanceof CMSPreviewable || $record->has_extension(CMSPreviewable::class)) { $form->addExtraClass('cms-previewable'); } $form->addExtraClass('fill-height flexbox-area-grow'); diff --git a/code/Controllers/ContentController.php b/code/Controllers/ContentController.php index 3fcb51f972..204fd2e3cb 100644 --- a/code/Controllers/ContentController.php +++ b/code/Controllers/ContentController.php @@ -2,6 +2,7 @@ namespace SilverStripe\CMS\Controllers; +use SilverStripe\Admin\Navigator\SilverStripeNavigator; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\Control\Controller; use SilverStripe\Control\Director; diff --git a/code/Controllers/SilverStripeNavigator.php b/code/Controllers/SilverStripeNavigator.php deleted file mode 100644 index dce05372ab..0000000000 --- a/code/Controllers/SilverStripeNavigator.php +++ /dev/null @@ -1,107 +0,0 @@ -record = $record; - } - - /** - * @return SS_List of SilverStripeNavigatorItem - */ - public function getItems() - { - $items = []; - - $classes = ClassInfo::subclassesFor(SilverStripeNavigatorItem::class); - array_shift($classes); - - // Sort menu items according to priority - foreach ($classes as $class) { - /** @var SilverStripeNavigatorItem $item */ - $item = new $class($this->record); - if (!$item->canView()) { - continue; - } - - // This funny litle formula ensures that the first item added with the same priority will be left-most. - $priority = $item->getPriority() * 100 - 1; - - // Ensure that we can have duplicates with the same (default) priority - while (isset($items[$priority])) { - $priority++; - } - - $items[$priority] = $item; - } - ksort($items); - - // Drop the keys and let the ArrayList handle the numbering, so $First, $Last and others work properly. - return new ArrayList(array_values($items ?? [])); - } - - /** - * @return DataObject|\SilverStripe\ORM\CMSPreviewable - */ - public function getRecord() - { - return $this->record; - } - - /** - * @param DataObject|CMSPreviewable $record - * @return array template data - */ - public static function get_for_record($record) - { - $html = ''; - $message = ''; - $navigator = new SilverStripeNavigator($record); - $items = $navigator->getItems(); - foreach ($items as $item) { - $text = $item->getHTML(); - if ($text) { - $html .= $text; - } - $newMessage = $item->getMessage(); - if ($newMessage && $item->isActive()) { - $message = $newMessage; - } - } - - return [ - 'items' => $html, - 'message' => $message - ]; - } -} diff --git a/code/Controllers/SilverStripeNavigatorItem.php b/code/Controllers/SilverStripeNavigatorItem.php deleted file mode 100644 index 4c5644a469..0000000000 --- a/code/Controllers/SilverStripeNavigatorItem.php +++ /dev/null @@ -1,136 +0,0 @@ -record = $record; - } - - /** - * @return string HTML, mostly a link - but can be more complex as well. - * For example, a "future state" item might show a date selector. - */ - abstract public function getHTML(); - - /** - * @return string - * Get the Title of an item - */ - abstract public function getTitle(); - - /** - * Machine-friendly name. - * - * @return string - */ - public function getName() - { - return substr(static::class, strpos(static::class, '_') + 1); - } - - /** - * Optional link to a specific view of this record. - * Not all items are simple links, please use {@link getHTML()} - * to represent an item in markup unless you know what you're doing. - * - * @return string - */ - public function getLink() - { - return null; - } - - /** - * @return string - */ - public function getMessage() - { - return null; - } - - /** - * @return DataObject - */ - public function getRecord() - { - return $this->record; - } - - /** - * @return int - */ - public function getPriority() - { - return $this->config()->get('priority'); - } - - /** - * As items might convey different record states like a "stage" or "live" table, - * an item can be active (showing the record in this state). - * - * @return boolean - */ - public function isActive() - { - return false; - } - - /** - * Filters items based on member permissions or other criteria, - * such as if a state is generally available for the current record. - * - * @param Member $member - * @return Boolean - */ - public function canView($member = null) - { - return true; - } - - /** - * Counts as "archived" if the current record is a different version from both live and draft. - * - * @return boolean - */ - public function isArchived() - { - /** @var Versioned|DataObject $record */ - $record = $this->record; - if (!$record->hasExtension(Versioned::class) || !$record->hasStages()) { - return false; - } - - if (!isset($record->_cached_isArchived)) { - $record->_cached_isArchived = $record->isArchived(); - } - - return $record->_cached_isArchived; - } -} diff --git a/code/Controllers/SilverStripeNavigatorItem_ArchiveLink.php b/code/Controllers/SilverStripeNavigatorItem_ArchiveLink.php deleted file mode 100644 index 5262755748..0000000000 --- a/code/Controllers/SilverStripeNavigatorItem_ArchiveLink.php +++ /dev/null @@ -1,71 +0,0 @@ -isActive() ? 'ss-ui-button current' : 'ss-ui-button'; - $linkTitle = _t('SilverStripe\\CMS\\Controllers\\ContentController.ARCHIVEDSITE', 'Preview version'); - $recordLink = Convert::raw2att(Controller::join_links( - $this->record->AbsoluteLink(), - '?archiveDate=' . urlencode($this->record->LastEdited ?? '') - )); - return "$linkTitle"; - } - - public function getTitle() - { - return _t('SilverStripe\\CMS\\Controllers\\SilverStripeNavigator.ARCHIVED', 'Archived'); - } - - public function getMessage() - { - $date = Versioned::current_archived_date(); - if (empty($date)) { - return null; - } - /** @var DBDatetime $dateObj */ - $dateObj = DBField::create_field('Datetime', $date); - $title = _t('SilverStripe\\CMS\\Controllers\\ContentController.NOTEWONTBESHOWN', 'Note: this message will not be shown to your visitors'); - return " "; - } - - public function getLink() - { - $link = $this->record->PreviewLink(); - return $link ? Controller::join_links($link, '?archiveDate=' . urlencode($this->record->LastEdited ?? '')) : ''; - } - - public function canView($member = null) - { - /** @var Versioned|DataObject $record */ - $record = $this->record; - return ( - $record->hasExtension(Versioned::class) - && $record->hasStages() - && $this->isArchived() - // Don't follow redirects in preview, they break the CMS editing form - && !($record instanceof RedirectorPage) - && $this->getLink() - ); - } - - public function isActive() - { - return $this->isArchived(); - } -} diff --git a/code/Controllers/SilverStripeNavigatorItem_CMSLink.php b/code/Controllers/SilverStripeNavigatorItem_CMSLink.php index 85f85fce81..eb888e67a2 100644 --- a/code/Controllers/SilverStripeNavigatorItem_CMSLink.php +++ b/code/Controllers/SilverStripeNavigatorItem_CMSLink.php @@ -3,6 +3,7 @@ namespace SilverStripe\CMS\Controllers; use SilverStripe\Admin\LeftAndMain; +use SilverStripe\Admin\Navigator\SilverStripeNavigatorItem; use SilverStripe\CMS\Model\RedirectorPage; use SilverStripe\Control\Controller; diff --git a/code/Controllers/SilverStripeNavigatorItem_LiveLink.php b/code/Controllers/SilverStripeNavigatorItem_LiveLink.php deleted file mode 100644 index 32d720293b..0000000000 --- a/code/Controllers/SilverStripeNavigatorItem_LiveLink.php +++ /dev/null @@ -1,89 +0,0 @@ -getLivePage(); - if (!$livePage) { - return null; - } - - $linkClass = $this->isActive() ? 'class="current" ' : ''; - $linkTitle = _t('SilverStripe\\CMS\\Controllers\\ContentController.PUBLISHEDSITE', 'Published Site'); - $recordLink = Convert::raw2att(Controller::join_links($livePage->AbsoluteLink(), "?stage=Live")); - return "$linkTitle"; - } - - public function getTitle() - { - return _t( - 'SilverStripe\\CMS\\Controllers\\ContentController.PUBLISHED', - 'Published', - 'Used for the Switch between draft and published view mode. Needs to be a short label' - ); - } - - public function getMessage() - { - return " "; - } - - public function getLink() - { - $link = $this->getLivePage()->PreviewLink(); - return $link ? Controller::join_links($link, '?stage=Live') : ''; - } - - public function canView($member = null) - { - /** @var Versioned|DataObject $record */ - $record = $this->record; - return ( - $record->hasExtension(Versioned::class) - && $this->showLiveLink() - && $record->hasStages() - && $this->getLivePage() - && $this->getLink() - ); - } - - /** - * @return bool - */ - public function showLiveLink() - { - return (bool)Config::inst()->get(get_class($this->record), 'show_live_link'); - } - - public function isActive() - { - return ( - (!Versioned::get_stage() || Versioned::get_stage() == 'Live') - && !$this->isArchived() - ); - } - - protected function getLivePage() - { - $baseClass = $this->record->baseClass(); - return Versioned::get_by_stage($baseClass, Versioned::LIVE)->byID($this->record->ID); - } -} diff --git a/code/Controllers/SilverStripeNavigatorItem_StageLink.php b/code/Controllers/SilverStripeNavigatorItem_StageLink.php deleted file mode 100644 index 280f8cd940..0000000000 --- a/code/Controllers/SilverStripeNavigatorItem_StageLink.php +++ /dev/null @@ -1,99 +0,0 @@ -getDraftPage(); - if (!$draftPage) { - return null; - } - $linkClass = $this->isActive() ? 'class="current" ' : ''; - $linkTitle = _t('SilverStripe\\CMS\\Controllers\\ContentController.DRAFTSITE', 'Draft Site'); - $recordLink = Convert::raw2att(Controller::join_links($draftPage->AbsoluteLink(), "?stage=Stage")); - return "$linkTitle"; - } - - public function getTitle() - { - return _t( - 'SilverStripe\\CMS\\Controllers\\ContentController.DRAFT', - 'Draft', - 'Used for the Switch between draft and published view mode. Needs to be a short label' - ); - } - - public function getMessage() - { - return " "; - } - - public function getLink() - { - $date = Versioned::current_archived_date(); - $link = $this->record->PreviewLink(); - if (!$link) { - return ''; - } - return Controller::join_links( - $link, - '?stage=Stage', - $date ? '?archiveDate=' . $date : null - ); - } - - public function canView($member = null) - { - /** @var Versioned|DataObject $record */ - $record = $this->record; - return ( - $record->hasExtension(Versioned::class) - && $this->showStageLink() - && $record->hasStages() - && $this->getDraftPage() - && $this->getLink() - ); - } - - /** - * @return bool - */ - public function showStageLink() - { - return (bool)Config::inst()->get(get_class($this->record), 'show_stage_link'); - } - - public function isActive() - { - return ( - Versioned::get_stage() == 'Stage' - && !(ClassInfo::exists('SiteTreeFutureState') && SiteTreeFutureState::get_future_datetime()) - && !$this->isArchived() - ); - } - - protected function getDraftPage() - { - $baseClass = $this->record->baseClass(); - return Versioned::get_by_stage($baseClass, Versioned::DRAFT)->byID($this->record->ID); - } -} diff --git a/code/Controllers/SilverStripeNavigatorItem_Unversioned.php b/code/Controllers/SilverStripeNavigatorItem_Unversioned.php deleted file mode 100644 index 2ee5f4e397..0000000000 --- a/code/Controllers/SilverStripeNavigatorItem_Unversioned.php +++ /dev/null @@ -1,80 +0,0 @@ -getLink()); - $linkTitle = _t('SilverStripe\\CMS\\Controllers\\ContentController.UNVERSIONEDPREVIEW', 'Preview'); - return "$linkTitle"; - } - - public function getLink() - { - return $this->getRecord()->PreviewLink() ?? ''; - } - - public function getTitle() - { - return _t( - 'SilverStripe\\CMS\\Controllers\\ContentController.UNVERSIONEDPREVIEW', - 'Preview', - 'Used for the Switch between states (if any other other states are added). Needs to be a short label' - ); - } - - /** - * True if the record doesn't have the Versioned extension and is configured to display this item. - * - * @param Member $member - * @return bool - */ - public function canView($member = null) - { - return ( - $this->recordIsUnversioned() - && $this->showUnversionedLink() - && $this->getLink() - ); - } - - private function recordIsUnversioned(): bool - { - $record = $this->getRecord(); - // If the record has the Versioned extension, it can be considered unversioned - // for the purposes of this class if it has no stages and is not archived. - if ($record->hasExtension(Versioned::class)) { - return (!$record->hasStages()) && !$this->isArchived(); - } - // Completely unversioned. - return true; - } - - /** - * True if the record is configured to display this item. - * - * @return bool - */ - public function showUnversionedLink(): bool - { - return (bool) Config::inst()->get(get_class($this->record), 'show_unversioned_preview_link'); - } - - /** - * This item is always active, as there are unlikely to be other preview states available for the record. - * - * @return bool - */ - public function isActive() - { - return true; - } -} diff --git a/lang/en.yml b/lang/en.yml index a539d2941a..7f71d59a3d 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -114,8 +114,6 @@ en: SilverStripe\CMS\Controllers\CMSSiteTreeFilter_StatusRemovedFromDraftPages: Title: 'Live but removed from draft' SilverStripe\CMS\Controllers\ContentController: - ARCHIVEDSITE: 'Preview version' - ARCHIVEDSITEFROM: 'Archived site from' CMS: CMS DRAFT: Draft DRAFTSITE: 'Draft Site' @@ -134,11 +132,8 @@ en: Password: Password PostInstallTutorialIntro: 'This website is a simplistic version of a SilverStripe 3 site. To extend this, please take a look at {link}.' StartEditing: 'You can start editing your content by opening the CMS.' - UNVERSIONEDPREVIEW: Preview UnableDeleteInstall: 'Unable to delete installation files. Please delete the files below manually' VIEWPAGEIN: 'View Page in:' - SilverStripe\CMS\Controllers\SilverStripeNavigator: - ARCHIVED: Archived SilverStripe\CMS\Forms\AnchorLinkFormFactory: ANCHORVALUE: Anchor SilverStripe\CMS\Forms\InternalLinkFormFactory: diff --git a/templates/SilverStripe/CMS/Controllers/Includes/CMSMain_PreviewPanel.ss b/templates/SilverStripe/CMS/Controllers/Includes/CMSMain_PreviewPanel.ss deleted file mode 100644 index 65e1bbab36..0000000000 --- a/templates/SilverStripe/CMS/Controllers/Includes/CMSMain_PreviewPanel.ss +++ /dev/null @@ -1,16 +0,0 @@ -My awesome content" And I select "awesome" in the "Content" HTML field When I press the "Insert link" HTML field button - And I click "Link to external URL" in the ".mce-menu" element + And I click "Link to external URL" in the ".tox-collection__group" element And I should see an "form#Form_ModalsEditorExternalLink" element Then the "URL" field should contain "http://silverstripe.org" # This doesn't seem to suffer from that issue When I fill in "http://google.com" for "URL" - And I press the "Insert" button + And I press the "Insert link" button Then the "Content" HTML field should contain "awesome" # Required to avoid "unsaved changes" browser dialog Then I press the "Save" button diff --git a/tests/behat/features/insert-anchor-link.feature b/tests/behat/features/insert-anchor-link.feature index 23468c12d4..a97ad46a9e 100644 --- a/tests/behat/features/insert-anchor-link.feature +++ b/tests/behat/features/insert-anchor-link.feature @@ -16,7 +16,7 @@ So that I can link to a external website or a page on my site Scenario: I can link to an anchor in an internal page When I select "awesome" in the "Content" HTML field And I press the "Insert link" HTML field button - And I click "Anchor on a page" in the ".mce-menu" element + And I click "Anchor on a page" in the ".tox-collection__group" element Then I should see an "form#Form_editorAnchorLink" element And I should see "About Us" in the "#Form_editorAnchorLink_PageID_Holder .Select-multi-value-wrapper" element When I click "About Us" in the "#Form_editorAnchorLink_PageID_Holder .Select-multi-value-wrapper" element @@ -25,7 +25,7 @@ So that I can link to a external website or a page on my site And I click "youranchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-menu-outer" element Then I should see "youranchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-value" element When I fill in "my desc" for "Link description" - And I press the "Insert" button + And I press the "Insert link" button Then the "Content" HTML field should contain "awesome" # Required to avoid "unsaved changes" browser dialog Then I press the "Save" button @@ -33,7 +33,7 @@ So that I can link to a external website or a page on my site Scenario: I can link to an anchor from a dataobject on the current page When I select "awesome" in the "Content" HTML field And I press the "Insert link" HTML field button - And I click "Anchor on a page" in the ".mce-menu" element + And I click "Anchor on a page" in the ".tox-collection__group" element Then I should see an "form#Form_editorAnchorLink" element And I should see "About Us" in the "#Form_editorAnchorLink_PageID_Holder .Select-multi-value-wrapper" element When I click "Select or enter anchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-multi-value-wrapper" element @@ -41,7 +41,7 @@ So that I can link to a external website or a page on my site When I click "dataobject-anchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-menu-outer" element Then I should see "dataobject-anchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-value" element When I fill in "my desc" for "Link description" - And I press the "Insert" button + And I press the "Insert link" button Then the "Content" HTML field should contain "awesome" # Required to avoid "unsaved changes" browser dialog Then I press the "Save" button @@ -50,7 +50,7 @@ So that I can link to a external website or a page on my site Given I fill in the "Content" HTML field with "
My awesome content
" When I select "awesome" in the "Content" HTML field And I press the "Insert link" HTML field button - And I click "Anchor on a page" in the ".mce-menu" element + And I click "Anchor on a page" in the ".tox-collection__group" element Then I should see an "form#Form_editorAnchorLink" element And I should see "About Us" in the "#Form_editorAnchorLink_PageID_Holder .Select-multi-value-wrapper" element When I click "Select or enter anchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-multi-value-wrapper" element @@ -59,7 +59,7 @@ So that I can link to a external website or a page on my site When I click "unsaved-anchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-menu-outer" element Then I should see "unsaved-anchor" in the "#Form_editorAnchorLink_Anchor_Holder .Select-value" element When I fill in "my desc" for "Link description" - And I press the "Insert" button + And I press the "Insert link" button Then the "Content" HTML field should contain "awesome" # Required to avoid "unsaved changes" browser dialog Then I press the "Save" button diff --git a/tests/behat/features/redirector-page.feature b/tests/behat/features/redirector-page.feature index 9fb7b244bb..a1f8799312 100644 --- a/tests/behat/features/redirector-page.feature +++ b/tests/behat/features/redirector-page.feature @@ -1,4 +1,3 @@ -@gsat Feature: Redirector Pages As an author I want to redirect to a different location diff --git a/tests/behat/src/FixtureContext.php b/tests/behat/src/FixtureContext.php index ba6c59dbd6..b216a28115 100644 --- a/tests/behat/src/FixtureContext.php +++ b/tests/behat/src/FixtureContext.php @@ -118,22 +118,6 @@ public function iSeeTheRadioButtonAttributeEquals($radioLabel, $attribute, $valu Assert::assertEquals($value, $radioButton->getAttribute($attribute)); } - /** - * Assumes you've just opened the Insert link menu, e.g. - * I click on the "div[aria-label='Insert link [Ctrl+K]'] button" element - * - * @When /^I select "(.+?)" from the TinyMCE menu with javascript$/ - * @param string $label - */ - public function iSelectFromTheTinyMceMenu($label) - { - // :visible and :contains are jQuery css selectors - $js = <<