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);
+ }
}
};