--- ./editors/ckeditor.inc	Fri Jan 14 16:42:47 2011
+++ ./editors/ckeditor.inc.new	Fri Jan 28 23:16:14 2011
@@ -44,6 +44,9 @@
       '3.0.0.3665' => array(
         'js files' => array('ckeditor-3.0.js'),
       ),
+      '3.2.1.5372' => array(
+        'js files' => array('ckeditor-3.2.1.js'),
+      ),
     ),
   );
   return $editor;
@@ -181,6 +184,14 @@
     }
   }
 
+  // Get font styles, supported in ckeditor versions 3.2.1 and above
+  if (!empty($config['css_classes'])) {
+    $styles = wysiwyg_ckeditor_get_styles_set($config['css_classes']);
+    if (!empty($styles)) {
+      $settings['stylesSet'] = $styles;
+    }
+  }
+
   if (isset($config['language'])) {
     $settings['language'] = $config['language'];
   }
@@ -332,3 +343,26 @@
   return $plugins;
 }
 
+/**
+ * Return an array for JS of custom Font styles
+ * note: only checking for correct format of each line, no error logging/hinting, should be done on the settings form
+ */
+function wysiwyg_ckeditor_get_styles_set($css_classes) {
+  $css_styles = array();
+  $lines = explode("\n", $css_classes);
+  foreach ($lines as $line) {
+    if (!empty($line)) {
+      $l = explode("=", $line);
+      if (count($l) === 2) {
+        $lc = explode(".", $l[1]);
+        if (count($lc) === 2) {
+          $style['name'] = trim($l[0]);
+          $style['element'] = trim($lc[0]);
+          $style['attributes']['class'] = trim($lc[1]);
+          $css_styles[] = $style;
+        }
+      }
+    }
+  }
+  return $css_styles;
+}
diff -urpN editors.orig/js/ckeditor-3.2.1.js editors/js/ckeditor-3.2.1.js
--- ./editors/js/ckeditor-3.2.1.js	Wed Dec 31 16:00:00 1969
+++ ./editors/js/ckeditor-3.2.1.js	Thu Jan 27 22:57:00 2011
@@ -0,0 +1,221 @@
+// $Id: ckeditor-3.0.js,v 1.2.4.10 2010/12/29 20:01:49 twod Exp $
+(function($) {
+
+Drupal.wysiwyg.editor.init.ckeditor = function(settings) {
+  // Plugins must only be loaded once. Only the settings from the first format
+  // will be used but they're identical anyway.
+  var registeredPlugins = {};
+  for (var format in settings) {
+    if (Drupal.settings.wysiwyg.plugins[format]) {
+      // Register native external plugins.
+      // Array syntax required; 'native' is a predefined token in JavaScript.
+      for (var pluginName in Drupal.settings.wysiwyg.plugins[format]['native']) {
+        if (!registeredPlugins[pluginName]) {
+          var plugin = Drupal.settings.wysiwyg.plugins[format]['native'][pluginName];
+          CKEDITOR.plugins.addExternal(pluginName, plugin.path, plugin.fileName);
+          registeredPlugins[pluginName] = true;
+        }
+      }
+      // Register Drupal plugins.
+      for (var pluginName in Drupal.settings.wysiwyg.plugins[format].drupal) {
+        if (!registeredPlugins[pluginName]) {
+          Drupal.wysiwyg.editor.instance.ckeditor.addPlugin(pluginName, Drupal.settings.wysiwyg.plugins[format].drupal[pluginName], Drupal.settings.wysiwyg.plugins.drupal[pluginName]);
+          registeredPlugins[pluginName] = true;
+        }
+      }
+    }
+    // Register Font styles.
+    if (Drupal.settings.wysiwyg.configs.ckeditor[format].stylesSet) {
+      CKEDITOR.stylesSet.add(format, Drupal.settings.wysiwyg.configs.ckeditor[format].stylesSet);
+    }
+  }
+};
+
+
+/**
+ * Attach this editor to a target element.
+ */
+Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
+  // Apply editor instance settings.
+  CKEDITOR.config.customConfig = '';
+
+  settings.on = {
+    instanceReady: function(ev) {
+      var editor = ev.editor;
+      // Get a list of block, list and table tags from CKEditor's XHTML DTD.
+      // @see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Output_Formatting.
+      var dtd = CKEDITOR.dtd;
+      var tags = CKEDITOR.tools.extend({}, dtd.$block, dtd.$listItem, dtd.$tableContent);
+      // Set source formatting rules for each listed tag except <pre>.
+      // Linebreaks can be inserted before or after opening and closing tags.
+      if (settings.apply_source_formatting) {
+        // Mimic FCKeditor output, by breaking lines between tags.
+        for (var tag in tags) {
+          if (tag == 'pre') {
+            continue;
+          }
+          this.dataProcessor.writer.setRules(tag, {
+            indent: true,
+            breakBeforeOpen: true,
+            breakAfterOpen: false,
+            breakBeforeClose: false,
+            breakAfterClose: true
+          });
+        }
+      }
+      else {
+        // CKEditor adds default formatting to <br>, so we want to remove that
+        // here too.
+        tags.br = 1;
+        // No indents or linebreaks;
+        for (var tag in tags) {
+          if (tag == 'pre') {
+            continue;
+          }
+          this.dataProcessor.writer.setRules(tag, {
+            indent: false,
+            breakBeforeOpen: false,
+            breakAfterOpen: false,
+            breakBeforeClose: false,
+            breakAfterClose: false
+          });
+        }
+      }
+    },
+
+    pluginsLoaded: function(ev) {
+      // Override the conversion methods to let Drupal plugins modify the data.
+      var editor = ev.editor;
+      if (editor.dataProcessor && Drupal.settings.wysiwyg.plugins[params.format]) {
+        editor.dataProcessor.toHtml = CKEDITOR.tools.override(editor.dataProcessor.toHtml, function(originalToHtml) {
+          // Convert raw data for display in WYSIWYG mode.
+          return function(data, fixForBody) {
+            for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+              if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
+                data = Drupal.wysiwyg.plugins[plugin].attach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], editor.name);
+                data = Drupal.wysiwyg.instances[params.field].prepareContent(data);
+              }
+            }
+            return originalToHtml.call(this, data, fixForBody);
+          };
+        });
+        editor.dataProcessor.toDataFormat = CKEDITOR.tools.override(editor.dataProcessor.toDataFormat, function(originalToDataFormat) {
+          // Convert WYSIWYG mode content to raw data.
+          return function(data, fixForBody) {
+            data = originalToDataFormat.call(this, data, fixForBody);
+            for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+              if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
+                data = Drupal.wysiwyg.plugins[plugin].detach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], editor.name);
+              }
+            }
+            return data;
+          };
+        });
+      }
+    },
+
+    selectionChange: function (event) {
+      if (Drupal.settings.wysiwyg.plugins[params.format]) {
+        $.each(Drupal.settings.wysiwyg.plugins[params.format].drupal, function (name) {
+          var plugin = Drupal.wysiwyg.plugins[name];
+          if ($.isFunction(plugin.isNode)) {
+            var node = event.data.selection.getSelectedElement();
+            var state = plugin.isNode(node ? node.$ : null) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
+            event.editor.getCommand(name).setState(state);
+          }
+        });
+      }
+    },
+
+    focus: function(ev) {
+      Drupal.wysiwyg.activeId = ev.editor.name;
+    }
+  };
+
+  // Attach editor.
+  CKEDITOR.replace(params.field, settings);
+};
+
+/**
+ * Detach a single or all editors.
+ *
+ * @todo 3.x: editor.prototype.getInstances() should always return an array
+ *   containing all instances or the passed in params.field instance, but
+ *   always return an array to simplify all detach functions.
+ */
+Drupal.wysiwyg.editor.detach.ckeditor = function(context, params) {
+  if (typeof params != 'undefined') {
+    var instance = CKEDITOR.instances[params.field];
+    if (instance) {
+      instance.destroy();
+    }
+  }
+  else {
+    for (var instanceName in CKEDITOR.instances) {
+      CKEDITOR.instances[instanceName].destroy();
+    }
+  }
+};
+
+Drupal.wysiwyg.editor.instance.ckeditor = {
+  addPlugin: function(pluginName, settings, pluginSettings) {
+    CKEDITOR.plugins.add(pluginName, {
+      // Wrap Drupal plugin in a proxy pluygin.
+      init: function(editor) {
+        if (settings.css) {
+          editor.on('mode', function(ev) {
+            if (ev.editor.mode == 'wysiwyg') {
+              // Inject CSS files directly into the editing area head tag.
+              $('head', $('#cke_contents_' + ev.editor.name + ' iframe').eq(0).contents()).append('<link rel="stylesheet" href="' + settings.css + '" type="text/css" >');
+            }
+          });
+        }
+        if (typeof Drupal.wysiwyg.plugins[pluginName].invoke == 'function') {
+          var pluginCommand = {
+            exec: function (editor) {
+              var data = { format: 'html', node: null, content: '' };
+              var selection = editor.getSelection();
+              if (selection) {
+                data.node = selection.getSelectedElement();
+                if (data.node) {
+                  data.node = data.node.$;
+                }
+                if (selection.getType() == CKEDITOR.SELECTION_TEXT) {
+                  if (CKEDITOR.env.ie) {
+                    data.content = selection.getNative().createRange().text;
+                  }
+                  else {
+                    data.content = selection.getNative().toString();
+                  }
+                }
+                else if (data.node) {
+                  // content is supposed to contain the "outerHTML".
+                  data.content = data.node.parentNode.innerHTML;
+                }
+              }
+              Drupal.wysiwyg.plugins[pluginName].invoke(data, pluginSettings, editor.name);
+            }
+          };
+          editor.addCommand(pluginName, pluginCommand);
+        }
+        editor.ui.addButton(pluginName, {
+          label: settings.iconTitle,
+          command: pluginName,
+          icon: settings.icon
+        });
+
+        // @todo Add button state handling.
+      }
+    });
+  },
+  prepareContent: function(content) {
+    // @todo Don't know if we need this yet.
+    return content;
+  },
+  insert: function(content) {
+    content = this.prepareContent(content);
+    CKEDITOR.instances[this.field].insertHtml(content);
+  }
+};
+
+})(jQuery);
