Index: wysiwyg_editor.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg_editor.admin.inc,v
retrieving revision 1.16
diff -u -p -r1.16 wysiwyg_editor.admin.inc
--- wysiwyg_editor.admin.inc	5 Oct 2008 16:27:33 -0000	1.16
+++ wysiwyg_editor.admin.inc	6 Oct 2008 02:51:01 -0000
@@ -166,49 +166,6 @@ function wysiwyg_editor_profile_form($fo
     '#description' => t('The language for the Wysiwyg Editor interface. Language codes are based on the <a href="http://www.loc.gov/standards/iso639-2/englangn.html">ISO-639-2</a> format.'),
   );
 
-  $form['visibility'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Visibility'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-
-  // If the visibility is set to PHP mode but the user doesn't have this block
-  // permission, don't allow them to edit nor see this PHP code
-  $access = user_access('use PHP for block visibility');
-  if ($profile->settings['access'] == 2 && !$access) {
-    $form['visibility'] = array();
-    $form['visibility']['access'] = array(
-      '#type' => 'value',
-      '#value' => 2,
-    );
-    $form['visibility']['access_pages'] = array(
-      '#type' => 'value',
-      '#value' => $profile->settings['access_pages'],
-    );
-  }
-  else {
-    $options = array(t('Show on every page except the listed pages.'), t('Show on only the listed pages.'));
-    $description = t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '%blog' for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
-    if ($access) {
-      $options[] = t('Show if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
-      $description .= ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
-    }
-    $form['visibility']['access'] = array(
-      '#type' => 'radios',
-      '#title' => t('Show Wysiwyg Editor on specific pages'),
-      '#default_value' => $profile->settings['access'],
-      '#options' => $options,
-    );
-    $form['visibility']['access_pages'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Pages'),
-      '#default_value' => $profile->settings['access_pages'],
-      '#description' => $description,
-      '#wysiwyg' => FALSE,
-    );
-  }
-
   $form['buttons'] = array(
     '#type' => 'fieldset',
     '#title' => t('Buttons and plugins'),
Index: wysiwyg_editor.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg_editor.js,v
retrieving revision 1.7
diff -u -p -r1.7 wysiwyg_editor.js
--- wysiwyg_editor.js	5 Oct 2008 21:01:20 -0000	1.7
+++ wysiwyg_editor.js	9 Oct 2008 09:51:07 -0000
@@ -1,87 +1,146 @@
 // $Id: wysiwyg_editor.js,v 1.7 2008/10/05 21:01:20 sun Exp $
 
-Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {}, 'toggle': {} };
+Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {} };
 
 /**
- * Initialize all editor libraries.
+ * Initialize editor libraries.
+ *
+ * Some editors need to be initialized before the DOM is fully loaded. The
+ * init hook gives them a chance to do so.
  */
-Drupal.wysiwygEditorInit = function() {
+Drupal.wysiwygInit = function() {
   jQuery.each(Drupal.wysiwyg.init, function(editor) {
     this(Drupal.settings.wysiwygEditor.configs[editor]);
   });
 }
 
 /**
- * Attach editors to fields.
+ * Attach editors to input formats and target elements (f.e. textareas).
+ *
+ * This behavior searches for input format selectors and formatting guidelines
+ * that have been preprocessed by Wysiwyg API. All CSS classes of those elements
+ * with the prefix 'wysiwyg-' are parsed into input format parameters, defining
+ * the configured editor, editor theme, target element id, and variable other
+ * properties, which are passed to the attach/detach hooks of the corresponding
+ * editor.
+ *
+ * Furthermore, an "enable/disable rich-text" toggle link is added after the
+ * target element to allow users to alter its contents in plain text.
  *
- * This function can be called to process AJAX-loaded content.
+ * This is executed once, while editor attach/detach hooks can be invoked
+ * multiple times.
+ *
+ * @param context
+ *   A DOM element, supplied by Drupal.attachBehaviors().
  */
 Drupal.behaviors.attachWysiwyg = function(context) {
-  jQuery.each(Drupal.wysiwyg.attach, function(editor) {
-    // Show toggle link if set.
-    if (Drupal.settings.wysiwygEditor.showToggle) {
-      for (var theme in Drupal.settings.wysiwygEditor.configs[editor]) {
-        $('textarea.wysiwyg-' + theme + ':not(.wysiwyg-processed)', context).each(function() {
-          Drupal.wysiwygEditorAttachToggleLink(this, editor, theme);
-        });
+  $('.wysiwyg:not(.wysiwyg-processed)', context).each(function() {
+    // Parse the element's CSS classes into parameters.
+    // Format is wysiwyg-name-value.
+    var classes = this.className.split(' ');
+    var params = {};
+    for (var i in classes) {
+      if (classes[i].substr(0, 8) == 'wysiwyg-') {
+        var parts = classes[i].split('-');
+        var value = parts.slice(2).join('-');
+        params[parts[1]] = value;
       }
     }
-    this(context, Drupal.settings.wysiwygEditor.configs[editor]);
+    $this = $(this);
+    // Directly attach this editor, if the input format is enabled or there is
+    // only one input format at all.
+    if (($this.is(':input') && $this.is(':checked')) || $this.is('div')) {
+      Drupal.wysiwygEditorAttachToggleLink(context, params);
+      Drupal.wysiwygAttach(context, params);
+    }
+    // Attach onChange handlers to input format selector elements.
+    // @todo To support different editors on the same page, we need to store
+    //   the last attached editor of each target element separately.
+    if ($this.is(':input')) {
+      $this.change(function() {
+        Drupal.wysiwygDetach(context, params);
+        Drupal.wysiwygAttach(context, params);
+      });
+    }
+    $this.addClass('wysiwyg-processed');
+  });
+}
+
+/**
+ * Attach an editor to a target element.
+ *
+ * This tests whether the passed in editor implements the attach hook and
+ * invokes it if available. Editor profile settings are cloned first, so they
+ * cannot be overridden. After attaching the editor, the toggle link is shown
+ * again, except in case we are attaching no editor.
+ *
+ * @param context
+ *   A DOM element, supplied by Drupal.attachBehaviors().
+ * @param params
+ *   An object containing input format parameters.
+ */
+Drupal.wysiwygAttach = function(context, params) {
+  if (typeof Drupal.wysiwyg.attach[params.editor] == 'function') {
+    Drupal.wysiwyg.attach[params.editor](context, params, Drupal.wysiwyg.clone(Drupal.settings.wysiwygEditor.configs[params.editor]));
+    $('#wysiwyg-toggle-' + params.field).show();
+  }
+  if (params.editor == 'none') {
+    $('#wysiwyg-toggle-' + params.field).hide();
+  }
+}
+
+/**
+ * Detach all editors from a target element.
+ *
+ * Until there is a central registry of target elements storing the currently
+ * attached editor, we simply invoke the detach hook of all editors to ensure
+ * that no editor is attached to the target element.
+ *
+ * @param context
+ *   A DOM element, supplied by Drupal.attachBehaviors().
+ * @param params
+ *   An object containing input format parameters.
+ */
+Drupal.wysiwygDetach = function(context, params) {
+  jQuery.each(Drupal.wysiwyg.detach, function(editor) {
+    this(context, params);
   });
 }
 
 /**
- * Append a toggle link to an element.
+ * Append a editor toggle link to a target element.
  *
- * @param element
- *   The DOM element to toggle the editor for.
- * @param editor
- *   The editor name assigned to the element.
- * @param theme
- *   The editor theme assigned to the element.
+ * @param context
+ *   A DOM element, supplied by Drupal.attachBehaviors().
+ * @param params
+ *   An object containing input format parameters.
  */
-Drupal.wysiwygEditorAttachToggleLink = function(element, editor, theme) {
+Drupal.wysiwygEditorAttachToggleLink = function(context, params) {
   var text = document.createTextNode(Drupal.settings.wysiwygEditor.status ? Drupal.settings.wysiwygEditor.disable : Drupal.settings.wysiwygEditor.enable);
   var a = document.createElement('a');
-  $(a)
-    .click(function() {
-      Drupal.wysiwygEditorToggle(element, editor, theme);
+  $(a).toggle(
+    function() {
+      Drupal.wysiwygDetach(context, params);
+      $('#wysiwyg-toggle-' + params.field).html(Drupal.settings.wysiwygEditor.enable).blur();
+      // After disabling the editor, re-attach default behaviors.
+      Drupal.wysiwyg.attach.none(context, params);
+    },
+    function() {
+      // Before enabling the editor, detach default behaviors.
+      Drupal.wysiwyg.detach.none(context, params);
+      Drupal.wysiwygAttach(context, params);
+      $('#wysiwyg-toggle-' + params.field).html(Drupal.settings.wysiwygEditor.disable).blur();
     })
-    .attr('id', 'wysiwyg4' + element.id)
-    .css('cursor', 'pointer')
+    .attr('id', 'wysiwyg-toggle-' + params.field)
+    .attr('href', 'javascript:void(0);')
     .append(text);
   var div = document.createElement('div');
   $(div).append(a);
-  $(element).after(div);
-}
-
-/**
- * Enable/disable the editor and change toggle link text accordingly.
- *
- * Toggle implementation functions are expected to return the new state of a
- * toggled editor.
- *
- * @param element
- *   The DOM element to toggle the editor for.
- * @param editor
- *   The editor name assigned to the element.
- * @param theme
- *   The editor theme assigned to the element.
- */
-Drupal.wysiwygEditorToggle = function(element, editor, theme) {
-  if (typeof Drupal.wysiwyg.toggle[editor] == 'function') {
-    var new_state = Drupal.wysiwyg.toggle[editor](element, theme);
-  }
-  if (new_state) {
-    $('#wysiwyg4' + element.id).html(Drupal.settings.wysiwygEditor.disable).blur();
-  }
-  else {
-    $('#wysiwyg4' + element.id).html(Drupal.settings.wysiwygEditor.enable).blur();
-  }
+  $('#' + params.field).after(div);
 }
 
 /**
- * Clone a configuration object recursively; required for certain editors.
+ * Clone a configuration object recursively.
  *
  * @param obj
  *   The object to clone.
@@ -103,7 +162,7 @@ Drupal.wysiwyg.clone = function(obj) {
 }
 
 /**
- * Initialize editor libraries.
+ * Allow certain editor libraries to initialize before the DOM is loaded.
  */
-Drupal.wysiwygEditorInit();
+Drupal.wysiwygInit();
 
Index: wysiwyg_editor.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg_editor.module,v
retrieving revision 1.26
diff -u -p -r1.26 wysiwyg_editor.module
--- wysiwyg_editor.module	5 Oct 2008 21:01:20 -0000	1.26
+++ wysiwyg_editor.module	9 Oct 2008 10:02:00 -0000
@@ -4,7 +4,12 @@
 
 /**
  * @file
- * Integrate Wysiwyg editors into Drupal.
+ * Integrate client-side editors with Drupal.
+ *
+ * Please note that this module is slowly moving to become wysiwyg.module. Most
+ * functions are still based on the obsolete wysiwyg_editor name, which was
+ * originally chosen, because it was not clear whether editors would just be
+ * one component of a larger API.
  */
 
 /**
@@ -63,18 +68,27 @@ function wysiwyg_editor_perm() {
 /**
  * Implementation of hook_elements().
  *
+ * Before Drupal 7, there is no way to easily identify form fields that are
+ * input format enabled. This is a workaround: We assign a form #after_build
+ * processing callback that is executed on all forms after they have been
+ * completely built, so that form elements already are in their effective order and
+ * position.
+ *
+ * @see wysiwyg_process_form()
+ *
  * @todo Remove #wysiwyg_style; the GUI for an editor should be solely handled
  *   via profiles, when profiles are attached to an input format. It makes no
  *   sense to display TinyMCE's simple GUI/theme for the user signature, when
  *   the input format allows users to use advanced HTML and hence, editor
- *   plugins.  Fix this here, in wysiwyg_editor_process_textarea(), and lastly
+ *   plugins.  Fix this here, in wysiwyg_editor_process_element(), and lastly
  *   in wysiwyg_editor_get_config().
  */
 function wysiwyg_editor_elements() {
   $type = array();
   if (user_access('access wysiwyg editor')) {
-    // Let Wysiwyg Editor potentially process each textarea.
-    $type['textarea'] = array('#process' => array('wysiwyg_editor_process_textarea'), '#wysiwyg' => TRUE, '#wysiwyg_style' => 'advanced');
+    // @todo Derive editor theme from input format.
+    $type['textarea'] = array('#wysiwyg_style' => 'advanced');
+    $type['form'] = array('#after_build' => array('wysiwyg_process_form'));
   }
   return $type;
 }
@@ -91,75 +105,128 @@ function wysiwyg_editor_form_alter(&$for
 }
 
 /**
- * Alter #wysiwyg for certain core textareas.
+ * Process a textarea for Wysiwyg Editor.
  *
- * @param $element
- *   The textarea element to be processed.
- */
-function wysiwyg_editor_filter_elements(&$element) {
-  switch ($element['#name']) {
-    // Disable Wysiwyg Editor for these textareas.
-    case 'log': // Node revisions log message.
-    case 'img_assist_pages': // Image Assist visibility settings.
-    case 'caption': // User signature?
-    case 'pages': // (Block) Visibility settings.
-    case 'access_pages': // Wysiwyg Editor profile settings.
-    case 'user_mail_welcome_body': // User settings.
-    case 'user_mail_approval_body': // User settings.
-    case 'user_mail_pass_body': // User settings.
-    case 'synonyms': // Taxonomy terms.
-    case 'description': // Taxonomy terms.
-      $element['#wysiwyg'] = FALSE;
-      break;
-
-    // Force 'simple' theme for some smaller textareas.
-    case 'signature': // User signature.
-    case 'site_mission':
-    case 'site_footer':
-    case 'site_offline_message':
-    case 'page_help': // Page content-type help message?
-    case 'user_registration_help':
-    case 'user_picture_guidelines':
-      $element['#wysiwyg_style'] = 'simple';
-      break;
+ * This way, we can recurse into the form and search for certain, hard-coded
+ * elements that have been added by filter_form(). If an input format selector
+ * or input format guidelines element is found, we assume that the preceding
+ * element is the corresponding textarea and use it's #id for attaching
+ * client-side editors.
+ *
+ * @see wysiwyg_editor_elements(), filter_form()
+ */
+function wysiwyg_process_form(&$form) {
+  // Iterate over element children; resetting array keys to access last index.
+  if ($children = array_values(element_children($form))) {
+    foreach ($children as $index => $item) {
+      $element = &$form[$item];
+
+      // filter_form() always uses the key 'format'. We need a type-agnostic
+      // match to prevent false positives. Also, there must have been at least
+      // one element on this level.
+      if ($item === 'format' && $index > 0) {
+        // Make sure we either match a input format selector or input format
+        // guidelines (displayed if user has access to one input format only).
+        if ((isset($element['#type']) && $element['#type'] == 'fieldset') || isset($element['format']['guidelines'])) {
+          // The element before this element is the target form field.
+          $field = &$form[$children[$index - 1]];
+
+          // Disable #resizable to avoid resizable behavior to hi-jack the UI,
+          // but load the behavior, so the 'none' editor can attach/detach it.
+          $extra_class = '';
+          if (!empty($field['#resizable'])) {
+            // Due to our CSS class parsing, we can add arbitrary parameters
+            // for each input format.
+            $extra_class = ' wysiwyg-resizable-1';
+            $field['#resizable'] = FALSE;
+            drupal_add_js('misc/textarea.js');
+          }
+
+          // Determine the available input formats. The last child element is a
+          // link to "More information about formatting options". When only one
+          // input format is displayed, we also have to remove formatting
+          // guidelines, stored in the child 'format'.
+          $formats = element_children($element);
+          array_pop($formats);
+          unset($formats['format']);
+          foreach ($formats as $format) {
+            // Default to 'none' editor (Drupal's default behaviors).
+            $editor = 'none';
+            $theme = '';
+            // Fetch the profile associated to this input format.
+            $profile = wysiwyg_get_profile($format);
+            if ($profile) {
+              $editor = $profile->settings['editor'];
+              // Check editor theme (and reset it if not/no longer available).
+              $theme = wysiwyg_editor_get_themes($profile, $field['#wysiwyg_style']);
+
+              // Add profile settings for this input format.
+              wysiwyg_editor_add_settings($profile, $theme);
+              // Add plugin settings for this input format.
+              wysiwyg_editor_add_plugin_settings($profile);
+
+              $theme = ' wysiwyg-theme-'. $theme;
+            }
+
+            // Use a prefix/suffix for a single input format, or attach to input
+            // format selector radio buttons.
+            if (isset($element['format']['guidelines'])) {
+              $element[$format]['#prefix'] = '<div class="wysiwyg wysiwyg-editor-'. $editor .' wysiwyg-field-'. $field['#id'] . $theme . $extra_class .'">';
+              $element[$format]['#suffix'] = '</div>';
+            }
+            else {
+              if (isset($element[$format]['#attributes']['class'])) {
+                $element[$format]['#attributes']['class'] .= ' ';
+              }
+              else {
+                $element[$format]['#attributes']['class'] = '';
+              }
+              $element[$format]['#attributes']['class'] .= 'wysiwyg wysiwyg-editor-'. $editor .' wysiwyg-field-'. $field['#id'] . $theme . $extra_class;
+            }
+          }
+        }
+        // If this element is 'format', do not recurse further.
+        continue;
+      }
+      // Recurse into children.
+      wysiwyg_process_form($element);
+    }
   }
+  return $form;
 }
 
 /**
- * Process a textarea for Wysiwyg Editor.
+ * Determine the profile to use for a given input format id.
+ *
+ * This function also performs sanity checks for the configured editor in a
+ * profile to ensure that we do not load a malformed editor.
+ *
+ * @param $format
+ *   The internal id of an input format.
+ *
+ * @return
+ *   A wysiwyg profile.
+ *
+ * @see wysiwyg_editor_load_editor(), wysiwyg_get_editor()
+ *
+ * @todo Replace wysiwyg_editor_current_profile() with a input format to profile
+ *   association.
  */
-function wysiwyg_editor_process_textarea($element) {
-  wysiwyg_editor_filter_elements($element);
-
-  if ($element['#wysiwyg']) {
-    $profile = wysiwyg_editor_load_profile(wysiwyg_editor_current_profile());
-    if ($profile && _wysiwyg_editor_page_match($profile)) {
-      if (!wysiwyg_editor_load_editor($profile)) {
-        // Bail out if editor could not be loaded.
-        return $element;
-      }
-      // Check editor theme (and reset if needed).
-      // Default to advanced theme if the requested one is not installed.
-      $element['#wysiwyg_style'] = wysiwyg_editor_get_themes($profile, $element['#wysiwyg_style']);
-
-      wysiwyg_editor_add_settings($profile, $element['#wysiwyg_style']);
-      wysiwyg_editor_add_plugin_settings($profile);
-      if (!isset($element['#attributes'])) {
-        $element['#attributes'] = array();
-      }
-      if (!isset($element['#attributes']['class'])) {
-        $element['#attributes']['class'] = 'wysiwyg wysiwyg-'. $element['#wysiwyg_style'];
-      }
-      else {
-        $element['#attributes']['class'] .= ' wysiwyg wysiwyg-'. $element['#wysiwyg_style'];
-      }
-      // Set resizable to false to avoid drupal.js resizable function from
-      // taking control of the textarea
-      $element['#resizable'] = FALSE;
+function wysiwyg_get_profile($format) {
+  // Determine whether this input format has PHP filter enabled.
+  // Temporary, until input format to profile associations are in place.
+  $filters = filter_list_format($format);
+  foreach ($filters as $filter) {
+    if ($filter->module == 'php') {
+      return FALSE;
     }
   }
-
-  return $element;
+  if ($profile = wysiwyg_editor_load_profile(wysiwyg_editor_current_profile())) {
+    if (wysiwyg_editor_load_editor($profile)) {
+      return $profile;
+    }
+  }
+  return FALSE;
 }
 
 /**
@@ -171,16 +238,16 @@ function wysiwyg_editor_process_textarea
  * @return
  *   TRUE if the editor has been loaded, FALSE if not.
  *
- * @see wysiwyg_editor_process_textarea()
+ * @see wysiwyg_get_profile()
  */
 function wysiwyg_editor_load_editor($profile) {
   static $settings_added;
   static $loaded = array();
 
   $name = $profile->settings['editor'];
-  // Library files must only be loaded once.
+  // Library files must be loaded only once.
   if (!isset($loaded[$name])) {
-    // Load editor 
+    // Load editor.
     $editor = wysiwyg_get_editor($name);
     if ($editor) {
       // Determine library files to load.
@@ -231,6 +298,10 @@ function wysiwyg_editor_load_editor($pro
       'enable' => t('Enable rich-text'),
     )), 'setting');
 
+    // The 'none' editor is a special editor implementation, allowing us to
+    // attach and detach regular Drupal behaviors just like any other editor.
+    drupal_add_js(wysiwyg_get_path('editors/js/none.js'), 'module', 'footer');
+
     // Add wysiwyg_editor.js to the footer to ensure it's executed after the
     // Drupal.settings array has been rendered and populated. Also, since editor
     // library initialization functions must be loaded first by the browser,
@@ -421,48 +492,6 @@ function wysiwyg_editor_load_profile($na
 }
 
 /**
- * Determine if Wysiwyg Editor has permission to be used on the current page.
- *
- * @return
- *   TRUE if can render, FALSE if not allowed.
- */
-function _wysiwyg_editor_page_match($profile) {
-  $page_match = FALSE;
-  if (!is_object($profile)) {
-    return FALSE;
-  }
-
-  // Kill Wysiwyg Editor if we're editing a textarea with PHP in it!
-  if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'edit') {
-    $node = node_load(arg(1));
-    $filters = filter_list_format($node->format);
-    foreach ($filters as $filter) {
-      if ($filter->module == 'php') {
-        return FALSE;
-      }
-    }
-  }
-
-  if ($profile->settings['access_pages']) {
-    // If the PHP option wasn't selected
-    if ($profile->settings['access'] < 2) {
-      $path = drupal_get_path_alias($_GET['q']);
-      $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($profile->settings['access_pages'], '/')) .')$/';
-      $page_match = !($profile->settings['access'] xor preg_match($regexp, $path));
-    }
-    else {
-      $page_match = drupal_eval($profile->settings['access_pages']);
-    }
-  }
-  // No pages were specified to block so show on all
-  else {
-    $page_match = TRUE;
-  }
-
-  return $page_match;
-}
-
-/**
  * Implementation of hook_user().
  */
 function wysiwyg_editor_user($type, &$edit, &$user, $category = NULL) {
Index: editors/js/fckeditor-2.6.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/fckeditor-2.6.js,v
retrieving revision 1.1
diff -u -p -r1.1 fckeditor-2.6.js
--- editors/js/fckeditor-2.6.js	5 Oct 2008 22:08:38 -0000	1.1
+++ editors/js/fckeditor-2.6.js	9 Oct 2008 03:19:27 -0000
@@ -1,69 +1,45 @@
 // $Id: fckeditor-2.6.js,v 1.1 2008/10/05 22:08:38 sun Exp $
 
-Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {}, 'toggle': {} };
+Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {} };
 
 /**
- * Attach FCKeditor to textareas, using the theme specified in CSS class names.
+ * Attach this editor to a target element.
  *
- * @param editorSettings
- *   An object containing editor settings for each enabled editor theme.
+ * See Drupal.wysiwyg.attach.none() for a full desciption of this hook.
  */
-Drupal.wysiwyg.attach.fckeditor = function(context, editorSettings) {
-  for (var theme in editorSettings) {
-    $('textarea.wysiwyg-' + theme + ':not(.wysiwyg-processed)', context).each(function() {
-      // @todo Convert string into variable name w/o overwriting string?
-      //   workaround: build object via editors[this.id] = new ...
-      var oFCK_1 = new FCKeditor(this.id);
-      // Clone, so original settings are not overwritten.
-      var config = Drupal.wysiwyg.clone(editorSettings[theme]);
-      // Configure settings for this theme.
-      oFCK_1.BasePath = config.BasePath;
-      for (var setting in config) {
-        oFCK_1.Config[setting] = config[setting];
-      }
-      // Attach Wysiwyg Editor control if default is on.
-      if (Drupal.settings.wysiwygEditor.status) {
-        oFCK_1.ReplaceTextarea();
-      }
-      $(this).addClass('wysiwyg-processed');
-    });
+Drupal.wysiwyg.attach.fckeditor = function(context, params, settings) {
+  // @todo Convert string into variable name w/o overwriting string?
+  //   workaround: build object via editors[this.id] = new ...
+  var FCKinstance = new FCKeditor(params.field);
+  // Configure settings for this theme.
+  FCKinstance.BasePath = settings[params.theme].BasePath;
+  for (var setting in settings[params.theme]) {
+    FCKinstance.Config[setting] = settings[params.theme][setting];
   }
-}
-
-/**
- * Detach all FCKeditor editors.
- *
- * @todo Context support required to remove only certain editors (think AHAH/AJAX).
- */
-Drupal.wysiwyg.detach.fckeditor = function(context) {
-  if (tinyMCE.activeEditor) {
-    tinyMCE.triggerSave();
-    tinyMCE.activeEditor.remove();
+  // Attach editor control if default is on.
+  if (Drupal.settings.wysiwygEditor.status) {
+    FCKinstance.ReplaceTextarea();
   }
 }
 
 /**
- * Toggle editor and return new state.
- *
- * @param element
- *   The DOM element to toggle the editor for.
- * @param theme
- *   The editor theme assigned to the element.
+ * Detach a single or all editors.
  *
- * @return
- *   A boolean value indicating whether the editor has been enabled.
+ * See Drupal.wysiwyg.detach.none() for a full desciption of this hook.
  */
-Drupal.wysiwyg.toggle.fckeditor = function(element, theme) {
-  var instance = FCKeditorAPI.GetInstance(element.id);
-  if ($(element).css('display') != 'none' || instance == null) {
-    instance.SetHTML($(element).hide().val());
-    $('#' + element.id + '___Frame').show();
-    return true;
-  }
-  else {
-    $('#' + element.id).val(instance.GetXHTML()).show();
-    $('#' + element.id + '___Frame').hide();
-    return false;
+Drupal.wysiwyg.detach.fckeditor = function(context, params) {
+  if (typeof params != 'undefined') {
+    var editor = FCKeditorAPI.GetInstance(params.field);
+    if (editor) {
+      $('#' + params.field).val(editor.GetXHTML()).show();
+      $('#' + params.field + '___Config').remove();
+      $('#' + params.field + '___Frame').remove();
+      delete FCKeditorAPI.__Instances[params.field];
+    }
   }
+//  else {
+//    tinyMCE.triggerSave();
+//    tinyMCE.remove();
+//  }
 }
 
Index: editors/js/none.js
===================================================================
RCS file: editors/js/none.js
diff -N editors/js/none.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ editors/js/none.js	9 Oct 2008 03:16:25 -0000
@@ -0,0 +1,46 @@
+// $Id: tinymce-3.js,v 1.1 2008/10/05 21:01:20 sun Exp $
+
+Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {} };
+
+/**
+ * Attach this editor to a target element.
+ *
+ * @param context
+ *   A DOM element, supplied by Drupal.attachBehaviors().
+ * @param params
+ *   An object containing input format parameters. Default parameters are:
+ *   - editor: The internal editor name.
+ *   - theme: The name/key of the editor theme/profile to use.
+ *   - field: The CSS id of the target element.
+ * @param settings
+ *   An object containing editor settings for all enabled editor themes.
+ */
+Drupal.wysiwyg.attach.none = function(context, params, settings) {
+  if (params.resizable) {
+    $('#' + params.field).addClass('resizable');
+    Drupal.behaviors.textarea();
+  }
+}
+
+/**
+ * Detach a single or all editors.
+ *
+ * See Drupal.wysiwyg.attach.none() for a full desciption of arguments.
+ *
+ * @param context
+ *   A DOM element, supplied by Drupal.attachBehaviors().
+ * @param params
+ *   (optional) An object containing input format parameters. If defined,
+ *   only the editor instance in params.field should be detached. Otherwise,
+ *   all editors should be detached and saved, so they can be submitted in
+ *   AJAX/AHAH applications.
+ */
+Drupal.wysiwyg.detach.none = function(context, params) {
+  if (typeof params != 'undefined') {
+    var $textarea = $('#' + params.field, context).removeClass('textarea-processed');
+    var $div = $textarea.parents('div.resizable-textarea');
+    $div.before($textarea);
+    $div.remove();
+  }
+}
+
Index: editors/js/tinymce-2.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/tinymce-2.js,v
retrieving revision 1.1
diff -u -p -r1.1 tinymce-2.js
--- editors/js/tinymce-2.js	5 Oct 2008 21:01:20 -0000	1.1
+++ editors/js/tinymce-2.js	9 Oct 2008 16:11:23 -0000
@@ -1,9 +1,9 @@
 // $Id: tinymce-2.js,v 1.1 2008/10/05 21:01:20 sun Exp $
 
-Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {}, 'toggle': {} };
+Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {} };
 
 /**
- * Initialize TinyMCE instances.
+ * Initialize editor instances.
  *
  * This function needs to be called before the page is fully loaded, as
  * calling tinyMCE.init() after the page is loaded breaks IE6.
@@ -31,54 +31,34 @@ Drupal.wysiwyg.init.tinymce = function(e
 }
 
 /**
- * Attach TinyMCE to textareas, using the theme specified in CSS class names.
+ * Attach this editor to a target element.
  *
- * @param editorSettings
- *   An object containing editor settings for each enabled editor theme.
+ * See Drupal.wysiwyg.attach.none() for a full desciption of this hook.
  */
-Drupal.wysiwyg.attach.tinymce = function(context, editorSettings) {
-  for (var theme in editorSettings) {
-    // Clone, so original settings are not overwritten.
-    var config = Drupal.wysiwyg.clone(editorSettings[theme]);
-    // Configure settings for this theme.
-    for (var setting in config) {
-      tinyMCE.settings[setting] = config[setting];
-    }
-    $('textarea.wysiwyg-' + theme + ':not(.wysiwyg-processed)', context).each(function() {
-      // Attach Wysiwyg Editor control if default is on.
-      if (Drupal.settings.wysiwygEditor.status) {
-        tinyMCE.execCommand('mceAddControl', true, this.id);
-      }
-      $(this).addClass('wysiwyg-processed');
-    });
+Drupal.wysiwyg.attach.tinymce = function(context, params, editorSettings) {
+  // Configure settings for this theme.
+  for (var setting in editorSettings[params.theme]) {
+    tinyMCE.settings[setting] = editorSettings[params.theme][setting];
+  }
+  // Attach editor control if default is on.
+  if (Drupal.settings.wysiwygEditor.status) {
+    tinyMCE.execCommand('mceAddControl', true, params.field);
   }
 }
 
 /**
- * Toggle editor and return new state.
- *
- * @param element
- *   The DOM element to toggle the editor for.
- * @param theme
- *   The editor theme assigned to the element.
+ * Detach a single or all editors.
  *
- * @return
- *   A boolean value indicating whether the editor has been enabled.
+ * See Drupal.wysiwyg.detach.none() for a full desciption of this hook.
  */
-Drupal.wysiwyg.toggle.tinymce = function(element, theme) {
-  if (tinyMCE.getEditorId(element.id) == null) {
-    // Clone, so original settings are not overwritten.
-    var config = Drupal.wysiwyg.clone(Drupal.settings.wysiwygEditor.configs.tinymce[theme]);
-    // Set configuration options for this theme.
-    for (var setting in config) {
-      tinyMCE.settings[setting] = config[setting];
-    }
-    tinyMCE.addMCEControl(element, element.id);
-    return true;
-  }
-  else {
-    tinyMCE.removeMCEControl(tinyMCE.getEditorId(element.id));
-    return false;
+Drupal.wysiwyg.detach.tinymce = function(context, params) {
+  if (typeof params != 'undefined') {
+    tinyMCE.removeMCEControl(tinyMCE.getEditorId(params.field));
+    $('#' + params.field).removeAttr('style');
   }
+//  else if (tinyMCE.activeEditor) {
+//    tinyMCE.triggerSave();
+//    tinyMCE.activeEditor.remove();
+//  }
 }
 
Index: editors/js/tinymce-3.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/tinymce-3.js,v
retrieving revision 1.1
diff -u -p -r1.1 tinymce-3.js
--- editors/js/tinymce-3.js	5 Oct 2008 21:01:20 -0000	1.1
+++ editors/js/tinymce-3.js	9 Oct 2008 03:19:50 -0000
@@ -1,9 +1,9 @@
 // $Id: tinymce-3.js,v 1.1 2008/10/05 21:01:20 sun Exp $
 
-Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {}, 'toggle': {} };
+Drupal.wysiwyg = Drupal.wysiwyg || { 'init': {}, 'attach': {}, 'detach': {} };
 
 /**
- * Initialize TinyMCE instances.
+ * Initialize editor instances.
  *
  * @todo Is the following note still valid for 3.x?
  * This function needs to be called before the page is fully loaded, as
@@ -33,54 +33,37 @@ Drupal.wysiwyg.init.tinymce = function(e
 }
 
 /**
- * Attach TinyMCE to textareas, using the theme specified in CSS class names.
+ * Attach this editor to a target element.
  *
- * @param editorSettings
- *   An object containing editor settings for each enabled editor theme.
+ * See Drupal.wysiwyg.attach.none() for a full desciption of this hook.
  */
-Drupal.wysiwyg.attach.tinymce = function(context, editorSettings) {
-  for (var theme in editorSettings) {
-    // Clone, so original settings are not overwritten.
-    var config = Drupal.wysiwyg.clone(editorSettings[theme]);
-    // Configure settings for this theme.
-    for (var setting in config) {
-      tinyMCE.settings[setting] = config[setting];
-    }
-    $('textarea.wysiwyg-' + theme + ':not(.wysiwyg-processed)', context).each(function() {
-      // Attach Wysiwyg Editor control if default is on.
-      if (Drupal.settings.wysiwygEditor.status) {
-        tinyMCE.execCommand('mceAddControl', true, this.id);
-      }
-      $(this).addClass('wysiwyg-processed');
-    });
+Drupal.wysiwyg.attach.tinymce = function(context, params, editorSettings) {
+  // Configure settings for this theme.
+  for (var setting in editorSettings[params.theme]) {
+    tinyMCE.settings[setting] = editorSettings[params.theme][setting];
+  }
+  // Attach editor control if default is on.
+  if (Drupal.settings.wysiwygEditor.status) {
+    tinyMCE.execCommand('mceAddControl', true, params.field);
   }
 }
 
 /**
- * Detach all TinyMCE editors.
+ * Detach a single or all editors.
  *
- * @todo Context support required to remove only certain editors (think AHAH/AJAX).
+ * See Drupal.wysiwyg.detach.none() for a full desciption of this hook.
  */
-Drupal.wysiwyg.detach.tinymce = function(context) {
-  if (tinyMCE.activeEditor) {
+Drupal.wysiwyg.detach.tinymce = function(context, params) {
+  if (typeof params != 'undefined') {
+    var editor = tinyMCE.get(params.field);
+    if (editor) {
+      editor.save();
+      editor.remove();
+    }
+  }
+  else if (tinyMCE.activeEditor) {
     tinyMCE.triggerSave();
     tinyMCE.activeEditor.remove();
   }
 }
 
-/**
- * Toggle editor and return new state.
- *
- * @param element
- *   The DOM element to toggle the editor for.
- * @param theme
- *   The editor theme assigned to the element.
- *
- * @return
- *   A boolean value indicating whether the editor has been enabled.
- */
-Drupal.wysiwyg.toggle.tinymce = function(element, theme) {
-  tinyMCE.execCommand('mceToggleEditor', false, element.id);
-  return !(tinyMCE.get(element.id).isHidden());
-}
-
