/* (c) Copyright by authors of the Tiki Wiki CMS Groupware Project * * All Rights Reserved. See copyright.txt for details and a complete list of authors. * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. * $Id$ * * Tiki plugin integration plugin. * * Based on ckeditor flash plugin */ (function() { var protectTikiPluginsRegexp = /<(?:div|span)[^>]*data-syntax="([^"]*)"[\s\S]*?end tiki_plugin -->\s*?<\/(?:div|span)>/mig; CKEDITOR.plugins.add( 'tikiplugin', { init : function(editor) { var asplugin = this; editor.config.protectedSource.push( protectTikiPluginsRegexp ); this.command = new CKEDITOR.command( editor , { modes: { wysiwyg:1 }, canUndo: false }); editor.addCommand('tikiplugin', this.command); editor.commands.tikiplugin.exec = function(data) { // needs to be added after the command is added var sel = editor.getSelection(), r; // Selection will be unavailable after context menu shows up - in IE, lock it now. if ( CKEDITOR.env.ie ) { if (sel) { sel.lock(); } } if (data === editor) { r = sel.getRanges(); data = r[0].getEnclosedNode(); if (!data) { data = r[0].getCommonAncestor(); } } if (!data.hasClass("tiki_plugin")) { var pluginTemp = $(".tiki_plugin:first", data.$); if (pluginTemp.length) { data = new CKEDITOR.dom.element(pluginTemp[0]); } } while (!data.hasClass("tiki_plugin") && data.getParent()) { // try parents? data = data.getParent(); if (data.hasClass("tiki_plugin")) { break; } } if (!data.hasClass("tiki_plugin")) { // problem here - wrong element sent in? debugger; // intentionally left in to catch occasional IE edge cases return; } var args = {}; var str = data.data("args"); var pairs = str.split("&"); for (var i = 0; i < pairs.length; i++) { if (pairs[i].indexOf("=") > -1) { var val = pairs[i].substring((pairs[i].indexOf("=") + 1)); if (val.match(/^".*"$/)) { // strip off extra quotes val = val.substring(1, val.length - 1) } args[pairs[i].substring(0, pairs[i].indexOf("="))] = $('
').html(val).text(); // decode html entities; } } sel.selectElement( data ); popupPluginForm( editor.name, data.data("plugin"), 0, '', args, data.data("body"), ''); }; // override plugin and icon class (make visible and grey) CKEDITOR.addCss('.tiki_plugin .plugin_icon { display:block;position:absolute;z-index:1;}' + '.tiki_plugin { background-color: #eee; border: 1px solid #666;}'); // If the "menu" plugin is loaded, register the menu items. if (editor.addMenuItems) { editor.addMenuGroup("tiki", 999); editor.addMenuItems( { tikiplugin : { label : 'Tiki Plugin', command : 'tikiplugin', group : 'tiki', icon : CKEDITOR.config._TikiRoot + 'img/icons/plugin_edit.png' } }); // remove the built in image menu item editor.removeMenuItem('image'); } editor.on('contentDom', function() { // re-apply the events etc when wysiwyg mode happens $(".tiki_plugin", editor.document.$).each(function() { var parentPlugin = new CKEDITOR.dom.element(this); $(this).find("*").addBack().each(function(){ $(this).mousedown(function(){ var sel = editor.getSelection(); if (sel) { sel.selectElement(parentPlugin); } return false; }); //.attr("contenteditable", "false"); }); }); editor.on( 'doubleclick', function(evt) { var element = evt.data.element; element = asplugin.getPluginParent( element ); if (element) { evt.cancel(); evt.stop(); evt.data.dialog = null; //this.plugins.tikiplugin.command.exec(element); this.execCommand('tikiplugin', element); } }); }); // If the "contextmenu" plugin is loaded, register the listeners. if (editor.contextMenu) { editor.contextMenu.addListener(function(element, selection) { element = asplugin.getPluginParent( element ); if (element) { return { tikiplugin : CKEDITOR.TRISTATE_OFF }; } }); } if (jqueryTiki.autosave) { // pref check // changed for ckeditor4 - to check? if (typeof editor.plugins["tikiwiki"] === "undefined") { // also defined in tikiwiki plugin this.ckToHtml = editor.dataProcessor.toHtml; // reference to original ckeditor dataProcessor editor.dataProcessor.toHtml = function ( data, fixForBody ) { return asplugin.toHtmlFormat( editor, data, fixForBody ); }; this.ckToData = editor.dataProcessor.toDataFormat; editor.dataProcessor.toDataFormat = function ( html, fixForBody ) { return asplugin.toHTMLSource( editor, html, fixForBody ); }; } } }, // end of init() getPluginParent: function ( element ) { while (element && element.getParent()) { if (element.data('plugin')) { return element; } element = element.getParent(); } return null; }, toHTMLSource: function( editor, html, fixForBody ) { // de-protect ck_protected comments var output = html; output = this.ckToData.call( editor.dataProcessor, output, fixForBody ); output = output.replace(/<\/p>\n\n

\n\n$/g, "

"); if (typeof editor.plugins["tikiwiki"] === "undefined") { output = output.replace(/
([\s\S]*?)<\/pre>/ig, "$1");
            }
            // replace visual plugins with syntax
            output = output.replace( protectTikiPluginsRegexp, function() {
                if (arguments.length > 0) {
                    var plugCode = $("").html(arguments[1]).text();
                    if (typeof editor.plugins["tikiwiki"] !== "undefined") {    // also defined in tikiwiki plugin
                        plugCode = plugCode.replace(/\n/g, "
"); } return plugCode; // decode html entities } else { alert("ckeditor: error parsing to html source"); return ""; } }); output = output.replace(/\s*

[\s]*<\/p>\s*/mgi, ""); // strip out empty

tags return output; }, toHtmlFormat: function( editor, data, fixForBody ) { if (!jqueryTiki.autosave) { alert(tr("AJAX Autosave preference not enabled. Please go to admin/features/interface to enable it.")); } if (typeof editor.pluginReparsing !== "undefined" && editor.pluginReparsing) { editor.pluginReparsing = false; return data; } var output = ""; var asplugin = this; var orig_data = $("#editwiki").val(); // just in case var isHtml = auto_save_allowHtml(editor.element.$.form); ajaxLoadingShow( "cke_contents_" + editor.name); $("#ajaxLoading").show(); // FIXME safari/chrome refuse to show until ajax finished jQuery.ajax({ async: false, // wait for this one url: $.service("edit", "tohtml"), type: "POST", dataType: "json", data: { referer: editor.config.autoSaveSelf, editor_id: editor.name, data: data, allowhtml: isHtml }, // good callback success: function(data) { ajaxLoadingHide(); output = data.data; output = asplugin.ckToHtml.call(editor.dataProcessor, output, fixForBody); if (output.indexOf("") === -1 && output.indexOf(" -1) { alert("Is this code still needed? (tikiplugin/plugin.js line 223)"); output += ""; // workaround for cke 3.4 / tiki 6.0 FIXME } }, // bad callback - no good info in the params :( error: function(req, status, error) { ajaxLoadingHide(); output = orig_data; //"ajax error"; alert(tr("AJAX Error") + "\n" + tr("It may not be possible to edit this page reliably in WYSIWYG mode in this browser.") + "\n\n" + error.message); } }); return output; }, requires : [ '' ] // TODO check req - autosave? (really) }); if (typeof CKEDITOR.editor.prototype.reParse != 'function') { CKEDITOR.editor.prototype.pluginReparsing = false; CKEDITOR.editor.prototype.reParse = function() { // send the whole source off to the server to get reparsed? var myoutput = ""; var mydata = this.getData(); myoutput = this.dataProcessor.toHtml(mydata); this.pluginReparsing = true; this.setData(myoutput); }; } })();