Skip to content

Commit f7381ec

Browse files
author
SReject
committed
Bug fixing, code cleanup, more tests
Added: test for $JSONForEach on an object Fixed: Script not unloading in AdiIRC Fixed: /JSONHttpFetch -f failing Fixed: $JSON().ToFile not working Fixed: Bug within js's side forEach function failing to loop Change: All timers are now named offline connection-independant milisecond timers. Change: Rearranged position of certain js-side functions Change: cleaned up js's side forEach Change: increased version Improved: js-side comments
1 parent b15f887 commit f7381ec

3 files changed

Lines changed: 111 additions & 87 deletions

File tree

src/JSON For mIRC.js

Lines changed: 72 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,50 @@
11
/*jslint for:true*/
22
/*globals ActiveXObject, JSONCreate*/
33
(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+
}
448

549
// es5 .forEach() polyfill
650
Array.prototype.forEach = function (callback) {
@@ -9,7 +53,7 @@
953
}
1054
};
1155

12-
// es5 .find() polyfill
56+
// es6 .find() polyfill
1357
Array.prototype.find = function (callback) {
1458
for (var i = 0; i < this.length; i += 1) {
1559
if (callback.call(this, this[i])) {
@@ -29,18 +73,7 @@
2973
return keys;
3074
};
3175

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
4477
(JSON = {}).parse = function(i) {
4578
try {
4679
i = String(i).replace(/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, function(c) {
@@ -52,18 +85,17 @@
5285
} catch (e) {}
5386
throw new Error("INVALID_JSON");
5487
};
88+
89+
// es5 JSON.stringify polyfill
5590
JSON.stringify = function (value) {
5691
var type = getType(value),
5792
output = '[';
58-
if (value === undefined) {
93+
if (value === undefined || type === 'function') {
5994
return;
6095
}
6196
if (value === null) {
6297
return 'null';
6398
}
64-
if (type === 'function') {
65-
return;
66-
}
6799
if (type === 'number') {
68100
return isFinite(value) ? value.toString() : 'null';
69101
}
@@ -93,65 +125,38 @@
93125
});
94126
return '{' + output.join(',') + '}';
95127
};
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+
});
131136

132137
function JSONWrapper(parent, json) {
133138
if (parent === undefined) {
134139
parent = {};
135140
}
141+
if (json === undefined) {
142+
this._isChild = false;
143+
this._json = parent._json || {};
144+
} else {
145+
this._isChild = true;
146+
this._json = json;
147+
}
136148
this._state = parent._state || 'init';
137149
this._type = parent._type || 'text';
138150
this._parse = parent._parse === false ? false : true;
139151
this._error = parent._error || false;
140152
this._input = parent._input;
141-
this._isChild = false;
142153
this._http = parent._http || {
143154
method: 'GET',
144155
url: '',
145156
headers: [],
146157
data: null,
147158
timeout: 85000
148159
};
149-
if (json === undefined) {
150-
this._json = parent._json || {};
151-
} else {
152-
this._isChild = true;
153-
this._json = json;
154-
}
155160
}
156161

157162
JSONWrapper.prototype = {
@@ -223,7 +228,7 @@
223228
this._state = 'done';
224229
if (this._type === 'http') {
225230
try {
226-
var request = new ActiveXObject(JSONWrapper.HTTP);
231+
var request = new ActiveXObject(HTTPObject);
227232
request.open(this._http.method, this._http.url, false);
228233
this._http.headers.forEach(function (header) {
229234
request.setRequestHeader(header[0], header[1]);
@@ -305,33 +310,29 @@
305310
throw new Error('REFERENCE_NOT_FOUND');
306311
},
307312

308-
forEach: function (walk, fuzzy) {
313+
forEach: function () {
309314
var self = parsed(this),
310315
args = Array.prototype.slice.call(arguments),
311-
path = self._json.path.slice(0),
312316
type = self.type(),
313317
res = [],
314318
maxDepth = args[0] ? Infinity : 1;
315319

316-
args.pop(0);
320+
args.shift();
317321

318322
function addResult(item, path) {
319323
var ref = new JSONWrapper(self, {
320324
path: path,
321325
value: item
322-
}),
323-
params = args.slice(0);
326+
});
324327

325328
if (maxDepth !== Infinity && args.length > 1) {
326-
ref = ref.walk.apply(ref, params)
329+
ref = ref.walk.apply(ref, args.slice(0))
327330
}
328331
res.push(ref);
329332
}
330333

331334
function walk(item, path, depth) {
332335
var type = getType(item);
333-
334-
depth += 1;
335336
path = path.slice(0);
336337

337338
if (depth > maxDepth) {
@@ -341,14 +342,14 @@
341342
Object.keys(item).forEach(function (key) {
342343
var kpath = path.slice(0);
343344
kpath.push(key)
344-
walk(item[key], kpath, depth);
345+
walk(item[key], kpath, depth + 1);
345346
});
346347

347348
} else if (type === 'array') {
348349
item.forEach(function (value, index) {
349350
var kpath = path.slice(0);
350351
kpath.push(index);
351-
walk(value, kpath, depth);
352+
walk(value, kpath, depth +1);
352353
});
353354

354355
} else {
@@ -359,7 +360,7 @@
359360
if (type !== 'object' && type !== 'array') {
360361
throw new Error('ILLEGAL_REFERENCE');
361362
}
362-
walk(self._json.value, path, 1);
363+
walk(self._json.value, self._json.path.slice(0), 1);
363364
return res;
364365
},
365366

@@ -442,13 +443,6 @@
442443
}
443444
};
444445

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-
452446
JSONCreate = function(type, source, noparse) {
453447
var self = new JSONWrapper();
454448
self._state = 'init';

src/JSON For mIRC.mrc

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ on *:LOAD:{
1919
if ($~adiircexe) {
2020
if ($version < 2.6) {
2121
echo -a [JSON For mIRC] AdiIRC v2.6 or later is required
22+
.unload -rs $qt($script)
2223
}
2324
}
2425
elseif ($version < 7.44) {
@@ -220,7 +221,7 @@ alias JSONOpen {
220221
if (%Error) {
221222
set -eu0 %SReject/JSONForMirc/Error %Error
222223
if (%Com && $com(%Com)) {
223-
$+(.timer, %com) 1 0 JSONClose $unsafe($1)
224+
.timer $+ %Com -iom 1 0 JSONClose $unsafe($1)
224225
}
225226
jfm_log -EeD %Error
226227
}
@@ -229,7 +230,7 @@ alias JSONOpen {
229230
;; and then log the successful handler creation
230231
else {
231232
if (d isincs %Switches) {
232-
$+(.timer, %Com) -o 1 0 JSONClose $unsafe($1)
233+
.timer $+ %Com -iom 1 0 JSONClose $unsafe($1)
233234
}
234235
jfm_log -EsD Created $1 (as com %Com $+ )
235236
}
@@ -486,7 +487,7 @@ alias JSONHttpFetch {
486487

487488
;; if the -f switch is specified, read the file's contents into the temp bvar
488489
elseif (f isincs %Switches) {
489-
bread $qt($file($2-).longfn) 1 $file($2-).size %BVar
490+
bread $qt($file($2-).longfn) 0 $file($2-).size %BVar
490491
}
491492

492493
;; if no switches were specified, store the @data in the temp bvar
@@ -596,7 +597,7 @@ alias JSONClose {
596597
;; Close the com, turn off timers associated to the com and log the close
597598
.comclose %Com
598599
if ($timer(%Com)) {
599-
$+(.timer, %Com) off
600+
.timer $+ %Com off
600601
}
601602
jfm_log Closed %Com
602603
}
@@ -840,7 +841,7 @@ alias JSON {
840841
}
841842

842843
;; if the suffix is 'tofile', validate the 2nd parameter
843-
if (%Suffix, == tofile) {
844+
if (%Suffix == tofile) {
844845
if ($0 < 2) {
845846
%Error = INVALID_PARAMETERS
846847
}
@@ -930,7 +931,7 @@ alias JSON {
930931

931932
;; otherwise, close the child com after script execution, update the %Com variable to indicate the child com
932933
;; and decrease the indent for log lines
933-
$+(.timer, %ChildCom) -o 1 0 JSONClose %ChildCom
934+
.timer $+ %ChildCom -iom 1 0 JSONClose %ChildCom
934935
%Com = %ChildCom
935936
jfm_log
936937
}
@@ -1120,7 +1121,7 @@ alias JSONForEach {
11201121
else {
11211122

11221123
;; start a timer to close the com
1123-
.timer -m 1 0 JSONClose $unsafe(%com)
1124+
.timer $+ %Com -iom 1 0 JSONClose $unsafe(%Com)
11241125

11251126
;; check length
11261127
if (!$com(%Com, length, 2) || $comerr) {
@@ -1152,7 +1153,7 @@ alias JSONForEach {
11521153
;; if successful, start a timer to close the com and then call the specified command
11531154
else {
11541155
jfm_log -I Calling $iif(/ $+ * !iswm $2, /) $+ $2 %Name
1155-
$+(.timer, %Name) -m 1 0 JSONClose $unsafe(%Name)
1156+
.timer $+ %Name -iom 1 0 JSONClose $unsafe(%Name)
11561157
$2 %Name
11571158
jfm_log -D
11581159
}

test/JSON for mIRC - Tests.mrc

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ alias JSONTest {
55
var %x = 1, %fail
66
JSONShutDown
77
JSONDebug on
8+
window -n @SReject/JSONForMirc/Log
89
while ($isalias(jfm_test $+ %x)) {
910
tokenize 32 $jfm_test [ $+ [ %x ] ]
1011
if (!$1) {
@@ -433,7 +434,7 @@ alias -l jfm_test77 {
433434
alias -l jfm_test78 {
434435
set -u0 %_jfm_test78_forEachTest $false
435436
var %res = $JSONForEach($JSON(jfm_testvalues, array), _jfm_test78_forEachTest)
436-
if ($JSONError) return $false $!JSONForEach($JSON(jfm_testvalues, array), _jfm_test78_forEachTest)
437+
if ($JSONError) return $false $!JSONForEach($JSON(jfm_testvalues, array), _jfm_test78_forEachTest) $+([,$v1,])
437438
if (%_jfm_test78_forEachTest) return $false $v1
438439
if (3 !== %res) return $false $!JSONForEach($JSON(jfm_testvalues, array), _jfm_test78_forEachTest) == $v2
439440
unset %_jfm_test78_forEachTest
@@ -472,3 +473,31 @@ alias -l jfm_test80 {
472473
}
473474
return $true $!JSONVersion(short)
474475
}
476+
alias -l jfm_test81 {
477+
set -u0 %_jfm_test81_forEachTest $false
478+
var %res = $JSONForEach($JSON(jfm_testvalues, object), _jfm_test81_forEachTest)
479+
if ($JSONError) return $false $!JSONForEach($JSON(jfm_testvalues, object), _jfm_test81_forEachTest) $+([,$v1,])
480+
if (%_jfm_test81_forEachTest) return $false $v1
481+
if (3 !== %res) return $false $!JSONForEach($JSON(jfm_testvalues, object), _jfm_test81_forEachTest) == $v2
482+
unset %_jfm_test81_forEachTest
483+
return $true $!JSONForEach($JSON(jfm_testvalues, object), _jfm_test81_forEachTest)
484+
}
485+
alias _jfm_test81_forEachTest {
486+
if (!%_jfm_test81_forEachTest) {
487+
if ($0 !== 1) {
488+
set -u0 %_jfm_test81_forEachTest INVALID_PARAMETERS
489+
}
490+
elseif (!$com($1)) {
491+
set -u0 %_jfm_test81_forEachTest COM_DOESNOT_EXIST
492+
}
493+
else {
494+
var %res = $JSON($1).value
495+
if ($jsonerror) {
496+
set -u0 %_jfm_test81_forEachTest $v1
497+
}
498+
elseif (item* !iswm %Res) {
499+
set -u0 %_jfm_test81_forEachTest $!JSON( $+ $1 $+ ).value == %Res
500+
}
501+
}
502+
}
503+
}

0 commit comments

Comments
 (0)