OLD | NEW |
(Empty) | |
| 1 /* |
| 2 Copyright (c) 2008, Yahoo! Inc. All rights reserved. |
| 3 Code licensed under the BSD License: |
| 4 http://developer.yahoo.net/yui/license.txt |
| 5 version: 2.6.0 |
| 6 */ |
| 7 /** |
| 8 * The YAHOO object is the single global object used by YUI Library. It |
| 9 * contains utility function for setting up namespaces, inheritance, and |
| 10 * logging. YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces |
| 11 * created automatically for and used by the library. |
| 12 * @module yahoo |
| 13 * @title YAHOO Global |
| 14 */ |
| 15 |
| 16 /** |
| 17 * YAHOO_config is not included as part of the library. Instead it is an |
| 18 * object that can be defined by the implementer immediately before |
| 19 * including the YUI library. The properties included in this object |
| 20 * will be used to configure global properties needed as soon as the |
| 21 * library begins to load. |
| 22 * @class YAHOO_config |
| 23 * @static |
| 24 */ |
| 25 |
| 26 /** |
| 27 * A reference to a function that will be executed every time a YAHOO module |
| 28 * is loaded. As parameter, this function will receive the version |
| 29 * information for the module. See <a href="YAHOO.env.html#getVersion"> |
| 30 * YAHOO.env.getVersion</a> for the description of the version data structure. |
| 31 * @property listener |
| 32 * @type Function |
| 33 * @static |
| 34 * @default undefined |
| 35 */ |
| 36 |
| 37 /** |
| 38 * Set to true if the library will be dynamically loaded after window.onload. |
| 39 * Defaults to false |
| 40 * @property injecting |
| 41 * @type boolean |
| 42 * @static |
| 43 * @default undefined |
| 44 */ |
| 45 |
| 46 /** |
| 47 * Instructs the yuiloader component to dynamically load yui components and |
| 48 * their dependencies. See the yuiloader documentation for more information |
| 49 * about dynamic loading |
| 50 * @property load |
| 51 * @static |
| 52 * @default undefined |
| 53 * @see yuiloader |
| 54 */ |
| 55 |
| 56 /** |
| 57 * Forces the use of the supplied locale where applicable in the library |
| 58 * @property locale |
| 59 * @type string |
| 60 * @static |
| 61 * @default undefined |
| 62 */ |
| 63 |
| 64 if (typeof YAHOO == "undefined" || !YAHOO) { |
| 65 /** |
| 66 * The YAHOO global namespace object. If YAHOO is already defined, the |
| 67 * existing YAHOO object will not be overwritten so that defined |
| 68 * namespaces are preserved. |
| 69 * @class YAHOO |
| 70 * @static |
| 71 */ |
| 72 var YAHOO = {}; |
| 73 } |
| 74 |
| 75 /** |
| 76 * Returns the namespace specified and creates it if it doesn't exist |
| 77 * <pre> |
| 78 * YAHOO.namespace("property.package"); |
| 79 * YAHOO.namespace("YAHOO.property.package"); |
| 80 * </pre> |
| 81 * Either of the above would create YAHOO.property, then |
| 82 * YAHOO.property.package |
| 83 * |
| 84 * Be careful when naming packages. Reserved words may work in some browsers |
| 85 * and not others. For instance, the following will fail in Safari: |
| 86 * <pre> |
| 87 * YAHOO.namespace("really.long.nested.namespace"); |
| 88 * </pre> |
| 89 * This fails because "long" is a future reserved word in ECMAScript |
| 90 * |
| 91 * @method namespace |
| 92 * @static |
| 93 * @param {String*} arguments 1-n namespaces to create |
| 94 * @return {Object} A reference to the last namespace object created |
| 95 */ |
| 96 YAHOO.namespace = function() { |
| 97 var a=arguments, o=null, i, j, d; |
| 98 for (i=0; i<a.length; i=i+1) { |
| 99 d=a[i].split("."); |
| 100 o=YAHOO; |
| 101 |
| 102 // YAHOO is implied, so it is ignored if it is included |
| 103 for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) { |
| 104 o[d[j]]=o[d[j]] || {}; |
| 105 o=o[d[j]]; |
| 106 } |
| 107 } |
| 108 |
| 109 return o; |
| 110 }; |
| 111 |
| 112 /** |
| 113 * Uses YAHOO.widget.Logger to output a log message, if the widget is |
| 114 * available. |
| 115 * |
| 116 * @method log |
| 117 * @static |
| 118 * @param {String} msg The message to log. |
| 119 * @param {String} cat The log category for the message. Default |
| 120 * categories are "info", "warn", "error", time". |
| 121 * Custom categories can be used as well. (opt) |
| 122 * @param {String} src The source of the the message (opt) |
| 123 * @return {Boolean} True if the log operation was successful. |
| 124 */ |
| 125 YAHOO.log = function(msg, cat, src) { |
| 126 var l=YAHOO.widget.Logger; |
| 127 if(l && l.log) { |
| 128 return l.log(msg, cat, src); |
| 129 } else { |
| 130 return false; |
| 131 } |
| 132 }; |
| 133 |
| 134 /** |
| 135 * Registers a module with the YAHOO object |
| 136 * @method register |
| 137 * @static |
| 138 * @param {String} name the name of the module (event, slider, etc) |
| 139 * @param {Function} mainClass a reference to class in the module. This |
| 140 * class will be tagged with the version info |
| 141 * so that it will be possible to identify the |
| 142 * version that is in use when multiple versions |
| 143 * have loaded |
| 144 * @param {Object} data metadata object for the module. Currently it |
| 145 * is expected to contain a "version" property |
| 146 * and a "build" property at minimum. |
| 147 */ |
| 148 YAHOO.register = function(name, mainClass, data) { |
| 149 var mods = YAHOO.env.modules; |
| 150 if (!mods[name]) { |
| 151 mods[name] = { versions:[], builds:[] }; |
| 152 } |
| 153 var m=mods[name],v=data.version,b=data.build,ls=YAHOO.env.listeners; |
| 154 m.name = name; |
| 155 m.version = v; |
| 156 m.build = b; |
| 157 m.versions.push(v); |
| 158 m.builds.push(b); |
| 159 m.mainClass = mainClass; |
| 160 // fire the module load listeners |
| 161 for (var i=0;i<ls.length;i=i+1) { |
| 162 ls[i](m); |
| 163 } |
| 164 // label the main class |
| 165 if (mainClass) { |
| 166 mainClass.VERSION = v; |
| 167 mainClass.BUILD = b; |
| 168 } else { |
| 169 YAHOO.log("mainClass is undefined for module " + name, "warn"); |
| 170 } |
| 171 }; |
| 172 |
| 173 /** |
| 174 * YAHOO.env is used to keep track of what is known about the YUI library and |
| 175 * the browsing environment |
| 176 * @class YAHOO.env |
| 177 * @static |
| 178 */ |
| 179 YAHOO.env = YAHOO.env || { |
| 180 |
| 181 /** |
| 182 * Keeps the version info for all YUI modules that have reported themselves |
| 183 * @property modules |
| 184 * @type Object[] |
| 185 */ |
| 186 modules: [], |
| 187 |
| 188 /** |
| 189 * List of functions that should be executed every time a YUI module |
| 190 * reports itself. |
| 191 * @property listeners |
| 192 * @type Function[] |
| 193 */ |
| 194 listeners: [] |
| 195 }; |
| 196 |
| 197 /** |
| 198 * Returns the version data for the specified module: |
| 199 * <dl> |
| 200 * <dt>name:</dt> <dd>The name of the module</dd> |
| 201 * <dt>version:</dt> <dd>The version in use</dd> |
| 202 * <dt>build:</dt> <dd>The build number in use</dd> |
| 203 * <dt>versions:</dt> <dd>All versions that were registered</dd> |
| 204 * <dt>builds:</dt> <dd>All builds that were registered.</dd> |
| 205 * <dt>mainClass:</dt> <dd>An object that was was stamped with the |
| 206 * current version and build. If |
| 207 * mainClass.VERSION != version or mainClass.BUILD != build, |
| 208 * multiple versions of pieces of the library have been |
| 209 * loaded, potentially causing issues.</dd> |
| 210 * </dl> |
| 211 * |
| 212 * @method getVersion |
| 213 * @static |
| 214 * @param {String} name the name of the module (event, slider, etc) |
| 215 * @return {Object} The version info |
| 216 */ |
| 217 YAHOO.env.getVersion = function(name) { |
| 218 return YAHOO.env.modules[name] || null; |
| 219 }; |
| 220 |
| 221 /** |
| 222 * Do not fork for a browser if it can be avoided. Use feature detection when |
| 223 * you can. Use the user agent as a last resort. YAHOO.env.ua stores a version |
| 224 * number for the browser engine, 0 otherwise. This value may or may not map |
| 225 * to the version number of the browser using the engine. The value is |
| 226 * presented as a float so that it can easily be used for boolean evaluation |
| 227 * as well as for looking for a particular range of versions. Because of this, |
| 228 * some of the granularity of the version info may be lost (e.g., Gecko 1.8.0.9 |
| 229 * reports 1.8). |
| 230 * @class YAHOO.env.ua |
| 231 * @static |
| 232 */ |
| 233 YAHOO.env.ua = function() { |
| 234 var o={ |
| 235 |
| 236 /** |
| 237 * Internet Explorer version number or 0. Example: 6 |
| 238 * @property ie |
| 239 * @type float |
| 240 */ |
| 241 ie:0, |
| 242 |
| 243 /** |
| 244 * Opera version number or 0. Example: 9.2 |
| 245 * @property opera |
| 246 * @type float |
| 247 */ |
| 248 opera:0, |
| 249 |
| 250 /** |
| 251 * Gecko engine revision number. Will evaluate to 1 if Gecko |
| 252 * is detected but the revision could not be found. Other browsers |
| 253 * will be 0. Example: 1.8 |
| 254 * <pre> |
| 255 * Firefox 1.0.0.4: 1.7.8 <-- Reports 1.7 |
| 256 * Firefox 1.5.0.9: 1.8.0.9 <-- Reports 1.8 |
| 257 * Firefox 2.0.0.3: 1.8.1.3 <-- Reports 1.8 |
| 258 * Firefox 3 alpha: 1.9a4 <-- Reports 1.9 |
| 259 * </pre> |
| 260 * @property gecko |
| 261 * @type float |
| 262 */ |
| 263 gecko:0, |
| 264 |
| 265 /** |
| 266 * AppleWebKit version. KHTML browsers that are not WebKit browsers |
| 267 * will evaluate to 1, other browsers 0. Example: 418.9.1 |
| 268 * <pre> |
| 269 * Safari 1.3.2 (312.6): 312.8.1 <-- Reports 312.8 -- currently the |
| 270 * latest available for Mac OSX 10.3. |
| 271 * Safari 2.0.2: 416 <-- hasOwnProperty introduced |
| 272 * Safari 2.0.4: 418 <-- preventDefault fixed |
| 273 * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run |
| 274 * different versions of webkit |
| 275 * Safari 2.0.4 (419.3): 419 <-- Tiger installations that have been |
| 276 * updated, but not updated |
| 277 * to the latest patch. |
| 278 * Webkit 212 nightly: 522+ <-- Safari 3.0 precursor (with native S
VG |
| 279 * and many major issues fixed). |
| 280 * 3.x yahoo.com, flickr:422 <-- Safari 3.x hacks the user agent |
| 281 * string when hitting yahoo.com and |
| 282 * flickr.com. |
| 283 * Safari 3.0.4 (523.12):523.12 <-- First Tiger release - automatic upd
ate |
| 284 * from 2.x via the 10.4.11 OS patch |
| 285 * Webkit nightly 1/2008:525+ <-- Supports DOMContentLoaded event. |
| 286 * yahoo.com user agent hack removed. |
| 287 * |
| 288 * </pre> |
| 289 * http://developer.apple.com/internet/safari/uamatrix.html |
| 290 * @property webkit |
| 291 * @type float |
| 292 */ |
| 293 webkit: 0, |
| 294 |
| 295 /** |
| 296 * The mobile property will be set to a string containing any relevant |
| 297 * user agent information when a modern mobile browser is detected. |
| 298 * Currently limited to Safari on the iPhone/iPod Touch, Nokia N-series |
| 299 * devices with the WebKit-based browser, and Opera Mini. |
| 300 * @property mobile |
| 301 * @type string |
| 302 */ |
| 303 mobile: null, |
| 304 |
| 305 /** |
| 306 * Adobe AIR version number or 0. Only populated if webkit is detected. |
| 307 * Example: 1.0 |
| 308 * @property air |
| 309 * @type float |
| 310 */ |
| 311 air: 0 |
| 312 |
| 313 }; |
| 314 |
| 315 var ua=navigator.userAgent, m; |
| 316 |
| 317 // Modern KHTML browsers should qualify as Safari X-Grade |
| 318 if ((/KHTML/).test(ua)) { |
| 319 o.webkit=1; |
| 320 } |
| 321 // Modern WebKit browsers are at least X-Grade |
| 322 m=ua.match(/AppleWebKit\/([^\s]*)/); |
| 323 if (m&&m[1]) { |
| 324 o.webkit=parseFloat(m[1]); |
| 325 |
| 326 // Mobile browser check |
| 327 if (/ Mobile\//.test(ua)) { |
| 328 o.mobile = "Apple"; // iPhone or iPod Touch |
| 329 } else { |
| 330 m=ua.match(/NokiaN[^\/]*/); |
| 331 if (m) { |
| 332 o.mobile = m[0]; // Nokia N-series, ex: NokiaN95 |
| 333 } |
| 334 } |
| 335 |
| 336 m=ua.match(/AdobeAIR\/([^\s]*)/); |
| 337 if (m) { |
| 338 o.air = m[0]; // Adobe AIR 1.0 or better |
| 339 } |
| 340 |
| 341 } |
| 342 |
| 343 if (!o.webkit) { // not webkit |
| 344 // @todo check Opera/8.01 (J2ME/MIDP; Opera Mini/2.0.4509/1316; fi; U; s
sr) |
| 345 m=ua.match(/Opera[\s\/]([^\s]*)/); |
| 346 if (m&&m[1]) { |
| 347 o.opera=parseFloat(m[1]); |
| 348 m=ua.match(/Opera Mini[^;]*/); |
| 349 if (m) { |
| 350 o.mobile = m[0]; // ex: Opera Mini/2.0.4509/1316 |
| 351 } |
| 352 } else { // not opera or webkit |
| 353 m=ua.match(/MSIE\s([^;]*)/); |
| 354 if (m&&m[1]) { |
| 355 o.ie=parseFloat(m[1]); |
| 356 } else { // not opera, webkit, or ie |
| 357 m=ua.match(/Gecko\/([^\s]*)/); |
| 358 if (m) { |
| 359 o.gecko=1; // Gecko detected, look for revision |
| 360 m=ua.match(/rv:([^\s\)]*)/); |
| 361 if (m&&m[1]) { |
| 362 o.gecko=parseFloat(m[1]); |
| 363 } |
| 364 } |
| 365 } |
| 366 } |
| 367 } |
| 368 |
| 369 return o; |
| 370 }(); |
| 371 |
| 372 /* |
| 373 * Initializes the global by creating the default namespaces and applying |
| 374 * any new configuration information that is detected. This is the setup |
| 375 * for env. |
| 376 * @method init |
| 377 * @static |
| 378 * @private |
| 379 */ |
| 380 (function() { |
| 381 YAHOO.namespace("util", "widget", "example"); |
| 382 if ("undefined" !== typeof YAHOO_config) { |
| 383 var l=YAHOO_config.listener,ls=YAHOO.env.listeners,unique=true,i; |
| 384 if (l) { |
| 385 // if YAHOO is loaded multiple times we need to check to see if |
| 386 // this is a new config object. If it is, add the new component |
| 387 // load listener to the stack |
| 388 for (i=0;i<ls.length;i=i+1) { |
| 389 if (ls[i]==l) { |
| 390 unique=false; |
| 391 break; |
| 392 } |
| 393 } |
| 394 if (unique) { |
| 395 ls.push(l); |
| 396 } |
| 397 } |
| 398 } |
| 399 })(); |
| 400 /** |
| 401 * Provides the language utilites and extensions used by the library |
| 402 * @class YAHOO.lang |
| 403 */ |
| 404 YAHOO.lang = YAHOO.lang || {}; |
| 405 |
| 406 (function() { |
| 407 |
| 408 var L = YAHOO.lang, |
| 409 |
| 410 // ADD = ["toString", "valueOf", "hasOwnProperty"], |
| 411 ADD = ["toString", "valueOf"], |
| 412 |
| 413 OB = { |
| 414 |
| 415 /** |
| 416 * Determines whether or not the provided object is an array. |
| 417 * Testing typeof/instanceof/constructor of arrays across frame |
| 418 * boundaries isn't possible in Safari unless you have a reference |
| 419 * to the other frame to test against its Array prototype. To |
| 420 * handle this case, we test well-known array properties instead. |
| 421 * properties. |
| 422 * @method isArray |
| 423 * @param {any} o The object being testing |
| 424 * @return {boolean} the result |
| 425 */ |
| 426 isArray: function(o) { |
| 427 if (o) { |
| 428 return L.isNumber(o.length) && L.isFunction(o.splice); |
| 429 } |
| 430 return false; |
| 431 }, |
| 432 |
| 433 /** |
| 434 * Determines whether or not the provided object is a boolean |
| 435 * @method isBoolean |
| 436 * @param {any} o The object being testing |
| 437 * @return {boolean} the result |
| 438 */ |
| 439 isBoolean: function(o) { |
| 440 return typeof o === 'boolean'; |
| 441 }, |
| 442 |
| 443 /** |
| 444 * Determines whether or not the provided object is a function |
| 445 * @method isFunction |
| 446 * @param {any} o The object being testing |
| 447 * @return {boolean} the result |
| 448 */ |
| 449 isFunction: function(o) { |
| 450 return typeof o === 'function'; |
| 451 }, |
| 452 |
| 453 /** |
| 454 * Determines whether or not the provided object is null |
| 455 * @method isNull |
| 456 * @param {any} o The object being testing |
| 457 * @return {boolean} the result |
| 458 */ |
| 459 isNull: function(o) { |
| 460 return o === null; |
| 461 }, |
| 462 |
| 463 /** |
| 464 * Determines whether or not the provided object is a legal number |
| 465 * @method isNumber |
| 466 * @param {any} o The object being testing |
| 467 * @return {boolean} the result |
| 468 */ |
| 469 isNumber: function(o) { |
| 470 return typeof o === 'number' && isFinite(o); |
| 471 }, |
| 472 |
| 473 /** |
| 474 * Determines whether or not the provided object is of type object |
| 475 * or function |
| 476 * @method isObject |
| 477 * @param {any} o The object being testing |
| 478 * @return {boolean} the result |
| 479 */ |
| 480 isObject: function(o) { |
| 481 return (o && (typeof o === 'object' || L.isFunction(o))) || false; |
| 482 }, |
| 483 |
| 484 /** |
| 485 * Determines whether or not the provided object is a string |
| 486 * @method isString |
| 487 * @param {any} o The object being testing |
| 488 * @return {boolean} the result |
| 489 */ |
| 490 isString: function(o) { |
| 491 return typeof o === 'string'; |
| 492 }, |
| 493 |
| 494 /** |
| 495 * Determines whether or not the provided object is undefined |
| 496 * @method isUndefined |
| 497 * @param {any} o The object being testing |
| 498 * @return {boolean} the result |
| 499 */ |
| 500 isUndefined: function(o) { |
| 501 return typeof o === 'undefined'; |
| 502 }, |
| 503 |
| 504 |
| 505 /** |
| 506 * IE will not enumerate native functions in a derived object even if the |
| 507 * function was overridden. This is a workaround for specific functions |
| 508 * we care about on the Object prototype. |
| 509 * @property _IEEnumFix |
| 510 * @param {Function} r the object to receive the augmentation |
| 511 * @param {Function} s the object that supplies the properties to augment |
| 512 * @static |
| 513 * @private |
| 514 */ |
| 515 _IEEnumFix: (YAHOO.env.ua.ie) ? function(r, s) { |
| 516 for (var i=0;i<ADD.length;i=i+1) { |
| 517 var fname=ADD[i],f=s[fname]; |
| 518 if (L.isFunction(f) && f!=Object.prototype[fname]) { |
| 519 r[fname]=f; |
| 520 } |
| 521 } |
| 522 } : function(){}, |
| 523 |
| 524 /** |
| 525 * Utility to set up the prototype, constructor and superclass properties to |
| 526 * support an inheritance strategy that can chain constructors and methods. |
| 527 * Static members will not be inherited. |
| 528 * |
| 529 * @method extend |
| 530 * @static |
| 531 * @param {Function} subc the object to modify |
| 532 * @param {Function} superc the object to inherit |
| 533 * @param {Object} overrides additional properties/methods to add to the |
| 534 * subclass prototype. These will override the |
| 535 * matching items obtained from the superclass |
| 536 * if present. |
| 537 */ |
| 538 extend: function(subc, superc, overrides) { |
| 539 if (!superc||!subc) { |
| 540 throw new Error("extend failed, please check that " + |
| 541 "all dependencies are included."); |
| 542 } |
| 543 var F = function() {}; |
| 544 F.prototype=superc.prototype; |
| 545 subc.prototype=new F(); |
| 546 subc.prototype.constructor=subc; |
| 547 subc.superclass=superc.prototype; |
| 548 if (superc.prototype.constructor == Object.prototype.constructor) { |
| 549 superc.prototype.constructor=superc; |
| 550 } |
| 551 |
| 552 if (overrides) { |
| 553 for (var i in overrides) { |
| 554 if (L.hasOwnProperty(overrides, i)) { |
| 555 subc.prototype[i]=overrides[i]; |
| 556 } |
| 557 } |
| 558 |
| 559 L._IEEnumFix(subc.prototype, overrides); |
| 560 } |
| 561 }, |
| 562 |
| 563 /** |
| 564 * Applies all properties in the supplier to the receiver if the |
| 565 * receiver does not have these properties yet. Optionally, one or |
| 566 * more methods/properties can be specified (as additional |
| 567 * parameters). This option will overwrite the property if receiver |
| 568 * has it already. If true is passed as the third parameter, all |
| 569 * properties will be applied and _will_ overwrite properties in |
| 570 * the receiver. |
| 571 * |
| 572 * @method augmentObject |
| 573 * @static |
| 574 * @since 2.3.0 |
| 575 * @param {Function} r the object to receive the augmentation |
| 576 * @param {Function} s the object that supplies the properties to augment |
| 577 * @param {String*|boolean} arguments zero or more properties methods |
| 578 * to augment the receiver with. If none specified, everything |
| 579 * in the supplier will be used unless it would |
| 580 * overwrite an existing property in the receiver. If true |
| 581 * is specified as the third parameter, all properties will |
| 582 * be applied and will overwrite an existing property in |
| 583 * the receiver |
| 584 */ |
| 585 augmentObject: function(r, s) { |
| 586 if (!s||!r) { |
| 587 throw new Error("Absorb failed, verify dependencies."); |
| 588 } |
| 589 var a=arguments, i, p, override=a[2]; |
| 590 if (override && override!==true) { // only absorb the specified properti
es |
| 591 for (i=2; i<a.length; i=i+1) { |
| 592 r[a[i]] = s[a[i]]; |
| 593 } |
| 594 } else { // take everything, overwriting only if the third parameter is
true |
| 595 for (p in s) { |
| 596 if (override || !(p in r)) { |
| 597 r[p] = s[p]; |
| 598 } |
| 599 } |
| 600 |
| 601 L._IEEnumFix(r, s); |
| 602 } |
| 603 }, |
| 604 |
| 605 /** |
| 606 * Same as YAHOO.lang.augmentObject, except it only applies prototype proper
ties |
| 607 * @see YAHOO.lang.augmentObject |
| 608 * @method augmentProto |
| 609 * @static |
| 610 * @param {Function} r the object to receive the augmentation |
| 611 * @param {Function} s the object that supplies the properties to augment |
| 612 * @param {String*|boolean} arguments zero or more properties methods |
| 613 * to augment the receiver with. If none specified, everything |
| 614 * in the supplier will be used unless it would overwrite an existing
|
| 615 * property in the receiver. if true is specified as the third |
| 616 * parameter, all properties will be applied and will overwrite an |
| 617 * existing property in the receiver |
| 618 */ |
| 619 augmentProto: function(r, s) { |
| 620 if (!s||!r) { |
| 621 throw new Error("Augment failed, verify dependencies."); |
| 622 } |
| 623 //var a=[].concat(arguments); |
| 624 var a=[r.prototype,s.prototype]; |
| 625 for (var i=2;i<arguments.length;i=i+1) { |
| 626 a.push(arguments[i]); |
| 627 } |
| 628 L.augmentObject.apply(this, a); |
| 629 }, |
| 630 |
| 631 |
| 632 /** |
| 633 * Returns a simple string representation of the object or array. |
| 634 * Other types of objects will be returned unprocessed. Arrays |
| 635 * are expected to be indexed. Use object notation for |
| 636 * associative arrays. |
| 637 * @method dump |
| 638 * @since 2.3.0 |
| 639 * @param o {Object} The object to dump |
| 640 * @param d {int} How deep to recurse child objects, default 3 |
| 641 * @return {String} the dump result |
| 642 */ |
| 643 dump: function(o, d) { |
| 644 var i,len,s=[],OBJ="{...}",FUN="f(){...}", |
| 645 COMMA=', ', ARROW=' => '; |
| 646 |
| 647 // Cast non-objects to string |
| 648 // Skip dates because the std toString is what we want |
| 649 // Skip HTMLElement-like objects because trying to dump |
| 650 // an element will cause an unhandled exception in FF 2.x |
| 651 if (!L.isObject(o)) { |
| 652 return o + ""; |
| 653 } else if (o instanceof Date || ("nodeType" in o && "tagName" in o)) { |
| 654 return o; |
| 655 } else if (L.isFunction(o)) { |
| 656 return FUN; |
| 657 } |
| 658 |
| 659 // dig into child objects the depth specifed. Default 3 |
| 660 d = (L.isNumber(d)) ? d : 3; |
| 661 |
| 662 // arrays [1, 2, 3] |
| 663 if (L.isArray(o)) { |
| 664 s.push("["); |
| 665 for (i=0,len=o.length;i<len;i=i+1) { |
| 666 if (L.isObject(o[i])) { |
| 667 s.push((d > 0) ? L.dump(o[i], d-1) : OBJ); |
| 668 } else { |
| 669 s.push(o[i]); |
| 670 } |
| 671 s.push(COMMA); |
| 672 } |
| 673 if (s.length > 1) { |
| 674 s.pop(); |
| 675 } |
| 676 s.push("]"); |
| 677 // objects {k1 => v1, k2 => v2} |
| 678 } else { |
| 679 s.push("{"); |
| 680 for (i in o) { |
| 681 if (L.hasOwnProperty(o, i)) { |
| 682 s.push(i + ARROW); |
| 683 if (L.isObject(o[i])) { |
| 684 s.push((d > 0) ? L.dump(o[i], d-1) : OBJ); |
| 685 } else { |
| 686 s.push(o[i]); |
| 687 } |
| 688 s.push(COMMA); |
| 689 } |
| 690 } |
| 691 if (s.length > 1) { |
| 692 s.pop(); |
| 693 } |
| 694 s.push("}"); |
| 695 } |
| 696 |
| 697 return s.join(""); |
| 698 }, |
| 699 |
| 700 /** |
| 701 * Does variable substitution on a string. It scans through the string |
| 702 * looking for expressions enclosed in { } braces. If an expression |
| 703 * is found, it is used a key on the object. If there is a space in |
| 704 * the key, the first word is used for the key and the rest is provided |
| 705 * to an optional function to be used to programatically determine the |
| 706 * value (the extra information might be used for this decision). If |
| 707 * the value for the key in the object, or what is returned from the |
| 708 * function has a string value, number value, or object value, it is |
| 709 * substituted for the bracket expression and it repeats. If this |
| 710 * value is an object, it uses the Object's toString() if this has |
| 711 * been overridden, otherwise it does a shallow dump of the key/value |
| 712 * pairs. |
| 713 * @method substitute |
| 714 * @since 2.3.0 |
| 715 * @param s {String} The string that will be modified. |
| 716 * @param o {Object} An object containing the replacement values |
| 717 * @param f {Function} An optional function that can be used to |
| 718 * process each match. It receives the key, |
| 719 * value, and any extra metadata included with |
| 720 * the key inside of the braces. |
| 721 * @return {String} the substituted string |
| 722 */ |
| 723 substitute: function (s, o, f) { |
| 724 var i, j, k, key, v, meta, saved=[], token, |
| 725 DUMP='dump', SPACE=' ', LBRACE='{', RBRACE='}'; |
| 726 |
| 727 |
| 728 for (;;) { |
| 729 i = s.lastIndexOf(LBRACE); |
| 730 if (i < 0) { |
| 731 break; |
| 732 } |
| 733 j = s.indexOf(RBRACE, i); |
| 734 if (i + 1 >= j) { |
| 735 break; |
| 736 } |
| 737 |
| 738 //Extract key and meta info |
| 739 token = s.substring(i + 1, j); |
| 740 key = token; |
| 741 meta = null; |
| 742 k = key.indexOf(SPACE); |
| 743 if (k > -1) { |
| 744 meta = key.substring(k + 1); |
| 745 key = key.substring(0, k); |
| 746 } |
| 747 |
| 748 // lookup the value |
| 749 v = o[key]; |
| 750 |
| 751 // if a substitution function was provided, execute it |
| 752 if (f) { |
| 753 v = f(key, v, meta); |
| 754 } |
| 755 |
| 756 if (L.isObject(v)) { |
| 757 if (L.isArray(v)) { |
| 758 v = L.dump(v, parseInt(meta, 10)); |
| 759 } else { |
| 760 meta = meta || ""; |
| 761 |
| 762 // look for the keyword 'dump', if found force obj dump |
| 763 var dump = meta.indexOf(DUMP); |
| 764 if (dump > -1) { |
| 765 meta = meta.substring(4); |
| 766 } |
| 767 |
| 768 // use the toString if it is not the Object toString |
| 769 // and the 'dump' meta info was not found |
| 770 if (v.toString===Object.prototype.toString||dump>-1) { |
| 771 v = L.dump(v, parseInt(meta, 10)); |
| 772 } else { |
| 773 v = v.toString(); |
| 774 } |
| 775 } |
| 776 } else if (!L.isString(v) && !L.isNumber(v)) { |
| 777 // This {block} has no replace string. Save it for later. |
| 778 v = "~-" + saved.length + "-~"; |
| 779 saved[saved.length] = token; |
| 780 |
| 781 // break; |
| 782 } |
| 783 |
| 784 s = s.substring(0, i) + v + s.substring(j + 1); |
| 785 |
| 786 |
| 787 } |
| 788 |
| 789 // restore saved {block}s |
| 790 for (i=saved.length-1; i>=0; i=i-1) { |
| 791 s = s.replace(new RegExp("~-" + i + "-~"), "{" + saved[i] + "}", "g
"); |
| 792 } |
| 793 |
| 794 return s; |
| 795 }, |
| 796 |
| 797 |
| 798 /** |
| 799 * Returns a string without any leading or trailing whitespace. If |
| 800 * the input is not a string, the input will be returned untouched. |
| 801 * @method trim |
| 802 * @since 2.3.0 |
| 803 * @param s {string} the string to trim |
| 804 * @return {string} the trimmed string |
| 805 */ |
| 806 trim: function(s){ |
| 807 try { |
| 808 return s.replace(/^\s+|\s+$/g, ""); |
| 809 } catch(e) { |
| 810 return s; |
| 811 } |
| 812 }, |
| 813 |
| 814 /** |
| 815 * Returns a new object containing all of the properties of |
| 816 * all the supplied objects. The properties from later objects |
| 817 * will overwrite those in earlier objects. |
| 818 * @method merge |
| 819 * @since 2.3.0 |
| 820 * @param arguments {Object*} the objects to merge |
| 821 * @return the new merged object |
| 822 */ |
| 823 merge: function() { |
| 824 var o={}, a=arguments; |
| 825 for (var i=0, l=a.length; i<l; i=i+1) { |
| 826 L.augmentObject(o, a[i], true); |
| 827 } |
| 828 return o; |
| 829 }, |
| 830 |
| 831 /** |
| 832 * Executes the supplied function in the context of the supplied |
| 833 * object 'when' milliseconds later. Executes the function a |
| 834 * single time unless periodic is set to true. |
| 835 * @method later |
| 836 * @since 2.4.0 |
| 837 * @param when {int} the number of milliseconds to wait until the fn |
| 838 * is executed |
| 839 * @param o the context object |
| 840 * @param fn {Function|String} the function to execute or the name of |
| 841 * the method in the 'o' object to execute |
| 842 * @param data [Array] data that is provided to the function. This accepts |
| 843 * either a single item or an array. If an array is provided, the |
| 844 * function is executed with one parameter for each array item. If |
| 845 * you need to pass a single array parameter, it needs to be wrapped in |
| 846 * an array [myarray] |
| 847 * @param periodic {boolean} if true, executes continuously at supplied |
| 848 * interval until canceled |
| 849 * @return a timer object. Call the cancel() method on this object to |
| 850 * stop the timer. |
| 851 */ |
| 852 later: function(when, o, fn, data, periodic) { |
| 853 when = when || 0; |
| 854 o = o || {}; |
| 855 var m=fn, d=data, f, r; |
| 856 |
| 857 if (L.isString(fn)) { |
| 858 m = o[fn]; |
| 859 } |
| 860 |
| 861 if (!m) { |
| 862 throw new TypeError("method undefined"); |
| 863 } |
| 864 |
| 865 if (!L.isArray(d)) { |
| 866 d = [data]; |
| 867 } |
| 868 |
| 869 f = function() { |
| 870 m.apply(o, d); |
| 871 }; |
| 872 |
| 873 r = (periodic) ? setInterval(f, when) : setTimeout(f, when); |
| 874 |
| 875 return { |
| 876 interval: periodic, |
| 877 cancel: function() { |
| 878 if (this.interval) { |
| 879 clearInterval(r); |
| 880 } else { |
| 881 clearTimeout(r); |
| 882 } |
| 883 } |
| 884 }; |
| 885 }, |
| 886 |
| 887 /** |
| 888 * A convenience method for detecting a legitimate non-null value. |
| 889 * Returns false for null/undefined/NaN, true for other values, |
| 890 * including 0/false/'' |
| 891 * @method isValue |
| 892 * @since 2.3.0 |
| 893 * @param o {any} the item to test |
| 894 * @return {boolean} true if it is not null/undefined/NaN || false |
| 895 */ |
| 896 isValue: function(o) { |
| 897 // return (o || o === false || o === 0 || o === ''); // Infinity fails |
| 898 return (L.isObject(o) || L.isString(o) || L.isNumber(o) || L.isBoolean(o)); |
| 899 } |
| 900 |
| 901 }; |
| 902 |
| 903 /** |
| 904 * Determines whether or not the property was added |
| 905 * to the object instance. Returns false if the property is not present |
| 906 * in the object, or was inherited from the prototype. |
| 907 * This abstraction is provided to enable hasOwnProperty for Safari 1.3.x. |
| 908 * There is a discrepancy between YAHOO.lang.hasOwnProperty and |
| 909 * Object.prototype.hasOwnProperty when the property is a primitive added to |
| 910 * both the instance AND prototype with the same value: |
| 911 * <pre> |
| 912 * var A = function() {}; |
| 913 * A.prototype.foo = 'foo'; |
| 914 * var a = new A(); |
| 915 * a.foo = 'foo'; |
| 916 * alert(a.hasOwnProperty('foo')); // true |
| 917 * alert(YAHOO.lang.hasOwnProperty(a, 'foo')); // false when using fallback |
| 918 * </pre> |
| 919 * @method hasOwnProperty |
| 920 * @param {any} o The object being testing |
| 921 * @param prop {string} the name of the property to test |
| 922 * @return {boolean} the result |
| 923 */ |
| 924 L.hasOwnProperty = (Object.prototype.hasOwnProperty) ? |
| 925 function(o, prop) { |
| 926 return o && o.hasOwnProperty(prop); |
| 927 } : function(o, prop) { |
| 928 return !L.isUndefined(o[prop]) && |
| 929 o.constructor.prototype[prop] !== o[prop]; |
| 930 }; |
| 931 |
| 932 // new lang wins |
| 933 OB.augmentObject(L, OB, true); |
| 934 |
| 935 /* |
| 936 * An alias for <a href="YAHOO.lang.html">YAHOO.lang</a> |
| 937 * @class YAHOO.util.Lang |
| 938 */ |
| 939 YAHOO.util.Lang = L; |
| 940 |
| 941 /** |
| 942 * Same as YAHOO.lang.augmentObject, except it only applies prototype |
| 943 * properties. This is an alias for augmentProto. |
| 944 * @see YAHOO.lang.augmentObject |
| 945 * @method augment |
| 946 * @static |
| 947 * @param {Function} r the object to receive the augmentation |
| 948 * @param {Function} s the object that supplies the properties to augment |
| 949 * @param {String*|boolean} arguments zero or more properties methods to |
| 950 * augment the receiver with. If none specified, everything |
| 951 * in the supplier will be used unless it would |
| 952 * overwrite an existing property in the receiver. if true |
| 953 * is specified as the third parameter, all properties will |
| 954 * be applied and will overwrite an existing property in |
| 955 * the receiver |
| 956 */ |
| 957 L.augment = L.augmentProto; |
| 958 |
| 959 /** |
| 960 * An alias for <a href="YAHOO.lang.html#augment">YAHOO.lang.augment</a> |
| 961 * @for YAHOO |
| 962 * @method augment |
| 963 * @static |
| 964 * @param {Function} r the object to receive the augmentation |
| 965 * @param {Function} s the object that supplies the properties to augment |
| 966 * @param {String*} arguments zero or more properties methods to |
| 967 * augment the receiver with. If none specified, everything |
| 968 * in the supplier will be used unless it would |
| 969 * overwrite an existing property in the receiver |
| 970 */ |
| 971 YAHOO.augment = L.augmentProto; |
| 972 |
| 973 /** |
| 974 * An alias for <a href="YAHOO.lang.html#extend">YAHOO.lang.extend</a> |
| 975 * @method extend |
| 976 * @static |
| 977 * @param {Function} subc the object to modify |
| 978 * @param {Function} superc the object to inherit |
| 979 * @param {Object} overrides additional properties/methods to add to the |
| 980 * subclass prototype. These will override the |
| 981 * matching items obtained from the superclass if present. |
| 982 */ |
| 983 YAHOO.extend = L.extend; |
| 984 |
| 985 })(); |
| 986 YAHOO.register("yahoo", YAHOO, {version: "2.6.0", build: "1321"}); |
OLD | NEW |