2014-05-12 20:08:19 +02:00
/ * !
* https : //github.com/es-shims/es5-shim
2016-05-16 13:33:49 +02:00
* @ license es5 - shim Copyright 2009 - 2015 by contributors , MIT License
2014-05-12 20:08:19 +02:00
* see https : //github.com/es-shims/es5-shim/blob/master/LICENSE
* /
// vim: ts=4 sts=4 sw=4 expandtab
2016-05-16 13:33:49 +02:00
// Add semicolon to prevent IIFE from being passed as argument to concatenated code.
2014-05-12 20:08:19 +02:00
;
// UMD (Universal Module Definition)
2016-05-16 13:33:49 +02:00
// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
2014-05-12 20:08:19 +02:00
( function ( root , factory ) {
2016-05-16 13:33:49 +02:00
'use strict' ;
/* global define, exports, module */
2014-05-12 20:08:19 +02:00
if ( typeof define === 'function' && define . amd ) {
// AMD. Register as an anonymous module.
define ( factory ) ;
} else if ( typeof exports === 'object' ) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like enviroments that support module.exports,
// like Node.
module . exports = factory ( ) ;
} else {
// Browser globals (root is window)
root . returnExports = factory ( ) ;
2014-06-06 14:29:32 +02:00
}
2014-05-12 20:08:19 +02:00
} ( this , function ( ) {
/ * *
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines .
*
* Annotated ES5 : http : //es5.github.com/ (specific links below)
* ES5 Spec : http : //www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
* Required reading : http : //javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
* /
// Shortcut to an often accessed properties, in order to avoid multiple
2016-05-16 13:33:49 +02:00
// dereference that costs universally. This also holds a reference to known-good
// functions.
var $Array = Array ;
var ArrayPrototype = $Array . prototype ;
var $Object = Object ;
var ObjectPrototype = $Object . prototype ;
var $Function = Function ;
var FunctionPrototype = $Function . prototype ;
var $String = String ;
var StringPrototype = $String . prototype ;
var $Number = Number ;
var NumberPrototype = $Number . prototype ;
var array _slice = ArrayPrototype . slice ;
2014-08-10 12:02:48 +02:00
var array _splice = ArrayPrototype . splice ;
var array _push = ArrayPrototype . push ;
var array _unshift = ArrayPrototype . unshift ;
2016-05-16 13:33:49 +02:00
var array _concat = ArrayPrototype . concat ;
var array _join = ArrayPrototype . join ;
2014-08-10 12:02:48 +02:00
var call = FunctionPrototype . call ;
2016-05-16 13:33:49 +02:00
var apply = FunctionPrototype . apply ;
var max = Math . max ;
var min = Math . min ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
// Having a toString local variable name breaks in Opera so use to_string.
var to _string = ObjectPrototype . toString ;
2014-06-06 14:29:32 +02:00
2016-05-16 13:33:49 +02:00
/* global Symbol */
/* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
var hasToStringTag = typeof Symbol === 'function' && typeof Symbol . toStringTag === 'symbol' ;
var isCallable ; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function . prototype . toString , constructorRegex = /^\s*class / , isES6ClassFn = function isES6ClassFn ( value ) { try { var fnStr = fnToStr . call ( value ) ; var singleStripped = fnStr . replace ( /\/\/.*\n/g , '' ) ; var multiStripped = singleStripped . replace ( /\/\*[.\s\S]*\*\//g , '' ) ; var spaceStripped = multiStripped . replace ( /\n/mg , ' ' ) . replace ( / {2}/g , ' ' ) ; return constructorRegex . test ( spaceStripped ) ; } catch ( e ) { return false ; /* not a function */ } } , tryFunctionObject = function tryFunctionObject ( value ) { try { if ( isES6ClassFn ( v alue ) ) { return false ; } fnToStr . call ( value ) ; return true ; } catch ( e ) { return false ; } } , fnClass = '[object Function]' , genClass = '[object GeneratorFunction]' , isCallable = function isCallable ( value ) { if ( ! value ) { return false ; } if ( typeof value !== 'function' && typeof value !== 'object' ) { return false ; } if ( hasToStringTag ) { return tryFunctionObject ( value ) ; } if ( isES6ClassFn ( value ) ) { return false ; } var strClass = to _string . call ( value ) ; return strClass === fnClass || strClass === genClass ; } ;
var isRegex ; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp . prototype . exec , tryRegexExec = function tryRegexExec ( value ) { try { regexExec . call ( value ) ; return true ; } catch ( e ) { return false ; } } , regexClass = '[object RegExp]' ; isRegex = function isRegex ( value ) { if ( typeof value !== 'object' ) { return false ; } return hasToStringTag ? tryRegexExec ( value ) : to _string . call ( value ) === regexClass ; } ;
var isString ; /* inlined from https://npmjs.com/is-string */ var strValue = String . prototype . valueOf , tryStringObject = function tryStringObject ( value ) { try { strValue . call ( value ) ; return true ; } catch ( e ) { return false ; } } , stringClass = '[object String]' ; isString = function isString ( value ) { if ( typeof value === 'string' ) { return true ; } if ( typeof value !== 'object' ) { return false ; } return hasToStringTag ? tryStringObject ( value ) : to _string . call ( value ) === stringClass ; } ;
/* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
/* inlined from http://npmjs.com/define-properties */
var supportsDescriptors = $Object . defineProperty && ( function ( ) {
2014-08-10 12:02:48 +02:00
try {
2016-05-16 13:33:49 +02:00
var obj = { } ;
$Object . defineProperty ( obj , 'x' , { enumerable : false , value : obj } ) ;
for ( var _ in obj ) { return false ; }
return obj . x === obj ;
2014-08-10 12:02:48 +02:00
} catch ( e ) { /* this is ES3 */
return false ;
}
} ( ) ) ;
2016-05-16 13:33:49 +02:00
var defineProperties = ( function ( has ) {
// Define configurable, writable, and non-enumerable props
// if they don't exist.
var defineProperty ;
if ( supportsDescriptors ) {
defineProperty = function ( object , name , method , forceAssign ) {
if ( ! forceAssign && ( name in object ) ) { return ; }
$Object . defineProperty ( object , name , {
configurable : true ,
enumerable : false ,
writable : true ,
value : method
} ) ;
} ;
} else {
defineProperty = function ( object , name , method , forceAssign ) {
if ( ! forceAssign && ( name in object ) ) { return ; }
object [ name ] = method ;
} ;
}
return function defineProperties ( object , map , forceAssign ) {
for ( var name in map ) {
if ( has . call ( map , name ) ) {
defineProperty ( object , name , map [ name ] , forceAssign ) ;
}
}
} ;
} ( ObjectPrototype . hasOwnProperty ) ) ;
2014-08-10 12:02:48 +02:00
//
// Util
// ======
//
2016-05-16 13:33:49 +02:00
/* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
var isPrimitive = function isPrimitive ( input ) {
2014-08-10 12:02:48 +02:00
var type = typeof input ;
2016-05-16 13:33:49 +02:00
return input === null || ( type !== 'object' && type !== 'function' ) ;
} ;
2014-08-10 12:02:48 +02:00
2016-05-16 13:33:49 +02:00
var isActualNaN = $Number . isNaN || function ( x ) { return x !== x ; } ;
var ES = {
// ES5 9.4
// http://es5.github.com/#x9.4
// http://jsperf.com/to-integer
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
ToInteger : function ToInteger ( num ) {
var n = + num ;
if ( isActualNaN ( n ) ) {
n = 0 ;
} else if ( n !== 0 && n !== ( 1 / 0 ) && n !== - ( 1 / 0 ) ) {
n = ( n > 0 || - 1 ) * Math . floor ( Math . abs ( n ) ) ;
2014-08-10 12:02:48 +02:00
}
2016-05-16 13:33:49 +02:00
return n ;
} ,
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
ToPrimitive : function ToPrimitive ( input ) {
var val , valueOf , toStr ;
if ( isPrimitive ( input ) ) {
return input ;
2014-08-10 12:02:48 +02:00
}
2016-05-16 13:33:49 +02:00
valueOf = input . valueOf ;
if ( isCallable ( valueOf ) ) {
val = valueOf . call ( input ) ;
if ( isPrimitive ( val ) ) {
return val ;
}
}
toStr = input . toString ;
if ( isCallable ( toStr ) ) {
val = toStr . call ( input ) ;
if ( isPrimitive ( val ) ) {
return val ;
}
}
throw new TypeError ( ) ;
} ,
// ES5 9.9
// http://es5.github.com/#x9.9
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
ToObject : function ( o ) {
if ( o == null ) { // this matches both null and undefined
throw new TypeError ( "can't convert " + o + ' to object' ) ;
}
return $Object ( o ) ;
} ,
2014-08-10 12:02:48 +02:00
2016-05-16 13:33:49 +02:00
/* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
ToUint32 : function ToUint32 ( x ) {
return x >>> 0 ;
2014-08-10 12:02:48 +02:00
}
} ;
2014-05-12 20:08:19 +02:00
//
// Function
// ========
//
// ES-5 15.3.4.5
// http://es5.github.com/#x15.3.4.5
2016-05-16 13:33:49 +02:00
var Empty = function Empty ( ) { } ;
2014-05-12 20:08:19 +02:00
2014-08-10 12:02:48 +02:00
defineProperties ( FunctionPrototype , {
bind : function bind ( that ) { // .length is 1
2014-05-12 20:08:19 +02:00
// 1. Let Target be the this value.
var target = this ;
// 2. If IsCallable(Target) is false, throw a TypeError exception.
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( target ) ) {
throw new TypeError ( 'Function.prototype.bind called on incompatible ' + target ) ;
2014-05-12 20:08:19 +02:00
}
// 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
2016-05-16 13:33:49 +02:00
var args = array _slice . call ( arguments , 1 ) ; // for normal call
2014-05-12 20:08:19 +02:00
// 4. Let F be a new native ECMAScript object.
// 11. Set the [[Prototype]] internal property of F to the standard
// built-in Function prototype object as specified in 15.3.3.1.
// 12. Set the [[Call]] internal property of F as described in
// 15.3.4.5.1.
// 13. Set the [[Construct]] internal property of F as described in
// 15.3.4.5.2.
// 14. Set the [[HasInstance]] internal property of F as described in
// 15.3.4.5.3.
2016-05-16 13:33:49 +02:00
var bound ;
2014-05-12 20:08:19 +02:00
var binder = function ( ) {
if ( this instanceof bound ) {
// 15.3.4.5.2 [[Construct]]
// When the [[Construct]] internal method of a function object,
// F that was created using the bind function is called with a
// list of arguments ExtraArgs, the following steps are taken:
// 1. Let target be the value of F's [[TargetFunction]]
// internal property.
// 2. If target has no [[Construct]] internal method, a
// TypeError exception is thrown.
// 3. Let boundArgs be the value of F's [[BoundArgs]] 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
// values as the list ExtraArgs in the same order.
// 5. Return the result of calling the [[Construct]] internal
// method of target providing args as the arguments.
2016-05-16 13:33:49 +02:00
var result = apply . call (
target ,
2014-05-12 20:08:19 +02:00
this ,
2016-05-16 13:33:49 +02:00
array _concat . call ( args , array _slice . call ( arguments ) )
2014-05-12 20:08:19 +02:00
) ;
2016-05-16 13:33:49 +02:00
if ( $Object ( result ) === result ) {
2014-05-12 20:08:19 +02:00
return result ;
}
return this ;
} else {
// 15.3.4.5.1 [[Call]]
// When the [[Call]] internal method of a function object, F,
// which was created using the bind function is called with a
// this value and a list of arguments ExtraArgs, the following
// steps are taken:
// 1. Let boundArgs be the value of F's [[BoundArgs]] internal
// property.
// 2. Let boundThis be the value of F's [[BoundThis]] internal
// 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
// 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
// providing args as the arguments.
// equiv: target.call(this, ...boundArgs, ...args)
2016-05-16 13:33:49 +02:00
return apply . call (
target ,
2014-05-12 20:08:19 +02:00
that ,
2016-05-16 13:33:49 +02:00
array _concat . call ( args , array _slice . call ( arguments ) )
2014-05-12 20:08:19 +02:00
) ;
}
} ;
// 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
// larger.
// 16. Else set the length own property of F to 0.
2016-05-16 13:33:49 +02:00
var boundLength = max ( 0 , target . length - args . length ) ;
2014-05-12 20:08:19 +02:00
// 17. Set the attributes of the length own property of F to the values
// specified in 15.3.5.1.
var boundArgs = [ ] ;
for ( var i = 0 ; i < boundLength ; i ++ ) {
2016-05-16 13:33:49 +02:00
array _push . call ( boundArgs , '$' + i ) ;
2014-05-12 20:08:19 +02:00
}
// XXX Build a dynamic function with desired amount of arguments is the only
// way to set the length property of a function.
// In environments where Content Security Policies enabled (Chrome extensions,
// for ex.) all use of eval or Function costructor throws an exception.
// However in all of these environments Function.prototype.bind exists
// and so this code will never be executed.
2016-05-16 13:33:49 +02:00
bound = $Function ( 'binder' , 'return function (' + array _join . call ( boundArgs , ',' ) + '){ return binder.apply(this, arguments); }' ) ( binder ) ;
2014-05-12 20:08:19 +02:00
if ( target . prototype ) {
Empty . prototype = target . prototype ;
bound . prototype = new Empty ( ) ;
// Clean up dangling references.
Empty . prototype = null ;
}
// 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
// arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
// thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
// false.
// 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
// have a prototype property or the [[Code]], [[FormalParameters]], and
// [[Scope]] internal properties.
// XXX can't delete prototype in pure-js.
// 22. Return F.
return bound ;
2014-08-10 12:02:48 +02:00
}
} ) ;
2014-05-12 20:08:19 +02:00
// _Please note: Shortcuts are defined after `Function.prototype.bind` as we
2016-05-16 13:33:49 +02:00
// use it in defining shortcuts.
2014-08-10 12:02:48 +02:00
var owns = call . bind ( ObjectPrototype . hasOwnProperty ) ;
2016-05-16 13:33:49 +02:00
var toStr = call . bind ( ObjectPrototype . toString ) ;
var arraySlice = call . bind ( array _slice ) ;
var arraySliceApply = apply . bind ( array _slice ) ;
var strSlice = call . bind ( StringPrototype . slice ) ;
var strSplit = call . bind ( StringPrototype . split ) ;
var strIndexOf = call . bind ( StringPrototype . indexOf ) ;
var pushCall = call . bind ( array _push ) ;
var isEnum = call . bind ( ObjectPrototype . propertyIsEnumerable ) ;
var arraySort = call . bind ( ArrayPrototype . sort ) ;
2014-05-12 20:08:19 +02:00
//
// Array
// =====
//
2016-05-16 13:33:49 +02:00
var isArray = $Array . isArray || function isArray ( obj ) {
return toStr ( obj ) === '[object Array]' ;
} ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.12
// http://es5.github.com/#x15.4.4.13
// Return len+argCount.
// [bugfix, ielt8]
// IE < 8 bug: [].unshift(0) === undefined but should be "1"
2014-08-10 12:02:48 +02:00
var hasUnshiftReturnValueBug = [ ] . unshift ( 0 ) !== 1 ;
defineProperties ( ArrayPrototype , {
unshift : function ( ) {
2014-05-12 20:08:19 +02:00
array _unshift . apply ( this , arguments ) ;
return this . length ;
2014-08-10 12:02:48 +02:00
}
} , hasUnshiftReturnValueBug ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.3.2
// http://es5.github.com/#x15.4.3.2
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
2016-05-16 13:33:49 +02:00
defineProperties ( $Array , { isArray : isArray } ) ;
2014-05-12 20:08:19 +02:00
// The IsCallable() check in the Array functions
// has been replaced with a strict check on the
// internal class of the object to trap cases where
// the provided function was actually a regular
// expression literal, which in V8 and
// JavaScriptCore is a typeof "function". Only in
// V8 are regular expression literals permitted as
// reduce parameters, so it is desirable in the
// general case for the shim to match the more
// strict and common behavior of rejecting regular
// expressions.
// 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)
2016-05-16 13:33:49 +02:00
var boxedString = $Object ( 'a' ) ;
var splitString = boxedString [ 0 ] !== 'a' || ! ( 0 in boxedString ) ;
2014-05-12 20:08:19 +02:00
var properlyBoxesContext = function properlyBoxed ( method ) {
// Check node 0.6.21 bug where third parameter is not boxed
2014-06-06 14:29:32 +02:00
var properlyBoxesNonStrict = true ;
var properlyBoxesStrict = true ;
2016-05-16 13:33:49 +02:00
var threwException = false ;
2014-05-12 20:08:19 +02:00
if ( method ) {
2016-05-16 13:33:49 +02:00
try {
method . call ( 'foo' , function ( _ , _ _ , context ) {
if ( typeof context !== 'object' ) {
properlyBoxesNonStrict = false ;
}
} ) ;
2014-06-06 14:29:32 +02:00
2016-05-16 13:33:49 +02:00
method . call ( [ 1 ] , function ( ) {
'use strict' ;
properlyBoxesStrict = typeof this === 'string' ;
} , 'x' ) ;
} catch ( e ) {
threwException = true ;
}
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
return ! ! method && ! threwException && properlyBoxesNonStrict && properlyBoxesStrict ;
2014-05-12 20:08:19 +02:00
} ;
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
forEach : function forEach ( callbackfn /*, thisArg*/ ) {
var object = ES . ToObject ( this ) ;
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : object ;
var i = - 1 ;
var length = ES . ToUint32 ( self . length ) ;
var T ;
if ( arguments . length > 1 ) {
T = arguments [ 1 ] ;
}
2014-05-12 20:08:19 +02:00
// If no callback function or if callback is not a callable function
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( callbackfn ) ) {
throw new TypeError ( 'Array.prototype.forEach callback must be a function' ) ;
2014-05-12 20:08:19 +02:00
}
while ( ++ i < length ) {
if ( i in self ) {
// Invoke the callback function with call, passing arguments:
// context, property value, property key, thisArg object
2016-05-16 13:33:49 +02:00
if ( typeof T === 'undefined' ) {
callbackfn ( self [ i ] , i , object ) ;
} else {
callbackfn . call ( T , self [ i ] , i , object ) ;
}
2014-05-12 20:08:19 +02:00
}
}
2014-08-10 12:02:48 +02:00
}
} , ! properlyBoxesContext ( ArrayPrototype . forEach ) ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.19
// http://es5.github.com/#x15.4.4.19
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
map : function map ( callbackfn /*, thisArg*/ ) {
var object = ES . ToObject ( this ) ;
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : object ;
var length = ES . ToUint32 ( self . length ) ;
var result = $Array ( length ) ;
var T ;
if ( arguments . length > 1 ) {
T = arguments [ 1 ] ;
}
2014-05-12 20:08:19 +02:00
// If no callback function or if callback is not a callable function
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( callbackfn ) ) {
throw new TypeError ( 'Array.prototype.map callback must be a function' ) ;
2014-05-12 20:08:19 +02:00
}
for ( var i = 0 ; i < length ; i ++ ) {
2014-06-06 14:29:32 +02:00
if ( i in self ) {
2016-05-16 13:33:49 +02:00
if ( typeof T === 'undefined' ) {
result [ i ] = callbackfn ( self [ i ] , i , object ) ;
} else {
result [ i ] = callbackfn . call ( T , self [ i ] , i , object ) ;
}
2014-06-06 14:29:32 +02:00
}
2014-05-12 20:08:19 +02:00
}
return result ;
2014-08-10 12:02:48 +02:00
}
} , ! properlyBoxesContext ( ArrayPrototype . map ) ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.20
// http://es5.github.com/#x15.4.4.20
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
filter : function filter ( callbackfn /*, thisArg*/ ) {
var object = ES . ToObject ( this ) ;
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : object ;
var length = ES . ToUint32 ( self . length ) ;
var result = [ ] ;
var value ;
var T ;
if ( arguments . length > 1 ) {
T = arguments [ 1 ] ;
}
2014-05-12 20:08:19 +02:00
// If no callback function or if callback is not a callable function
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( callbackfn ) ) {
throw new TypeError ( 'Array.prototype.filter callback must be a function' ) ;
2014-05-12 20:08:19 +02:00
}
for ( var i = 0 ; i < length ; i ++ ) {
if ( i in self ) {
value = self [ i ] ;
2016-05-16 13:33:49 +02:00
if ( typeof T === 'undefined' ? callbackfn ( value , i , object ) : callbackfn . call ( T , value , i , object ) ) {
pushCall ( result , value ) ;
2014-05-12 20:08:19 +02:00
}
}
}
return result ;
2014-08-10 12:02:48 +02:00
}
} , ! properlyBoxesContext ( ArrayPrototype . filter ) ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.16
// http://es5.github.com/#x15.4.4.16
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
every : function every ( callbackfn /*, thisArg*/ ) {
var object = ES . ToObject ( this ) ;
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : object ;
var length = ES . ToUint32 ( self . length ) ;
var T ;
if ( arguments . length > 1 ) {
T = arguments [ 1 ] ;
}
2014-05-12 20:08:19 +02:00
// If no callback function or if callback is not a callable function
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( callbackfn ) ) {
throw new TypeError ( 'Array.prototype.every callback must be a function' ) ;
2014-05-12 20:08:19 +02:00
}
for ( var i = 0 ; i < length ; i ++ ) {
2016-05-16 13:33:49 +02:00
if ( i in self && ! ( typeof T === 'undefined' ? callbackfn ( self [ i ] , i , object ) : callbackfn . call ( T , self [ i ] , i , object ) ) ) {
2014-05-12 20:08:19 +02:00
return false ;
}
}
return true ;
2014-08-10 12:02:48 +02:00
}
} , ! properlyBoxesContext ( ArrayPrototype . every ) ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.17
// http://es5.github.com/#x15.4.4.17
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
some : function some ( callbackfn /*, thisArg */ ) {
var object = ES . ToObject ( this ) ;
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : object ;
var length = ES . ToUint32 ( self . length ) ;
var T ;
if ( arguments . length > 1 ) {
T = arguments [ 1 ] ;
}
2014-05-12 20:08:19 +02:00
// If no callback function or if callback is not a callable function
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( callbackfn ) ) {
throw new TypeError ( 'Array.prototype.some callback must be a function' ) ;
2014-05-12 20:08:19 +02:00
}
for ( var i = 0 ; i < length ; i ++ ) {
2016-05-16 13:33:49 +02:00
if ( i in self && ( typeof T === 'undefined' ? callbackfn ( self [ i ] , i , object ) : callbackfn . call ( T , self [ i ] , i , object ) ) ) {
2014-05-12 20:08:19 +02:00
return true ;
}
}
return false ;
2014-08-10 12:02:48 +02:00
}
} , ! properlyBoxesContext ( ArrayPrototype . some ) ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.21
// http://es5.github.com/#x15.4.4.21
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
var reduceCoercesToObject = false ;
2014-08-10 12:02:48 +02:00
if ( ArrayPrototype . reduce ) {
2016-05-16 13:33:49 +02:00
reduceCoercesToObject = typeof ArrayPrototype . reduce . call ( 'es5' , function ( _ , _ _ , _ _ _ , list ) {
return list ;
} ) === 'object' ;
2014-05-12 20:08:19 +02:00
}
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
reduce : function reduce ( callbackfn /*, initialValue*/ ) {
var object = ES . ToObject ( this ) ;
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : object ;
var length = ES . ToUint32 ( self . length ) ;
2014-05-12 20:08:19 +02:00
// If no callback function or if callback is not a callable function
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( callbackfn ) ) {
throw new TypeError ( 'Array.prototype.reduce callback must be a function' ) ;
2014-05-12 20:08:19 +02:00
}
// no value to return if no initial value and an empty array
2016-05-16 13:33:49 +02:00
if ( length === 0 && arguments . length === 1 ) {
throw new TypeError ( 'reduce of empty array with no initial value' ) ;
2014-05-12 20:08:19 +02:00
}
var i = 0 ;
var result ;
if ( arguments . length >= 2 ) {
result = arguments [ 1 ] ;
} else {
do {
if ( i in self ) {
result = self [ i ++ ] ;
break ;
}
// if array contains no values, no initial value to return
if ( ++ i >= length ) {
2016-05-16 13:33:49 +02:00
throw new TypeError ( 'reduce of empty array with no initial value' ) ;
2014-05-12 20:08:19 +02:00
}
} while ( true ) ;
}
for ( ; i < length ; i ++ ) {
if ( i in self ) {
2016-05-16 13:33:49 +02:00
result = callbackfn ( result , self [ i ] , i , object ) ;
2014-05-12 20:08:19 +02:00
}
}
return result ;
2014-08-10 12:02:48 +02:00
}
} , ! reduceCoercesToObject ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.22
// http://es5.github.com/#x15.4.4.22
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
2014-06-06 14:29:32 +02:00
var reduceRightCoercesToObject = false ;
2014-08-10 12:02:48 +02:00
if ( ArrayPrototype . reduceRight ) {
2016-05-16 13:33:49 +02:00
reduceRightCoercesToObject = typeof ArrayPrototype . reduceRight . call ( 'es5' , function ( _ , _ _ , _ _ _ , list ) {
return list ;
} ) === 'object' ;
2014-06-06 14:29:32 +02:00
}
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
reduceRight : function reduceRight ( callbackfn /*, initial*/ ) {
var object = ES . ToObject ( this ) ;
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : object ;
var length = ES . ToUint32 ( self . length ) ;
2014-05-12 20:08:19 +02:00
// If no callback function or if callback is not a callable function
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( callbackfn ) ) {
throw new TypeError ( 'Array.prototype.reduceRight callback must be a function' ) ;
2014-05-12 20:08:19 +02:00
}
// no value to return if no initial value, empty array
2016-05-16 13:33:49 +02:00
if ( length === 0 && arguments . length === 1 ) {
throw new TypeError ( 'reduceRight of empty array with no initial value' ) ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
var result ;
var i = length - 1 ;
2014-05-12 20:08:19 +02:00
if ( arguments . length >= 2 ) {
result = arguments [ 1 ] ;
} else {
do {
if ( i in self ) {
result = self [ i -- ] ;
break ;
}
// if array contains no values, no initial value to return
if ( -- i < 0 ) {
2016-05-16 13:33:49 +02:00
throw new TypeError ( 'reduceRight of empty array with no initial value' ) ;
2014-05-12 20:08:19 +02:00
}
} while ( true ) ;
}
if ( i < 0 ) {
return result ;
}
do {
2014-06-06 14:29:32 +02:00
if ( i in self ) {
2016-05-16 13:33:49 +02:00
result = callbackfn ( result , self [ i ] , i , object ) ;
2014-05-12 20:08:19 +02:00
}
} while ( i -- ) ;
return result ;
2014-08-10 12:02:48 +02:00
}
} , ! reduceRightCoercesToObject ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.14
// http://es5.github.com/#x15.4.4.14
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
2016-05-16 13:33:49 +02:00
var hasFirefox2IndexOfBug = ArrayPrototype . indexOf && [ 0 , 1 ] . indexOf ( 1 , 2 ) !== - 1 ;
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
indexOf : function indexOf ( searchElement /*, fromIndex */ ) {
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : ES . ToObject ( this ) ;
var length = ES . ToUint32 ( self . length ) ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
if ( length === 0 ) {
2014-05-12 20:08:19 +02:00
return - 1 ;
}
var i = 0 ;
if ( arguments . length > 1 ) {
2016-05-16 13:33:49 +02:00
i = ES . ToInteger ( arguments [ 1 ] ) ;
2014-05-12 20:08:19 +02:00
}
// handle negative indices
2016-05-16 13:33:49 +02:00
i = i >= 0 ? i : max ( 0 , length + i ) ;
2014-05-12 20:08:19 +02:00
for ( ; i < length ; i ++ ) {
2016-05-16 13:33:49 +02:00
if ( i in self && self [ i ] === searchElement ) {
2014-05-12 20:08:19 +02:00
return i ;
}
}
return - 1 ;
2014-08-10 12:02:48 +02:00
}
} , hasFirefox2IndexOfBug ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.4.4.15
// http://es5.github.com/#x15.4.4.15
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
2016-05-16 13:33:49 +02:00
var hasFirefox2LastIndexOfBug = ArrayPrototype . lastIndexOf && [ 0 , 1 ] . lastIndexOf ( 0 , - 3 ) !== - 1 ;
2014-08-10 12:02:48 +02:00
defineProperties ( ArrayPrototype , {
2016-05-16 13:33:49 +02:00
lastIndexOf : function lastIndexOf ( searchElement /*, fromIndex */ ) {
var self = splitString && isString ( this ) ? strSplit ( this , '' ) : ES . ToObject ( this ) ;
var length = ES . ToUint32 ( self . length ) ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
if ( length === 0 ) {
2014-05-12 20:08:19 +02:00
return - 1 ;
}
var i = length - 1 ;
if ( arguments . length > 1 ) {
2016-05-16 13:33:49 +02:00
i = min ( i , ES . ToInteger ( arguments [ 1 ] ) ) ;
2014-05-12 20:08:19 +02:00
}
// handle negative indices
i = i >= 0 ? i : length - Math . abs ( i ) ;
for ( ; i >= 0 ; i -- ) {
2016-05-16 13:33:49 +02:00
if ( i in self && searchElement === self [ i ] ) {
2014-05-12 20:08:19 +02:00
return i ;
}
}
return - 1 ;
2014-08-10 12:02:48 +02:00
}
} , hasFirefox2LastIndexOfBug ) ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
// ES5 15.4.4.12
// http://es5.github.com/#x15.4.4.12
var spliceNoopReturnsEmptyArray = ( function ( ) {
var a = [ 1 , 2 ] ;
var result = a . splice ( ) ;
return a . length === 2 && isArray ( result ) && result . length === 0 ;
} ( ) ) ;
defineProperties ( ArrayPrototype , {
// Safari 5.0 bug where .splice() returns undefined
splice : function splice ( start , deleteCount ) {
if ( arguments . length === 0 ) {
return [ ] ;
} else {
return array _splice . apply ( this , arguments ) ;
}
}
} , ! spliceNoopReturnsEmptyArray ) ;
var spliceWorksWithEmptyObject = ( function ( ) {
var obj = { } ;
ArrayPrototype . splice . call ( obj , 0 , 0 , 1 ) ;
return obj . length === 1 ;
} ( ) ) ;
defineProperties ( ArrayPrototype , {
splice : function splice ( start , deleteCount ) {
if ( arguments . length === 0 ) { return [ ] ; }
var args = arguments ;
this . length = max ( ES . ToInteger ( this . length ) , 0 ) ;
if ( arguments . length > 0 && typeof deleteCount !== 'number' ) {
args = arraySlice ( arguments ) ;
if ( args . length < 2 ) {
pushCall ( args , this . length - start ) ;
} else {
args [ 1 ] = ES . ToInteger ( deleteCount ) ;
}
}
return array _splice . apply ( this , args ) ;
}
} , ! spliceWorksWithEmptyObject ) ;
var spliceWorksWithLargeSparseArrays = ( function ( ) {
// Per https://github.com/es-shims/es5-shim/issues/295
// Safari 7/8 breaks with sparse arrays of size 1e5 or greater
var arr = new $Array ( 1e5 ) ;
// note: the index MUST be 8 or larger or the test will false pass
arr [ 8 ] = 'x' ;
arr . splice ( 1 , 1 ) ;
// note: this test must be defined *after* the indexOf shim
// per https://github.com/es-shims/es5-shim/issues/313
return arr . indexOf ( 'x' ) === 7 ;
} ( ) ) ;
var spliceWorksWithSmallSparseArrays = ( function ( ) {
// Per https://github.com/es-shims/es5-shim/issues/295
// Opera 12.15 breaks on this, no idea why.
var n = 256 ;
var arr = [ ] ;
arr [ n ] = 'a' ;
arr . splice ( n + 1 , 0 , 'b' ) ;
return arr [ n ] === 'a' ;
} ( ) ) ;
defineProperties ( ArrayPrototype , {
splice : function splice ( start , deleteCount ) {
var O = ES . ToObject ( this ) ;
var A = [ ] ;
var len = ES . ToUint32 ( O . length ) ;
var relativeStart = ES . ToInteger ( start ) ;
var actualStart = relativeStart < 0 ? max ( ( len + relativeStart ) , 0 ) : min ( relativeStart , len ) ;
var actualDeleteCount = min ( max ( ES . ToInteger ( deleteCount ) , 0 ) , len - actualStart ) ;
var k = 0 ;
var from ;
while ( k < actualDeleteCount ) {
from = $String ( actualStart + k ) ;
if ( owns ( O , from ) ) {
A [ k ] = O [ from ] ;
}
k += 1 ;
}
var items = arraySlice ( arguments , 2 ) ;
var itemCount = items . length ;
var to ;
if ( itemCount < actualDeleteCount ) {
k = actualStart ;
var maxK = len - actualDeleteCount ;
while ( k < maxK ) {
from = $String ( k + actualDeleteCount ) ;
to = $String ( k + itemCount ) ;
if ( owns ( O , from ) ) {
O [ to ] = O [ from ] ;
} else {
delete O [ to ] ;
}
k += 1 ;
}
k = len ;
var minK = len - actualDeleteCount + itemCount ;
while ( k > minK ) {
delete O [ k - 1 ] ;
k -= 1 ;
}
} else if ( itemCount > actualDeleteCount ) {
k = len - actualDeleteCount ;
while ( k > actualStart ) {
from = $String ( k + actualDeleteCount - 1 ) ;
to = $String ( k + itemCount - 1 ) ;
if ( owns ( O , from ) ) {
O [ to ] = O [ from ] ;
} else {
delete O [ to ] ;
}
k -= 1 ;
}
}
k = actualStart ;
for ( var i = 0 ; i < items . length ; ++ i ) {
O [ k ] = items [ i ] ;
k += 1 ;
}
O . length = len - actualDeleteCount + itemCount ;
return A ;
}
} , ! spliceWorksWithLargeSparseArrays || ! spliceWorksWithSmallSparseArrays ) ;
var originalJoin = ArrayPrototype . join ;
var hasStringJoinBug ;
try {
hasStringJoinBug = Array . prototype . join . call ( '123' , ',' ) !== '1,2,3' ;
} catch ( e ) {
hasStringJoinBug = true ;
}
if ( hasStringJoinBug ) {
defineProperties ( ArrayPrototype , {
join : function join ( separator ) {
var sep = typeof separator === 'undefined' ? ',' : separator ;
return originalJoin . call ( isString ( this ) ? strSplit ( this , '' ) : this , sep ) ;
}
} , hasStringJoinBug ) ;
}
var hasJoinUndefinedBug = [ 1 , 2 ] . join ( undefined ) !== '1,2' ;
if ( hasJoinUndefinedBug ) {
defineProperties ( ArrayPrototype , {
join : function join ( separator ) {
var sep = typeof separator === 'undefined' ? ',' : separator ;
return originalJoin . call ( this , sep ) ;
}
} , hasJoinUndefinedBug ) ;
}
var pushShim = function push ( item ) {
var O = ES . ToObject ( this ) ;
var n = ES . ToUint32 ( O . length ) ;
var i = 0 ;
while ( i < arguments . length ) {
O [ n + i ] = arguments [ i ] ;
i += 1 ;
}
O . length = n + i ;
return n + i ;
} ;
var pushIsNotGeneric = ( function ( ) {
var obj = { } ;
var result = Array . prototype . push . call ( obj , undefined ) ;
return result !== 1 || obj . length !== 1 || typeof obj [ 0 ] !== 'undefined' || ! owns ( obj , 0 ) ;
} ( ) ) ;
defineProperties ( ArrayPrototype , {
push : function push ( item ) {
if ( isArray ( this ) ) {
return array _push . apply ( this , arguments ) ;
}
return pushShim . apply ( this , arguments ) ;
}
} , pushIsNotGeneric ) ;
// This fixes a very weird bug in Opera 10.6 when pushing `undefined
var pushUndefinedIsWeird = ( function ( ) {
var arr = [ ] ;
var result = arr . push ( undefined ) ;
return result !== 1 || arr . length !== 1 || typeof arr [ 0 ] !== 'undefined' || ! owns ( arr , 0 ) ;
} ( ) ) ;
defineProperties ( ArrayPrototype , { push : pushShim } , pushUndefinedIsWeird ) ;
// ES5 15.2.3.14
// http://es5.github.io/#x15.4.4.10
// Fix boxed string bug
defineProperties ( ArrayPrototype , {
slice : function ( start , end ) {
var arr = isString ( this ) ? strSplit ( this , '' ) : this ;
return arraySliceApply ( arr , arguments ) ;
}
} , splitString ) ;
var sortIgnoresNonFunctions = ( function ( ) {
try {
[ 1 , 2 ] . sort ( null ) ;
[ 1 , 2 ] . sort ( { } ) ;
return true ;
} catch ( e ) { /**/ }
return false ;
} ( ) ) ;
var sortThrowsOnRegex = ( function ( ) {
// this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
try {
[ 1 , 2 ] . sort ( /a/ ) ;
return false ;
} catch ( e ) { /**/ }
return true ;
} ( ) ) ;
var sortIgnoresUndefined = ( function ( ) {
// applies in IE 8, for one.
try {
[ 1 , 2 ] . sort ( undefined ) ;
return true ;
} catch ( e ) { /**/ }
return false ;
} ( ) ) ;
defineProperties ( ArrayPrototype , {
sort : function sort ( compareFn ) {
if ( typeof compareFn === 'undefined' ) {
return arraySort ( this ) ;
}
if ( ! isCallable ( compareFn ) ) {
throw new TypeError ( 'Array.prototype.sort callback must be a function' ) ;
}
return arraySort ( this , compareFn ) ;
}
} , sortIgnoresNonFunctions || ! sortIgnoresUndefined || ! sortThrowsOnRegex ) ;
2014-05-12 20:08:19 +02:00
//
// Object
// ======
//
// ES5 15.2.3.14
// http://es5.github.com/#x15.2.3.14
2014-08-10 12:02:48 +02:00
// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
2016-05-16 13:33:49 +02:00
var hasDontEnumBug = ! ( { 'toString' : null } ) . propertyIsEnumerable ( 'toString' ) ;
var hasProtoEnumBug = function ( ) { } . propertyIsEnumerable ( 'prototype' ) ;
var hasStringEnumBug = ! owns ( 'x' , '0' ) ;
var equalsConstructorPrototype = function ( o ) {
var ctor = o . constructor ;
return ctor && ctor . prototype === o ;
} ;
var blacklistedKeys = {
$window : true ,
$console : true ,
$parent : true ,
$self : true ,
$frame : true ,
$frames : true ,
$frameElement : true ,
$webkitIndexedDB : true ,
$webkitStorageInfo : true ,
$external : true
} ;
var hasAutomationEqualityBug = ( function ( ) {
/* globals window */
if ( typeof window === 'undefined' ) { return false ; }
for ( var k in window ) {
try {
if ( ! blacklistedKeys [ '$' + k ] && owns ( window , k ) && window [ k ] !== null && typeof window [ k ] === 'object' ) {
equalsConstructorPrototype ( window [ k ] ) ;
}
} catch ( e ) {
return true ;
}
}
return false ;
} ( ) ) ;
var equalsConstructorPrototypeIfNotBuggy = function ( object ) {
if ( typeof window === 'undefined' || ! hasAutomationEqualityBug ) { return equalsConstructorPrototype ( object ) ; }
try {
return equalsConstructorPrototype ( object ) ;
} catch ( e ) {
return false ;
}
} ;
var dontEnums = [
'toString' ,
'toLocaleString' ,
'valueOf' ,
'hasOwnProperty' ,
'isPrototypeOf' ,
'propertyIsEnumerable' ,
'constructor'
] ;
var dontEnumsLength = dontEnums . length ;
// taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
// can be replaced with require('is-arguments') if we ever use a build process instead
var isStandardArguments = function isArguments ( value ) {
return toStr ( value ) === '[object Arguments]' ;
} ;
var isLegacyArguments = function isArguments ( value ) {
return value !== null &&
typeof value === 'object' &&
typeof value . length === 'number' &&
value . length >= 0 &&
! isArray ( value ) &&
isCallable ( value . callee ) ;
} ;
var isArguments = isStandardArguments ( arguments ) ? isStandardArguments : isLegacyArguments ;
defineProperties ( $Object , {
2014-08-10 12:02:48 +02:00
keys : function keys ( object ) {
2016-05-16 13:33:49 +02:00
var isFn = isCallable ( object ) ;
var isArgs = isArguments ( object ) ;
var isObject = object !== null && typeof object === 'object' ;
var isStr = isObject && isString ( object ) ;
2014-05-12 20:08:19 +02:00
if ( ! isObject && ! isFn && ! isArgs ) {
2016-05-16 13:33:49 +02:00
throw new TypeError ( 'Object.keys called on a non-object' ) ;
2014-05-12 20:08:19 +02:00
}
var theKeys = [ ] ;
var skipProto = hasProtoEnumBug && isFn ;
2016-05-16 13:33:49 +02:00
if ( ( isStr && hasStringEnumBug ) || isArgs ) {
2014-05-12 20:08:19 +02:00
for ( var i = 0 ; i < object . length ; ++ i ) {
2016-05-16 13:33:49 +02:00
pushCall ( theKeys , $String ( i ) ) ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
}
if ( ! isArgs ) {
2014-05-12 20:08:19 +02:00
for ( var name in object ) {
if ( ! ( skipProto && name === 'prototype' ) && owns ( object , name ) ) {
2016-05-16 13:33:49 +02:00
pushCall ( theKeys , $String ( name ) ) ;
2014-05-12 20:08:19 +02:00
}
}
}
if ( hasDontEnumBug ) {
2016-05-16 13:33:49 +02:00
var skipConstructor = equalsConstructorPrototypeIfNotBuggy ( object ) ;
2014-05-12 20:08:19 +02:00
for ( var j = 0 ; j < dontEnumsLength ; j ++ ) {
var dontEnum = dontEnums [ j ] ;
if ( ! ( skipConstructor && dontEnum === 'constructor' ) && owns ( object , dontEnum ) ) {
2016-05-16 13:33:49 +02:00
pushCall ( theKeys , dontEnum ) ;
2014-05-12 20:08:19 +02:00
}
}
}
return theKeys ;
2014-08-10 12:02:48 +02:00
}
} ) ;
2016-05-16 13:33:49 +02:00
var keysWorksWithArguments = $Object . keys && ( function ( ) {
2014-06-06 14:29:32 +02:00
// Safari 5.0 bug
2016-05-16 13:33:49 +02:00
return $Object . keys ( arguments ) . length === 2 ;
2014-08-10 12:02:48 +02:00
} ( 1 , 2 ) ) ;
2016-05-16 13:33:49 +02:00
var keysHasArgumentsLengthBug = $Object . keys && ( function ( ) {
var argKeys = $Object . keys ( arguments ) ;
return arguments . length !== 1 || argKeys . length !== 1 || argKeys [ 0 ] !== 1 ;
} ( 1 ) ) ;
var originalKeys = $Object . keys ;
defineProperties ( $Object , {
2014-08-10 12:02:48 +02:00
keys : function keys ( object ) {
2014-06-06 14:29:32 +02:00
if ( isArguments ( object ) ) {
2016-05-16 13:33:49 +02:00
return originalKeys ( arraySlice ( object ) ) ;
2014-06-06 14:29:32 +02:00
} else {
return originalKeys ( object ) ;
}
2014-08-10 12:02:48 +02:00
}
2016-05-16 13:33:49 +02:00
} , ! keysWorksWithArguments || keysHasArgumentsLengthBug ) ;
2014-05-12 20:08:19 +02:00
//
// Date
// ====
//
2016-05-16 13:33:49 +02:00
var hasNegativeMonthYearBug = new Date ( - 3509827329600292 ) . getUTCMonth ( ) !== 0 ;
var aNegativeTestDate = new Date ( - 1509842289600292 ) ;
var aPositiveTestDate = new Date ( 1449662400000 ) ;
var hasToUTCStringFormatBug = aNegativeTestDate . toUTCString ( ) !== 'Mon, 01 Jan -45875 11:59:59 GMT' ;
var hasToDateStringFormatBug ;
var hasToStringFormatBug ;
var timeZoneOffset = aNegativeTestDate . getTimezoneOffset ( ) ;
if ( timeZoneOffset < - 720 ) {
hasToDateStringFormatBug = aNegativeTestDate . toDateString ( ) !== 'Tue Jan 02 -45875' ;
hasToStringFormatBug = ! ( /^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/ ) . test ( aPositiveTestDate . toString ( ) ) ;
} else {
hasToDateStringFormatBug = aNegativeTestDate . toDateString ( ) !== 'Mon Jan 01 -45875' ;
hasToStringFormatBug = ! ( /^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/ ) . test ( aPositiveTestDate . toString ( ) ) ;
}
var originalGetFullYear = call . bind ( Date . prototype . getFullYear ) ;
var originalGetMonth = call . bind ( Date . prototype . getMonth ) ;
var originalGetDate = call . bind ( Date . prototype . getDate ) ;
var originalGetUTCFullYear = call . bind ( Date . prototype . getUTCFullYear ) ;
var originalGetUTCMonth = call . bind ( Date . prototype . getUTCMonth ) ;
var originalGetUTCDate = call . bind ( Date . prototype . getUTCDate ) ;
var originalGetUTCDay = call . bind ( Date . prototype . getUTCDay ) ;
var originalGetUTCHours = call . bind ( Date . prototype . getUTCHours ) ;
var originalGetUTCMinutes = call . bind ( Date . prototype . getUTCMinutes ) ;
var originalGetUTCSeconds = call . bind ( Date . prototype . getUTCSeconds ) ;
var originalGetUTCMilliseconds = call . bind ( Date . prototype . getUTCMilliseconds ) ;
var dayName = [ 'Sun' , 'Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' , 'Sat' ] ;
var monthName = [ 'Jan' , 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' , 'Jul' , 'Aug' , 'Sep' , 'Oct' , 'Nov' , 'Dec' ] ;
var daysInMonth = function daysInMonth ( month , year ) {
return originalGetDate ( new Date ( year , month , 0 ) ) ;
} ;
defineProperties ( Date . prototype , {
getFullYear : function getFullYear ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var year = originalGetFullYear ( this ) ;
if ( year < 0 && originalGetMonth ( this ) > 11 ) {
return year + 1 ;
}
return year ;
} ,
getMonth : function getMonth ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var year = originalGetFullYear ( this ) ;
var month = originalGetMonth ( this ) ;
if ( year < 0 && month > 11 ) {
return 0 ;
}
return month ;
} ,
getDate : function getDate ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var year = originalGetFullYear ( this ) ;
var month = originalGetMonth ( this ) ;
var date = originalGetDate ( this ) ;
if ( year < 0 && month > 11 ) {
if ( month === 12 ) {
return date ;
}
var days = daysInMonth ( 0 , year + 1 ) ;
return ( days - date ) + 1 ;
}
return date ;
} ,
getUTCFullYear : function getUTCFullYear ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var year = originalGetUTCFullYear ( this ) ;
if ( year < 0 && originalGetUTCMonth ( this ) > 11 ) {
return year + 1 ;
}
return year ;
} ,
getUTCMonth : function getUTCMonth ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var year = originalGetUTCFullYear ( this ) ;
var month = originalGetUTCMonth ( this ) ;
if ( year < 0 && month > 11 ) {
return 0 ;
}
return month ;
} ,
getUTCDate : function getUTCDate ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var year = originalGetUTCFullYear ( this ) ;
var month = originalGetUTCMonth ( this ) ;
var date = originalGetUTCDate ( this ) ;
if ( year < 0 && month > 11 ) {
if ( month === 12 ) {
return date ;
}
var days = daysInMonth ( 0 , year + 1 ) ;
return ( days - date ) + 1 ;
}
return date ;
}
} , hasNegativeMonthYearBug ) ;
defineProperties ( Date . prototype , {
toUTCString : function toUTCString ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var day = originalGetUTCDay ( this ) ;
var date = originalGetUTCDate ( this ) ;
var month = originalGetUTCMonth ( this ) ;
var year = originalGetUTCFullYear ( this ) ;
var hour = originalGetUTCHours ( this ) ;
var minute = originalGetUTCMinutes ( this ) ;
var second = originalGetUTCSeconds ( this ) ;
return dayName [ day ] + ', ' +
( date < 10 ? '0' + date : date ) + ' ' +
monthName [ month ] + ' ' +
year + ' ' +
( hour < 10 ? '0' + hour : hour ) + ':' +
( minute < 10 ? '0' + minute : minute ) + ':' +
( second < 10 ? '0' + second : second ) + ' GMT' ;
}
} , hasNegativeMonthYearBug || hasToUTCStringFormatBug ) ;
// Opera 12 has `,`
defineProperties ( Date . prototype , {
toDateString : function toDateString ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var day = this . getDay ( ) ;
var date = this . getDate ( ) ;
var month = this . getMonth ( ) ;
var year = this . getFullYear ( ) ;
return dayName [ day ] + ' ' +
monthName [ month ] + ' ' +
( date < 10 ? '0' + date : date ) + ' ' +
year ;
}
} , hasNegativeMonthYearBug || hasToDateStringFormatBug ) ;
// can't use defineProperties here because of toString enumeration issue in IE <= 8
if ( hasNegativeMonthYearBug || hasToStringFormatBug ) {
Date . prototype . toString = function toString ( ) {
if ( ! this || ! ( this instanceof Date ) ) {
throw new TypeError ( 'this is not a Date object.' ) ;
}
var day = this . getDay ( ) ;
var date = this . getDate ( ) ;
var month = this . getMonth ( ) ;
var year = this . getFullYear ( ) ;
var hour = this . getHours ( ) ;
var minute = this . getMinutes ( ) ;
var second = this . getSeconds ( ) ;
var timezoneOffset = this . getTimezoneOffset ( ) ;
var hoursOffset = Math . floor ( Math . abs ( timezoneOffset ) / 60 ) ;
var minutesOffset = Math . floor ( Math . abs ( timezoneOffset ) % 60 ) ;
return dayName [ day ] + ' ' +
monthName [ month ] + ' ' +
( date < 10 ? '0' + date : date ) + ' ' +
year + ' ' +
( hour < 10 ? '0' + hour : hour ) + ':' +
( minute < 10 ? '0' + minute : minute ) + ':' +
( second < 10 ? '0' + second : second ) + ' GMT' +
( timezoneOffset > 0 ? '-' : '+' ) +
( hoursOffset < 10 ? '0' + hoursOffset : hoursOffset ) +
( minutesOffset < 10 ? '0' + minutesOffset : minutesOffset ) ;
} ;
if ( supportsDescriptors ) {
$Object . defineProperty ( Date . prototype , 'toString' , {
configurable : true ,
enumerable : false ,
writable : true
} ) ;
}
}
2014-05-12 20:08:19 +02:00
// 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 object is not a finite Number a RangeError exception is thrown.
2014-08-10 12:02:48 +02:00
var negativeDate = - 62198755200000 ;
2016-05-16 13:33:49 +02:00
var negativeYearString = '-000001' ;
2014-08-10 12:02:48 +02:00
var hasNegativeDateBug = Date . prototype . toISOString && new Date ( negativeDate ) . toISOString ( ) . indexOf ( negativeYearString ) === - 1 ;
2016-05-16 13:33:49 +02:00
var hasSafari51DateBug = Date . prototype . toISOString && new Date ( - 1 ) . toISOString ( ) !== '1969-12-31T23:59:59.999Z' ;
var getTime = call . bind ( Date . prototype . getTime ) ;
2014-08-10 12:02:48 +02:00
defineProperties ( Date . prototype , {
toISOString : function toISOString ( ) {
2016-05-16 13:33:49 +02:00
if ( ! isFinite ( this ) || ! isFinite ( getTime ( this ) ) ) {
// Adope Photoshop requires the second check.
throw new RangeError ( 'Date.prototype.toISOString called on non-finite value.' ) ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
var year = originalGetUTCFullYear ( this ) ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
var month = originalGetUTCMonth ( this ) ;
2014-05-12 20:08:19 +02:00
// see https://github.com/es-shims/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.
2016-05-16 13:33:49 +02:00
var result = [ month + 1 , originalGetUTCDate ( this ) , originalGetUTCHours ( this ) , originalGetUTCMinutes ( this ) , originalGetUTCSeconds ( this ) ] ;
2014-05-12 20:08:19 +02:00
year = (
2016-05-16 13:33:49 +02:00
( year < 0 ? '-' : ( year > 9999 ? '+' : '' ) ) +
strSlice ( '00000' + Math . abs ( year ) , ( 0 <= year && year <= 9999 ) ? - 4 : - 6 )
2014-05-12 20:08:19 +02:00
) ;
2016-05-16 13:33:49 +02:00
for ( var i = 0 ; i < result . length ; ++ i ) {
// pad months, days, hours, minutes, and seconds to have two digits.
result [ i ] = strSlice ( '00' + result [ i ] , - 2 ) ;
2014-05-12 20:08:19 +02:00
}
// pad milliseconds to have three digits.
return (
2016-05-16 13:33:49 +02:00
year + '-' + arraySlice ( result , 0 , 2 ) . join ( '-' ) +
'T' + arraySlice ( result , 2 ) . join ( ':' ) + '.' +
strSlice ( '000' + originalGetUTCMilliseconds ( this ) , - 3 ) + 'Z'
2014-05-12 20:08:19 +02:00
) ;
2014-08-10 12:02:48 +02:00
}
2016-05-16 13:33:49 +02:00
} , hasNegativeDateBug || hasSafari51DateBug ) ;
2014-05-12 20:08:19 +02:00
// 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
// JSON.stringify (15.12.3).
2016-05-16 13:33:49 +02:00
var dateToJSONIsSupported = ( function ( ) {
try {
return 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 ) {
return false ;
}
} ( ) ) ;
2014-05-12 20:08:19 +02:00
if ( ! dateToJSONIsSupported ) {
Date . prototype . toJSON = function toJSON ( key ) {
// 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.
2016-05-16 13:33:49 +02:00
// 2. Let tv be ES.ToPrimitive(O, hint Number).
var O = $Object ( this ) ;
var tv = ES . ToPrimitive ( O ) ;
2014-05-12 20:08:19 +02:00
// 3. If tv is a Number and is not finite, return null.
2016-05-16 13:33:49 +02:00
if ( typeof tv === 'number' && ! isFinite ( tv ) ) {
2014-05-12 20:08:19 +02:00
return null ;
}
// 4. Let toISO be the result of calling the [[Get]] internal method of
// O with argument "toISOString".
2016-05-16 13:33:49 +02:00
var toISO = O . toISOString ;
2014-05-12 20:08:19 +02:00
// 5. If IsCallable(toISO) is false, throw a TypeError exception.
2016-05-16 13:33:49 +02:00
if ( ! isCallable ( toISO ) ) {
throw new TypeError ( 'toISOString property is not callable' ) ;
2014-05-12 20:08:19 +02:00
}
// 6. Return the result of calling the [[Call]] internal method of
// toISO with O as the this value and an empty argument list.
2016-05-16 13:33:49 +02:00
return toISO . call ( O ) ;
2014-05-12 20:08:19 +02:00
// NOTE 1 The argument is ignored.
// NOTE 2 The toJSON function is intentionally generic; it does not
// require that its this value be a Date object. Therefore, it can be
// transferred to other kinds of objects for use as a method. However,
// it does require that any such object have a toISOString method. An
// object is free to use the argument key to filter its
// stringification.
} ;
}
// ES5 15.9.4.2
// http://es5.github.com/#x15.9.4.2
// based on work shared by Daniel Friesen (dantman)
// http://gist.github.com/303249
var supportsExtendedYears = Date . parse ( '+033658-09-27T01:46:40.000Z' ) === 1e15 ;
2016-05-16 13:33:49 +02:00
var acceptsInvalidDates = ! isNaN ( Date . parse ( '2012-04-04T24:00:00.500Z' ) ) || ! isNaN ( Date . parse ( '2012-11-31T23:59:59.000Z' ) ) || ! isNaN ( Date . parse ( '2012-12-31T23:59:60.000Z' ) ) ;
var doesNotParseY2KNewYear = isNaN ( Date . parse ( '2000-01-01T00:00:00.000Z' ) ) ;
if ( doesNotParseY2KNewYear || acceptsInvalidDates || ! supportsExtendedYears ) {
2014-05-12 20:08:19 +02:00
// XXX global assignment won't work in embeddings that use
// an alternate object for the context.
2016-05-16 13:33:49 +02:00
/* global Date: true */
/* eslint-disable no-undef */
var maxSafeUnsigned32Bit = Math . pow ( 2 , 31 ) - 1 ;
var hasSafariSignedIntBug = isActualNaN ( new Date ( 1970 , 0 , 1 , 0 , 0 , 0 , maxSafeUnsigned32Bit + 1 ) . getTime ( ) ) ;
/* eslint-disable no-implicit-globals */
2014-06-06 14:29:32 +02:00
Date = ( function ( NativeDate ) {
2016-05-16 13:33:49 +02:00
/* eslint-enable no-implicit-globals */
/* eslint-enable no-undef */
2014-05-12 20:08:19 +02:00
// Date.length === 7
2016-05-16 13:33:49 +02:00
var DateShim = function Date ( Y , M , D , h , m , s , ms ) {
2014-05-12 20:08:19 +02:00
var length = arguments . length ;
2016-05-16 13:33:49 +02:00
var date ;
2014-05-12 20:08:19 +02:00
if ( this instanceof NativeDate ) {
2016-05-16 13:33:49 +02:00
var seconds = s ;
var millis = ms ;
if ( hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit ) {
// work around a Safari 8/9 bug where it treats the seconds as signed
var msToShift = Math . floor ( ms / maxSafeUnsigned32Bit ) * maxSafeUnsigned32Bit ;
var sToShift = Math . floor ( msToShift / 1e3 ) ;
seconds += sToShift ;
millis -= sToShift * 1e3 ;
}
date = length === 1 && $String ( Y ) === Y ? // isString(Y)
2014-05-12 20:08:19 +02:00
// We explicitly pass it through parse:
2016-05-16 13:33:49 +02:00
new NativeDate ( DateShim . parse ( Y ) ) :
2014-05-12 20:08:19 +02:00
// We have to manually make calls depending on argument
// length here
2016-05-16 13:33:49 +02:00
length >= 7 ? new NativeDate ( Y , M , D , h , m , seconds , millis ) :
length >= 6 ? new NativeDate ( Y , M , D , h , m , seconds ) :
2014-05-12 20:08:19 +02:00
length >= 5 ? new NativeDate ( Y , M , D , h , m ) :
length >= 4 ? new NativeDate ( Y , M , D , h ) :
length >= 3 ? new NativeDate ( Y , M , D ) :
length >= 2 ? new NativeDate ( Y , M ) :
2016-05-16 13:33:49 +02:00
length >= 1 ? new NativeDate ( Y instanceof NativeDate ? + Y : Y ) :
2014-05-12 20:08:19 +02:00
new NativeDate ( ) ;
2016-05-16 13:33:49 +02:00
} else {
date = NativeDate . apply ( this , arguments ) ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
if ( ! isPrimitive ( date ) ) {
// Prevent mixups with unfixed Date object
defineProperties ( date , { constructor : DateShim } , true ) ;
}
return date ;
} ;
2014-05-12 20:08:19 +02:00
// 15.9.1.15 Date Time String Format.
2016-05-16 13:33:49 +02:00
var isoDateExpression = new RegExp ( '^' +
'(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
2014-05-12 20:08:19 +02:00
// 6-digit extended year
2016-05-16 13:33:49 +02:00
'(?:-(\\d{2})' + // optional month capture
'(?:-(\\d{2})' + // optional day capture
'(?:' + // capture hours:minutes:seconds.milliseconds
'T(\\d{2})' + // hours capture
':(\\d{2})' + // minutes capture
'(?:' + // optional :seconds.milliseconds
':(\\d{2})' + // seconds capture
'(?:(\\.\\d{1,}))?' + // milliseconds capture
')?' +
'(' + // capture UTC offset component
'Z|' + // UTC capture
'(?:' + // offset specifier +/-hours:minutes
'([-+])' + // sign capture
'(\\d{2})' + // hours offset capture
':(\\d{2})' + // minutes offset capture
')' +
')?)?)?)?' +
'$' ) ;
var months = [ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 , 365 ] ;
var dayFromMonth = function dayFromMonth ( year , month ) {
2014-05-12 20:08:19 +02:00
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 )
) ;
2016-05-16 13:33:49 +02:00
} ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
var toUTC = function toUTC ( t ) {
var s = 0 ;
var ms = t ;
if ( hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit ) {
// work around a Safari 8/9 bug where it treats the seconds as signed
var msToShift = Math . floor ( ms / maxSafeUnsigned32Bit ) * maxSafeUnsigned32Bit ;
var sToShift = Math . floor ( msToShift / 1e3 ) ;
s += sToShift ;
ms -= sToShift * 1e3 ;
}
return $Number ( new NativeDate ( 1970 , 0 , 1 , 0 , 0 , s , ms ) ) ;
} ;
2014-05-12 20:08:19 +02:00
// Copy any custom methods a 3rd party library may have added
for ( var key in NativeDate ) {
2016-05-16 13:33:49 +02:00
if ( owns ( NativeDate , key ) ) {
DateShim [ key ] = NativeDate [ key ] ;
}
2014-05-12 20:08:19 +02:00
}
// Copy "native" methods explicitly; they may be non-enumerable
2016-05-16 13:33:49 +02:00
defineProperties ( DateShim , {
now : NativeDate . now ,
UTC : NativeDate . UTC
} , true ) ;
DateShim . prototype = NativeDate . prototype ;
defineProperties ( DateShim . prototype , {
constructor : DateShim
} , true ) ;
2014-05-12 20:08:19 +02:00
// Upgrade Date.parse to handle simplified ISO 8601 strings
2016-05-16 13:33:49 +02:00
var parseShim = function parse ( string ) {
2014-05-12 20:08:19 +02:00
var match = isoDateExpression . exec ( string ) ;
if ( match ) {
// parse months, days, hours, minutes, seconds, and milliseconds
// provide default values if necessary
// parse the UTC offset component
2016-05-16 13:33:49 +02:00
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 = Math . floor ( $Number ( match [ 7 ] || 0 ) * 1000 ) ,
2014-05-12 20:08:19 +02:00
// When time zone is missed, local offset should be used
// (ES 5.1 bug)
// see https://bugs.ecmascript.org/show_bug.cgi?id=112
isLocalTime = Boolean ( match [ 4 ] && ! match [ 8 ] ) ,
2016-05-16 13:33:49 +02:00
signOffset = match [ 9 ] === '-' ? 1 : - 1 ,
hourOffset = $Number ( match [ 10 ] || 0 ) ,
minuteOffset = $Number ( match [ 11 ] || 0 ) ,
2014-05-12 20:08:19 +02:00
result ;
2016-05-16 13:33:49 +02:00
var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0 ;
2014-05-12 20:08:19 +02:00
if (
2016-05-16 13:33:49 +02:00
hour < ( hasMinutesOrSecondsOrMilliseconds ? 24 : 25 ) &&
2014-05-12 20:08:19 +02:00
minute < 60 && second < 60 && millisecond < 1000 &&
month > - 1 && month < 12 && hourOffset < 24 &&
minuteOffset < 60 && // detect invalid offsets
day > - 1 &&
2016-05-16 13:33:49 +02:00
day < ( dayFromMonth ( year , month + 1 ) - dayFromMonth ( year , month ) )
2014-05-12 20:08:19 +02:00
) {
result = (
( dayFromMonth ( year , month ) + day ) * 24 +
hour +
hourOffset * signOffset
) * 60 ;
result = (
( result + minute + minuteOffset * signOffset ) * 60 +
second
) * 1000 + millisecond ;
if ( isLocalTime ) {
result = toUTC ( result ) ;
}
if ( - 8.64 e15 <= result && result <= 8.64 e15 ) {
return result ;
}
}
return NaN ;
}
return NativeDate . parse . apply ( this , arguments ) ;
} ;
2016-05-16 13:33:49 +02:00
defineProperties ( DateShim , { parse : parseShim } ) ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
return DateShim ;
} ( Date ) ) ;
/* global Date: false */
2014-05-12 20:08:19 +02:00
}
// ES5 15.9.4.4
// http://es5.github.com/#x15.9.4.4
if ( ! Date . now ) {
Date . now = function now ( ) {
return new Date ( ) . getTime ( ) ;
} ;
}
//
// Number
// ======
//
// ES5.1 15.7.4.5
// http://es5.github.com/#x15.7.4.5
2014-08-10 12:02:48 +02:00
var hasToFixedBugs = NumberPrototype . toFixed && (
2016-05-16 13:33:49 +02:00
( 0.00008 ) . toFixed ( 3 ) !== '0.000' ||
( 0.9 ) . toFixed ( 0 ) !== '1' ||
( 1.255 ) . toFixed ( 2 ) !== '1.25' ||
( 1000000000000000128 ) . toFixed ( 0 ) !== '1000000000000000128'
2014-08-10 12:02:48 +02:00
) ;
var toFixedHelpers = {
base : 1e7 ,
size : 6 ,
data : [ 0 , 0 , 0 , 0 , 0 , 0 ] ,
multiply : function multiply ( n , c ) {
var i = - 1 ;
2016-05-16 13:33:49 +02:00
var c2 = c ;
2014-08-10 12:02:48 +02:00
while ( ++ i < toFixedHelpers . size ) {
2016-05-16 13:33:49 +02:00
c2 += n * toFixedHelpers . data [ i ] ;
toFixedHelpers . data [ i ] = c2 % toFixedHelpers . base ;
c2 = Math . floor ( c2 / toFixedHelpers . base ) ;
2014-08-10 12:02:48 +02:00
}
} ,
divide : function divide ( n ) {
2016-05-16 13:33:49 +02:00
var i = toFixedHelpers . size ;
var c = 0 ;
2014-08-10 12:02:48 +02:00
while ( -- i >= 0 ) {
c += toFixedHelpers . data [ i ] ;
toFixedHelpers . data [ i ] = Math . floor ( c / n ) ;
c = ( c % n ) * toFixedHelpers . base ;
}
} ,
numToString : function numToString ( ) {
var i = toFixedHelpers . size ;
var s = '' ;
while ( -- i >= 0 ) {
if ( s !== '' || i === 0 || toFixedHelpers . data [ i ] !== 0 ) {
2016-05-16 13:33:49 +02:00
var t = $String ( toFixedHelpers . data [ i ] ) ;
2014-08-10 12:02:48 +02:00
if ( s === '' ) {
s = t ;
} else {
2016-05-16 13:33:49 +02:00
s += strSlice ( '0000000' , 0 , 7 - t . length ) + t ;
2014-08-10 12:02:48 +02:00
}
}
}
return s ;
} ,
pow : function pow ( x , n , acc ) {
return ( n === 0 ? acc : ( n % 2 === 1 ? pow ( x , n - 1 , acc * x ) : pow ( x * x , n / 2 , acc ) ) ) ;
} ,
log : function log ( x ) {
var n = 0 ;
2016-05-16 13:33:49 +02:00
var x2 = x ;
while ( x2 >= 4096 ) {
2014-08-10 12:02:48 +02:00
n += 12 ;
2016-05-16 13:33:49 +02:00
x2 /= 4096 ;
2014-08-10 12:02:48 +02:00
}
2016-05-16 13:33:49 +02:00
while ( x2 >= 2 ) {
2014-08-10 12:02:48 +02:00
n += 1 ;
2016-05-16 13:33:49 +02:00
x2 /= 2 ;
2014-08-10 12:02:48 +02:00
}
return n ;
}
} ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
var toFixedShim = function toFixed ( fractionDigits ) {
var f , x , s , m , e , z , j , k ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
// Test for NaN and round fractionDigits down
f = $Number ( fractionDigits ) ;
f = isActualNaN ( f ) ? 0 : Math . floor ( f ) ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
if ( f < 0 || f > 20 ) {
throw new RangeError ( 'Number.toFixed called with invalid number of decimals' ) ;
}
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
x = $Number ( this ) ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
if ( isActualNaN ( x ) ) {
return 'NaN' ;
}
2014-08-10 12:02:48 +02:00
2016-05-16 13:33:49 +02:00
// If it is too big or small, return the string value of the number
if ( x <= - 1e21 || x >= 1e21 ) {
return $String ( x ) ;
}
2014-08-10 12:02:48 +02:00
2016-05-16 13:33:49 +02:00
s = '' ;
2014-08-10 12:02:48 +02:00
2016-05-16 13:33:49 +02:00
if ( x < 0 ) {
s = '-' ;
x = - x ;
}
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
m = '0' ;
if ( x > 1e-21 ) {
// 1e-21 < x < 1e21
// -70 < log2(x) < 70
e = toFixedHelpers . log ( x * toFixedHelpers . pow ( 2 , 69 , 1 ) ) - 69 ;
z = ( e < 0 ? x * toFixedHelpers . pow ( 2 , - e , 1 ) : x / toFixedHelpers . pow ( 2 , e , 1 ) ) ;
z *= 0x10000000000000 ; // Math.pow(2, 52);
e = 52 - e ;
// -18 < e < 122
// x = z / 2 ^ e
if ( e > 0 ) {
toFixedHelpers . multiply ( 0 , z ) ;
j = f ;
while ( j >= 7 ) {
toFixedHelpers . multiply ( 1e7 , 0 ) ;
j -= 7 ;
}
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
toFixedHelpers . multiply ( toFixedHelpers . pow ( 10 , j , 1 ) , 0 ) ;
j = e - 1 ;
2014-08-10 12:02:48 +02:00
2016-05-16 13:33:49 +02:00
while ( j >= 23 ) {
toFixedHelpers . divide ( 1 << 23 ) ;
j -= 23 ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
toFixedHelpers . divide ( 1 << j ) ;
toFixedHelpers . multiply ( 1 , 1 ) ;
toFixedHelpers . divide ( 2 ) ;
m = toFixedHelpers . numToString ( ) ;
} else {
toFixedHelpers . multiply ( 0 , z ) ;
toFixedHelpers . multiply ( 1 << ( - e ) , 0 ) ;
m = toFixedHelpers . numToString ( ) + strSlice ( '0.00000000000000000000' , 2 , 2 + f ) ;
2014-08-10 12:02:48 +02:00
}
2016-05-16 13:33:49 +02:00
}
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
if ( f > 0 ) {
k = m . length ;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
if ( k <= f ) {
m = s + strSlice ( '0.0000000000000000000' , 0 , f - k + 2 ) + m ;
2014-08-10 12:02:48 +02:00
} else {
2016-05-16 13:33:49 +02:00
m = s + strSlice ( m , 0 , k - f ) + '.' + strSlice ( m , k - f ) ;
2014-08-10 12:02:48 +02:00
}
2016-05-16 13:33:49 +02:00
} else {
m = s + m ;
2014-08-10 12:02:48 +02:00
}
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
return m ;
} ;
defineProperties ( NumberPrototype , { toFixed : toFixedShim } , hasToFixedBugs ) ;
var hasToPrecisionUndefinedBug = ( function ( ) {
try {
return 1.0 . toPrecision ( undefined ) === '1' ;
} catch ( e ) {
return true ;
}
} ( ) ) ;
var originalToPrecision = NumberPrototype . toPrecision ;
defineProperties ( NumberPrototype , {
toPrecision : function toPrecision ( precision ) {
return typeof precision === 'undefined' ? originalToPrecision . call ( this ) : originalToPrecision . call ( this , precision ) ;
}
} , hasToPrecisionUndefinedBug ) ;
2014-05-12 20:08:19 +02:00
//
// String
// ======
//
// ES5 15.5.4.14
// http://es5.github.com/#x15.5.4.14
// [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
// Many browsers do not split properly with regular expressions or they
// do not perform the split correctly under obscure conditions.
// See http://blog.stevenlevithan.com/archives/cross-browser-split
// I've tested in many browsers and this seems to cover the deviant ones:
// 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
// '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
// 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
// [undefined, "t", undefined, "e", ...]
// ''.split(/.?/) should be [], not [""]
// '.'.split(/()()/) should be ["."], not ["", "", "."]
if (
'ab' . split ( /(?:ab)*/ ) . length !== 2 ||
'.' . split ( /(.?)(.?)/ ) . length !== 4 ||
2016-05-16 13:33:49 +02:00
'tesst' . split ( /(s)*/ ) [ 1 ] === 't' ||
2014-06-06 14:29:32 +02:00
'test' . split ( /(?:)/ , - 1 ) . length !== 4 ||
2014-05-12 20:08:19 +02:00
'' . split ( /.?/ ) . length ||
'.' . split ( /()()/ ) . length > 1
) {
( function ( ) {
2016-05-16 13:33:49 +02:00
var compliantExecNpcg = typeof ( /()??/ ) . exec ( '' ) [ 1 ] === 'undefined' ; // NPCG: nonparticipating capturing group
var maxSafe32BitInt = Math . pow ( 2 , 32 ) - 1 ;
2014-05-12 20:08:19 +02:00
2014-08-10 12:02:48 +02:00
StringPrototype . split = function ( separator , limit ) {
2016-05-16 13:33:49 +02:00
var string = String ( this ) ;
if ( typeof separator === 'undefined' && limit === 0 ) {
2014-05-12 20:08:19 +02:00
return [ ] ;
2014-06-06 14:29:32 +02:00
}
2014-05-12 20:08:19 +02:00
// If `separator` is not a regex, use native split
2016-05-16 13:33:49 +02:00
if ( ! isRegex ( separator ) ) {
return strSplit ( this , separator , limit ) ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
var output = [ ] ;
var flags = ( separator . ignoreCase ? 'i' : '' ) +
( separator . multiline ? 'm' : '' ) +
( separator . unicode ? 'u' : '' ) + // in ES6
( separator . sticky ? 'y' : '' ) , // Firefox 3+ and ES6
2014-05-12 20:08:19 +02:00
lastLastIndex = 0 ,
// Make `global` and avoid `lastIndex` issues by working with a copy
separator2 , match , lastIndex , lastLength ;
2016-05-16 13:33:49 +02:00
var separatorCopy = new RegExp ( separator . source , flags + 'g' ) ;
2014-05-12 20:08:19 +02:00
if ( ! compliantExecNpcg ) {
// Doesn't need flags gy, but they don't hurt
2016-05-16 13:33:49 +02:00
separator2 = new RegExp ( '^' + separatorCopy . source + '$(?!\\s)' , flags ) ;
2014-05-12 20:08:19 +02:00
}
/ * V a l u e s f o r ` l i m i t ` , p e r t h e s p e c :
2016-05-16 13:33:49 +02:00
* If undefined : 4294967295 // maxSafe32BitInt
2014-05-12 20:08:19 +02:00
* If 0 , Infinity , or NaN : 0
* If positive number : limit = Math . floor ( limit ) ; if ( limit > 4294967295 ) limit -= 4294967296 ;
* If negative number : 4294967296 - Math . floor ( Math . abs ( limit ) )
* If other : Type - convert , then use the above rules
* /
2016-05-16 13:33:49 +02:00
var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES . ToUint32 ( limit ) ;
match = separatorCopy . exec ( string ) ;
while ( match ) {
// `separatorCopy.lastIndex` is not reliable cross-browser
2014-05-12 20:08:19 +02:00
lastIndex = match . index + match [ 0 ] . length ;
if ( lastIndex > lastLastIndex ) {
2016-05-16 13:33:49 +02:00
pushCall ( output , strSlice ( string , lastLastIndex , match . index ) ) ;
2014-05-12 20:08:19 +02:00
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if ( ! compliantExecNpcg && match . length > 1 ) {
2016-05-16 13:33:49 +02:00
/* eslint-disable no-loop-func */
2014-05-12 20:08:19 +02:00
match [ 0 ] . replace ( separator2 , function ( ) {
for ( var i = 1 ; i < arguments . length - 2 ; i ++ ) {
2016-05-16 13:33:49 +02:00
if ( typeof arguments [ i ] === 'undefined' ) {
2014-05-12 20:08:19 +02:00
match [ i ] = void 0 ;
}
}
} ) ;
2016-05-16 13:33:49 +02:00
/* eslint-enable no-loop-func */
2014-05-12 20:08:19 +02:00
}
if ( match . length > 1 && match . index < string . length ) {
2016-05-16 13:33:49 +02:00
array _push . apply ( output , arraySlice ( match , 1 ) ) ;
2014-05-12 20:08:19 +02:00
}
lastLength = match [ 0 ] . length ;
lastLastIndex = lastIndex ;
2016-05-16 13:33:49 +02:00
if ( output . length >= splitLimit ) {
2014-05-12 20:08:19 +02:00
break ;
}
}
2016-05-16 13:33:49 +02:00
if ( separatorCopy . lastIndex === match . index ) {
separatorCopy . lastIndex ++ ; // Avoid an infinite loop
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
match = separatorCopy . exec ( string ) ;
2014-05-12 20:08:19 +02:00
}
if ( lastLastIndex === string . length ) {
2016-05-16 13:33:49 +02:00
if ( lastLength || ! separatorCopy . test ( '' ) ) {
pushCall ( output , '' ) ;
2014-05-12 20:08:19 +02:00
}
} else {
2016-05-16 13:33:49 +02:00
pushCall ( output , strSlice ( string , lastLastIndex ) ) ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
return output . length > splitLimit ? arraySlice ( output , 0 , splitLimit ) : output ;
2014-05-12 20:08:19 +02:00
} ;
} ( ) ) ;
// [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) -> []
2016-05-16 13:33:49 +02:00
} else if ( '0' . split ( void 0 , 0 ) . length ) {
2014-08-10 12:02:48 +02:00
StringPrototype . split = function split ( separator , limit ) {
2016-05-16 13:33:49 +02:00
if ( typeof separator === 'undefined' && limit === 0 ) { return [ ] ; }
return strSplit ( this , separator , limit ) ;
2014-05-12 20:08:19 +02:00
} ;
}
2014-08-10 12:02:48 +02:00
var str _replace = StringPrototype . replace ;
2014-05-12 20:08:19 +02:00
var replaceReportsGroupsCorrectly = ( function ( ) {
var groups = [ ] ;
'x' . replace ( /x(.)?/g , function ( match , group ) {
2016-05-16 13:33:49 +02:00
pushCall ( groups , group ) ;
2014-05-12 20:08:19 +02:00
} ) ;
return groups . length === 1 && typeof groups [ 0 ] === 'undefined' ;
} ( ) ) ;
if ( ! replaceReportsGroupsCorrectly ) {
2014-08-10 12:02:48 +02:00
StringPrototype . replace = function replace ( searchValue , replaceValue ) {
2016-05-16 13:33:49 +02:00
var isFn = isCallable ( replaceValue ) ;
2014-05-12 20:08:19 +02:00
var hasCapturingGroups = isRegex ( searchValue ) && ( /\)[*?]/ ) . test ( searchValue . source ) ;
if ( ! isFn || ! hasCapturingGroups ) {
2014-06-06 14:29:32 +02:00
return str _replace . call ( this , searchValue , replaceValue ) ;
2014-05-12 20:08:19 +02:00
} else {
var wrappedReplaceValue = function ( match ) {
var length = arguments . length ;
var originalLastIndex = searchValue . lastIndex ;
searchValue . lastIndex = 0 ;
2016-05-16 13:33:49 +02:00
var args = searchValue . exec ( match ) || [ ] ;
2014-05-12 20:08:19 +02:00
searchValue . lastIndex = originalLastIndex ;
2016-05-16 13:33:49 +02:00
pushCall ( args , arguments [ length - 2 ] , arguments [ length - 1 ] ) ;
2014-05-12 20:08:19 +02:00
return replaceValue . apply ( this , args ) ;
} ;
return str _replace . call ( this , searchValue , wrappedReplaceValue ) ;
}
} ;
}
// ECMA-262, 3rd B.2.3
2014-06-06 14:29:32 +02:00
// Not an ECMAScript standard, although ECMAScript 3rd Edition has a
2014-05-12 20:08:19 +02:00
// 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
2014-08-10 12:02:48 +02:00
var string _substr = StringPrototype . substr ;
2016-05-16 13:33:49 +02:00
var hasNegativeSubstrBug = '' . substr && '0b' . substr ( - 1 ) !== 'b' ;
2014-08-10 12:02:48 +02:00
defineProperties ( StringPrototype , {
substr : function substr ( start , length ) {
2016-05-16 13:33:49 +02:00
var normalizedStart = start ;
if ( start < 0 ) {
normalizedStart = max ( this . length + start , 0 ) ;
}
return string _substr . call ( this , normalizedStart , length ) ;
2014-08-10 12:02:48 +02:00
}
} , hasNegativeSubstrBug ) ;
2014-05-12 20:08:19 +02:00
// ES5 15.5.4.20
// whitespace from: http://es5.github.io/#x15.5.4.20
2016-05-16 13:33:49 +02:00
var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
'\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
'\u2029\uFEFF' ;
2014-05-12 20:08:19 +02:00
var zeroWidth = '\u200b' ;
2016-05-16 13:33:49 +02:00
var wsRegexChars = '[' + ws + ']' ;
var trimBeginRegexp = new RegExp ( '^' + wsRegexChars + wsRegexChars + '*' ) ;
var trimEndRegexp = new RegExp ( wsRegexChars + wsRegexChars + '*$' ) ;
2014-08-10 12:02:48 +02:00
var hasTrimWhitespaceBug = StringPrototype . trim && ( ws . trim ( ) || ! zeroWidth . trim ( ) ) ;
defineProperties ( StringPrototype , {
2014-05-12 20:08:19 +02:00
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
// http://perfectionkills.com/whitespace-deviations/
2014-08-10 12:02:48 +02:00
trim : function trim ( ) {
2016-05-16 13:33:49 +02:00
if ( typeof this === 'undefined' || this === null ) {
throw new TypeError ( "can't convert " + this + ' to object' ) ;
2014-05-12 20:08:19 +02:00
}
2016-05-16 13:33:49 +02:00
return $String ( this ) . replace ( trimBeginRegexp , '' ) . replace ( trimEndRegexp , '' ) ;
2014-08-10 12:02:48 +02:00
}
} , hasTrimWhitespaceBug ) ;
2016-05-16 13:33:49 +02:00
var trim = call . bind ( String . prototype . trim ) ;
var hasLastIndexBug = StringPrototype . lastIndexOf && 'abcあい' . lastIndexOf ( 'あい' , 2 ) !== - 1 ;
defineProperties ( StringPrototype , {
lastIndexOf : function lastIndexOf ( searchString ) {
if ( typeof this === 'undefined' || this === null ) {
throw new TypeError ( "can't convert " + this + ' to object' ) ;
}
var S = $String ( this ) ;
var searchStr = $String ( searchString ) ;
var numPos = arguments . length > 1 ? $Number ( arguments [ 1 ] ) : NaN ;
var pos = isActualNaN ( numPos ) ? Infinity : ES . ToInteger ( numPos ) ;
var start = min ( max ( pos , 0 ) , S . length ) ;
var searchLen = searchStr . length ;
var k = start + searchLen ;
while ( k > 0 ) {
k = max ( 0 , k - searchLen ) ;
var index = strIndexOf ( strSlice ( S , k , start + searchLen ) , searchStr ) ;
if ( index !== - 1 ) {
return k + index ;
}
}
return - 1 ;
}
} , hasLastIndexBug ) ;
var originalLastIndexOf = StringPrototype . lastIndexOf ;
defineProperties ( StringPrototype , {
lastIndexOf : function lastIndexOf ( searchString ) {
return originalLastIndexOf . apply ( this , arguments ) ;
}
} , StringPrototype . lastIndexOf . length !== 1 ) ;
2014-05-12 20:08:19 +02:00
// ES-5 15.1.2.2
2016-05-16 13:33:49 +02:00
/* eslint-disable radix */
2014-05-12 20:08:19 +02:00
if ( parseInt ( ws + '08' ) !== 8 || parseInt ( ws + '0x16' ) !== 22 ) {
2016-05-16 13:33:49 +02:00
/* eslint-enable radix */
/* global parseInt: true */
2014-05-12 20:08:19 +02:00
parseInt = ( function ( origParseInt ) {
2016-05-16 13:33:49 +02:00
var hexRegex = /^[\-+]?0[xX]/ ;
return function parseInt ( str , radix ) {
var string = trim ( str ) ;
var defaultedRadix = $Number ( radix ) || ( hexRegex . test ( string ) ? 16 : 10 ) ;
return origParseInt ( string , defaultedRadix ) ;
2014-05-12 20:08:19 +02:00
} ;
} ( parseInt ) ) ;
}
2016-05-16 13:33:49 +02:00
// https://es5.github.io/#x15.1.2.3
if ( 1 / parseFloat ( '-0' ) !== - Infinity ) {
/* global parseFloat: true */
parseFloat = ( function ( origParseFloat ) {
return function parseFloat ( string ) {
var inputString = trim ( string ) ;
var result = origParseFloat ( inputString ) ;
return result === 0 && strSlice ( inputString , 0 , 1 ) === '-' ? - 0 : result ;
} ;
} ( parseFloat ) ) ;
}
if ( String ( new RangeError ( 'test' ) ) !== 'RangeError: test' ) {
var errorToStringShim = function toString ( ) {
if ( typeof this === 'undefined' || this === null ) {
throw new TypeError ( "can't convert " + this + ' to object' ) ;
}
var name = this . name ;
if ( typeof name === 'undefined' ) {
name = 'Error' ;
} else if ( typeof name !== 'string' ) {
name = $String ( name ) ;
}
var msg = this . message ;
if ( typeof msg === 'undefined' ) {
msg = '' ;
} else if ( typeof msg !== 'string' ) {
msg = $String ( msg ) ;
}
if ( ! name ) {
return msg ;
}
if ( ! msg ) {
return name ;
}
return name + ': ' + msg ;
} ;
// can't use defineProperties here because of toString enumeration issue in IE <= 8
Error . prototype . toString = errorToStringShim ;
}
if ( supportsDescriptors ) {
var ensureNonEnumerable = function ( obj , prop ) {
if ( isEnum ( obj , prop ) ) {
var desc = Object . getOwnPropertyDescriptor ( obj , prop ) ;
if ( desc . configurable ) {
desc . enumerable = false ;
Object . defineProperty ( obj , prop , desc ) ;
}
}
} ;
ensureNonEnumerable ( Error . prototype , 'message' ) ;
if ( Error . prototype . message !== '' ) {
Error . prototype . message = '' ;
}
ensureNonEnumerable ( Error . prototype , 'name' ) ;
}
if ( String ( /a/mig ) !== '/a/gim' ) {
var regexToString = function toString ( ) {
var str = '/' + this . source + '/' ;
if ( this . global ) {
str += 'g' ;
}
if ( this . ignoreCase ) {
str += 'i' ;
}
if ( this . multiline ) {
str += 'm' ;
}
return str ;
} ;
// can't use defineProperties here because of toString enumeration issue in IE <= 8
RegExp . prototype . toString = regexToString ;
}
2014-05-12 20:08:19 +02:00
} ) ) ;