2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('attribute-observable', function (Y, NAME) {
15 * The attribute module provides an augmentable Attribute implementation, which
16 * adds configurable attributes and attribute change events to the class being
17 * augmented. It also provides a State class, which is used internally by Attribute,
18 * but can also be used independently to provide a name/property/value data structure to
25 * The `attribute-observable` submodule provides augmentable attribute change event support
26 * for AttributeCore based implementations.
29 * @submodule attribute-observable
31 var EventTarget = Y.EventTarget,
34 BROADCAST = "broadcast";
37 * Provides an augmentable implementation of attribute change events for
40 * @class AttributeObservable
41 * @extensionfor AttributeCore
44 function AttributeObservable() {
45 // Perf tweak - avoid creating event literals if not required.
46 this._ATTR_E_FACADE = {};
48 EventTarget.call(this, {emitFacade:true});
51 AttributeObservable._ATTR_CFG = [BROADCAST];
53 AttributeObservable.prototype = {
56 * Sets the value of an attribute.
61 * @param {String} name The name of the attribute. If the
62 * current value of the attribute is an Object, dot notation can be used
63 * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
65 * @param {Any} value The value to set the attribute to.
67 * @param {Object} opts (Optional) Optional event data to be mixed into
68 * the event facade passed to subscribers of the attribute's change event. This
69 * can be used as a flexible way to identify the source of a call to set, allowing
70 * the developer to distinguish between set called internally by the host, vs.
71 * set called externally by the application developer.
73 * @return {Object} A reference to the host object.
75 set : function(name, val, opts) {
76 return this._setAttr(name, val, opts);
80 * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
86 * @param {String} name The name of the attribute.
87 * @param {Any} val The value to set the attribute to.
88 * @param {Object} opts (Optional) Optional event data to be mixed into
89 * the event facade passed to subscribers of the attribute's change event.
90 * @return {Object} A reference to the host object.
92 _set : function(name, val, opts) {
93 return this._setAttr(name, val, opts, true);
97 * Sets multiple attribute values.
100 * @param {Object} attrs An object with attributes name/value pairs.
101 * @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set
102 * @return {Object} A reference to the host object.
105 setAttrs : function(attrs, opts) {
106 return this._setAttrs(attrs, opts);
110 * Implementation behind the public setAttrs method, to set multiple attribute values.
114 * @param {Object} attrs An object with attributes name/value pairs.
115 * @param {Object} opts Properties to mix into the event payload. These are shared and mixed into each set
116 * @return {Object} A reference to the host object.
119 _setAttrs : function(attrs, opts) {
121 for (attr in attrs) {
122 if ( attrs.hasOwnProperty(attr) ) {
123 this.set(attr, attrs[attr], opts);
130 * Utility method to help setup the event payload and fire the attribute change event.
132 * @method _fireAttrChange
134 * @param {String} attrName The name of the attribute
135 * @param {String} subAttrName The full path of the property being changed,
136 * if this is a sub-attribute value being change. Otherwise null.
137 * @param {Any} currVal The current value of the attribute
138 * @param {Any} newVal The new value of the attribute
139 * @param {Object} opts Any additional event data to mix into the attribute change event's event facade.
140 * @param {Object} [cfg] The attribute config stored in State, if already available.
142 _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) {
144 eventName = this._getFullType(attrName + CHANGE),
151 cfg = state.data[attrName] || {};
154 if (!cfg.published) {
156 // PERF: Using lower level _publish() for
157 // critical path performance
158 e = host._publish(eventName);
161 e.defaultTargetOnly = true;
162 e.defaultFn = host._defAttrChangeFn;
164 broadcast = cfg.broadcast;
165 if (broadcast !== undefined) {
166 e.broadcast = broadcast;
169 cfg.published = true;
173 facade = Y.merge(opts);
174 facade._attrOpts = opts;
176 facade = host._ATTR_E_FACADE;
179 // Not using the single object signature for fire({type:..., newVal:...}), since
180 // we don't want to override type. Changed to the fire(type, {newVal:...}) signature.
182 facade.attrName = attrName;
183 facade.subAttrName = subAttrName;
184 facade.prevVal = currVal;
185 facade.newVal = newVal;
187 if (host._hasPotentialSubscribers(eventName)) {
188 host.fire(eventName, facade);
190 this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg);
195 * Default function for attribute change events.
198 * @method _defAttrChangeFn
199 * @param {EventFacade} e The event object for attribute change events.
200 * @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not
202 _defAttrChangeFn : function(e, eventFastPath) {
204 var opts = e._attrOpts;
209 if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) {
211 Y.log('State not updated and stopImmediatePropagation called for attribute: ' + e.attrName + ' , value:' + e.newVal, 'warn', 'attribute');
213 if (!eventFastPath) {
214 // Prevent "after" listeners from being invoked since nothing changed.
215 e.stopImmediatePropagation();
219 if (!eventFastPath) {
220 e.newVal = this.get(e.attrName);
226 // Basic prototype augment - no lazy constructor invocation.
227 Y.mix(AttributeObservable, EventTarget, false, null, 1);
229 Y.AttributeObservable = AttributeObservable;
232 The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now
233 an alias for the `AttributeObservable` class extension. Use that class
234 extnesion instead. This alias will be removed in a future version of YUI.
236 @class AttributeEvents
238 @deprecated Use `AttributeObservable` instead.
239 @see AttributeObservable
241 Y.AttributeEvents = AttributeObservable;
244 }, '3.13.0', {"requires": ["event-custom"]});