diff --git a/modules/backend/assets/js/october-min.js b/modules/backend/assets/js/october-min.js index 0bc34fc0b..fd40defc6 100644 --- a/modules/backend/assets/js/october-min.js +++ b/modules/backend/assets/js/october-min.js @@ -1338,4 +1338,7 @@ var loaded=0 $.each(sources,function(index,source){var img=new Image() img.onload=function(){if(++loaded==sources.length&&callback) callback()} -img.src=source})}};return o;};assetManager=new AssetManager(); \ No newline at end of file +img.src=source})}};return o;};assetManager=new AssetManager();if($.oc===undefined) +$.oc={} +$.oc.escapeHtmlString=function(string){var htmlEscapes={'&':'&','<':'<','>':'>','"':'"',"'":''','/':'/'},htmlEscaper=/[&<>"'\/]/g +return(''+string).replace(htmlEscaper,function(match){return htmlEscapes[match];})} \ No newline at end of file diff --git a/modules/backend/formwidgets/RichEditor.php b/modules/backend/formwidgets/RichEditor.php index 7045976b7..17e7069b1 100644 --- a/modules/backend/formwidgets/RichEditor.php +++ b/modules/backend/formwidgets/RichEditor.php @@ -102,51 +102,10 @@ class RichEditor extends FormWidgetBase return $buttons; } - /** - * Returns a single collection of available page links. - * This implementation has room to place links under - * different groups based on the link type. - * @return array - */ - public function onGetPageLinks() + public function onLoadPageLinksForm() { - $links = []; - $types = $this->getPageLinkTypes(); - - $links[] = ['name' => 'Select a page...', 'url' => false]; - - $iterator = function($links, $level = 0) use (&$iterator) { - $result = []; - foreach ($links as $linkUrl => $link) { - - /* - * Remove scheme and host from URL - */ - $baseUrl = Request::getSchemeAndHttpHost(); - if (strpos($linkUrl, $baseUrl) === 0) { - $linkUrl = substr($linkUrl, strlen($baseUrl)); - } - - $linkName = str_repeat(' ', $level * 4); - $linkName .= is_array($link) ? array_get($link, 'title', '') : $link; - $result[] = ['name' => $linkName, 'url' => $linkUrl]; - - if (is_array($link)) { - $result = array_merge( - $result, - $iterator(array_get($link, 'links', []), $level + 1) - ); - } - } - - return $result; - }; - - foreach ($types as $typeCode => $typeName) { - $links = array_merge($links, $iterator($this->getPageLinks($typeCode))); - } - - return ['links' => $links]; + $this->vars['links'] = $this->getPageLinksArray(); + return $this->makePartial('page_links_form'); } /** @@ -225,4 +184,51 @@ class RichEditor extends FormWidgetBase return $result; } + + /** + * Returns a single collection of available page links. + * This implementation has room to place links under + * different groups based on the link type. + * @return array + */ + protected function getPageLinksArray() + { + $links = []; + $types = $this->getPageLinkTypes(); + + $links[] = ['name' => 'Select a page...', 'url' => false]; + + $iterator = function($links, $level = 0) use (&$iterator) { + $result = []; + foreach ($links as $linkUrl => $link) { + + /* + * Remove scheme and host from URL + */ + $baseUrl = Request::getSchemeAndHttpHost(); + if (strpos($linkUrl, $baseUrl) === 0) { + $linkUrl = substr($linkUrl, strlen($baseUrl)); + } + + $linkName = str_repeat(' ', $level * 4); + $linkName .= is_array($link) ? array_get($link, 'title', '') : $link; + $result[] = ['name' => $linkName, 'url' => $linkUrl]; + + if (is_array($link)) { + $result = array_merge( + $result, + $iterator(array_get($link, 'links', []), $level + 1) + ); + } + } + + return $result; + }; + + foreach ($types as $typeCode => $typeName) { + $links = array_merge($links, $iterator($this->getPageLinks($typeCode))); + } + + return $links; + } } diff --git a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css index 23f9a7c1a..a50db275d 100755 --- a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css +++ b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css @@ -50,17 +50,17 @@ iframe.fr-iframe{width:100%;border:none;position:relative;display:block;z-index: .fr-toolbar.fr-inline .fr-separator.fr-hs{float:none} .fr-toolbar.fr-inline .fr-separator.fr-vs{float:none;display:inline-block} .fr-toolbar .fr-command.fr-btn,.fr-popup .fr-command.fr-btn{background:transparent;color:rgba(64,82,97,0.8);-moz-outline:0;outline:0;border:0;line-height:1;cursor:pointer;text-align:left;margin:0px 2px;transition:background 0.2s ease 0s;-webkit-transition:background 0.2s ease 0s;-moz-transition:background 0.2s ease 0s;-ms-transition:background 0.2s ease 0s;-o-transition:background 0.2s ease 0s;border-radius:0;-moz-border-radius:0;-webkit-border-radius:0;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;z-index:2;position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-decoration:none;user-select:none;-o-user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;float:left;padding:0;width:38px;height:37px} -.fr-toolbar .fr-command.fr-btn i,.fr-popup .fr-command.fr-btn i{display:block;font-size:15px;width:15px;margin:11px 11.5px;text-align:center;float:none} -.fr-toolbar .fr-command.fr-btn span,.fr-popup .fr-command.fr-btn span{font-size:14px;display:block;line-height:14px;min-width:38px;float:left;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;height:15px;font-weight:bold} -.fr-toolbar .fr-command.fr-btn img,.fr-popup .fr-command.fr-btn img{margin:11px 11.5px;width:15px} +.fr-toolbar .fr-command.fr-btn i,.fr-popup .fr-command.fr-btn i{display:block;font-size:14;width:14;margin:11.5px 12px;text-align:center;float:none} +.fr-toolbar .fr-command.fr-btn span,.fr-popup .fr-command.fr-btn span{font-size:14px;display:block;line-height:14px;min-width:38px;float:left;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;height:14;font-weight:bold} +.fr-toolbar .fr-command.fr-btn img,.fr-popup .fr-command.fr-btn img{margin:11.5px 12px;width:14} .fr-toolbar .fr-command.fr-btn.fr-active,.fr-popup .fr-command.fr-btn.fr-active{color:#000000;background:transparent} .fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-selection,.fr-popup .fr-command.fr-btn.fr-dropdown.fr-selection{width:auto} .fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-selection span,.fr-popup .fr-command.fr-btn.fr-dropdown.fr-selection span{font-weight:normal} -.fr-toolbar .fr-command.fr-btn.fr-dropdown i,.fr-popup .fr-command.fr-btn.fr-dropdown i,.fr-toolbar .fr-command.fr-btn.fr-dropdown span,.fr-popup .fr-command.fr-btn.fr-dropdown span,.fr-toolbar .fr-command.fr-btn.fr-dropdown img,.fr-popup .fr-command.fr-btn.fr-dropdown img{margin-left:7.5px;margin-right:15.5px} +.fr-toolbar .fr-command.fr-btn.fr-dropdown i,.fr-popup .fr-command.fr-btn.fr-dropdown i,.fr-toolbar .fr-command.fr-btn.fr-dropdown span,.fr-popup .fr-command.fr-btn.fr-dropdown span,.fr-toolbar .fr-command.fr-btn.fr-dropdown img,.fr-popup .fr-command.fr-btn.fr-dropdown img{margin-left:8px;margin-right:16px} .fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-active,.fr-popup .fr-command.fr-btn.fr-dropdown.fr-active{color:rgba(64,82,97,0.8);background:#d6d6d6} .fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-active:hover,.fr-popup .fr-command.fr-btn.fr-dropdown.fr-active:hover,.fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-active:focus,.fr-popup .fr-command.fr-btn.fr-dropdown.fr-active:focus{background:#d6d6d6 !important;color:rgba(64,82,97,0.8) !important} .fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-active:hover::after,.fr-popup .fr-command.fr-btn.fr-dropdown.fr-active:hover::after,.fr-toolbar .fr-command.fr-btn.fr-dropdown.fr-active:focus::after,.fr-popup .fr-command.fr-btn.fr-dropdown.fr-active:focus::after{border-top-color:rgba(64,82,97,0.8) !important} -.fr-toolbar .fr-command.fr-btn.fr-dropdown::after,.fr-popup .fr-command.fr-btn.fr-dropdown::after{position:absolute;width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(64,82,97,0.8);right:3.75px;top:16.5px;content:""} +.fr-toolbar .fr-command.fr-btn.fr-dropdown::after,.fr-popup .fr-command.fr-btn.fr-dropdown::after{position:absolute;width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(64,82,97,0.8);right:4px;top:16.5px;content:""} .fr-toolbar .fr-command.fr-btn.fr-disabled,.fr-popup .fr-command.fr-btn.fr-disabled{color:#bdbdbd;cursor:default} .fr-toolbar .fr-command.fr-btn.fr-disabled::after,.fr-popup .fr-command.fr-btn.fr-disabled::after{border-top-color:#bdbdbd !important} .fr-toolbar .fr-command.fr-btn.fr-hidden,.fr-popup .fr-command.fr-btn.fr-hidden{display:none} @@ -68,10 +68,10 @@ iframe.fr-iframe{width:100%;border:none;position:relative;display:block;z-index: .fr-toolbar.fr-disabled .fr-btn.fr-dropdown::after,.fr-popup.fr-disabled .fr-btn.fr-dropdown::after,.fr-toolbar.fr-disabled .fr-btn.fr-active.fr-dropdown::after,.fr-popup.fr-disabled .fr-btn.fr-active.fr-dropdown::after{border-top-color:#bdbdbd} .fr-toolbar.fr-rtl .fr-command.fr-btn,.fr-popup.fr-rtl .fr-command.fr-btn{float:right} .fr-toolbar.fr-inline .fr-command.fr-btn{float:none} -.fr-desktop .fr-command:hover,.fr-desktop .fr-command:focus{color:#222222;background:#ebebeb} +.fr-desktop .fr-command:hover,.fr-desktop .fr-command:focus{color:#222222;background:#dddddd} .fr-desktop .fr-command:hover::after,.fr-desktop .fr-command:focus::after{border-top-color:#222222 !important} .fr-desktop .fr-command.fr-selected{color:rgba(64,82,97,0.8);background:#d6d6d6} -.fr-desktop .fr-command.fr-active:hover,.fr-desktop .fr-command.fr-active:focus{color:#1e88e5;background:#ebebeb} +.fr-desktop .fr-command.fr-active:hover,.fr-desktop .fr-command.fr-active:focus{color:#1e88e5;background:#dddddd} .fr-desktop .fr-command.fr-active.fr-selected{color:#1e88e5;background:#d6d6d6} .fr-desktop .fr-command.fr-disabled:hover,.fr-desktop .fr-command.fr-disabled:focus,.fr-desktop .fr-command.fr-disabled.fr-selected{background:transparent} .fr-desktop.fr-disabled .fr-command:hover,.fr-desktop.fr-disabled .fr-command:focus,.fr-desktop.fr-disabled .fr-command.fr-selected{background:transparent} @@ -161,9 +161,9 @@ textarea.fr-code{display:none;width:100%;resize:none;-moz-resize:none;-webkit-re .fr-box.fr-code-view .fr-element,.fr-box.fr-code-view .fr-placeholder,.fr-box.fr-code-view .fr-iframe{display:none} .fr-box.fr-code-view .CodeMirror{display:block} .fr-box.fr-inline.fr-code-view .fr-command.fr-btn.html-switch{display:block} -.fr-box.fr-inline .fr-command.fr-btn.html-switch{position:absolute;top:0;right:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);display:none;background:#ffffff;color:rgba(64,82,97,0.8);-moz-outline:0;outline:0;border:0;line-height:1;cursor:pointer;text-align:left;padding:11px 11.5px;transition:background 0.2s ease 0s;-webkit-transition:background 0.2s ease 0s;-moz-transition:background 0.2s ease 0s;-ms-transition:background 0.2s ease 0s;-o-transition:background 0.2s ease 0s;border-radius:0;-moz-border-radius:0;-webkit-border-radius:0;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-decoration:none;user-select:none;-o-user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none} -.fr-box.fr-inline .fr-command.fr-btn.html-switch i{font-size:15px;width:15px;text-align:center} -.fr-box.fr-inline .fr-command.fr-btn.html-switch.fr-desktop:hover{background:#ebebeb} +.fr-box.fr-inline .fr-command.fr-btn.html-switch{position:absolute;top:0;right:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);box-shadow:0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);display:none;background:#ffffff;color:rgba(64,82,97,0.8);-moz-outline:0;outline:0;border:0;line-height:1;cursor:pointer;text-align:left;padding:11.5px 12px;transition:background 0.2s ease 0s;-webkit-transition:background 0.2s ease 0s;-moz-transition:background 0.2s ease 0s;-ms-transition:background 0.2s ease 0s;-o-transition:background 0.2s ease 0s;border-radius:0;-moz-border-radius:0;-webkit-border-radius:0;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;z-index:2;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-decoration:none;user-select:none;-o-user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none} +.fr-box.fr-inline .fr-command.fr-btn.html-switch i{font-size:14;width:14;text-align:center} +.fr-box.fr-inline .fr-command.fr-btn.html-switch.fr-desktop:hover{background:#dddddd} .fr-file-upload-layer{border:dashed 2px #bdbdbd;padding:25px 0;position:relative;font-size:14px;letter-spacing:1px;line-height:140%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-align:center} .fr-file-upload-layer:hover{background:#ebebeb} .fr-file-upload-layer.fr-drop{background:#ebebeb;border-color:#1e88e5} diff --git a/modules/backend/formwidgets/richeditor/assets/js/build-min.js b/modules/backend/formwidgets/richeditor/assets/js/build-min.js index bf18a7bad..d0af9ce2a 100755 --- a/modules/backend/formwidgets/richeditor/assets/js/build-min.js +++ b/modules/backend/formwidgets/richeditor/assets/js/build-min.js @@ -378,7 +378,22 @@ $.FE.DEFAULTS.imageInsertButtons.push('mmImageManager');$.FE.RegisterCommand('mm $.FE.DefineIcon('mmImageManager',{NAME:'folder'});$.FE.DEFAULTS.fileInsertButtons.push('mmFileManager');$.FE.RegisterCommand('mmFileManager',{title:'Browse',undo:false,focus:false,callback:function(){this.mediaManager.insertFile();},plugin:'mediaManager'}) $.FE.DefineIcon('mmFileManager',{NAME:'folder'});$.FE.DEFAULTS.videoInsertButtons.push('mmVideoManager');$.FE.RegisterCommand('mmVideoManager',{title:'Browse',undo:false,focus:false,callback:function(){this.mediaManager.insertVideo();},plugin:'mediaManager'}) $.FE.DefineIcon('mmVideoManager',{NAME:'folder'});$.FE.DEFAULTS.audioInsertButtons.push('mmAudioManager');$.FE.RegisterCommand('mmAudioManager',{title:'Browse',undo:false,focus:false,callback:function(){this.mediaManager.insertAudio();},plugin:'mediaManager'}) -$.FE.DefineIcon('mmAudioManager',{NAME:'folder'});})(jQuery);(function($){$.FroalaEditor.PLUGINS.figures=function(editor){function insertElement($el){var html=$('
').append($el.clone()).remove().html() +$.FE.DefineIcon('mmAudioManager',{NAME:'folder'});})(jQuery);var richeditorPageLinksPlugin +function richeditorPageLinksSelectPage($form){richeditorPageLinksPlugin.setLinkValueFromPopup($form)} +(function($){$.FroalaEditor.PLUGINS.pageLinks=function(editor){function setLinkValueFromPopup($form){var $select=$('select[name=pagelink]',$form) +var link={text:$('option:selected',$select).text().trim(),href:$select.val()} +setTimeout(function(){editor.popups.show('link.insert') +setLinkValue(link)},300)} +function setLinkValue(link){var $popup=editor.popups.get('link.insert');var text_inputs=$popup.find('input.fr-link-attr[type="text"]');var check_inputs=$popup.find('input.fr-link-attr[type="checkbox"]');var $input;var i;for(i=0;i').append($el.clone()).remove().html() editor.events.focus(true) editor.selection.restore() editor.html.insert(html) @@ -485,7 +500,6 @@ froalaOptions.htmlDoNotWrapTags=this.options.noWrapTags?this.options.noWrapTags. if(this.options.removeTags){froalaOptions.htmlRemoveTags=this.options.removeTags.split(/[\s,]+/)} froalaOptions.lineBreakerTags=['figure','table','hr','iframe','form','dl'] froalaOptions.shortcutsEnabled=['show','bold','italic','underline','indent','outdent','undo','redo'] -froalaOptions.linkInsertButtons=['linkBack','|'] froalaOptions.imageUploadURL=froalaOptions.fileUploadURL=window.location froalaOptions.imageUploadParam=froalaOptions.fileUploadParam='file_data' froalaOptions.imageUploadParams=froalaOptions.fileUploadParams={X_OCTOBER_MEDIA_MANAGER_QUICK_UPLOAD:1} diff --git a/modules/backend/formwidgets/richeditor/assets/js/build.js b/modules/backend/formwidgets/richeditor/assets/js/build.js index cca431bdf..ba2eaa15e 100755 --- a/modules/backend/formwidgets/richeditor/assets/js/build.js +++ b/modules/backend/formwidgets/richeditor/assets/js/build.js @@ -39,6 +39,7 @@ =require ../vendor/froala_drm/js/plugins/code_beautifier.min.js =require plugins/mediamanager.js +=require plugins/pagelinks.js =require plugins/figures.js =require richeditor.js diff --git a/modules/backend/formwidgets/richeditor/assets/js/plugins/pagelinks.js b/modules/backend/formwidgets/richeditor/assets/js/plugins/pagelinks.js new file mode 100644 index 000000000..af6608b66 --- /dev/null +++ b/modules/backend/formwidgets/richeditor/assets/js/plugins/pagelinks.js @@ -0,0 +1,94 @@ +// +// Page links +// + +var richeditorPageLinksPlugin + +function richeditorPageLinksSelectPage($form) { + richeditorPageLinksPlugin.setLinkValueFromPopup($form) +} + +(function ($) { + $.FroalaEditor.PLUGINS.pageLinks = function (editor) { + + function setLinkValueFromPopup($form) { + var $select = $('select[name=pagelink]', $form) + + var link = { + text: $('option:selected', $select).text().trim(), + href: $select.val() + } + + // Wait for popup to close + setTimeout(function() { + editor.popups.show('link.insert') + + setLinkValue(link) + }, 300) + } + + function setLinkValue(link) { + var $popup = editor.popups.get('link.insert'); + var text_inputs = $popup.find('input.fr-link-attr[type="text"]'); + var check_inputs = $popup.find('input.fr-link-attr[type="checkbox"]'); + + var $input; + var i; + for (i = 0; i < text_inputs.length; i++) { + $input = $(text_inputs[i]); + if (link[$input.attr('name')]) { + $input.val(link[$input.attr('name')]); + } + else if ($input.attr('name') != 'text') { + $input.val(''); + } + } + + for (i = 0; i < check_inputs.length; i++) { + $input = $(check_inputs[i]); + $input.prop('checked', $input.data('checked') == link[$input.attr('name')]); + } + } + + function insertLink() { + richeditorPageLinksPlugin = this + + editor.$el.popup({ + handler: 'onLoadPageLinksForm' + }) + } + + /** + * Init. + */ + function _init () { + } + + return { + _init: _init, + setLinkValueFromPopup: setLinkValueFromPopup, + setLinkValue: setLinkValue, + insertLink: insertLink + } + } + + $.FE.DEFAULTS.audioInsertButtons.push('mmAudioManager'); + + $.FE.DEFAULTS.linkInsertButtons = ['linkBack', '|', 'linkPageLinks'] + + $.FE.RegisterCommand('linkPageLinks', { + title: 'Choose Link', + undo: false, + focus: false, + callback: function () { + this.pageLinks.insertLink() + }, + plugin: 'pageLinks' + }) + + // Add the font size icon. + $.FE.DefineIcon('linkPageLinks', { + NAME: 'search' + }); + +})(jQuery); diff --git a/modules/backend/formwidgets/richeditor/assets/js/richeditor.js b/modules/backend/formwidgets/richeditor/assets/js/richeditor.js index 58a4dd54e..ce5992f09 100755 --- a/modules/backend/formwidgets/richeditor/assets/js/richeditor.js +++ b/modules/backend/formwidgets/richeditor/assets/js/richeditor.js @@ -160,7 +160,6 @@ froalaOptions.lineBreakerTags = ['figure', 'table', 'hr', 'iframe', 'form', 'dl'] froalaOptions.shortcutsEnabled = ['show', 'bold', 'italic', 'underline', 'indent', 'outdent', 'undo', 'redo'] - froalaOptions.linkInsertButtons = ['linkBack', '|'] // File upload froalaOptions.imageUploadURL = froalaOptions.fileUploadURL = window.location diff --git a/modules/backend/formwidgets/richeditor/assets/less/richeditor.less b/modules/backend/formwidgets/richeditor/assets/less/richeditor.less index 5fce8ccaf..da18c2fd1 100755 --- a/modules/backend/formwidgets/richeditor/assets/less/richeditor.less +++ b/modules/backend/formwidgets/richeditor/assets/less/richeditor.less @@ -45,7 +45,9 @@ @ui-border-color: @input-border-color; @ui-border-top: 1px solid @ui-border-color; @editor-padding: 20px; +@btn-hover-bg: #ddd; @btn-text: fade(@btn-secondary-color, 80%); +@btn-font-size: 14; @btn-active-text: #000; @input-label-color: @color-label; diff --git a/modules/backend/formwidgets/richeditor/partials/_page_links_form.htm b/modules/backend/formwidgets/richeditor/partials/_page_links_form.htm new file mode 100644 index 000000000..5c7c1bd5b --- /dev/null +++ b/modules/backend/formwidgets/richeditor/partials/_page_links_form.htm @@ -0,0 +1,33 @@ + 'pageLinksForm']) ?> + + + + +