Skip to content

Commit 05937b5

Browse files
committed
Emit each top-level node as separate data events
1 parent 3242eee commit 05937b5

File tree

16 files changed

+76
-69
lines changed

16 files changed

+76
-69
lines changed

index.js

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ util.inherits(JSONMLParser, Transform);
99
function JSONMLParser() {
1010
Transform.call(this);
1111
this._readableState.objectMode = true;
12-
this._parent = [];
1312
this.source = new Parser(this._createSourceOptions());
1413
}
1514

@@ -21,37 +20,41 @@ JSONMLParser.prototype._transform = function(chunk, encoding, done) {
2120
JSONMLParser.prototype._flush = function(done) {
2221
this._onParseDone = done;
2322
this.source.end();
24-
done();
2523
};
2624

2725
JSONMLParser.prototype._createSourceOptions = function() {
2826
var transform = this;
27+
var parent;
2928
return {
3029
onopentag: function(tagName, attributes) {
3130
var element = [tagName];
3231
if (!isEmpty(attributes)) {
3332
element.push(attributes);
3433
}
35-
transform._parent.push(element);
36-
element.parent = transform._parent;
37-
transform._parent = element;
34+
if (parent) {
35+
parent.push(element);
36+
element.parent = parent;
37+
}
38+
parent = element;
3839
},
3940
ontext: function(text) {
40-
transform._parent.push(decode(text));
41+
(parent || transform).push(decode(text));
4142
},
4243
oncomment: function(text) {
43-
transform._parent.push(['#comment', text]);
44+
(parent || transform).push(['#comment', text]);
4445
},
4546
onclosetag: function() {
46-
var parent = transform._parent.parent;
47-
delete transform._parent.parent;
48-
transform._parent = parent;
47+
var p = parent.parent;
48+
delete parent.parent;
49+
if (!p) {
50+
transform.push(parent);
51+
}
52+
parent = p;
4953
},
5054
onerror: function(err) {
5155
transform.emit('error', err);
5256
},
5357
onend: function() {
54-
transform.push(transform._parent);
5558
transform._onParseDone();
5659
}
5760
};
@@ -62,8 +65,15 @@ module.exports = function(markup, callback) {
6265
if (isEmpty(arguments)) {
6366
return parser;
6467
} else {
68+
var result = [];
6569
parser.on('data', function(data) {
66-
callback(null, data);
70+
result.push(data);
71+
});
72+
parser.on('end', function() {
73+
if (result.length < 2) {
74+
result = result[0];
75+
}
76+
callback(null, result);
6777
});
6878
parser.on('error', callback);
6979
parser.end(markup);

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"jshint": "jshint index.js test",
88
"jscs": "jscs index.js test",
99
"validate": "npm run jshint && npm run jscs",
10-
"testling": "browserify -t brfs test/test.js | testling",
10+
"testling": "browserify test/test.js | testling",
1111
"unit": "(cd test; covert test.js && ./cli.sh)",
1212
"test": "npm run validate && npm run unit"
1313
},
@@ -38,7 +38,6 @@
3838
"nomnom": "^1.8.0"
3939
},
4040
"devDependencies": {
41-
"brfs": "^1.2.0",
4241
"browserify": "^5.9.1",
4342
"covert": "^0.4.0",
4443
"jscs": "^1.5.9",

test/01-empty/expected.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/01-empty/markup.html

Whitespace-only changes.

test/02-single-shallow-tag/expected.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/02-single-shallow-tag/markup.html

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/03-no-attributes/expected.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/03-no-attributes/markup.html

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/04-nested-tags/expected.json

Lines changed: 0 additions & 9 deletions
This file was deleted.

test/04-nested-tags/markup.html

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/05-comments/expected.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/05-comments/markup.html

Lines changed: 0 additions & 3 deletions
This file was deleted.

test/06-html-entities/expected.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

test/06-html-entities/markup.html

Lines changed: 0 additions & 4 deletions
This file was deleted.

test/cli/expected.json

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

test/test.js

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
var fs = require('fs');
21
var test = require('tape');
32
var Transform = require('stream').Transform;
43
var parse = require('../');
54

65
function verify(markup, expected, t) {
7-
var result;
6+
var result = [];
87
parse()
98
.on('data', function(data) {
10-
result = data;
9+
result.push(data);
1110
})
1211
.on('end', function() {
1312
t.deepEqual(result, expected);
@@ -27,47 +26,80 @@ test('should not return anything in \'callback mode\'', function(t) {
2726
t.end();
2827
});
2928

30-
test('should emit an empty array for empty input markup', function(t) {
31-
var markup = fs.readFileSync(__dirname + '/01-empty/markup.html', 'utf8');
32-
var expected = require('./01-empty/expected.json');
33-
verify(markup, expected, t);
29+
test('should not emit anything for empty input markup', function(t) {
30+
verify('', [], t);
3431
});
3532

3633
test('should not set a node-list array on the node if it has no children', function(t) {
37-
var markup = fs.readFileSync(__dirname + '/02-single-shallow-tag/markup.html', 'utf8');
38-
var expected = require('./02-single-shallow-tag/expected.json');
34+
var markup = '<button class="btn"></button>';
35+
var expected = [['button', { 'class': 'btn' }]];
3936
verify(markup, expected, t);
4037
});
4138

4239
test('should not set a attribute hash on the node if it has none', function(t) {
43-
var markup = fs.readFileSync(__dirname + '/03-no-attributes/markup.html', 'utf8');
44-
var expected = require('./03-no-attributes/expected.json');
40+
var markup = '<div></div>';
41+
var expected = [['div']];
4542
verify(markup, expected, t);
4643
});
4744

4845
test('should parse nested tags and text nodes', function(t) {
49-
var markup = fs.readFileSync(__dirname + '/04-nested-tags/markup.html', 'utf8');
50-
var expected = require('./04-nested-tags/expected.json');
46+
var markup =
47+
'<ul>\n' +
48+
' <li>One</li>\n' +
49+
' <li class="selected">Two</li>\n' +
50+
' <li>Three</li>\n' +
51+
'</ul>';
52+
var expected = [['ul',
53+
'\n ',
54+
['li', 'One'],
55+
'\n ',
56+
['li', { 'class': 'selected' }, 'Two'],
57+
'\n ',
58+
['li', 'Three'],
59+
'\n'
60+
]];
5161
verify(markup, expected, t);
5262
});
5363

5464
test('should parse comments', function(t) {
55-
var markup = fs.readFileSync(__dirname + '/05-comments/markup.html', 'utf8');
56-
var expected = require('./05-comments/expected.json');
65+
var markup =
66+
'<!-- this is a comment -->\n' +
67+
'Not a comment\n' +
68+
'<!-- another comment -->';
69+
var expected = [
70+
['#comment', ' this is a comment '],
71+
'\nNot a comment\n',
72+
['#comment', ' another comment ']
73+
];
5774
verify(markup, expected, t);
5875
});
5976

6077
test('should convert HTML entities into unicode characters', function(t) {
61-
var markup = fs.readFileSync(__dirname + '/06-html-entities/markup.html', 'utf8');
62-
var expected = require('./06-html-entities/expected.json');
78+
var markup =
79+
'<button class="close">&times;</button>\n' +
80+
'&laquo;Yeah, ok&raquo;\n' +
81+
'&aelig;&oslash;&aring;\n' +
82+
'&copy; Awesome Inc.';
83+
var expected = [
84+
['button', { 'class': 'close' }, '×'],
85+
'\n«Yeah, ok»\næøå\n© Awesome Inc.'
86+
];
6387
verify(markup, expected, t);
6488
});
6589

6690
test('should also offer a node-style callback API', function(t) {
6791
parse('<div></div>', function(err, result) {
6892
t.notOk(err);
69-
t.deepEqual(result, [['div']]);
70-
t.end();
93+
t.deepEqual(result, ['div']);
94+
parse('<b></b><i><u></u></i>', function(err, result) {
95+
t.notOk(err);
96+
t.deepEqual(result, [['b'], ['i', ['u']]]);
97+
parse('', function(err, result) {
98+
t.notOk(err);
99+
t.equal(result, undefined);
100+
t.end();
101+
});
102+
});
71103
});
72104
});
73105

0 commit comments

Comments
 (0)