PageSourceSearch

https://kirjanpitolautakunta.fi/o/frontend-js-aui-web/aui/oop/oop.js

js kirjanpitolautakunta.fi collected 2026-10-02 18:16:25 UTC 14,815 bytes, 432 lines download raw bytes

1YUI.add('oop', function (Y, NAME) {
2
3/**
4Adds object inheritance and manipulation utilities to the YUI instance. This
5module is required by most YUI components.
6
7@module oop
8**/
9
10var L            = Y.Lang,
11    A            = Y.Array,
12    OP           = Object.prototype,
13    CLONE_MARKER = '_~yuim~_',
14
15    hasOwn   = OP.hasOwnProperty,
16    toString = OP.toString;
17
18/**
19Calls the specified _action_ method on _o_ if it exists. Otherwise, if _o_ is an
20array, calls the _action_ method on `Y.Array`, or if _o_ is an object, calls the
21_action_ method on `Y.Object`.
22
23If _o_ is an array-like object, it will be coerced to an array.
24
25This is intended to be used with array/object iteration methods that share
26signatures, such as `each()`, `some()`, etc.
27
28@method dispatch
29@param {Object} o Array or object to dispatch to.
30@param {Function} f Iteration callback.
31    @param {Mixed} f.value Value being iterated.
32    @param {Mixed} f.key Current object key or array index.
33    @param {Mixed} f.object Object or array being iterated.
34@param {Object} c `this` object to bind the iteration callback to.
35@param {Boolean} proto If `true`, prototype properties of objects will be
36    iterated.
37@param {String} action Function name to be dispatched on _o_. For example:
38    'some', 'each', etc.
39@private
40@return {Mixed} Returns the value returned by the chosen iteration action, which
41    varies.
42**/
43function dispatch(o, f, c, proto, action) {
44    if (o && o[action] && o !== Y) {
45        return o[action].call(o, f, c);
46    } else {
47        switch (A.test(o)) {
48            case 1:
49                return A[action](o, f, c);
50            case 2:
51                return A[action](Y.Array(o, 0, true), f, c);
52            default:
53                return Y.Object[action](o, f, c, proto);
54        }
55    }
56}
57
58/**
59Augments the _receiver_ with prototype properties from the _supplier_. The
60receiver may be a constructor function or an object. The supplier must be a
61constructor function.
62
63If the _receiver_ is an object, then the _supplier_ constructor will be called
64immediately after _receiver_ is augmented, with _receiver_ as the `this` object.
65
66If the _receiver_ is a constructor function, then all prototype methods of
67_supplier_ that are copied to _receiver_ will be sequestered, and the
68_supplier_ constructor will not be called immediately. The first time any
69sequestered method is called on the _receiver_'s prototype, all sequestered
70methods will be immediately copied to the _receiver_'s prototype, the
71_supplier_'s constructor will be executed, and finally the newly unsequestered
72method that was called will be executed.
73
74This sequestering logic sounds like a bunch of complicated voodoo, but it makes
75it cheap to perform frequent augmentation by ensuring that suppliers'
76constructors are only called if a supplied method is actually used. If none of
77the supplied methods is ever used, then there's no need to take the performance
78hit of calling the _supplier_'s constructor.
79
80@method augment
81@param {Function|Object} receiver Object or function to be augmented.
82@param {Function} supplier Function that supplies the prototype properties with
83  which to augment the _receiver_.
84@param {Boolean} [overwrite=false] If `true`, properties already on the receiver
85  will be overwritten if found on the supplier's prototype.
86@param {String[]} [whitelist] An array of property names. If specified,
87  only the whitelisted prototype properties will be applied to the receiver, and
88  all others will be ignored.
89@param {Array|any} [args] Argument or array of arguments to pass to the
90  supplier's constructor when initializing.
91@return {Function} Augmented object.
92@for YUI
93**/
94Y.augment = function (receiver, supplier, overwrite, whitelist, args) {
95    var rProto    = receiver.prototype,
96        sequester = rProto && supplier,
97        sProto    = supplier.prototype,
98        to        = rProto || receiver,
99
100        copy,
101        newPrototype,
102        replacements,
103        sequestered,
104        unsequester;
105
106    args = args ? Y.Array(args) : [];
107
108    if (sequester) {
109        newPrototype = {};
110        replacements = {};
111        sequestered  = {};
112
113        copy = function (value, key) {
114            if (overwrite || !(key in rProto)) {
115                if (toString.call(value) === '[object Function]') {
116                    sequestered[key] = value;
117
118                    newPrototype[key] = replacements[key] = function () {
119                        return unsequester(this, value, arguments);
120                    };
121                } else {
122                    newPrototype[key] = value;
123                }
124            }
125        };
126
127        unsequester = function (instance, fn, fnArgs) {
128            // Unsequester all sequestered functions.
129            for (var key in sequestered) {
130                if (hasOwn.call(sequestered, key)
131                        && instance[key] === replacements[key]) {
132
133                    instance[key] = sequestered[key];
134                }
135            }
136
137            // Execute the supplier constructor.
138            supplier.apply(instance, args);
139
140            // Finally, execute the original sequestered function.
141            return fn.apply(instance, fnArgs);
142        };
143
144        if (whitelist) {
145            Y.Array.each(whitelist, function (name) {
146                if (name in sProto) {
147                    copy(sProto[name], name);
148                }
149            });
150        } else {
151            Y.Object.each(sProto, copy, null, true);
152        }
153    }
154
155    Y.mix(to, newPrototype || sProto, overwrite, whitelist);
156
157    if (!sequester) {
158        supplier.apply(to, args);
159    }
160
161    return receiver;
162};
163
164/**
165 * Copies object properties from the supplier to the receiver. If the target has
166 * the property, and the property is an object, the target object will be
167 * augmented with the supplier's value.
168 *
169 * @method aggregate
170 * @param {Object} receiver Object to receive the augmentation.
171 * @param {Object} supplier Object that supplies the properties with which to
172 *     augment the receiver.
173 * @param {Boolean} [overwrite=false] If `true`, properties already on the receiver
174 *     will be overwritten if found on the supplier.
175 * @param {String[]} [whitelist] Whitelist. If supplied, only properties in this
176 *     list will be applied to the receiver.
177 * @return {Object} Augmented object.
178 */
179Y.aggregate = function(r, s, ov, wl) {
180    return Y.mix(r, s, ov, wl, 0, true);
181};
182
183/**
184 * Utility to set up the prototype, constructor and superclass properties to
185 * support an inheritance strategy that can chain constructors and methods.
186 * Static members will not be inherited.
187 *
188 * @method extend
189 * @param {function} r   the object to modify.
190 * @param {function} s the object to inherit.
191 * @param {object} px prototype properties to add/override.
192 * @param {object} sx static properties to add/override.
193 * @return {object} the extended object.
194 */
195Y.extend = function(r, s, px, sx) {
196    if (!s || !r) {
197        Y.error('extend failed, verify dependencies');
198    }
199
200    var sp = s.prototype, rp = Y.Object(sp);
201    r.prototype = rp;
202
203    rp.constructor = r;
204    r.superclass = sp;
205
206    // assign constructor property
207    if (s != Object && sp.constructor == OP.constructor) {
208        sp.constructor = s;
209    }
210
211    // add prototype overrides
212    if (px) {
213        Y.mix(rp, px, true);
214    }
215
216    // add object overrides
217    if (sx) {
218        Y.mix(r, sx, true);
219    }
220
221    return r;
222};
223
224/**
225 * Executes the supplied function for each item in
226 * a collection.  Supports arrays, objects, and
227 * NodeLists
228 * @method each
229 * @param {object} o the object to iterate.
230 * @param {function} f the function to execute.  This function
231 * receives the value, key, and object as parameters.
232 * @param {object} c the execution context for the function.
233 * @param {boolean} proto if true, prototype properties are
234 * iterated on objects.
235 * @return {YUI} the YUI instance.
236 */
237Y.each = function(o, f, c, proto) {
238    return dispatch(o, f, c, proto, 'each');
239};
240
241/**
242 * Executes the supplied function for each item in
243 * a collection.  The operation stops if the function
244 * returns true. Supports arrays, objects, and
245 * NodeLists.
246 * @method some
247 * @param {object} o the object to iterate.
248 * @param {function} f the function to execute.  This function
249 * receives the value, key, and object as parameters.
250 * @param {object} c the execution context for the function.
251 * @param {boolean} proto if true, prototype properties are
252 * iterated on objects.
253 * @return {boolean} true if the function ever returns true,
254 * false otherwise.
255 */
256Y.some = function(o, f, c, proto) {
257    return dispatch(o, f, c, proto, 'some');
258};
259
260/**
261Deep object/array copy. Function clones are actually wrappers around the
262original function. Array-like objects are treated as arrays. Primitives are
263returned untouched. Optionally, a function can be provided to handle other data
264types, filter keys, validate values, etc.
265
266**Note:** Cloning a non-trivial object is a reasonably heavy operation, due to
267the need to recursively iterate down non-primitive properties. Clone should be
268used only when a deep clone down to leaf level properties is explicitly
269required. This method will also
270
271In many cases (for example, when trying to isolate objects used as hashes for
272configuration properties), a shallow copy, using `Y.merge()` is normally
273sufficient. If more than one level of isolation is required, `Y.merge()` can be
274used selectively at each level which needs to be isolated from the original
275without going all the way to leaf properties.
276
277@method clone
278@param {object} o what to clone.
279@param {boolean} safe if true, objects will not have prototype items from the
280    source. If false, they will. In this case, the original is initially
281    protected, but the clone is not completely immune from changes to the source
282    object prototype. Also, cloned prototype items that are deleted from the
283    clone will result in the value of the source prototype being exposed. If
284    operating on a non-safe clone, items should be nulled out rather than
285    deleted.
286@param {function} f optional function to apply to each item in a collection; it
287    will be executed prior to applying the value to the new object.
288    Return false to prevent the copy.
289@param {object} c optional execution context for f.
290@param {object} owner Owner object passed when clone is iterating an object.
291    Used to set up context for cloned functions.
292@param {object} cloned hash of previously cloned objects to avoid multiple
293    clones.
294@return {Array|Object} the cloned object.
295**/
296Y.clone = function(o, safe, f, c, owner, cloned) {
297    var o2, marked, stamp;
298
299    // Does not attempt to clone:
300    //
301    // * Non-typeof-object values, "primitive" values don't need cloning.
302    //
303    // * YUI instances, cloning complex object like YUI instances is not
304    //   advised, this is like cloning the world.
305    //
306    // * DOM nodes (#2528250), common host objects like DOM nodes cannot be
307    //   "subclassed" in Firefox and old versions of IE. Trying to use
308    //   `Object.create()` or `Y.extend()` on a DOM node will throw an error in
309    //   these browsers.
310    //
311    // Instad, the passed-in `o` will be return as-is when it matches one of the
312    // above criteria.
313    if (!L.isObject(o) ||
314            Y.instanceOf(o, YUI) ||
315            (o.addEventListener || o.attachEvent)) {
316
317        return o;
318    }
319
320    marked = cloned || {};
321
322    switch (L.type(o)) {
323        case 'date':
324            return new Date(o);
325        case 'regexp':
326            // if we do this we need to set the flags too
327            // return new RegExp(o.source);
328            return o;
329        case 'function':
330            // o2 = Y.bind(o, owner);
331            // break;
332            return o;
333        case 'array':
334            o2 = [];
335            break;
336        default:
337
338            // #2528250 only one clone of a given object should be created.
339            if (o[CLONE_MARKER]) {
340                return marked[o[CLONE_MARKER]];
341            }
342
343            stamp = Y.guid();
344
345            o2 = (safe) ? {} : Y.Object(o);
346
347            o[CLONE_MARKER] = stamp;
348            marked[stamp] = o;
349    }
350
351    Y.each(o, function(v, k) {
352        if ((k || k === 0) && (!f || (f.call(c || this, v, k, this, o) !== false))) {
353            if (k !== CLONE_MARKER) {
354                if (k == 'prototype') {
355                    // skip the prototype
356                // } else if (o[k] === o) {
357                //     this[k] = this;
358                } else {
359                    this[k] =
360                        Y.clone(v, safe, f, c, owner || o, marked);
361                }
362            }
363        }
364    }, o2);
365
366    if (!cloned) {
367        Y.Object.each(marked, function(v, k) {
368            if (v[CLONE_MARKER]) {
369                try {
370                    delete v[CLONE_MARKER];
371                } catch (e) {
372                    v[CLONE_MARKER] = null;
373                }
374            }
375        }, this);
376        marked = null;
377    }
378
379    return o2;
380};
381
382/**
383 * Returns a function that will execute the supplied function in the
384 * supplied object's context, optionally adding any additional
385 * supplied parameters to the beginning of the arguments collection the
386 * supplied to the function.
387 *
388 * @method bind
389 * @param {Function|String} f the function to bind, or a function name
390 * to execute on the context object.
391 * @param {object} c the execution context.
392 * @param {any} args* 0..n arguments to include before the arguments the
393 * function is executed with.
394 * @return {function} the wrapped function.
395 */
396Y.bind = function(f, c) {
397    var xargs = arguments.length > 2 ?
398            Y.Array(arguments, 2, true) : null;
399    return function() {
400        var fn = L.isString(f) ? c[f] : f,
401            args = (xargs) ?
402                xargs.concat(Y.Array(arguments, 0, true)) : arguments;
403        return fn.apply(c || fn, args);
404    };
405};
406
407/**
408 * Returns a function that will execute the supplied function in the
409 * supplied object's context, optionally adding any additional
410 * supplied parameters to the end of the arguments the function
411 * is executed with.
412 *
413 * @method rbind
414 * @param {Function|String} f the function to bind, or a function name
415 * to execute on the context object.
416 * @param {object} c the execution context.
417 * @param {any} args* 0..n arguments to append to the end of
418 * arguments collection supplied to the function.
419 * @return {function} the wrapped function.
420 */
421Y.rbind = function(f, c) {
422    var xargs = arguments.length > 2 ? Y.Array(arguments, 2, true) : null;
423    return function() {
424        var fn = L.isString(f) ? c[f] : f,
425            args = (xargs) ?
426                Y.Array(arguments, 0, true).concat(xargs) : arguments;
427        return fn.apply(c || fn, args);
428    };
429};
430
431
432}, 'patched-v3.18.7', {"requires": ["yui-base"]});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.