You are here

tinymce.module in TinyMCE 7

File

tinymce.module
View source
<?php

/**
 * @file
 * Provides integration with the TinyMCE WYSIWYG editor.
 */
require_once dirname(__FILE__) . '/includes/tinymce.wysiwyg.inc';
define('TINYMCE_VERSION', '4.0.2');

/**
 * Implements hook_editor_info().
 */
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;
}

/**
 * Implements hook_library().
 */
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;
}

/**
 * Implements hook_theme().
 */
function tinymce_theme() {
  return array(
    'tinymce_settings_toolbar' => array(
      'variables' => array(
        'editor' => NULL,
        'plugins' => NULL,
      ),
    ),
  );
}

/**
 * Implements hook_init().
 */
function tinymce_init() {

  // Add our CSS file that adds common needed classes, such as align-left,
  // align-right, underline, indent, etc.
  drupal_add_css(drupal_get_path('module', 'tinymce') . '/css/tinymce.css');

  // In Drupal 8 these settings are added by hook_library(), but the D7 version
  // doesn't have a library for integration because it uses WYSIWYG API.
  $settings = array(
    'tinymce' => array(
      'modulePath' => drupal_get_path('module', 'tinymce'),
    ),
  );
  drupal_add_js($settings, array(
    'type' => 'setting',
  ));
}

/**
 * Retrieves the full list of installed TinyMCE plugins.
 */
function tinymce_plugins() {
  $plugins = module_invoke_all('tinymce_plugins');
  drupal_alter('tinymce_plugins', $plugins);
  return $plugins;
}

/**
 * Implements hook_tinymce_plugins().
 *
 * Return a list of all plugins provided by this module.
 */
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'),
      // A class is used on spans for 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">&nbsp;</span>',
      'attributes' => array(
        'class' => array(
          'tinymce-group-button-separator',
        ),
      ),
      'multiple' => TRUE,
    ),
    '-' => array(
      'label' => t('Separator'),
      'image_alternative' => '<span class="tinymce-separator">&nbsp;</span>',
      'attributes' => array(
        'class' => array(
          'tinymce-button-separator',
        ),
      ),
      'multiple' => TRUE,
    ),
  );

  // Populate image locations that match button names.
  foreach ($buttons as $button_name => &$button) {
    if (!isset($button['image_alternative']) && !isset($button['image'])) {

      // Because button names are ASCII text, drupal_strtolower() is not needed.
      $button['image'] = $image_prefix . strtolower($button_name) . '.png';
    }
  }

  // List all the basic plugin buttons as an "internal" plugin.
  $plugins['default'] = array(
    'buttons' => $buttons,
    'internal' => TRUE,
  );

  // The drupalimage plugin replaces normal image functionality.
  $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',
      ),
    ),
  );

  // The drupalcaption plugin provides consistent behaviors for image captions.
  $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',
  );

  // The drupalbreak plugin provides support for Drupal's <!--break--> comment.
  $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',
      ),
    ),
  );

  // Webkit support for resizing images.
  $plugins['webkitdrag'] = array(
    'path' => drupal_get_path('module', 'tinymce') . '/js/plugins/webkitdrag',
    'file' => 'plugin.js',
    'enabled callback' => 'tinymce_image_plugin_check',
  );
  return $plugins;
}

/**
 * Enabled callback for hook_tinymce_plugins().
 *
 * Checks if our Caption plugin should be enabled based on the configuration of
 * a text format and editor.
 */
function tinymce_image_plugin_check($editor, $format) {

  // Automatically enable caption support if the DrupalImage button is enabled.
  foreach ($editor->settings['toolbar'] as $row) {
    if (in_array('DrupalImage', $row)) {
      return TRUE;
    }
  }
}

/**
 * Preprocess variables for theme_tinymce_settings_toolbar().
 */
function template_preprocess_tinymce_settings_toolbar(&$variables) {

  // Simplify the language direction information for toolbar buttons.
  global $language;
  $variables['language_direction'] = isset($language->direction) && $language->direction === LANGUAGE_RTL ? 'rtl' : 'ltr';

  // Create lists of active and disabled buttons.
  $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']);
}

/**
 * Displays the toolbar configuration for TinyMCE.
 */
function theme_tinymce_settings_toolbar($variables) {
  $editor = $variables['editor'];
  $plugins = $variables['plugins'];
  $rtl = $variables['language_direction'] === 'rtl' ? '_rtl' : '';

  // Assemble items to be added to active button rows.
  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;
    }
  }

  // Assemble list of disabled buttons (which are always a single row).
  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;
  }

  // Assemble list of multiple buttons that may be added multiple times.
  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;
  }

  // We don't use theme_item_list() below in case there are no buttons in the
  // active or disabled list, as theme_item_list() will not print an empty UL.
  $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;
}

/**
 * Editor settings callback; Provide options for TinyMCE module.
 */
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;
}

/**
 * Additional submit handler for filter_admin_format_form().
 */
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);
}

/**
 * Editor JS settings callback; Add Aloha settings to the page for a format.
 *
 * @param $editor
 *   The editor object for which Aloha is adding its settings.
 * @param $format
 *   The filter format object for which Aloha is adding its settings.
 * @param $existing_settings
 *   Settings that have already been added to the page by filters.
 */
function tinymce_add_settings($editor, $format, $existing_settings) {
  global $language;

  // Loop through all available plugins and check to see if it has been
  // explicitly enabled. At the same time, associate each plugin with its
  // buttons (if any) so we can check if the plugin should be enabled implicitly
  // based on the toolbar.
  $plugin_info = tinymce_plugins();
  $external_plugins = array();
  $external_css = array();
  $all_buttons = array();
  foreach ($plugin_info as $plugin_name => $plugin) {

    // Check if this plugin should be enabled.
    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']);
        }
      }
    }

    // Associate each plugin with its button.
    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']);
    }
  }

  // Change the toolbar separators into groups and record needed plugins based
  // on use in the toolbar.
  $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 {

        // Sanity check that the button exists in our installation.
        if (isset($all_buttons[$button_name])) {
          $button_group['items'][] = $button_name;

          // Keep track of the needed plugin for this button, if any.
          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[] = '/';
  }

  // Collect a list of CSS files to be added to the editor instance.
  $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);

  // Convert all paths to be relative to root.
  foreach ($css as $key => $css_path) {
    $css[$key] = base_path() . $css_path;
  }

  // Initialize reasonable defaults that provide expected basic bahvior.
  $settings = array(
    'toolbar' => $toolbar,
    'extraPlugins' => implode(',', array_keys($external_plugins)),
    'removePlugins' => 'image',
    //'forcePasteAsPlainText' => TRUE,
    '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',
  );

  // These settings are used specifically by Drupal.
  $settings['externalPlugins'] = $external_plugins;
  return $settings;
}

/**
 * Retrieves the default theme's TinyMCE stylesheets defined in the .info file.
 *
 * Themes may specify iframe-specific CSS files for use with TinyMCE by
 * including a "tinymce_stylesheets" key in the theme .info file.
 *
 * @code
 * tinymce_stylesheets[] = css/tinymce-iframe.css
 * @endcode
 */
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;
}

Functions

Namesort descending Description
template_preprocess_tinymce_settings_toolbar Preprocess variables for theme_tinymce_settings_toolbar().
theme_tinymce_settings_toolbar Displays the toolbar configuration for TinyMCE.
tinymce_add_settings Editor JS settings callback; Add Aloha settings to the page for a format.
tinymce_editor_info Implements hook_editor_info().
tinymce_image_plugin_check Enabled callback for hook_tinymce_plugins().
tinymce_init Implements hook_init().
tinymce_library Implements hook_library().
tinymce_plugins Retrieves the full list of installed TinyMCE plugins.
tinymce_settings_form Editor settings callback; Provide options for TinyMCE module.
tinymce_settings_form_submit Additional submit handler for filter_admin_format_form().
tinymce_theme Implements hook_theme().
tinymce_tinymce_plugins Implements hook_tinymce_plugins().
_tinymce_theme_css Retrieves the default theme's TinyMCE stylesheets defined in the .info file.

Constants

Namesort descending Description
TINYMCE_VERSION