Index: wysiwyg.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg.module,v
retrieving revision 1.23
diff -u -p -r1.23 wysiwyg.module
--- wysiwyg.module	22 Feb 2009 18:27:36 -0000	1.23
+++ wysiwyg.module	27 Feb 2009 23:35:19 -0000
@@ -328,21 +328,31 @@ function wysiwyg_add_editor_settings($pr
 
 /**
  * Add settings for external plugins.
- * 
+ *
+ * Plugins can be used in multiple profiles, but not necessarily in all. Because
+ * of that, we need to process plugins for each profile, even if their settings
+ * are not stored per profile.
+ *
+ * Implementations of hook_wysiwyg_plugin() may execute different code for each
+ * editor. Therefore, we have to invoke those implementations for each editor,
+ * but process the resulting plugins separately for each profile.
+ *
+ * Drupal plugins differ to native plugins in that they have plugin-specific
+ * definitions and settings, which need to be processed only once. But they are
+ * also passed to the editor to prepare settings specific to the editor.
+ * Therefore, we load and process the Drupal plugins only once, and hand off the
+ * effective definitions for each profile to the editor.
+ *
  * @param $profile
  *   A wysiwyg editor profile.
+ *
+ * @todo Rewrite wysiwyg_process_form() to build a registry of effective
+ *   profiles in use, so we can process plugins in multiple profiles in one shot
+ *   and simplify this entire function.
  */
 function wysiwyg_add_plugin_settings($profile) {
-  static $plugins_added = array();
-  
-  // External plugins must only be loaded once.
-  // @todo Actually, each native plugin must not be added twice, but different
-  //   profiles can have different plugin-sets for the same editor.  We should
-  //   check each plugin for each editor.
-  if (isset($plugins_added[$profile->editor])) {
-    return;
-  }
-  $plugins_added[$profile->editor] = TRUE;
+  static $plugins_native = array();
+  static $plugins_drupal = array();
 
   $editor = wysiwyg_get_editor($profile->editor);
   // Assume that this editor does not support neither native external plugins
@@ -351,46 +361,53 @@ function wysiwyg_add_plugin_settings($pr
     return;
   }
 
-  // Collect native editor plugins provided via hook_wysiwyg_plugin().
-  $plugins = module_invoke_all('wysiwyg_plugin', $editor['name'], $editor['installed version']);
-  // Only keep enabled native plugins in this profile.
-  foreach ($plugins as $plugin => $meta) {
+  // Collect native external plugins for this editor provided via
+  // hook_wysiwyg_plugin().
+  if (!array_key_exists($editor['name'], $plugins_native)) {
+    $plugins_native[$editor['name']] = module_invoke_all('wysiwyg_plugin', $editor['name'], $editor['installed version']);
+  }
+  // Only keep native external plugins that are enabled in this profile.
+  foreach ($plugins_native[$editor['name']] as $plugin => $meta) {
     if (!isset($profile->settings['buttons'][$plugin])) {
-      unset($plugins[$plugin]);
+      unset($plugins_native[$editor['name']][$plugin]);
     }
   }
   // Invoke the editor's plugin settings callback, so it can populate the
-  // settings for external plugins with custom, required values.
-  $plugins = $editor['plugin settings callback']($editor, $profile, $plugins);
+  // settings for native external plugins with custom, required values.
+  $settings_native = $editor['plugin settings callback']($editor, $profile, $plugins_native[$editor['name']]);
 
-  drupal_add_js(array('wysiwyg' => array('plugins' => array($profile->editor => array('native' => $plugins)))), 'setting');
+  drupal_add_js(array('wysiwyg' => array('plugins' => array($profile->editor => array('native' => $settings_native)))), 'setting');
 
   // If this editor does not define a proxy plugin and a proxy plugin settings
-  // callback, it does not support "Drupal plugins".
+  // callback, it does not support Drupal plugins.
   if (!(isset($editor['proxy plugin']) && isset($editor['proxy plugin settings callback']) && function_exists($editor['proxy plugin settings callback']))) {
     return;
   }
 
-  // Collect, load, and add API plugins provided by Drupal modules.
-  $plugins += $editor['proxy plugin'];
+  // Collect, load, and add proxy plugins provided by Drupal modules.
   $proxy = key($editor['proxy plugin']);
   $proxy_plugins = array();
   foreach (wysiwyg_get_all_plugins() as $plugin_name => $meta) {
     if (isset($profile->settings['buttons'][$proxy][$plugin_name])) {
-      $proxy_plugins[$plugin_name] = $meta;
-      // Load the Drupal plugin's JavaScript.
-      drupal_add_js($meta['js path'] .'/'. $meta['js file']);
-      // Add plugin specific settings.
-      if (isset($meta['settings'])) {
-        drupal_add_js(array('wysiwyg' => array('plugins' => array('drupal' => array($plugin_name => $meta['settings'])))), 'setting');
+      if (!isset($plugins_drupal[$plugin_name])) {
+        $proxy_plugins[$plugin_name] = $plugins_drupal[$plugin_name] = $meta;
+        // Load the Drupal plugin's JavaScript.
+        drupal_add_js($meta['js path'] .'/'. $meta['js file']);
+        // Add plugin specific settings.
+        if (isset($meta['settings'])) {
+          drupal_add_js(array('wysiwyg' => array('plugins' => array('drupal' => array($plugin_name => $meta['settings'])))), 'setting');
+        }
+      }
+      else {
+        $proxy_plugins[$plugin_name] = $plugins_drupal[$plugin_name];
       }
     }
   }
   // Invoke the editor's proxy plugin settings callback, so it can populate
   // the settings for Drupal plugins with custom, required values.
-  $proxy_plugins = $editor['proxy plugin settings callback']($editor, $profile, $proxy_plugins);
+  $settings_drupal = $editor['proxy plugin settings callback']($editor, $profile, $proxy_plugins);
 
-  drupal_add_js(array('wysiwyg' => array('plugins' => array($profile->editor => array('drupal' => $proxy_plugins)))), 'setting');
+  drupal_add_js(array('wysiwyg' => array('plugins' => array($profile->editor => array('drupal' => $settings_drupal)))), 'setting');
 }
 
 /**
