Use old method to init ckeditor

Instead of using global JS-variables and ignoring serendipity[textarea]={$view}, this
approach actually uses the variable and therefore reinstates wysiwyg_init.tpl.

ckeditor_custom_config.js (Thx Ian!) is still respected, but the toolbar got restored to the old version. We need an easy way to remove _underline_, for example. It could be extended though.

This fixes #{107} somewhat, as serendipity_image_selector.php is useable now, but still with display errors (and without an upload widget). Probably still a good idea to copy the ML-eapproach of the normal textareas

This also works with htmlnuggets, without using spawnnugget from the core, instead wysiwyg_init.tpl gets reused in the plugin-config.

ckeditor_custom_plugin.js got emptied, the relevant code (which should only be the part that adds the plugins into the toolbar) should be integrated into wysiwyg_init.tpl).
This commit is contained in:
onli 2014-03-23 23:03:09 +01:00
parent 31eba101f6
commit 0d54063c5e
7 changed files with 44 additions and 306 deletions

View File

@ -8,16 +8,16 @@
CKEDITOR.editorConfig = function( config ) {
// Advanced Content Filter ACF works in two modes:
// automatic the filter is configured by editor features (like plugins, buttons, and commands) that are enabled with configuration options
// automatic the filter is configured by editor features (like plugins, buttons, and commands) that are enabled with configuration options
// such as CKEDITOR.config.plugins, CKEDITOR.config.extraPlugins, and CKEDITOR.config.toolbar,
// custom the filter is configured by the CKEDITOR.config.allowedContent option and only features that match this setting are activated.
// custom the filter is configured by the CKEDITOR.config.allowedContent option and only features that match this setting are activated.
// In both modes it is possible to extend the filter configuration by using the CKEDITOR.config.extraAllowedContent setting.
// If you want to disable Advanced Content Filter, set CKEDITOR.config.allowedContent to true. All available editor features will be activated and input data will not be filtered.
// Allowed content rules. This setting is used when instantiating CKEDITOR.editor.filter.
// The following values are accepted:
// CKEDITOR.filter.allowedContentRules defined rules will be added to the CKEDITOR.editor.filter.
// true will disable the filter (data will not be filtered, all features will be activated).
// default the filter will be configured by loaded features (toolbar items, commands, etc.).
// CKEDITOR.filter.allowedContentRules defined rules will be added to the CKEDITOR.editor.filter.
// true will disable the filter (data will not be filtered, all features will be activated).
// default the filter will be configured by loaded features (toolbar items, commands, etc.).
// In all cases filter configuration may be extended by extraAllowedContent. This option may be especially useful when you want to use the default allowedContent value along with some additional rules.
//
// config.allowedContent = CONFIG_ACF_OFF;
@ -81,26 +81,4 @@ CKEDITOR.editorConfig = function( config ) {
//config.uiColor = '#14B8C4'; // light turquoise
config['skin'] = 'moono';
config['height'] = 400;
// remove custom toolbar buttons and plugins
//config.removePlugins = 'flash,iframe';
config.removeButtons = 'Styles';
// set the custom toolbar group
// Note: indent is disabled, mediaembed plugin is set here and procurator placeholders for "protected Source" is buttonless
config.toolbarGroups = [
{ name: 'styles' },
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', /*'indent', */'blocks', 'align', 'bidi' ] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
{ name: 'others' },
{ name: 'mediaembed' },
{ name: 'tools' },
{ name: 'about' }
];
};

View File

@ -1,200 +1,3 @@
/**
* @fileOverview A Serendipity custom CKEDITOR additional plugin creator file: ckeditor_custom_plugin.js, v. 1.0, 2014-03-15, Ian
*/
/**
* Get the instance ready event and set global instance var
* This is read by serendipity_editor.js(.tpl) and in case of serendipity_html_nugget_plugin by below serendipity_imageSelector_addToBody()
*/
CKEDITOR.on( 'instanceReady', function( event ) {
event.editor.on( 'focus', function() {
isinstance = this;
});
});
/**
* Create a prototyp foreach array function
* This is faster than using ckeditor.js internal forEach() implementation or even using plain for()
*/
if (!Array.prototype.forEach) {
Array.prototype.forEach = function (fn, scope) {
'use strict';
var i, len;
for (i = 0, len = this.length; i < len; ++i) {
if (i in this) {
fn.call(scope, this[i], i, this);
}
}
};
}
/**
* ExecutionCommand string replacement function
* Used in CKEDITOR.plugins.add(), to get ready to execute (eval) the button command passed by Serendipity plugins
* @param string string
* @return string string
*/
function ecfit(str) {
str = str.replace('function() { ', '');
str = str.replace(' }', '');
str = str.replace(CKEDITOR_S9Y_BASEURL, '');
return str;
}
/**
* This was previously a nugget only area, spawned by head! (textareas of staticpage nuggets, html nugget plugins, etc.)
* called via Spawnnugget(), set by real plugins like staticpages and cores functions_plugins_admin.inc in case of $ev['skip_nuggets'] === false
*
* NOW it is used by all textareas!
*
* @param string $eventData['item']
* @param string $eventData['jsname']
* @param array/object jsEventData/json_encode($eventData['buttons'])
*/
function Spawnnuggets(item, addEP, jsED) {
if (!item) var item = null;
if (!addEP) var addEP = null;
if (!jsED) var jsED = null;
var textarea_instance = !isNaN(item) ? 'nuggets' + item : item;
var name_extraPlugins = (addEP !== null) ? addEP : textarea_instance;
var jsEventData = (jsED !== null) ? jsED : window.jsEventData; // global set by 'backend_wysiwyg_finish' hook
var extraPluginList = name_extraPlugins+',mediaembed,procurator'; // no spaces allowed!
if (document.getElementById(textarea_instance)) {
CKEDITOR.replace(textarea_instance, {
// Load our specific configuration file.
customConfig : CKEDITOR_CCPATHFILE+'ckeditor_custom_config.js',
// or do and set
// Reset toolbar Groups settings
// toolbarGroups: null
// or any other configuration option here
// uiColor : '#AADC6E', // light green example
// language: 'fr', // default lang set example for french
// set all plugins at once - no spaces allowed!
extraPlugins: extraPluginList,
// Set the startup mode view [OK]
// startupMode: 'source',
// listen on load - do I need this still? YES!!!
on: {
loaded: function( evt ) {
var editor = evt.editor,
rules = {
elements: {
mediainsert: function( element ) {
// XHTML output instead of HTML - but this does not react on trailing slash eg <media "blah" />
// editor.dataProcessor.writer.selfClosingEnd = ' />';
//avoid line breaks with special block elements
var tags = ['mediainsert', 'gallery', 'media'];
for (var key in tags) {
editor.dataProcessor.writer.setRules(tags[key],
{
// Indicates that this tag causes indentation on line breaks inside of it.
indent : true,
// Inserts a line break before the element opening tag.
breakBeforeOpen : true,
// Inserts a line break after the element opening tag.
breakAfterOpen : false,
// Inserts a line break before the element closing tag.
breakBeforeClose : true,
// Inserts a line break after the element closing tag.
breakAfterClose : false
});
}
},
// Output dimensions of w/h images, since we either need an unchanged MediaLibrary image code for responsive templates or tweak some replacements!
img: function( element ) {
var style = element.attributes.style;
if ( style )
{
// Get the height from the style.
var match = /(?:^|\s)height\s*:\s*(\d+)px/i.exec( style );
var height = match && match[1];
if ( height )
{
element.attributes.style = element.attributes.style.replace( /(?:^|\s)height\s*:\s*(\d+)px;?/i , '' );
//element.attributes.height = height;
// Do not add to element attribute height, since then the height will be automatically (re-) added to style again by ckeditor or image js
// The current result is now: img alt class src style{width}. That is the only working state to get arround this issue in a relative simple way!
// Remember: Turning ACF OFF, will leave code alone, but still removes the height="" attribute! (workaround in extraAllowedContent added img[height]!)
}
}
}
}
};
// It's good to set both filters - dataFilter is used when loading data and htmlFilter when retrieving.
editor.dataProcessor.htmlFilter.addRules( rules );
editor.dataProcessor.dataFilter.addRules( rules );
}
}
});
CKEDITOR.plugins.add(name_extraPlugins, {
init: function(editor) {
if(typeof jsEventData !== 'undefined') {
jsEventData.forEach( function(k, i) {
var execcom = ecfit(jsEventData[i].javascript);
editor.addCommand( jsEventData[i].id, {
exec: function( editor ) {
eval(execcom); // [OK] only way this code is executable
}
});
editor.ui.addButton(jsEventData[i].id, {
label: jsEventData[i].name,
title: jsEventData[i].name+' Plugin',
icon: CKEDITOR_S9YPLUGPATH+jsEventData[i].img_path,
iconName: jsEventData[i].id+'_icon',
command: jsEventData[i].id
});
});
}
editor.addCommand( 'openML', {
exec : function( editor ) {
serendipity.openPopup('serendipity_admin.php?serendipity[adminModule]=media&serendipity[noBanner]=true&serendipity[noSidebar]=true&serendipity[noFooter]=true&serendipity[showMediaToolbar]=false&serendipity[showUpload]=true&serendipity[textarea]={$item}');
//window.open('serendipity_admin_image_selector.php', 'ImageSel', 'width=800,height=600,toolbar=no,scrollbars=1,scrollbars,resize=1,resizable=1');
}
});
editor.ui.addButton('openML', {
label: 'S9yMedia',
title: 'Serendipity Media Library',
icon: CKEDITOR_CCIMGPATH,
iconName: 'openML_icon',
command: 'openML'
});
}
});
}
}
/**
* Clone an old serendipity_editor.js function, to avoid a
* TypeError: (parent.)self.opener.serendipity_imageSelector_addToBody is not a function
* in case of serendipity_html_nugget_plugin textarea (nuggets3) usage
* and other popup function using plugins, like linktrimmer and amazonchooser
*/
function serendipity_imageSelector_addToBody (str, textarea) {
var oEditor = isinstance;
if (oEditor.mode == "wysiwyg") {
oEditor.insertHtml(str);
}
}
/*
var serendipity = {}; // define the namespace
serendipity.serendipity_imageSelector_addToBody = function(str, textarea) {
var oEditor = isinstance;
if (oEditor.mode == "wysiwyg") {
oEditor.insertHtml(str);
}
return;
}
*/

View File

@ -183,23 +183,13 @@ function serendipity_emit_htmlarea_code($item, $jsname, $spawnMulti = false) {
$backend_wysiwyg = true;
}
//actually we don't even need this any more...
if (is_array($eventData['buttons'])) {
foreach($eventData['buttons'] as $button) {
$toolbar['other'][] = $button;
break;
}
}
$data = array();
$data['init'] = $init;
$data['spawnMulti'] = $spawnMulti;
$data['jsname'] = $jsname;
$data['eventData'] = $eventData;
$data['item'] = $item;
$data['toolbar'] = $toolbar;
$data['backend_wysiwyg'] = $backend_wysiwyg ? $backend_wysiwyg : false;
$data['jsEventData'] = 'jsEventData = '.json_encode($eventData['buttons']);
echo serendipity_smarty_show('admin/wysiwyg_init.tpl', $data);
}

View File

@ -85,50 +85,6 @@ function create(htmlStr) {
}
break;
case 'backend_wysiwyg':
if (preg_match('@^nugget@i', $eventData['item'])) {
// switch to wysiwyg finisher directly, in case of nuggets
serendipity_plugin_api::hook_event('backend_wysiwyg_finish', $bag, $eventData);
} else {
// this only builds textareas of normal entry forms, the possible button data will be passed to 'backend_footer' via serendipity_emit_htmlarea_code() function
if (isset($eventData['item']) && !empty($eventData['item'])) {
?>
<script type="text/javascript">
$( document ).ready(function() {
if (window.Spawnnuggets) Spawnnuggets('<?php echo $eventData['item']; ?>', 'entryforms<?php echo $eventData['jsname']; ?>', null);//case1
});
</script>
<?php
}
}
break;
case 'backend_wysiwyg_finish':
// pass nugget $eventData['item'] and $eventData['buttons'] into the 'backend_footer' hook
serendipity_plugin_api::hook_event('backend_footer', $bag, $eventData);
break;
case 'backend_footer':
if ($serendipity['wysiwyg']) {
if (isset($eventData['item']) && !empty($eventData['item'])) {
if (isset($eventData['buttons']) && (is_array($eventData['buttons']) && !empty($eventData['buttons']))) {
// case staticpage nuggets - pulled by if (window.Spawnnuggets) Spawnnuggets(n);
?>
<script type="text/javascript">
$( document ).ready(function() {
jsEventData = <?php echo json_encode($eventData['buttons']); ?>;//case2
});
</script>
<?php
}
}
}
break;
return true;
break;
}

View File

@ -167,17 +167,6 @@
{/if}
{if $admin_vars.admin_installed}{serendipity_hookPlugin hook="backend_footer" hookAll="true"}{/if}
{if $backend_wysiwyg}
{* CKEDITOR_CCPATHFILE could also be a custom path to a templates ckekeditor_custom_config.js file *}
<script type="text/javascript">
CKEDITOR_CCPATHFILE = '{$serendipityHTTPPath}htmlarea/';
CKEDITOR_CCIMGPATH = '{$serendipityHTTPPath}templates/2k11/admin/img/thumbnail.png';
CKEDITOR_S9YPLUGPATH = '{$serendipityHTTPPath}plugins/';
CKEDITOR_S9Y_BASEURL = '{$serendipityHTTPPath}';
</script>
<script src="{$serendipityHTTPPath}htmlarea/ckeditor/ckeditor.js"></script>
<script src="{$serendipityHTTPPath}htmlarea/ckeditor_custom_plugin.js"></script>
{/if}
</body>
</html>

View File

@ -50,18 +50,4 @@
{/if}
{if $spawnNuggets}
{serendipity_hookPlugin hook="backend_wysiwyg_nuggets" eventData=$ev hookAll=true}
{if $ev['skip_nuggets'] === false}
<script type="text/javascript">
function Spawnnugget() {
{foreach $ev['nuggets'] AS $nuggetid}
if (window.Spawnnuggets) Spawnnuggets('{$nuggetid}');//case3{* plugin nuggets via function serendipity_plugin_config() eg side html nuggets *}
{/foreach}
}
</script>
{/if}
{/if}

View File

@ -1,4 +1,40 @@
{* this is build for normal backend entry (body/extended) textareas in function serendipity_emit_htmlarea_code() *}
<script type="text/javascript">
{$jsEventData};{* do not use $('document').ready(function() here, since needs to happen when set *}
{if $init == false}
<script src="{$serendipityHTTPPath}htmlarea/ckeditor/ckeditor.js"></script>
<script src="{$serendipityHTTPPath}htmlarea/ckeditor_custom_plugin.js"></script>
{/if}
<script>
$('document').ready(function() {
CKEDITOR.plugins.add('s9y_medialibrary{$item}', {
init: function( editor ) {
editor.addCommand( 'openML', {
exec : function( editor ) {
serendipity.openPopup('serendipity_admin.php?serendipity[adminModule]=media&serendipity[noBanner]=true&serendipity[noSidebar]=true&serendipity[noFooter]=true&serendipity[showMediaToolbar]=false&serendipity[showUpload]=true&serendipity[textarea]={$item}');
}
});
editor.ui.addButton('s9y_medialibrary{$item}', {
label: 'Media',
command: 'openML',
icon: '{serendipity_getFile file="admin/img/thumbnail.png"}'
});
}
});
CKEDITOR.replace($('#'+serendipity.escapeBrackets('{$item}')).get(0), {
customConfig : '{$serendipityHTTPPath}htmlarea/ckeditor_custom_config.js',
extraPlugins : 's9y_medialibrary{$item}',
toolbar: [
{ name: 'tools', items: [ 'Maximize' ] },
{ name: 'styles', items: [ 'Format' ] },
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'RemoveFormat' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote' ] },
{ name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
{ name: 'insert', items: [ 'Image', 's9y_medialibrary{$item}', 'Table', 'HorizontalRule', 'SpecialChar' ] },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', '-', 'Undo', 'Redo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Scayt' ] },
{ name: 'others', items: [ '-' ] },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source' ] },
{ name: 'about', items: [ 'About' ] }
]
});
});
</script>