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	7 Feb 2010 15:21:10 -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'),
@@ -187,7 +195,9 @@ function wysiwyg_yui_settings($editor, $
             array('text' => 'Verdana'),
           ));
         }
-        $buttons[] = wysiwyg_yui_button_setting($editor, $plugin, $button, $extra);
+        if ($plugin == 'default') {
+        	$buttons[] = wysiwyg_yui_button_setting($editor, $plugin, $button, $extra);
+        }
       }
     }
     // Group buttons in a dummy group.
@@ -209,7 +219,6 @@ function wysiwyg_yui_settings($editor, $
       $settings['extracss'] = '@import "' . implode('"; @import "', $settings['extracss']) . '";';
     }
   }
-
   return $settings;
 }
 
@@ -230,8 +239,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 +275,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) {
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	7 Feb 2010 15:26:40 -0000
@@ -2,12 +2,37 @@
 
 /**
  * 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);
+
+  // Import plugins CSS.
+  if (Drupal.settings.wysiwyg.plugins[params.format]) {
+    for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+      if (Drupal.settings.wysiwyg.plugins[params.format].drupal[plugin].css) {
+        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);
+
+  // Create plugins buttons.
+  if (Drupal.settings.wysiwyg.plugins[params.format]) {
+    editor.on('toolbarLoaded', function() {
+      // Create a group for extra plugins.
+      editor.toolbar.addButtonGroup({ group: 'plugins', buttons: [] });
+      // Load Drupal plugins.
+      for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
+        Drupal.wysiwyg.editor.instance.yui.addPlugin(plugin, Drupal.settings.wysiwyg.plugins[params.format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin], params.field);
+      }
+    });
+  }
   editor.render();
 };
 
@@ -32,3 +57,88 @@ Drupal.wysiwyg.editor.detach.yui = funct
   }
 };
 
+/**
+ * Instance methods for YUI Editor.
+ */
+Drupal.wysiwyg.editor.instance.yui = {
+  addPlugin: function (plugin, settings, pluginSettings, instanceId) {
+    if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
+      return;
+    }
+    var editor = YAHOO.widget.EditorInfo._instances[instanceId];
+    var button = { 
+      type: settings.type,
+      label: settings.iconTitle,
+      value: plugin,
+      disabled: false
+    };
+    editor.toolbar.addButtonToGroup(button, 'plugins');
+
+    var buttons = editor.toolbar.getButtons();
+    var lastButton = buttons[buttons.length - 1];
+    $(lastButton._button).parent().css('background', 'transparent url(' + settings.icon + ') no-repeat center');
+
+    editor.toolbar.on(plugin + 'Click', function (e) {
+      editor._createCurrentElement('span');
+      var data = { format: 'html', node: editor.currentElement[0], content: $(editor.currentElement[0]).html() };
+      Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instanceId);
+    });
+
+    editor.on('editorContentLoaded', function (e) {
+      e.target.setEditorHTML(e.target._getEditorHTML());
+    });
+
+    editor.on('afterSetEditorHTML', function (e) {
+      if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
+        e.content = Drupal.wysiwyg.plugins[plugin].attach(e.content, pluginSettings, instanceId);
+        e.content = Drupal.wysiwyg.editor.instance.yui.prepareContent(e.content);
+      }
+    });
+
+    editor.on('afterGetEditorHTML', function (e) {
+      if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
+        e.content = Drupal.wysiwyg.plugins[plugin].detach(e.content, pluginSettings, instanceId);
+      }
+    });
+
+    editor.on('afterNodeChange', function (e) {
+      if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
+        if (Drupal.wysiwyg.plugins[plugin].isNode(e.target._getSelectedElement())) {
+          this.toolbar.selectButton(plugin);
+        }
+      }
+    });
+  },
+
+  prepareContent: function (content) {
+    var editor = YAHOO.widget.EditorInfo._instances[this.field];
+    content = editor.cleanHTML(content);
+    return content;
+  },
+
+  insert: function (content) {
+    var editor = YAHOO.widget.EditorInfo._instances[this.field];
+    editor.execCommand('inserthtml', content);
+  },
+
+  getContent: function () {
+    var editor = YAHOO.widget.EditorInfo._instances[this.field];
+    return editor.getEditorHTML();
+  }
+};
+
+// Enable events on content insertion and retrieval.
+YAHOO.widget.Editor.prototype._setEditorHTML = YAHOO.widget.Editor.prototype.setEditorHTML;
+YAHOO.widget.Editor.prototype._getEditorHTML = YAHOO.widget.Editor.prototype.getEditorHTML;
+
+YAHOO.widget.Editor.prototype.setEditorHTML = function (incomingHTML) {
+  var params = { type: 'afterSetEditorHTML', target: this, content: incomingHTML };
+  this.fireEvent('afterSetEditorHTML', params);
+  this._setEditorHTML(params.content);
+};
+
+YAHOO.widget.Editor.prototype.getEditorHTML = function () {
+  var params = { type: 'afterGetEditorHTML', target: this, content: this._getEditorHTML() };
+  this.fireEvent('afterGetEditorHTML', params);
+  return params.content;
+}
