6
<link rel="stylesheet" href="http://yui.yahooapis.com/3.4.0pr3/build/cssgrids/grids-min.css">
7
<link rel="stylesheet" href="../assets/css/main.css">
8
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
9
<script src="../../build/yui/yui-min.js"></script>
17
<a href="#toc" class="jump">Jump to Table of Contents</a>
21
<div id="main" class="yui3-u">
22
<div class="content"><div class="intro">
24
Plugins allow you to unobtrusively add functionality to objects (referred to as the "host" object) such as nodes and widgets.
25
Plugins can inherit from the <code>Plugin.Base</code> class, but this is not a hard requirement as we'll see later.
29
Plugins are used to add atomic pieces of functionality or features to component instances (hosts), without having to bake support or even
30
knowledge of the feature into the component class. This allows features to be mixed and matched per component instance, without having to build all
31
features into a monolithic component class or having to ship multiple versions of the component class with varying combinations of features.
35
<h2 id="getting-started">Getting Started</h2>
38
To include the source files for Plugin and its dependencies, first load
39
the YUI seed file if you haven't already loaded it.
42
<pre class="code prettyprint"><script src="http://yui.yahooapis.com/3.4.1/build/yui/yui-min.js"></script></pre>
46
Next, create a new YUI instance for your application and populate it with the
47
modules you need by specifying them as arguments to the <code>YUI().use()</code> method.
48
YUI will automatically load any dependencies required by the modules you
52
<pre class="code prettyprint">// Create a new YUI instance and populate it with the required modules.
53
YUI().use('plugin', function (Y) {
54
// Plugin is available and ready for use. Add implementation
55
// code here.
60
For more information on creating YUI instances and on the
61
<a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_use"><code>use()</code> method</a>, see the
62
documentation for the <a href="../yui/index.html">YUI Global object</a>.
66
<h2 id="using">Creating Plugins</h2>
68
<h3 id="simple">Simple Plugins</h3>
71
For the most basic plugins, which don't have any events or attributes of their own, and which don't modify the behavior
72
of the host by listening for any host events, or overriding any of the host's methods, plugins can simply be basic JavaScript classes.
76
The only requirement for the class is that it has a static namespace property <code>NS</code> with a value assigned to it.
77
The value of the <code>NS</code> property is used to define the property on the host instance which will refer to
78
the plugin when it's plugged into the host.
82
When plugins are plugged into a host instance a new instance of the plugin is created,
83
and a reference to the host is added to the configuration object passed to the plugin's constructor,
84
so that the plugin has a way to reference the host object. (similarly, when plugins are unplugged from a host
85
object they are destroyed).
88
<p>So, putting this all together, a simple plugin class may look something like the following:</p>
90
<pre class="code prettyprint">// This AnchorPlugin is designed to be added to Node instances (the host will be a Node instance)
92
function AnchorPlugin(config) {
94
// Hold onto the host instance (a Node in this case),
95
// for other plugin methods to use.
97
this._node = config.host;
100
// When plugged into a node instance, the plugin will be
101
// available on the "anchors" property.
102
AnchorPlugin.NS = "anchors"
104
AnchorPlugin.prototype = {
105
disable: function() {
106
var node = this._node;
107
var anchors = node.queryAll("a");
108
anchors.addClass("disabled");
109
anchors.setAttribute("disabled", true);
114
<p>To use the <code>AnchorPlugin</code>, the user would plug it into a Node reference they were holding on to:</p>
116
<pre class="code prettyprint">var container = Y.one("div.actions");
117
container.plug(AnchorPlugin);</pre>
120
<p>And invoke methods on the plugin, through the namespace it is bound to:</p>
122
<pre class="code prettyprint">container.anchors.disable();</pre>
125
<h3 id="advanced">Advanced Plugins</h3>
127
<p>For basic features, simple plugin classes as described above may suffice. However, when you have more complex features which you'd like to encapsulate, the ability to use
128
attributes and events for your plugin implementation becomes useful. More importantly, for many plugins, you'll be looking to modify the default
129
behavior of the host instance in some way (for example an Animation Plugin may want to change the default show/hide behavior of a Widget, to be animated).</p>
131
<p>For these richer plugins, you should extend the base plugin class <a href="http://yuilibrary.com/yui/docs/api/Plugin.Base.html"><code>Plugin.Base</code></a>. </p>
133
<p><code>Plugin</code> is a subclass of <code>Base</code>, thereby providing managed attributes, lifecycle methods, and custom event support. Additionally it allows the plugin code to
134
either listen for and react to events fired by the host or inject custom logic before or after methods invoked on the host object (through the YUI 3 <a href="http://yuilibrary.com/yui/docs/api/Do.html">AOP</a> infrastructure).
135
<code>Plugin.Base</code> also sets up <code>host</code> as an attribute, so you can access it through <code>this.get("host")</code> in your plugin implementation code.
138
<h4 id="extendingplugin">Extending Plugin.Base</h4>
140
<p>You can extend the <code>Plugin.Base</code> class, just as you would extend the <a href="../base/index.html"><code>Base</code></a> class. One thing to note when comparing this to simple plugins
141
is that the host reference is automatically set up as an attribute by the <code>Plugin.Base</code> class, so a reference to it does not need to be set up explicitly.</p>
143
<p>The class structure for an advanced plugin follows the pattern for all classes derived from Base, with the addition of the <code>NS</code> property to define
144
the namespace for the plugin (see the <a href="../base/index.html">Base</a> documentation for details about NAME and ATTRS).</p>
147
<pre class="code prettyprint">// A plugin class designed to animate Widget's show and hide methods.
148
function WidgetAnimPlugin(config) {
149
WidgetAnimPlugin.superclass.constructor.apply(this, arguments);
152
// Define Static properties NAME (to identify the class) and NS (to identify the namespace)
153
WidgetAnimPlugin.NAME = 'widgetAnimPlugin';
154
WidgetAnimPlugin.NS = 'fx';
156
// Attribute definitions for the plugin
157
WidgetAnimPlugin.ATTRS = {
168
// Extend Plugin.Base
169
Y.extend(WidgetAnimPlugin, Y.Plugin.Base, {
171
// Add any required prototype methods
176
<p>The plugin class structure described above is captured in this <a href="../assets/plugin/myplugin.js.txt">"MyPlugin" Template File</a>, which you can use as a starting point to create your own plugins derived from <code>Plugin.Base</code>.</p>
178
<h4 id="pluginlisteners">Plugin Listeners</h4>
180
<p>The main value obtained by extending <code>Plugin.Base</code> is the ability to react to events fired by the host
181
using <code>Plugin.Base</code>'s <a href="http://yuilibrary.com/yui/docs/api/Plugin.Base.html#method_onHostEvent"><code>onHostEvent</code></a> and <a href="http://yuilibrary.com/yui/docs/api/Plugin.Base.html#method_afterHostEvent"><code>afterHostEvent</code></a> methods, or
182
modify methods on the host, using <a href="http://yuilibrary.com/yui/docs/api/Plugin.Base.html#method_beforeHostMethod"><code>beforeHostMethod</code></a> and <a href="http://yuilibrary.com/yui/docs/api/Plugin.Base.html#method_afterHostMethod"><code>afterHostMethod</code></a>.</p>
184
<p>The value of doing this through the above <code>Plugin.Base</code> methods as opposed to working with the host directly, is that any listeners added by the plugin using the above methods are removed when the plugin is unplugged.
185
This is important. Plugins should clean up after themselves when unplugged from the host.</p>
187
<h5 id="events">Events</h5>
189
<p>As mentioned, plugins which derive from <code>Plugin.Base</code> have the ability to listen for events on the host object and react to them.</p>
191
<p>For example, all widgets fire a <code>render</code> event when they are rendered. Your widget-specific plugin may need to know when this occurs,
192
so that it can inject custom elements into the markup the host renders. It can do this through the <code>afterHostEvent</code> method:</p>
194
<pre class="code prettyprint">// A plugin which introduces rounded corners to a widget.
195
function RoundedCornersPlugin(config) {
199
RoundedCornersPlugin.NAME = 'roundedCornersPlugin';
200
RoundedCornersPlugin.NS = 'corners';
202
Y.extend(RoundedCornersPlugin, Y.Plugin.Base, {
204
// Automatically called by Base, during construction
205
initializer: function(config) {
206
// "render" is a widget event
207
this.afterHostEvent('render', this.insertCornerElements);
210
insertCornerElements: function() {
211
var widget = this.get("host");
212
var boundingBox = widget.get("boundingBox");
214
var tl = Y.Node.create(TL_TEMPLATE);
217
boundingBox.appendChild(tlNode);
218
boundingBox.appendChild(trNode);
219
boundingBox.appendChild(blNode);
220
boundingBox.appendChild(brNode);
225
<h5 id="methods">Methods</h5>
227
<p>In some cases, your plugin may need to override the logic in the host class' methods. The <code>beforeHostMethod</code> and <code>afterHostMethod</code> methods provided by <code>Plugin.Base</code>
228
allow you to insert custom plugin logic before or after a method is executed on the host object.</p>
230
<p>For example, to animate the way a widget is shown or hidden, we may need to override the method
231
which actually flips the visibility style attribute on the widget's bounding box and replace it with an animated opacity implementation,
234
<pre class="code prettyprint">// A plugin class designed to animate Widget's show and hide methods.
235
function WidgetAnimPlugin(config) {
239
WidgetAnimPlugin.NAME = 'widgetAnimPlugin';
240
WidgetAnimPlugin.NS = 'fx';
242
WidgetAnimPlugin.ATTRS = {
253
// Extend Plugin.Base, and override the default
254
// method _uiSetVisible, used by Widget to flip the visibility
255
Y.extend(WidgetAnimPlugin, Y.Plugin.Base, {
257
initializer : function(config) {
259
// Override Widget's _uiSetVisible method, with the custom animated method
260
this.beforeHostMethod("_uiSetVisible", this._uiAnimSetVisible);
263
_uiAnimSetVisible : function(show) {
264
// Instead of flipping visibility, use the animation
265
// instances configured for the plugin to animate
266
// hide/show.
267
if (this.get("host").get("rendered")) {
269
this.get("animHidden").stop();
270
this.get("animVisible").run();
272
this.get("animVisible").stop();
273
this.get("animHidden").run();
276
// Prevent the default method from being invoked.
277
return new Y.Do.Prevent();
285
<div id="sidebar" class="yui3-u">
287
<div id="toc" class="sidebox">
289
<h2 class="no-toc">Table of Contents</h2>
295
<a href="#getting-started">Getting Started</a>
298
<a href="#using">Creating Plugins</a>
301
<a href="#simple">Simple Plugins</a>
304
<a href="#advanced">Advanced Plugins</a>
307
<a href="#extendingplugin">Extending Plugin.Base</a>
310
<a href="#pluginlisteners">Plugin Listeners</a>
313
<a href="#events">Events</a>
316
<a href="#methods">Methods</a>
332
<div class="sidebox">
334
<h2 class="no-toc">Examples That Use This Component</h2>
338
<ul class="examples">
341
<li data-description="Shows how to create an IO plugin for Widget.">
342
<a href="../widget/widget-plugin.html">Creating a Widget Plugin</a>
347
<li data-description="Shows how to create a simple plugin to retrieve content for the Overlay using the io utility.">
348
<a href="../overlay/overlay-io-plugin.html">IO Plugin</a>
353
<li data-description="Shows how to create a simple plugin to animate the Overlay's movement and visibility.">
354
<a href="../overlay/overlay-anim-plugin.html">Animation Plugin</a>
366
<script src="../assets/vendor/prettify/prettify-min.js"></script>
367
<script>prettyPrint();</script>