Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('attribute-observable', function (Y, NAME) {
2
 
3
    /*For log lines*/
4
    /*jshint maxlen:200*/
5
 
6
 
7
    /**
8
     * The attribute module provides an augmentable Attribute implementation, which
9
     * adds configurable attributes and attribute change events to the class being
10
     * augmented. It also provides a State class, which is used internally by Attribute,
11
     * but can also be used independently to provide a name/property/value data structure to
12
     * store state.
13
     *
14
     * @module attribute
15
     */
16
 
17
    /**
18
     * The `attribute-observable` submodule provides augmentable attribute change event support
19
     * for AttributeCore based implementations.
20
     *
21
     * @module attribute
22
     * @submodule attribute-observable
23
     */
24
    var EventTarget = Y.EventTarget,
25
 
26
        CHANGE = "Change",
27
        BROADCAST = "broadcast";
28
 
29
    /**
30
     * Provides an augmentable implementation of attribute change events for
31
     * AttributeCore.
32
     *
33
     * @class AttributeObservable
34
     * @extensionfor AttributeCore
35
     * @uses EventTarget
36
     */
37
    function AttributeObservable() {
38
        // Perf tweak - avoid creating event literals if not required.
39
        this._ATTR_E_FACADE = {};
40
 
41
        EventTarget.call(this, {emitFacade:true});
42
    }
43
 
44
    AttributeObservable._ATTR_CFG = [BROADCAST];
45
 
46
    AttributeObservable.prototype = {
47
 
48
        /**
49
         * Sets the value of an attribute.
50
         *
51
         * @method set
52
         * @chainable
53
         *
54
         * @param {String} name The name of the attribute. If the
55
         * current value of the attribute is an Object, dot notation can be used
56
         * to set the value of a property within the object (e.g. <code>set("x.y.z", 5)</code>).
57
         *
58
         * @param {Any} value The value to set the attribute to.
59
         *
60
         * @param {Object} opts (Optional) Optional event data to be mixed into
61
         * the event facade passed to subscribers of the attribute's change event. This
62
         * can be used as a flexible way to identify the source of a call to set, allowing
63
         * the developer to distinguish between set called internally by the host, vs.
64
         * set called externally by the application developer.
65
         *
66
         * @return {Object} A reference to the host object.
67
         */
68
        set : function(name, val, opts) {
69
            return this._setAttr(name, val, opts);
70
        },
71
 
72
        /**
73
         * Allows setting of readOnly/writeOnce attributes. See <a href="#method_set">set</a> for argument details.
74
         *
75
         * @method _set
76
         * @protected
77
         * @chainable
78
         *
79
         * @param {String} name The name of the attribute.
80
         * @param {Any} val The value to set the attribute to.
81
         * @param {Object} opts (Optional) Optional event data to be mixed into
82
         * the event facade passed to subscribers of the attribute's change event.
83
         * @return {Object} A reference to the host object.
84
         */
85
        _set : function(name, val, opts) {
86
            return this._setAttr(name, val, opts, true);
87
        },
88
 
89
        /**
90
         * Sets multiple attribute values.
91
         *
92
         * @method setAttrs
93
         * @param {Object} attrs  An object with attributes name/value pairs.
94
         * @param {Object} opts  Properties to mix into the event payload. These are shared and mixed into each set
95
         * @return {Object} A reference to the host object.
96
         * @chainable
97
         */
98
        setAttrs : function(attrs, opts) {
99
            return this._setAttrs(attrs, opts);
100
        },
101
 
102
        /**
103
         * Implementation behind the public setAttrs method, to set multiple attribute values.
104
         *
105
         * @method _setAttrs
106
         * @protected
107
         * @param {Object} attrs  An object with attributes name/value pairs.
108
         * @param {Object} opts  Properties to mix into the event payload. These are shared and mixed into each set
109
         * @return {Object} A reference to the host object.
110
         * @chainable
111
         */
112
        _setAttrs : function(attrs, opts) {
113
            var attr;
114
            for (attr in attrs) {
115
                if ( attrs.hasOwnProperty(attr) ) {
116
                    this.set(attr, attrs[attr], opts);
117
                }
118
            }
119
            return this;
120
        },
121
 
122
        /**
123
         * Utility method to help setup the event payload and fire the attribute change event.
124
         *
125
         * @method _fireAttrChange
126
         * @private
127
         * @param {String} attrName The name of the attribute
128
         * @param {String} subAttrName The full path of the property being changed,
129
         * if this is a sub-attribute value being change. Otherwise null.
130
         * @param {Any} currVal The current value of the attribute
131
         * @param {Any} newVal The new value of the attribute
132
         * @param {Object} opts Any additional event data to mix into the attribute change event's event facade.
133
         * @param {Object} [cfg] The attribute config stored in State, if already available.
134
         */
135
        _fireAttrChange : function(attrName, subAttrName, currVal, newVal, opts, cfg) {
136
            var host = this,
137
                eventName = this._getFullType(attrName + CHANGE),
138
                state = host._state,
139
                facade,
140
                broadcast,
141
                e;
142
 
143
            if (!cfg) {
144
                cfg = state.data[attrName] || {};
145
            }
146
 
147
            if (!cfg.published) {
148
 
149
                // PERF: Using lower level _publish() for
150
                // critical path performance
151
                e = host._publish(eventName);
152
 
153
                e.emitFacade = true;
154
                e.defaultTargetOnly = true;
155
                e.defaultFn = host._defAttrChangeFn;
156
 
157
                broadcast = cfg.broadcast;
158
                if (broadcast !== undefined) {
159
                    e.broadcast = broadcast;
160
                }
161
 
162
                cfg.published = true;
163
            }
164
 
165
            if (opts) {
166
                facade = Y.merge(opts);
167
                facade._attrOpts = opts;
168
            } else {
169
                facade = host._ATTR_E_FACADE;
170
            }
171
 
172
            // Not using the single object signature for fire({type:..., newVal:...}), since
173
            // we don't want to override type. Changed to the fire(type, {newVal:...}) signature.
174
 
175
            facade.attrName = attrName;
176
            facade.subAttrName = subAttrName;
177
            facade.prevVal = currVal;
178
            facade.newVal = newVal;
179
 
180
            if (host._hasPotentialSubscribers(eventName)) {
181
                host.fire(eventName, facade);
182
            } else {
183
                this._setAttrVal(attrName, subAttrName, currVal, newVal, opts, cfg);
184
            }
185
        },
186
 
187
        /**
188
         * Default function for attribute change events.
189
         *
190
         * @private
191
         * @method _defAttrChangeFn
192
         * @param {EventFacade} e The event object for attribute change events.
193
         * @param {boolean} eventFastPath Whether or not we're using this as a fast path in the case of no listeners or not
194
         */
195
        _defAttrChangeFn : function(e, eventFastPath) {
196
 
197
            var opts = e._attrOpts;
198
            if (opts) {
199
                delete e._attrOpts;
200
            }
201
 
202
            if (!this._setAttrVal(e.attrName, e.subAttrName, e.prevVal, e.newVal, opts)) {
203
 
204
                Y.log('State not updated and stopImmediatePropagation called for attribute: ' + e.attrName + ' , value:' + e.newVal, 'warn', 'attribute');
205
 
206
                if (!eventFastPath) {
207
                    // Prevent "after" listeners from being invoked since nothing changed.
208
                    e.stopImmediatePropagation();
209
                }
210
 
211
            } else {
212
                if (!eventFastPath) {
213
                    e.newVal = this.get(e.attrName);
214
                }
215
            }
216
        }
217
    };
218
 
219
    // Basic prototype augment - no lazy constructor invocation.
220
    Y.mix(AttributeObservable, EventTarget, false, null, 1);
221
 
222
    Y.AttributeObservable = AttributeObservable;
223
 
224
    /**
225
    The `AttributeEvents` class extension was deprecated in YUI 3.8.0 and is now
226
    an alias for the `AttributeObservable` class extension. Use that class
227
    extnesion instead. This alias will be removed in a future version of YUI.
228
 
229
    @class AttributeEvents
230
    @uses EventTarget
231
    @deprecated Use `AttributeObservable` instead.
232
    @see AttributeObservable
233
    **/
234
    Y.AttributeEvents = AttributeObservable;
235
 
236
 
237
}, '3.18.1', {"requires": ["event-custom"]});