Cross Reference: /yui3/src/base/docs/index.mustache
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<div class="intro">
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <p>Base is designed to be a low-level foundation class from which other attribute- and event target-based classes in the
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove YUI library can be derived. It provides a standard template for creating attribute-based objects across the
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai library and provides a consistent `init()` and `destroy()` sequence that chains
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai initialization (`initializer`) and destruction (`destructor`) methods for the class hierarchy.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <p>It also provides a way for classes to reuse implementation code through plugins, or through extensions.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</div>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
7595c1df4eac8380e4cedc434e2c4f8ad40ab382Satyen Desai{{>getting-started}}
7595c1df4eac8380e4cedc434e2c4f8ad40ab382Satyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<h2 id="extendbase">Extending Base</h2>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove<p>Although Base can be instantiated, it's really designed to be a root class, which you extend when creating your
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaiown `Attribute` and `EventTarget` based classes as shown below:</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiYUI().use("base", function(Y) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai function MyClass(config) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Invoke Base constructor, passing through arguments
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai MyClass.superclass.constructor.apply(this, arguments);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai Y.extend(MyClass, Y.Base, {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Prototype methods for your new class
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai });
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai});
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove<p>Base itself augments `Attribute`, which in turn augments `EventTarget`; Base is therefore both an <em>Attribute provider</em> and
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaian <em>Event Target</em>.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>Base's constructor expects a configuration object literal, which is used to set up initial values for attributes during construction (discussed below).</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<h2 id="staticprops">Static Properties</h2>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>Base looks for two "static" properties which it requires you to add to your class constructor &mdash; `NAME` and `ATTRS`. Base uses these properties when setting up events and attributes for the class:</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaifunction MyClass(config) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai MyClass.superclass.constructor.apply(this, arguments);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai}
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai// Used to identify instances of this class
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai// For example, to prefix event names
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiMyClass.NAME = "myClass";
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove// "Associative Array", used to define the set of attributes
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai// added by this class. The name of the attribute is the key,
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove// and the object literal value acts as the configuration
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai// object passed to addAttrs
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiMyClass.ATTRS = {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai A : {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Attribute "A" configuration
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai B : {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Attribute "B" configuration
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai}
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiY.extend(MyClass, Y.Base, {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Prototype methods for your new class
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai});
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<h3 id="nameprop">NAME</h3>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>The `NAME` property is a string which is used to identify the class.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>One core area where it is currently used is to prefix all events that are published by instances of your class.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiFor example, any events published by the class `MyClass` in the above code snippet will have the `myClass` prefix. By convention the name string is a camelCase version of the class name.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>Event prefixes allow events with the same name fired from instances of different classes to be uniquely identified, when bubbled or broadcast. For instance, a `click` event on any Menu widget can be discerned by subscribing to the `menu:click` event; an Editor click would be distinguished as `editor:click`. Because YUI 3.x Custom Events bubble, this prefixing allows you to subscribe to events from specific classes at a higher level in your application &mdash; that is, you can listen from common event target, much the way you would when using event delegation when working with DOM events. For example:</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai// NAME is used to prefix the provided event type, if not already prefixed,
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai// when publishing, firing and subscribing to events.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiMyClass.prototype.doSomething = function() {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Actually fires the event type "myclass:enabled"
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai this.fire("enabled");
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai}
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai...
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaivar o = new MyClass(cfg);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaio.on("enabled", function() {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Actually listening for "myclass:enabled".
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai});
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaio.on("myclass:enabled", function() {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Also listening for "myclass:enabled"
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai});
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>The `NAME` property is also used in the default `toString` implementation for Base.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<h3 id="attrsprop">ATTRS</h3>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove<p>The `ATTRS` property is an associative array (an object with attribute name/configuration pairs) which is used to define the default set of
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaiattributes that your class adds to each instance. The instance will contain attributes defined by each class in the class
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grovehierarchy from which it is created, with each class adding the set of attributes and supporting code that it
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desairequires.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
e6180acff02ff08d123f76824eb765a7c25c5bf2Satyen Desai<p>For example, this is the (partial) set of attributes which the <a href="{{apiDocs}}/classes/DD.Drag.html#attrs">Drag</a> class defines:</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiDrag.ATTRS = {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai node: {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai setter: function(node) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai var n = Y.one(node);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai if (!n) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai Y.fail('DD.Drag: Invalid Node Given: ' + node);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai return n;
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai dragNode: {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai setter: function(node) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai var n = Y.one(node);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai if (!n) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai Y.fail('DD.Drag: Invalid dragNode Given: ' + node);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai return n;
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai offsetNode: {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai value: true
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai clickPixelThresh: {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai value: DDM.get('clickPixelThresh')
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai ...
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai}; // End of Drag.ATTRS associative array (object literal)
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove<p>Each property in the object literal (e.g. `"dragNode"`), defines the name of the attribute to be added, and
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaithe corresponding value defines the attribute's configuration. See <a href="../attribute/index.html#configuration">Attribute's discussion of configuration properties</a>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaifor more details about how configuration objects should be structured.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove<p>When instantiating a class derived from Base, Base's `init()` method will initialize
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaithe set of attributes defined by the `ATTRS` property for each class in the class hierarchy. This helps avoid
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaireplication of attribute initialization code in the constructor/initializer of each class.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>It also defines a specific order in which
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaiattributes are initialized &mdash; starting from the Base class first and ending with the specific subclass being instantiated. Within a class, the order in which attributes are defined
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grovein the `ATTRS` property does not matter. If an attribute defined in the `ATTRS` configuration for the class, requests the value of
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Groveanother attribute defined after it in the `ATTRS` configuration (in its `valueFn` or `getter` for example),
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaithe later attribute will be initialized on demand, when the first attribute attempts to `get` the value of the later attribute.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiIt is worth noting that Base adds or initializes attributes lazily for performance reasons, meaning the attribute will not be initialized until the first call to get or set it is made. This behavior
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grovecan be overridden if desired for specific attributes by setting the `lazyAdd` configuration property to `false` (for example if the `setter` for the attribute is responsible
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaifor setting some other non attribute state in the object).
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<h2 id="initdestroy">Initialization and Destruction</h2>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>Base implements final versions of its `init` and `destroy` methods used to establish the initialization and destruction lifecycle phases.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiClasses extending Base can perform operations during initialization or destruction by defining prototype-level `initializer` and `destructor` methods:</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiY.extend(MyClass, Y.Base, {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Prototype methods for your new class
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Tasks MyClass needs to perform during
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // the init() lifecycle phase
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai initializer : function(cfg) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai this._wrapper = Y.Node.create('<div class="yui-wrapper"></div>');
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove // Tasks MyClass needs to perform during
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // the destroy() lifecycle phase
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai destructor : function() {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai Y.Event.purgeElement(this._wrapper);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai this._wrapper.get("parentNode").removeChild(this._wrapper);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai this._wrapper = null;
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai});
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>Base's `init` and `destroy` methods take care of invoking `initializer` and `destructor` methods for each class in the hierarchy.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiThe implementations for each class do not need to call superclass versions of the method. Base ensures that initialization and destruction occur in a fixed order, following the class hierarchy.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<dl>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <dt>`initializer()`</dt>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <dd>
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove Base's `init` method, which is invoked by Base's constructor, will invoke the `initializer` method for each class in the hierarchy &mdash; starting from the Base class first and ending with the subclass being instantiated.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai The `initializer` method for each class is invoked after its attributes have been initialized (as discussed above) and will receive the configuration object literal passed to the `init` method.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai </dd>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <dt>`destructor()`</dt>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <dd>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai Base's `destroy` method, when called, will invoke the `destructor` method for each class in the hierarchy &mdash; starting from the subclass instantiated to create the instance and ending with the Base class (the opposite of initialization).
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai </dd>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</dl>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>If your class does not require any code to be executed during `init` or `destroy`, you do not need to define the corresponding `initializer` or `destructor` method on its prototype.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>The <a href="{{componentAssets}}/mycomponent.js.txt">"MyComponent" template file</a> provides a starting point for you to create your own components derived from `Base`.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<h2 id="plugins">Plugins</h2>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiPlugins can be used to add atomic pieces of functionality or features to instances of objects derived from Base, without having to bake support, or even
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Groveknowledge of the feature, into the core object class. This allows features to be mixed and matched per instance, without having to build all features into a monolithic class or having to ship multiple
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaiclasses with varying permutations of features.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai `Plugin.Host` adds the following key methods to the `Base` class:
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<dl>
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove <dt><a href="{{apiDocs}}/Plugin.Host.html#method_plug">`plug(pluginClass, pluginConfig)`</a></dt>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <dd>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <p>Adds a plugin to the instance with the configuration specified. The `plug` method adds a new instance of the plugin
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai and attaches it to the instance on the namespace (property) defined by the plugin class' `NS` property.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <p>The `plug` method also allows multiple plugins to be added in a single call by passing in an array of plugins with optional configurations as defined in the API documentation.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai </dd>
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove <dt><a href="{{apiDocs}}/Plugin.Host.html#method_unplug">`unplug(pluginClass)`</a> or <a href="{{apiDocs}}/Plugin.Host.html#method_unplug">`unplug(namespace)`</a></dt>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <dd>Removes the provided plugin or the plugin at the attached namespace from the instance and destroys it.</dd>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</dl>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove<p>The above 2 methods are designed to be used after an instance of the component has already been created.
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan GrovePlugins can also be added using the constructor configuration object, using the `plugins`
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaiconfiguration key. For example:</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaivar overlay = new Y.Overlay({
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai srcNode: "#module",
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai plugins : [{fn:AnimPlugin, cfg:{duration:2}}]
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai});
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiAdditionally, if the component developer wants a certain set of plugins added to his or her component by default, static <a href="{{apiDocs}}/Base.html#method_Base.plug">`Base.plug`</a> and <a href="{{apiDocs}}/Base.html#method_Base.unplug">`Base.unplug`</a>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaimethods are provided, allowing the developer to define the list of plugins to be added as part of the class definition.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen DesaiThe <a href="../plugin/index.html">Plugin landing page</a> discusses plugin development in detail. The <a href="../widget/widget-plugin.html">Widget IO Plugin</a>, <a href="../overlay/overlay-io-plugin.html">Overlay IO Plugin</a> and
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<a href="../overlay/overlay-anim-plugin.html">Overlay Animation Plugin</a> examples also provide a concrete look at plugin development.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiThe <a href="{{componentAssets}}/../plugin/myplugin.js.txt">"MyPlugin" template file</a> provides a starting point for you to create your own plugins derived from `Plugin.Base`.
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<h2 id="extensions">Extensions</h2>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>The `Base` class provides a static `build` method used to create custom classes, by mixing a main class, with one or more extension classes.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<p>Extension classes are similar to plugins, in that they encapsulate or bundle specific feature implementations. However extensions are used to mix and match code at the class level, to create new classes, whereas plugins are used to mix and match code at the instance level.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai<p>In addition to `build`, Base also provides the static `create` and `mix` methods, which are sugar methods on top of `Base.build`.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai<dl>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai <dt><a href="{{apiDocs}}/Base.html#method_Base.create">`Base.create`</a></dt>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai <dd>The `create` sugar method makes the task of creating a completely new class, which mixes in extensions, a lot more succint, by providing a way for the caller to pass in additional prototype and static properties which
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai will exist on the newly created class.</dd>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai <dt><a href="{{apiDocs}}/Base.html#method_Base.mix">`Base.mix`</a></dt>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai <dd>The `mix` sugar method on the other hand, can be used to add extensions into an already existing class.</dd>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai</dl>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai<h3>Create</h3>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai<p>The `Base.create` method can be used to dynamically create new classes that are derived from an existing main class and mix in additional "extension" classes to add methods, attributes, events and properties to the main class.
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai`Base.create` leaves the original main and mixed-in classes untouched so that the main class can still be used without the additional features mixed in. `Base.mix`, on the other hand, can be used if modifying an existing class is the goal.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai/* Main Class */
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaifunction Panel(cfg) {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai Panel.superclass.constructor.apply(this, arguments);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai}
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiPanel.ATTRS = {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Panel attributes
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai close : { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai minimize : { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai shadow : { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai ...
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai};
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiY.extend(Panel, Y.Base, {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai // Panel methods
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai show : function() { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai hide : function() { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai minimize : function() { ... }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai};
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai/* Additional Resizable Feature */
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaifunction Resizable() {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai this._initResizable();
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai}
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiResizable.ATTRS = {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai handles : { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai constrain : { ... }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai};
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiResizable.prototype = {
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove _initResizable : function() { ... }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai lock : function() { ... }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai};
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai/* Additional Modality Feature */
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaifunction Modal() {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai this._initModality();
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai}
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiModal.ATTRS = {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai modal : { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai region : { ... }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai};
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen DesaiModal.prototype = {
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai _initModality : function() { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai showMask() : function() { ... },
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai hideMask() : function() { ... }
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai};
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove// Create a new class WindowPanel, which extends Panel, and
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai// combines methods/attributes from Resizable and Modal
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desaivar WindowPanel = Y.Base.create("windowPanel", Panel, [Resizable, Modal]);
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaivar wp = new WindowPanel({
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove shadow: true,
3cca96e417d4ba9bb3ff6882b6a29378351ea3f3Ryan Grove modal: true,
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai handles:["e", "s", "se"]
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai});
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaiwp.show();
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desaiwp.lock();
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai```
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai<p>Under the hood, `Base.create`:</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai<ul>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <li>Creates a new 'built' class by extending the main class passed in as the first argument.</li>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai <li>Augments the list of feature classes, or extensions, to the built class, so that it now has their prototype methods.</li>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai <li>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai <p>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai Aggregates or copies any known static properties on the built class. Static properties to setup on the built class are defined by the component or class author, through a `_buildCfg` static property on the main class, or on the extension.
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai For example Base defines the `ATTRS` property as a property which needs to be custom aggregated when mixing in extentions, and Widget adds the `HTML_PARSER` property for aggregation.
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai </p>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai <p>
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai The <a href="{{apiDocs}}/Base.html#method_Base.create">`Base.create` API Documention</a> provides more details about the structure of `_buildCfg` and how it can be used by component authors.
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai </p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai </li>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai</ul>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai<p>The new class constructor created by `Base.create` will invoke the constructors for the main and feature classes when the new class is instantiated, during the init part of the lifecycle.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
6db1a39fd114a49560ef9175038d39486ce8b532Satyen Desai<p>See Base's <a href="{{apiDocs}}/Base.html">`API documentation`</a> for more details on the `create` and `mix` methods.</p>
02116a8536c9212761e6bf4c29521c9e8af4988eSatyen Desai
e808b8824ca1091c8efb5669db9129e68e5e1c14Satyen Desai<p>The <a href="{{componentAssets}}/myextension.js.txt">"MyExtension" template file</a> provides a starting point for you to create your own extensions.</p>