Instance and class based plugins in YUI 3

Using plugins in YUI 3 is a way to add functionality to existing objects in YUI (very much like you would use prototype to augment a function to a normal JavaScript object). Objects in YUI all derive from Y.Base.

Note that this post is about YUI 3 and not YUI 2.

However, the current YUI 3 documentation does really only get into how to add a plugin to a current instance. What about adding functionality to the class level so all instances of the same type of objects automatically get it?

First an example of how a simple plugin may look like:

NodePlugin = function(config) {
    this._node = config.host;
}

NodePlugin.NS = 'vis';
NodePlugin.NAME = 'NodeVisibiltyPlugin';

NodePlugin.prototype = {
    show: function() {
        this._node.setStyle('display', 'block');
        return this_node;
    },

    hide: function() {
        this._node.setStyle('display', 'none');
        return this_node;
    }
};

What this plugin does it to add hide() and show() functions to the vis namespace (as specified in the code) of Y.Node.

This plugin would typically be used like this:

var node = Y.one('#myElement');
node.plug(NodePlugin); // add plugin functionality
node.vis.hide();

If you would like to use the plugin functionality for all node objects it would be somewhat tedious to invoke plug() for each and every instance. The way to get around this, which is not really documented except in the API reference, is to use the static method Y.Plugin.Host.plug.

Y.Plugin.Host.plug(Y.Node, NodePlugin); // plug once ...

var node = Y.one('#myElement');
node.vis.hide(); // ... use anywhere

Now any new instances of Y.node have access to the plugin methods through the specified namespace. I also discovered that in order for this to work the static NAME property must be defined in the plugin object.