123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- (function($) {
- /**
- * Initialize editor instances.
- *
- * @todo Is the following note still valid for 3.x?
- * 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.PluginManager.load(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.
- var ed = new tinymce.Editor(params.field, settings);
- // Reset active instance id on any event.
- ed.onEvent.add(function(ed, e) {
- Drupal.wysiwyg.activeId = ed.id;
- });
- // Make toolbar buttons wrappable (required for IE).
- ed.onPostRender.add(function (ed) {
- var $toolbar = $('<div class="wysiwygToolbar"></div>');
- $('#' + ed.editorContainer + ' table.mceToolbar > tbody > tr > td').each(function () {
- $('<div></div>').addClass(this.className).append($(this).children()).appendTo($toolbar);
- });
- $('#' + ed.editorContainer + ' table.mceLayout td.mceToolbar').append($toolbar);
- $('#' + ed.editorContainer + ' table.mceToolbar').remove();
- });
- // 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.
- ed.render();
- };
- /**
- * 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') {
- var instance = tinyMCE.get(params.field);
- if (instance) {
- instance.save();
- instance.remove();
- }
- }
- else {
- // Save contents of all editors back into textareas.
- tinyMCE.triggerSave();
- // Remove all editor instances.
- for (var instance in tinyMCE.editors) {
- tinyMCE.editors[instance].remove();
- }
- }
- };
- Drupal.wysiwyg.editor.instance.tinymce = {
- addPlugin: function(plugin, settings, pluginSettings) {
- if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
- return;
- }
- tinymce.create('tinymce.plugins.' + plugin, {
- /**
- * Initialize the plugin, executed after the plugin has been created.
- *
- * @param ed
- * The tinymce.Editor instance the plugin is initialized in.
- * @param url
- * The absolute URL of the plugin location.
- */
- init: function(ed, url) {
- // Register an editor command for this plugin, invoked by the plugin's button.
- ed.addCommand(plugin, function() {
- if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
- var data = { format: 'html', node: ed.selection.getNode(), content: ed.selection.getContent() };
- // TinyMCE creates a completely new instance for fullscreen mode.
- var instanceId = ed.id == 'mce_fullscreen' ? ed.getParam('fullscreen_editor_id') : ed.id;
- Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instanceId);
- }
- });
- // Register the plugin button.
- ed.addButton(plugin, {
- title : settings.iconTitle,
- cmd : plugin,
- image : settings.icon
- });
- // Load custom CSS for editor contents on startup.
- ed.onInit.add(function() {
- if (settings.css) {
- ed.dom.loadCSS(settings.css);
- }
- });
- // Attach: Replace plain text with HTML representations.
- ed.onBeforeSetContent.add(function(ed, data) {
- if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
- data.content = Drupal.wysiwyg.plugins[plugin].attach(data.content, pluginSettings, ed.id);
- data.content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(data.content);
- }
- });
- // Detach: Replace HTML representations with plain text.
- ed.onGetContent.add(function(ed, data) {
- if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
- data.content = Drupal.wysiwyg.plugins[plugin].detach(data.content, pluginSettings, ed.id);
- }
- });
- // isNode: Return whether the plugin button should be enabled for the
- // current selection.
- ed.onNodeChange.add(function(ed, command, node) {
- if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
- command.setActive(plugin, Drupal.wysiwyg.plugins[plugin].isNode(node));
- }
- });
- },
- /**
- * Return information about the plugin as a name/value array.
- */
- getInfo: function() {
- return {
- longname: settings.title
- };
- }
- });
- // Register plugin.
- tinymce.PluginManager.add(plugin, tinymce.plugins[plugin]);
- },
- openDialog: function(dialog, params) {
- var instanceId = this.isFullscreen() ? 'mce_fullscreen' : this.field;
- var editor = tinyMCE.get(instanceId);
- editor.windowManager.open({
- file: dialog.url + '/' + instanceId,
- width: dialog.width,
- height: dialog.height,
- inline: 1
- }, params);
- },
- closeDialog: function(dialog) {
- var instanceId = this.isFullscreen() ? 'mce_fullscreen' : this.field;
- var editor = tinyMCE.get(instanceId);
- editor.windowManager.close(dialog);
- },
- 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: { 'class': 'mceItem' }
- };
- var $content = $('<div>' + content + '</div>'); // No .outerHTML() in jQuery :(
- // Find all placeholder/replacement content of Drupal plugins.
- $content.find('.drupal-content').each(function() {
- // Recursively process DOM elements below this element to apply special
- // properties.
- var $drupalContent = $(this);
- $.each(specialProperties, function(element, properties) {
- $drupalContent.find(element).andSelf().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 instanceId = this.isFullscreen() ? 'mce_fullscreen' : this.field;
- tinyMCE.execInstanceCommand(instanceId, 'mceInsertContent', false, content);
- },
- isFullscreen: function() {
- // TinyMCE creates a completely new instance for fullscreen mode.
- return tinyMCE.activeEditor.id == 'mce_fullscreen' && tinyMCE.activeEditor.getParam('fullscreen_editor_id') == this.field;
- }
- };
- })(jQuery);
|