View source
<?php
require_once dirname(__FILE__) . '/includes/tinymce.wysiwyg.inc';
define('TINYMCE_VERSION', '4.0.2');
function tinymce_editor_info() {
$editors['tinymce'] = array(
'label' => t('TinyMCE'),
'library' => array(
'tinymce',
'drupal.tinymce',
),
'default settings' => array(
'toolbar' => array(
array(
'Source',
'|',
'Bold',
'Italic',
'|',
'NumberedList',
'BulletedList',
'Blockquote',
'|',
'JustifyLeft',
'JustifyCenter',
'JustifyRight',
'|',
'Link',
'Unlink',
'|',
'Image',
'Maximize',
),
),
'format_list' => array(
'p',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
),
'style_list' => array(),
),
'settings callback' => 'tinymce_settings_form',
'js settings callback' => 'tinymce_add_settings',
);
return $editors;
}
function tinymce_library() {
$module_path = drupal_get_path('module', 'tinymce');
$libraries['drupal.tinymce.admin'] = array(
'title' => 'Drupal behavior to enable TinyMCE on textareas.',
'version' => VERSION,
'js' => array(
$module_path . '/js/tinymce.admin.js' => array(),
),
'css' => array(
$module_path . '/css/tinymce.admin.css' => array(),
),
'dependencies' => array(
array(
'system',
'jquery.once',
),
array(
'system',
'ui.sortable',
),
array(
'system',
'ui.draggable',
),
),
);
$libraries['tinymce'] = array(
'title' => 'Loads the main TinyMCE library.',
'version' => TINYMCE_VERSION,
'js' => array(
$module_path . '/lib/tinymce/tinymce.js' => array(),
),
);
return $libraries;
}
function tinymce_theme() {
return array(
'tinymce_settings_toolbar' => array(
'variables' => array(
'editor' => NULL,
'plugins' => NULL,
),
),
);
}
function tinymce_init() {
drupal_add_css(drupal_get_path('module', 'tinymce') . '/css/tinymce.css');
$settings = array(
'tinymce' => array(
'modulePath' => drupal_get_path('module', 'tinymce'),
),
);
drupal_add_js($settings, array(
'type' => 'setting',
));
}
function tinymce_plugins() {
$plugins = module_invoke_all('tinymce_plugins');
drupal_alter('tinymce_plugins', $plugins);
return $plugins;
}
function tinymce_tinymce_plugins() {
$image_prefix = drupal_get_path('module', 'tinymce') . '/images/buttons/';
$buttons = array(
'Bold' => array(
'label' => t('Bold'),
'required_tags' => array(
'strong',
),
),
'Italic' => array(
'label' => t('Italic'),
'required_tags' => array(
'em',
),
),
'Underline' => array(
'label' => t('Underline'),
'required_tags' => array(
'span',
),
),
'Strike' => array(
'label' => t('Strike-through'),
'required_tags' => array(
'del',
),
),
'JustifyLeft' => array(
'label' => t('Align left'),
'required_tags' => array(
'p',
),
),
'JustifyCenter' => array(
'label' => t('Align center'),
'required_tags' => array(
'p',
),
),
'JustifyRight' => array(
'label' => t('Align right'),
'required_tags' => array(
'p',
),
),
'JustifyBlock' => array(
'label' => t('Justify'),
'required_tags' => array(
'p',
),
),
'BulletedList' => array(
'label' => t('Bullet list'),
'image_rtl' => $image_prefix . '/bulletedlist-rtl.png',
'required_tags' => array(
'ul',
'li',
),
),
'NumberedList' => array(
'label' => t('Numbered list'),
'image_rtl' => $image_prefix . '/numberedlist-rtl.png',
'required_tags' => array(
'ol',
'li',
),
),
'Outdent' => array(
'label' => t('Outdent'),
'image_rtl' => $image_prefix . '/outdent-rtl.png',
'required_tags' => array(
'p',
),
),
'Indent' => array(
'label' => t('Indent'),
'image_rtl' => $image_prefix . '/indent-rtl.png',
'required_tags' => array(
'p',
),
),
'Undo' => array(
'label' => t('Undo'),
'image_rtl' => $image_prefix . '/undo-rtl.png',
),
'Redo' => array(
'label' => t('Redo'),
'image_rtl' => $image_prefix . '/redo-rtl.png',
),
'Link' => array(
'label' => t('Link'),
'required_tags' => array(
'a',
),
),
'Unlink' => array(
'label' => t('Unlink'),
'required_tags' => array(
'a',
),
),
'Anchor' => array(
'image_rtl' => $image_prefix . '/anchor-rtl.png',
'label' => t('Anchor'),
'required_tags' => array(
'a',
),
),
'Superscript' => array(
'label' => t('Superscript'),
'required_tags' => array(
'sub',
),
),
'Subscript' => array(
'label' => t('Subscript'),
'required_tags' => array(
'sup',
),
),
'Blockquote' => array(
'label' => t('Blockquote'),
'required_tags' => array(
'blockquote',
),
),
'Source' => array(
'label' => t('Source code'),
),
'HorizontalRule' => array(
'label' => t('Horizontal rule'),
'required_tags' => array(
'hr',
),
),
'Cut' => array(
'label' => t('Cut'),
),
'Copy' => array(
'label' => t('Copy'),
),
'Paste' => array(
'label' => t('Paste'),
),
'PasteText' => array(
'label' => t('Paste Text'),
'image_rtl' => $image_prefix . '/pastetext-rtl.png',
),
'PasteFromWord' => array(
'label' => t('Paste from Word'),
'image_rtl' => $image_prefix . '/pastefromword-rtl.png',
),
'ShowBlocks' => array(
'label' => t('Show blocks'),
'image_rtl' => $image_prefix . '/showblocks-rtl.png',
),
'RemoveFormat' => array(
'label' => t('Remove format'),
),
'SpecialChar' => array(
'label' => t('Character map'),
),
'Format' => array(
'label' => t('HTML block format'),
'image_alternative' => '<span class="tinymce-button-dropdown">' . t('Format') . '<span class="tinymce-button-arrow"></span></span>',
),
'Styles' => array(
'label' => t('Font style'),
'image_alternative' => '<span class="tinymce-button-dropdown">' . t('Styles') . '<span class="tinymce-button-arrow"></span></span>',
),
'Table' => array(
'label' => t('Table'),
'required_tags' => array(
'table',
'thead',
'tbody',
'tr',
'td',
'th',
),
),
'Maximize' => array(
'label' => t('Maximize'),
),
'|' => array(
'label' => t('Group separator'),
'image_alternative' => '<span class="tinymce-group-separator"> </span>',
'attributes' => array(
'class' => array(
'tinymce-group-button-separator',
),
),
'multiple' => TRUE,
),
'-' => array(
'label' => t('Separator'),
'image_alternative' => '<span class="tinymce-separator"> </span>',
'attributes' => array(
'class' => array(
'tinymce-button-separator',
),
),
'multiple' => TRUE,
),
);
foreach ($buttons as $button_name => &$button) {
if (!isset($button['image_alternative']) && !isset($button['image'])) {
$button['image'] = $image_prefix . strtolower($button_name) . '.png';
}
}
$plugins['default'] = array(
'buttons' => $buttons,
'internal' => TRUE,
);
$plugins['drupalimage'] = array(
'path' => drupal_get_path('module', 'tinymce') . '/js/plugins/drupalimage',
'file' => 'plugin.js',
'buttons' => array(
'DrupalImage' => array(
'label' => t('Image'),
'required_tags' => array(
'img',
),
'image' => $image_prefix . '/image.png',
),
),
);
$plugins['drupalcaption'] = array(
'path' => drupal_get_path('module', 'tinymce') . '/js/plugins/drupalcaption',
'file' => 'plugin.js',
'css' => array(
drupal_get_path('module', 'tinymce') . '/css/tinymce-caption.css',
),
'enabled callback' => 'tinymce_image_plugin_check',
);
$plugins['drupalbreak'] = array(
'path' => drupal_get_path('module', 'tinymce') . '/js/plugins/drupalbreak',
'file' => 'plugin.js',
'buttons' => array(
'DrupalBreak' => array(
'label' => t('Teaser break'),
'image' => $image_prefix . '/pagebreak.png',
'image_rtl' => $image_prefix . '/pagebreak-rtl.png',
),
),
);
$plugins['webkitdrag'] = array(
'path' => drupal_get_path('module', 'tinymce') . '/js/plugins/webkitdrag',
'file' => 'plugin.js',
'enabled callback' => 'tinymce_image_plugin_check',
);
return $plugins;
}
function tinymce_image_plugin_check($editor, $format) {
foreach ($editor->settings['toolbar'] as $row) {
if (in_array('DrupalImage', $row)) {
return TRUE;
}
}
}
function template_preprocess_tinymce_settings_toolbar(&$variables) {
global $language;
$variables['language_direction'] = isset($language->direction) && $language->direction === LANGUAGE_RTL ? 'rtl' : 'ltr';
$editor = $variables['editor'];
$plugins = $variables['plugins'];
$buttons = array();
$variables['multiple_buttons'] = array();
foreach ($plugins as $plugin) {
if (isset($plugin['buttons'])) {
foreach ($plugin['buttons'] as $button_name => $button) {
if (!empty($button['multiple'])) {
$variables['multiple_buttons'][$button_name] = $button;
}
$button['name'] = $button_name;
$buttons[$button_name] = $button;
}
}
}
$variables['active_buttons'] = array();
foreach ($editor->settings['toolbar'] as $row_number => $row) {
foreach ($row as $button_name) {
if (isset($buttons[$button_name])) {
$variables['active_buttons'][$row_number][] = $buttons[$button_name];
if (empty($buttons[$button_name]['multiple'])) {
unset($buttons[$button_name]);
}
}
}
}
$variables['disabled_buttons'] = array_diff_key($buttons, $variables['multiple_buttons']);
}
function theme_tinymce_settings_toolbar($variables) {
$editor = $variables['editor'];
$plugins = $variables['plugins'];
$rtl = $variables['language_direction'] === 'rtl' ? '_rtl' : '';
foreach ($variables['active_buttons'] as $row_number => $row_buttons) {
foreach ($row_buttons as $button) {
$button_name = $button['name'];
if (isset($button['image_alternative'])) {
$data = $button['image_alternative'];
}
elseif (isset($button['image'])) {
$data = theme('image', array(
'path' => $button['image' . $rtl],
'title' => $button['label'],
));
}
else {
$data = '?';
}
$button_item = array(
'data' => $data,
'data-button-name' => $button_name,
);
if (!empty($button['multiple'])) {
$button['attributes']['class'][] = 'tinymce-multiple-button';
}
if (!empty($button['attributes'])) {
$button_item = array_merge($button_item, $button['attributes']);
}
$active_buttons[$row_number][] = $button_item;
}
}
foreach ($variables['disabled_buttons'] as $button_name => $button) {
if (isset($button['image_alternative'])) {
$data = $button['image_alternative'];
}
elseif (isset($button['image'])) {
$data = theme('image', array(
'path' => $button['image' . $rtl],
'title' => $button['label'],
));
}
else {
$data = '?';
}
$button_item = array(
'data' => $data,
'data-button-name' => $button_name,
);
if (isset($button['attributes'])) {
$button_item = array_merge($button_item, $button['attributes']);
}
$disabled_buttons[] = $button_item;
}
foreach ($variables['multiple_buttons'] as $button_name => $button) {
if (isset($button['image_alternative'])) {
$data = $button['image_alternative'];
}
elseif (isset($button['image'])) {
$data = theme('image', array(
'path' => $button['image' . $rtl],
'title' => $button['label'],
));
}
else {
$data = '?';
}
$button_item = array(
'data' => $data,
'data-button-name' => $button_name,
);
$button['attributes']['class'][] = 'tinymce-multiple-button';
if (isset($button['attributes'])) {
$button_item = array_merge($button_item, $button['attributes']);
}
$multiple_buttons[] = $button_item;
}
$output = '';
$output .= '<strong>' . t('Active toolbar') . '</strong>';
$output .= '<div class="tinymce-toolbar-active clearfix">';
foreach ($active_buttons as $button_row) {
$output .= '<ul class="tinymce-buttons">';
foreach ($button_row as $button) {
$contents = $button['data'];
unset($button['data']);
$attributes = drupal_attributes($button);
$output .= '<li' . $attributes . '>' . $contents . '</li>';
}
$output .= '</ul>';
}
if (empty($active_buttons)) {
$output .= '<ul class="tinymce-buttons">';
$output .= '</ul>';
}
$output .= '<div class="tinymce-row-controls">';
$output .= '<a href="#" class="tinymce-row-remove" title="' . t('Remove row') . '">-</a>';
$output .= '<a href="#" class="tinymce-row-add" title="' . t('Add row') . '">+</a>';
$output .= '</div>';
$output .= '</div>';
$output .= '<strong>' . t('Available buttons') . '</strong>';
$output .= '<div class="tinymce-toolbar-disabled clearfix">';
$output .= '<ul class="tinymce-buttons">';
foreach ($disabled_buttons as $button) {
$contents = $button['data'];
unset($button['data']);
$attributes = drupal_attributes($button);
$output .= '<li' . $attributes . '>' . $contents . '</li>';
}
$output .= '</ul>';
$output .= '<strong class="tinymce-multiple-label">' . t('Dividers') . ': </strong>';
$output .= '<ul class="tinymce-multiple-buttons">';
foreach ($multiple_buttons as $button) {
$contents = $button['data'];
unset($button['data']);
$attributes = drupal_attributes($button);
$output .= '<li' . $attributes . '>' . $contents . '</li>';
}
$output .= '</ul>';
$output .= '</div>';
return $output;
}
function tinymce_settings_form(&$form, $form_state, $editor, $format) {
$module_path = drupal_get_path('module', 'tinymce');
$plugins = tinymce_plugins();
$elements['toolbar'] = array(
'#type' => 'fieldset',
'#title' => t('Toolbar'),
'#parents' => array(
'editor_settings',
),
'#attached' => array(
'library' => array(
array(
'tinymce',
'drupal.tinymce.admin',
),
),
'js' => array(
array(
'data' => array(
'tinymce' => array(
'toolbarAdmin' => theme('tinymce_settings_toolbar', array(
'editor' => $editor,
'plugins' => $plugins,
)),
),
),
'type' => 'setting',
),
),
),
'#attributes' => array(
'class' => array(
'tinymce-toolbar-configuration',
),
),
);
$elements['toolbar']['toolbar'] = array(
'#type' => 'textarea',
'#title' => t('Toolbar configuration'),
'#default_value' => json_encode($editor->settings['toolbar']),
'#attributes' => array(
'class' => array(
'tinymce-toolbar-textarea',
),
),
);
$elements['toolbar']['format_list'] = array(
'#type' => 'textfield',
'#title' => t('Format list'),
'#default_value' => implode(', ', $editor->settings['format_list']),
'#description' => t('A list of tags that will be provided in the "Format" dropdown, separated by commas.'),
);
$elements['toolbar']['style_list'] = array(
'#type' => 'textarea',
'#title' => t('Style list'),
'#rows' => 4,
'#default_value' => implode("\n", $editor->settings['style_list']),
'#description' => t('A list of classes that will be provided in the "Styles" dropdown, each on a separate line. These styles should be available in your theme\'s editor.css as well as in your theme\'s main CSS file.'),
);
array_unshift($form['#submit'], 'tinymce_settings_form_submit');
return $elements;
}
function tinymce_settings_form_submit($form, &$form_state) {
$settings = $form_state['values']['editor_settings'];
form_set_value($form['editor_settings']['toolbar']['toolbar'], json_decode($settings['toolbar'], FALSE), $form_state);
$format_list = array();
foreach (explode(',', $settings['format_list']) as $format) {
$format_list[] = trim($format);
}
form_set_value($form['editor_settings']['toolbar']['format_list'], $format_list, $form_state);
$styles = array();
foreach (explode("\n", $settings['style_list']) as $style) {
$styles[] = trim($style);
}
form_set_value($form['editor_settings']['toolbar']['style_list'], $styles, $form_state);
}
function tinymce_add_settings($editor, $format, $existing_settings) {
global $language;
$plugin_info = tinymce_plugins();
$external_plugins = array();
$external_css = array();
$all_buttons = array();
foreach ($plugin_info as $plugin_name => $plugin) {
if (isset($plugin['enabled callback'])) {
if ($plugin['enabled callback'] === TRUE || $plugin['enabled callback']($editor, $plugin_name) && !empty($plugin['path'])) {
$external_plugins[$plugin_name]['file'] = $plugin['file'];
$external_plugins[$plugin_name]['path'] = $plugin['path'];
if (isset($plugin['css'])) {
$external_css = array_merge($external_css, $plugin['css']);
}
}
}
if (isset($plugin['buttons'])) {
if (empty($plugin['internal'])) {
foreach ($plugin['buttons'] as $button_name => &$button) {
$button['plugin'] = $plugin;
$button['plugin']['name'] = $plugin_name;
unset($button['plugin']['buttons']);
}
}
$all_buttons = array_merge($all_buttons, $plugin['buttons']);
}
}
$toolbar = array();
foreach ($editor->settings['toolbar'] as $row_number => $row) {
$button_group = array();
foreach ($row as $button_name) {
if ($button_name === '|') {
$toolbar[] = $button_group;
$button_group = array();
}
else {
if (isset($all_buttons[$button_name])) {
$button_group['items'][] = $button_name;
if (isset($all_buttons[$button_name]['plugin']['path'])) {
$plugin_name = $all_buttons[$button_name]['plugin']['name'];
$external_plugin = $all_buttons[$button_name]['plugin'];
$external_plugins[$plugin_name]['file'] = $external_plugin['file'];
$external_plugins[$plugin_name]['path'] = $external_plugin['path'];
if (isset($external_plugin['css'])) {
$external_css = array_merge($external_css, $external_plugin['css']);
}
}
}
}
}
$toolbar[] = $button_group;
$toolbar[] = '/';
}
$css = array(
drupal_get_path('module', 'tinymce') . '/css/tinymce.css',
drupal_get_path('module', 'tinymce') . '/css/tinymce-iframe.css',
);
$css = array_merge($css, $external_css, _tinymce_theme_css());
drupal_alter('tinymce_css', $css, $editor, $format);
foreach ($css as $key => $css_path) {
$css[$key] = base_path() . $css_path;
}
$settings = array(
'toolbar' => $toolbar,
'extraPlugins' => implode(',', array_keys($external_plugins)),
'removePlugins' => 'image',
'contentsCss' => array_values($css),
'pasteFromWordPromptCleanup' => TRUE,
'indentClasses' => array(
'indent1',
'indent2',
'indent3',
),
'justifyClasses' => array(
'align-left',
'align-center',
'align-right',
'align-justify',
),
'coreStyles_underline' => array(
'element' => 'span',
'attributes' => array(
'class' => 'underline',
),
),
'format_tags' => implode(';', $editor->settings['format_list']),
'removeDialogTabs' => 'image:Link;image:advanced;link:advanced',
'language' => isset($language->language) ? $language->language : '',
'resize_dir' => 'vertical',
);
$settings['externalPlugins'] = $external_plugins;
return $settings;
}
function _tinymce_theme_css($theme = NULL) {
$css = array();
if (!isset($theme)) {
$theme = variable_get('theme_default');
}
if ($theme_path = drupal_get_path('theme', $theme)) {
$info = system_get_info('theme', $theme);
if (isset($info['tinymce_stylesheets'])) {
$css = $info['tinymce_stylesheets'];
foreach ($css as $key => $path) {
$css[$key] = $theme_path . '/' . $path;
}
}
if (isset($info['base theme'])) {
$css = array_merge($css, _tinymce_theme_css($info['base theme']));
}
}
return $css;
}