|
1 | 1 | /*jslint for:true*/ |
2 | 2 | /*globals ActiveXObject, JSONCreate*/ |
3 | 3 | (function() { |
| 4 | + |
| 5 | + // returns the type of an input |
| 6 | + function getType(obj) { |
| 7 | + if (obj === null) return 'null'; |
| 8 | + return Object.prototype.toString.call(obj).match(/^\[object ([^\]]+)\]$/)[1].toLowerCase(); |
| 9 | + } |
| 10 | + |
| 11 | + // returns true if an input object has the specified property |
| 12 | + function hasOwnProp(obj, property) { |
| 13 | + return Object.prototype.hasOwnProperty.call(obj, property); |
| 14 | + } |
| 15 | + |
| 16 | + // Checks if an instance has been parsed |
| 17 | + // if not, an error is thrown otherwise the instance is returned |
| 18 | + function parsed(self) { |
| 19 | + if (self._state !== 'done' || self._error || !self._parse) { |
| 20 | + throw new Error('NOT_PARSED'); |
| 21 | + } |
| 22 | + return self; |
| 23 | + } |
| 24 | + |
| 25 | + // checks if an instance has a pending http request |
| 26 | + // if not, an error is thrown, otherwise the instance is returned |
| 27 | + function httpPending(self) { |
| 28 | + if (self._type !== 'http') { |
| 29 | + throw new Error('HTTP_NOT_INUSE'); |
| 30 | + } |
| 31 | + if (self._state !== 'http_pending') { |
| 32 | + throw new Error('HTTP_NOT_PENDING'); |
| 33 | + } |
| 34 | + return self._http; |
| 35 | + } |
| 36 | + |
| 37 | + // Checks if an instance http request has completed |
| 38 | + // if not, an error is thrown, otherwise the instance is returned |
| 39 | + function httpDone(self) { |
| 40 | + if (self._type !== 'http') { |
| 41 | + throw new Error('HTTP_NOT_INUSE'); |
| 42 | + } |
| 43 | + if (self._state !== 'done') { |
| 44 | + throw new Error('HTTP_PENDING'); |
| 45 | + } |
| 46 | + return self._http; |
| 47 | + } |
4 | 48 |
|
5 | 49 | // es5 .forEach() polyfill |
6 | 50 | Array.prototype.forEach = function (callback) { |
|
9 | 53 | } |
10 | 54 | }; |
11 | 55 |
|
12 | | - // es5 .find() polyfill |
| 56 | + // es6 .find() polyfill |
13 | 57 | Array.prototype.find = function (callback) { |
14 | 58 | for (var i = 0; i < this.length; i += 1) { |
15 | 59 | if (callback.call(this, this[i])) { |
|
29 | 73 | return keys; |
30 | 74 | }; |
31 | 75 |
|
32 | | - // returns the type of an input |
33 | | - function getType(obj) { |
34 | | - if (obj === null) return 'null'; |
35 | | - return Object.prototype.toString.call(obj).match(/^\[object ([^\]]+)\]$/)[1].toLowerCase(); |
36 | | - } |
37 | | - |
38 | | - // returns true if an input object has the specified property |
39 | | - function hasOwnProp(obj, property) { |
40 | | - return Object.prototype.hasOwnProperty.call(obj, property); |
41 | | - } |
42 | | - |
43 | | - // es5 JSON polyfill |
| 76 | + // es5 JSON.parse polyfill |
44 | 77 | (JSON = {}).parse = function(i) { |
45 | 78 | try { |
46 | 79 | i = String(i).replace(/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, function(c) { |
|
52 | 85 | } catch (e) {} |
53 | 86 | throw new Error("INVALID_JSON"); |
54 | 87 | }; |
| 88 | + |
| 89 | + // es5 JSON.stringify polyfill |
55 | 90 | JSON.stringify = function (value) { |
56 | 91 | var type = getType(value), |
57 | 92 | output = '['; |
58 | | - if (value === undefined) { |
| 93 | + if (value === undefined || type === 'function') { |
59 | 94 | return; |
60 | 95 | } |
61 | 96 | if (value === null) { |
62 | 97 | return 'null'; |
63 | 98 | } |
64 | | - if (type === 'function') { |
65 | | - return; |
66 | | - } |
67 | 99 | if (type === 'number') { |
68 | 100 | return isFinite(value) ? value.toString() : 'null'; |
69 | 101 | } |
|
93 | 125 | }); |
94 | 126 | return '{' + output.join(',') + '}'; |
95 | 127 | }; |
96 | | - |
97 | | - // Checks if an instance has been parsed |
98 | | - // if not, an error is thrown otherwise the instance is returned |
99 | | - function parsed(self) { |
100 | | - if (self._state !== 'done' || self._error || !self._parse) { |
101 | | - throw new Error('NOT_PARSED'); |
102 | | - } |
103 | | - return self; |
104 | | - } |
105 | | - |
106 | | - // checks if an instance has a pending http request |
107 | | - // if not, an error is thrown, otherwise the instance is returned |
108 | | - function httpPending(self) { |
109 | | - if (self._type !== 'http') { |
110 | | - throw new Error('HTTP_NOT_INUSE'); |
111 | | - } |
112 | | - if (self._state !== 'http_pending') { |
113 | | - throw new Error('HTTP_NOT_PENDING'); |
114 | | - } |
115 | | - return self._http; |
116 | | - } |
117 | | - |
118 | | - // Checks if an instance http request has completed |
119 | | - // if not, an error is thrown, otherwise the instance is returned |
120 | | - function httpDone(self) { |
121 | | - if (self._type !== 'http') { |
122 | | - throw new Error('HTTP_NOT_INUSE'); |
123 | | - } |
124 | | - if (self._state !== 'done') { |
125 | | - throw new Error('HTTP_PENDING'); |
126 | | - } |
127 | | - return self._http; |
128 | | - } |
129 | | - |
130 | | - |
| 128 | + |
| 129 | + |
| 130 | + HTTPObject = ['MSXML2.SERVERXMLHTTP.6.0', 'MSXML2.SERVERXMLHTTP.3.0', 'MSXML2.SERVERXMLHTTP'].find(function (xhr) { |
| 131 | + try { |
| 132 | + var test = new ActiveXObject(xhr); |
| 133 | + return xhr; |
| 134 | + } catch (ignore) {} |
| 135 | + }); |
131 | 136 |
|
132 | 137 | function JSONWrapper(parent, json) { |
133 | 138 | if (parent === undefined) { |
134 | 139 | parent = {}; |
135 | 140 | } |
| 141 | + if (json === undefined) { |
| 142 | + this._isChild = false; |
| 143 | + this._json = parent._json || {}; |
| 144 | + } else { |
| 145 | + this._isChild = true; |
| 146 | + this._json = json; |
| 147 | + } |
136 | 148 | this._state = parent._state || 'init'; |
137 | 149 | this._type = parent._type || 'text'; |
138 | 150 | this._parse = parent._parse === false ? false : true; |
139 | 151 | this._error = parent._error || false; |
140 | 152 | this._input = parent._input; |
141 | | - this._isChild = false; |
142 | 153 | this._http = parent._http || { |
143 | 154 | method: 'GET', |
144 | 155 | url: '', |
145 | 156 | headers: [], |
146 | 157 | data: null, |
147 | 158 | timeout: 85000 |
148 | 159 | }; |
149 | | - if (json === undefined) { |
150 | | - this._json = parent._json || {}; |
151 | | - } else { |
152 | | - this._isChild = true; |
153 | | - this._json = json; |
154 | | - } |
155 | 160 | } |
156 | 161 |
|
157 | 162 | JSONWrapper.prototype = { |
|
223 | 228 | this._state = 'done'; |
224 | 229 | if (this._type === 'http') { |
225 | 230 | try { |
226 | | - var request = new ActiveXObject(JSONWrapper.HTTP); |
| 231 | + var request = new ActiveXObject(HTTPObject); |
227 | 232 | request.open(this._http.method, this._http.url, false); |
228 | 233 | this._http.headers.forEach(function (header) { |
229 | 234 | request.setRequestHeader(header[0], header[1]); |
|
305 | 310 | throw new Error('REFERENCE_NOT_FOUND'); |
306 | 311 | }, |
307 | 312 |
|
308 | | - forEach: function (walk, fuzzy) { |
| 313 | + forEach: function () { |
309 | 314 | var self = parsed(this), |
310 | 315 | args = Array.prototype.slice.call(arguments), |
311 | | - path = self._json.path.slice(0), |
312 | 316 | type = self.type(), |
313 | 317 | res = [], |
314 | 318 | maxDepth = args[0] ? Infinity : 1; |
315 | 319 |
|
316 | | - args.pop(0); |
| 320 | + args.shift(); |
317 | 321 |
|
318 | 322 | function addResult(item, path) { |
319 | 323 | var ref = new JSONWrapper(self, { |
320 | 324 | path: path, |
321 | 325 | value: item |
322 | | - }), |
323 | | - params = args.slice(0); |
| 326 | + }); |
324 | 327 |
|
325 | 328 | if (maxDepth !== Infinity && args.length > 1) { |
326 | | - ref = ref.walk.apply(ref, params) |
| 329 | + ref = ref.walk.apply(ref, args.slice(0)) |
327 | 330 | } |
328 | 331 | res.push(ref); |
329 | 332 | } |
330 | 333 |
|
331 | 334 | function walk(item, path, depth) { |
332 | 335 | var type = getType(item); |
333 | | - |
334 | | - depth += 1; |
335 | 336 | path = path.slice(0); |
336 | 337 |
|
337 | 338 | if (depth > maxDepth) { |
|
341 | 342 | Object.keys(item).forEach(function (key) { |
342 | 343 | var kpath = path.slice(0); |
343 | 344 | kpath.push(key) |
344 | | - walk(item[key], kpath, depth); |
| 345 | + walk(item[key], kpath, depth + 1); |
345 | 346 | }); |
346 | 347 |
|
347 | 348 | } else if (type === 'array') { |
348 | 349 | item.forEach(function (value, index) { |
349 | 350 | var kpath = path.slice(0); |
350 | 351 | kpath.push(index); |
351 | | - walk(value, kpath, depth); |
| 352 | + walk(value, kpath, depth +1); |
352 | 353 | }); |
353 | 354 |
|
354 | 355 | } else { |
|
359 | 360 | if (type !== 'object' && type !== 'array') { |
360 | 361 | throw new Error('ILLEGAL_REFERENCE'); |
361 | 362 | } |
362 | | - walk(self._json.value, path, 1); |
| 363 | + walk(self._json.value, self._json.path.slice(0), 1); |
363 | 364 | return res; |
364 | 365 | }, |
365 | 366 |
|
|
442 | 443 | } |
443 | 444 | }; |
444 | 445 |
|
445 | | - JSONWrapper.HTTP = ['MSXML2.SERVERXMLHTTP.6.0', 'MSXML2.SERVERXMLHTTP.3.0', 'MSXML2.SERVERXMLHTTP'].find(function (xhr) { |
446 | | - try { |
447 | | - var test = new ActiveXObject(xhr); |
448 | | - return xhr; |
449 | | - } catch (ignore) {} |
450 | | - }); |
451 | | - |
452 | 446 | JSONCreate = function(type, source, noparse) { |
453 | 447 | var self = new JSONWrapper(); |
454 | 448 | self._state = 'init'; |
|
0 commit comments