You are here

ckeditor.module in CKEditor for WYSIWYG Module 8

Same filename and directory in other branches
  1. 7 ckeditor.module

Provides integration with the CKEditor WYSIWYG editor.

File

ckeditor.module
View source
<?php

/**
 * @file
 * Provides integration with the CKEditor WYSIWYG editor.
 */
define('CKEDITOR_VERSION', '4.0.1');

/**
 * Implements hook_library_info().
 */
function ckeditor_library_info() {
  $module_path = drupal_get_path('module', 'ckeditor');
  $settings = array(
    'ckeditor' => array(
      'modulePath' => drupal_get_path('module', 'ckeditor'),
    ),
  );
  $libraries['drupal.ckeditor'] = array(
    'title' => 'Drupal behavior to enable CKEditor on textareas.',
    'version' => VERSION,
    'js' => array(
      $module_path . '/js/ckeditor.js' => array(),
      array(
        'data' => $settings,
        'type' => 'setting',
      ),
    ),
    'dependencies' => array(
      array(
        'editor',
        'drupal.editor',
      ),
      array(
        'ckeditor',
        'ckeditor',
      ),
    ),
  );
  $libraries['drupal.ckeditor.css'] = array(
    'title' => 'Formatting CSS for common classes used in CKEditor.',
    'version' => VERSION,
    'css' => array(
      $module_path . '/css/ckeditor.css' => array(),
    ),
  );
  $libraries['drupal.ckeditor.admin'] = array(
    'title' => 'Drupal behavior to enable CKEditor on textareas.',
    'version' => VERSION,
    'js' => array(
      $module_path . '/js/ckeditor.admin.js' => array(),
    ),
    'css' => array(
      $module_path . '/css/ckeditor.admin.css' => array(),
    ),
    'dependencies' => array(
      array(
        'system',
        'jquery.once',
      ),
      array(
        'system',
        'jquery.ui.sortable',
      ),
      array(
        'system',
        'jquery.ui.draggable',
      ),
    ),
  );
  $libraries['ckeditor'] = array(
    'title' => 'Loads the main CKEditor library.',
    'version' => CKEDITOR_VERSION,
    'js' => array(
      $module_path . '/lib/ckeditor/ckeditor.js' => array(),
    ),
  );
  return $libraries;
}

/**
 * Implements hook_theme().
 */
function ckeditor_theme() {
  return array(
    'ckeditor_settings_toolbar' => array(
      'file' => 'ckeditor.admin.inc',
      'variables' => array(
        'editor' => NULL,
        'plugins' => NULL,
      ),
    ),
  );
}

/**
 * Implements hook_page_build().
 */
function ckeditor_page_build(&$page) {

  // Add our CSS file that adds common needed classes, such as align-left,
  // align-right, underline, indent, etc.
  $page['#attached']['library'][] = array(
    'ckeditor',
    'drupal.ckeditor.css',
  );
}

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

/**
 * Implements hook_ckeditor_plugins().
 *
 * Return a list of all plugins provided by this module.
 */
function ckeditor_ckeditor_plugins() {
  $image_prefix = drupal_get_path('module', 'ckeditor') . '/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(
        'sup',
      ),
    ),
    'Subscript' => array(
      'label' => t('Subscript'),
      'required_tags' => array(
        'sub',
      ),
    ),
    '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="ckeditor-button-dropdown">' . t('Format') . '<span class="ckeditor-button-arrow"></span></span>',
    ),
    'Styles' => array(
      'label' => t('Font style'),
      'image_alternative' => '<span class="ckeditor-button-dropdown">' . t('Styles') . '<span class="ckeditor-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="ckeditor-group-separator">&nbsp;</span>',
      'attributes' => array(
        'class' => array(
          'ckeditor-group-button-separator',
        ),
      ),
      'multiple' => TRUE,
    ),
    '-' => array(
      'label' => t('Separator'),
      'image_alternative' => '<span class="ckeditor-separator">&nbsp;</span>',
      'attributes' => array(
        'class' => array(
          'ckeditor-button-separator',
        ),
      ),
      'multiple' => TRUE,
    ),
  );

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

      // Because we know the list of strings, 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', 'ckeditor') . '/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', 'ckeditor') . '/js/plugins/drupalcaption',
    'file' => 'plugin.js',
    'css' => array(
      drupal_get_path('module', 'ckeditor') . '/css/ckeditor-caption.css',
    ),
    'enabled callback' => 'ckeditor_image_plugin_check',
  );

  // The drupalbreak plugin provides support for Drupal's <!--break--> comment.
  $plugins['drupalbreak'] = array(
    'path' => drupal_get_path('module', 'ckeditor') . '/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', 'ckeditor') . '/js/plugins/webkitdrag',
    'file' => 'plugin.js',
    'enabled callback' => 'ckeditor_image_plugin_check',
  );
  return $plugins;
}

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

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

/**
 * Retrieves the default theme's CKEditor stylesheets defined in the .info file.
 *
 * Themes may specify iFrame-specific CSS files for use with CKEditor by
 * including a "ckeditor_stylesheets" key in the theme .info file.
 *
 * @code
 * ckeditor_stylesheets[] = css/ckeditor-iframe.css
 * @endcode
 */
function _ckeditor_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['ckeditor_stylesheets'])) {
      $css = $info['ckeditor_stylesheets'];
      foreach ($css as $key => $path) {
        $css[$key] = $theme_path . '/' . $path;
      }
    }
    if (isset($info['base theme'])) {
      $css = array_merge($css, _ckeditor_theme_css($info['base theme']));
    }
  }
  return $css;
}

Functions

Namesort descending Description
ckeditor_ckeditor_plugins Implements hook_ckeditor_plugins().
ckeditor_image_plugin_check Enabled callback for hook_ckeditor_plugins().
ckeditor_library_info Implements hook_library_info().
ckeditor_page_build Implements hook_page_build().
ckeditor_plugins Retrieves the full list of installed CKEditor plugins.
ckeditor_theme Implements hook_theme().
_ckeditor_theme_css Retrieves the default theme's CKEditor stylesheets defined in the .info file.

Constants

Namesort descending Description
CKEDITOR_VERSION @file Provides integration with the CKEditor WYSIWYG editor.