// https://github.com/kriskowal/es5-shim // Copyright 2009-2012 by contributors, MIT License define(function(require, exports, module) { /* * 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/ */ // // Function // ======== // // 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("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 var args = slice.call(arguments, 1); // for normal call // 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. var bound = 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. var result = target.apply( this, args.concat(slice.call(arguments)) ); if (Object(result) === result) { 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) return target.apply( that, args.concat(slice.call(arguments)) ); } }; 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 // 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 // specified in 15.3.5.1. // 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; }; } // Shortcut to an often accessed properties, in order to avoid multiple // dereference that costs universally. // _Please note: Shortcuts are defined after `Function.prototype.bind` as we // us it in defining shortcuts. var call = Function.prototype.call; var prototypeOfArray = Array.prototype; var prototypeOfObject = Object.prototype; var slice = prototypeOfArray.slice; // 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. var defineGetter; var defineSetter; var lookupGetter; var lookupSetter; var supportsAccessors; if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { defineGetter = call.bind(prototypeOfObject.__defineGetter__); defineSetter = call.bind(prototypeOfObject.__defineSetter__); lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); } // // Array // ===== // // 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) { if(function() { // test IE < 9 to splice bug - see issue #138 function makeArray(l) { var a = new Array(l+2); a[0] = a[1] = 0; return a; } var array = [], lengthBefore; array.splice.apply(array, makeArray(20)); array.splice.apply(array, makeArray(26)); lengthBefore = array.length; //46 array.splice(5, 0, "XXX"); // add one element lengthBefore + 1 == array.length if (lengthBefore + 1 == array.length) { return true;// has right splice implementation without bugs } // else { // IE8 bug // } }()) {//IE 6/7 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))) } }; } else {//IE8 // taken from http://docs.sencha.com/ext-js/4-1/source/Array2.html Array.prototype.splice = function(pos, removeCount){ var length = this.length; if (pos > 0) { if (pos > length) pos = length; } else if (pos == void 0) { pos = 0; } else if (pos < 0) { pos = Math.max(length + pos, 0); } if (!(pos+removeCount < length)) removeCount = length - pos; var removed = this.slice(pos, pos+removeCount); var insert = slice.call(arguments, 2); var add = insert.length; // we try to use Array.push when we can for efficiency... if (pos === length) { if (add) { this.push.apply(this, insert); } } else { var remove = Math.min(removeCount, length - pos); var tailOldPos = pos + remove; var tailNewPos = tailOldPos + add - remove; var tailCount = length - tailOldPos; var lengthAfterRemove = length - remove; if (tailNewPos < tailOldPos) { // case A for (var i = 0; i < tailCount; ++i) { this[tailNewPos+i] = this[tailOldPos+i]; } } else if (tailNewPos > tailOldPos) { // case B for (i = tailCount; i--; ) { this[tailNewPos+i] = this[tailOldPos+i]; } } // else, add == remove (nothing to do) if (add && pos === lengthAfterRemove) { this.length = lengthAfterRemove; // truncate array this.push.apply(this, insert); } else { this.length = lengthAfterRemove + add; // reserves space for (i = 0; i < add; ++i) { this[pos+i] = insert[i]; } } } return removed; }; } } // 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]"; }; } // 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) var boxedString = Object("a"), splitString = boxedString[0] != "a" || !(0 in boxedString); if (!Array.prototype.forEach) { Array.prototype.forEach = function forEach(fun /*, thisp*/) { var object = toObject(this), self = splitString && _toString(this) == "[object String]" ? this.split("") : object, thisp = arguments[1], i = -1, 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 } 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, object); } } }; } // 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 if (!Array.prototype.map) { Array.prototype.map = function map(fun /*, thisp*/) { 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(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self) result[i] = fun.call(thisp, self[i], i, object); } return result; }; } // 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 if (!Array.prototype.filter) { Array.prototype.filter = function filter(fun /*, thisp */) { 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(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self) { value = self[i]; if (fun.call(thisp, value, i, object)) { result.push(value); } } } return result; }; } // ES5 15.4.4.16 // http://es5.github.com/#x15.4.4.16 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every if (!Array.prototype.every) { Array.prototype.every = function every(fun /*, thisp */) { 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(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self && !fun.call(thisp, self[i], i, object)) { return false; } } return true; }; } // ES5 15.4.4.17 // http://es5.github.com/#x15.4.4.17 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some if (!Array.prototype.some) { Array.prototype.some = function some(fun /*, thisp */) { 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(fun + " is not a function"); } for (var i = 0; i < length; i++) { if (i in self && fun.call(thisp, self[i], i, object)) { return true; } } return false; }; } // 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 if (!Array.prototype.reduce) { Array.prototype.reduce = function reduce(fun /*, initial*/) { 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(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("reduce of empty array with no initial value"); } 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) { 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, object); } } return result; }; } // 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 if (!Array.prototype.reduceRight) { Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { 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(fun + " is not a function"); } // no value to return if no initial value, empty array 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) { 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) { 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, object); } } while (i--); return result; }; } // 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 || ([0, 1].indexOf(1, 2) != -1)) { Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = 0; if (arguments.length > 1) { i = toInteger(arguments[1]); } // handle negative indices i = i >= 0 ? i : Math.max(0, length + i); for (; i < length; i++) { if (i in self && self[i] === sought) { return i; } } return -1; }; } // 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 || ([0, 1].lastIndexOf(0, -3) != -1)) { Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { var self = splitString && _toString(this) == "[object String]" ? this.split("") : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = 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]) { return i; } } return -1; }; } // // Object // ====== // // ES5 15.2.3.2 // http://es5.github.com/#x15.2.3.2 if (!Object.getPrototypeOf) { // https://github.com/kriskowal/es5-shim/issues#issue/2 // http://ejohn.org/blog/objectgetprototypeof/ // recommended by fschaefer on github Object.getPrototypeOf = function getPrototypeOf(object) { return object.__proto__ || ( object.constructor ? object.constructor.prototype : prototypeOfObject ); }; } // ES5 15.2.3.3 // http://es5.github.com/#x15.2.3.3 if (!Object.getOwnPropertyDescriptor) { var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " + "non-object: "; Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { if ((typeof object != "object" && typeof object != "function") || object === null) throw new TypeError(ERR_NON_OBJECT + object); // If object does not owns property return undefined immediately. if (!owns(object, property)) return; var descriptor, getter, setter; // If object has a property then it's for sure both `enumerable` and // `configurable`. descriptor = { enumerable: true, configurable: true }; // If JS engine supports accessor properties then property may be a // getter or setter. if (supportsAccessors) { // Unfortunately `__lookupGetter__` will return a getter even // if object has own non getter property along with a same named // inherited getter. To avoid misbehavior we temporary remove // `__proto__` so that `__lookupGetter__` will return getter only // if it's owned by an object. var prototype = object.__proto__; object.__proto__ = prototypeOfObject; var getter = lookupGetter(object, property); var setter = lookupSetter(object, property); // Once we have getter and setter we can put values back. object.__proto__ = prototype; if (getter || setter) { if (getter) descriptor.get = getter; if (setter) descriptor.set = setter; // If it was accessor property we're done and return here // in order to avoid adding `value` to the descriptor. return descriptor; } } // If we got this far we know that object has an own property that is // not an accessor so we set it as a value and return descriptor. descriptor.value = object[property]; return descriptor; }; } // ES5 15.2.3.4 // http://es5.github.com/#x15.2.3.4 if (!Object.getOwnPropertyNames) { Object.getOwnPropertyNames = function getOwnPropertyNames(object) { return Object.keys(object); }; } // ES5 15.2.3.5 // http://es5.github.com/#x15.2.3.5 if (!Object.create) { var createEmpty; if (Object.prototype.__proto__ === null) { createEmpty = function () { return { "__proto__": null }; }; } else { // In old IE __proto__ can't be used to manually set `null` createEmpty = function () { var empty = {}; for (var i in empty) empty[i] = null; empty.constructor = empty.hasOwnProperty = empty.propertyIsEnumerable = empty.isPrototypeOf = empty.toLocaleString = empty.toString = empty.valueOf = empty.__proto__ = null; return empty; } } Object.create = function create(prototype, properties) { var object; if (prototype === null) { object = createEmpty(); } else { if (typeof prototype != "object") throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); var Type = function () {}; Type.prototype = prototype; object = new Type(); // IE has no built-in implementation of `Object.getPrototypeOf` // neither `__proto__`, but this manually setting `__proto__` will // guarantee that `Object.getPrototypeOf` will work as expected with // objects created using `Object.create` object.__proto__ = prototype; } if (properties !== void 0) Object.defineProperties(object, properties); return object; }; } // ES5 15.2.3.6 // http://es5.github.com/#x15.2.3.6 // Patch for WebKit and IE8 standard mode // Designed by hax // related issue: https://github.com/kriskowal/es5-shim/issues#issue/5 // IE8 Reference: // http://msdn.microsoft.com/en-us/library/dd282900.aspx // http://msdn.microsoft.com/en-us/library/dd229916.aspx // WebKit Bugs: // https://bugs.webkit.org/show_bug.cgi?id=36423 function doesDefinePropertyWork(object) { try { Object.defineProperty(object, "sentinel", {}); return "sentinel" in object; } catch (exception) { // returns falsy } } // check whether defineProperty works if it's given. Otherwise, // shim partially. if (Object.defineProperty) { var definePropertyWorksOnObject = doesDefinePropertyWork({}); var definePropertyWorksOnDom = typeof document == "undefined" || doesDefinePropertyWork(document.createElement("div")); if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { var definePropertyFallback = Object.defineProperty; } } if (!Object.defineProperty || definePropertyFallback) { var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + "on this javascript engine"; Object.defineProperty = function defineProperty(object, property, descriptor) { if ((typeof object != "object" && typeof object != "function") || object === null) throw new TypeError(ERR_NON_OBJECT_TARGET + object); if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); // make a valiant attempt to use the real defineProperty // for I8's DOM elements. if (definePropertyFallback) { try { return definePropertyFallback.call(Object, object, property, descriptor); } catch (exception) { // try the shim if the real one doesn't work } } // If it's a data property. if (owns(descriptor, "value")) { // fail silently if "writable", "enumerable", or "configurable" // are requested but not supported /* // alternate approach: if ( // can't implement these features; allow false but not true !(owns(descriptor, "writable") ? descriptor.writable : true) || !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) || !(owns(descriptor, "configurable") ? descriptor.configurable : true) ) throw new RangeError( "This implementation of Object.defineProperty does not " + "support configurable, enumerable, or writable." ); */ if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) { // As accessors are supported only on engines implementing // `__proto__` we can safely override `__proto__` while defining // a property to make sure that we don't hit an inherited // accessor. var prototype = object.__proto__; object.__proto__ = prototypeOfObject; // Deleting a property anyway since getter / setter may be // defined on object itself. delete object[property]; object[property] = descriptor.value; // Setting original `__proto__` back now. object.__proto__ = prototype; } else { object[property] = descriptor.value; } } else { if (!supportsAccessors) throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); // If we got that far then getters and setters can be defined !! if (owns(descriptor, "get")) defineGetter(object, property, descriptor.get); if (owns(descriptor, "set")) defineSetter(object, property, descriptor.set); } return object; }; } // ES5 15.2.3.7 // http://es5.github.com/#x15.2.3.7 if (!Object.defineProperties) { Object.defineProperties = function defineProperties(object, properties) { for (var property in properties) { if (owns(properties, property)) Object.defineProperty(object, property, properties[property]); } return object; }; } // ES5 15.2.3.8 // http://es5.github.com/#x15.2.3.8 if (!Object.seal) { Object.seal = function seal(object) { // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // ES5 15.2.3.9 // http://es5.github.com/#x15.2.3.9 if (!Object.freeze) { Object.freeze = function freeze(object) { // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // detect a Rhino bug and patch it try { Object.freeze(function () {}); } catch (exception) { Object.freeze = (function freeze(freezeObject) { return function freeze(object) { if (typeof object == "function") { return object; } else { return freezeObject(object); } }; })(Object.freeze); } // ES5 15.2.3.10 // http://es5.github.com/#x15.2.3.10 if (!Object.preventExtensions) { Object.preventExtensions = function preventExtensions(object) { // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // ES5 15.2.3.11 // http://es5.github.com/#x15.2.3.11 if (!Object.isSealed) { Object.isSealed = function isSealed(object) { return false; }; } // ES5 15.2.3.12 // http://es5.github.com/#x15.2.3.12 if (!Object.isFrozen) { Object.isFrozen = function isFrozen(object) { return false; }; } // ES5 15.2.3.13 // http://es5.github.com/#x15.2.3.13 if (!Object.isExtensible) { Object.isExtensible = function isExtensible(object) { // 1. If Type(O) is not Object throw a TypeError exception. if (Object(object) === object) { throw new TypeError(); // TODO message } // 2. Return the Boolean value of the [[Extensible]] internal property of O. var name = ''; while (owns(object, name)) { name += '?'; } object[name] = true; var returnValue = owns(object, name); delete object[name]; return returnValue; }; } // ES5 15.2.3.14 // http://es5.github.com/#x15.2.3.14 if (!Object.keys) { // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation var hasDontEnumBug = true, dontEnums = [ "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "constructor" ], dontEnumsLength = dontEnums.length; for (var key in {"toString": null}) { hasDontEnumBug = false; } Object.keys = function keys(object) { 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) { if (owns(object, name)) { keys.push(name); } } if (hasDontEnumBug) { for (var i = 0, ii = dontEnumsLength; i < ii; i++) { var dontEnum = dontEnums[i]; if (owns(object, dontEnum)) { keys.push(dontEnum); } } } return keys; }; } // // most of es5-shim Date section is removed since ace doesn't need it, it is too intrusive and it causes problems for users // ==== // // 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.20 // http://es5.github.com/#x15.5.4.20 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"; if (!String.prototype.trim || ws.trim()) { // http://blog.stevenlevithan.com/archives/faster-trim-javascript // http://perfectionkills.com/whitespace-deviations/ ws = "[" + ws + "]"; var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), trimEndRegexp = new RegExp(ws + ws + "*$"); String.prototype.trim = function trim() { return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); }; } // // Util // ====== // // ES5 9.4 // http://es5.github.com/#x9.4 // http://jsperf.com/to-integer function toInteger(n) { n = +n; if (n !== n) { // isNaN n = 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); }; });