parse5 2.1.5 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -19
- package/README.md +40 -40
- package/lib/common/doctype.js +1 -1
- package/lib/common/foreign_content.js +260 -250
- package/lib/common/html.js +0 -3
- package/lib/index.js +108 -108
- package/lib/location_info/parser_mixin.js +4 -1
- package/lib/location_info/tokenizer_mixin.js +169 -168
- package/lib/parser/index.js +2817 -2864
- package/lib/parser/open_element_stack.js +395 -382
- package/lib/sax/dev_null_stream.js +14 -14
- package/lib/sax/index.js +3 -5
- package/lib/sax/parser_feedback_simulator.js +153 -116
- package/lib/serializer/index.js +180 -180
- package/lib/serializer/stream.js +49 -49
- package/lib/tokenizer/index.js +69 -361
- package/lib/tokenizer/preprocessor.js +155 -131
- package/lib/tree_adapters/htmlparser2.js +327 -327
- package/package.json +7 -6
package/lib/serializer/index.js
CHANGED
|
@@ -1,180 +1,180 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var defaultTreeAdapter = require('../tree_adapters/default'),
|
|
4
|
-
doctype = require('../common/doctype'),
|
|
5
|
-
mergeOptions = require('../common/merge_options'),
|
|
6
|
-
HTML = require('../common/html');
|
|
7
|
-
|
|
8
|
-
//Aliases
|
|
9
|
-
var $ = HTML.TAG_NAMES,
|
|
10
|
-
NS = HTML.NAMESPACES;
|
|
11
|
-
|
|
12
|
-
//Default serializer options
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {Object} SerializerOptions
|
|
15
|
-
*
|
|
16
|
-
* @property {TreeAdapter} [treeAdapter=parse5.treeAdapters.default] - Specifies input tree format.
|
|
17
|
-
*/
|
|
18
|
-
var DEFAULT_OPTIONS = {
|
|
19
|
-
treeAdapter: defaultTreeAdapter
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
//Escaping regexes
|
|
23
|
-
var AMP_REGEX = /&/g,
|
|
24
|
-
NBSP_REGEX = /\u00a0/g,
|
|
25
|
-
DOUBLE_QUOTE_REGEX = /"/g,
|
|
26
|
-
LT_REGEX = /</g,
|
|
27
|
-
GT_REGEX = />/g;
|
|
28
|
-
|
|
29
|
-
//Serializer
|
|
30
|
-
var Serializer = module.exports = function (node, options) {
|
|
31
|
-
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
32
|
-
this.treeAdapter = this.options.treeAdapter;
|
|
33
|
-
|
|
34
|
-
this.html = '';
|
|
35
|
-
this.startNode = node;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
// NOTE: exported as static method for the testing purposes
|
|
39
|
-
Serializer.escapeString = function (str, attrMode) {
|
|
40
|
-
str = str
|
|
41
|
-
.replace(AMP_REGEX, '&')
|
|
42
|
-
.replace(NBSP_REGEX, ' ');
|
|
43
|
-
|
|
44
|
-
if (attrMode)
|
|
45
|
-
str = str.replace(DOUBLE_QUOTE_REGEX, '"');
|
|
46
|
-
|
|
47
|
-
else {
|
|
48
|
-
str = str
|
|
49
|
-
.replace(LT_REGEX, '<')
|
|
50
|
-
.replace(GT_REGEX, '>');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return str;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
//API
|
|
58
|
-
Serializer.prototype.serialize = function () {
|
|
59
|
-
this._serializeChildNodes(this.startNode);
|
|
60
|
-
|
|
61
|
-
return this.html;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
//Internals
|
|
66
|
-
Serializer.prototype._serializeChildNodes = function (parentNode) {
|
|
67
|
-
var childNodes = this.treeAdapter.getChildNodes(parentNode);
|
|
68
|
-
|
|
69
|
-
if (childNodes) {
|
|
70
|
-
for (var i = 0, cnLength = childNodes.length; i < cnLength; i++) {
|
|
71
|
-
var currentNode = childNodes[i];
|
|
72
|
-
|
|
73
|
-
if (this.treeAdapter.isElementNode(currentNode))
|
|
74
|
-
this._serializeElement(currentNode);
|
|
75
|
-
|
|
76
|
-
else if (this.treeAdapter.isTextNode(currentNode))
|
|
77
|
-
this._serializeTextNode(currentNode);
|
|
78
|
-
|
|
79
|
-
else if (this.treeAdapter.isCommentNode(currentNode))
|
|
80
|
-
this._serializeCommentNode(currentNode);
|
|
81
|
-
|
|
82
|
-
else if (this.treeAdapter.isDocumentTypeNode(currentNode))
|
|
83
|
-
this._serializeDocumentTypeNode(currentNode);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
Serializer.prototype._serializeElement = function (node) {
|
|
89
|
-
var tn = this.treeAdapter.getTagName(node),
|
|
90
|
-
ns = this.treeAdapter.getNamespaceURI(node);
|
|
91
|
-
|
|
92
|
-
this.html += '<' + tn;
|
|
93
|
-
this._serializeAttributes(node);
|
|
94
|
-
this.html += '>';
|
|
95
|
-
|
|
96
|
-
if (tn !== $.AREA && tn !== $.BASE && tn !== $.BASEFONT && tn !== $.BGSOUND && tn !== $.BR && tn !== $.BR &&
|
|
97
|
-
tn !== $.COL && tn !== $.EMBED && tn !== $.FRAME && tn !== $.HR && tn !== $.IMG && tn !== $.INPUT &&
|
|
98
|
-
tn !== $.KEYGEN && tn !== $.LINK && tn !== $.MENUITEM && tn !== $.META && tn !== $.PARAM && tn !== $.SOURCE &&
|
|
99
|
-
tn !== $.TRACK && tn !== $.WBR) {
|
|
100
|
-
|
|
101
|
-
if (tn === $.PRE || tn === $.TEXTAREA || tn === $.LISTING) {
|
|
102
|
-
var firstChild = this.treeAdapter.getFirstChild(node);
|
|
103
|
-
|
|
104
|
-
if (firstChild && this.treeAdapter.isTextNode(firstChild)) {
|
|
105
|
-
var content = this.treeAdapter.getTextNodeContent(firstChild);
|
|
106
|
-
|
|
107
|
-
if (content[0] === '\n')
|
|
108
|
-
this.html += '\n';
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
var childNodesHolder = tn === $.TEMPLATE && ns === NS.HTML ?
|
|
113
|
-
this.treeAdapter.getTemplateContent(node) :
|
|
114
|
-
node;
|
|
115
|
-
|
|
116
|
-
this._serializeChildNodes(childNodesHolder);
|
|
117
|
-
this.html += '</' + tn + '>';
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
Serializer.prototype._serializeAttributes = function (node) {
|
|
122
|
-
var attrs = this.treeAdapter.getAttrList(node);
|
|
123
|
-
|
|
124
|
-
for (var i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
|
|
125
|
-
var attr = attrs[i],
|
|
126
|
-
value = Serializer.escapeString(attr.value, true);
|
|
127
|
-
|
|
128
|
-
this.html += ' ';
|
|
129
|
-
|
|
130
|
-
if (!attr.namespace)
|
|
131
|
-
this.html += attr.name;
|
|
132
|
-
|
|
133
|
-
else if (attr.namespace === NS.XML)
|
|
134
|
-
this.html += 'xml:' + attr.name;
|
|
135
|
-
|
|
136
|
-
else if (attr.namespace === NS.XMLNS) {
|
|
137
|
-
if (attr.name !== 'xmlns')
|
|
138
|
-
this.html += 'xmlns:';
|
|
139
|
-
|
|
140
|
-
this.html += attr.name;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
else if (attr.namespace === NS.XLINK)
|
|
144
|
-
this.html += 'xlink:' + attr.name;
|
|
145
|
-
|
|
146
|
-
else
|
|
147
|
-
this.html += attr.namespace + ':' + attr.name;
|
|
148
|
-
|
|
149
|
-
this.html += '="' + value + '"';
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
Serializer.prototype._serializeTextNode = function (node) {
|
|
154
|
-
var content = this.treeAdapter.getTextNodeContent(node),
|
|
155
|
-
parent = this.treeAdapter.getParentNode(node),
|
|
156
|
-
parentTn = void 0;
|
|
157
|
-
|
|
158
|
-
if (parent && this.treeAdapter.isElementNode(parent))
|
|
159
|
-
parentTn = this.treeAdapter.getTagName(parent);
|
|
160
|
-
|
|
161
|
-
if (parentTn === $.STYLE || parentTn === $.SCRIPT || parentTn === $.XMP || parentTn === $.IFRAME ||
|
|
162
|
-
parentTn === $.NOEMBED || parentTn === $.NOFRAMES || parentTn === $.PLAINTEXT || parentTn === $.NOSCRIPT)
|
|
163
|
-
|
|
164
|
-
this.html += content;
|
|
165
|
-
|
|
166
|
-
else
|
|
167
|
-
this.html += Serializer.escapeString(content, false);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
Serializer.prototype._serializeCommentNode = function (node) {
|
|
171
|
-
this.html += '<!--' + this.treeAdapter.getCommentNodeContent(node) + '-->';
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
Serializer.prototype._serializeDocumentTypeNode = function (node) {
|
|
175
|
-
var name = this.treeAdapter.getDocumentTypeNodeName(node),
|
|
176
|
-
publicId = this.treeAdapter.getDocumentTypeNodePublicId(node),
|
|
177
|
-
systemId = this.treeAdapter.getDocumentTypeNodeSystemId(node);
|
|
178
|
-
|
|
179
|
-
this.html += '<' + doctype.serializeContent(name, publicId, systemId) + '>';
|
|
180
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var defaultTreeAdapter = require('../tree_adapters/default'),
|
|
4
|
+
doctype = require('../common/doctype'),
|
|
5
|
+
mergeOptions = require('../common/merge_options'),
|
|
6
|
+
HTML = require('../common/html');
|
|
7
|
+
|
|
8
|
+
//Aliases
|
|
9
|
+
var $ = HTML.TAG_NAMES,
|
|
10
|
+
NS = HTML.NAMESPACES;
|
|
11
|
+
|
|
12
|
+
//Default serializer options
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} SerializerOptions
|
|
15
|
+
*
|
|
16
|
+
* @property {TreeAdapter} [treeAdapter=parse5.treeAdapters.default] - Specifies input tree format.
|
|
17
|
+
*/
|
|
18
|
+
var DEFAULT_OPTIONS = {
|
|
19
|
+
treeAdapter: defaultTreeAdapter
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//Escaping regexes
|
|
23
|
+
var AMP_REGEX = /&/g,
|
|
24
|
+
NBSP_REGEX = /\u00a0/g,
|
|
25
|
+
DOUBLE_QUOTE_REGEX = /"/g,
|
|
26
|
+
LT_REGEX = /</g,
|
|
27
|
+
GT_REGEX = />/g;
|
|
28
|
+
|
|
29
|
+
//Serializer
|
|
30
|
+
var Serializer = module.exports = function (node, options) {
|
|
31
|
+
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
32
|
+
this.treeAdapter = this.options.treeAdapter;
|
|
33
|
+
|
|
34
|
+
this.html = '';
|
|
35
|
+
this.startNode = node;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// NOTE: exported as static method for the testing purposes
|
|
39
|
+
Serializer.escapeString = function (str, attrMode) {
|
|
40
|
+
str = str
|
|
41
|
+
.replace(AMP_REGEX, '&')
|
|
42
|
+
.replace(NBSP_REGEX, ' ');
|
|
43
|
+
|
|
44
|
+
if (attrMode)
|
|
45
|
+
str = str.replace(DOUBLE_QUOTE_REGEX, '"');
|
|
46
|
+
|
|
47
|
+
else {
|
|
48
|
+
str = str
|
|
49
|
+
.replace(LT_REGEX, '<')
|
|
50
|
+
.replace(GT_REGEX, '>');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return str;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
//API
|
|
58
|
+
Serializer.prototype.serialize = function () {
|
|
59
|
+
this._serializeChildNodes(this.startNode);
|
|
60
|
+
|
|
61
|
+
return this.html;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
//Internals
|
|
66
|
+
Serializer.prototype._serializeChildNodes = function (parentNode) {
|
|
67
|
+
var childNodes = this.treeAdapter.getChildNodes(parentNode);
|
|
68
|
+
|
|
69
|
+
if (childNodes) {
|
|
70
|
+
for (var i = 0, cnLength = childNodes.length; i < cnLength; i++) {
|
|
71
|
+
var currentNode = childNodes[i];
|
|
72
|
+
|
|
73
|
+
if (this.treeAdapter.isElementNode(currentNode))
|
|
74
|
+
this._serializeElement(currentNode);
|
|
75
|
+
|
|
76
|
+
else if (this.treeAdapter.isTextNode(currentNode))
|
|
77
|
+
this._serializeTextNode(currentNode);
|
|
78
|
+
|
|
79
|
+
else if (this.treeAdapter.isCommentNode(currentNode))
|
|
80
|
+
this._serializeCommentNode(currentNode);
|
|
81
|
+
|
|
82
|
+
else if (this.treeAdapter.isDocumentTypeNode(currentNode))
|
|
83
|
+
this._serializeDocumentTypeNode(currentNode);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
Serializer.prototype._serializeElement = function (node) {
|
|
89
|
+
var tn = this.treeAdapter.getTagName(node),
|
|
90
|
+
ns = this.treeAdapter.getNamespaceURI(node);
|
|
91
|
+
|
|
92
|
+
this.html += '<' + tn;
|
|
93
|
+
this._serializeAttributes(node);
|
|
94
|
+
this.html += '>';
|
|
95
|
+
|
|
96
|
+
if (tn !== $.AREA && tn !== $.BASE && tn !== $.BASEFONT && tn !== $.BGSOUND && tn !== $.BR && tn !== $.BR &&
|
|
97
|
+
tn !== $.COL && tn !== $.EMBED && tn !== $.FRAME && tn !== $.HR && tn !== $.IMG && tn !== $.INPUT &&
|
|
98
|
+
tn !== $.KEYGEN && tn !== $.LINK && tn !== $.MENUITEM && tn !== $.META && tn !== $.PARAM && tn !== $.SOURCE &&
|
|
99
|
+
tn !== $.TRACK && tn !== $.WBR) {
|
|
100
|
+
|
|
101
|
+
if (tn === $.PRE || tn === $.TEXTAREA || tn === $.LISTING) {
|
|
102
|
+
var firstChild = this.treeAdapter.getFirstChild(node);
|
|
103
|
+
|
|
104
|
+
if (firstChild && this.treeAdapter.isTextNode(firstChild)) {
|
|
105
|
+
var content = this.treeAdapter.getTextNodeContent(firstChild);
|
|
106
|
+
|
|
107
|
+
if (content[0] === '\n')
|
|
108
|
+
this.html += '\n';
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
var childNodesHolder = tn === $.TEMPLATE && ns === NS.HTML ?
|
|
113
|
+
this.treeAdapter.getTemplateContent(node) :
|
|
114
|
+
node;
|
|
115
|
+
|
|
116
|
+
this._serializeChildNodes(childNodesHolder);
|
|
117
|
+
this.html += '</' + tn + '>';
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
Serializer.prototype._serializeAttributes = function (node) {
|
|
122
|
+
var attrs = this.treeAdapter.getAttrList(node);
|
|
123
|
+
|
|
124
|
+
for (var i = 0, attrsLength = attrs.length; i < attrsLength; i++) {
|
|
125
|
+
var attr = attrs[i],
|
|
126
|
+
value = Serializer.escapeString(attr.value, true);
|
|
127
|
+
|
|
128
|
+
this.html += ' ';
|
|
129
|
+
|
|
130
|
+
if (!attr.namespace)
|
|
131
|
+
this.html += attr.name;
|
|
132
|
+
|
|
133
|
+
else if (attr.namespace === NS.XML)
|
|
134
|
+
this.html += 'xml:' + attr.name;
|
|
135
|
+
|
|
136
|
+
else if (attr.namespace === NS.XMLNS) {
|
|
137
|
+
if (attr.name !== 'xmlns')
|
|
138
|
+
this.html += 'xmlns:';
|
|
139
|
+
|
|
140
|
+
this.html += attr.name;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
else if (attr.namespace === NS.XLINK)
|
|
144
|
+
this.html += 'xlink:' + attr.name;
|
|
145
|
+
|
|
146
|
+
else
|
|
147
|
+
this.html += attr.namespace + ':' + attr.name;
|
|
148
|
+
|
|
149
|
+
this.html += '="' + value + '"';
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
Serializer.prototype._serializeTextNode = function (node) {
|
|
154
|
+
var content = this.treeAdapter.getTextNodeContent(node),
|
|
155
|
+
parent = this.treeAdapter.getParentNode(node),
|
|
156
|
+
parentTn = void 0;
|
|
157
|
+
|
|
158
|
+
if (parent && this.treeAdapter.isElementNode(parent))
|
|
159
|
+
parentTn = this.treeAdapter.getTagName(parent);
|
|
160
|
+
|
|
161
|
+
if (parentTn === $.STYLE || parentTn === $.SCRIPT || parentTn === $.XMP || parentTn === $.IFRAME ||
|
|
162
|
+
parentTn === $.NOEMBED || parentTn === $.NOFRAMES || parentTn === $.PLAINTEXT || parentTn === $.NOSCRIPT)
|
|
163
|
+
|
|
164
|
+
this.html += content;
|
|
165
|
+
|
|
166
|
+
else
|
|
167
|
+
this.html += Serializer.escapeString(content, false);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
Serializer.prototype._serializeCommentNode = function (node) {
|
|
171
|
+
this.html += '<!--' + this.treeAdapter.getCommentNodeContent(node) + '-->';
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
Serializer.prototype._serializeDocumentTypeNode = function (node) {
|
|
175
|
+
var name = this.treeAdapter.getDocumentTypeNodeName(node),
|
|
176
|
+
publicId = this.treeAdapter.getDocumentTypeNodePublicId(node),
|
|
177
|
+
systemId = this.treeAdapter.getDocumentTypeNodeSystemId(node);
|
|
178
|
+
|
|
179
|
+
this.html += '<' + doctype.serializeContent(name, publicId, systemId) + '>';
|
|
180
|
+
};
|
package/lib/serializer/stream.js
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var ReadableStream = require('stream').Readable,
|
|
4
|
-
inherits = require('util').inherits,
|
|
5
|
-
Serializer = require('./index');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Streaming AST node to an HTML serializer.
|
|
9
|
-
* A [readable stream]{@link https://nodejs.org/api/stream.html#stream_class_stream_readable}.
|
|
10
|
-
* @class SerializerStream
|
|
11
|
-
* @memberof parse5
|
|
12
|
-
* @instance
|
|
13
|
-
* @extends stream.Readable
|
|
14
|
-
* @param {ASTNode} node - Node to serialize.
|
|
15
|
-
* @param {SerializerOptions} [options] - Serialization options.
|
|
16
|
-
* @example
|
|
17
|
-
* var parse5 = require('parse5');
|
|
18
|
-
* var fs = require('fs');
|
|
19
|
-
*
|
|
20
|
-
* var file = fs.createWriteStream('/home/index.html');
|
|
21
|
-
*
|
|
22
|
-
* // Serializes the parsed document to HTML and writes it to the file.
|
|
23
|
-
* var document = parse5.parse('<body>Who is John Galt?</body>');
|
|
24
|
-
* var serializer = new parse5.SerializerStream(document);
|
|
25
|
-
*
|
|
26
|
-
* serializer.pipe(file);
|
|
27
|
-
*/
|
|
28
|
-
var SerializerStream = module.exports = function (node, options) {
|
|
29
|
-
ReadableStream.call(this);
|
|
30
|
-
|
|
31
|
-
this.serializer = new Serializer(node, options);
|
|
32
|
-
|
|
33
|
-
Object.defineProperty(this.serializer, 'html', {
|
|
34
|
-
//NOTE: To make `+=` concat operator work properly we define
|
|
35
|
-
//getter which always returns empty string
|
|
36
|
-
get: function () {
|
|
37
|
-
return '';
|
|
38
|
-
},
|
|
39
|
-
set: this.push.bind(this)
|
|
40
|
-
});
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
inherits(SerializerStream, ReadableStream);
|
|
44
|
-
|
|
45
|
-
//Readable stream implementation
|
|
46
|
-
SerializerStream.prototype._read = function () {
|
|
47
|
-
this.serializer.serialize();
|
|
48
|
-
this.push(null);
|
|
49
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ReadableStream = require('stream').Readable,
|
|
4
|
+
inherits = require('util').inherits,
|
|
5
|
+
Serializer = require('./index');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Streaming AST node to an HTML serializer.
|
|
9
|
+
* A [readable stream]{@link https://nodejs.org/api/stream.html#stream_class_stream_readable}.
|
|
10
|
+
* @class SerializerStream
|
|
11
|
+
* @memberof parse5
|
|
12
|
+
* @instance
|
|
13
|
+
* @extends stream.Readable
|
|
14
|
+
* @param {ASTNode} node - Node to serialize.
|
|
15
|
+
* @param {SerializerOptions} [options] - Serialization options.
|
|
16
|
+
* @example
|
|
17
|
+
* var parse5 = require('parse5');
|
|
18
|
+
* var fs = require('fs');
|
|
19
|
+
*
|
|
20
|
+
* var file = fs.createWriteStream('/home/index.html');
|
|
21
|
+
*
|
|
22
|
+
* // Serializes the parsed document to HTML and writes it to the file.
|
|
23
|
+
* var document = parse5.parse('<body>Who is John Galt?</body>');
|
|
24
|
+
* var serializer = new parse5.SerializerStream(document);
|
|
25
|
+
*
|
|
26
|
+
* serializer.pipe(file);
|
|
27
|
+
*/
|
|
28
|
+
var SerializerStream = module.exports = function (node, options) {
|
|
29
|
+
ReadableStream.call(this);
|
|
30
|
+
|
|
31
|
+
this.serializer = new Serializer(node, options);
|
|
32
|
+
|
|
33
|
+
Object.defineProperty(this.serializer, 'html', {
|
|
34
|
+
//NOTE: To make `+=` concat operator work properly we define
|
|
35
|
+
//getter which always returns empty string
|
|
36
|
+
get: function () {
|
|
37
|
+
return '';
|
|
38
|
+
},
|
|
39
|
+
set: this.push.bind(this)
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
inherits(SerializerStream, ReadableStream);
|
|
44
|
+
|
|
45
|
+
//Readable stream implementation
|
|
46
|
+
SerializerStream.prototype._read = function () {
|
|
47
|
+
this.serializer.serialize();
|
|
48
|
+
this.push(null);
|
|
49
|
+
};
|