diff --git a/editors/ckeditor.inc b/editors/ckeditor.inc index 12949af..2a6b255 100644 --- a/editors/ckeditor.inc +++ b/editors/ckeditor.inc @@ -30,6 +30,7 @@ function wysiwyg_ckeditor_editor() { 'install note callback' => 'wysiwyg_ckeditor_install_note', 'version callback' => 'wysiwyg_ckeditor_version', 'themes callback' => 'wysiwyg_ckeditor_themes', + 'settings form callback' => 'wysiwyg_ckeditor_settings_form', 'settings callback' => 'wysiwyg_ckeditor_settings', 'plugin callback' => 'wysiwyg_ckeditor_plugins', 'plugin settings callback' => 'wysiwyg_ckeditor_plugin_settings', @@ -120,6 +121,50 @@ function wysiwyg_ckeditor_themes($editor, $profile) { } /** + * Implements the 'settings form callback' callback for CKEditor. + * + * This callback: + * - Changes the description on the 'CSS Classes' element. + * - Defines an element validator on the 'CSS Classes' element. + * or + * - Hides the 'CSS Classes' element if the CKEditor version is too old. + * + * @param array $form + * An associative array containing the structure of the form. + * @param array $form_state + * A keyed array containing the current state of the form. + */ +function wysiwyg_ckeditor_settings_form(&$form, &$form_state) { + $editor = wysiwyg_get_editor($form['editor']['#value']); + if (version_compare($editor['installed version'], '3.2.1', '>=')) { + $form['css']['css_classes']['#description'] = t('Optionally define CSS classes for the "Font style" dropdown list.
Enter one class on each line in the format: !format. Example: !example
If left blank, CSS classes are automatically imported from all loaded stylesheet(s).', + array('!format' => '[title]=[element].[class]', '!example' => 'My heading=h1.header1')); + $form['css']['css_classes']['#element_validate'][] = 'wysiwyg_ckeditor_settings_form_css_classes_validate'; + } + else { + // Do not show elements that do not work in the currently installed version. + $form['css']['css_classes']['#access'] = FALSE; + } +} + +/** + * Implements a form validator for the CSS Classes element of the settings form. + * + * @param array $element + * An associative array containing the form element to validate. + * @param array $form_state + * A keyed array containing the current state of the form. + * @param array $form + * An associative array containing the structure of the form. + */ +function wysiwyg_ckeditor_settings_form_css_classes_validate($element, &$form_state, $form) { + $errors = wysiwyg_ckeditor_parse_styles_set($element['#value'], TRUE); + if (!empty($errors)) { + form_error($element, t('Incorrect syntax for the CSS Classes. See the description for how to use this option.')); + } +} + +/** * Return runtime editor settings for a given wysiwyg profile. * * @param $editor @@ -188,6 +233,14 @@ function wysiwyg_ckeditor_settings($editor, $config, $theme) { } } + // Get additional styles, supported in versions 3.2.1 and above. + if (!empty($config['css_classes']) && version_compare($editor['installed version'], '3.2.1', '>=')) { + $styles = wysiwyg_ckeditor_parse_styles_set($config['css_classes']); + if (!empty($styles)) { + $settings['stylesSet'] = $styles; + } + } + if (isset($config['language'])) { $settings['language'] = $config['language']; } @@ -344,3 +397,55 @@ function wysiwyg_ckeditor_plugins($editor) { return $plugins; } +/** + * Converts the CSS classes string to an array of js settings. + * + * The CSS classes are edited in element CSS Classes, fieldset CSS + * of page admin/config/content/wysiwyg/profile/{filter}/edit. + * + * This function can also be used to just validate the CSS classes. This could + * be done in 2 separate functions, both optimized for their specific use case, + * but that would lead to more code than this single function and (more or less) + * the same logic and knowledge about the syntax in 2 places. + * + * @param string $css_classes + * A list of classes to add to the style drop down. + * @param bool $validate + * TRUE to only validate, FALSE (default) to parse. + * + * @return array + * An array with the parsed css styles or line numbers that contain incorrect + * syntax. + */ +function wysiwyg_ckeditor_parse_styles_set($css_classes, $validate = FALSE) { + $css_styles = array(); + $errors = array(); + + // Handle both Unix and Windows line-endings. + $lines = explode("\n", str_replace("\r", '', $css_classes)); + $line_no = 0; + foreach ($lines as $line) { + $line_no++; + $line = trim($line); + if (!empty($line)) { + // [name]=[element].[class] pattern expected. + $line_parts = explode('=', $line); + if (count($line_parts) === 2) { + $selector_parts = explode('.', $line_parts[1]); + if (count($selector_parts) === 2) { + $style['name'] = trim($line_parts[0]); + $style['element'] = trim($selector_parts[0]); + $style['attributes']['class'] = trim($selector_parts[1]); + if (!empty($style['name']) && !empty($style['element']) && !empty($style['attributes']['class'])) { + // This line is correct. Add it to the list and continue the loop to + // prevent it being added to the list of errors. + $css_styles[] = $style; + continue; + } + } + } + $errors[] = $line_no; + } + } + return $validate ? $errors : $css_styles; +} diff --git a/editors/js/ckeditor-3.0.js b/editors/js/ckeditor-3.0.js index 56a1e6f..9915308 100644 --- a/editors/js/ckeditor-3.0.js +++ b/editors/js/ckeditor-3.0.js @@ -23,6 +23,10 @@ Drupal.wysiwyg.editor.init.ckeditor = function(settings) { } } } + // Register Font styles (versions 3.2.1 and above). + if (Drupal.settings.wysiwyg.configs.ckeditor[format].stylesSet) { + CKEDITOR.stylesSet.add(format, Drupal.settings.wysiwyg.configs.ckeditor[format].stylesSet); + } } };