PageRenderTime 90ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/wwwroot/demo/js/global-es5.js

http://github.com/AF83/ucengine
JavaScript | 553 lines | 304 code | 59 blank | 190 comment | 110 complexity | f9ef266cf67fc65d54f561451e1380e9 MD5 | raw file
  1. /*!
  2. Copyright (c) 2009, 280 North Inc. http://280north.com/
  3. MIT License. http://github.com/280north/narwhal/blob/master/README.md
  4. */
  5. // Brings an environment as close to ECMAScript 5 compliance
  6. // as is possible with the facilities of erstwhile engines.
  7. // ES5 Draft
  8. // http://www.ecma-international.org/publications/files/drafts/tc39-2009-050.pdf
  9. // NOTE: this is a draft, and as such, the URL is subject to change. If the
  10. // link is broken, check in the parent directory for the latest TC39 PDF.
  11. // http://www.ecma-international.org/publications/files/drafts/
  12. // Previous ES5 Draft
  13. // http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
  14. // This is a broken link to the previous draft of ES5 on which most of the
  15. // numbered specification references and quotes herein were taken. Updating
  16. // these references and quotes to reflect the new document would be a welcome
  17. // volunteer project.
  18. //
  19. // Array
  20. // =====
  21. //
  22. // ES5 15.4.3.2
  23. if (!Array.isArray) {
  24. Array.isArray = function(obj) {
  25. return Object.prototype.toString.call(obj) == "[object Array]";
  26. };
  27. }
  28. // ES5 15.4.4.18
  29. if (!Array.prototype.forEach) {
  30. Array.prototype.forEach = function(block, thisObject) {
  31. var len = this.length >>> 0;
  32. for (var i = 0; i < len; i++) {
  33. if (i in this) {
  34. block.call(thisObject, this[i], i, this);
  35. }
  36. }
  37. };
  38. }
  39. // ES5 15.4.4.19
  40. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  41. if (!Array.prototype.map) {
  42. Array.prototype.map = function(fun /*, thisp*/) {
  43. var len = this.length >>> 0;
  44. if (typeof fun != "function")
  45. throw new TypeError();
  46. var res = new Array(len);
  47. var thisp = arguments[1];
  48. for (var i = 0; i < len; i++) {
  49. if (i in this)
  50. res[i] = fun.call(thisp, this[i], i, this);
  51. }
  52. return res;
  53. };
  54. }
  55. // ES5 15.4.4.20
  56. if (!Array.prototype.filter) {
  57. Array.prototype.filter = function (block /*, thisp */) {
  58. var values = [];
  59. var thisp = arguments[1];
  60. for (var i = 0; i < this.length; i++)
  61. if (block.call(thisp, this[i]))
  62. values.push(this[i]);
  63. return values;
  64. };
  65. }
  66. // ES5 15.4.4.16
  67. if (!Array.prototype.every) {
  68. Array.prototype.every = function (block /*, thisp */) {
  69. var thisp = arguments[1];
  70. for (var i = 0; i < this.length; i++)
  71. if (!block.call(thisp, this[i]))
  72. return false;
  73. return true;
  74. };
  75. }
  76. // ES5 15.4.4.17
  77. if (!Array.prototype.some) {
  78. Array.prototype.some = function (block /*, thisp */) {
  79. var thisp = arguments[1];
  80. for (var i = 0; i < this.length; i++)
  81. if (block.call(thisp, this[i]))
  82. return true;
  83. return false;
  84. };
  85. }
  86. // ES5 15.4.4.21
  87. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
  88. if (!Array.prototype.reduce) {
  89. Array.prototype.reduce = function(fun /*, initial*/) {
  90. var len = this.length >>> 0;
  91. if (typeof fun != "function")
  92. throw new TypeError();
  93. // no value to return if no initial value and an empty array
  94. if (len == 0 && arguments.length == 1)
  95. throw new TypeError();
  96. var i = 0;
  97. if (arguments.length >= 2) {
  98. var rv = arguments[1];
  99. } else {
  100. do {
  101. if (i in this) {
  102. rv = this[i++];
  103. break;
  104. }
  105. // if array contains no values, no initial value to return
  106. if (++i >= len)
  107. throw new TypeError();
  108. } while (true);
  109. }
  110. for (; i < len; i++) {
  111. if (i in this)
  112. rv = fun.call(null, rv, this[i], i, this);
  113. }
  114. return rv;
  115. };
  116. }
  117. // ES5 15.4.4.22
  118. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
  119. if (!Array.prototype.reduceRight) {
  120. Array.prototype.reduceRight = function(fun /*, initial*/) {
  121. var len = this.length >>> 0;
  122. if (typeof fun != "function")
  123. throw new TypeError();
  124. // no value to return if no initial value, empty array
  125. if (len == 0 && arguments.length == 1)
  126. throw new TypeError();
  127. var i = len - 1;
  128. if (arguments.length >= 2) {
  129. var rv = arguments[1];
  130. } else {
  131. do {
  132. if (i in this) {
  133. rv = this[i--];
  134. break;
  135. }
  136. // if array contains no values, no initial value to return
  137. if (--i < 0)
  138. throw new TypeError();
  139. } while (true);
  140. }
  141. for (; i >= 0; i--) {
  142. if (i in this)
  143. rv = fun.call(null, rv, this[i], i, this);
  144. }
  145. return rv;
  146. };
  147. }
  148. // ES5 15.4.4.14
  149. if (!Array.prototype.indexOf) {
  150. Array.prototype.indexOf = function (value /*, fromIndex */ ) {
  151. var length = this.length;
  152. if (!length)
  153. return -1;
  154. var i = arguments[1] || 0;
  155. if (i >= length)
  156. return -1;
  157. if (i < 0)
  158. i += length;
  159. for (; i < length; i++) {
  160. if (!Object.prototype.hasOwnProperty.call(this, i))
  161. continue;
  162. if (value === this[i])
  163. return i;
  164. }
  165. return -1;
  166. };
  167. }
  168. // ES5 15.4.4.15
  169. if (!Array.prototype.lastIndexOf) {
  170. Array.prototype.lastIndexOf = function (value /*, fromIndex */) {
  171. var length = this.length;
  172. if (!length)
  173. return -1;
  174. var i = arguments[1] || length;
  175. if (i < 0)
  176. i += length;
  177. i = Math.min(i, length - 1);
  178. for (; i >= 0; i--) {
  179. if (!Object.prototype.hasOwnProperty.call(this, i))
  180. continue;
  181. if (value === this[i])
  182. return i;
  183. }
  184. return -1;
  185. };
  186. }
  187. //
  188. // Object
  189. // ======
  190. //
  191. // ES5 15.2.3.2
  192. if (!Object.getPrototypeOf) {
  193. Object.getPrototypeOf = function (object) {
  194. return object.__proto__;
  195. // or undefined if not available in this engine
  196. };
  197. }
  198. // ES5 15.2.3.3
  199. if (!Object.getOwnPropertyDescriptor) {
  200. Object.getOwnPropertyDescriptor = function (object) {
  201. return {}; // XXX
  202. };
  203. }
  204. // ES5 15.2.3.4
  205. if (!Object.getOwnPropertyNames) {
  206. Object.getOwnPropertyNames = function (object) {
  207. return Object.keys(object);
  208. };
  209. }
  210. // ES5 15.2.3.5
  211. if (!Object.create) {
  212. Object.create = function(prototype, properties) {
  213. if (typeof prototype != "object" || prototype === null)
  214. throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
  215. function Type() {};
  216. Type.prototype = prototype;
  217. var object = new Type();
  218. if (typeof properties !== "undefined")
  219. Object.defineProperties(object, properties);
  220. return object;
  221. };
  222. }
  223. // ES5 15.2.3.6
  224. if (!Object.defineProperty) {
  225. Object.defineProperty = function(object, property, descriptor) {
  226. var has = Object.prototype.hasOwnProperty;
  227. if (typeof descriptor == "object" && object.__defineGetter__) {
  228. if (has.call(descriptor, "value")) {
  229. if (!object.__lookupGetter__(property) && !object.__lookupSetter__(property))
  230. // data property defined and no pre-existing accessors
  231. object[property] = descriptor.value;
  232. if (has.call(descriptor, "get") || has.call(descriptor, "set"))
  233. // descriptor has a value property but accessor already exists
  234. throw new TypeError("Object doesn't support this action");
  235. }
  236. // fail silently if "writable", "enumerable", or "configurable"
  237. // are requested but not supported
  238. /*
  239. // alternate approach:
  240. if ( // can't implement these features; allow false but not true
  241. !(has.call(descriptor, "writable") ? descriptor.writable : true) ||
  242. !(has.call(descriptor, "enumerable") ? descriptor.enumerable : true) ||
  243. !(has.call(descriptor, "configurable") ? descriptor.configurable : true)
  244. )
  245. throw new RangeError(
  246. "This implementation of Object.defineProperty does not " +
  247. "support configurable, enumerable, or writable."
  248. );
  249. */
  250. else if (typeof descriptor.get == "function")
  251. object.__defineGetter__(property, descriptor.get);
  252. if (typeof descriptor.set == "function")
  253. object.__defineSetter__(property, descriptor.set);
  254. }
  255. return object;
  256. };
  257. }
  258. // ES5 15.2.3.7
  259. if (!Object.defineProperties) {
  260. Object.defineProperties = function(object, properties) {
  261. for (var property in properties) {
  262. if (Object.prototype.hasOwnProperty.call(properties, property))
  263. Object.defineProperty(object, property, properties[property]);
  264. }
  265. return object;
  266. };
  267. }
  268. // ES5 15.2.3.8
  269. if (!Object.seal) {
  270. Object.seal = function (object) {
  271. return object;
  272. };
  273. }
  274. // ES5 15.2.3.9
  275. if (!Object.freeze) {
  276. Object.freeze = function (object) {
  277. return object;
  278. };
  279. }
  280. // ES5 15.2.3.10
  281. if (!Object.preventExtensions) {
  282. Object.preventExtensions = function (object) {
  283. return object;
  284. };
  285. }
  286. // ES5 15.2.3.11
  287. if (!Object.isSealed) {
  288. Object.isSealed = function (object) {
  289. return false;
  290. };
  291. }
  292. // ES5 15.2.3.12
  293. if (!Object.isFrozen) {
  294. Object.isFrozen = function (object) {
  295. return false;
  296. };
  297. }
  298. // ES5 15.2.3.13
  299. if (!Object.isExtensible) {
  300. Object.isExtensible = function (object) {
  301. return true;
  302. };
  303. }
  304. // ES5 15.2.3.14
  305. if (!Object.keys) {
  306. Object.keys = function (object) {
  307. var keys = [];
  308. for (var name in object) {
  309. if (Object.prototype.hasOwnProperty.call(object, name)) {
  310. keys.push(name);
  311. }
  312. }
  313. return keys;
  314. };
  315. }
  316. //
  317. // Date
  318. // ====
  319. //
  320. // ES5 15.9.5.43
  321. // Format a Date object as a string according to a subset of the ISO-8601 standard.
  322. // Useful in Atom, among other things.
  323. if (!Date.prototype.toISOString) {
  324. Date.prototype.toISOString = function() {
  325. return (
  326. this.getFullYear() + "-" +
  327. (this.getMonth() + 1) + "-" +
  328. this.getDate() + "T" +
  329. this.getHours() + ":" +
  330. this.getMinutes() + ":" +
  331. this.getSeconds() + "Z"
  332. );
  333. }
  334. }
  335. // ES5 15.9.4.4
  336. if (!Date.now) {
  337. Date.now = function () {
  338. return new Date().getTime();
  339. };
  340. }
  341. // ES5 15.9.5.44
  342. if (!Date.prototype.toJSON) {
  343. Date.prototype.toJSON = function (key) {
  344. // This function provides a String representation of a Date object for
  345. // use by JSON.stringify (15.12.3). When the toJSON method is called
  346. // with argument key, the following steps are taken:
  347. // 1. Let O be the result of calling ToObject, giving it the this
  348. // value as its argument.
  349. // 2. Let tv be ToPrimitive(O, hint Number).
  350. // 3. If tv is a Number and is not finite, return null.
  351. // XXX
  352. // 4. Let toISO be the result of calling the [[Get]] internal method of
  353. // O with argument "toISOString".
  354. // 5. If IsCallable(toISO) is false, throw a TypeError exception.
  355. if (typeof this.toISOString != "function")
  356. throw new TypeError();
  357. // 6. Return the result of calling the [[Call]] internal method of
  358. // toISO with O as the this value and an empty argument list.
  359. return this.toISOString();
  360. // NOTE 1 The argument is ignored.
  361. // NOTE 2 The toJSON function is intentionally generic; it does not
  362. // require that its this value be a Date object. Therefore, it can be
  363. // transferred to other kinds of objects for use as a method. However,
  364. // it does require that any such object have a toISOString method. An
  365. // object is free to use the argument key to filter its
  366. // stringification.
  367. };
  368. }
  369. //
  370. // Function
  371. // ========
  372. //
  373. // ES-5 15.3.4.5
  374. // http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
  375. var slice = Array.prototype.slice;
  376. if (!Function.prototype.bind) {
  377. Function.prototype.bind = function (that) { // .length is 1
  378. // 1. Let Target be the this value.
  379. var target = this;
  380. // 2. If IsCallable(Target) is false, throw a TypeError exception.
  381. // XXX this gets pretty close, for all intents and purposes, letting
  382. // some duck-types slide
  383. if (typeof target.apply != "function" || typeof target.call != "function")
  384. return new TypeError();
  385. // 3. Let A be a new (possibly empty) internal list of all of the
  386. // argument values provided after thisArg (arg1, arg2 etc), in order.
  387. var args = slice.call(arguments);
  388. // 4. Let F be a new native ECMAScript object.
  389. // 9. Set the [[Prototype]] internal property of F to the standard
  390. // built-in Function prototype object as specified in 15.3.3.1.
  391. // 10. Set the [[Call]] internal property of F as described in
  392. // 15.3.4.5.1.
  393. // 11. Set the [[Construct]] internal property of F as described in
  394. // 15.3.4.5.2.
  395. // 12. Set the [[HasInstance]] internal property of F as described in
  396. // 15.3.4.5.3.
  397. // 13. The [[Scope]] internal property of F is unused and need not
  398. // exist.
  399. var bound = function () {
  400. if (this instanceof bound) {
  401. // 15.3.4.5.2 [[Construct]]
  402. // When the [[Construct]] internal method of a function object,
  403. // F that was created using the bind function is called with a
  404. // list of arguments ExtraArgs the following steps are taken:
  405. // 1. Let target be the value of F's [[TargetFunction]]
  406. // internal property.
  407. // 2. If target has no [[Construct]] internal method, a
  408. // TypeError exception is thrown.
  409. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
  410. // property.
  411. // 4. Let args be a new list containing the same values as the
  412. // list boundArgs in the same order followed by the same
  413. // values as the list ExtraArgs in the same order.
  414. var self = Object.create(target.prototype);
  415. target.apply(self, args.concat(slice.call(arguments)));
  416. return self;
  417. } else {
  418. // 15.3.4.5.1 [[Call]]
  419. // When the [[Call]] internal method of a function object, F,
  420. // which was created using the bind function is called with a
  421. // this value and a list of arguments ExtraArgs the following
  422. // steps are taken:
  423. // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
  424. // property.
  425. // 2. Let boundThis be the value of F's [[BoundThis]] internal
  426. // property.
  427. // 3. Let target be the value of F's [[TargetFunction]] internal
  428. // property.
  429. // 4. Let args be a new list containing the same values as the list
  430. // boundArgs in the same order followed by the same values as
  431. // the list ExtraArgs in the same order. 5. Return the
  432. // result of calling the [[Call]] internal method of target
  433. // providing boundThis as the this value and providing args
  434. // as the arguments.
  435. // equiv: target.call(this, ...boundArgs, ...args)
  436. return target.call.apply(
  437. target,
  438. args.concat(slice.call(arguments))
  439. );
  440. }
  441. };
  442. // 5. Set the [[TargetFunction]] internal property of F to Target.
  443. // extra:
  444. bound.bound = target;
  445. // 6. Set the [[BoundThis]] internal property of F to the value of
  446. // thisArg.
  447. // extra:
  448. bound.boundTo = that;
  449. // 7. Set the [[BoundArgs]] internal property of F to A.
  450. // extra:
  451. bound.boundArgs = args;
  452. bound.length = (
  453. // 14. If the [[Class]] internal property of Target is "Function", then
  454. typeof target == "function" ?
  455. // a. Let L be the length property of Target minus the length of A.
  456. // b. Set the length own property of F to either 0 or L, whichever is larger.
  457. Math.max(target.length - args.length, 0) :
  458. // 15. Else set the length own property of F to 0.
  459. 0
  460. )
  461. // 16. The length own property of F is given attributes as specified in
  462. // 15.3.5.1.
  463. // TODO
  464. // 17. Set the [[Extensible]] internal property of F to true.
  465. // TODO
  466. // 18. Call the [[DefineOwnProperty]] internal method of F with
  467. // arguments "caller", PropertyDescriptor {[[Value]]: null,
  468. // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
  469. // false}, and false.
  470. // TODO
  471. // 19. Call the [[DefineOwnProperty]] internal method of F with
  472. // arguments "arguments", PropertyDescriptor {[[Value]]: null,
  473. // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
  474. // false}, and false.
  475. // TODO
  476. // NOTE Function objects created using Function.prototype.bind do not
  477. // have a prototype property.
  478. // XXX can't delete it in pure-js.
  479. return bound;
  480. };
  481. }
  482. //
  483. // String
  484. // ======
  485. //
  486. // ES5 15.5.4.20
  487. if (!String.prototype.trim) {
  488. // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  489. var trimBeginRegexp = /^\s\s*/;
  490. var trimEndRegexp = /\s\s*$/;
  491. String.prototype.trim = function () {
  492. return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
  493. };
  494. }