Index: editors/yui.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/yui.inc,v
retrieving revision 1.6.2.3
diff -u -p -r1.6.2.3 yui.inc
--- editors/yui.inc	6 Feb 2010 18:17:49 -0000	1.6.2.3
+++ editors/yui.inc	10 Feb 2010 04:50:27 -0000
@@ -46,6 +46,14 @@ function wysiwyg_yui_editor() {
     'load callback' => 'wysiwyg_yui_load',
     'settings callback' => 'wysiwyg_yui_settings',
     'plugin callback' => 'wysiwyg_yui_plugins',
+    'plugin settings callback' => 'wysiwyg_yui_plugin_settings',
+    'proxy plugin' => array(
+      'drupal' => array(
+        'load' => TRUE,
+        'proxy' => TRUE,
+      ),
+    ),
+    'proxy plugin settings callback' => 'wysiwyg_yui_proxy_plugin_settings',
     'versions' => array(
       '2.7.0' => array(
         'js files' => array('yui.js'),
@@ -209,7 +217,6 @@ function wysiwyg_yui_settings($editor, $
       $settings['extracss'] = '@import "' . implode('"; @import "', $settings['extracss']) . '";';
     }
   }
-
   return $settings;
 }
 
@@ -230,8 +237,7 @@ function wysiwyg_yui_button_setting($edi
   static $plugins;
 
   if (!isset($plugins)) {
-    // @todo Invoke all enabled plugins, not just internals.
-    $plugins = wysiwyg_yui_plugins($editor);
+    $plugins = wysiwyg_get_plugins($editor['name']);
   }
 
   // Return a simple separator.
@@ -267,6 +273,41 @@ function wysiwyg_yui_button_setting($edi
 }
 
 /**
+ * Build a JS settings array of native external plugins that need to be loaded separately.
+*/
+function wysiwyg_yui_plugin_settings($editor, $profile, $plugins) {
+  $settings = array();
+  foreach ($plugins as $name => $plugin) {
+    if (!empty($plugin['load'])) {
+      // Add path for native external plugins; internal ones are loaded
+      // automatically.
+      if (empty($plugin['internal']) && isset($plugin['path'])) {
+        $settings[$name] = base_path() . $plugin['path'];
+      }
+    }
+  }
+  return $settings;
+}
+
+/**
+ * Build a JS settings array for Drupal plugins loaded via the proxy plugin.
+ */
+function wysiwyg_yui_proxy_plugin_settings($editor, $profile, $plugins) {
+  $settings = array();
+  foreach ($plugins as $name => $plugin) {
+    // Populate required plugin settings.
+    $settings[$name] = $plugin['dialog settings'] + array(
+      'title' => $plugin['title'],
+      'icon' => base_path() . $plugin['icon path'] . '/' . $plugin['icon file'],
+      'iconTitle' => $plugin['icon title'],
+      // @todo These should only be set if the plugin defined them.
+      'css' => base_path() . $plugin['css path'] . '/' . $plugin['css file'],
+    );
+  }
+  return $settings;
+}
+
+/**
  * Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
  */
 function wysiwyg_yui_plugins($editor) {
@@ -291,4 +332,3 @@ function wysiwyg_yui_plugins($editor) {
     ),
   );
 }
-
Index: editors/js/yui.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/editors/js/yui.js,v
retrieving revision 1.1.6.1
diff -u -p -r1.1.6.1 yui.js
--- editors/js/yui.js	6 Feb 2010 22:34:24 -0000	1.1.6.1
+++ editors/js/yui.js	10 Feb 2010 04:50:27 -0000
@@ -2,12 +2,70 @@
 
 /**
  * Attach this editor to a target element.
+ *
+ * Since buttons must be added before the editor is rendered, we add plugins
+ * buttons on attach event rather than in init.
  */
 Drupal.wysiwyg.editor.attach.yui = function(context, params, settings) {
   // Apply theme.
   $('#' + params.field).parent().addClass('yui-skin-' + settings.theme);
+
+  // Load plugins stylesheet.
+  for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+    settings.extracss += settings.extracss+' @import "'+Drupal.settings.wysiwyg.plugins[params.format].drupal[plugin].css+'"; ';
+  }
+
   // Attach editor.
   var editor = new YAHOO.widget.Editor(params.field, settings);
+
+  editor.on('toolbarLoaded', function() {
+    // Load Drupal plugins.
+    for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+      Drupal.wysiwyg.instances[params.field].addPlugin(plugin, Drupal.settings.wysiwyg.plugins[params.format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin]);
+    }
+  });
+
+  // Allow plugins to act on setEditorHTML.
+  var oldSetEditorHTML = editor.setEditorHTML;
+  editor.setEditorHTML = function (content) {
+    for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+      var pluginSettings = Drupal.settings.wysiwyg.plugins.drupal[plugin];
+      if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
+        content = Drupal.wysiwyg.plugins[plugin].attach(content, pluginSettings, params.field);
+        content = Drupal.wysiwyg.instances[params.field].prepareContent(content);
+      }
+    }
+    oldSetEditorHTML.call(this, content);
+  };
+
+  // Allow plugins to act on getEditorHTML.
+  var oldGetEditorHTML = editor.getEditorHTML;
+  editor.getEditorHTML = function () {
+    var content = oldGetEditorHTML.call(this);
+    for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+      var pluginSettings = Drupal.settings.wysiwyg.plugins.drupal[plugin];
+      if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
+        content = Drupal.wysiwyg.plugins[plugin].detach(content, pluginSettings, params.field);
+      }
+    }
+    return content;
+  }
+
+  // Reload the editor contents to give Drupal plugins a chance to act.
+  editor.on('editorContentLoaded', function (e) {
+    e.target.setEditorHTML(oldGetEditorHTML.call(e.target));
+  });
+
+  editor.on('afterNodeChange', function (e) {
+    for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+      if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
+        if (Drupal.wysiwyg.plugins[plugin].isNode(e.target._getSelectedElement())) {
+          this.toolbar.selectButton(plugin);
+        }
+      }
+    }
+  });
+
   editor.render();
 };
 
@@ -18,9 +76,10 @@ Drupal.wysiwyg.editor.attach.yui = funct
  */
 Drupal.wysiwyg.editor.detach.yui = function(context, params) {
   if (typeof params != 'undefined') {
-    var instance = YAHOO.widget.EditorInfo.getEditorById(params.field);
+    var instance = YAHOO.widget.EditorInfo._instances[params.field];
     if (instance) {
       instance.destroy();
+      delete YAHOO.widget.EditorInfo._instances[params.field];
     }
   }
   else {
@@ -28,7 +87,46 @@ Drupal.wysiwyg.editor.detach.yui = funct
       // Save contents of all editors back into textareas.
       var instance = YAHOO.widget.EditorInfo._instances[e];
       instance.destroy();
+      delete YAHOO.widget.EditorInfo.instances[e];
+    }
+  }
+};
+
+/**
+ * Instance methods for YUI Editor.
+ */
+Drupal.wysiwyg.editor.instance.yui = {
+  addPlugin: function (plugin, settings, pluginSettings) {
+    if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
+      return;
     }
+    var editor = YAHOO.widget.EditorInfo.getEditorById(this.field);
+    var button = editor.toolbar.getButtonByValue(plugin);
+    $(button._button).parent().css('background', 'transparent url(' + settings.icon + ') no-repeat center');
+    // 'this' will reference the toolbar while inside the event handler.
+    var instanceId = this.field;
+    editor.toolbar.on(plugin + 'Click', function (e) {
+      var selectedElement = editor._getSelectedElement();
+      // @todo Using .html() will cause XTHML vs HTML conflicts.
+      var data = { format: 'html', node: selectedElement, content: $(selectedElement).html() };
+      Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instanceId);
+    });
+  },
+
+  prepareContent: function (content) {
+    var editor = YAHOO.widget.EditorInfo.getEditorById(this.field);
+    content = editor.cleanHTML(content);
+    return content;
+  },
+
+  insert: function (content) {
+    var editor = YAHOO.widget.EditorInfo.getEditorById(this.field);
+    editor.execCommand('inserthtml', content);
+  },
+
+  getContent: function () {
+    var editor = YAHOO.widget.EditorInfo.getEditorById(this.field);
+    return editor.getEditorHTML();
   }
 };
 
