Refit the Predefined Page Links implementation

Refs #2005
This commit is contained in:
Samuel Georges 2016-05-25 05:19:12 +10:00
parent ff631ba92a
commit 4c50c23654
9 changed files with 210 additions and 58 deletions

View File

@ -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();
img.src=source})}};return o;};assetManager=new AssetManager();if($.oc===undefined)
$.oc={}
$.oc.escapeHtmlString=function(string){var htmlEscapes={'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#x27;','/':'&#x2F;'},htmlEscaper=/[&<>"'\/]/g
return(''+string).replace(htmlEscaper,function(match){return htmlEscapes[match];})}

View File

@ -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('&nbsp;', $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('&nbsp;', $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;
}
}

View File

@ -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}

View File

@ -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=$('<div />').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<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'})}
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'})
$.FE.DefineIcon('linkPageLinks',{NAME:'search'});})(jQuery);(function($){$.FroalaEditor.PLUGINS.figures=function(editor){function insertElement($el){var html=$('<div />').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}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -0,0 +1,33 @@
<?= Form::open(['id' => 'pageLinksForm']) ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title">Page link</h4>
</div>
<div class="modal-body">
<div class="form-group">
<select name="pagelink" class="form-control custom-select" id="pageLink">
<?php foreach ($links as $link): ?>
<option value="<?= array_get($link, 'url') ?>"><?= array_get($link, 'name') ?></option>
<?php endforeach ?>
</select>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-primary"
data-dismiss="popup"
onclick="richeditorPageLinksSelectPage($('#pageLinksForm'))">
Select
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
<?= Form::close() ?>