diff --git a/editors/js/tinymce-4.js b/editors/js/tinymce-4.js new file mode 100644 index 0000000..45e95b6 --- /dev/null +++ b/editors/js/tinymce-4.js @@ -0,0 +1,234 @@ +(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) { + tinymce.on('active focus', function(e) { + Drupal.wysiwyg.activeId = e.editor.id; + }); + // Fix Drupal toolbar obscuring editor toolbar in fullscreen mode. + var $drupalToolbars = $('#toolbar, #admin-menu', Drupal.overlayChild ? window.parent.document : document); + tinymce.on('AddEditor', function (e) { + e.editor.on('FullscreenStateChanged', function (e) { + if (e.state) { + $drupalToolbars.hide(); + } + else { + $drupalToolbars.show(); + } + }); + }); + + // Initialize editor configurations. + for (var format in settings) { + 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); + + // 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(); + settings.selector = '#' + params.field; + tinymce.init(settings); +}; + +/** + * 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, trigger) { + if (typeof params != 'undefined') { + var instance = tinymce.get(params.field); + if (instance) { + instance.save(); + if (trigger != 'serialize') { + instance.remove(); + } + } + } + else { + // Save contents of all editors back into textareas. + tinymce.triggerSave(); + if (trigger != 'serialize') { + // 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; + } + + // Register plugin. + tinymce.PluginManager.add('drupal_' + plugin, function (editor) { + var button = { + title : settings.iconTitle, + image : settings.icon, + onPostRender : function() { + var self = this; + editor.on('nodeChange', function (e) { + // isNode: Return whether the plugin button should be enabled for the + // current selection. + if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') { + self.active(Drupal.wysiwyg.plugins[plugin].isNode(e.element)); + } + }); + } + } + if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') { + button.onclick = function() { + var data = { format: 'html', node: editor.selection.getNode(), content: editor.selection.getContent() }; + // TinyMCE creates a completely new instance for fullscreen mode. + Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, editor.id); + } + } + + // Register the plugin button. + editor.addButton('drupal_' + plugin, button); + /** + * 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. + var editorId = (e.target.id == 'mce_fullscreen' ? e.target.getParam('fullscreen_editor_id') : e.target.id); + */ + editor.on('init', function(e) { + // Load custom CSS for editor contents on startup. + if (settings.css) { + editor.dom.loadCSS(settings.css); + } + + }); + + // Attach: Replace plain text with HTML representations. + editor.on('beforeSetContent', function(e) { + if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') { + e.content = Drupal.wysiwyg.plugins[plugin].attach(e.content, pluginSettings, e.target.id); + e.content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(e.content); + } + }); + + // Detach: Replace HTML representations with plain text. + editor.on('getContent', function(e) { + var editorId = (e.target.id == 'mce_fullscreen' ? e.target.getParam('fullscreen_editor_id') : e.target.id); + if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') { + e.content = Drupal.wysiwyg.plugins[plugin].detach(e.content, pluginSettings, editorId); + } + }); + }); + }, + + openDialog: function(dialog, params) { + var instanceId = this.getInstanceId(); + 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 editor = tinymce.get(this.getInstanceId()); + 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 = $('
body > table > tr > td
).') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_statusbar_location', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_statusbar_location'))),
- );
+ if (version_compare($version, '3.3', '>=')) {
+ $default_settings['style_formats'] = '';
+ };
+ if (version_compare($version, '4', '<')) {
+ $default_settings += array(
+ 'apply_source_formatting' => FALSE,
+ 'paste_auto_cleanup_on_paste' => TRUE,
+ 'preformatted' => FALSE,
+ 'remove_linebreaks' => TRUE,
+ // Also available, but buggy in TinyMCE 2.x: blockquote,code,dt,dd,samp.
+ 'theme_advanced_blockformats' => 'p,address,pre,h2,h3,h4,h5,h6,div',
+ 'theme_advanced_styles' => '',
+ 'theme_advanced_statusbar_location' => 'bottom',
+ 'theme_advanced_resizing' => TRUE,
+ 'theme_advanced_styles' => '',
+ 'theme_advanced_toolbar_align' => 'left',
+ 'theme_advanced_toolbar_location' => 'top',
+ );
+ }
- $form['appearance']['theme_advanced_resizing'] = array(
- '#type' => 'checkbox',
- '#title' => t('Enable resizing button'),
- '#default_value' => $settings['theme_advanced_resizing'],
- '#return_value' => 1,
- '#description' => t('This option gives you the ability to enable/disable the resizing button. If enabled, the Path location toolbar must be set to "Top" or "Bottom" in order to display the resize icon.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_resizing', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_resizing'))),
- );
+ $settings += $default_settings;
$form['output']['verify_html'] = array(
'#type' => 'checkbox',
'#title' => t('Verify HTML'),
'#default_value' => $settings['verify_html'],
'#return_value' => 1,
- '#description' => t('If enabled, potentially malicious code like <HEAD>
tags will be removed from HTML contents.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'verify_html', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:preformatted'))),
- );
-
- $form['output']['preformatted'] = array(
- '#type' => 'checkbox',
- '#title' => t('Preformatted'),
- '#default_value' => $settings['preformatted'],
- '#return_value' => 1,
- '#description' => t('If enabled, the editor will insert TAB characters on tab and preserve other whitespace characters just like a PRE element in HTML does.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'preformatted', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:preformatted'))),
+ '#description' => t('If enabled, potentially malicious code like <HEAD>
tags will be removed from HTML contents.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'verify_html', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:verify_html'))),
);
$form['output']['convert_fonts_to_spans'] = array(
@@ -208,61 +195,131 @@ function wysiwyg_tinymce_settings_form(&$form, &$form_state) {
'@setting' => 'convert_fonts_to_spans', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:convert_fonts_to_spans'))),
);
- $form['output']['remove_linebreaks'] = array(
- '#type' => 'checkbox',
- '#title' => t('Remove linebreaks'),
- '#default_value' => $settings['remove_linebreaks'],
- '#return_value' => 1,
- '#description' => t('If enabled, the editor will remove most linebreaks from contents. Disabling this option could avoid conflicts with other input filters.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'remove_linebreaks', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:remove_linebreaks'))),
- );
+ if (version_compare($version, '4', '<')) {
+ $form['appearance']['theme_advanced_toolbar_location'] = array(
+ '#type' => 'select',
+ '#title' => t('Toolbar location'),
+ '#default_value' => $settings['theme_advanced_toolbar_location'],
+ '#options' => array('bottom' => t('Bottom'), 'top' => t('Top')),
+ '#description' => t('This option controls whether the editor toolbar is displayed above or below the editing area.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_toolbar_location', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_toolbar_location'))),
+ );
- $form['output']['apply_source_formatting'] = array(
- '#type' => 'checkbox',
- '#title' => t('Apply source formatting'),
- '#default_value' => $settings['apply_source_formatting'],
- '#return_value' => 1,
- '#description' => t('If enabled, the editor will re-format the HTML source code. Disabling this option could avoid conflicts with other input filters.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'apply_source_formatting', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:apply_source_formatting'))),
- );
+ $form['appearance']['theme_advanced_toolbar_align'] = array(
+ '#type' => 'select',
+ '#title' => t('Button alignment'),
+ '#default_value' => $settings['theme_advanced_toolbar_align'],
+ '#options' => array('center' => t('Center'), 'left' => t('Left'), 'right' => t('Right')),
+ '#description' => t('This option controls the alignment of icons in the editor toolbar.'),
+ );
- $form['css']['theme_advanced_styles'] = array(
- '#type' => 'textarea',
- '#title' => t('CSS classes'),
- '#default_value' => $settings['theme_advanced_styles'],
- '#description' => t('Optionally define CSS classes for the "Font style" dropdown list.[title]=[class]
',
- '!example' => 'My heading=header1',
- )
- ) . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_styles', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_styles'))),
- );
+ $form['appearance']['theme_advanced_statusbar_location'] = array(
+ '#type' => 'select',
+ '#title' => t('Path location'),
+ '#default_value' => $settings['theme_advanced_statusbar_location'],
+ '#options' => array('none' => t('Hide'), 'top' => t('Top'), 'bottom' => t('Bottom')),
+ '#description' => t('Where to display the path to HTML elements (i.e. body > table > tr > td
).') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_statusbar_location', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_statusbar_location'))),
+ );
+ $form['appearance']['theme_advanced_resizing'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Enable resizing button'),
+ '#default_value' => $settings['theme_advanced_resizing'],
+ '#return_value' => 1,
+ '#description' => t('This option gives you the ability to enable/disable the resizing button. If enabled, the Path location toolbar must be set to "Top" or "Bottom" in order to display the resize icon.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_resizing', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_resizing'))),
+ );
- $form['css']['theme_advanced_blockformats'] = array(
- '#type' => 'textfield',
- '#title' => t('Block formats'),
- '#default_value' => $settings['theme_advanced_blockformats'],
- '#size' => 40,
- '#maxlength' => 250,
- '#description' => t('Comma separated list of HTML block formats. Possible values: @format-list
.', array('@format-list' => 'p,h1,h2,h3,h4,h5,h6,div,blockquote,address,pre,code,dt,dd')) . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_blockformats', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_blockformats'))),
- '#element_validate' => array('wysiwyg_tinymce_settings_form_validate_blockformats'),
- );
+ $form['output']['remove_linebreaks'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Remove linebreaks'),
+ '#default_value' => $settings['remove_linebreaks'],
+ '#return_value' => 1,
+ '#description' => t('If enabled, the editor will remove most linebreaks from contents. Disabling this option could avoid conflicts with other input filters.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'remove_linebreaks', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:remove_linebreaks'))),
+ );
+
+ $form['output']['preformatted'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Preformatted'),
+ '#default_value' => $settings['preformatted'],
+ '#return_value' => 1,
+ '#description' => t('If enabled, the editor will insert TAB characters on tab and preserve other whitespace characters just like a PRE element in HTML does.') . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'preformatted', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:preformatted'))),
+ );
+
+ $form['css']['theme_advanced_blockformats'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Block formats'),
+ '#default_value' => $settings['theme_advanced_blockformats'],
+ '#size' => 40,
+ '#maxlength' => 250,
+ '#description' => t('Comma separated list of HTML block formats. Possible values: @format-list
.', array('@format-list' => 'p,h1,h2,h3,h4,h5,h6,div,blockquote,address,pre,code,dt,dd')) . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_blockformats', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_blockformats'))),
+ '#element_validate' => array('wysiwyg_tinymce_settings_form_validate_blockformats'),
+ );
+
+ $form['css']['theme_advanced_styles'] = array(
+ '#type' => 'textarea',
+ '#title' => t('CSS classes'),
+ '#default_value' => $settings['theme_advanced_styles'],
+ '#description' => t('Optionally define CSS classes for the "Font style" dropdown list.[title]=[class]
',
+ '!example' => 'My heading=header1',
+ )
+ ) . ' ' . t('Uses the @setting setting internally.', array('@setting' => 'theme_advanced_styles', '@url' => url('http://www.tinymce.com/wiki.php/Configuration3x:theme_advanced_styles'))),
+ );
+ }
+ if (version_compare($version, '3.3', '>=')) {
+ $link_url = url('http://www.tinymce.com/wiki.php/Configuration3x:style_formats');
+ if (version_compare($version, '4', '>=')) {
+ $form['css']['theme_advanced_styles']['#access'] = FALSE;
+ $link_url = url('http://www.tinymce.com/wiki.php/Configuration:style_formats');
+ }
+ else {
+ $form['css']['theme_advanced_styles']['#description'] .= '