ecmascript5.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. //----------------------------------------------------------------------
  2. //
  3. // ECMAScript 5 Polyfills
  4. //
  5. //----------------------------------------------------------------------
  6. //----------------------------------------------------------------------
  7. // ES5 15.2 Object Objects
  8. //----------------------------------------------------------------------
  9. //
  10. // ES5 15.2.3 Properties of the Object Constructor
  11. //
  12. // ES5 15.2.3.2 Object.getPrototypeOf ( O )
  13. // From http://ejohn.org/blog/objectgetprototypeof/
  14. // NOTE: won't work for typical function T() {}; T.prototype = {}; new T; case
  15. // since the constructor property is destroyed.
  16. if (!Object.getPrototypeOf) {
  17. Object.getPrototypeOf = function (o) {
  18. if (o !== Object(o)) { throw new TypeError("Object.getPrototypeOf called on non-object"); }
  19. return o.__proto__ || o.constructor.prototype || Object.prototype;
  20. };
  21. }
  22. // // ES5 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P )
  23. // if (typeof Object.getOwnPropertyDescriptor !== "function") {
  24. // Object.getOwnPropertyDescriptor = function (o, name) {
  25. // if (o !== Object(o)) { throw new TypeError(); }
  26. // if (o.hasOwnProperty(name)) {
  27. // return {
  28. // value: o[name],
  29. // enumerable: true,
  30. // writable: true,
  31. // configurable: true
  32. // };
  33. // }
  34. // };
  35. // }
  36. // ES5 15.2.3.4 Object.getOwnPropertyNames ( O )
  37. if (typeof Object.getOwnPropertyNames !== "function") {
  38. Object.getOwnPropertyNames = function (o) {
  39. if (o !== Object(o)) { throw new TypeError("Object.getOwnPropertyNames called on non-object"); }
  40. var props = [], p;
  41. for (p in o) {
  42. if (Object.prototype.hasOwnProperty.call(o, p)) {
  43. props.push(p);
  44. }
  45. }
  46. return props;
  47. };
  48. }
  49. // ES5 15.2.3.5 Object.create ( O [, Properties] )
  50. if (typeof Object.create !== "function") {
  51. Object.create = function (prototype, properties) {
  52. "use strict";
  53. if (prototype !== Object(prototype)) { throw new TypeError(); }
  54. /** @constructor */
  55. function Ctor() {}
  56. Ctor.prototype = prototype;
  57. var o = new Ctor();
  58. o.constructor = Ctor;
  59. if (arguments.length > 1) {
  60. if (properties !== Object(properties)) { throw new TypeError(); }
  61. Object.defineProperties(o, properties);
  62. }
  63. return o;
  64. };
  65. }
  66. // ES 15.2.3.6 Object.defineProperty ( O, P, Attributes )
  67. // Partial support for most common case - getters, setters, and values
  68. (function() {
  69. if (!Object.defineProperty ||
  70. !(function () { try { Object.defineProperty({}, 'x', {}); return true; } catch (e) { return false; } } ())) {
  71. var orig = Object.defineProperty;
  72. Object.defineProperty = function (o, prop, desc) {
  73. "use strict";
  74. // In IE8 try built-in implementation for defining properties on DOM prototypes.
  75. if (orig) { try { return orig(o, prop, desc); } catch (e) {} }
  76. if (o !== Object(o)) { throw new TypeError("Object.defineProperty called on non-object"); }
  77. if (Object.prototype.__defineGetter__ && ('get' in desc)) {
  78. Object.prototype.__defineGetter__.call(o, prop, desc.get);
  79. }
  80. if (Object.prototype.__defineSetter__ && ('set' in desc)) {
  81. Object.prototype.__defineSetter__.call(o, prop, desc.set);
  82. }
  83. if ('value' in desc) {
  84. o[prop] = desc.value;
  85. }
  86. return o;
  87. };
  88. }
  89. }());
  90. // ES 15.2.3.7 Object.defineProperties ( O, Properties )
  91. if (typeof Object.defineProperties !== "function") {
  92. Object.defineProperties = function (o, properties) {
  93. "use strict";
  94. if (o !== Object(o)) { throw new TypeError("Object.defineProperties called on non-object"); }
  95. var name;
  96. for (name in properties) {
  97. if (Object.prototype.hasOwnProperty.call(properties, name)) {
  98. Object.defineProperty(o, name, properties[name]);
  99. }
  100. }
  101. return o;
  102. };
  103. }
  104. // ES5 15.2.3.14 Object.keys ( O )
  105. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
  106. if (!Object.keys) {
  107. Object.keys = function (o) {
  108. if (o !== Object(o)) { throw new TypeError('Object.keys called on non-object'); }
  109. var ret = [], p;
  110. for (p in o) {
  111. if (Object.prototype.hasOwnProperty.call(o, p)) {
  112. ret.push(p);
  113. }
  114. }
  115. return ret;
  116. };
  117. }
  118. //----------------------------------------------------------------------
  119. // ES5 15.3 Function Objects
  120. //----------------------------------------------------------------------
  121. //
  122. // ES5 15.3.4 Properties of the Function Prototype Object
  123. //
  124. // ES5 15.3.4.5 Function.prototype.bind ( thisArg [, arg1 [, arg2, ... ]] )
  125. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
  126. if (!Function.prototype.bind) {
  127. Function.prototype.bind = function (o) {
  128. if (typeof this !== 'function') { throw new TypeError("Bind must be called on a function"); }
  129. var slice = [].slice,
  130. args = slice.call(arguments, 1),
  131. self = this,
  132. bound = function () {
  133. return self.apply(this instanceof nop ? this : (o || {}),
  134. args.concat(slice.call(arguments)));
  135. };
  136. /** @constructor */
  137. function nop() {}
  138. nop.prototype = self.prototype;
  139. bound.prototype = new nop();
  140. return bound;
  141. };
  142. }
  143. //----------------------------------------------------------------------
  144. // ES5 15.4 Array Objects
  145. //----------------------------------------------------------------------
  146. //
  147. // ES5 15.4.3 Properties of the Array Constructor
  148. //
  149. // ES5 15.4.3.2 Array.isArray ( arg )
  150. // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
  151. Array.isArray = Array.isArray || function (o) { return Boolean(o && Object.prototype.toString.call(Object(o)) === '[object Array]'); };
  152. //
  153. // ES5 15.4.4 Properties of the Array Prototype Object
  154. //
  155. // ES5 15.4.4.14 Array.prototype.indexOf ( searchElement [ , fromIndex ] )
  156. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
  157. if (!Array.prototype.indexOf) {
  158. Array.prototype.indexOf = function (searchElement /*, fromIndex */) {
  159. "use strict";
  160. if (this === void 0 || this === null) { throw new TypeError(); }
  161. var t = Object(this);
  162. var len = t.length >>> 0;
  163. if (len === 0) { return -1; }
  164. var n = 0;
  165. if (arguments.length > 0) {
  166. n = Number(arguments[1]);
  167. if (isNaN(n)) {
  168. n = 0;
  169. } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
  170. n = (n > 0 || -1) * Math.floor(Math.abs(n));
  171. }
  172. }
  173. if (n >= len) { return -1; }
  174. var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
  175. for (; k < len; k++) {
  176. if (k in t && t[k] === searchElement) {
  177. return k;
  178. }
  179. }
  180. return -1;
  181. };
  182. }
  183. // ES5 15.4.4.15 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )
  184. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
  185. if (!Array.prototype.lastIndexOf) {
  186. Array.prototype.lastIndexOf = function (searchElement /*, fromIndex*/) {
  187. "use strict";
  188. if (this === void 0 || this === null) { throw new TypeError(); }
  189. var t = Object(this);
  190. var len = t.length >>> 0;
  191. if (len === 0) { return -1; }
  192. var n = len;
  193. if (arguments.length > 1) {
  194. n = Number(arguments[1]);
  195. if (n !== n) {
  196. n = 0;
  197. } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
  198. n = (n > 0 || -1) * Math.floor(Math.abs(n));
  199. }
  200. }
  201. var k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n);
  202. for (; k >= 0; k--) {
  203. if (k in t && t[k] === searchElement) {
  204. return k;
  205. }
  206. }
  207. return -1;
  208. };
  209. }
  210. // ES5 15.4.4.16 Array.prototype.every ( callbackfn [ , thisArg ] )
  211. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
  212. if (!Array.prototype.every) {
  213. Array.prototype.every = function (fun /*, thisp */) {
  214. "use strict";
  215. if (this === void 0 || this === null) { throw new TypeError(); }
  216. var t = Object(this);
  217. var len = t.length >>> 0;
  218. if (typeof fun !== "function") { throw new TypeError(); }
  219. var thisp = arguments[1], i;
  220. for (i = 0; i < len; i++) {
  221. if (i in t && !fun.call(thisp, t[i], i, t)) {
  222. return false;
  223. }
  224. }
  225. return true;
  226. };
  227. }
  228. // ES5 15.4.4.17 Array.prototype.some ( callbackfn [ , thisArg ] )
  229. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
  230. if (!Array.prototype.some) {
  231. Array.prototype.some = function (fun /*, thisp */) {
  232. "use strict";
  233. if (this === void 0 || this === null) { throw new TypeError(); }
  234. var t = Object(this);
  235. var len = t.length >>> 0;
  236. if (typeof fun !== "function") { throw new TypeError(); }
  237. var thisp = arguments[1], i;
  238. for (i = 0; i < len; i++) {
  239. if (i in t && fun.call(thisp, t[i], i, t)) {
  240. return true;
  241. }
  242. }
  243. return false;
  244. };
  245. }
  246. // ES5 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] )
  247. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach
  248. if (!Array.prototype.forEach) {
  249. Array.prototype.forEach = function (fun /*, thisp */) {
  250. "use strict";
  251. if (this === void 0 || this === null) { throw new TypeError(); }
  252. var t = Object(this);
  253. var len = t.length >>> 0;
  254. if (typeof fun !== "function") { throw new TypeError(); }
  255. var thisp = arguments[1], i;
  256. for (i = 0; i < len; i++) {
  257. if (i in t) {
  258. fun.call(thisp, t[i], i, t);
  259. }
  260. }
  261. };
  262. }
  263. // ES5 15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] )
  264. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Map
  265. if (!Array.prototype.map) {
  266. Array.prototype.map = function (fun /*, thisp */) {
  267. "use strict";
  268. if (this === void 0 || this === null) { throw new TypeError(); }
  269. var t = Object(this);
  270. var len = t.length >>> 0;
  271. if (typeof fun !== "function") { throw new TypeError(); }
  272. var res = []; res.length = len;
  273. var thisp = arguments[1], i;
  274. for (i = 0; i < len; i++) {
  275. if (i in t) {
  276. res[i] = fun.call(thisp, t[i], i, t);
  277. }
  278. }
  279. return res;
  280. };
  281. }
  282. // ES5 15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] )
  283. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Filter
  284. if (!Array.prototype.filter) {
  285. Array.prototype.filter = function (fun /*, thisp */) {
  286. "use strict";
  287. if (this === void 0 || this === null) { throw new TypeError(); }
  288. var t = Object(this);
  289. var len = t.length >>> 0;
  290. if (typeof fun !== "function") { throw new TypeError(); }
  291. var res = [];
  292. var thisp = arguments[1], i;
  293. for (i = 0; i < len; i++) {
  294. if (i in t) {
  295. var val = t[i]; // in case fun mutates this
  296. if (fun.call(thisp, val, i, t)) {
  297. res.push(val);
  298. }
  299. }
  300. }
  301. return res;
  302. };
  303. }
  304. // ES5 15.4.4.21 Array.prototype.reduce ( callbackfn [ , initialValue ] )
  305. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce
  306. if (!Array.prototype.reduce) {
  307. Array.prototype.reduce = function (fun /*, initialValue */) {
  308. "use strict";
  309. if (this === void 0 || this === null) { throw new TypeError(); }
  310. var t = Object(this);
  311. var len = t.length >>> 0;
  312. if (typeof fun !== "function") { throw new TypeError(); }
  313. // no value to return if no initial value and an empty array
  314. if (len === 0 && arguments.length === 1) { throw new TypeError(); }
  315. var k = 0;
  316. var accumulator;
  317. if (arguments.length >= 2) {
  318. accumulator = arguments[1];
  319. } else {
  320. do {
  321. if (k in t) {
  322. accumulator = t[k++];
  323. break;
  324. }
  325. // if array contains no values, no initial value to return
  326. if (++k >= len) { throw new TypeError(); }
  327. }
  328. while (true);
  329. }
  330. while (k < len) {
  331. if (k in t) {
  332. accumulator = fun.call(undefined, accumulator, t[k], k, t);
  333. }
  334. k++;
  335. }
  336. return accumulator;
  337. };
  338. }
  339. // ES5 15.4.4.22 Array.prototype.reduceRight ( callbackfn [, initialValue ] )
  340. // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/ReduceRight
  341. if (!Array.prototype.reduceRight) {
  342. Array.prototype.reduceRight = function (callbackfn /*, initialValue */) {
  343. "use strict";
  344. if (this === void 0 || this === null) { throw new TypeError(); }
  345. var t = Object(this);
  346. var len = t.length >>> 0;
  347. if (typeof callbackfn !== "function") { throw new TypeError(); }
  348. // no value to return if no initial value, empty array
  349. if (len === 0 && arguments.length === 1) { throw new TypeError(); }
  350. var k = len - 1;
  351. var accumulator;
  352. if (arguments.length >= 2) {
  353. accumulator = arguments[1];
  354. } else {
  355. do {
  356. if (k in this) {
  357. accumulator = this[k--];
  358. break;
  359. }
  360. // if array contains no values, no initial value to return
  361. if (--k < 0) { throw new TypeError(); }
  362. }
  363. while (true);
  364. }
  365. while (k >= 0) {
  366. if (k in t) {
  367. accumulator = callbackfn.call(undefined, accumulator, t[k], k, t);
  368. }
  369. k--;
  370. }
  371. return accumulator;
  372. };
  373. }
  374. //----------------------------------------------------------------------
  375. // ES5 15.5 String Objects
  376. //----------------------------------------------------------------------
  377. //
  378. // ES5 15.5.4 Properties of the String Prototype Object
  379. //
  380. // ES5 15.5.4.20 String.prototype.trim()
  381. if (!String.prototype.trim) {
  382. String.prototype.trim = function () {
  383. return String(this).replace(/^\s+/, '').replace(/\s+$/, '');
  384. };
  385. }
  386. //----------------------------------------------------------------------
  387. // ES5 15.9 Date Objects
  388. //----------------------------------------------------------------------
  389. //
  390. // ES 15.9.4 Properties of the Date Constructor
  391. //
  392. // ES5 15.9.4.4 Date.now ( )
  393. // From https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date/now
  394. if (!Date.now) {
  395. Date.now = function now() {
  396. return Number(new Date());
  397. };
  398. }
  399. //
  400. // ES5 15.9.5 Properties of the Date Prototype Object
  401. //
  402. // ES5 15.9.4.43 Date.prototype.toISOString ( )
  403. // Inspired by http://www.json.org/json2.js
  404. if (!Date.prototype.toISOString) {
  405. Date.prototype.toISOString = function () {
  406. function pad2(n) { return ('00' + n).slice(-2); }
  407. function pad3(n) { return ('000' + n).slice(-3); }
  408. return this.getUTCFullYear() + '-' +
  409. pad2(this.getUTCMonth() + 1) + '-' +
  410. pad2(this.getUTCDate()) + 'T' +
  411. pad2(this.getUTCHours()) + ':' +
  412. pad2(this.getUTCMinutes()) + ':' +
  413. pad2(this.getUTCSeconds()) + '.' +
  414. pad3(this.getUTCMilliseconds()) + 'Z';
  415. };
  416. }
  417. //----------------------------------------------------------------------
  418. //
  419. // Non-standard JavaScript (Mozilla) functions
  420. //
  421. //----------------------------------------------------------------------
  422. (function () {
  423. // JavaScript 1.8.1
  424. String.prototype.trimLeft = String.prototype.trimLeft || function () {
  425. return String(this).replace(/^\s+/, '');
  426. };
  427. // JavaScript 1.8.1
  428. String.prototype.trimRight = String.prototype.trimRight || function () {
  429. return String(this).replace(/\s+$/, '');
  430. };
  431. // JavaScript 1.?
  432. var ESCAPES = {
  433. //'\x00': '\\0', Special case in FF3.6, removed by FF10
  434. '\b': '\\b',
  435. '\t': '\\t',
  436. '\n': '\\n',
  437. '\f': '\\f',
  438. '\r': '\\r',
  439. '"' : '\\"',
  440. '\\': '\\\\'
  441. };
  442. String.prototype.quote = String.prototype.quote || function() {
  443. return '"' + String(this).replace(/[\x00-\x1F"\\\x7F-\uFFFF]/g, function(c) {
  444. if (Object.prototype.hasOwnProperty.call(ESCAPES, c)) {
  445. return ESCAPES[c];
  446. } else if (c.charCodeAt(0) <= 0xFF) {
  447. return '\\x' + ('00' + c.charCodeAt(0).toString(16).toUpperCase()).slice(-2);
  448. } else {
  449. return '\\u' + ('0000' + c.charCodeAt(0).toString(16).toUpperCase()).slice(-4);
  450. }
  451. }) + '"';
  452. };
  453. }());
  454. //----------------------------------------------------------------------
  455. //
  456. // Browser Polyfills
  457. //
  458. //----------------------------------------------------------------------
  459. if ('window' in this && 'document' in this) {
  460. //----------------------------------------------------------------------
  461. //
  462. // Web Standards Polyfills
  463. //
  464. //----------------------------------------------------------------------
  465. //
  466. // document.head (HTML5)
  467. //
  468. document.head = document.head || document.getElementsByTagName('head')[0];
  469. //
  470. // XMLHttpRequest (http://www.w3.org/TR/XMLHttpRequest/)
  471. //
  472. window.XMLHttpRequest = window.XMLHttpRequest || function () {
  473. /*global ActiveXObject*/
  474. try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) { }
  475. try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) { }
  476. try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) { }
  477. throw new Error("This browser does not support XMLHttpRequest.");
  478. };
  479. // XMLHttpRequest.UNSENT = 0;
  480. // XMLHttpRequest.OPENED = 1;
  481. // XMLHttpRequest.HEADERS_RECEIVED = 2;
  482. // XMLHttpRequest.LOADING = 3;
  483. // XMLHttpRequest.DONE = 4;
  484. //----------------------------------------------------------------------
  485. //
  486. // Performance
  487. //
  488. //----------------------------------------------------------------------
  489. // requestAnimationFrame
  490. // http://www.w3.org/TR/animation-timing/
  491. (function() {
  492. var TARGET_FPS = 60,
  493. requests = {},
  494. raf_handle = 1,
  495. timeout_handle = -1;
  496. function isVisible(element) {
  497. return element.offsetWidth > 0 && element.offsetHeight > 0;
  498. }
  499. function onFrameTimer() {
  500. var cur_requests = requests, id, request;
  501. requests = Object.create(null);
  502. timeout_handle = -1;
  503. for (id in cur_requests) {
  504. if (Object.prototype.hasOwnProperty.call(cur_requests, id)) {
  505. request = cur_requests[id];
  506. if (!request.element || isVisible(request.element)) {
  507. request.callback(Date.now());
  508. }
  509. }
  510. }
  511. }
  512. function requestAnimationFrame(callback, element) {
  513. var cb_handle = raf_handle++;
  514. requests[cb_handle] = {callback: callback, element: element};
  515. if (timeout_handle === -1) {
  516. timeout_handle = window.setTimeout(onFrameTimer, 1000 / TARGET_FPS);
  517. }
  518. return cb_handle;
  519. }
  520. function cancelAnimationFrame(handle) {
  521. delete requests[handle];
  522. if (Object.keys(requests).length === 0) {
  523. window.clearTimeout(timeout_handle);
  524. timeout_handle = -1;
  525. }
  526. }
  527. window.requestAnimationFrame =
  528. window.requestAnimationFrame ||
  529. window.webkitRequestAnimationFrame ||
  530. window.mozRequestAnimationFrame ||
  531. window.oRequestAnimationFrame ||
  532. window.msRequestAnimationFrame ||
  533. requestAnimationFrame;
  534. // NOTE: Older versions of the spec called this "cancelRequestAnimationFrame"
  535. window.cancelAnimationFrame = window.cancelRequestAnimationFrame =
  536. window.cancelAnimationFrame || window.cancelRequestAnimationFrame ||
  537. window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
  538. window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame ||
  539. window.oCancelAnimationFrame || window.oCancelRequestAnimationFrame ||
  540. window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame ||
  541. cancelAnimationFrame;
  542. }());
  543. // setImmediate
  544. // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
  545. (function () {
  546. function setImmediate(callback, args) {
  547. var params = [].slice.call(arguments, 1), i;
  548. return window.setTimeout(function() {
  549. callback.apply(null, params);
  550. }, 0);
  551. }
  552. function clearImmediate(handle) {
  553. window.clearTimeout(handle);
  554. }
  555. window.setImmediate =
  556. window.setImmediate ||
  557. window.msSetImmediate ||
  558. setImmediate;
  559. window.clearImmediate =
  560. window.clearImmediate ||
  561. window.msClearImmediate ||
  562. clearImmediate;
  563. } ());
  564. //----------------------------------------------------------------------
  565. //
  566. // DOM
  567. //
  568. //----------------------------------------------------------------------
  569. //
  570. // Selectors API Level 1 (http://www.w3.org/TR/selectors-api/)
  571. // http://ajaxian.com/archives/creating-a-queryselector-for-ie-that-runs-at-native-speed
  572. //
  573. if (!document.querySelectorAll) {
  574. document.querySelectorAll = function (selectors) {
  575. var style = document.createElement('style'), elements = [], element;
  576. document.documentElement.firstChild.appendChild(style);
  577. document._qsa = [];
  578. style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
  579. window.scrollBy(0, 0);
  580. style.parentNode.removeChild(style);
  581. while (document._qsa.length) {
  582. element = document._qsa.shift();
  583. element.style.removeAttribute('x-qsa');
  584. elements.push(element);
  585. }
  586. document._qsa = null;
  587. return elements;
  588. };
  589. }
  590. if (!document.querySelector) {
  591. document.querySelector = function (selectors) {
  592. var elements = document.querySelectorAll(selectors);
  593. return (elements.length) ? elements[0] : null;
  594. };
  595. }
  596. if (!document.getElementsByClassName) {
  597. document.getElementsByClassName = function (classNames) {
  598. classNames = String(classNames).replace(/^|\s+/g, '.');
  599. return document.querySelectorAll(classNames);
  600. };
  601. }
  602. //
  603. // DOM Enumerations (http://www.w3.org/TR/DOM-Level-2-Core/)
  604. //
  605. window.Node = window.Node || function Node() { throw new TypeError("Illegal constructor"); };
  606. Node.ELEMENT_NODE = 1;
  607. Node.ATTRIBUTE_NODE = 2;
  608. Node.TEXT_NODE = 3;
  609. Node.CDATA_SECTION_NODE = 4;
  610. Node.ENTITY_REFERENCE_NODE = 5;
  611. Node.ENTITY_NODE = 6;
  612. Node.PROCESSING_INSTRUCTION_NODE = 7;
  613. Node.COMMENT_NODE = 8;
  614. Node.DOCUMENT_NODE = 9;
  615. Node.DOCUMENT_TYPE_NODE = 10;
  616. Node.DOCUMENT_FRAGMENT_NODE = 11;
  617. Node.NOTATION_NODE = 12;
  618. window.DOMException = window.DOMException || function DOMException() { throw new TypeError("Illegal constructor"); };
  619. DOMException.INDEX_SIZE_ERR = 1;
  620. DOMException.DOMSTRING_SIZE_ERR = 2;
  621. DOMException.HIERARCHY_REQUEST_ERR = 3;
  622. DOMException.WRONG_DOCUMENT_ERR = 4;
  623. DOMException.INVALID_CHARACTER_ERR = 5;
  624. DOMException.NO_DATA_ALLOWED_ERR = 6;
  625. DOMException.NO_MODIFICATION_ALLOWED_ERR = 7;
  626. DOMException.NOT_FOUND_ERR = 8;
  627. DOMException.NOT_SUPPORTED_ERR = 9;
  628. DOMException.INUSE_ATTRIBUTE_ERR = 10;
  629. DOMException.INVALID_STATE_ERR = 11;
  630. DOMException.SYNTAX_ERR = 12;
  631. DOMException.INVALID_MODIFICATION_ERR = 13;
  632. DOMException.NAMESPACE_ERR = 14;
  633. DOMException.INVALID_ACCESS_ERR = 15;
  634. //
  635. // Events and EventTargets
  636. //
  637. (function(){
  638. if (!('Element' in window) || Element.prototype.addEventListener || !Object.defineProperty)
  639. return;
  640. // interface Event
  641. // PhaseType (const unsigned short)
  642. Event.CAPTURING_PHASE = 1;
  643. Event.AT_TARGET = 2;
  644. Event.BUBBLING_PHASE = 3;
  645. Object.defineProperty(Event.prototype, 'CAPTURING_PHASE', { get: function() { return 1; } });
  646. Object.defineProperty(Event.prototype, 'AT_TARGET', { get: function() { return 2; } });
  647. Object.defineProperty(Event.prototype, 'BUBBLING_HASE', { get: function() { return 3; } });
  648. Object.defineProperty(Event.prototype, 'target', {
  649. get: function() {
  650. return this.srcElement;
  651. }
  652. });
  653. Object.defineProperty(Event.prototype, 'currentTarget', {
  654. get: function() {
  655. return this._currentTarget;
  656. }
  657. });
  658. Object.defineProperty(Event.prototype, 'eventPhase', {
  659. get: function() {
  660. return (this.srcElement === this.currentTarget) ? Event.AT_TARGET : Event.BUBBLING_PHASE;
  661. }
  662. });
  663. Object.defineProperty(Event.prototype, 'bubbles', {
  664. get: function() {
  665. switch (this.type) {
  666. // Mouse
  667. case 'click':
  668. case 'dblclick':
  669. case 'mousedown':
  670. case 'mouseup':
  671. case 'mouseover':
  672. case 'mousemove':
  673. case 'mouseout':
  674. case 'mousewheel':
  675. // Keyboard
  676. case 'keydown':
  677. case 'keypress':
  678. case 'keyup':
  679. // Frame/Object
  680. case 'resize':
  681. case 'scroll':
  682. // Form
  683. case 'select':
  684. case 'change':
  685. case 'submit':
  686. case 'reset':
  687. return true;
  688. }
  689. return false;
  690. }
  691. });
  692. Object.defineProperty(Event.prototype, 'cancelable', {
  693. get: function() {
  694. switch (this.type) {
  695. // Mouse
  696. case 'click':
  697. case 'dblclick':
  698. case 'mousedown':
  699. case 'mouseup':
  700. case 'mouseover':
  701. case 'mouseout':
  702. case 'mousewheel':
  703. // Keyboard
  704. case 'keydown':
  705. case 'keypress':
  706. case 'keyup':
  707. // Form
  708. case 'submit':
  709. return true;
  710. }
  711. return false;
  712. }
  713. });
  714. Object.defineProperty(Event.prototype, 'timeStamp', {
  715. get: function() {
  716. return this._timeStamp;
  717. }
  718. });
  719. Event.prototype.stopPropagation = function() {
  720. this.cancelBubble = true;
  721. };
  722. Event.prototype.preventDefault = function() {
  723. this.returnValue = false;
  724. };
  725. Object.defineProperty(Event.prototype, 'defaultPrevented', {
  726. get: function() {
  727. return this.returnValue === false;
  728. }
  729. });
  730. // interface EventTarget
  731. function addEventListener(type, listener, useCapture) {
  732. var target = this;
  733. var f = function(e) {
  734. e._timeStamp = Number(new Date);
  735. e._currentTarget = target;
  736. listener.call(this, e);
  737. e._currentTarget = null;
  738. };
  739. this['_' + type + listener] = f;
  740. this.attachEvent('on' + type, f);
  741. }
  742. function removeEventListener(type, listener, useCapture) {
  743. var f = this['_' + type + listener];
  744. if (f) {
  745. this.detachEvent('on' + type, f);
  746. this['_' + type + listener] = null;
  747. }
  748. }
  749. var p1 = Window.prototype, p2 = HTMLDocument.prototype, p3 = Element.prototype;
  750. p1.addEventListener = p2.addEventListener = p3.addEventListener = addEventListener;
  751. p1.removeEventListener = p2.removeEventListener = p3.removeEventListener = removeEventListener;
  752. }());
  753. // Shim for DOM Events for IE7-
  754. // http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
  755. // Use addEvent(object, event, handler) instead of object.addEventListener(event, handler)
  756. window.addEvent = function (obj, type, fn) {
  757. if (obj.addEventListener) {
  758. obj.addEventListener(type, fn, false);
  759. } else if (obj.attachEvent) {
  760. obj["e" + type + fn] = fn;
  761. obj[type + fn] = function () {
  762. var e = window.event;
  763. e.currentTarget = obj;
  764. e.preventDefault = function () { e.returnValue = false; };
  765. e.stopPropagation = function () { e.cancelBubble = true; };
  766. e.target = e.srcElement;
  767. e.timeStamp = Number(new Date);
  768. obj["e" + type + fn].call(this, e);
  769. };
  770. obj.attachEvent("on" + type, obj[type + fn]);
  771. }
  772. };
  773. window.removeEvent = function (obj, type, fn) {
  774. if (obj.removeEventListener) {
  775. obj.removeEventListener(type, fn, false);
  776. } else if (obj.detachEvent) {
  777. obj.detachEvent("on" + type, obj[type + fn]);
  778. obj[type + fn] = null;
  779. obj["e" + type + fn] = null;
  780. }
  781. };
  782. //----------------------------------------------------------------------
  783. //
  784. // DOMTokenList - classList and relList shims
  785. //
  786. //----------------------------------------------------------------------
  787. // Shim for http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-classlist
  788. // Use getClassList(elem) instead of elem.classList() if IE7- support is needed
  789. // Use getRelList(elem) instead of elem.relList() if IE7- support is needed
  790. (function () {
  791. /** @constructor */
  792. function DOMTokenListShim(o, p) {
  793. function split(s) { return s.length ? s.split(/\s+/g) : []; }
  794. // NOTE: This does not exactly match the spec.
  795. function removeTokenFromString(token, string) {
  796. var tokens = split(string),
  797. index = tokens.indexOf(token);
  798. if (index !== -1) {
  799. tokens.splice(index, 1);
  800. }
  801. return tokens.join(' ');
  802. }
  803. Object.defineProperties(
  804. this,
  805. {
  806. length: {
  807. get: function () { return split(o[p]).length; }
  808. },
  809. item: {
  810. value: function (idx) {
  811. var tokens = split(o[p]);
  812. return 0 <= idx && idx < tokens.length ? tokens[idx] : null;
  813. }
  814. },
  815. contains: {
  816. value: function (token) {
  817. token = String(token);
  818. if (token.length === 0) { throw new SyntaxError(); }
  819. if (/\s/.test(token)) { throw new Error("InvalidCharacterError"); }
  820. var tokens = split(o[p]);
  821. return tokens.indexOf(token) !== -1;
  822. }
  823. },
  824. add: {
  825. value: function (tokens___) {
  826. tokens = Array.prototype.slice.call(arguments).map(String);
  827. if (tokens.some(function(token) { return token.length === 0; })) {
  828. throw new SyntaxError();
  829. }
  830. if (tokens.some(function(token) { return /\s/.test(token); })) {
  831. throw new Error("InvalidCharacterError");
  832. }
  833. try {
  834. var underlying_string = o[p];
  835. var token_list = split(underlying_string);
  836. tokens = tokens.filter(function(token) { return token_list.indexOf(token) === -1; });
  837. if (tokens.length === 0) {
  838. return;
  839. }
  840. if (underlying_string.length !== 0 && !/\s$/.test(underlying_string)) {
  841. underlying_string += ' ';
  842. }
  843. underlying_string += tokens.join(' ');
  844. o[p] = underlying_string;
  845. } finally {
  846. var length = split(o[p]).length;
  847. if (this.length !== length) { this.length = length; }
  848. }
  849. }
  850. },
  851. remove: {
  852. value: function (tokens___) {
  853. tokens = Array.prototype.slice.call(arguments).map(String);
  854. if (tokens.some(function(token) { return token.length === 0; })) {
  855. throw new SyntaxError();
  856. }
  857. if (tokens.some(function(token) { return /\s/.test(token); })) {
  858. throw new Error("InvalidCharacterError");
  859. }
  860. try {
  861. var underlying_string = o[p];
  862. tokens.forEach(function(token) {
  863. underlying_string = removeTokenFromString(token, underlying_string);
  864. });
  865. o[p] = underlying_string;
  866. } finally {
  867. var length = split(o[p]).length;
  868. if (this.length !== length) { this.length = length; }
  869. }
  870. }
  871. },
  872. toggle: {
  873. value: function (token, force) {
  874. try {
  875. token = String(token);
  876. if (token.length === 0) { throw new SyntaxError(); }
  877. if (/\s/.test(token)) { throw new Error("InvalidCharacterError"); }
  878. var tokens = split(o[p]),
  879. index = tokens.indexOf(token);
  880. if (index !== -1 && (!force || force === (void 0))) {
  881. o[p] = removeTokenFromString(token, o[p]);
  882. return false;
  883. }
  884. if (index !== -1 && force) {
  885. return true;
  886. }
  887. var underlying_string = o[p];
  888. if (underlying_string.length !== 0 && !/\s$/.test(underlying_string)) {
  889. underlying_string += ' ';
  890. }
  891. underlying_string += token;
  892. o[p] = underlying_string;
  893. return true;
  894. } finally {
  895. var length = split(o[p]).length;
  896. if (this.length !== length) { this.length = length; }
  897. }
  898. }
  899. },
  900. toString: {
  901. value: function () {
  902. return o[p];
  903. }
  904. }
  905. });
  906. if (!('length' in this)) {
  907. // In case getters are not supported
  908. this.length = split(o[p]).length;
  909. } else {
  910. // If they are, shim in index getters (up to 100)
  911. for (var i = 0; i < 100; ++i) {
  912. Object.defineProperty(this, String(i), {
  913. get: (function(n) { return function () { return this.item(n); }; }(i))
  914. });
  915. }
  916. }
  917. }
  918. function addToElementPrototype(p, f) {
  919. if ('Element' in window && Element.prototype && Object.defineProperty) {
  920. Object.defineProperty(Element.prototype, p, { get: f });
  921. }
  922. }
  923. if ('classList' in document.createElement('span')) {
  924. window.getClassList = function (elem) { return elem.classList; };
  925. } else {
  926. window.getClassList = function (elem) { return new DOMTokenListShim(elem, 'className'); };
  927. addToElementPrototype('classList', function() { return new DOMTokenListShim(this, 'className'); } );
  928. }
  929. if ('relList' in document.createElement('link')) {
  930. window.getRelList = function (elem) { return elem.relList; };
  931. } else {
  932. window.getRelList = function (elem) { return new DOMTokenListShim(elem, 'rel'); };
  933. addToElementPrototype('relList', function() { return new DOMTokenListShim(this, 'rel'); } );
  934. }
  935. }());
  936. if (!('dataset' in document.createElement('span')) &&
  937. 'Element' in window && Element.prototype && Object.defineProperty) {
  938. Object.defineProperty(Element.prototype, 'dataset', { get: function() {
  939. var result = Object.create(null);
  940. for (var i = 0; i < this.attributes.length; ++i) {
  941. var attr = this.attributes[i];
  942. if (attr.specified && attr.name.substring(0, 5) === 'data-') {
  943. (function(element, name) {
  944. Object.defineProperty(result, name, {
  945. get: function() {
  946. return element.getAttribute('data-' + name);
  947. },
  948. set: function(value) {
  949. element.setAttribute('data-' + name, value);
  950. }});
  951. }(this, attr.name.substring(5)));
  952. }
  953. }
  954. return result;
  955. }});
  956. }
  957. }
  958. //
  959. // Base64 utility methods (HTML5)
  960. //
  961. (function (global) {
  962. var B64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  963. global.atob = global.atob || function (input) {
  964. input = String(input);
  965. var position = 0,
  966. output = [],
  967. buffer = 0, bits = 0, n;
  968. input = input.replace(/\s/g, '');
  969. if ((input.length % 4) === 0) { input = input.replace(/=+$/, ''); }
  970. if ((input.length % 4) === 1) { throw new Error("InvalidCharacterError"); }
  971. if (/[^+/0-9A-Za-z]/.test(input)) { throw new Error("InvalidCharacterError"); }
  972. while (position < input.length) {
  973. n = B64_ALPHABET.indexOf(input.charAt(position));
  974. buffer = (buffer << 6) | n;
  975. bits += 6;
  976. if (bits === 24) {
  977. output.push(String.fromCharCode((buffer >> 16) & 0xFF));
  978. output.push(String.fromCharCode((buffer >> 8) & 0xFF));
  979. output.push(String.fromCharCode(buffer & 0xFF));
  980. bits = 0;
  981. buffer = 0;
  982. }
  983. position += 1;
  984. }
  985. if (bits === 12) {
  986. buffer = buffer >> 4;
  987. output.push(String.fromCharCode(buffer & 0xFF));
  988. } else if (bits === 18) {
  989. buffer = buffer >> 2;
  990. output.push(String.fromCharCode((buffer >> 8) & 0xFF));
  991. output.push(String.fromCharCode(buffer & 0xFF));
  992. }
  993. return output.join('');
  994. };
  995. global.btoa = global.btoa || function (input) {
  996. input = String(input);
  997. var position = 0,
  998. out = [],
  999. o1, o2, o3,
  1000. e1, e2, e3, e4;
  1001. if (/[^\x00-\xFF]/.test(input)) { throw new Error("InvalidCharacterError"); }
  1002. while (position < input.length) {
  1003. o1 = input.charCodeAt(position++);
  1004. o2 = input.charCodeAt(position++);
  1005. o3 = input.charCodeAt(position++);
  1006. // 111111 112222 222233 333333
  1007. e1 = o1 >> 2;
  1008. e2 = ((o1 & 0x3) << 4) | (o2 >> 4);
  1009. e3 = ((o2 & 0xf) << 2) | (o3 >> 6);
  1010. e4 = o3 & 0x3f;
  1011. if (position === input.length + 2) {
  1012. e3 = 64; e4 = 64;
  1013. }
  1014. else if (position === input.length + 1) {
  1015. e4 = 64;
  1016. }
  1017. out.push(B64_ALPHABET.charAt(e1),
  1018. B64_ALPHABET.charAt(e2),
  1019. B64_ALPHABET.charAt(e3),
  1020. B64_ALPHABET.charAt(e4));
  1021. }
  1022. return out.join('');
  1023. };
  1024. } (this));