236 lines
8.6 KiB
JavaScript
236 lines
8.6 KiB
JavaScript
(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);
|