From 07cacd9190b92f3182d5bb191cf3c536711ace58 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 17 Nov 2012 18:48:34 +0400 Subject: [PATCH] update es5-shim to v 2.0.5 --- lib/ace/lib/es5-shim.js | 588 ++++++++++++++++++++++++++-------------- 1 file changed, 392 insertions(+), 196 deletions(-) diff --git a/lib/ace/lib/es5-shim.js b/lib/ace/lib/es5-shim.js index 3a3b68c5..c1664146 100644 --- a/lib/ace/lib/es5-shim.js +++ b/lib/ace/lib/es5-shim.js @@ -1,28 +1,5 @@ -// vim: ts=4 sts=4 sw=4 expandtab -// -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License -// -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project) -// -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA -// -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License -// -- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License -// -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License -// -- kossnocorp Sasha Koss XXX TODO License or CLA -// -- bryanforbes Bryan Forbes XXX TODO License or CLA -// -- killdream Quildreen Motta Copyright (C) 2011 MIT Licence -// -- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD License -// -- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License -// -- bbqsrc Brendan Molloy (C) 2011 Creative Commons Zero (public domain) -// -- iwyg XXX TODO License or CLA -// -- DomenicDenicola Domenic Denicola Copyright (C) 2011 MIT License -// -- xavierm02 Montillet Xavier XXX TODO License or CLA -// -- Raynos Raynos XXX TODO License or CLA -// -- samsonjs Sami Samhuri Copyright (C) 2010 MIT License -// -- rwldrn Rick Waldron Copyright (C) 2011 MIT License -// -- lexer Alexey Zakharov XXX TODO License or CLA - -/*! - Copyright (c) 2009, 280 North Inc. http://280north.com/ - MIT License. http://github.com/280north/narwhal/blob/master/README.md -*/ +// https://github.com/kriskowal/es5-shim +// Copyright 2009-2012 by contributors, MIT License define(function(require, exports, module) { @@ -32,12 +9,9 @@ define(function(require, exports, module) { * * Annotated ES5: http://es5.github.com/ (specific links below) * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf - * - * @module + * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ */ -/*whatsupdoc*/ - // // Function // ======== @@ -46,13 +20,16 @@ define(function(require, exports, module) { // ES-5 15.3.4.5 // http://es5.github.com/#x15.3.4.5 +function Empty() {} + if (!Function.prototype.bind) { Function.prototype.bind = function bind(that) { // .length is 1 // 1. Let Target be the this value. var target = this; // 2. If IsCallable(Target) is false, throw a TypeError exception. - if (typeof target != "function") - throw new TypeError(); // TODO message + if (typeof target != "function") { + throw new TypeError("Function.prototype.bind called on incompatible " + target); + } // 3. Let A be a new (possibly empty) internal list of all of the // argument values provided after thisArg (arg1, arg2 etc), in order. // XXX slicedArgs will stand in for "A" if used @@ -82,20 +59,17 @@ if (!Function.prototype.bind) { // 4. Let args be a new list containing the same values as the // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. - // 5. Return the result of calling the [[Construct]] internal + // 5. Return the result of calling the [[Construct]] internal // method of target providing args as the arguments. - var F = function(){}; - F.prototype = target.prototype; - var self = new F; - var result = target.apply( - self, + this, args.concat(slice.call(arguments)) ); - if (result !== null && Object(result) === result) + if (Object(result) === result) { return result; - return self; + } + return this; } else { // 15.3.4.5.1 [[Call]] @@ -109,11 +83,11 @@ if (!Function.prototype.bind) { // property. // 3. Let target be the value of F's [[TargetFunction]] internal // property. - // 4. Let args be a new list containing the same values as the - // list boundArgs in the same order followed by the same + // 4. Let args be a new list containing the same values as the + // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. - // 5. Return the result of calling the [[Call]] internal method - // of target providing boundThis as the this value and + // 5. Return the result of calling the [[Call]] internal method + // of target providing boundThis as the this value and // providing args as the arguments. // equiv: target.call(this, ...boundArgs, ...args) @@ -125,11 +99,17 @@ if (!Function.prototype.bind) { } }; + if(target.prototype) { + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + // Clean up dangling references. + Empty.prototype = null; + } // XXX bound.length is never writable, so don't even try // // 15. If the [[Class]] internal property of Target is "Function", then // a. Let L be the length property of Target minus the length of A. - // b. Set the length own property of F to either 0 or L, whichever is + // b. Set the length own property of F to either 0 or L, whichever is // larger. // 16. Else set the length own property of F to 0. // 17. Set the attributes of the length own property of F to the values @@ -137,20 +117,20 @@ if (!Function.prototype.bind) { // TODO // 18. Set the [[Extensible]] internal property of F to true. - + // TODO // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). - // 20. Call the [[DefineOwnProperty]] internal method of F with + // 20. Call the [[DefineOwnProperty]] internal method of F with // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: - // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and + // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and // false. - // 21. Call the [[DefineOwnProperty]] internal method of F with - // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, + // 21. Call the [[DefineOwnProperty]] internal method of F with + // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, // and false. // TODO - // NOTE Function objects created using Function.prototype.bind do not + // NOTE Function objects created using Function.prototype.bind do not // have a prototype property or the [[Code]], [[FormalParameters]], and // [[Scope]] internal properties. // XXX can't delete prototype in pure-js. @@ -168,7 +148,8 @@ var call = Function.prototype.call; var prototypeOfArray = Array.prototype; var prototypeOfObject = Object.prototype; var slice = prototypeOfArray.slice; -var toString = call.bind(prototypeOfObject.toString); +// Having a toString local variable name breaks in Opera so use _toString. +var _toString = call.bind(prototypeOfObject.toString); var owns = call.bind(prototypeOfObject.hasOwnProperty); // If JS engine supports accessors creating shortcuts. @@ -189,12 +170,31 @@ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { // ===== // +// ES5 15.4.4.12 +// http://es5.github.com/#x15.4.4.12 +// Default value for second param +// [bugfix, ielt9, old browsers] +// IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12" +if ([1,2].splice(0).length != 2) { + var array_splice = Array.prototype.splice; + Array.prototype.splice = function(start, deleteCount) { + if (!arguments.length) { + return []; + } else { + return array_splice.apply(this, [ + start === void 0 ? 0 : start, + deleteCount === void 0 ? (this.length - start) : deleteCount + ].concat(slice.call(arguments, 2))) + } + }; +} + // ES5 15.4.3.2 // http://es5.github.com/#x15.4.3.2 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray if (!Array.isArray) { Array.isArray = function isArray(obj) { - return toString(obj) == "[object Array]"; + return _toString(obj) == "[object Array]"; }; } @@ -213,25 +213,34 @@ if (!Array.isArray) { // ES5 15.4.4.18 // http://es5.github.com/#x15.4.4.18 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach + +// Check failure of by-index access of string characters (IE < 9) +// and failure of `0 in boxedString` (Rhino) +var boxedString = Object("a"), + splitString = boxedString[0] != "a" || !(0 in boxedString); + if (!Array.prototype.forEach) { Array.prototype.forEach = function forEach(fun /*, thisp*/) { - var self = toObject(this), + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, thisp = arguments[1], - i = 0, + i = -1, length = self.length >>> 0; // If no callback function or if callback is not a callable function - if (toString(fun) != "[object Function]") { + if (_toString(fun) != "[object Function]") { throw new TypeError(); // TODO message } - while (i < length) { + while (++i < length) { if (i in self) { // Invoke the callback function with call, passing arguments: - // context, property value, property key, thisArg object context - fun.call(thisp, self[i], i, self); + // context, property value, property key, thisArg object + // context + fun.call(thisp, self[i], i, object); } - i++; } }; } @@ -241,19 +250,22 @@ if (!Array.prototype.forEach) { // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map if (!Array.prototype.map) { Array.prototype.map = function map(fun /*, thisp*/) { - var self = toObject(this), + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, length = self.length >>> 0, result = Array(length), thisp = arguments[1]; // If no callback function or if callback is not a callable function - if (toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self) - result[i] = fun.call(thisp, self[i], i, self); + result[i] = fun.call(thisp, self[i], i, object); } return result; }; @@ -264,19 +276,27 @@ if (!Array.prototype.map) { // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter if (!Array.prototype.filter) { Array.prototype.filter = function filter(fun /*, thisp */) { - var self = toObject(this), + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, length = self.length >>> 0, result = [], + value, thisp = arguments[1]; // If no callback function or if callback is not a callable function - if (toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { - if (i in self && fun.call(thisp, self[i], i, self)) - result.push(self[i]); + if (i in self) { + value = self[i]; + if (fun.call(thisp, value, i, object)) { + result.push(value); + } + } } return result; }; @@ -287,18 +307,22 @@ if (!Array.prototype.filter) { // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every if (!Array.prototype.every) { Array.prototype.every = function every(fun /*, thisp */) { - var self = toObject(this), + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, length = self.length >>> 0, thisp = arguments[1]; // If no callback function or if callback is not a callable function - if (toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { - if (i in self && !fun.call(thisp, self[i], i, self)) + if (i in self && !fun.call(thisp, self[i], i, object)) { return false; + } } return true; }; @@ -309,18 +333,22 @@ if (!Array.prototype.every) { // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some if (!Array.prototype.some) { Array.prototype.some = function some(fun /*, thisp */) { - var self = toObject(this), + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, length = self.length >>> 0, thisp = arguments[1]; // If no callback function or if callback is not a callable function - if (toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); } for (var i = 0; i < length; i++) { - if (i in self && fun.call(thisp, self[i], i, self)) + if (i in self && fun.call(thisp, self[i], i, object)) { return true; + } } return false; }; @@ -331,17 +359,21 @@ if (!Array.prototype.some) { // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce if (!Array.prototype.reduce) { Array.prototype.reduce = function reduce(fun /*, initial*/) { - var self = toObject(this), + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, length = self.length >>> 0; // If no callback function or if callback is not a callable function - if (toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); } // no value to return if no initial value and an empty array - if (!length && arguments.length == 1) - throw new TypeError(); // TODO message + if (!length && arguments.length == 1) { + throw new TypeError("reduce of empty array with no initial value"); + } var i = 0; var result; @@ -355,14 +387,16 @@ if (!Array.prototype.reduce) { } // if array contains no values, no initial value to return - if (++i >= length) - throw new TypeError(); // TODO message + if (++i >= length) { + throw new TypeError("reduce of empty array with no initial value"); + } } while (true); } for (; i < length; i++) { - if (i in self) - result = fun.call(void 0, result, self[i], i, self); + if (i in self) { + result = fun.call(void 0, result, self[i], i, object); + } } return result; @@ -374,17 +408,21 @@ if (!Array.prototype.reduce) { // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight if (!Array.prototype.reduceRight) { Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { - var self = toObject(this), + var object = toObject(this), + self = splitString && _toString(this) == "[object String]" ? + this.split("") : + object, length = self.length >>> 0; // If no callback function or if callback is not a callable function - if (toString(fun) != "[object Function]") { - throw new TypeError(); // TODO message + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); } // no value to return if no initial value, empty array - if (!length && arguments.length == 1) - throw new TypeError(); // TODO message + if (!length && arguments.length == 1) { + throw new TypeError("reduceRight of empty array with no initial value"); + } var result, i = length - 1; if (arguments.length >= 2) { @@ -397,14 +435,16 @@ if (!Array.prototype.reduceRight) { } // if array contains no values, no initial value to return - if (--i < 0) - throw new TypeError(); // TODO message + if (--i < 0) { + throw new TypeError("reduceRight of empty array with no initial value"); + } } while (true); } do { - if (i in this) - result = fun.call(void 0, result, self[i], i, self); + if (i in this) { + result = fun.call(void 0, result, self[i], i, object); + } } while (i--); return result; @@ -414,17 +454,21 @@ if (!Array.prototype.reduceRight) { // ES5 15.4.4.14 // http://es5.github.com/#x15.4.4.14 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf -if (!Array.prototype.indexOf) { +if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { - var self = toObject(this), + var self = splitString && _toString(this) == "[object String]" ? + this.split("") : + toObject(this), length = self.length >>> 0; - if (!length) + if (!length) { return -1; + } var i = 0; - if (arguments.length > 1) + if (arguments.length > 1) { i = toInteger(arguments[1]); + } // handle negative indices i = i >= 0 ? i : Math.max(0, length + i); @@ -440,21 +484,26 @@ if (!Array.prototype.indexOf) { // ES5 15.4.4.15 // http://es5.github.com/#x15.4.4.15 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf -if (!Array.prototype.lastIndexOf) { +if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { - var self = toObject(this), + var self = splitString && _toString(this) == "[object String]" ? + this.split("") : + toObject(this), length = self.length >>> 0; - if (!length) + if (!length) { return -1; + } var i = length - 1; - if (arguments.length > 1) + if (arguments.length > 1) { i = Math.min(i, toInteger(arguments[1])); + } // handle negative indices i = i >= 0 ? i : length - Math.abs(i); for (; i >= 0; i--) { - if (i in self && sought === self[i]) + if (i in self && sought === self[i]) { return i; + } } return -1; }; @@ -803,13 +852,18 @@ if (!Object.keys) { ], dontEnumsLength = dontEnums.length; - for (var key in {"toString": null}) + for (var key in {"toString": null}) { hasDontEnumBug = false; + } Object.keys = function keys(object) { - if ((typeof object != "object" && typeof object != "function") || object === null) + if ( + (typeof object != "object" && typeof object != "function") || + object === null + ) { throw new TypeError("Object.keys called on a non-object"); + } var keys = []; for (var name in object) { @@ -826,7 +880,6 @@ if (!Object.keys) { } } } - return keys; }; @@ -839,66 +892,101 @@ if (!Object.keys) { // ES5 15.9.5.43 // http://es5.github.com/#x15.9.5.43 -// This function returns a String value represent the instance in time -// represented by this Date object. The format of the String is the Date Time -// string format defined in 15.9.1.15. All fields are present in the String. -// The time zone is always UTC, denoted by the suffix Z. If the time value of +// This function returns a String value represent the instance in time +// represented by this Date object. The format of the String is the Date Time +// string format defined in 15.9.1.15. All fields are present in the String. +// The time zone is always UTC, denoted by the suffix Z. If the time value of // this object is not a finite Number a RangeError exception is thrown. -if (!Date.prototype.toISOString || (new Date(-62198755200000).toISOString().indexOf('-000001') === -1)) { +var negativeDate = -62198755200000, + negativeYearString = "-000001"; +if ( + !Date.prototype.toISOString || + (new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1) +) { Date.prototype.toISOString = function toISOString() { - var result, length, value, year; - if (!isFinite(this)) - throw new RangeError; + var result, length, value, year, month; + if (!isFinite(this)) { + throw new RangeError("Date.prototype.toISOString called on non-finite value."); + } + + year = this.getUTCFullYear(); + + month = this.getUTCMonth(); + // see https://github.com/kriskowal/es5-shim/issues/111 + year += Math.floor(month / 12); + month = (month % 12 + 12) % 12; // the date time string format is specified in 15.9.1.15. - result = [this.getUTCMonth() + 1, this.getUTCDate(), + result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; - year = this.getUTCFullYear(); - year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6); + year = ( + (year < 0 ? "-" : (year > 9999 ? "+" : "")) + + ("00000" + Math.abs(year)) + .slice(0 <= year && year <= 9999 ? -4 : -6) + ); length = result.length; while (length--) { value = result[length]; - // pad months, days, hours, minutes, and seconds to have two digits. - if (value < 10) + // pad months, days, hours, minutes, and seconds to have two + // digits. + if (value < 10) { result[length] = "0" + value; + } } // pad milliseconds to have three digits. - return year + "-" + result.slice(0, 2).join("-") + "T" + result.slice(2).join(":") + "." + - ("000" + this.getUTCMilliseconds()).slice(-3) + "Z"; - } -} - -// ES5 15.9.4.4 -// http://es5.github.com/#x15.9.4.4 -if (!Date.now) { - Date.now = function now() { - return new Date().getTime(); + return ( + year + "-" + result.slice(0, 2).join("-") + + "T" + result.slice(2).join(":") + "." + + ("000" + this.getUTCMilliseconds()).slice(-3) + "Z" + ); }; } + // ES5 15.9.5.44 // http://es5.github.com/#x15.9.5.44 -// This function provides a String representation of a Date object for use by +// This function provides a String representation of a Date object for use by // JSON.stringify (15.12.3). -if (!Date.prototype.toJSON) { +var dateToJSONIsSupported = false; +try { + dateToJSONIsSupported = ( + Date.prototype.toJSON && + new Date(NaN).toJSON() === null && + new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && + Date.prototype.toJSON.call({ // generic + toISOString: function () { + return true; + } + }) + ); +} catch (e) { +} +if (!dateToJSONIsSupported) { Date.prototype.toJSON = function toJSON(key) { - // When the toJSON method is called with argument key, the following + // When the toJSON method is called with argument key, the following // steps are taken: // 1. Let O be the result of calling ToObject, giving it the this // value as its argument. - // 2. Let tv be ToPrimitive(O, hint Number). + // 2. Let tv be toPrimitive(O, hint Number). + var o = Object(this), + tv = toPrimitive(o), + toISO; // 3. If tv is a Number and is not finite, return null. - // XXX + if (typeof tv === "number" && !isFinite(tv)) { + return null; + } // 4. Let toISO be the result of calling the [[Get]] internal method of // O with argument "toISOString". + toISO = o.toISOString; // 5. If IsCallable(toISO) is false, throw a TypeError exception. - if (typeof this.toISOString != "function") - throw new TypeError(); // TODO message + if (typeof toISO != "function") { + throw new TypeError("toISOString property is not callable"); + } // 6. Return the result of calling the [[Call]] internal method of // toISO with O as the this value and an empty argument list. - return this.toISOString(); + return toISO.call(o); // NOTE 1 The argument is ignored. @@ -915,13 +1003,13 @@ if (!Date.prototype.toJSON) { // http://es5.github.com/#x15.9.4.2 // based on work shared by Daniel Friesen (dantman) // http://gist.github.com/303249 -if (Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) { +if (!Date.parse || "Date.parse is buggy") { // XXX global assignment won't work in embeddings that use // an alternate object for the context. Date = (function(NativeDate) { // Date.length === 7 - var Date = function Date(Y, M, D, h, m, s, ms) { + function Date(Y, M, D, h, m, s, ms) { var length = arguments.length; if (this instanceof NativeDate) { var date = length == 1 && String(Y) === Y ? // isString(Y) @@ -946,7 +1034,8 @@ if (Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) { // 15.9.1.15 Date Time String Format. var isoDateExpression = new RegExp("^" + - "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + 6-digit extended year + "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + + // 6-digit extended year "(?:-(\\d{2})" + // optional month capture "(?:-(\\d{2})" + // optional day capture "(?:" + // capture hours:minutes:seconds.milliseconds @@ -956,7 +1045,7 @@ if (Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) { ":(\\d{2})" + // seconds capture "(?:\\.(\\d{3}))?" + // milliseconds capture ")?" + - "(?:" + // capture UTC offset component + "(" + // capture UTC offset component "Z|" + // UTC capture "(?:" + // offset specifier +/-hours:minutes "([-+])" + // sign capture @@ -966,9 +1055,25 @@ if (Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) { ")?)?)?)?" + "$"); + var months = [ + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 + ]; + + function dayFromMonth(year, month) { + var t = month > 1 ? 1 : 0; + return ( + months[month] + + Math.floor((year - 1969 + t) / 4) - + Math.floor((year - 1901 + t) / 100) + + Math.floor((year - 1601 + t) / 400) + + 365 * (year - 1970) + ); + } + // Copy any custom methods a 3rd party library may have added - for (var key in NativeDate) + for (var key in NativeDate) { Date[key] = NativeDate[key]; + } // Copy "native" methods explicitly; they may be non-enumerable Date.now = NativeDate.now; @@ -980,45 +1085,53 @@ if (Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) { Date.parse = function parse(string) { var match = isoDateExpression.exec(string); if (match) { - match.shift(); // kill match[0], the full match // parse months, days, hours, minutes, seconds, and milliseconds - for (var i = 1; i < 7; i++) { - // provide default values if necessary - match[i] = +(match[i] || (i < 3 ? 1 : 0)); - // match[1] is the month. Months are 0-11 in JavaScript - // `Date` objects, but 1-12 in ISO notation, so we - // decrement. - if (i == 1) - match[i]--; - } - + // provide default values if necessary // parse the UTC offset component - var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop(); - - // compute the explicit time zone offset if specified - var offset = 0; - if (sign) { - // detect invalid offsets and return early - if (hourOffset > 23 || minuteOffset > 59) - return NaN; - - // express the provided time zone offset in minutes. The offset is - // negative for time zones west of UTC; positive otherwise. - offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1); + var year = Number(match[1]), + month = Number(match[2] || 1) - 1, + day = Number(match[3] || 1) - 1, + hour = Number(match[4] || 0), + minute = Number(match[5] || 0), + second = Number(match[6] || 0), + millisecond = Number(match[7] || 0), + // When time zone is missed, local offset should be used + // (ES 5.1 bug) + // see https://bugs.ecmascript.org/show_bug.cgi?id=112 + offset = !match[4] || match[8] ? + 0 : Number(new NativeDate(1970, 0)), + signOffset = match[9] === "-" ? 1 : -1, + hourOffset = Number(match[10] || 0), + minuteOffset = Number(match[11] || 0), + result; + if ( + hour < ( + minute > 0 || second > 0 || millisecond > 0 ? + 24 : 25 + ) && + minute < 60 && second < 60 && millisecond < 1000 && + month > -1 && month < 12 && hourOffset < 24 && + minuteOffset < 60 && // detect invalid offsets + day > -1 && + day < ( + dayFromMonth(year, month + 1) - + dayFromMonth(year, month) + ) + ) { + result = ( + (dayFromMonth(year, month) + day) * 24 + + hour + + hourOffset * signOffset + ) * 60; + result = ( + (result + minute + minuteOffset * signOffset) * 60 + + second + ) * 1000 + millisecond + offset; + if (-8.64e15 <= result && result <= 8.64e15) { + return result; + } } - - // Date.UTC for years between 0 and 99 converts year to 1900 + year - // The Gregorian calendar has a 400-year cycle, so - // to Date.UTC(year + 400, .... ) - 12622780800000 == Date.UTC(year, ...), - // where 12622780800000 - number of milliseconds in Gregorian calendar 400 years - var year = +match[0]; - if (0 <= year && year <= 99) { - match[0] = year + 400; - return NativeDate.UTC.apply(this, match) + offset - 12622780800000; - } - - // compute a new UTC date value, accounting for the optional offset - return NativeDate.UTC.apply(this, match) + offset; + return NaN; } return NativeDate.parse.apply(this, arguments); }; @@ -1027,11 +1140,59 @@ if (Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) { })(Date); } +// ES5 15.9.4.4 +// http://es5.github.com/#x15.9.4.4 +if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; +} + + // // String // ====== // + +// ES5 15.5.4.14 +// http://es5.github.com/#x15.5.4.14 +// [bugfix, chrome] +// If separator is undefined, then the result array contains just one String, +// which is the this value (converted to a String). If limit is not undefined, +// then the output array is truncated so that it contains no more than limit +// elements. +// "0".split(undefined, 0) -> [] +if("0".split(void 0, 0).length) { + var string_split = String.prototype.split; + String.prototype.split = function(separator, limit) { + if(separator === void 0 && limit === 0)return []; + return string_split.apply(this, arguments); + } +} + +// ECMA-262, 3rd B.2.3 +// Note an ECMAScript standart, although ECMAScript 3rd Edition has a +// non-normative section suggesting uniform semantics and it should be +// normalized across all browsers +// [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE +if("".substr && "0b".substr(-1) !== "b") { + var string_substr = String.prototype.substr; + /** + * Get the substring of a string + * @param {integer} start where to start the substring + * @param {integer} length how many characters to return + * @return {string} + */ + String.prototype.substr = function(start, length) { + return string_substr.call( + this, + start < 0 ? (start = this.length + start) < 0 ? 0 : start : start, + length + ); + } +} + // ES5 15.5.4.20 // http://es5.github.com/#x15.5.4.20 var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + @@ -1044,7 +1205,12 @@ if (!String.prototype.trim || ws.trim()) { var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), trimEndRegexp = new RegExp(ws + ws + "*$"); String.prototype.trim = function trim() { - return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); + if (this === undefined || this === null) { + throw new TypeError("can't convert "+this+" to object"); + } + return String(this) + .replace(trimBeginRegexp, "") + .replace(trimEndRegexp, ""); }; } @@ -1056,27 +1222,57 @@ if (!String.prototype.trim || ws.trim()) { // ES5 9.4 // http://es5.github.com/#x9.4 // http://jsperf.com/to-integer -var toInteger = function (n) { + +function toInteger(n) { n = +n; - if (n !== n) // isNaN + if (n !== n) { // isNaN n = 0; - else if (n !== 0 && n !== (1/0) && n !== -(1/0)) + } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } return n; +} + +function isPrimitive(input) { + var type = typeof input; + return ( + input === null || + type === "undefined" || + type === "boolean" || + type === "number" || + type === "string" + ); +} + +function toPrimitive(input) { + var val, valueOf, toString; + if (isPrimitive(input)) { + return input; + } + valueOf = input.valueOf; + if (typeof valueOf === "function") { + val = valueOf.call(input); + if (isPrimitive(val)) { + return val; + } + } + toString = input.toString; + if (typeof toString === "function") { + val = toString.call(input); + if (isPrimitive(val)) { + return val; + } + } + throw new TypeError(); +} + +// ES5 9.9 +// http://es5.github.com/#x9.9 +var toObject = function (o) { + if (o == null) { // this matches both null and undefined + throw new TypeError("can't convert "+o+" to object"); + } + return Object(o); }; -var prepareString = "a"[0] != "a", - // ES5 9.9 - // http://es5.github.com/#x9.9 - toObject = function (o) { - if (o == null) { // this matches both null and undefined - throw new TypeError(); // TODO message - } - // If the implementation doesn't support by-index access of - // string characters (ex. IE < 7), split the string - if (prepareString && typeof o == "string" && o) { - return o.split(""); - } - return Object(o); - }; });