1
+ // These polyfills taken from MDN (developer.mozilla.org)
2
+
3
+ // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
4
+ if ( ! Object . keys ) {
5
+ Object . keys = ( function ( ) {
6
+ 'use strict' ;
7
+ var hasOwnProperty = Object . prototype . hasOwnProperty ,
8
+ hasDontEnumBug = ! ( { toString : null } ) . propertyIsEnumerable ( 'toString' ) ,
9
+ dontEnums = [
10
+ 'toString' ,
11
+ 'toLocaleString' ,
12
+ 'valueOf' ,
13
+ 'hasOwnProperty' ,
14
+ 'isPrototypeOf' ,
15
+ 'propertyIsEnumerable' ,
16
+ 'constructor'
17
+ ] ,
18
+ dontEnumsLength = dontEnums . length ;
19
+
20
+ return function ( obj ) {
21
+ if ( typeof obj !== 'object' && ( typeof obj !== 'function' || obj === null ) ) {
22
+ throw new TypeError ( 'Object.keys called on non-object' ) ;
23
+ }
24
+
25
+ var result = [ ] , prop , i ;
26
+
27
+ for ( prop in obj ) {
28
+ if ( hasOwnProperty . call ( obj , prop ) ) {
29
+ result . push ( prop ) ;
30
+ }
31
+ }
32
+
33
+ if ( hasDontEnumBug ) {
34
+ for ( i = 0 ; i < dontEnumsLength ; i ++ ) {
35
+ if ( hasOwnProperty . call ( obj , dontEnums [ i ] ) ) {
36
+ result . push ( dontEnums [ i ] ) ;
37
+ }
38
+ }
39
+ }
40
+ return result ;
41
+ } ;
42
+ } ( ) ) ;
43
+ }
44
+
45
+ // Production steps of ECMA-262, Edition 5, 15.4.4.18
46
+ // Reference: http://es5.github.io/#x15.4.4.18
47
+ if ( ! Array . prototype . forEach ) {
48
+
49
+ Array . prototype . forEach = function ( callback , thisArg ) {
50
+
51
+ var T , k ;
52
+
53
+ if ( this == null ) {
54
+ throw new TypeError ( ' this is null or not defined' ) ;
55
+ }
56
+
57
+ // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
58
+ var O = Object ( this ) ;
59
+
60
+ // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
61
+ // 3. Let len be ToUint32(lenValue).
62
+ var len = O . length >>> 0 ;
63
+
64
+ // 4. If IsCallable(callback) is false, throw a TypeError exception.
65
+ // See: http://es5.github.com/#x9.11
66
+ if ( typeof callback !== "function" ) {
67
+ throw new TypeError ( callback + ' is not a function' ) ;
68
+ }
69
+
70
+ // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
71
+ if ( arguments . length > 1 ) {
72
+ T = thisArg ;
73
+ }
74
+
75
+ // 6. Let k be 0
76
+ k = 0 ;
77
+
78
+ // 7. Repeat, while k < len
79
+ while ( k < len ) {
80
+
81
+ var kValue ;
82
+
83
+ // a. Let Pk be ToString(k).
84
+ // This is implicit for LHS operands of the in operator
85
+ // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
86
+ // This step can be combined with c
87
+ // c. If kPresent is true, then
88
+ if ( k in O ) {
89
+
90
+ // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
91
+ kValue = O [ k ] ;
92
+
93
+ // ii. Call the Call internal method of callback with T as the this value and
94
+ // argument list containing kValue, k, and O.
95
+ callback . call ( T , kValue , k , O ) ;
96
+ }
97
+ // d. Increase k by 1.
98
+ k ++ ;
99
+ }
100
+ // 8. return undefined
101
+ } ;
102
+ }
103
+
104
+ // Production steps of ECMA-262, Edition 5, 15.4.4.14
105
+ // Reference: http://es5.github.io/#x15.4.4.14
106
+ if ( ! Array . prototype . indexOf ) {
107
+ Array . prototype . indexOf = function ( searchElement , fromIndex ) {
108
+
109
+ var k ;
110
+
111
+ // 1. Let O be the result of calling ToObject passing
112
+ // the this value as the argument.
113
+ if ( this == null ) {
114
+ throw new TypeError ( '"this" is null or not defined' ) ;
115
+ }
116
+
117
+ var O = Object ( this ) ;
118
+
119
+ // 2. Let lenValue be the result of calling the Get
120
+ // internal method of O with the argument "length".
121
+ // 3. Let len be ToUint32(lenValue).
122
+ var len = O . length >>> 0 ;
123
+
124
+ // 4. If len is 0, return -1.
125
+ if ( len === 0 ) {
126
+ return - 1 ;
127
+ }
128
+
129
+ // 5. If argument fromIndex was passed let n be
130
+ // ToInteger(fromIndex); else let n be 0.
131
+ var n = + fromIndex || 0 ;
132
+
133
+ if ( Math . abs ( n ) === Infinity ) {
134
+ n = 0 ;
135
+ }
136
+
137
+ // 6. If n >= len, return -1.
138
+ if ( n >= len ) {
139
+ return - 1 ;
140
+ }
141
+
142
+ // 7. If n >= 0, then Let k be n.
143
+ // 8. Else, n<0, Let k be len - abs(n).
144
+ // If k is less than 0, then let k be 0.
145
+ k = Math . max ( n >= 0 ? n : len - Math . abs ( n ) , 0 ) ;
146
+
147
+ // 9. Repeat, while k < len
148
+ while ( k < len ) {
149
+ // a. Let Pk be ToString(k).
150
+ // This is implicit for LHS operands of the in operator
151
+ // b. Let kPresent be the result of calling the
152
+ // HasProperty internal method of O with argument Pk.
153
+ // This step can be combined with c
154
+ // c. If kPresent is true, then
155
+ // i. Let elementK be the result of calling the Get
156
+ // internal method of O with the argument ToString(k).
157
+ // ii. Let same be the result of applying the
158
+ // Strict Equality Comparison Algorithm to
159
+ // searchElement and elementK.
160
+ // iii. If same is true, return k.
161
+ if ( k in O && O [ k ] === searchElement ) {
162
+ return k ;
163
+ }
164
+ k ++ ;
165
+ }
166
+ return - 1 ;
167
+ } ;
168
+ }
0 commit comments