es5-shim.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. // https://github.com/kriskowal/es5-shim
  2. // Copyright 2009-2012 by contributors, MIT License
  3. define(function(require, exports, module) {
  4. /*
  5. * Brings an environment as close to ECMAScript 5 compliance
  6. * as is possible with the facilities of erstwhile engines.
  7. *
  8. * Annotated ES5: http://es5.github.com/ (specific links below)
  9. * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
  10. * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
  11. */
  12. //
  13. // Function
  14. // ========
  15. //
  16. // ES-5 15.3.4.5
  17. // http://es5.github.com/#x15.3.4.5
  18. function Empty() {}
  19. if (!Function.prototype.bind) {
  20. Function.prototype.bind = function bind(that) { // .length is 1
  21. // 1. Let Target be the this value.
  22. var target = this;
  23. // 2. If IsCallable(Target) is false, throw a TypeError exception.
  24. if (typeof target != "function") {
  25. throw new TypeError("Function.prototype.bind called on incompatible " + target);
  26. }
  27. // 3. Let A be a new (possibly empty) internal list of all of the
  28. // argument values provided after thisArg (arg1, arg2 etc), in order.
  29. // XXX slicedArgs will stand in for "A" if used
  30. var args = slice.call(arguments, 1); // for normal call
  31. // 4. Let F be a new native ECMAScript object.
  32. // 11. Set the [[Prototype]] internal property of F to the standard
  33. // built-in Function prototype object as specified in 15.3.3.1.
  34. // 12. Set the [[Call]] internal property of F as described in
  35. // 15.3.4.5.1.
  36. // 13. Set the [[Construct]] internal property of F as described in
  37. // 15.3.4.5.2.
  38. // 14. Set the [[HasInstance]] internal property of F as described in
  39. // 15.3.4.5.3.
  40. var bound = function () {
  41. if (this instanceof bound) {
  42. // 15.3.4.5.2 [[Construct]]
  43. // When the [[Construct]] internal method of a function object,
  44. // F that was created using the bind function is called with a
  45. // list of arguments ExtraArgs, the following steps are taken:
  46. // 1. Let target be the value of F's [[TargetFunction]]
  47. // internal property.
  48. // 2. If target has no [[Construct]] internal method, a
  49. // TypeError exception is thrown.
  50. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
  51. // property.
  52. // 4. Let args be a new list containing the same values as the
  53. // list boundArgs in the same order followed by the same
  54. // values as the list ExtraArgs in the same order.
  55. // 5. Return the result of calling the [[Construct]] internal
  56. // method of target providing args as the arguments.
  57. var result = target.apply(
  58. this,
  59. args.concat(slice.call(arguments))
  60. );
  61. if (Object(result) === result) {
  62. return result;
  63. }
  64. return this;
  65. } else {
  66. // 15.3.4.5.1 [[Call]]
  67. // When the [[Call]] internal method of a function object, F,
  68. // which was created using the bind function is called with a
  69. // this value and a list of arguments ExtraArgs, the following
  70. // steps are taken:
  71. // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
  72. // property.
  73. // 2. Let boundThis be the value of F's [[BoundThis]] internal
  74. // property.
  75. // 3. Let target be the value of F's [[TargetFunction]] internal
  76. // property.
  77. // 4. Let args be a new list containing the same values as the
  78. // list boundArgs in the same order followed by the same
  79. // values as the list ExtraArgs in the same order.
  80. // 5. Return the result of calling the [[Call]] internal method
  81. // of target providing boundThis as the this value and
  82. // providing args as the arguments.
  83. // equiv: target.call(this, ...boundArgs, ...args)
  84. return target.apply(
  85. that,
  86. args.concat(slice.call(arguments))
  87. );
  88. }
  89. };
  90. if(target.prototype) {
  91. Empty.prototype = target.prototype;
  92. bound.prototype = new Empty();
  93. // Clean up dangling references.
  94. Empty.prototype = null;
  95. }
  96. // XXX bound.length is never writable, so don't even try
  97. //
  98. // 15. If the [[Class]] internal property of Target is "Function", then
  99. // a. Let L be the length property of Target minus the length of A.
  100. // b. Set the length own property of F to either 0 or L, whichever is
  101. // larger.
  102. // 16. Else set the length own property of F to 0.
  103. // 17. Set the attributes of the length own property of F to the values
  104. // specified in 15.3.5.1.
  105. // TODO
  106. // 18. Set the [[Extensible]] internal property of F to true.
  107. // TODO
  108. // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
  109. // 20. Call the [[DefineOwnProperty]] internal method of F with
  110. // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
  111. // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
  112. // false.
  113. // 21. Call the [[DefineOwnProperty]] internal method of F with
  114. // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
  115. // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
  116. // and false.
  117. // TODO
  118. // NOTE Function objects created using Function.prototype.bind do not
  119. // have a prototype property or the [[Code]], [[FormalParameters]], and
  120. // [[Scope]] internal properties.
  121. // XXX can't delete prototype in pure-js.
  122. // 22. Return F.
  123. return bound;
  124. };
  125. }
  126. // Shortcut to an often accessed properties, in order to avoid multiple
  127. // dereference that costs universally.
  128. // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
  129. // us it in defining shortcuts.
  130. var call = Function.prototype.call;
  131. var prototypeOfArray = Array.prototype;
  132. var prototypeOfObject = Object.prototype;
  133. var slice = prototypeOfArray.slice;
  134. // Having a toString local variable name breaks in Opera so use _toString.
  135. var _toString = call.bind(prototypeOfObject.toString);
  136. var owns = call.bind(prototypeOfObject.hasOwnProperty);
  137. // If JS engine supports accessors creating shortcuts.
  138. var defineGetter;
  139. var defineSetter;
  140. var lookupGetter;
  141. var lookupSetter;
  142. var supportsAccessors;
  143. if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
  144. defineGetter = call.bind(prototypeOfObject.__defineGetter__);
  145. defineSetter = call.bind(prototypeOfObject.__defineSetter__);
  146. lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
  147. lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
  148. }
  149. //
  150. // Array
  151. // =====
  152. //
  153. // ES5 15.4.4.12
  154. // http://es5.github.com/#x15.4.4.12
  155. // Default value for second param
  156. // [bugfix, ielt9, old browsers]
  157. // IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12"
  158. if ([1,2].splice(0).length != 2) {
  159. if(function() { // test IE < 9 to splice bug - see issue #138
  160. function makeArray(l) {
  161. var a = new Array(l+2);
  162. a[0] = a[1] = 0;
  163. return a;
  164. }
  165. var array = [], lengthBefore;
  166. array.splice.apply(array, makeArray(20));
  167. array.splice.apply(array, makeArray(26));
  168. lengthBefore = array.length; //46
  169. array.splice(5, 0, "XXX"); // add one element
  170. lengthBefore + 1 == array.length
  171. if (lengthBefore + 1 == array.length) {
  172. return true;// has right splice implementation without bugs
  173. }
  174. // else {
  175. // IE8 bug
  176. // }
  177. }()) {//IE 6/7
  178. var array_splice = Array.prototype.splice;
  179. Array.prototype.splice = function(start, deleteCount) {
  180. if (!arguments.length) {
  181. return [];
  182. } else {
  183. return array_splice.apply(this, [
  184. start === void 0 ? 0 : start,
  185. deleteCount === void 0 ? (this.length - start) : deleteCount
  186. ].concat(slice.call(arguments, 2)))
  187. }
  188. };
  189. } else {//IE8
  190. // taken from http://docs.sencha.com/ext-js/4-1/source/Array2.html
  191. Array.prototype.splice = function(pos, removeCount){
  192. var length = this.length;
  193. if (pos > 0) {
  194. if (pos > length)
  195. pos = length;
  196. } else if (pos == void 0) {
  197. pos = 0;
  198. } else if (pos < 0) {
  199. pos = Math.max(length + pos, 0);
  200. }
  201. if (!(pos+removeCount < length))
  202. removeCount = length - pos;
  203. var removed = this.slice(pos, pos+removeCount);
  204. var insert = slice.call(arguments, 2);
  205. var add = insert.length;
  206. // we try to use Array.push when we can for efficiency...
  207. if (pos === length) {
  208. if (add) {
  209. this.push.apply(this, insert);
  210. }
  211. } else {
  212. var remove = Math.min(removeCount, length - pos);
  213. var tailOldPos = pos + remove;
  214. var tailNewPos = tailOldPos + add - remove;
  215. var tailCount = length - tailOldPos;
  216. var lengthAfterRemove = length - remove;
  217. if (tailNewPos < tailOldPos) { // case A
  218. for (var i = 0; i < tailCount; ++i) {
  219. this[tailNewPos+i] = this[tailOldPos+i];
  220. }
  221. } else if (tailNewPos > tailOldPos) { // case B
  222. for (i = tailCount; i--; ) {
  223. this[tailNewPos+i] = this[tailOldPos+i];
  224. }
  225. } // else, add == remove (nothing to do)
  226. if (add && pos === lengthAfterRemove) {
  227. this.length = lengthAfterRemove; // truncate array
  228. this.push.apply(this, insert);
  229. } else {
  230. this.length = lengthAfterRemove + add; // reserves space
  231. for (i = 0; i < add; ++i) {
  232. this[pos+i] = insert[i];
  233. }
  234. }
  235. }
  236. return removed;
  237. };
  238. }
  239. }
  240. // ES5 15.4.3.2
  241. // http://es5.github.com/#x15.4.3.2
  242. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
  243. if (!Array.isArray) {
  244. Array.isArray = function isArray(obj) {
  245. return _toString(obj) == "[object Array]";
  246. };
  247. }
  248. // The IsCallable() check in the Array functions
  249. // has been replaced with a strict check on the
  250. // internal class of the object to trap cases where
  251. // the provided function was actually a regular
  252. // expression literal, which in V8 and
  253. // JavaScriptCore is a typeof "function". Only in
  254. // V8 are regular expression literals permitted as
  255. // reduce parameters, so it is desirable in the
  256. // general case for the shim to match the more
  257. // strict and common behavior of rejecting regular
  258. // expressions.
  259. // ES5 15.4.4.18
  260. // http://es5.github.com/#x15.4.4.18
  261. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
  262. // Check failure of by-index access of string characters (IE < 9)
  263. // and failure of `0 in boxedString` (Rhino)
  264. var boxedString = Object("a"),
  265. splitString = boxedString[0] != "a" || !(0 in boxedString);
  266. if (!Array.prototype.forEach) {
  267. Array.prototype.forEach = function forEach(fun /*, thisp*/) {
  268. var object = toObject(this),
  269. self = splitString && _toString(this) == "[object String]" ?
  270. this.split("") :
  271. object,
  272. thisp = arguments[1],
  273. i = -1,
  274. length = self.length >>> 0;
  275. // If no callback function or if callback is not a callable function
  276. if (_toString(fun) != "[object Function]") {
  277. throw new TypeError(); // TODO message
  278. }
  279. while (++i < length) {
  280. if (i in self) {
  281. // Invoke the callback function with call, passing arguments:
  282. // context, property value, property key, thisArg object
  283. // context
  284. fun.call(thisp, self[i], i, object);
  285. }
  286. }
  287. };
  288. }
  289. // ES5 15.4.4.19
  290. // http://es5.github.com/#x15.4.4.19
  291. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  292. if (!Array.prototype.map) {
  293. Array.prototype.map = function map(fun /*, thisp*/) {
  294. var object = toObject(this),
  295. self = splitString && _toString(this) == "[object String]" ?
  296. this.split("") :
  297. object,
  298. length = self.length >>> 0,
  299. result = Array(length),
  300. thisp = arguments[1];
  301. // If no callback function or if callback is not a callable function
  302. if (_toString(fun) != "[object Function]") {
  303. throw new TypeError(fun + " is not a function");
  304. }
  305. for (var i = 0; i < length; i++) {
  306. if (i in self)
  307. result[i] = fun.call(thisp, self[i], i, object);
  308. }
  309. return result;
  310. };
  311. }
  312. // ES5 15.4.4.20
  313. // http://es5.github.com/#x15.4.4.20
  314. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  315. if (!Array.prototype.filter) {
  316. Array.prototype.filter = function filter(fun /*, thisp */) {
  317. var object = toObject(this),
  318. self = splitString && _toString(this) == "[object String]" ?
  319. this.split("") :
  320. object,
  321. length = self.length >>> 0,
  322. result = [],
  323. value,
  324. thisp = arguments[1];
  325. // If no callback function or if callback is not a callable function
  326. if (_toString(fun) != "[object Function]") {
  327. throw new TypeError(fun + " is not a function");
  328. }
  329. for (var i = 0; i < length; i++) {
  330. if (i in self) {
  331. value = self[i];
  332. if (fun.call(thisp, value, i, object)) {
  333. result.push(value);
  334. }
  335. }
  336. }
  337. return result;
  338. };
  339. }
  340. // ES5 15.4.4.16
  341. // http://es5.github.com/#x15.4.4.16
  342. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
  343. if (!Array.prototype.every) {
  344. Array.prototype.every = function every(fun /*, thisp */) {
  345. var object = toObject(this),
  346. self = splitString && _toString(this) == "[object String]" ?
  347. this.split("") :
  348. object,
  349. length = self.length >>> 0,
  350. thisp = arguments[1];
  351. // If no callback function or if callback is not a callable function
  352. if (_toString(fun) != "[object Function]") {
  353. throw new TypeError(fun + " is not a function");
  354. }
  355. for (var i = 0; i < length; i++) {
  356. if (i in self && !fun.call(thisp, self[i], i, object)) {
  357. return false;
  358. }
  359. }
  360. return true;
  361. };
  362. }
  363. // ES5 15.4.4.17
  364. // http://es5.github.com/#x15.4.4.17
  365. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
  366. if (!Array.prototype.some) {
  367. Array.prototype.some = function some(fun /*, thisp */) {
  368. var object = toObject(this),
  369. self = splitString && _toString(this) == "[object String]" ?
  370. this.split("") :
  371. object,
  372. length = self.length >>> 0,
  373. thisp = arguments[1];
  374. // If no callback function or if callback is not a callable function
  375. if (_toString(fun) != "[object Function]") {
  376. throw new TypeError(fun + " is not a function");
  377. }
  378. for (var i = 0; i < length; i++) {
  379. if (i in self && fun.call(thisp, self[i], i, object)) {
  380. return true;
  381. }
  382. }
  383. return false;
  384. };
  385. }
  386. // ES5 15.4.4.21
  387. // http://es5.github.com/#x15.4.4.21
  388. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
  389. if (!Array.prototype.reduce) {
  390. Array.prototype.reduce = function reduce(fun /*, initial*/) {
  391. var object = toObject(this),
  392. self = splitString && _toString(this) == "[object String]" ?
  393. this.split("") :
  394. object,
  395. length = self.length >>> 0;
  396. // If no callback function or if callback is not a callable function
  397. if (_toString(fun) != "[object Function]") {
  398. throw new TypeError(fun + " is not a function");
  399. }
  400. // no value to return if no initial value and an empty array
  401. if (!length && arguments.length == 1) {
  402. throw new TypeError("reduce of empty array with no initial value");
  403. }
  404. var i = 0;
  405. var result;
  406. if (arguments.length >= 2) {
  407. result = arguments[1];
  408. } else {
  409. do {
  410. if (i in self) {
  411. result = self[i++];
  412. break;
  413. }
  414. // if array contains no values, no initial value to return
  415. if (++i >= length) {
  416. throw new TypeError("reduce of empty array with no initial value");
  417. }
  418. } while (true);
  419. }
  420. for (; i < length; i++) {
  421. if (i in self) {
  422. result = fun.call(void 0, result, self[i], i, object);
  423. }
  424. }
  425. return result;
  426. };
  427. }
  428. // ES5 15.4.4.22
  429. // http://es5.github.com/#x15.4.4.22
  430. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
  431. if (!Array.prototype.reduceRight) {
  432. Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
  433. var object = toObject(this),
  434. self = splitString && _toString(this) == "[object String]" ?
  435. this.split("") :
  436. object,
  437. length = self.length >>> 0;
  438. // If no callback function or if callback is not a callable function
  439. if (_toString(fun) != "[object Function]") {
  440. throw new TypeError(fun + " is not a function");
  441. }
  442. // no value to return if no initial value, empty array
  443. if (!length && arguments.length == 1) {
  444. throw new TypeError("reduceRight of empty array with no initial value");
  445. }
  446. var result, i = length - 1;
  447. if (arguments.length >= 2) {
  448. result = arguments[1];
  449. } else {
  450. do {
  451. if (i in self) {
  452. result = self[i--];
  453. break;
  454. }
  455. // if array contains no values, no initial value to return
  456. if (--i < 0) {
  457. throw new TypeError("reduceRight of empty array with no initial value");
  458. }
  459. } while (true);
  460. }
  461. do {
  462. if (i in this) {
  463. result = fun.call(void 0, result, self[i], i, object);
  464. }
  465. } while (i--);
  466. return result;
  467. };
  468. }
  469. // ES5 15.4.4.14
  470. // http://es5.github.com/#x15.4.4.14
  471. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
  472. if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
  473. Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
  474. var self = splitString && _toString(this) == "[object String]" ?
  475. this.split("") :
  476. toObject(this),
  477. length = self.length >>> 0;
  478. if (!length) {
  479. return -1;
  480. }
  481. var i = 0;
  482. if (arguments.length > 1) {
  483. i = toInteger(arguments[1]);
  484. }
  485. // handle negative indices
  486. i = i >= 0 ? i : Math.max(0, length + i);
  487. for (; i < length; i++) {
  488. if (i in self && self[i] === sought) {
  489. return i;
  490. }
  491. }
  492. return -1;
  493. };
  494. }
  495. // ES5 15.4.4.15
  496. // http://es5.github.com/#x15.4.4.15
  497. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
  498. if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
  499. Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
  500. var self = splitString && _toString(this) == "[object String]" ?
  501. this.split("") :
  502. toObject(this),
  503. length = self.length >>> 0;
  504. if (!length) {
  505. return -1;
  506. }
  507. var i = length - 1;
  508. if (arguments.length > 1) {
  509. i = Math.min(i, toInteger(arguments[1]));
  510. }
  511. // handle negative indices
  512. i = i >= 0 ? i : length - Math.abs(i);
  513. for (; i >= 0; i--) {
  514. if (i in self && sought === self[i]) {
  515. return i;
  516. }
  517. }
  518. return -1;
  519. };
  520. }
  521. //
  522. // Object
  523. // ======
  524. //
  525. // ES5 15.2.3.2
  526. // http://es5.github.com/#x15.2.3.2
  527. if (!Object.getPrototypeOf) {
  528. // https://github.com/kriskowal/es5-shim/issues#issue/2
  529. // http://ejohn.org/blog/objectgetprototypeof/
  530. // recommended by fschaefer on github
  531. Object.getPrototypeOf = function getPrototypeOf(object) {
  532. return object.__proto__ || (
  533. object.constructor ?
  534. object.constructor.prototype :
  535. prototypeOfObject
  536. );
  537. };
  538. }
  539. // ES5 15.2.3.3
  540. // http://es5.github.com/#x15.2.3.3
  541. if (!Object.getOwnPropertyDescriptor) {
  542. var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
  543. "non-object: ";
  544. Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
  545. if ((typeof object != "object" && typeof object != "function") || object === null)
  546. throw new TypeError(ERR_NON_OBJECT + object);
  547. // If object does not owns property return undefined immediately.
  548. if (!owns(object, property))
  549. return;
  550. var descriptor, getter, setter;
  551. // If object has a property then it's for sure both `enumerable` and
  552. // `configurable`.
  553. descriptor = { enumerable: true, configurable: true };
  554. // If JS engine supports accessor properties then property may be a
  555. // getter or setter.
  556. if (supportsAccessors) {
  557. // Unfortunately `__lookupGetter__` will return a getter even
  558. // if object has own non getter property along with a same named
  559. // inherited getter. To avoid misbehavior we temporary remove
  560. // `__proto__` so that `__lookupGetter__` will return getter only
  561. // if it's owned by an object.
  562. var prototype = object.__proto__;
  563. object.__proto__ = prototypeOfObject;
  564. var getter = lookupGetter(object, property);
  565. var setter = lookupSetter(object, property);
  566. // Once we have getter and setter we can put values back.
  567. object.__proto__ = prototype;
  568. if (getter || setter) {
  569. if (getter) descriptor.get = getter;
  570. if (setter) descriptor.set = setter;
  571. // If it was accessor property we're done and return here
  572. // in order to avoid adding `value` to the descriptor.
  573. return descriptor;
  574. }
  575. }
  576. // If we got this far we know that object has an own property that is
  577. // not an accessor so we set it as a value and return descriptor.
  578. descriptor.value = object[property];
  579. return descriptor;
  580. };
  581. }
  582. // ES5 15.2.3.4
  583. // http://es5.github.com/#x15.2.3.4
  584. if (!Object.getOwnPropertyNames) {
  585. Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
  586. return Object.keys(object);
  587. };
  588. }
  589. // ES5 15.2.3.5
  590. // http://es5.github.com/#x15.2.3.5
  591. if (!Object.create) {
  592. var createEmpty;
  593. if (Object.prototype.__proto__ === null) {
  594. createEmpty = function () {
  595. return { "__proto__": null };
  596. };
  597. } else {
  598. // In old IE __proto__ can't be used to manually set `null`
  599. createEmpty = function () {
  600. var empty = {};
  601. for (var i in empty)
  602. empty[i] = null;
  603. empty.constructor =
  604. empty.hasOwnProperty =
  605. empty.propertyIsEnumerable =
  606. empty.isPrototypeOf =
  607. empty.toLocaleString =
  608. empty.toString =
  609. empty.valueOf =
  610. empty.__proto__ = null;
  611. return empty;
  612. }
  613. }
  614. Object.create = function create(prototype, properties) {
  615. var object;
  616. if (prototype === null) {
  617. object = createEmpty();
  618. } else {
  619. if (typeof prototype != "object")
  620. throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
  621. var Type = function () {};
  622. Type.prototype = prototype;
  623. object = new Type();
  624. // IE has no built-in implementation of `Object.getPrototypeOf`
  625. // neither `__proto__`, but this manually setting `__proto__` will
  626. // guarantee that `Object.getPrototypeOf` will work as expected with
  627. // objects created using `Object.create`
  628. object.__proto__ = prototype;
  629. }
  630. if (properties !== void 0)
  631. Object.defineProperties(object, properties);
  632. return object;
  633. };
  634. }
  635. // ES5 15.2.3.6
  636. // http://es5.github.com/#x15.2.3.6
  637. // Patch for WebKit and IE8 standard mode
  638. // Designed by hax <hax.github.com>
  639. // related issue: https://github.com/kriskowal/es5-shim/issues#issue/5
  640. // IE8 Reference:
  641. // http://msdn.microsoft.com/en-us/library/dd282900.aspx
  642. // http://msdn.microsoft.com/en-us/library/dd229916.aspx
  643. // WebKit Bugs:
  644. // https://bugs.webkit.org/show_bug.cgi?id=36423
  645. function doesDefinePropertyWork(object) {
  646. try {
  647. Object.defineProperty(object, "sentinel", {});
  648. return "sentinel" in object;
  649. } catch (exception) {
  650. // returns falsy
  651. }
  652. }
  653. // check whether defineProperty works if it's given. Otherwise,
  654. // shim partially.
  655. if (Object.defineProperty) {
  656. var definePropertyWorksOnObject = doesDefinePropertyWork({});
  657. var definePropertyWorksOnDom = typeof document == "undefined" ||
  658. doesDefinePropertyWork(document.createElement("div"));
  659. if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
  660. var definePropertyFallback = Object.defineProperty;
  661. }
  662. }
  663. if (!Object.defineProperty || definePropertyFallback) {
  664. var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
  665. var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
  666. var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
  667. "on this javascript engine";
  668. Object.defineProperty = function defineProperty(object, property, descriptor) {
  669. if ((typeof object != "object" && typeof object != "function") || object === null)
  670. throw new TypeError(ERR_NON_OBJECT_TARGET + object);
  671. if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
  672. throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
  673. // make a valiant attempt to use the real defineProperty
  674. // for I8's DOM elements.
  675. if (definePropertyFallback) {
  676. try {
  677. return definePropertyFallback.call(Object, object, property, descriptor);
  678. } catch (exception) {
  679. // try the shim if the real one doesn't work
  680. }
  681. }
  682. // If it's a data property.
  683. if (owns(descriptor, "value")) {
  684. // fail silently if "writable", "enumerable", or "configurable"
  685. // are requested but not supported
  686. /*
  687. // alternate approach:
  688. if ( // can't implement these features; allow false but not true
  689. !(owns(descriptor, "writable") ? descriptor.writable : true) ||
  690. !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) ||
  691. !(owns(descriptor, "configurable") ? descriptor.configurable : true)
  692. )
  693. throw new RangeError(
  694. "This implementation of Object.defineProperty does not " +
  695. "support configurable, enumerable, or writable."
  696. );
  697. */
  698. if (supportsAccessors && (lookupGetter(object, property) ||
  699. lookupSetter(object, property)))
  700. {
  701. // As accessors are supported only on engines implementing
  702. // `__proto__` we can safely override `__proto__` while defining
  703. // a property to make sure that we don't hit an inherited
  704. // accessor.
  705. var prototype = object.__proto__;
  706. object.__proto__ = prototypeOfObject;
  707. // Deleting a property anyway since getter / setter may be
  708. // defined on object itself.
  709. delete object[property];
  710. object[property] = descriptor.value;
  711. // Setting original `__proto__` back now.
  712. object.__proto__ = prototype;
  713. } else {
  714. object[property] = descriptor.value;
  715. }
  716. } else {
  717. if (!supportsAccessors)
  718. throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
  719. // If we got that far then getters and setters can be defined !!
  720. if (owns(descriptor, "get"))
  721. defineGetter(object, property, descriptor.get);
  722. if (owns(descriptor, "set"))
  723. defineSetter(object, property, descriptor.set);
  724. }
  725. return object;
  726. };
  727. }
  728. // ES5 15.2.3.7
  729. // http://es5.github.com/#x15.2.3.7
  730. if (!Object.defineProperties) {
  731. Object.defineProperties = function defineProperties(object, properties) {
  732. for (var property in properties) {
  733. if (owns(properties, property))
  734. Object.defineProperty(object, property, properties[property]);
  735. }
  736. return object;
  737. };
  738. }
  739. // ES5 15.2.3.8
  740. // http://es5.github.com/#x15.2.3.8
  741. if (!Object.seal) {
  742. Object.seal = function seal(object) {
  743. // this is misleading and breaks feature-detection, but
  744. // allows "securable" code to "gracefully" degrade to working
  745. // but insecure code.
  746. return object;
  747. };
  748. }
  749. // ES5 15.2.3.9
  750. // http://es5.github.com/#x15.2.3.9
  751. if (!Object.freeze) {
  752. Object.freeze = function freeze(object) {
  753. // this is misleading and breaks feature-detection, but
  754. // allows "securable" code to "gracefully" degrade to working
  755. // but insecure code.
  756. return object;
  757. };
  758. }
  759. // detect a Rhino bug and patch it
  760. try {
  761. Object.freeze(function () {});
  762. } catch (exception) {
  763. Object.freeze = (function freeze(freezeObject) {
  764. return function freeze(object) {
  765. if (typeof object == "function") {
  766. return object;
  767. } else {
  768. return freezeObject(object);
  769. }
  770. };
  771. })(Object.freeze);
  772. }
  773. // ES5 15.2.3.10
  774. // http://es5.github.com/#x15.2.3.10
  775. if (!Object.preventExtensions) {
  776. Object.preventExtensions = function preventExtensions(object) {
  777. // this is misleading and breaks feature-detection, but
  778. // allows "securable" code to "gracefully" degrade to working
  779. // but insecure code.
  780. return object;
  781. };
  782. }
  783. // ES5 15.2.3.11
  784. // http://es5.github.com/#x15.2.3.11
  785. if (!Object.isSealed) {
  786. Object.isSealed = function isSealed(object) {
  787. return false;
  788. };
  789. }
  790. // ES5 15.2.3.12
  791. // http://es5.github.com/#x15.2.3.12
  792. if (!Object.isFrozen) {
  793. Object.isFrozen = function isFrozen(object) {
  794. return false;
  795. };
  796. }
  797. // ES5 15.2.3.13
  798. // http://es5.github.com/#x15.2.3.13
  799. if (!Object.isExtensible) {
  800. Object.isExtensible = function isExtensible(object) {
  801. // 1. If Type(O) is not Object throw a TypeError exception.
  802. if (Object(object) === object) {
  803. throw new TypeError(); // TODO message
  804. }
  805. // 2. Return the Boolean value of the [[Extensible]] internal property of O.
  806. var name = '';
  807. while (owns(object, name)) {
  808. name += '?';
  809. }
  810. object[name] = true;
  811. var returnValue = owns(object, name);
  812. delete object[name];
  813. return returnValue;
  814. };
  815. }
  816. // ES5 15.2.3.14
  817. // http://es5.github.com/#x15.2.3.14
  818. if (!Object.keys) {
  819. // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
  820. var hasDontEnumBug = true,
  821. dontEnums = [
  822. "toString",
  823. "toLocaleString",
  824. "valueOf",
  825. "hasOwnProperty",
  826. "isPrototypeOf",
  827. "propertyIsEnumerable",
  828. "constructor"
  829. ],
  830. dontEnumsLength = dontEnums.length;
  831. for (var key in {"toString": null}) {
  832. hasDontEnumBug = false;
  833. }
  834. Object.keys = function keys(object) {
  835. if (
  836. (typeof object != "object" && typeof object != "function") ||
  837. object === null
  838. ) {
  839. throw new TypeError("Object.keys called on a non-object");
  840. }
  841. var keys = [];
  842. for (var name in object) {
  843. if (owns(object, name)) {
  844. keys.push(name);
  845. }
  846. }
  847. if (hasDontEnumBug) {
  848. for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
  849. var dontEnum = dontEnums[i];
  850. if (owns(object, dontEnum)) {
  851. keys.push(dontEnum);
  852. }
  853. }
  854. }
  855. return keys;
  856. };
  857. }
  858. //
  859. // most of es5-shim Date section is removed since ace doesn't need it, it is too intrusive and it causes problems for users
  860. // ====
  861. //
  862. // ES5 15.9.4.4
  863. // http://es5.github.com/#x15.9.4.4
  864. if (!Date.now) {
  865. Date.now = function now() {
  866. return new Date().getTime();
  867. };
  868. }
  869. //
  870. // String
  871. // ======
  872. //
  873. // ES5 15.5.4.20
  874. // http://es5.github.com/#x15.5.4.20
  875. var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
  876. "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
  877. "\u2029\uFEFF";
  878. if (!String.prototype.trim || ws.trim()) {
  879. // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  880. // http://perfectionkills.com/whitespace-deviations/
  881. ws = "[" + ws + "]";
  882. var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
  883. trimEndRegexp = new RegExp(ws + ws + "*$");
  884. String.prototype.trim = function trim() {
  885. return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
  886. };
  887. }
  888. //
  889. // Util
  890. // ======
  891. //
  892. // ES5 9.4
  893. // http://es5.github.com/#x9.4
  894. // http://jsperf.com/to-integer
  895. function toInteger(n) {
  896. n = +n;
  897. if (n !== n) { // isNaN
  898. n = 0;
  899. } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
  900. n = (n > 0 || -1) * Math.floor(Math.abs(n));
  901. }
  902. return n;
  903. }
  904. function isPrimitive(input) {
  905. var type = typeof input;
  906. return (
  907. input === null ||
  908. type === "undefined" ||
  909. type === "boolean" ||
  910. type === "number" ||
  911. type === "string"
  912. );
  913. }
  914. function toPrimitive(input) {
  915. var val, valueOf, toString;
  916. if (isPrimitive(input)) {
  917. return input;
  918. }
  919. valueOf = input.valueOf;
  920. if (typeof valueOf === "function") {
  921. val = valueOf.call(input);
  922. if (isPrimitive(val)) {
  923. return val;
  924. }
  925. }
  926. toString = input.toString;
  927. if (typeof toString === "function") {
  928. val = toString.call(input);
  929. if (isPrimitive(val)) {
  930. return val;
  931. }
  932. }
  933. throw new TypeError();
  934. }
  935. // ES5 9.9
  936. // http://es5.github.com/#x9.9
  937. var toObject = function (o) {
  938. if (o == null) { // this matches both null and undefined
  939. throw new TypeError("can't convert "+o+" to object");
  940. }
  941. return Object(o);
  942. };
  943. });