|
1 YUI.add('pluginhost-base', function (Y, NAME) { |
|
2 |
|
3 /** |
|
4 * Provides the augmentable PluginHost interface, which can be added to any class. |
|
5 * @module pluginhost |
|
6 */ |
|
7 |
|
8 /** |
|
9 * Provides the augmentable PluginHost interface, which can be added to any class. |
|
10 * @module pluginhost-base |
|
11 */ |
|
12 |
|
13 /** |
|
14 * <p> |
|
15 * An augmentable class, which provides the augmented class with the ability to host plugins. |
|
16 * It adds <a href="#method_plug">plug</a> and <a href="#method_unplug">unplug</a> methods to the augmented class, which can |
|
17 * be used to add or remove plugins from instances of the class. |
|
18 * </p> |
|
19 * |
|
20 * <p>Plugins can also be added through the constructor configuration object passed to the host class' constructor using |
|
21 * the "plugins" property. Supported values for the "plugins" property are those defined by the <a href="#method_plug">plug</a> method. |
|
22 * |
|
23 * For example the following code would add the AnimPlugin and IOPlugin to Overlay (the plugin host): |
|
24 * <xmp> |
|
25 * var o = new Overlay({plugins: [ AnimPlugin, {fn:IOPlugin, cfg:{section:"header"}}]}); |
|
26 * </xmp> |
|
27 * </p> |
|
28 * <p> |
|
29 * Plug.Host's protected <a href="#method_initPlugins">_initPlugins</a> and <a href="#method_destroyPlugins">_destroyPlugins</a> |
|
30 * methods should be invoked by the host class at the appropriate point in the host's lifecyle. |
|
31 * </p> |
|
32 * |
|
33 * @class Plugin.Host |
|
34 */ |
|
35 |
|
36 var L = Y.Lang; |
|
37 |
|
38 function PluginHost() { |
|
39 this._plugins = {}; |
|
40 } |
|
41 |
|
42 PluginHost.prototype = { |
|
43 |
|
44 /** |
|
45 * Adds a plugin to the host object. This will instantiate the |
|
46 * plugin and attach it to the configured namespace on the host object. |
|
47 * |
|
48 * @method plug |
|
49 * @chainable |
|
50 * @param P {Function | Object |Array} Accepts the plugin class, or an |
|
51 * object with a "fn" property specifying the plugin class and |
|
52 * a "cfg" property specifying the configuration for the Plugin. |
|
53 * <p> |
|
54 * Additionally an Array can also be passed in, with the above function or |
|
55 * object values, allowing the user to add multiple plugins in a single call. |
|
56 * </p> |
|
57 * @param config (Optional) If the first argument is the plugin class, the second argument |
|
58 * can be the configuration for the plugin. |
|
59 * @return {Base} A reference to the host object |
|
60 */ |
|
61 plug: function(Plugin, config) { |
|
62 var i, ln, ns; |
|
63 |
|
64 if (L.isArray(Plugin)) { |
|
65 for (i = 0, ln = Plugin.length; i < ln; i++) { |
|
66 this.plug(Plugin[i]); |
|
67 } |
|
68 } else { |
|
69 if (Plugin && !L.isFunction(Plugin)) { |
|
70 config = Plugin.cfg; |
|
71 Plugin = Plugin.fn; |
|
72 } |
|
73 |
|
74 // Plugin should be fn by now |
|
75 if (Plugin && Plugin.NS) { |
|
76 ns = Plugin.NS; |
|
77 |
|
78 config = config || {}; |
|
79 config.host = this; |
|
80 |
|
81 if (this.hasPlugin(ns)) { |
|
82 // Update config |
|
83 if (this[ns].setAttrs) { |
|
84 this[ns].setAttrs(config); |
|
85 } |
|
86 } else { |
|
87 // Create new instance |
|
88 this[ns] = new Plugin(config); |
|
89 this._plugins[ns] = Plugin; |
|
90 } |
|
91 } |
|
92 } |
|
93 return this; |
|
94 }, |
|
95 |
|
96 /** |
|
97 * Removes a plugin from the host object. This will destroy the |
|
98 * plugin instance and delete the namespace from the host object. |
|
99 * |
|
100 * @method unplug |
|
101 * @param {String | Function} plugin The namespace of the plugin, or the plugin class with the static NS namespace property defined. If not provided, |
|
102 * all registered plugins are unplugged. |
|
103 * @return {Base} A reference to the host object |
|
104 * @chainable |
|
105 */ |
|
106 unplug: function(plugin) { |
|
107 var ns = plugin, |
|
108 plugins = this._plugins; |
|
109 |
|
110 if (plugin) { |
|
111 if (L.isFunction(plugin)) { |
|
112 ns = plugin.NS; |
|
113 if (ns && (!plugins[ns] || plugins[ns] !== plugin)) { |
|
114 ns = null; |
|
115 } |
|
116 } |
|
117 |
|
118 if (ns) { |
|
119 if (this[ns]) { |
|
120 if (this[ns].destroy) { |
|
121 this[ns].destroy(); |
|
122 } |
|
123 delete this[ns]; |
|
124 } |
|
125 if (plugins[ns]) { |
|
126 delete plugins[ns]; |
|
127 } |
|
128 } |
|
129 } else { |
|
130 for (ns in this._plugins) { |
|
131 if (this._plugins.hasOwnProperty(ns)) { |
|
132 this.unplug(ns); |
|
133 } |
|
134 } |
|
135 } |
|
136 return this; |
|
137 }, |
|
138 |
|
139 /** |
|
140 * Determines if a plugin has plugged into this host. |
|
141 * |
|
142 * @method hasPlugin |
|
143 * @param {String} ns The plugin's namespace |
|
144 * @return {Plugin} Returns a truthy value (the plugin instance) if present, or undefined if not. |
|
145 */ |
|
146 hasPlugin : function(ns) { |
|
147 return (this._plugins[ns] && this[ns]); |
|
148 }, |
|
149 |
|
150 /** |
|
151 * Initializes static plugins registered on the host (using the |
|
152 * Base.plug static method) and any plugins passed to the |
|
153 * instance through the "plugins" configuration property. |
|
154 * |
|
155 * @method _initPlugins |
|
156 * @param {Object} config The configuration object with property name/value pairs. |
|
157 * @private |
|
158 */ |
|
159 |
|
160 _initPlugins: function(config) { |
|
161 this._plugins = this._plugins || {}; |
|
162 |
|
163 if (this._initConfigPlugins) { |
|
164 this._initConfigPlugins(config); |
|
165 } |
|
166 }, |
|
167 |
|
168 /** |
|
169 * Unplugs and destroys all plugins on the host |
|
170 * @method _destroyPlugins |
|
171 * @private |
|
172 */ |
|
173 _destroyPlugins: function() { |
|
174 this.unplug(); |
|
175 } |
|
176 }; |
|
177 |
|
178 Y.namespace("Plugin").Host = PluginHost; |
|
179 |
|
180 |
|
181 }, '@VERSION@', {"requires": ["yui-base"]}); |