NOBUG: Fixed file access permissions
[moodle.git] / lib / yuilib / 3.13.0 / attribute-observable / attribute-observable-debug.js
blobe757a1e51c8ce646b967efc79f76830e9a0cdf19
1 /*
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/
6 */
8 YUI.add('attribute-observable', function (Y, NAME) {
10     /*For log lines*/
11     /*jshint maxlen:200*/
14     /**
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
19      * store state.
20      *
21      * @module attribute
22      */
24     /**
25      * The `attribute-observable` submodule provides augmentable attribute change event support
26      * for AttributeCore based implementations.
27      *
28      * @module attribute
29      * @submodule attribute-observable
30      */
31     var EventTarget = Y.EventTarget,
33         CHANGE = "Change",
34         BROADCAST = "broadcast";
36     /**
37      * Provides an augmentable implementation of attribute change events for
38      * AttributeCore.
39      *
40      * @class AttributeObservable
41      * @extensionfor AttributeCore
42      * @uses EventTarget
43      */
44     function AttributeObservable() {
45         // Perf tweak - avoid creating event literals if not required.
46         this._ATTR_E_FACADE = {};
48         EventTarget.call(this, {emitFacade:true});
49     }
51     AttributeObservable._ATTR_CFG = [BROADCAST];
53     AttributeObservable.prototype = {
55         /**
56          * Sets the value of an attribute.
57          *
58          * @method set
59          * @chainable
60          *
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>).
64          *
65          * @param {Any} value The value to set the attribute to.
66          *
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.
72          *
73          * @return {Object} A reference to the host object.
74          */
75         set : function(name, val, opts) {
76             return this._setAttr(name, val, opts);
77         },
79         /**
80          * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
81          *
82          * @method _set
83          * @protected
84          * @chainable
85          *
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.
91          */
92         _set : function(name, val, opts) {
93             return this._setAttr(name, val, opts, true);
94         },
96         /**
97          * Sets multiple attribute values.
98          *
99          * @method setAttrs
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.
103          * @chainable
104          */
105         setAttrs : function(attrs, opts) {
106             return this._setAttrs(attrs, opts);
107         },
109         /**
110          * Implementation behind the public setAttrs method, to set multiple attribute values.
111          *
112          * @method _setAttrs
113          * @protected
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.
117          * @chainable
118          */
119         _setAttrs : function(attrs, opts) {
120             var attr;
121             for (attr in attrs) {
122                 if ( attrs.hasOwnProperty(attr) ) {
123                     this.set(attr, attrs[attr], opts);
124                 }
125             }
126             return this;
127         },
129         /**
130          * Utility method to help setup the event payload and fire the attribute change event.
131          *
132          * @method _fireAttrChange
133          * @private
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.
141          */
142         _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) {
143             var host = this,
144                 eventName = this._getFullType(attrName + CHANGE),
145                 state = host._state,
146                 facade,
147                 broadcast,
148                 e;
150             if (!cfg) {
151                 cfg = state.data[attrName] || {};
152             }
154             if (!cfg.published) {
156                 // PERF: Using lower level _publish() for
157                 // critical path performance
158                 e = host._publish(eventName);
160                 e.emitFacade = true;
161                 e.defaultTargetOnly = true;
162                 e.defaultFn = host._defAttrChangeFn;
164                 broadcast = cfg.broadcast;
165                 if (broadcast !== undefined) {
166                     e.broadcast = broadcast;
167                 }
169                 cfg.published = true;
170             }
172             if (opts) {
173                 facade = Y.merge(opts);
174                 facade._attrOpts = opts;
175             } else {
176                 facade = host._ATTR_E_FACADE;
177             }
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);
189             } else {
190                 this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg);
191             }
192         },
194         /**
195          * Default function for attribute change events.
196          *
197          * @private
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
201          */
202         _defAttrChangeFn : function(e, eventFastPath) {
204             var opts = e._attrOpts;
205             if (opts) {
206                 delete e._attrOpts;
207             }
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();
216                 }
218             } else {
219                 if (!eventFastPath) {
220                     e.newVal = this.get(e.attrName);
221                 }
222             }
223         }
224     };
226     // Basic prototype augment - no lazy constructor invocation.
227     Y.mix(AttributeObservable, EventTarget, false, null, 1);
229     Y.AttributeObservable = AttributeObservable;
231     /**
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
237     @uses EventTarget
238     @deprecated Use `AttributeObservable` instead.
239     @see AttributeObservable
240     **/
241     Y.AttributeEvents = AttributeObservable;
244 }, '3.13.0', {"requires": ["event-custom"]});