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) { |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Loading history...
|
|||
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) { |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
|
|||
66 | // In IE8 try built-in implementation for defining properties on DOM prototypes. |
||
67 | if (orig) { try { return orig(o, prop, desc); } catch (e) {} } |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
Best Practice
introduced
by
|
|||
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) { |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
|
|||
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; |
||
0 ignored issues
–
show
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later. Consider: if (a > 0)
b = 42;
If you or someone else later decides to put another statement in, only the first statement will be executed. if (a > 0)
console.log("a > 0");
b = 42;
In this case the statement if (a > 0) {
console.log("a > 0");
b = 42;
}
ensures that the proper code will be executed conditionally no matter how many statements are added or removed.
Loading history...
|
|||
138 | bound.prototype = new nop(); |
||
0 ignored issues
–
show
|
|||
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]'); }; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
|
|||
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(); } |
||
0 ignored issues
–
show
|
|||
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(); } |
||
0 ignored issues
–
show
|
|||
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(); } |
||
0 ignored issues
–
show
|
|||
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) { |
|
0 ignored issues
–
show
|
|||
250 | Array.prototype.some = function (fun /*, thisp */) { |
||
251 | if (this === void 0 || this === null) { throw TypeError(); } |
||
0 ignored issues
–
show
|
|||
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(); } |
||
0 ignored issues
–
show
|
|||
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) { |
|
0 ignored issues
–
show
|
|||
291 | Array.prototype.map = function (fun /*, thisp */) { |
||
292 | if (this === void 0 || this === null) { throw TypeError(); } |
||
0 ignored issues
–
show
|
|||
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(); } |
||
0 ignored issues
–
show
|
|||
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(); } |
||
0 ignored issues
–
show
|
|||
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
|
|||
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(); } |
||
0 ignored issues
–
show
|
|||
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 () { |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
|
|||
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() { |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
|
|||
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 ? { |
||
0 ignored issues
–
show
|
|||
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 |