|
1 YUI.add('base-observable', function (Y, NAME) { |
|
2 |
|
3 /** |
|
4 The `base-observable` submodule adds observability to Base's lifecycle and |
|
5 attributes, and also make it an `EventTarget`. |
|
6 |
|
7 @module base |
|
8 @submodule base-observable |
|
9 **/ |
|
10 var L = Y.Lang, |
|
11 |
|
12 DESTROY = "destroy", |
|
13 INIT = "init", |
|
14 |
|
15 BUBBLETARGETS = "bubbleTargets", |
|
16 _BUBBLETARGETS = "_bubbleTargets", |
|
17 |
|
18 AttributeObservable = Y.AttributeObservable, |
|
19 BaseCore = Y.BaseCore; |
|
20 |
|
21 /** |
|
22 Provides an augmentable implementation of lifecycle and attribute events for |
|
23 `BaseCore`. |
|
24 |
|
25 @class BaseObservable |
|
26 @extensionfor BaseCore |
|
27 @uses AttributeObservable |
|
28 @uses EventTarget |
|
29 @since 3.8.0 |
|
30 **/ |
|
31 function BaseObservable() {} |
|
32 |
|
33 BaseObservable._ATTR_CFG = AttributeObservable._ATTR_CFG.concat(); |
|
34 BaseObservable._NON_ATTRS_CFG = ["on", "after", "bubbleTargets"]; |
|
35 |
|
36 BaseObservable.prototype = { |
|
37 |
|
38 /** |
|
39 * Initializes Attribute |
|
40 * |
|
41 * @method _initAttribute |
|
42 * @private |
|
43 */ |
|
44 _initAttribute: function() { |
|
45 BaseCore.prototype._initAttribute.apply(this, arguments); |
|
46 AttributeObservable.call(this); |
|
47 |
|
48 this._eventPrefix = this.constructor.EVENT_PREFIX || this.constructor.NAME; |
|
49 this._yuievt.config.prefix = this._eventPrefix; |
|
50 }, |
|
51 |
|
52 /** |
|
53 * Init lifecycle method, invoked during construction. |
|
54 * Fires the init event prior to setting up attributes and |
|
55 * invoking initializers for the class hierarchy. |
|
56 * |
|
57 * @method init |
|
58 * @chainable |
|
59 * @param {Object} config Object with configuration property name/value pairs |
|
60 * @return {Base} A reference to this object |
|
61 */ |
|
62 init: function(config) { |
|
63 |
|
64 /** |
|
65 * <p> |
|
66 * Lifecycle event for the init phase, fired prior to initialization. |
|
67 * Invoking the preventDefault() method on the event object provided |
|
68 * to subscribers will prevent initialization from occuring. |
|
69 * </p> |
|
70 * <p> |
|
71 * Subscribers to the "after" momemt of this event, will be notified |
|
72 * after initialization of the object is complete (and therefore |
|
73 * cannot prevent initialization). |
|
74 * </p> |
|
75 * |
|
76 * @event init |
|
77 * @preventable _defInitFn |
|
78 * @param {EventFacade} e Event object, with a cfg property which |
|
79 * refers to the configuration object passed to the constructor. |
|
80 */ |
|
81 |
|
82 // PERF: Using lower level _publish() for |
|
83 // critical path performance |
|
84 |
|
85 var type = this._getFullType(INIT), |
|
86 e = this._publish(type); |
|
87 |
|
88 e.emitFacade = true; |
|
89 e.fireOnce = true; |
|
90 e.defaultTargetOnly = true; |
|
91 e.defaultFn = this._defInitFn; |
|
92 |
|
93 this._preInitEventCfg(config); |
|
94 |
|
95 if (e._hasPotentialSubscribers()) { |
|
96 this.fire(type, {cfg: config}); |
|
97 } else { |
|
98 |
|
99 this._baseInit(config); |
|
100 |
|
101 // HACK. Major hack actually. But really fast for no-listeners. |
|
102 // Since it's fireOnce, subscribers may come along later, so since we're |
|
103 // bypassing the event stack the first time, we need to tell the published |
|
104 // event that it's been "fired". Could extract it into a CE method? |
|
105 e.fired = true; |
|
106 e.firedWith = [{cfg:config}]; |
|
107 } |
|
108 |
|
109 return this; |
|
110 }, |
|
111 |
|
112 /** |
|
113 * Handles the special on, after and target properties which allow the user to |
|
114 * easily configure on and after listeners as well as bubble targets during |
|
115 * construction, prior to init. |
|
116 * |
|
117 * @private |
|
118 * @method _preInitEventCfg |
|
119 * @param {Object} config The user configuration object |
|
120 */ |
|
121 _preInitEventCfg : function(config) { |
|
122 if (config) { |
|
123 if (config.on) { |
|
124 this.on(config.on); |
|
125 } |
|
126 if (config.after) { |
|
127 this.after(config.after); |
|
128 } |
|
129 } |
|
130 |
|
131 var i, l, target, |
|
132 userTargets = (config && BUBBLETARGETS in config); |
|
133 |
|
134 if (userTargets || _BUBBLETARGETS in this) { |
|
135 target = userTargets ? (config && config.bubbleTargets) : this._bubbleTargets; |
|
136 |
|
137 if (L.isArray(target)) { |
|
138 for (i = 0, l = target.length; i < l; i++) { |
|
139 this.addTarget(target[i]); |
|
140 } |
|
141 } else if (target) { |
|
142 this.addTarget(target); |
|
143 } |
|
144 } |
|
145 }, |
|
146 |
|
147 /** |
|
148 * <p> |
|
149 * Destroy lifecycle method. Fires the destroy |
|
150 * event, prior to invoking destructors for the |
|
151 * class hierarchy. |
|
152 * </p> |
|
153 * <p> |
|
154 * Subscribers to the destroy |
|
155 * event can invoke preventDefault on the event object, to prevent destruction |
|
156 * from proceeding. |
|
157 * </p> |
|
158 * @method destroy |
|
159 * @return {Base} A reference to this object |
|
160 * @chainable |
|
161 */ |
|
162 destroy: function() { |
|
163 Y.log('destroy called', 'life', 'base'); |
|
164 |
|
165 /** |
|
166 * <p> |
|
167 * Lifecycle event for the destroy phase, |
|
168 * fired prior to destruction. Invoking the preventDefault |
|
169 * method on the event object provided to subscribers will |
|
170 * prevent destruction from proceeding. |
|
171 * </p> |
|
172 * <p> |
|
173 * Subscribers to the "after" moment of this event, will be notified |
|
174 * after destruction is complete (and as a result cannot prevent |
|
175 * destruction). |
|
176 * </p> |
|
177 * @event destroy |
|
178 * @preventable _defDestroyFn |
|
179 * @param {EventFacade} e Event object |
|
180 */ |
|
181 this.publish(DESTROY, { |
|
182 fireOnce:true, |
|
183 defaultTargetOnly:true, |
|
184 defaultFn: this._defDestroyFn |
|
185 }); |
|
186 this.fire(DESTROY); |
|
187 |
|
188 this.detachAll(); |
|
189 return this; |
|
190 }, |
|
191 |
|
192 /** |
|
193 * Default init event handler |
|
194 * |
|
195 * @method _defInitFn |
|
196 * @param {EventFacade} e Event object, with a cfg property which |
|
197 * refers to the configuration object passed to the constructor. |
|
198 * @protected |
|
199 */ |
|
200 _defInitFn : function(e) { |
|
201 this._baseInit(e.cfg); |
|
202 }, |
|
203 |
|
204 /** |
|
205 * Default destroy event handler |
|
206 * |
|
207 * @method _defDestroyFn |
|
208 * @param {EventFacade} e Event object |
|
209 * @protected |
|
210 */ |
|
211 _defDestroyFn : function(e) { |
|
212 this._baseDestroy(e.cfg); |
|
213 } |
|
214 }; |
|
215 |
|
216 Y.mix(BaseObservable, AttributeObservable, false, null, 1); |
|
217 |
|
218 Y.BaseObservable = BaseObservable; |
|
219 |
|
220 |
|
221 }, '@VERSION@', {"requires": ["attribute-observable", "base-core"]}); |