[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 /*! 2 * https://github.com/es-shims/es5-shim 3 * @license es5-shim Copyright 2009-2014 by contributors, MIT License 4 * see https://github.com/es-shims/es5-shim/blob/master/LICENSE 5 */ 6 7 // vim: ts=4 sts=4 sw=4 expandtab 8 9 //Add semicolon to prevent IIFE from being passed as argument to concated code. 10 ; 11 12 // UMD (Universal Module Definition) 13 // see https://github.com/umdjs/umd/blob/master/returnExports.js 14 (function (root, factory) { 15 if (typeof define === 'function' && define.amd) { 16 // AMD. Register as an anonymous module. 17 define(factory); 18 } else if (typeof exports === 'object') { 19 // Node. Does not work with strict CommonJS, but 20 // only CommonJS-like enviroments that support module.exports, 21 // like Node. 22 module.exports = factory(); 23 } else { 24 // Browser globals (root is window) 25 root.returnExports = factory(); 26 } 27 }(this, function () { 28 29 /** 30 * Brings an environment as close to ECMAScript 5 compliance 31 * as is possible with the facilities of erstwhile engines. 32 * 33 * Annotated ES5: http://es5.github.com/ (specific links below) 34 * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf 35 * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ 36 */ 37 38 // Shortcut to an often accessed properties, in order to avoid multiple 39 // dereference that costs universally. 40 var ArrayPrototype = Array.prototype; 41 var ObjectPrototype = Object.prototype; 42 var FunctionPrototype = Function.prototype; 43 var StringPrototype = String.prototype; 44 var NumberPrototype = Number.prototype; 45 var _Array_slice_ = ArrayPrototype.slice; 46 var array_splice = ArrayPrototype.splice; 47 var array_push = ArrayPrototype.push; 48 var array_unshift = ArrayPrototype.unshift; 49 var call = FunctionPrototype.call; 50 51 // Having a toString local variable name breaks in Opera so use _toString. 52 var _toString = ObjectPrototype.toString; 53 54 var isFunction = function (val) { 55 return ObjectPrototype.toString.call(val) === '[object Function]'; 56 }; 57 var isRegex = function (val) { 58 return ObjectPrototype.toString.call(val) === '[object RegExp]'; 59 }; 60 var isArray = function isArray(obj) { 61 return _toString.call(obj) === "[object Array]"; 62 }; 63 var isString = function isString(obj) { 64 return _toString.call(obj) === "[object String]"; 65 }; 66 var isArguments = function isArguments(value) { 67 var str = _toString.call(value); 68 var isArgs = str === '[object Arguments]'; 69 if (!isArgs) { 70 isArgs = !isArray(str) 71 && value !== null 72 && typeof value === 'object' 73 && typeof value.length === 'number' 74 && value.length >= 0 75 && isFunction(value.callee); 76 } 77 return isArgs; 78 }; 79 80 var supportsDescriptors = Object.defineProperty && (function () { 81 try { 82 Object.defineProperty({}, 'x', {}); 83 return true; 84 } catch (e) { /* this is ES3 */ 85 return false; 86 } 87 }()); 88 89 // Define configurable, writable and non-enumerable props 90 // if they don't exist. 91 var defineProperty; 92 if (supportsDescriptors) { 93 defineProperty = function (object, name, method, forceAssign) { 94 if (!forceAssign && (name in object)) { return; } 95 Object.defineProperty(object, name, { 96 configurable: true, 97 enumerable: false, 98 writable: true, 99 value: method 100 }); 101 }; 102 } else { 103 defineProperty = function (object, name, method, forceAssign) { 104 if (!forceAssign && (name in object)) { return; } 105 object[name] = method; 106 }; 107 } 108 var defineProperties = function (object, map, forceAssign) { 109 for (var name in map) { 110 if (ObjectPrototype.hasOwnProperty.call(map, name)) { 111 defineProperty(object, name, map[name], forceAssign); 112 } 113 } 114 }; 115 116 // 117 // Util 118 // ====== 119 // 120 121 // ES5 9.4 122 // http://es5.github.com/#x9.4 123 // http://jsperf.com/to-integer 124 125 function toInteger(n) { 126 n = +n; 127 if (n !== n) { // isNaN 128 n = 0; 129 } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { 130 n = (n > 0 || -1) * Math.floor(Math.abs(n)); 131 } 132 return n; 133 } 134 135 function isPrimitive(input) { 136 var type = typeof input; 137 return ( 138 input === null || 139 type === "undefined" || 140 type === "boolean" || 141 type === "number" || 142 type === "string" 143 ); 144 } 145 146 function toPrimitive(input) { 147 var val, valueOf, toStr; 148 if (isPrimitive(input)) { 149 return input; 150 } 151 valueOf = input.valueOf; 152 if (isFunction(valueOf)) { 153 val = valueOf.call(input); 154 if (isPrimitive(val)) { 155 return val; 156 } 157 } 158 toStr = input.toString; 159 if (isFunction(toStr)) { 160 val = toStr.call(input); 161 if (isPrimitive(val)) { 162 return val; 163 } 164 } 165 throw new TypeError(); 166 } 167 168 // ES5 9.9 169 // http://es5.github.com/#x9.9 170 var toObject = function (o) { 171 if (o == null) { // this matches both null and undefined 172 throw new TypeError("can't convert " + o + " to object"); 173 } 174 return Object(o); 175 }; 176 177 var ToUint32 = function ToUint32(x) { 178 return x >>> 0; 179 }; 180 181 // 182 // Function 183 // ======== 184 // 185 186 // ES-5 15.3.4.5 187 // http://es5.github.com/#x15.3.4.5 188 189 function Empty() {} 190 191 defineProperties(FunctionPrototype, { 192 bind: function bind(that) { // .length is 1 193 // 1. Let Target be the this value. 194 var target = this; 195 // 2. If IsCallable(Target) is false, throw a TypeError exception. 196 if (!isFunction(target)) { 197 throw new TypeError("Function.prototype.bind called on incompatible " + target); 198 } 199 // 3. Let A be a new (possibly empty) internal list of all of the 200 // argument values provided after thisArg (arg1, arg2 etc), in order. 201 // XXX slicedArgs will stand in for "A" if used 202 var args = _Array_slice_.call(arguments, 1); // for normal call 203 // 4. Let F be a new native ECMAScript object. 204 // 11. Set the [[Prototype]] internal property of F to the standard 205 // built-in Function prototype object as specified in 15.3.3.1. 206 // 12. Set the [[Call]] internal property of F as described in 207 // 15.3.4.5.1. 208 // 13. Set the [[Construct]] internal property of F as described in 209 // 15.3.4.5.2. 210 // 14. Set the [[HasInstance]] internal property of F as described in 211 // 15.3.4.5.3. 212 var binder = function () { 213 214 if (this instanceof bound) { 215 // 15.3.4.5.2 [[Construct]] 216 // When the [[Construct]] internal method of a function object, 217 // F that was created using the bind function is called with a 218 // list of arguments ExtraArgs, the following steps are taken: 219 // 1. Let target be the value of F's [[TargetFunction]] 220 // internal property. 221 // 2. If target has no [[Construct]] internal method, a 222 // TypeError exception is thrown. 223 // 3. Let boundArgs be the value of F's [[BoundArgs]] internal 224 // property. 225 // 4. Let args be a new list containing the same values as the 226 // list boundArgs in the same order followed by the same 227 // values as the list ExtraArgs in the same order. 228 // 5. Return the result of calling the [[Construct]] internal 229 // method of target providing args as the arguments. 230 231 var result = target.apply( 232 this, 233 args.concat(_Array_slice_.call(arguments)) 234 ); 235 if (Object(result) === result) { 236 return result; 237 } 238 return this; 239 240 } else { 241 // 15.3.4.5.1 [[Call]] 242 // When the [[Call]] internal method of a function object, F, 243 // which was created using the bind function is called with a 244 // this value and a list of arguments ExtraArgs, the following 245 // steps are taken: 246 // 1. Let boundArgs be the value of F's [[BoundArgs]] internal 247 // property. 248 // 2. Let boundThis be the value of F's [[BoundThis]] internal 249 // property. 250 // 3. Let target be the value of F's [[TargetFunction]] internal 251 // property. 252 // 4. Let args be a new list containing the same values as the 253 // list boundArgs in the same order followed by the same 254 // values as the list ExtraArgs in the same order. 255 // 5. Return the result of calling the [[Call]] internal method 256 // of target providing boundThis as the this value and 257 // providing args as the arguments. 258 259 // equiv: target.call(this, ...boundArgs, ...args) 260 return target.apply( 261 that, 262 args.concat(_Array_slice_.call(arguments)) 263 ); 264 265 } 266 267 }; 268 269 // 15. If the [[Class]] internal property of Target is "Function", then 270 // a. Let L be the length property of Target minus the length of A. 271 // b. Set the length own property of F to either 0 or L, whichever is 272 // larger. 273 // 16. Else set the length own property of F to 0. 274 275 var boundLength = Math.max(0, target.length - args.length); 276 277 // 17. Set the attributes of the length own property of F to the values 278 // specified in 15.3.5.1. 279 var boundArgs = []; 280 for (var i = 0; i < boundLength; i++) { 281 boundArgs.push("$" + i); 282 } 283 284 // XXX Build a dynamic function with desired amount of arguments is the only 285 // way to set the length property of a function. 286 // In environments where Content Security Policies enabled (Chrome extensions, 287 // for ex.) all use of eval or Function costructor throws an exception. 288 // However in all of these environments Function.prototype.bind exists 289 // and so this code will never be executed. 290 var bound = Function("binder", "return function (" + boundArgs.join(",") + "){return binder.apply(this,arguments)}")(binder); 291 292 if (target.prototype) { 293 Empty.prototype = target.prototype; 294 bound.prototype = new Empty(); 295 // Clean up dangling references. 296 Empty.prototype = null; 297 } 298 299 // TODO 300 // 18. Set the [[Extensible]] internal property of F to true. 301 302 // TODO 303 // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). 304 // 20. Call the [[DefineOwnProperty]] internal method of F with 305 // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: 306 // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and 307 // false. 308 // 21. Call the [[DefineOwnProperty]] internal method of F with 309 // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, 310 // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, 311 // and false. 312 313 // TODO 314 // NOTE Function objects created using Function.prototype.bind do not 315 // have a prototype property or the [[Code]], [[FormalParameters]], and 316 // [[Scope]] internal properties. 317 // XXX can't delete prototype in pure-js. 318 319 // 22. Return F. 320 return bound; 321 } 322 }); 323 324 // _Please note: Shortcuts are defined after `Function.prototype.bind` as we 325 // us it in defining shortcuts. 326 var owns = call.bind(ObjectPrototype.hasOwnProperty); 327 328 // If JS engine supports accessors creating shortcuts. 329 var defineGetter; 330 var defineSetter; 331 var lookupGetter; 332 var lookupSetter; 333 var supportsAccessors; 334 if ((supportsAccessors = owns(ObjectPrototype, "__defineGetter__"))) { 335 defineGetter = call.bind(ObjectPrototype.__defineGetter__); 336 defineSetter = call.bind(ObjectPrototype.__defineSetter__); 337 lookupGetter = call.bind(ObjectPrototype.__lookupGetter__); 338 lookupSetter = call.bind(ObjectPrototype.__lookupSetter__); 339 } 340 341 // 342 // Array 343 // ===== 344 // 345 346 // ES5 15.4.4.12 347 // http://es5.github.com/#x15.4.4.12 348 var spliceNoopReturnsEmptyArray = (function () { 349 var a = [1, 2]; 350 var result = a.splice(); 351 return a.length === 2 && isArray(result) && result.length === 0; 352 }()); 353 defineProperties(ArrayPrototype, { 354 // Safari 5.0 bug where .splice() returns undefined 355 splice: function splice(start, deleteCount) { 356 if (arguments.length === 0) { 357 return []; 358 } else { 359 return array_splice.apply(this, arguments); 360 } 361 } 362 }, spliceNoopReturnsEmptyArray); 363 364 var spliceWorksWithEmptyObject = (function () { 365 var obj = {}; 366 ArrayPrototype.splice.call(obj, 0, 0, 1); 367 return obj.length === 1; 368 }()); 369 defineProperties(ArrayPrototype, { 370 splice: function splice(start, deleteCount) { 371 if (arguments.length === 0) { return []; } 372 var args = arguments; 373 this.length = Math.max(toInteger(this.length), 0); 374 if (arguments.length > 0 && typeof deleteCount !== 'number') { 375 args = _Array_slice_.call(arguments); 376 if (args.length < 2) { 377 args.push(this.length - start); 378 } else { 379 args[1] = toInteger(deleteCount); 380 } 381 } 382 return array_splice.apply(this, args); 383 } 384 }, !spliceWorksWithEmptyObject); 385 386 // ES5 15.4.4.12 387 // http://es5.github.com/#x15.4.4.13 388 // Return len+argCount. 389 // [bugfix, ielt8] 390 // IE < 8 bug: [].unshift(0) === undefined but should be "1" 391 var hasUnshiftReturnValueBug = [].unshift(0) !== 1; 392 defineProperties(ArrayPrototype, { 393 unshift: function () { 394 array_unshift.apply(this, arguments); 395 return this.length; 396 } 397 }, hasUnshiftReturnValueBug); 398 399 // ES5 15.4.3.2 400 // http://es5.github.com/#x15.4.3.2 401 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray 402 defineProperties(Array, { isArray: isArray }); 403 404 // The IsCallable() check in the Array functions 405 // has been replaced with a strict check on the 406 // internal class of the object to trap cases where 407 // the provided function was actually a regular 408 // expression literal, which in V8 and 409 // JavaScriptCore is a typeof "function". Only in 410 // V8 are regular expression literals permitted as 411 // reduce parameters, so it is desirable in the 412 // general case for the shim to match the more 413 // strict and common behavior of rejecting regular 414 // expressions. 415 416 // ES5 15.4.4.18 417 // http://es5.github.com/#x15.4.4.18 418 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach 419 420 // Check failure of by-index access of string characters (IE < 9) 421 // and failure of `0 in boxedString` (Rhino) 422 var boxedString = Object("a"); 423 var splitString = boxedString[0] !== "a" || !(0 in boxedString); 424 425 var properlyBoxesContext = function properlyBoxed(method) { 426 // Check node 0.6.21 bug where third parameter is not boxed 427 var properlyBoxesNonStrict = true; 428 var properlyBoxesStrict = true; 429 if (method) { 430 method.call('foo', function (_, __, context) { 431 if (typeof context !== 'object') { properlyBoxesNonStrict = false; } 432 }); 433 434 method.call([1], function () { 435 'use strict'; 436 properlyBoxesStrict = typeof this === 'string'; 437 }, 'x'); 438 } 439 return !!method && properlyBoxesNonStrict && properlyBoxesStrict; 440 }; 441 442 defineProperties(ArrayPrototype, { 443 forEach: function forEach(fun /*, thisp*/) { 444 var object = toObject(this), 445 self = splitString && isString(this) ? this.split('') : object, 446 thisp = arguments[1], 447 i = -1, 448 length = self.length >>> 0; 449 450 // If no callback function or if callback is not a callable function 451 if (!isFunction(fun)) { 452 throw new TypeError(); // TODO message 453 } 454 455 while (++i < length) { 456 if (i in self) { 457 // Invoke the callback function with call, passing arguments: 458 // context, property value, property key, thisArg object 459 // context 460 fun.call(thisp, self[i], i, object); 461 } 462 } 463 } 464 }, !properlyBoxesContext(ArrayPrototype.forEach)); 465 466 // ES5 15.4.4.19 467 // http://es5.github.com/#x15.4.4.19 468 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map 469 defineProperties(ArrayPrototype, { 470 map: function map(fun /*, thisp*/) { 471 var object = toObject(this), 472 self = splitString && isString(this) ? this.split('') : object, 473 length = self.length >>> 0, 474 result = Array(length), 475 thisp = arguments[1]; 476 477 // If no callback function or if callback is not a callable function 478 if (!isFunction(fun)) { 479 throw new TypeError(fun + " is not a function"); 480 } 481 482 for (var i = 0; i < length; i++) { 483 if (i in self) { 484 result[i] = fun.call(thisp, self[i], i, object); 485 } 486 } 487 return result; 488 } 489 }, !properlyBoxesContext(ArrayPrototype.map)); 490 491 // ES5 15.4.4.20 492 // http://es5.github.com/#x15.4.4.20 493 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter 494 defineProperties(ArrayPrototype, { 495 filter: function filter(fun /*, thisp */) { 496 var object = toObject(this), 497 self = splitString && isString(this) ? this.split('') : object, 498 length = self.length >>> 0, 499 result = [], 500 value, 501 thisp = arguments[1]; 502 503 // If no callback function or if callback is not a callable function 504 if (!isFunction(fun)) { 505 throw new TypeError(fun + " is not a function"); 506 } 507 508 for (var i = 0; i < length; i++) { 509 if (i in self) { 510 value = self[i]; 511 if (fun.call(thisp, value, i, object)) { 512 result.push(value); 513 } 514 } 515 } 516 return result; 517 } 518 }, !properlyBoxesContext(ArrayPrototype.filter)); 519 520 // ES5 15.4.4.16 521 // http://es5.github.com/#x15.4.4.16 522 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every 523 defineProperties(ArrayPrototype, { 524 every: function every(fun /*, thisp */) { 525 var object = toObject(this), 526 self = splitString && isString(this) ? this.split('') : object, 527 length = self.length >>> 0, 528 thisp = arguments[1]; 529 530 // If no callback function or if callback is not a callable function 531 if (!isFunction(fun)) { 532 throw new TypeError(fun + " is not a function"); 533 } 534 535 for (var i = 0; i < length; i++) { 536 if (i in self && !fun.call(thisp, self[i], i, object)) { 537 return false; 538 } 539 } 540 return true; 541 } 542 }, !properlyBoxesContext(ArrayPrototype.every)); 543 544 // ES5 15.4.4.17 545 // http://es5.github.com/#x15.4.4.17 546 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some 547 defineProperties(ArrayPrototype, { 548 some: function some(fun /*, thisp */) { 549 var object = toObject(this), 550 self = splitString && isString(this) ? this.split('') : object, 551 length = self.length >>> 0, 552 thisp = arguments[1]; 553 554 // If no callback function or if callback is not a callable function 555 if (!isFunction(fun)) { 556 throw new TypeError(fun + " is not a function"); 557 } 558 559 for (var i = 0; i < length; i++) { 560 if (i in self && fun.call(thisp, self[i], i, object)) { 561 return true; 562 } 563 } 564 return false; 565 } 566 }, !properlyBoxesContext(ArrayPrototype.some)); 567 568 // ES5 15.4.4.21 569 // http://es5.github.com/#x15.4.4.21 570 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce 571 var reduceCoercesToObject = false; 572 if (ArrayPrototype.reduce) { 573 reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object'; 574 } 575 defineProperties(ArrayPrototype, { 576 reduce: function reduce(fun /*, initial*/) { 577 var object = toObject(this), 578 self = splitString && isString(this) ? this.split('') : object, 579 length = self.length >>> 0; 580 581 // If no callback function or if callback is not a callable function 582 if (!isFunction(fun)) { 583 throw new TypeError(fun + " is not a function"); 584 } 585 586 // no value to return if no initial value and an empty array 587 if (!length && arguments.length === 1) { 588 throw new TypeError("reduce of empty array with no initial value"); 589 } 590 591 var i = 0; 592 var result; 593 if (arguments.length >= 2) { 594 result = arguments[1]; 595 } else { 596 do { 597 if (i in self) { 598 result = self[i++]; 599 break; 600 } 601 602 // if array contains no values, no initial value to return 603 if (++i >= length) { 604 throw new TypeError("reduce of empty array with no initial value"); 605 } 606 } while (true); 607 } 608 609 for (; i < length; i++) { 610 if (i in self) { 611 result = fun.call(void 0, result, self[i], i, object); 612 } 613 } 614 615 return result; 616 } 617 }, !reduceCoercesToObject); 618 619 // ES5 15.4.4.22 620 // http://es5.github.com/#x15.4.4.22 621 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight 622 var reduceRightCoercesToObject = false; 623 if (ArrayPrototype.reduceRight) { 624 reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object'; 625 } 626 defineProperties(ArrayPrototype, { 627 reduceRight: function reduceRight(fun /*, initial*/) { 628 var object = toObject(this), 629 self = splitString && isString(this) ? this.split('') : object, 630 length = self.length >>> 0; 631 632 // If no callback function or if callback is not a callable function 633 if (!isFunction(fun)) { 634 throw new TypeError(fun + " is not a function"); 635 } 636 637 // no value to return if no initial value, empty array 638 if (!length && arguments.length === 1) { 639 throw new TypeError("reduceRight of empty array with no initial value"); 640 } 641 642 var result, i = length - 1; 643 if (arguments.length >= 2) { 644 result = arguments[1]; 645 } else { 646 do { 647 if (i in self) { 648 result = self[i--]; 649 break; 650 } 651 652 // if array contains no values, no initial value to return 653 if (--i < 0) { 654 throw new TypeError("reduceRight of empty array with no initial value"); 655 } 656 } while (true); 657 } 658 659 if (i < 0) { 660 return result; 661 } 662 663 do { 664 if (i in self) { 665 result = fun.call(void 0, result, self[i], i, object); 666 } 667 } while (i--); 668 669 return result; 670 } 671 }, !reduceRightCoercesToObject); 672 673 // ES5 15.4.4.14 674 // http://es5.github.com/#x15.4.4.14 675 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf 676 var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1; 677 defineProperties(ArrayPrototype, { 678 indexOf: function indexOf(sought /*, fromIndex */ ) { 679 var self = splitString && isString(this) ? this.split('') : toObject(this), 680 length = self.length >>> 0; 681 682 if (!length) { 683 return -1; 684 } 685 686 var i = 0; 687 if (arguments.length > 1) { 688 i = toInteger(arguments[1]); 689 } 690 691 // handle negative indices 692 i = i >= 0 ? i : Math.max(0, length + i); 693 for (; i < length; i++) { 694 if (i in self && self[i] === sought) { 695 return i; 696 } 697 } 698 return -1; 699 } 700 }, hasFirefox2IndexOfBug); 701 702 // ES5 15.4.4.15 703 // http://es5.github.com/#x15.4.4.15 704 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf 705 var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1; 706 defineProperties(ArrayPrototype, { 707 lastIndexOf: function lastIndexOf(sought /*, fromIndex */) { 708 var self = splitString && isString(this) ? this.split('') : toObject(this), 709 length = self.length >>> 0; 710 711 if (!length) { 712 return -1; 713 } 714 var i = length - 1; 715 if (arguments.length > 1) { 716 i = Math.min(i, toInteger(arguments[1])); 717 } 718 // handle negative indices 719 i = i >= 0 ? i : length - Math.abs(i); 720 for (; i >= 0; i--) { 721 if (i in self && sought === self[i]) { 722 return i; 723 } 724 } 725 return -1; 726 } 727 }, hasFirefox2LastIndexOfBug); 728 729 // 730 // Object 731 // ====== 732 // 733 734 // ES5 15.2.3.14 735 // http://es5.github.com/#x15.2.3.14 736 737 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation 738 var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), 739 hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), 740 dontEnums = [ 741 "toString", 742 "toLocaleString", 743 "valueOf", 744 "hasOwnProperty", 745 "isPrototypeOf", 746 "propertyIsEnumerable", 747 "constructor" 748 ], 749 dontEnumsLength = dontEnums.length; 750 751 defineProperties(Object, { 752 keys: function keys(object) { 753 var isFn = isFunction(object), 754 isArgs = isArguments(object), 755 isObject = object !== null && typeof object === 'object', 756 isStr = isObject && isString(object); 757 758 if (!isObject && !isFn && !isArgs) { 759 throw new TypeError("Object.keys called on a non-object"); 760 } 761 762 var theKeys = []; 763 var skipProto = hasProtoEnumBug && isFn; 764 if (isStr || isArgs) { 765 for (var i = 0; i < object.length; ++i) { 766 theKeys.push(String(i)); 767 } 768 } else { 769 for (var name in object) { 770 if (!(skipProto && name === 'prototype') && owns(object, name)) { 771 theKeys.push(String(name)); 772 } 773 } 774 } 775 776 if (hasDontEnumBug) { 777 var ctor = object.constructor, 778 skipConstructor = ctor && ctor.prototype === object; 779 for (var j = 0; j < dontEnumsLength; j++) { 780 var dontEnum = dontEnums[j]; 781 if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) { 782 theKeys.push(dontEnum); 783 } 784 } 785 } 786 return theKeys; 787 } 788 }); 789 790 var keysWorksWithArguments = Object.keys && (function () { 791 // Safari 5.0 bug 792 return Object.keys(arguments).length === 2; 793 }(1, 2)); 794 var originalKeys = Object.keys; 795 defineProperties(Object, { 796 keys: function keys(object) { 797 if (isArguments(object)) { 798 return originalKeys(ArrayPrototype.slice.call(object)); 799 } else { 800 return originalKeys(object); 801 } 802 } 803 }, !keysWorksWithArguments); 804 805 // 806 // Date 807 // ==== 808 // 809 810 // ES5 15.9.5.43 811 // http://es5.github.com/#x15.9.5.43 812 // This function returns a String value represent the instance in time 813 // represented by this Date object. The format of the String is the Date Time 814 // string format defined in 15.9.1.15. All fields are present in the String. 815 // The time zone is always UTC, denoted by the suffix Z. If the time value of 816 // this object is not a finite Number a RangeError exception is thrown. 817 var negativeDate = -62198755200000; 818 var negativeYearString = "-000001"; 819 var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; 820 821 defineProperties(Date.prototype, { 822 toISOString: function toISOString() { 823 var result, length, value, year, month; 824 if (!isFinite(this)) { 825 throw new RangeError("Date.prototype.toISOString called on non-finite value."); 826 } 827 828 year = this.getUTCFullYear(); 829 830 month = this.getUTCMonth(); 831 // see https://github.com/es-shims/es5-shim/issues/111 832 year += Math.floor(month / 12); 833 month = (month % 12 + 12) % 12; 834 835 // the date time string format is specified in 15.9.1.15. 836 result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; 837 year = ( 838 (year < 0 ? "-" : (year > 9999 ? "+" : "")) + 839 ("00000" + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6) 840 ); 841 842 length = result.length; 843 while (length--) { 844 value = result[length]; 845 // pad months, days, hours, minutes, and seconds to have two 846 // digits. 847 if (value < 10) { 848 result[length] = "0" + value; 849 } 850 } 851 // pad milliseconds to have three digits. 852 return ( 853 year + "-" + result.slice(0, 2).join("-") + 854 "T" + result.slice(2).join(":") + "." + 855 ("000" + this.getUTCMilliseconds()).slice(-3) + "Z" 856 ); 857 } 858 }, hasNegativeDateBug); 859 860 861 // ES5 15.9.5.44 862 // http://es5.github.com/#x15.9.5.44 863 // This function provides a String representation of a Date object for use by 864 // JSON.stringify (15.12.3). 865 var dateToJSONIsSupported = false; 866 try { 867 dateToJSONIsSupported = ( 868 Date.prototype.toJSON && 869 new Date(NaN).toJSON() === null && 870 new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && 871 Date.prototype.toJSON.call({ // generic 872 toISOString: function () { 873 return true; 874 } 875 }) 876 ); 877 } catch (e) { 878 } 879 if (!dateToJSONIsSupported) { 880 Date.prototype.toJSON = function toJSON(key) { 881 // When the toJSON method is called with argument key, the following 882 // steps are taken: 883 884 // 1. Let O be the result of calling ToObject, giving it the this 885 // value as its argument. 886 // 2. Let tv be toPrimitive(O, hint Number). 887 var o = Object(this), 888 tv = toPrimitive(o), 889 toISO; 890 // 3. If tv is a Number and is not finite, return null. 891 if (typeof tv === "number" && !isFinite(tv)) { 892 return null; 893 } 894 // 4. Let toISO be the result of calling the [[Get]] internal method of 895 // O with argument "toISOString". 896 toISO = o.toISOString; 897 // 5. If IsCallable(toISO) is false, throw a TypeError exception. 898 if (typeof toISO !== "function") { 899 throw new TypeError("toISOString property is not callable"); 900 } 901 // 6. Return the result of calling the [[Call]] internal method of 902 // toISO with O as the this value and an empty argument list. 903 return toISO.call(o); 904 905 // NOTE 1 The argument is ignored. 906 907 // NOTE 2 The toJSON function is intentionally generic; it does not 908 // require that its this value be a Date object. Therefore, it can be 909 // transferred to other kinds of objects for use as a method. However, 910 // it does require that any such object have a toISOString method. An 911 // object is free to use the argument key to filter its 912 // stringification. 913 }; 914 } 915 916 // ES5 15.9.4.2 917 // http://es5.github.com/#x15.9.4.2 918 // based on work shared by Daniel Friesen (dantman) 919 // http://gist.github.com/303249 920 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15; 921 var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')); 922 var doesNotParseY2KNewYear = isNaN(Date.parse("2000-01-01T00:00:00.000Z")); 923 if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) { 924 // XXX global assignment won't work in embeddings that use 925 // an alternate object for the context. 926 Date = (function (NativeDate) { 927 928 // Date.length === 7 929 function Date(Y, M, D, h, m, s, ms) { 930 var length = arguments.length; 931 if (this instanceof NativeDate) { 932 var date = length === 1 && String(Y) === Y ? // isString(Y) 933 // We explicitly pass it through parse: 934 new NativeDate(Date.parse(Y)) : 935 // We have to manually make calls depending on argument 936 // length here 937 length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) : 938 length >= 6 ? new NativeDate(Y, M, D, h, m, s) : 939 length >= 5 ? new NativeDate(Y, M, D, h, m) : 940 length >= 4 ? new NativeDate(Y, M, D, h) : 941 length >= 3 ? new NativeDate(Y, M, D) : 942 length >= 2 ? new NativeDate(Y, M) : 943 length >= 1 ? new NativeDate(Y) : 944 new NativeDate(); 945 // Prevent mixups with unfixed Date object 946 date.constructor = Date; 947 return date; 948 } 949 return NativeDate.apply(this, arguments); 950 } 951 952 // 15.9.1.15 Date Time String Format. 953 var isoDateExpression = new RegExp("^" + 954 "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + 955 // 6-digit extended year 956 "(?:-(\\d{2})" + // optional month capture 957 "(?:-(\\d{2})" + // optional day capture 958 "(?:" + // capture hours:minutes:seconds.milliseconds 959 "T(\\d{2})" + // hours capture 960 ":(\\d{2})" + // minutes capture 961 "(?:" + // optional :seconds.milliseconds 962 ":(\\d{2})" + // seconds capture 963 "(?:(\\.\\d{1,}))?" + // milliseconds capture 964 ")?" + 965 "(" + // capture UTC offset component 966 "Z|" + // UTC capture 967 "(?:" + // offset specifier +/-hours:minutes 968 "([-+])" + // sign capture 969 "(\\d{2})" + // hours offset capture 970 ":(\\d{2})" + // minutes offset capture 971 ")" + 972 ")?)?)?)?" + 973 "$"); 974 975 var months = [ 976 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 977 ]; 978 979 function dayFromMonth(year, month) { 980 var t = month > 1 ? 1 : 0; 981 return ( 982 months[month] + 983 Math.floor((year - 1969 + t) / 4) - 984 Math.floor((year - 1901 + t) / 100) + 985 Math.floor((year - 1601 + t) / 400) + 986 365 * (year - 1970) 987 ); 988 } 989 990 function toUTC(t) { 991 return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t)); 992 } 993 994 // Copy any custom methods a 3rd party library may have added 995 for (var key in NativeDate) { 996 Date[key] = NativeDate[key]; 997 } 998 999 // Copy "native" methods explicitly; they may be non-enumerable 1000 Date.now = NativeDate.now; 1001 Date.UTC = NativeDate.UTC; 1002 Date.prototype = NativeDate.prototype; 1003 Date.prototype.constructor = Date; 1004 1005 // Upgrade Date.parse to handle simplified ISO 8601 strings 1006 Date.parse = function parse(string) { 1007 var match = isoDateExpression.exec(string); 1008 if (match) { 1009 // parse months, days, hours, minutes, seconds, and milliseconds 1010 // provide default values if necessary 1011 // parse the UTC offset component 1012 var year = Number(match[1]), 1013 month = Number(match[2] || 1) - 1, 1014 day = Number(match[3] || 1) - 1, 1015 hour = Number(match[4] || 0), 1016 minute = Number(match[5] || 0), 1017 second = Number(match[6] || 0), 1018 millisecond = Math.floor(Number(match[7] || 0) * 1000), 1019 // When time zone is missed, local offset should be used 1020 // (ES 5.1 bug) 1021 // see https://bugs.ecmascript.org/show_bug.cgi?id=112 1022 isLocalTime = Boolean(match[4] && !match[8]), 1023 signOffset = match[9] === "-" ? 1 : -1, 1024 hourOffset = Number(match[10] || 0), 1025 minuteOffset = Number(match[11] || 0), 1026 result; 1027 if ( 1028 hour < ( 1029 minute > 0 || second > 0 || millisecond > 0 ? 1030 24 : 25 1031 ) && 1032 minute < 60 && second < 60 && millisecond < 1000 && 1033 month > -1 && month < 12 && hourOffset < 24 && 1034 minuteOffset < 60 && // detect invalid offsets 1035 day > -1 && 1036 day < ( 1037 dayFromMonth(year, month + 1) - 1038 dayFromMonth(year, month) 1039 ) 1040 ) { 1041 result = ( 1042 (dayFromMonth(year, month) + day) * 24 + 1043 hour + 1044 hourOffset * signOffset 1045 ) * 60; 1046 result = ( 1047 (result + minute + minuteOffset * signOffset) * 60 + 1048 second 1049 ) * 1000 + millisecond; 1050 if (isLocalTime) { 1051 result = toUTC(result); 1052 } 1053 if (-8.64e15 <= result && result <= 8.64e15) { 1054 return result; 1055 } 1056 } 1057 return NaN; 1058 } 1059 return NativeDate.parse.apply(this, arguments); 1060 }; 1061 1062 return Date; 1063 })(Date); 1064 } 1065 1066 // ES5 15.9.4.4 1067 // http://es5.github.com/#x15.9.4.4 1068 if (!Date.now) { 1069 Date.now = function now() { 1070 return new Date().getTime(); 1071 }; 1072 } 1073 1074 1075 // 1076 // Number 1077 // ====== 1078 // 1079 1080 // ES5.1 15.7.4.5 1081 // http://es5.github.com/#x15.7.4.5 1082 var hasToFixedBugs = NumberPrototype.toFixed && ( 1083 (0.00008).toFixed(3) !== '0.000' 1084 || (0.9).toFixed(0) !== '1' 1085 || (1.255).toFixed(2) !== '1.25' 1086 || (1000000000000000128).toFixed(0) !== "1000000000000000128" 1087 ); 1088 1089 var toFixedHelpers = { 1090 base: 1e7, 1091 size: 6, 1092 data: [0, 0, 0, 0, 0, 0], 1093 multiply: function multiply(n, c) { 1094 var i = -1; 1095 while (++i < toFixedHelpers.size) { 1096 c += n * toFixedHelpers.data[i]; 1097 toFixedHelpers.data[i] = c % toFixedHelpers.base; 1098 c = Math.floor(c / toFixedHelpers.base); 1099 } 1100 }, 1101 divide: function divide(n) { 1102 var i = toFixedHelpers.size, c = 0; 1103 while (--i >= 0) { 1104 c += toFixedHelpers.data[i]; 1105 toFixedHelpers.data[i] = Math.floor(c / n); 1106 c = (c % n) * toFixedHelpers.base; 1107 } 1108 }, 1109 numToString: function numToString() { 1110 var i = toFixedHelpers.size; 1111 var s = ''; 1112 while (--i >= 0) { 1113 if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) { 1114 var t = String(toFixedHelpers.data[i]); 1115 if (s === '') { 1116 s = t; 1117 } else { 1118 s += '0000000'.slice(0, 7 - t.length) + t; 1119 } 1120 } 1121 } 1122 return s; 1123 }, 1124 pow: function pow(x, n, acc) { 1125 return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); 1126 }, 1127 log: function log(x) { 1128 var n = 0; 1129 while (x >= 4096) { 1130 n += 12; 1131 x /= 4096; 1132 } 1133 while (x >= 2) { 1134 n += 1; 1135 x /= 2; 1136 } 1137 return n; 1138 } 1139 }; 1140 1141 defineProperties(NumberPrototype, { 1142 toFixed: function toFixed(fractionDigits) { 1143 var f, x, s, m, e, z, j, k; 1144 1145 // Test for NaN and round fractionDigits down 1146 f = Number(fractionDigits); 1147 f = f !== f ? 0 : Math.floor(f); 1148 1149 if (f < 0 || f > 20) { 1150 throw new RangeError("Number.toFixed called with invalid number of decimals"); 1151 } 1152 1153 x = Number(this); 1154 1155 // Test for NaN 1156 if (x !== x) { 1157 return "NaN"; 1158 } 1159 1160 // If it is too big or small, return the string value of the number 1161 if (x <= -1e21 || x >= 1e21) { 1162 return String(x); 1163 } 1164 1165 s = ""; 1166 1167 if (x < 0) { 1168 s = "-"; 1169 x = -x; 1170 } 1171 1172 m = "0"; 1173 1174 if (x > 1e-21) { 1175 // 1e-21 < x < 1e21 1176 // -70 < log2(x) < 70 1177 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69; 1178 z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1)); 1179 z *= 0x10000000000000; // Math.pow(2, 52); 1180 e = 52 - e; 1181 1182 // -18 < e < 122 1183 // x = z / 2 ^ e 1184 if (e > 0) { 1185 toFixedHelpers.multiply(0, z); 1186 j = f; 1187 1188 while (j >= 7) { 1189 toFixedHelpers.multiply(1e7, 0); 1190 j -= 7; 1191 } 1192 1193 toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0); 1194 j = e - 1; 1195 1196 while (j >= 23) { 1197 toFixedHelpers.divide(1 << 23); 1198 j -= 23; 1199 } 1200 1201 toFixedHelpers.divide(1 << j); 1202 toFixedHelpers.multiply(1, 1); 1203 toFixedHelpers.divide(2); 1204 m = toFixedHelpers.numToString(); 1205 } else { 1206 toFixedHelpers.multiply(0, z); 1207 toFixedHelpers.multiply(1 << (-e), 0); 1208 m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f); 1209 } 1210 } 1211 1212 if (f > 0) { 1213 k = m.length; 1214 1215 if (k <= f) { 1216 m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m; 1217 } else { 1218 m = s + m.slice(0, k - f) + '.' + m.slice(k - f); 1219 } 1220 } else { 1221 m = s + m; 1222 } 1223 1224 return m; 1225 } 1226 }, hasToFixedBugs); 1227 1228 1229 // 1230 // String 1231 // ====== 1232 // 1233 1234 // ES5 15.5.4.14 1235 // http://es5.github.com/#x15.5.4.14 1236 1237 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers] 1238 // Many browsers do not split properly with regular expressions or they 1239 // do not perform the split correctly under obscure conditions. 1240 // See http://blog.stevenlevithan.com/archives/cross-browser-split 1241 // I've tested in many browsers and this seems to cover the deviant ones: 1242 // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] 1243 // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] 1244 // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not 1245 // [undefined, "t", undefined, "e", ...] 1246 // ''.split(/.?/) should be [], not [""] 1247 // '.'.split(/()()/) should be ["."], not ["", "", "."] 1248 1249 var string_split = StringPrototype.split; 1250 if ( 1251 'ab'.split(/(?:ab)*/).length !== 2 || 1252 '.'.split(/(.?)(.?)/).length !== 4 || 1253 'tesst'.split(/(s)*/)[1] === "t" || 1254 'test'.split(/(?:)/, -1).length !== 4 || 1255 ''.split(/.?/).length || 1256 '.'.split(/()()/).length > 1 1257 ) { 1258 (function () { 1259 var compliantExecNpcg = /()??/.exec("")[1] === void 0; // NPCG: nonparticipating capturing group 1260 1261 StringPrototype.split = function (separator, limit) { 1262 var string = this; 1263 if (separator === void 0 && limit === 0) { 1264 return []; 1265 } 1266 1267 // If `separator` is not a regex, use native split 1268 if (_toString.call(separator) !== "[object RegExp]") { 1269 return string_split.call(this, separator, limit); 1270 } 1271 1272 var output = [], 1273 flags = (separator.ignoreCase ? "i" : "") + 1274 (separator.multiline ? "m" : "") + 1275 (separator.extended ? "x" : "") + // Proposed for ES6 1276 (separator.sticky ? "y" : ""), // Firefox 3+ 1277 lastLastIndex = 0, 1278 // Make `global` and avoid `lastIndex` issues by working with a copy 1279 separator2, match, lastIndex, lastLength; 1280 separator = new RegExp(separator.source, flags + "g"); 1281 string += ""; // Type-convert 1282 if (!compliantExecNpcg) { 1283 // Doesn't need flags gy, but they don't hurt 1284 separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags); 1285 } 1286 /* Values for `limit`, per the spec: 1287 * If undefined: 4294967295 // Math.pow(2, 32) - 1 1288 * If 0, Infinity, or NaN: 0 1289 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; 1290 * If negative number: 4294967296 - Math.floor(Math.abs(limit)) 1291 * If other: Type-convert, then use the above rules 1292 */ 1293 limit = limit === void 0 ? 1294 -1 >>> 0 : // Math.pow(2, 32) - 1 1295 ToUint32(limit); 1296 while (match = separator.exec(string)) { 1297 // `separator.lastIndex` is not reliable cross-browser 1298 lastIndex = match.index + match[0].length; 1299 if (lastIndex > lastLastIndex) { 1300 output.push(string.slice(lastLastIndex, match.index)); 1301 // Fix browsers whose `exec` methods don't consistently return `undefined` for 1302 // nonparticipating capturing groups 1303 if (!compliantExecNpcg && match.length > 1) { 1304 match[0].replace(separator2, function () { 1305 for (var i = 1; i < arguments.length - 2; i++) { 1306 if (arguments[i] === void 0) { 1307 match[i] = void 0; 1308 } 1309 } 1310 }); 1311 } 1312 if (match.length > 1 && match.index < string.length) { 1313 ArrayPrototype.push.apply(output, match.slice(1)); 1314 } 1315 lastLength = match[0].length; 1316 lastLastIndex = lastIndex; 1317 if (output.length >= limit) { 1318 break; 1319 } 1320 } 1321 if (separator.lastIndex === match.index) { 1322 separator.lastIndex++; // Avoid an infinite loop 1323 } 1324 } 1325 if (lastLastIndex === string.length) { 1326 if (lastLength || !separator.test("")) { 1327 output.push(""); 1328 } 1329 } else { 1330 output.push(string.slice(lastLastIndex)); 1331 } 1332 return output.length > limit ? output.slice(0, limit) : output; 1333 }; 1334 }()); 1335 1336 // [bugfix, chrome] 1337 // If separator is undefined, then the result array contains just one String, 1338 // which is the this value (converted to a String). If limit is not undefined, 1339 // then the output array is truncated so that it contains no more than limit 1340 // elements. 1341 // "0".split(undefined, 0) -> [] 1342 } else if ("0".split(void 0, 0).length) { 1343 StringPrototype.split = function split(separator, limit) { 1344 if (separator === void 0 && limit === 0) { return []; } 1345 return string_split.call(this, separator, limit); 1346 }; 1347 } 1348 1349 var str_replace = StringPrototype.replace; 1350 var replaceReportsGroupsCorrectly = (function () { 1351 var groups = []; 1352 'x'.replace(/x(.)?/g, function (match, group) { 1353 groups.push(group); 1354 }); 1355 return groups.length === 1 && typeof groups[0] === 'undefined'; 1356 }()); 1357 1358 if (!replaceReportsGroupsCorrectly) { 1359 StringPrototype.replace = function replace(searchValue, replaceValue) { 1360 var isFn = isFunction(replaceValue); 1361 var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source); 1362 if (!isFn || !hasCapturingGroups) { 1363 return str_replace.call(this, searchValue, replaceValue); 1364 } else { 1365 var wrappedReplaceValue = function (match) { 1366 var length = arguments.length; 1367 var originalLastIndex = searchValue.lastIndex; 1368 searchValue.lastIndex = 0; 1369 var args = searchValue.exec(match); 1370 searchValue.lastIndex = originalLastIndex; 1371 args.push(arguments[length - 2], arguments[length - 1]); 1372 return replaceValue.apply(this, args); 1373 }; 1374 return str_replace.call(this, searchValue, wrappedReplaceValue); 1375 } 1376 }; 1377 } 1378 1379 // ECMA-262, 3rd B.2.3 1380 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a 1381 // non-normative section suggesting uniform semantics and it should be 1382 // normalized across all browsers 1383 // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE 1384 var string_substr = StringPrototype.substr; 1385 var hasNegativeSubstrBug = "".substr && "0b".substr(-1) !== "b"; 1386 defineProperties(StringPrototype, { 1387 substr: function substr(start, length) { 1388 return string_substr.call( 1389 this, 1390 start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start, 1391 length 1392 ); 1393 } 1394 }, hasNegativeSubstrBug); 1395 1396 // ES5 15.5.4.20 1397 // whitespace from: http://es5.github.io/#x15.5.4.20 1398 var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + 1399 "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + 1400 "\u2029\uFEFF"; 1401 var zeroWidth = '\u200b'; 1402 var wsRegexChars = "[" + ws + "]"; 1403 var trimBeginRegexp = new RegExp("^" + wsRegexChars + wsRegexChars + "*"); 1404 var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + "*$"); 1405 var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim()); 1406 defineProperties(StringPrototype, { 1407 // http://blog.stevenlevithan.com/archives/faster-trim-javascript 1408 // http://perfectionkills.com/whitespace-deviations/ 1409 trim: function trim() { 1410 if (this === void 0 || this === null) { 1411 throw new TypeError("can't convert " + this + " to object"); 1412 } 1413 return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); 1414 } 1415 }, hasTrimWhitespaceBug); 1416 1417 // ES-5 15.1.2.2 1418 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { 1419 parseInt = (function (origParseInt) { 1420 var hexRegex = /^0[xX]/; 1421 return function parseIntES5(str, radix) { 1422 str = String(str).trim(); 1423 if (!Number(radix)) { 1424 radix = hexRegex.test(str) ? 16 : 10; 1425 } 1426 return origParseInt(str, radix); 1427 }; 1428 }(parseInt)); 1429 } 1430 1431 }));
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |