1 | /*! |
||
2 | * @see https://github.com/inexorabletash/polyfill/blob/master/es5.js |
||
3 | */ |
||
4 | //---------------------------------------------------------------------- |
||
5 | // |
||
6 | // ECMAScript 5 Polyfills |
||
7 | // |
||
8 | //---------------------------------------------------------------------- |
||
9 | |||
10 | //---------------------------------------------------------------------- |
||
11 | // ES5 15.2 Object Objects |
||
12 | //---------------------------------------------------------------------- |
||
13 | |||
14 | // |
||
15 | // ES5 15.2.3 Properties of the Object Constructor |
||
16 | // |
||
17 | |||
18 | // ES5 15.2.3.2 Object.getPrototypeOf ( O ) |
||
19 | // From http://ejohn.org/blog/objectgetprototypeof/ |
||
20 | // NOTE: won't work for typical function T() {}; T.prototype = {}; new T; case |
||
21 | // since the constructor property is destroyed. |
||
22 | if (!Object.getPrototypeOf) { |
||
23 | Object.getPrototypeOf = function (o) { |
||
24 | if (o !== Object(o)) { throw TypeError("Object.getPrototypeOf called on non-object"); } |
||
25 | return o.__proto__ || o.constructor.prototype || Object.prototype; |
||
26 | }; |
||
27 | } |
||
28 | |||
29 | // ES5 15.2.3.4 Object.getOwnPropertyNames ( O ) |
||
30 | if (typeof Object.getOwnPropertyNames !== "function") { |
||
31 | Object.getOwnPropertyNames = function (o) { |
||
32 | if (o !== Object(o)) { throw TypeError("Object.getOwnPropertyNames called on non-object"); } |
||
33 | var props = [], p; |
||
34 | for (p in o) { |
||
35 | if (Object.prototype.hasOwnProperty.call(o, p)) { |
||
36 | props.push(p); |
||
37 | } |
||
38 | } |
||
39 | return props; |
||
40 | }; |
||
41 | } |
||
42 | |||
43 | // ES5 15.2.3.5 Object.create ( O [, Properties] ) |
||
44 | if (typeof Object.create !== "function") { |
||
45 | Object.create = function (prototype, properties) { |
||
46 | if (typeof prototype !== "object") { throw TypeError(); } |
||
47 | function Ctor() {} |
||
48 | Ctor.prototype = prototype; |
||
49 | var o = new Ctor(); |
||
50 | if (prototype) { o.constructor = Ctor; } |
||
51 | if (properties !== undefined) { |
||
52 | if (properties !== Object(properties)) { throw TypeError(); } |
||
53 | Object.defineProperties(o, properties); |
||
54 | } |
||
55 | return o; |
||
56 | }; |
||
57 | } |
||
58 | |||
59 | // ES 15.2.3.6 Object.defineProperty ( O, P, Attributes ) |
||
60 | // Partial support for most common case - getters, setters, and values |
||
61 | (function() { |
||
62 | if (!Object.defineProperty || |
||
63 | !(function () { try { Object.defineProperty({}, 'x', {}); return true; } catch (e) { return false; } } ())) { |
||
64 | var orig = Object.defineProperty; |
||
65 | Object.defineProperty = function (o, prop, desc) { |
||
66 | // In IE8 try built-in implementation for defining properties on DOM prototypes. |
||
67 | if (orig) { try { return orig(o, prop, desc); } catch (e) {} } |
||
68 | |||
69 | if (o !== Object(o)) { throw TypeError("Object.defineProperty called on non-object"); } |
||
70 | if (Object.prototype.__defineGetter__ && ('get' in desc)) { |
||
71 | Object.prototype.__defineGetter__.call(o, prop, desc.get); |
||
72 | } |
||
73 | if (Object.prototype.__defineSetter__ && ('set' in desc)) { |
||
74 | Object.prototype.__defineSetter__.call(o, prop, desc.set); |
||
75 | } |
||
76 | if ('value' in desc) { |
||
77 | o[prop] = desc.value; |
||
78 | } |
||
79 | return o; |
||
80 | }; |
||
81 | } |
||
82 | }()); |
||
83 | |||
84 | // ES 15.2.3.7 Object.defineProperties ( O, Properties ) |
||
85 | if (typeof Object.defineProperties !== "function") { |
||
86 | Object.defineProperties = function (o, properties) { |
||
87 | if (o !== Object(o)) { throw TypeError("Object.defineProperties called on non-object"); } |
||
88 | var name; |
||
89 | for (name in properties) { |
||
90 | if (Object.prototype.hasOwnProperty.call(properties, name)) { |
||
91 | Object.defineProperty(o, name, properties[name]); |
||
92 | } |
||
93 | } |
||
94 | return o; |
||
95 | }; |
||
96 | } |
||
97 | |||
98 | |||
99 | // ES5 15.2.3.14 Object.keys ( O ) |
||
100 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys |
||
101 | if (!Object.keys) { |
||
102 | Object.keys = function (o) { |
||
103 | if (o !== Object(o)) { throw TypeError('Object.keys called on non-object'); } |
||
104 | var ret = [], p; |
||
105 | for (p in o) { |
||
106 | if (Object.prototype.hasOwnProperty.call(o, p)) { |
||
107 | ret.push(p); |
||
108 | } |
||
109 | } |
||
110 | return ret; |
||
111 | }; |
||
112 | } |
||
113 | |||
114 | //---------------------------------------------------------------------- |
||
115 | // ES5 15.3 Function Objects |
||
116 | //---------------------------------------------------------------------- |
||
117 | |||
118 | // |
||
119 | // ES5 15.3.4 Properties of the Function Prototype Object |
||
120 | // |
||
121 | |||
122 | // ES5 15.3.4.5 Function.prototype.bind ( thisArg [, arg1 [, arg2, ... ]] ) |
||
123 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind |
||
124 | if (!Function.prototype.bind) { |
||
125 | Function.prototype.bind = function (o) { |
||
126 | if (typeof this !== 'function') { throw TypeError("Bind must be called on a function"); } |
||
127 | |||
128 | var args = Array.prototype.slice.call(arguments, 1), |
||
129 | self = this, |
||
130 | nop = function() {}, |
||
131 | bound = function () { |
||
132 | return self.apply(this instanceof nop ? this : o, |
||
133 | args.concat(Array.prototype.slice.call(arguments))); |
||
134 | }; |
||
135 | |||
136 | if (this.prototype) |
||
137 | nop.prototype = this.prototype; |
||
138 | bound.prototype = new nop(); |
||
139 | return bound; |
||
140 | }; |
||
141 | } |
||
142 | |||
143 | |||
144 | //---------------------------------------------------------------------- |
||
145 | // ES5 15.4 Array Objects |
||
146 | //---------------------------------------------------------------------- |
||
147 | |||
148 | // |
||
149 | // ES5 15.4.3 Properties of the Array Constructor |
||
150 | // |
||
151 | |||
152 | |||
153 | // ES5 15.4.3.2 Array.isArray ( arg ) |
||
154 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray |
||
155 | Array.isArray = Array.isArray || function (o) { return Boolean(o && Object.prototype.toString.call(Object(o)) === '[object Array]'); }; |
||
156 | |||
157 | |||
158 | // |
||
159 | // ES5 15.4.4 Properties of the Array Prototype Object |
||
160 | // |
||
161 | |||
162 | // ES5 15.4.4.14 Array.prototype.indexOf ( searchElement [ , fromIndex ] ) |
||
163 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf |
||
164 | if (!Array.prototype.indexOf) { |
||
165 | Array.prototype.indexOf = function (searchElement /*, fromIndex */) { |
||
166 | if (this === void 0 || this === null) { throw TypeError(); } |
||
167 | |||
168 | var t = Object(this); |
||
169 | var len = t.length >>> 0; |
||
170 | if (len === 0) { return -1; } |
||
171 | |||
172 | var n = 0; |
||
173 | if (arguments.length > 0) { |
||
174 | n = Number(arguments[1]); |
||
175 | if (isNaN(n)) { |
||
176 | n = 0; |
||
177 | } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { |
||
178 | n = (n > 0 || -1) * Math.floor(Math.abs(n)); |
||
179 | } |
||
180 | } |
||
181 | |||
182 | if (n >= len) { return -1; } |
||
183 | |||
184 | var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); |
||
185 | |||
186 | for (; k < len; k++) { |
||
187 | if (k in t && t[k] === searchElement) { |
||
188 | return k; |
||
189 | } |
||
190 | } |
||
191 | return -1; |
||
192 | }; |
||
193 | } |
||
194 | |||
195 | // ES5 15.4.4.15 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] ) |
||
196 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf |
||
197 | if (!Array.prototype.lastIndexOf) { |
||
198 | Array.prototype.lastIndexOf = function (searchElement /*, fromIndex*/) { |
||
199 | if (this === void 0 || this === null) { throw TypeError(); } |
||
200 | |||
201 | var t = Object(this); |
||
202 | var len = t.length >>> 0; |
||
203 | if (len === 0) { return -1; } |
||
204 | |||
205 | var n = len; |
||
206 | if (arguments.length > 1) { |
||
207 | n = Number(arguments[1]); |
||
208 | if (n !== n) { |
||
209 | n = 0; |
||
210 | } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { |
||
211 | n = (n > 0 || -1) * Math.floor(Math.abs(n)); |
||
212 | } |
||
213 | } |
||
214 | |||
215 | var k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); |
||
216 | |||
217 | for (; k >= 0; k--) { |
||
218 | if (k in t && t[k] === searchElement) { |
||
219 | return k; |
||
220 | } |
||
221 | } |
||
222 | return -1; |
||
223 | }; |
||
224 | } |
||
225 | |||
226 | // ES5 15.4.4.16 Array.prototype.every ( callbackfn [ , thisArg ] ) |
||
227 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every |
||
228 | if (!Array.prototype.every) { |
||
229 | Array.prototype.every = function (fun /*, thisp */) { |
||
230 | if (this === void 0 || this === null) { throw TypeError(); } |
||
231 | |||
232 | var t = Object(this); |
||
233 | var len = t.length >>> 0; |
||
234 | if (typeof fun !== "function") { throw TypeError(); } |
||
235 | |||
236 | var thisp = arguments[1], i; |
||
237 | for (i = 0; i < len; i++) { |
||
238 | if (i in t && !fun.call(thisp, t[i], i, t)) { |
||
239 | return false; |
||
240 | } |
||
241 | } |
||
242 | |||
243 | return true; |
||
244 | }; |
||
245 | } |
||
246 | |||
247 | // ES5 15.4.4.17 Array.prototype.some ( callbackfn [ , thisArg ] ) |
||
248 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some |
||
249 | View Code Duplication | if (!Array.prototype.some) { |
|
250 | Array.prototype.some = function (fun /*, thisp */) { |
||
251 | if (this === void 0 || this === null) { throw TypeError(); } |
||
252 | |||
253 | var t = Object(this); |
||
254 | var len = t.length >>> 0; |
||
255 | if (typeof fun !== "function") { throw TypeError(); } |
||
256 | |||
257 | var thisp = arguments[1], i; |
||
258 | for (i = 0; i < len; i++) { |
||
259 | if (i in t && fun.call(thisp, t[i], i, t)) { |
||
260 | return true; |
||
261 | } |
||
262 | } |
||
263 | |||
264 | return false; |
||
265 | }; |
||
266 | } |
||
267 | |||
268 | // ES5 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] ) |
||
269 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach |
||
270 | if (!Array.prototype.forEach) { |
||
271 | Array.prototype.forEach = function (fun /*, thisp */) { |
||
272 | if (this === void 0 || this === null) { throw TypeError(); } |
||
273 | |||
274 | var t = Object(this); |
||
275 | var len = t.length >>> 0; |
||
276 | if (typeof fun !== "function") { throw TypeError(); } |
||
277 | |||
278 | var thisp = arguments[1], i; |
||
279 | for (i = 0; i < len; i++) { |
||
280 | if (i in t) { |
||
281 | fun.call(thisp, t[i], i, t); |
||
282 | } |
||
283 | } |
||
284 | }; |
||
285 | } |
||
286 | |||
287 | |||
288 | // ES5 15.4.4.19 Array.prototype.map ( callbackfn [ , thisArg ] ) |
||
289 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Map |
||
290 | View Code Duplication | if (!Array.prototype.map) { |
|
291 | Array.prototype.map = function (fun /*, thisp */) { |
||
292 | if (this === void 0 || this === null) { throw TypeError(); } |
||
293 | |||
294 | var t = Object(this); |
||
295 | var len = t.length >>> 0; |
||
296 | if (typeof fun !== "function") { throw TypeError(); } |
||
297 | |||
298 | var res = []; res.length = len; |
||
299 | var thisp = arguments[1], i; |
||
300 | for (i = 0; i < len; i++) { |
||
301 | if (i in t) { |
||
302 | res[i] = fun.call(thisp, t[i], i, t); |
||
303 | } |
||
304 | } |
||
305 | |||
306 | return res; |
||
307 | }; |
||
308 | } |
||
309 | |||
310 | // ES5 15.4.4.20 Array.prototype.filter ( callbackfn [ , thisArg ] ) |
||
311 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Filter |
||
312 | if (!Array.prototype.filter) { |
||
313 | Array.prototype.filter = function (fun /*, thisp */) { |
||
314 | if (this === void 0 || this === null) { throw TypeError(); } |
||
315 | |||
316 | var t = Object(this); |
||
317 | var len = t.length >>> 0; |
||
318 | if (typeof fun !== "function") { throw TypeError(); } |
||
319 | |||
320 | var res = []; |
||
321 | var thisp = arguments[1], i; |
||
322 | for (i = 0; i < len; i++) { |
||
323 | if (i in t) { |
||
324 | var val = t[i]; // in case fun mutates this |
||
325 | if (fun.call(thisp, val, i, t)) { |
||
326 | res.push(val); |
||
327 | } |
||
328 | } |
||
329 | } |
||
330 | |||
331 | return res; |
||
332 | }; |
||
333 | } |
||
334 | |||
335 | |||
336 | // ES5 15.4.4.21 Array.prototype.reduce ( callbackfn [ , initialValue ] ) |
||
337 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce |
||
338 | if (!Array.prototype.reduce) { |
||
339 | Array.prototype.reduce = function (fun /*, initialValue */) { |
||
340 | if (this === void 0 || this === null) { throw TypeError(); } |
||
341 | |||
342 | var t = Object(this); |
||
343 | var len = t.length >>> 0; |
||
344 | if (typeof fun !== "function") { throw TypeError(); } |
||
345 | |||
346 | // no value to return if no initial value and an empty array |
||
347 | if (len === 0 && arguments.length === 1) { throw TypeError(); } |
||
348 | |||
349 | var k = 0; |
||
350 | var accumulator; |
||
351 | if (arguments.length >= 2) { |
||
352 | accumulator = arguments[1]; |
||
353 | } else { |
||
354 | do { |
||
355 | if (k in t) { |
||
356 | accumulator = t[k++]; |
||
357 | break; |
||
358 | } |
||
359 | |||
360 | // if array contains no values, no initial value to return |
||
361 | if (++k >= len) { throw TypeError(); } |
||
362 | } |
||
363 | while (true); |
||
364 | } |
||
365 | |||
366 | while (k < len) { |
||
367 | if (k in t) { |
||
368 | accumulator = fun.call(undefined, accumulator, t[k], k, t); |
||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
369 | } |
||
370 | k++; |
||
371 | } |
||
372 | |||
373 | return accumulator; |
||
374 | }; |
||
375 | } |
||
376 | |||
377 | |||
378 | // ES5 15.4.4.22 Array.prototype.reduceRight ( callbackfn [, initialValue ] ) |
||
379 | // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/ReduceRight |
||
380 | if (!Array.prototype.reduceRight) { |
||
381 | Array.prototype.reduceRight = function (callbackfn /*, initialValue */) { |
||
382 | if (this === void 0 || this === null) { throw TypeError(); } |
||
383 | |||
384 | var t = Object(this); |
||
385 | var len = t.length >>> 0; |
||
386 | if (typeof callbackfn !== "function") { throw TypeError(); } |
||
387 | |||
388 | // no value to return if no initial value, empty array |
||
389 | if (len === 0 && arguments.length === 1) { throw TypeError(); } |
||
390 | |||
391 | var k = len - 1; |
||
392 | var accumulator; |
||
393 | if (arguments.length >= 2) { |
||
394 | accumulator = arguments[1]; |
||
395 | } else { |
||
396 | do { |
||
397 | if (k in this) { |
||
398 | accumulator = this[k--]; |
||
399 | break; |
||
400 | } |
||
401 | |||
402 | // if array contains no values, no initial value to return |
||
403 | if (--k < 0) { throw TypeError(); } |
||
404 | } |
||
405 | while (true); |
||
406 | } |
||
407 | |||
408 | while (k >= 0) { |
||
409 | if (k in t) { |
||
410 | accumulator = callbackfn.call(undefined, accumulator, t[k], k, t); |
||
0 ignored issues
–
show
|
|||
411 | } |
||
412 | k--; |
||
413 | } |
||
414 | |||
415 | return accumulator; |
||
416 | }; |
||
417 | } |
||
418 | |||
419 | |||
420 | //---------------------------------------------------------------------- |
||
421 | // ES5 15.5 String Objects |
||
422 | //---------------------------------------------------------------------- |
||
423 | |||
424 | // |
||
425 | // ES5 15.5.4 Properties of the String Prototype Object |
||
426 | // |
||
427 | |||
428 | |||
429 | // ES5 15.5.4.20 String.prototype.trim() |
||
430 | if (!String.prototype.trim) { |
||
431 | String.prototype.trim = function () { |
||
432 | return String(this).replace(/^\s+/, '').replace(/\s+$/, ''); |
||
433 | }; |
||
434 | } |
||
435 | |||
436 | |||
437 | |||
438 | //---------------------------------------------------------------------- |
||
439 | // ES5 15.9 Date Objects |
||
440 | //---------------------------------------------------------------------- |
||
441 | |||
442 | |||
443 | // |
||
444 | // ES 15.9.4 Properties of the Date Constructor |
||
445 | // |
||
446 | |||
447 | // ES5 15.9.4.4 Date.now ( ) |
||
448 | // From https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date/now |
||
449 | if (!Date.now) { |
||
450 | Date.now = function now() { |
||
451 | return Number(new Date()); |
||
452 | }; |
||
453 | } |
||
454 | |||
455 | |||
456 | // |
||
457 | // ES5 15.9.5 Properties of the Date Prototype Object |
||
458 | // |
||
459 | |||
460 | // ES5 15.9.4.43 Date.prototype.toISOString ( ) |
||
461 | // Inspired by http://www.json.org/json2.js |
||
462 | if (!Date.prototype.toISOString) { |
||
463 | Date.prototype.toISOString = function () { |
||
464 | function pad2(n) { return ('00' + n).slice(-2); } |
||
465 | function pad3(n) { return ('000' + n).slice(-3); } |
||
466 | |||
467 | return this.getUTCFullYear() + '-' + |
||
468 | pad2(this.getUTCMonth() + 1) + '-' + |
||
469 | pad2(this.getUTCDate()) + 'T' + |
||
470 | pad2(this.getUTCHours()) + ':' + |
||
471 | pad2(this.getUTCMinutes()) + ':' + |
||
472 | pad2(this.getUTCSeconds()) + '.' + |
||
473 | pad3(this.getUTCMilliseconds()) + 'Z'; |
||
474 | }; |
||
475 | } |
||
476 | |||
477 | /*! |
||
478 | * @see https://gist.github.com/jhermsmeier/9a34b06a107bbf5d2c91 |
||
479 | */ |
||
480 | Object.getOwnPropertyDescriptor = function( object, key ) { |
||
481 | |||
482 | var hasSupport = |
||
483 | typeof object.__lookupGetter__ === 'function' && |
||
484 | typeof object.__lookupSetter__ === 'function' |
||
485 | |||
486 | // TODO: How does one determine this?! |
||
487 | var isGetterSetter = !hasSupport ? null : |
||
488 | object.__lookupGetter__( key ) || |
||
489 | object.__lookupSetter__( key ) |
||
490 | |||
491 | return isGetterSetter != null ? { |
||
492 | configurable: true, |
||
493 | enumerable: true, |
||
494 | get: object.__lookupGetter__( key ), |
||
495 | set: object.__lookupSetter__( key ) |
||
496 | } : { |
||
497 | configurable: true, |
||
498 | writable: true, |
||
499 | enumerable: true, |
||
500 | value: object[ key ] |
||
501 | } |
||
502 | |||
503 | } |
||
504 |