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.