3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
7 YUI.add('attribute-events', function(Y) {
10 * The attribute module provides an augmentable Attribute implementation, which
11 * adds configurable attributes and attribute change events to the class being
12 * augmented. It also provides a State class, which is used internally by Attribute,
13 * but can also be used independently to provide a name/property/value data structure to
20 * The attribute-events submodule provides augmentable attribute change event support
21 * for AttributeCore based implementations.
24 * @submodule attribute-events
26 var EventTarget = Y.EventTarget,
29 BROADCAST = "broadcast",
30 PUBLISHED = "published";
33 * Provides an augmentable implementation of attribute change events for
36 * @class AttributeEvents
39 function AttributeEvents() {
40 // Perf tweak - avoid creating event literals if not required.
41 this._ATTR_E_FACADE = {};
42 EventTarget.call(this, {emitFacade:true});
45 AttributeEvents._ATTR_CFG = [BROADCAST];
47 AttributeEvents.prototype = {
50 * Sets the value of an attribute.
55 * @param {String} name The name of the attribute. If the
56 * current value of the attribute is an Object, dot notation can be used
57 * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
59 * @param {Any} value The value to set the attribute to.
61 * @param {Object} opts (Optional) Optional event data to be mixed into
62 * the event facade passed to subscribers of the attribute's change event. This
63 * can be used as a flexible way to identify the source of a call to set, allowing
64 * the developer to distinguish between set called internally by the host, vs.
65 * set called externally by the application developer.
67 * @return {Object} A reference to the host object.
69 set : function(name, val, opts) {
70 return this._setAttr(name, val, opts);
74 * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
80 * @param {String} name The name of the attribute.
81 * @param {Any} val The value to set the attribute to.
82 * @param {Object} opts (Optional) Optional event data to be mixed into
83 * the event facade passed to subscribers of the attribute's change event.
84 * @return {Object} A reference to the host object.
86 _set : function(name, val, opts) {
87 return this._setAttr(name, val, opts, true);
91 * Sets multiple attribute values.
94 * @param {Object} attrs An object with attributes name/value pairs.
95 * @return {Object} A reference to the host object.
98 setAttrs : function(attrs, opts) {
99 return this._setAttrs(attrs, opts);
103 * Utility method to help setup the event payload and fire the attribute change event.
105 * @method _fireAttrChange
107 * @param {String} attrName The name of the attribute
108 * @param {String} subAttrName The full path of the property being changed,
109 * if this is a sub-attribute value being change. Otherwise null.
110 * @param {Any} currVal The current value of the attribute
111 * @param {Any} newVal The new value of the attribute
112 * @param {Object} opts Any additional event data to mix into the attribute change event's event facade.
114 _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts) {
116 eventName = attrName + CHANGE,
122 if (!state.get(attrName, PUBLISHED)) {
126 defaultTargetOnly: true,
127 defaultFn:host._defAttrChangeFn,
131 broadcast = state.get(attrName, BROADCAST);
132 if (broadcast !== undefined) {
133 evtCfg.broadcast = broadcast;
136 host.publish(eventName, evtCfg);
138 state.add(attrName, PUBLISHED, true);
141 facade = (opts) ? Y.merge(opts) : host._ATTR_E_FACADE;
143 // Not using the single object signature for fire({type:..., newVal:...}), since
144 // we don't want to override type. Changed to the fire(type, {newVal:...}) signature.
146 // facade.type = eventName;
147 facade.attrName = attrName;
148 facade.subAttrName = subAttrName;
149 facade.prevVal = currVal;
150 facade.newVal = newVal;
152 // host.fire(facade);
153 host.fire(eventName, facade);
157 * Default function for attribute change events.
160 * @method _defAttrChangeFn
161 * @param {EventFacade} e The event object for attribute change events.
163 _defAttrChangeFn : function(e) {
164 if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal)) {
165 // Prevent "after" listeners from being invoked since nothing changed.
166 e.stopImmediatePropagation();
168 e.newVal = this.get(e.attrName);
173 // Basic prototype augment - no lazy constructor invocation.
174 Y.mix(AttributeEvents, EventTarget, false, null, 1);
176 Y.AttributeEvents = AttributeEvents;
179 }, '3.5.0' ,{requires:['event-custom']});