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