parse5 3.0.3 → 5.1.0

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.
Files changed (43) hide show
  1. package/README.md +14 -16
  2. package/lib/common/doctype.js +125 -108
  3. package/lib/common/error-codes.js +65 -0
  4. package/lib/common/foreign-content.js +265 -0
  5. package/lib/common/html.js +102 -102
  6. package/lib/common/unicode.js +81 -19
  7. package/lib/extensions/error-reporting/mixin-base.js +43 -0
  8. package/lib/extensions/error-reporting/parser-mixin.js +52 -0
  9. package/lib/extensions/error-reporting/preprocessor-mixin.js +24 -0
  10. package/lib/extensions/error-reporting/tokenizer-mixin.js +17 -0
  11. package/lib/extensions/location-info/open-element-stack-mixin.js +35 -0
  12. package/lib/extensions/location-info/parser-mixin.js +222 -0
  13. package/lib/extensions/location-info/tokenizer-mixin.js +146 -0
  14. package/lib/extensions/position-tracking/preprocessor-mixin.js +64 -0
  15. package/lib/index.js +6 -21
  16. package/lib/parser/formatting-element-list.js +181 -0
  17. package/lib/parser/index.js +1469 -1332
  18. package/lib/parser/open-element-stack.js +482 -0
  19. package/lib/serializer/index.js +136 -122
  20. package/lib/tokenizer/index.js +1856 -1804
  21. package/lib/tokenizer/{named_entity_data.js → named-entity-data.js} +1 -1
  22. package/lib/tokenizer/preprocessor.js +115 -103
  23. package/lib/tree-adapters/default.js +217 -0
  24. package/lib/utils/{merge_options.js → merge-options.js} +2 -2
  25. package/lib/utils/mixin.js +33 -12
  26. package/package.json +32 -61
  27. package/LICENSE +0 -19
  28. package/lib/common/foreign_content.js +0 -260
  29. package/lib/extensions/location_info/open_element_stack_mixin.js +0 -34
  30. package/lib/extensions/location_info/parser_mixin.js +0 -213
  31. package/lib/extensions/location_info/tokenizer_mixin.js +0 -117
  32. package/lib/extensions/position_tracking/preprocessor_mixin.js +0 -72
  33. package/lib/index.d.ts +0 -1077
  34. package/lib/parser/formatting_element_list.js +0 -167
  35. package/lib/parser/open_element_stack.js +0 -395
  36. package/lib/parser/parser_stream.js +0 -76
  37. package/lib/parser/plain_text_conversion_stream.js +0 -20
  38. package/lib/sax/dev_null_stream.js +0 -14
  39. package/lib/sax/index.js +0 -118
  40. package/lib/sax/parser_feedback_simulator.js +0 -153
  41. package/lib/serializer/serializer_stream.js +0 -28
  42. package/lib/tree_adapters/default.js +0 -209
  43. package/lib/tree_adapters/htmlparser2.js +0 -338
package/lib/sax/index.js DELETED
@@ -1,118 +0,0 @@
1
- 'use strict';
2
-
3
- var TransformStream = require('stream').Transform,
4
- DevNullStream = require('./dev_null_stream'),
5
- inherits = require('util').inherits,
6
- Tokenizer = require('../tokenizer'),
7
- LocationInfoTokenizerMixin = require('../extensions/location_info/tokenizer_mixin'),
8
- ParserFeedbackSimulator = require('./parser_feedback_simulator'),
9
- mergeOptions = require('../utils/merge_options');
10
-
11
- var DEFAULT_OPTIONS = {
12
- locationInfo: false
13
- };
14
-
15
- var SAXParser = module.exports = function (options) {
16
- TransformStream.call(this);
17
-
18
- this.options = mergeOptions(DEFAULT_OPTIONS, options);
19
-
20
- this.tokenizer = new Tokenizer(options);
21
-
22
- if (this.options.locationInfo)
23
- new LocationInfoTokenizerMixin(this.tokenizer);
24
-
25
- this.parserFeedbackSimulator = new ParserFeedbackSimulator(this.tokenizer);
26
-
27
- this.pendingText = null;
28
- this.currentTokenLocation = void 0;
29
-
30
- this.lastChunkWritten = false;
31
- this.stopped = false;
32
-
33
- // NOTE: always pipe stream to the /dev/null stream to avoid
34
- // `highWaterMark` hit even if we don't have consumers.
35
- // (see: https://github.com/inikulin/parse5/issues/97#issuecomment-171940774)
36
- this.pipe(new DevNullStream());
37
- };
38
-
39
- inherits(SAXParser, TransformStream);
40
-
41
- //TransformStream implementation
42
- SAXParser.prototype._transform = function (chunk, encoding, callback) {
43
- if (!this.stopped) {
44
- this.tokenizer.write(chunk.toString('utf8'), this.lastChunkWritten);
45
- this._runParsingLoop();
46
- }
47
-
48
- this.push(chunk);
49
-
50
- callback();
51
- };
52
-
53
- SAXParser.prototype._flush = function (callback) {
54
- callback();
55
- };
56
-
57
- SAXParser.prototype.end = function (chunk, encoding, callback) {
58
- this.lastChunkWritten = true;
59
- TransformStream.prototype.end.call(this, chunk, encoding, callback);
60
- };
61
-
62
- SAXParser.prototype.stop = function () {
63
- this.stopped = true;
64
- };
65
-
66
- //Internals
67
- SAXParser.prototype._runParsingLoop = function () {
68
- do {
69
- var token = this.parserFeedbackSimulator.getNextToken();
70
-
71
- if (token.type === Tokenizer.HIBERNATION_TOKEN)
72
- break;
73
-
74
- if (token.type === Tokenizer.CHARACTER_TOKEN ||
75
- token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN ||
76
- token.type === Tokenizer.NULL_CHARACTER_TOKEN) {
77
-
78
- if (this.options.locationInfo) {
79
- if (this.pendingText === null)
80
- this.currentTokenLocation = token.location;
81
-
82
- else
83
- this.currentTokenLocation.endOffset = token.location.endOffset;
84
- }
85
-
86
- this.pendingText = (this.pendingText || '') + token.chars;
87
- }
88
-
89
- else {
90
- this._emitPendingText();
91
- this._handleToken(token);
92
- }
93
- } while (!this.stopped && token.type !== Tokenizer.EOF_TOKEN);
94
- };
95
-
96
- SAXParser.prototype._handleToken = function (token) {
97
- if (this.options.locationInfo)
98
- this.currentTokenLocation = token.location;
99
-
100
- if (token.type === Tokenizer.START_TAG_TOKEN)
101
- this.emit('startTag', token.tagName, token.attrs, token.selfClosing, this.currentTokenLocation);
102
-
103
- else if (token.type === Tokenizer.END_TAG_TOKEN)
104
- this.emit('endTag', token.tagName, this.currentTokenLocation);
105
-
106
- else if (token.type === Tokenizer.COMMENT_TOKEN)
107
- this.emit('comment', token.data, this.currentTokenLocation);
108
-
109
- else if (token.type === Tokenizer.DOCTYPE_TOKEN)
110
- this.emit('doctype', token.name, token.publicId, token.systemId, this.currentTokenLocation);
111
- };
112
-
113
- SAXParser.prototype._emitPendingText = function () {
114
- if (this.pendingText !== null) {
115
- this.emit('text', this.pendingText, this.currentTokenLocation);
116
- this.pendingText = null;
117
- }
118
- };
@@ -1,153 +0,0 @@
1
- 'use strict';
2
-
3
- var Tokenizer = require('../tokenizer'),
4
- foreignContent = require('../common/foreign_content'),
5
- UNICODE = require('../common/unicode'),
6
- HTML = require('../common/html');
7
-
8
-
9
- //Aliases
10
- var $ = HTML.TAG_NAMES,
11
- NS = HTML.NAMESPACES;
12
-
13
-
14
- //ParserFeedbackSimulator
15
- //Simulates adjustment of the Tokenizer which performed by standard parser during tree construction.
16
- var ParserFeedbackSimulator = module.exports = function (tokenizer) {
17
- this.tokenizer = tokenizer;
18
-
19
- this.namespaceStack = [];
20
- this.namespaceStackTop = -1;
21
- this._enterNamespace(NS.HTML);
22
- };
23
-
24
- ParserFeedbackSimulator.prototype.getNextToken = function () {
25
- var token = this.tokenizer.getNextToken();
26
-
27
- if (token.type === Tokenizer.START_TAG_TOKEN)
28
- this._handleStartTagToken(token);
29
-
30
- else if (token.type === Tokenizer.END_TAG_TOKEN)
31
- this._handleEndTagToken(token);
32
-
33
- else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN && this.inForeignContent) {
34
- token.type = Tokenizer.CHARACTER_TOKEN;
35
- token.chars = UNICODE.REPLACEMENT_CHARACTER;
36
- }
37
-
38
- else if (this.skipNextNewLine) {
39
- if (token.type !== Tokenizer.HIBERNATION_TOKEN)
40
- this.skipNextNewLine = false;
41
-
42
- if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN && token.chars[0] === '\n') {
43
- if (token.chars.length === 1)
44
- return this.getNextToken();
45
-
46
- token.chars = token.chars.substr(1);
47
- }
48
- }
49
-
50
- return token;
51
- };
52
-
53
- //Namespace stack mutations
54
- ParserFeedbackSimulator.prototype._enterNamespace = function (namespace) {
55
- this.namespaceStackTop++;
56
- this.namespaceStack.push(namespace);
57
-
58
- this.inForeignContent = namespace !== NS.HTML;
59
- this.currentNamespace = namespace;
60
- this.tokenizer.allowCDATA = this.inForeignContent;
61
- };
62
-
63
- ParserFeedbackSimulator.prototype._leaveCurrentNamespace = function () {
64
- this.namespaceStackTop--;
65
- this.namespaceStack.pop();
66
-
67
- this.currentNamespace = this.namespaceStack[this.namespaceStackTop];
68
- this.inForeignContent = this.currentNamespace !== NS.HTML;
69
- this.tokenizer.allowCDATA = this.inForeignContent;
70
- };
71
-
72
- //Token handlers
73
- ParserFeedbackSimulator.prototype._ensureTokenizerMode = function (tn) {
74
- if (tn === $.TEXTAREA || tn === $.TITLE)
75
- this.tokenizer.state = Tokenizer.MODE.RCDATA;
76
-
77
- else if (tn === $.PLAINTEXT)
78
- this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
79
-
80
- else if (tn === $.SCRIPT)
81
- this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
82
-
83
- else if (tn === $.STYLE || tn === $.IFRAME || tn === $.XMP ||
84
- tn === $.NOEMBED || tn === $.NOFRAMES || tn === $.NOSCRIPT)
85
- this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
86
- };
87
-
88
- ParserFeedbackSimulator.prototype._handleStartTagToken = function (token) {
89
- var tn = token.tagName;
90
-
91
- if (tn === $.SVG)
92
- this._enterNamespace(NS.SVG);
93
-
94
- else if (tn === $.MATH)
95
- this._enterNamespace(NS.MATHML);
96
-
97
- if (this.inForeignContent) {
98
- if (foreignContent.causesExit(token)) {
99
- this._leaveCurrentNamespace();
100
- return;
101
- }
102
-
103
- var currentNs = this.currentNamespace;
104
-
105
- if (currentNs === NS.MATHML)
106
- foreignContent.adjustTokenMathMLAttrs(token);
107
-
108
- else if (currentNs === NS.SVG) {
109
- foreignContent.adjustTokenSVGTagName(token);
110
- foreignContent.adjustTokenSVGAttrs(token);
111
- }
112
-
113
- foreignContent.adjustTokenXMLAttrs(token);
114
-
115
- tn = token.tagName;
116
-
117
- if (!token.selfClosing && foreignContent.isIntegrationPoint(tn, currentNs, token.attrs))
118
- this._enterNamespace(NS.HTML);
119
- }
120
-
121
- else {
122
- if (tn === $.PRE || tn === $.TEXTAREA || tn === $.LISTING)
123
- this.skipNextNewLine = true;
124
-
125
- else if (tn === $.IMAGE)
126
- token.tagName = $.IMG;
127
-
128
- this._ensureTokenizerMode(tn);
129
- }
130
- };
131
-
132
- ParserFeedbackSimulator.prototype._handleEndTagToken = function (token) {
133
- var tn = token.tagName;
134
-
135
- if (!this.inForeignContent) {
136
- var previousNs = this.namespaceStack[this.namespaceStackTop - 1];
137
-
138
- if (previousNs === NS.SVG && foreignContent.SVG_TAG_NAMES_ADJUSTMENT_MAP[tn])
139
- tn = foreignContent.SVG_TAG_NAMES_ADJUSTMENT_MAP[tn];
140
-
141
- //NOTE: check for exit from integration point
142
- if (foreignContent.isIntegrationPoint(tn, previousNs, token.attrs))
143
- this._leaveCurrentNamespace();
144
- }
145
-
146
- else if (tn === $.SVG && this.currentNamespace === NS.SVG ||
147
- tn === $.MATH && this.currentNamespace === NS.MATHML)
148
- this._leaveCurrentNamespace();
149
-
150
- // NOTE: adjust end tag name as well for consistency
151
- if (this.currentNamespace === NS.SVG)
152
- foreignContent.adjustTokenSVGTagName(token);
153
- };
@@ -1,28 +0,0 @@
1
- 'use strict';
2
-
3
- var ReadableStream = require('stream').Readable,
4
- inherits = require('util').inherits,
5
- Serializer = require('./index');
6
-
7
- var SerializerStream = module.exports = function (node, options) {
8
- ReadableStream.call(this);
9
-
10
- this.serializer = new Serializer(node, options);
11
-
12
- Object.defineProperty(this.serializer, 'html', {
13
- //NOTE: To make `+=` concat operator work properly we define
14
- //getter which always returns empty string
15
- get: function () {
16
- return '';
17
- },
18
- set: this.push.bind(this)
19
- });
20
- };
21
-
22
- inherits(SerializerStream, ReadableStream);
23
-
24
- //Readable stream implementation
25
- SerializerStream.prototype._read = function () {
26
- this.serializer.serialize();
27
- this.push(null);
28
- };
@@ -1,209 +0,0 @@
1
- 'use strict';
2
-
3
- var DOCUMENT_MODE = require('../common/html').DOCUMENT_MODE;
4
-
5
- //Node construction
6
- exports.createDocument = function () {
7
- return {
8
- nodeName: '#document',
9
- mode: DOCUMENT_MODE.NO_QUIRKS,
10
- childNodes: []
11
- };
12
- };
13
-
14
- exports.createDocumentFragment = function () {
15
- return {
16
- nodeName: '#document-fragment',
17
- childNodes: []
18
- };
19
- };
20
-
21
- exports.createElement = function (tagName, namespaceURI, attrs) {
22
- return {
23
- nodeName: tagName,
24
- tagName: tagName,
25
- attrs: attrs,
26
- namespaceURI: namespaceURI,
27
- childNodes: [],
28
- parentNode: null
29
- };
30
- };
31
-
32
- exports.createCommentNode = function (data) {
33
- return {
34
- nodeName: '#comment',
35
- data: data,
36
- parentNode: null
37
- };
38
- };
39
-
40
- var createTextNode = function (value) {
41
- return {
42
- nodeName: '#text',
43
- value: value,
44
- parentNode: null
45
- };
46
- };
47
-
48
-
49
- //Tree mutation
50
- var appendChild = exports.appendChild = function (parentNode, newNode) {
51
- parentNode.childNodes.push(newNode);
52
- newNode.parentNode = parentNode;
53
- };
54
-
55
- var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
56
- var insertionIdx = parentNode.childNodes.indexOf(referenceNode);
57
-
58
- parentNode.childNodes.splice(insertionIdx, 0, newNode);
59
- newNode.parentNode = parentNode;
60
- };
61
-
62
- exports.setTemplateContent = function (templateElement, contentElement) {
63
- templateElement.content = contentElement;
64
- };
65
-
66
- exports.getTemplateContent = function (templateElement) {
67
- return templateElement.content;
68
- };
69
-
70
- exports.setDocumentType = function (document, name, publicId, systemId) {
71
- var doctypeNode = null;
72
-
73
- for (var i = 0; i < document.childNodes.length; i++) {
74
- if (document.childNodes[i].nodeName === '#documentType') {
75
- doctypeNode = document.childNodes[i];
76
- break;
77
- }
78
- }
79
-
80
- if (doctypeNode) {
81
- doctypeNode.name = name;
82
- doctypeNode.publicId = publicId;
83
- doctypeNode.systemId = systemId;
84
- }
85
-
86
- else {
87
- appendChild(document, {
88
- nodeName: '#documentType',
89
- name: name,
90
- publicId: publicId,
91
- systemId: systemId
92
- });
93
- }
94
- };
95
-
96
- exports.setDocumentMode = function (document, mode) {
97
- document.mode = mode;
98
- };
99
-
100
- exports.getDocumentMode = function (document) {
101
- return document.mode;
102
- };
103
-
104
- exports.detachNode = function (node) {
105
- if (node.parentNode) {
106
- var idx = node.parentNode.childNodes.indexOf(node);
107
-
108
- node.parentNode.childNodes.splice(idx, 1);
109
- node.parentNode = null;
110
- }
111
- };
112
-
113
- exports.insertText = function (parentNode, text) {
114
- if (parentNode.childNodes.length) {
115
- var prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
116
-
117
- if (prevNode.nodeName === '#text') {
118
- prevNode.value += text;
119
- return;
120
- }
121
- }
122
-
123
- appendChild(parentNode, createTextNode(text));
124
- };
125
-
126
- exports.insertTextBefore = function (parentNode, text, referenceNode) {
127
- var prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
128
-
129
- if (prevNode && prevNode.nodeName === '#text')
130
- prevNode.value += text;
131
- else
132
- insertBefore(parentNode, createTextNode(text), referenceNode);
133
- };
134
-
135
- exports.adoptAttributes = function (recipient, attrs) {
136
- var recipientAttrsMap = [];
137
-
138
- for (var i = 0; i < recipient.attrs.length; i++)
139
- recipientAttrsMap.push(recipient.attrs[i].name);
140
-
141
- for (var j = 0; j < attrs.length; j++) {
142
- if (recipientAttrsMap.indexOf(attrs[j].name) === -1)
143
- recipient.attrs.push(attrs[j]);
144
- }
145
- };
146
-
147
-
148
- //Tree traversing
149
- exports.getFirstChild = function (node) {
150
- return node.childNodes[0];
151
- };
152
-
153
- exports.getChildNodes = function (node) {
154
- return node.childNodes;
155
- };
156
-
157
- exports.getParentNode = function (node) {
158
- return node.parentNode;
159
- };
160
-
161
- exports.getAttrList = function (element) {
162
- return element.attrs;
163
- };
164
-
165
- //Node data
166
- exports.getTagName = function (element) {
167
- return element.tagName;
168
- };
169
-
170
- exports.getNamespaceURI = function (element) {
171
- return element.namespaceURI;
172
- };
173
-
174
- exports.getTextNodeContent = function (textNode) {
175
- return textNode.value;
176
- };
177
-
178
- exports.getCommentNodeContent = function (commentNode) {
179
- return commentNode.data;
180
- };
181
-
182
- exports.getDocumentTypeNodeName = function (doctypeNode) {
183
- return doctypeNode.name;
184
- };
185
-
186
- exports.getDocumentTypeNodePublicId = function (doctypeNode) {
187
- return doctypeNode.publicId;
188
- };
189
-
190
- exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
191
- return doctypeNode.systemId;
192
- };
193
-
194
- //Node types
195
- exports.isTextNode = function (node) {
196
- return node.nodeName === '#text';
197
- };
198
-
199
- exports.isCommentNode = function (node) {
200
- return node.nodeName === '#comment';
201
- };
202
-
203
- exports.isDocumentTypeNode = function (node) {
204
- return node.nodeName === '#documentType';
205
- };
206
-
207
- exports.isElementNode = function (node) {
208
- return !!node.tagName;
209
- };