~landscape/lazr-js/trunk

« back to all changes in this revision

Viewing changes to src-js/lazrjs/yui/3.0.0/build/pluginhost/pluginhost-debug.js

  • Committer: Sidnei da Silva
  • Date: 2009-10-21 21:43:07 UTC
  • mfrom: (120.2.15 yui-3.0.0)
  • mto: (124.5.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 126.
  • Revision ID: sidnei.da.silva@canonical.com-20091021214307-mpul9404n317puk5
- Merge from yui-3.0.0, resolving conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.net/yui/license.txt
 
5
version: 3.0.0
 
6
build: 1549
 
7
*/
 
8
YUI.add('pluginhost', function(Y) {
 
9
 
 
10
    /**
 
11
     * Provides the augmentable PluginHost interface, which can be added to any class.
 
12
     * @module pluginhost
 
13
     */
 
14
 
 
15
    /**
 
16
     * <p>
 
17
     * An augmentable class, which provides the augmented class with the ability to host plugins.
 
18
     * It adds <a href="#method_plug">plug</a> and <a href="#method_unplug">unplug</a> methods to the augmented class, which can 
 
19
     * be used to add or remove plugins from instances of the class.
 
20
     * </p>
 
21
     *
 
22
     * <p>Plugins can also be added through the constructor configuration object passed to the host class' constructor using
 
23
     * the "plugins" property. Supported values for the "plugins" property are those defined by the <a href="#method_plug">plug</a> method. 
 
24
     * 
 
25
     * For example the following code would add the AnimPlugin and IOPlugin to Overlay (the plugin host):
 
26
     * <xmp>
 
27
     * var o = new Overlay({plugins: [ AnimPlugin, {fn:IOPlugin, cfg:{section:"header"}}]});
 
28
     * </xmp>
 
29
     * </p>
 
30
     * <p>
 
31
     * Plug.Host's protected <a href="#method_initPlugins">_initPlugins</a> and <a href="#method_destroyPlugins">_destroyPlugins</a> 
 
32
     * methods should be invoked by the host class at the appropriate point in the host's lifecyle.  
 
33
     * </p>
 
34
     *
 
35
     * @class Plugin.Host
 
36
     */
 
37
 
 
38
    var L = Y.Lang;
 
39
 
 
40
    function PluginHost() {
 
41
        this._plugins = {};
 
42
    }
 
43
 
 
44
    PluginHost.prototype = {
 
45
 
 
46
        /**
 
47
         * Adds a plugin to the host object. This will instantiate the 
 
48
         * plugin and attach it to the configured namespace on the host object.
 
49
         *
 
50
         * @method plug
 
51
         * @chainable
 
52
         * @param p {Function | Object |Array} Accepts the plugin class, or an 
 
53
         * object with a "fn" property specifying the plugin class and 
 
54
         * a "cfg" property specifying the configuration for the Plugin.
 
55
         * <p>
 
56
         * Additionally an Array can also be passed in, with the above function or 
 
57
         * object values, allowing the user to add multiple plugins in a single call.
 
58
         * </p>
 
59
         * @param config (Optional) If the first argument is the plugin class, the second argument
 
60
         * can be the configuration for the plugin.
 
61
         * @return {Base} A reference to the host object
 
62
         */
 
63
 
 
64
        plug: function(p, config) {
 
65
            if (p) {
 
66
                if (L.isFunction(p)) {
 
67
                    this._plug(p, config);
 
68
                } else if (L.isArray(p)) {
 
69
                    for (var i = 0, ln = p.length; i < ln; i++) {
 
70
                        this.plug(p[i]);
 
71
                    }
 
72
                } else {
 
73
                    this._plug(p.fn, p.cfg);
 
74
                }
 
75
            }
 
76
            return this;
 
77
        },
 
78
 
 
79
        /**
 
80
         * Removes a plugin from the host object. This will destroy the 
 
81
         * plugin instance and delete the namepsace from the host object. 
 
82
         *
 
83
         * @method unplug
 
84
         * @param {String | Function} plugin The namespace of the plugin, or the plugin class with the static NS namespace property defined. If not provided,
 
85
         * all registered plugins are unplugged.
 
86
         * @return {Base} A reference to the host object
 
87
         * @chainable
 
88
         */
 
89
        unplug: function(plugin) {
 
90
            if (plugin) {
 
91
                this._unplug(plugin);
 
92
            } else {
 
93
                var ns;
 
94
                for (ns in this._plugins) {
 
95
                    if (this._plugins.hasOwnProperty(ns)) {
 
96
                        this._unplug(ns);
 
97
                    }
 
98
                }
 
99
            }
 
100
            return this;
 
101
        },
 
102
 
 
103
        /**
 
104
         * Determines if a plugin has plugged into this host.
 
105
         *
 
106
         * @method hasPlugin
 
107
         * @param {String} ns The plugin's namespace
 
108
         * @return {boolean} returns true, if the plugin has been plugged into this host, false otherwise.
 
109
         */
 
110
        hasPlugin : function(ns) {
 
111
            return (this._plugins[ns] && this[ns]);
 
112
        },
 
113
 
 
114
        /**
 
115
         * Initializes static plugins registered on the host (using the
 
116
         * Base.plug static method) and any plugins passed to the 
 
117
         * instance through the "plugins" configuration property.
 
118
         *
 
119
         * @method _initPlugins
 
120
         * @param {Config} config The configuration object with property name/value pairs.
 
121
         * @private
 
122
         */
 
123
        _initPlugins: function(config) {
 
124
            this._plugins = this._plugins || {};
 
125
 
 
126
            // Class Configuration
 
127
            var classes = (this._getClasses) ? this._getClasses() : [this.constructor],
 
128
                plug = [],
 
129
                unplug = {},
 
130
                constructor, i, classPlug, classUnplug, pluginClassName;
 
131
 
 
132
            //TODO: Room for optimization. Can we apply statically/unplug in same pass?
 
133
            for (i = classes.length - 1; i >= 0; i--) {
 
134
                constructor = classes[i];
 
135
 
 
136
                classUnplug = constructor._UNPLUG;
 
137
                if (classUnplug) {
 
138
                    // subclasses over-write
 
139
                    Y.mix(unplug, classUnplug, true);
 
140
                }
 
141
 
 
142
                classPlug = constructor._PLUG;
 
143
                if (classPlug) {
 
144
                    // subclasses over-write
 
145
                    Y.mix(plug, classPlug, true);
 
146
                }
 
147
            }
 
148
    
 
149
            for (pluginClassName in plug) {
 
150
                if (plug.hasOwnProperty(pluginClassName)) {
 
151
                    if (!unplug[pluginClassName]) {
 
152
                        this.plug(plug[pluginClassName]);
 
153
                    }
 
154
                }
 
155
            }
 
156
    
 
157
            // User Configuration
 
158
            if (config && config.plugins) {
 
159
                this.plug(config.plugins);
 
160
            }
 
161
        },
 
162
 
 
163
        /**
 
164
         * Unplugs and destroys all plugins on the host
 
165
         * @method _destroyPlugins
 
166
         * @private
 
167
         */
 
168
        _destroyPlugins: function() {
 
169
            this._unplug();
 
170
        },
 
171
 
 
172
        /**
 
173
         * Private method used to instantiate and attach plugins to the host
 
174
         *
 
175
         * @method _plug
 
176
         * @param {Function} PluginClass The plugin class to instantiate
 
177
         * @param {Object} config The configuration object for the plugin
 
178
         * @private
 
179
         */
 
180
        _plug: function(PluginClass, config) {
 
181
            if (PluginClass && PluginClass.NS) {
 
182
                var ns = PluginClass.NS;
 
183
    
 
184
                config = config || {};
 
185
                config.host = this;
 
186
    
 
187
                if (this.hasPlugin(ns)) {
 
188
                    // Update config
 
189
                    this[ns].setAttrs(config);
 
190
                } else {
 
191
                    // Create new instance
 
192
                    this[ns] = new PluginClass(config);
 
193
                    this._plugins[ns] = PluginClass;
 
194
                }
 
195
            }
 
196
        },
 
197
 
 
198
        /**
 
199
         * Unplugs and destroys a plugin already instantiated with the host.
 
200
         *
 
201
         * @method _unplug
 
202
         * @private
 
203
         * @param {String | Function} plugin The namespace for the plugin, or a plugin class with the static NS property defined.
 
204
         */
 
205
        _unplug : function(plugin) {
 
206
            var ns = plugin, 
 
207
                plugins = this._plugins;
 
208
    
 
209
            if (L.isFunction(plugin)) {
 
210
                ns = plugin.NS;
 
211
                if (ns && (!plugins[ns] || plugins[ns] !== plugin)) {
 
212
                    ns = null;
 
213
                }
 
214
            }
 
215
    
 
216
            if (ns) {
 
217
                if (this[ns]) {
 
218
                    this[ns].destroy();
 
219
                    delete this[ns];
 
220
                }
 
221
                if (plugins[ns]) {
 
222
                    delete plugins[ns];
 
223
                }
 
224
            }
 
225
        }
 
226
    };
 
227
    
 
228
    /**
 
229
     * Registers plugins to be instantiated at the class level (plugins 
 
230
     * which should be plugged into every instance of the class by default).
 
231
     *
 
232
     * @method Plugin.Host.plug
 
233
     * @static
 
234
     *
 
235
     * @param {Function} hostClass The host class on which to register the plugins
 
236
     * @param {Function | Array} plugin Either the plugin class, an array of plugin classes or an array of objects (with fn and cfg properties defined)
 
237
     * @param {Object} config (Optional) If plugin is the plugin class, the configuration for the plugin
 
238
     */
 
239
    PluginHost.plug = function(hostClass, plugin, config) {
 
240
        // Cannot plug into Base, since Plugins derive from Base [ will cause infinite recurrsion ]
 
241
        var p, i, l, name;
 
242
    
 
243
        if (hostClass !== Y.Base) {
 
244
            hostClass._PLUG = hostClass._PLUG || {};
 
245
    
 
246
            if (!L.isArray(plugin)) {
 
247
                if (config) {
 
248
                    plugin = {fn:plugin, cfg:config};
 
249
                }
 
250
                plugin = [plugin];
 
251
            }
 
252
    
 
253
            for (i = 0, l = plugin.length; i < l;i++) {
 
254
                p = plugin[i];
 
255
                name = p.NAME || p.fn.NAME;
 
256
                hostClass._PLUG[name] = p;
 
257
            }
 
258
        }
 
259
    };
 
260
 
 
261
    /**
 
262
     * Unregisters any class level plugins which have been registered by the host class, or any
 
263
     * other class in the hierarchy.
 
264
     *
 
265
     * @method Plugin.Host.unplug
 
266
     * @static
 
267
     *
 
268
     * @param {Function} hostClass The host class from which to unregister the plugins
 
269
     * @param {Function | Array} plugin The plugin class, or an array of plugin classes
 
270
     */
 
271
    PluginHost.unplug = function(hostClass, plugin) {
 
272
        var p, i, l, name;
 
273
    
 
274
        if (hostClass !== Y.Base) {
 
275
            hostClass._UNPLUG = hostClass._UNPLUG || {};
 
276
    
 
277
            if (!L.isArray(plugin)) {
 
278
                plugin = [plugin];
 
279
            }
 
280
    
 
281
            for (i = 0, l = plugin.length; i < l; i++) {
 
282
                p = plugin[i];
 
283
                name = p.NAME;
 
284
                if (!hostClass._PLUG[name]) {
 
285
                    hostClass._UNPLUG[name] = p;
 
286
                } else {
 
287
                    delete hostClass._PLUG[name];
 
288
                }
 
289
            }
 
290
        }
 
291
    };
 
292
 
 
293
    Y.namespace("Plugin").Host = PluginHost;
 
294
 
 
295
 
 
296
}, '3.0.0' ,{requires:['yui-base']});