(function($) { /** * Initialize editor instances. * * This function needs to be called before the page is fully loaded, as * calling tinyMCE.init() after the page is loaded breaks IE6. * * @param editorSettings * An object containing editor settings for each input format. */ Drupal.wysiwyg.editor.init.tinymce = function(settings) { // If JS compression is enabled, TinyMCE is unable to autodetect its global // settinge, hence we need to define them manually. // @todo Move global library settings somewhere else. tinyMCE.baseURL = settings.global.editorBasePath; tinyMCE.srcMode = (settings.global.execMode == 'src' ? '_src' : ''); tinyMCE.gzipMode = (settings.global.execMode == 'gzip'); // Initialize editor configurations. for (var format in settings) { if (format == 'global') { continue; } tinyMCE.init(settings[format]); if (Drupal.settings.wysiwyg.plugins[format]) { // Load native external plugins. // Array syntax required; 'native' is a predefined token in JavaScript. for (var plugin in Drupal.settings.wysiwyg.plugins[format]['native']) { tinyMCE.loadPlugin(plugin, Drupal.settings.wysiwyg.plugins[format]['native'][plugin]); } // Load Drupal plugins. for (var plugin in Drupal.settings.wysiwyg.plugins[format].drupal) { Drupal.wysiwyg.editor.instance.tinymce.addPlugin(plugin, Drupal.settings.wysiwyg.plugins[format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin]); } } } }; /** * Attach this editor to a target element. * * See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook. */ Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) { // Configure editor settings for this input format. for (var setting in settings) { tinyMCE.settings[setting] = settings[setting]; } // Remove TinyMCE's internal mceItem class, which was incorrectly added to // submitted content by Wysiwyg <2.1. TinyMCE only temporarily adds the class // for placeholder elements. If preemptively set, the class prevents (native) // editor plugins from gaining an active state, so we have to manually remove // it prior to attaching the editor. This is done on the client-side instead // of the server-side, as Wysiwyg has no way to figure out where content is // stored, and the class only affects editing. $field = $('#' + params.field); $field.val($field.val().replace(/(<.+?\s+class=['"][\w\s]*?)\bmceItem\b([\w\s]*?['"].*?>)/ig, '$1$2')); // Attach editor. tinyMCE.execCommand('mceAddControl', true, params.field); }; /** * Detach a single or all editors. * * See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook. */ Drupal.wysiwyg.editor.detach.tinymce = function(context, params) { if (typeof params != 'undefined') { tinyMCE.removeMCEControl(tinyMCE.getEditorId(params.field)); $('#' + params.field).removeAttr('style'); } // else if (tinyMCE.activeEditor) { // tinyMCE.triggerSave(); // tinyMCE.activeEditor.remove(); // } }; Drupal.wysiwyg.editor.instance.tinymce = { addPlugin: function(plugin, settings, pluginSettings) { if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') { return; } tinyMCE.addPlugin(plugin, { // Register an editor command for this plugin, invoked by the plugin's button. execCommand: function(editor_id, element, command, user_interface, value) { switch (command) { case plugin: if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') { var ed = tinyMCE.getInstanceById(editor_id); var data = { format: 'html', node: ed.getFocusElement(), content: ed.getFocusElement() }; Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, ed.formTargetElementId); return true; } } // Pass to next handler in chain. return false; }, // Register the plugin button. getControlHTML: function(control_name) { switch (control_name) { case plugin: return tinyMCE.getButtonHTML(control_name, settings.iconTitle, settings.icon, plugin); } return ''; }, // Load custom CSS for editor contents on startup. initInstance: function(ed) { if (settings.css) { tinyMCE.importCSS(ed.getDoc(), settings.css); } }, cleanup: function(type, content) { switch (type) { case 'insert_to_editor': // Attach: Replace plain text with HTML representations. if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') { content = Drupal.wysiwyg.plugins[plugin].attach(content, pluginSettings, tinyMCE.selectedInstance.editorId); content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(content); } break; case 'get_from_editor': // Detach: Replace HTML representations with plain text. if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') { content = Drupal.wysiwyg.plugins[plugin].detach(content, pluginSettings, tinyMCE.selectedInstance.editorId); } break; } // Pass through to next handler in chain return content; }, // isNode: Return whether the plugin button should be enabled for the // current selection. handleNodeChange: function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { if (node === null) { return; } if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') { if (Drupal.wysiwyg.plugins[plugin].isNode(node)) { tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonSelected'); return true; } } tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonNormal'); return true; }, /** * Return information about the plugin as a name/value array. */ getInfo: function() { return { longname: settings.title }; } }); }, openDialog: function(dialog, params) { var editor = tinyMCE.getInstanceById(this.field); tinyMCE.openWindow({ file: dialog.url + '/' + this.field, width: dialog.width, height: dialog.height, inline: 1 }, params); }, closeDialog: function(dialog) { var editor = tinyMCE.getInstanceById(this.field); tinyMCEPopup.close(); }, prepareContent: function(content) { // Certain content elements need to have additional DOM properties applied // to prevent this editor from highlighting an internal button in addition // to the button of a Drupal plugin. var specialProperties = { img: { 'name': 'mce_drupal' } }; var $content = $('
' + content + '
'); // No .outerHTML() in jQuery :( jQuery.each(specialProperties, function(element, properties) { $content.find(element).each(function() { for (var property in properties) { if (property == 'class') { $(this).addClass(properties[property]); } else { $(this).attr(property, properties[property]); } } }); }); return $content.html(); }, insert: function(content) { content = this.prepareContent(content); var editor = tinyMCE.getInstanceById(this.field); editor.execCommand('mceInsertContent', false, content); editor.repaint(); } }; })(jQuery);