(function($) { /** * Attach this editor to a target element. */ Drupal.wysiwyg.editor.attach.fckeditor = function(context, params, settings) { var FCKinstance = new FCKeditor(params.field, settings.Width, settings.Height, settings.ToolbarSet); // Apply editor instance settings. FCKinstance.BasePath = settings.EditorPath; FCKinstance.Config.wysiwygFormat = params.format; FCKinstance.Config.CustomConfigurationsPath = settings.CustomConfigurationsPath; // Load Drupal plugins and apply format specific settings. // @see fckeditor.config.js // @see Drupal.wysiwyg.editor.instance.fckeditor.init() // Attach editor. FCKinstance.ReplaceTextarea(); }; /** * Detach a single or all editors. */ Drupal.wysiwyg.editor.detach.fckeditor = function(context, params) { var instances = []; if (typeof params != 'undefined' && typeof FCKeditorAPI != 'undefined') { var instance = FCKeditorAPI.GetInstance(params.field); if (instance) { instances[params.field] = instance; } } else { instances = FCKeditorAPI.__Instances; } for (var instanceName in instances) { var instance = instances[instanceName]; instance.UpdateLinkedField(); // Since we already detach the editor and update the textarea, the submit // event handler needs to be removed to prevent data loss (in IE). // FCKeditor uses 2 nested iFrames; instance.EditingArea.Window is the // deepest. Its parent is the iFrame containing the editor. var instanceScope = instance.EditingArea.Window.parent; instanceScope.FCKTools.RemoveEventListener(instance.GetParentForm(), 'submit', instance.UpdateLinkedField); // Run cleanups before forcing an unload of the iFrames or IE crashes. // This also deletes the instance from the FCKeditorAPI.__Instances array. instanceScope.FCKTools.RemoveEventListener(instanceScope, 'unload', instanceScope.FCKeditorAPI_Cleanup); instanceScope.FCKTools.RemoveEventListener(instanceScope, 'beforeunload', instanceScope.FCKeditorAPI_ConfirmCleanup); if (jQuery.isFunction(instanceScope.FCKIECleanup_Cleanup)) { instanceScope.FCKIECleanup_Cleanup(); } instanceScope.FCKeditorAPI_ConfirmCleanup(); instanceScope.FCKeditorAPI_Cleanup(); // Remove the editor elements. $('#' + instanceName + '___Config').remove(); $('#' + instanceName + '___Frame').remove(); $('#' + instanceName).show(); } }; Drupal.wysiwyg.editor.instance.fckeditor = { init: function(instance) { // Track which editor instance is active. instance.FCK.Events.AttachEvent('OnFocus', function(editorInstance) { Drupal.wysiwyg.activeId = editorInstance.Name; }); // Create a custom data processor to wrap the default one and allow Drupal // plugins modify the editor contents. var wysiwygDataProcessor = function() {}; wysiwygDataProcessor.prototype = new instance.FCKDataProcessor(); // Attach: Convert text into HTML. wysiwygDataProcessor.prototype.ConvertToHtml = function(data) { // Called from SetData() with stripped comments/scripts, revert those // manipulations and attach Drupal plugins. var data = instance.FCKConfig.ProtectedSource.Revert(data); if (Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat] && Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) { for (var plugin in Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) { if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') { data = Drupal.wysiwyg.plugins[plugin].attach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], instance.FCK.Name); data = Drupal.wysiwyg.editor.instance.fckeditor.prepareContent(data); } } } // Re-protect the source and use the original data processor to convert it // into XHTML. data = instance.FCKConfig.ProtectedSource.Protect(data); return instance.FCKDataProcessor.prototype.ConvertToHtml.call(this, data); }; // Detach: Convert HTML into text. wysiwygDataProcessor.prototype.ConvertToDataFormat = function(rootNode, excludeRoot, ignoreIfEmptyParagraph, format) { // Called from GetData(), convert the content's DOM into a XHTML string // using the original data processor and detach Drupal plugins. var data = instance.FCKDataProcessor.prototype.ConvertToDataFormat.call(this, rootNode, excludeRoot, ignoreIfEmptyParagraph, format); if (Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat] && Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) { for (var plugin in Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) { if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') { data = Drupal.wysiwyg.plugins[plugin].detach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], instance.FCK.Name); } } } return data; }; instance.FCK.DataProcessor = new wysiwygDataProcessor(); }, addPlugin: function(plugin, settings, pluginSettings, instance) { if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') { return; } if (Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal[plugin].css) { instance.FCKConfig.EditorAreaCSS += ',' + Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal[plugin].css; } // @see fckcommands.js, fck_othercommands.js, fckpastewordcommand.js instance.FCKCommands.RegisterCommand(plugin, { // Invoke the plugin's button. Execute: function () { if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') { var data = { format: 'html', node: instance.FCKSelection.GetParentElement() }; // @todo This is NOT the same as data.node. data.content = data.node.innerHTML; Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instance.FCK.Name); } }, // isNode: Return whether the plugin button should be enabled for the // current selection. // @see FCKUnlinkCommand.prototype.GetState() GetState: function () { // Always disabled if not in WYSIWYG mode. if (instance.FCK.EditMode != FCK_EDITMODE_WYSIWYG) { return FCK_TRISTATE_DISABLED; } var state = instance.FCK.GetNamedCommandState(this.Name); // FCKeditor sets the wrong state in WebKit browsers. if (!$.support.queryCommandEnabled && state == FCK_TRISTATE_DISABLED) { state = FCK_TRISTATE_OFF; } if (state == FCK_TRISTATE_OFF && instance.FCK.EditMode == FCK_EDITMODE_WYSIWYG) { if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') { var node = instance.FCKSelection.GetSelectedElement(); state = Drupal.wysiwyg.plugins[plugin].isNode(node) ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF; } } return state; }, /** * Return information about the plugin as a name/value array. */ Name: plugin }); // Register the plugin button. // Arguments: commandName, label, tooltip, style, sourceView, contextSensitive, icon. instance.FCKToolbarItems.RegisterItem(plugin, new instance.FCKToolbarButton(plugin, settings.iconTitle, settings.iconTitle, null, false, true, settings.icon)); }, openDialog: function(dialog, params) { // @todo Implement open dialog. }, closeDialog: function(dialog) { // @todo Implement close dialog. }, prepareContent: function(content) { // @todo Not needed for FCKeditor? return content; }, insert: function(content) { var instance = FCKeditorAPI.GetInstance(this.field); // @see FCK.InsertHtml(), FCK.InsertElement() instance.InsertHtml(content); } }; })(jQuery);