Merge branch 'MDL-32509' of git://github.com/danpoltawski/moodle
[moodle.git] / lib / yui / 3.5.0 / build / attribute-events / attribute-events.js
blobbe18dea4685dafcae05ac6ddc1d3e0676338ba2f
1 /*
2 YUI 3.5.0 (build 5089)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('attribute-events', function(Y) {
9     /**
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
14      * store state.
15      *
16      * @module attribute
17      */
19     /**
20      * The attribute-events submodule provides augmentable attribute change event support 
21      * for AttributeCore based implementations.
22      *
23      * @module attribute
24      * @submodule attribute-events
25      */
26     var EventTarget = Y.EventTarget,
28         CHANGE = "Change",
29         BROADCAST = "broadcast",
30         PUBLISHED = "published";
32     /**
33      * Provides an augmentable implementation of attribute change events for 
34      * AttributeCore. 
35      *
36      * @class AttributeEvents
37      * @uses EventTarget
38      */
39     function AttributeEvents() {
40         // Perf tweak - avoid creating event literals if not required.
41         this._ATTR_E_FACADE = {};
42         EventTarget.call(this, {emitFacade:true});
43     }
45     AttributeEvents._ATTR_CFG = [BROADCAST];
47     AttributeEvents.prototype = {
49         /**
50          * Sets the value of an attribute.
51          *
52          * @method set
53          * @chainable
54          *
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>).
58          *
59          * @param {Any} value The value to set the attribute to.
60          *
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.
66          *
67          * @return {Object} A reference to the host object.
68          */
69         set : function(name, val, opts) {
70             return this._setAttr(name, val, opts);
71         },
73         /**
74          * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
75          *
76          * @method _set
77          * @protected
78          * @chainable
79          * 
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.
85          */
86         _set : function(name, val, opts) {
87             return this._setAttr(name, val, opts, true);
88         },
90         /**
91          * Sets multiple attribute values.
92          *
93          * @method setAttrs
94          * @param {Object} attrs  An object with attributes name/value pairs.
95          * @return {Object} A reference to the host object.
96          * @chainable
97          */
98         setAttrs : function(attrs, opts) {
99             return this._setAttrs(attrs, opts);
100         },
102         /**
103          * Utility method to help setup the event payload and fire the attribute change event.
104          * 
105          * @method _fireAttrChange
106          * @private
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.
113          */
114         _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts) {
115             var host = this,
116                 eventName = attrName + CHANGE,
117                 state = host._state,
118                 facade,
119                 broadcast,
120                 evtCfg;
122             if (!state.get(attrName, PUBLISHED)) {
123                 
124                 evtCfg = {
125                     queuable:false,
126                     defaultTargetOnly: true, 
127                     defaultFn:host._defAttrChangeFn, 
128                     silent:true
129                 };
131                 broadcast = state.get(attrName, BROADCAST);
132                 if (broadcast !== undefined) {
133                     evtCfg.broadcast = broadcast;
134                 }
136                 host.publish(eventName, evtCfg);
137                 
138                 state.add(attrName, PUBLISHED, true);
139             }
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);
154         },
156         /**
157          * Default function for attribute change events.
158          *
159          * @private
160          * @method _defAttrChangeFn
161          * @param {EventFacade} e The event object for attribute change events.
162          */
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();
167             } else {
168                 e.newVal = this.get(e.attrName);
169             }
170         }
171     };
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']});