parse5 2.2.3 → 3.0.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.
Files changed (33) hide show
  1. package/LICENSE +19 -19
  2. package/README.md +40 -40
  3. package/lib/common/doctype.js +156 -137
  4. package/lib/common/foreign_content.js +1 -1
  5. package/lib/common/html.js +272 -266
  6. package/lib/common/unicode.js +47 -47
  7. package/lib/extensions/location_info/open_element_stack_mixin.js +34 -0
  8. package/lib/extensions/location_info/parser_mixin.js +213 -0
  9. package/lib/extensions/location_info/tokenizer_mixin.js +117 -0
  10. package/lib/extensions/position_tracking/preprocessor_mixin.js +72 -0
  11. package/lib/index.d.ts +1077 -0
  12. package/lib/index.js +44 -108
  13. package/lib/parser/formatting_element_list.js +167 -167
  14. package/lib/parser/index.js +2819 -2817
  15. package/lib/parser/open_element_stack.js +395 -395
  16. package/lib/parser/parser_stream.js +76 -0
  17. package/lib/parser/plain_text_conversion_stream.js +20 -0
  18. package/lib/sax/dev_null_stream.js +14 -14
  19. package/lib/sax/index.js +7 -119
  20. package/lib/serializer/index.js +162 -180
  21. package/lib/serializer/{stream.js → serializer_stream.js} +28 -49
  22. package/lib/tokenizer/index.js +65 -22
  23. package/lib/tokenizer/named_entity_data.js +5 -0
  24. package/lib/tokenizer/preprocessor.js +0 -8
  25. package/lib/tree_adapters/default.js +209 -578
  26. package/lib/tree_adapters/htmlparser2.js +338 -327
  27. package/lib/{common → utils}/merge_options.js +13 -13
  28. package/lib/utils/mixin.js +18 -0
  29. package/package.json +13 -14
  30. package/lib/location_info/parser_mixin.js +0 -217
  31. package/lib/location_info/tokenizer_mixin.js +0 -169
  32. package/lib/parser/stream.js +0 -140
  33. package/lib/tokenizer/named_entity_trie.js +0 -6
@@ -1,13 +1,13 @@
1
- 'use strict';
2
-
3
- module.exports = function mergeOptions(defaults, options) {
4
- options = options || {};
5
-
6
- return [defaults, options].reduce(function (merged, optObj) {
7
- Object.keys(optObj).forEach(function (key) {
8
- merged[key] = optObj[key];
9
- });
10
-
11
- return merged;
12
- }, {});
13
- };
1
+ 'use strict';
2
+
3
+ module.exports = function mergeOptions(defaults, options) {
4
+ options = options || Object.create(null);
5
+
6
+ return [defaults, options].reduce(function (merged, optObj) {
7
+ Object.keys(optObj).forEach(function (key) {
8
+ merged[key] = optObj[key];
9
+ });
10
+
11
+ return merged;
12
+ }, Object.create(null));
13
+ };
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var Mixin = module.exports = function (host) {
4
+ var originalMethods = {},
5
+ overriddenMethods = this._getOverriddenMethods(this, originalMethods);
6
+
7
+ Object.keys(overriddenMethods).forEach(function (key) {
8
+ if (typeof overriddenMethods[key] === 'function') {
9
+ originalMethods[key] = host[key];
10
+ host[key] = overriddenMethods[key];
11
+ }
12
+ });
13
+ };
14
+
15
+ Mixin.prototype._getOverriddenMethods = function () {
16
+ throw new Error('Not implemented');
17
+ };
18
+
package/package.json CHANGED
@@ -1,30 +1,25 @@
1
1
  {
2
2
  "name": "parse5",
3
- "description": "WHATWG HTML5 specification-compliant, fast and ready for production HTML parsing/serialization toolset for Node.js",
4
- "version": "2.2.3",
3
+ "description": "HTML parsing/serialization toolset for Node.js. WHATWG HTML Living Standard (aka HTML5)-compliant.",
4
+ "version": "3.0.3",
5
5
  "author": "Ivan Nikulin <ifaaan@gmail.com> (https://github.com/inikulin)",
6
- "contributors": [
7
- "Alan Clarke (https://github.com/alanclarke)",
8
- "Evan You (http://evanyou.me)",
9
- "Saksham Aggarwal <s.agg2021@gmail.com>",
10
- "Sebastian Mayr <sebmaster16@gmail.com> (http://blog.smayr.name)",
11
- "Sean Lang <slang800@gmail.com> (http://slang.cx)"
12
- ],
6
+ "contributors": "https://github.com/inikulin/parse5/graphs/contributors",
13
7
  "homepage": "https://github.com/inikulin/parse5",
14
8
  "devDependencies": {
15
9
  "del": "^2.0.2",
16
10
  "gulp": "^3.9.0",
17
11
  "gulp-benchmark": "^1.1.1",
18
- "gulp-concat": "^2.6.0",
19
12
  "gulp-download": "0.0.1",
20
13
  "gulp-eslint": "^3.0.1",
21
- "gulp-insert": "^0.5.0",
22
14
  "gulp-install": "^0.6.0",
23
- "gulp-jsdoc-to-markdown": "^1.1.1",
24
15
  "gulp-mocha": "^2.1.3",
25
16
  "gulp-rename": "^1.2.2",
17
+ "gulp-typedoc": "^2.0.0",
18
+ "gulp-typescript": "^3.1.2",
26
19
  "publish-please": "^2.2.0",
27
- "through2": "^2.0.0"
20
+ "through2": "^2.0.0",
21
+ "typedoc": "^0.5.1",
22
+ "typescript": "^2.0.6"
28
23
  },
29
24
  "keywords": [
30
25
  "html",
@@ -49,6 +44,7 @@
49
44
  ],
50
45
  "license": "MIT",
51
46
  "main": "./lib/index.js",
47
+ "types": "./lib/index.d.ts",
52
48
  "repository": {
53
49
  "type": "git",
54
50
  "url": "git://github.com/inikulin/parse5.git"
@@ -60,5 +56,8 @@
60
56
  },
61
57
  "files": [
62
58
  "lib"
63
- ]
59
+ ],
60
+ "dependencies": {
61
+ "@types/node": "*"
62
+ }
64
63
  }
@@ -1,217 +0,0 @@
1
- 'use strict';
2
-
3
- var OpenElementStack = require('../parser/open_element_stack'),
4
- Tokenizer = require('../tokenizer'),
5
- HTML = require('../common/html');
6
-
7
-
8
- //Aliases
9
- var $ = HTML.TAG_NAMES;
10
-
11
-
12
- function setEndLocation(element, closingToken, treeAdapter) {
13
- var loc = element.__location;
14
-
15
- if (!loc)
16
- return;
17
-
18
- /**
19
- * @typedef {Object} ElementLocationInfo
20
- * @extends StartTagLocationInfo
21
- *
22
- * @property {StartTagLocationInfo} startTag - Element's start tag location info.
23
- * @property {LocationInfo} endTag - Element's end tag location info.
24
- */
25
- if (!loc.startTag) {
26
- loc.startTag = {
27
- line: loc.line,
28
- col: loc.col,
29
- startOffset: loc.startOffset,
30
- endOffset: loc.endOffset
31
- };
32
- if (loc.attrs)
33
- loc.startTag.attrs = loc.attrs;
34
- }
35
-
36
- if (closingToken.location) {
37
- var ctLocation = closingToken.location,
38
- tn = treeAdapter.getTagName(element),
39
- // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing tag and
40
- // for cases like <td> <p> </td> - 'p' closes without a closing tag
41
- isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN &&
42
- tn === closingToken.tagName;
43
-
44
- if (isClosingEndTag) {
45
- loc.endTag = {
46
- line: ctLocation.line,
47
- col: ctLocation.col,
48
- startOffset: ctLocation.startOffset,
49
- endOffset: ctLocation.endOffset
50
- };
51
- }
52
-
53
- if (isClosingEndTag)
54
- loc.endOffset = ctLocation.endOffset;
55
- else
56
- loc.endOffset = ctLocation.startOffset;
57
- }
58
- }
59
-
60
-
61
- exports.assign = function (parser) {
62
- //NOTE: obtain Parser proto this way to avoid module circular references
63
- var parserProto = Object.getPrototypeOf(parser),
64
- treeAdapter = parser.treeAdapter,
65
- attachableElementLocation = null,
66
- lastFosterParentingLocation = null,
67
- currentToken = null;
68
-
69
-
70
- //NOTE: patch _bootstrap method
71
- parser._bootstrap = function (document, fragmentContext) {
72
- parserProto._bootstrap.call(this, document, fragmentContext);
73
-
74
- attachableElementLocation = null;
75
- lastFosterParentingLocation = null;
76
- currentToken = null;
77
-
78
- //OpenElementStack
79
- parser.openElements.pop = function () {
80
- setEndLocation(this.current, currentToken, treeAdapter);
81
- OpenElementStack.prototype.pop.call(this);
82
- };
83
-
84
- parser.openElements.popAllUpToHtmlElement = function () {
85
- for (var i = this.stackTop; i > 0; i--)
86
- setEndLocation(this.items[i], currentToken, treeAdapter);
87
-
88
- OpenElementStack.prototype.popAllUpToHtmlElement.call(this);
89
- };
90
-
91
- parser.openElements.remove = function (element) {
92
- setEndLocation(element, currentToken, treeAdapter);
93
- OpenElementStack.prototype.remove.call(this, element);
94
- };
95
- };
96
-
97
-
98
- //Token processing
99
- parser._processTokenInForeignContent = function (token) {
100
- currentToken = token;
101
- parserProto._processTokenInForeignContent.call(this, token);
102
- };
103
-
104
- parser._processToken = function (token) {
105
- currentToken = token;
106
- parserProto._processToken.call(this, token);
107
-
108
- //NOTE: <body> and <html> are never popped from the stack, so we need to updated
109
- //their end location explicitly.
110
- if (token.type === Tokenizer.END_TAG_TOKEN &&
111
- (token.tagName === $.HTML ||
112
- token.tagName === $.BODY && this.openElements.hasInScope($.BODY))) {
113
- for (var i = this.openElements.stackTop; i >= 0; i--) {
114
- var element = this.openElements.items[i];
115
-
116
- if (this.treeAdapter.getTagName(element) === token.tagName) {
117
- setEndLocation(element, token, treeAdapter);
118
- break;
119
- }
120
- }
121
- }
122
- };
123
-
124
-
125
- //Doctype
126
- parser._setDocumentType = function (token) {
127
- parserProto._setDocumentType.call(this, token);
128
-
129
- var documentChildren = this.treeAdapter.getChildNodes(this.document),
130
- cnLength = documentChildren.length;
131
-
132
- for (var i = 0; i < cnLength; i++) {
133
- var node = documentChildren[i];
134
-
135
- if (this.treeAdapter.isDocumentTypeNode(node)) {
136
- node.__location = token.location;
137
- break;
138
- }
139
- }
140
- };
141
-
142
-
143
- //Elements
144
- parser._attachElementToTree = function (element) {
145
- //NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
146
- //So we will use token location stored in this methods for the element.
147
- element.__location = attachableElementLocation || null;
148
- attachableElementLocation = null;
149
- parserProto._attachElementToTree.call(this, element);
150
- };
151
-
152
- parser._appendElement = function (token, namespaceURI) {
153
- attachableElementLocation = token.location;
154
- parserProto._appendElement.call(this, token, namespaceURI);
155
- };
156
-
157
- parser._insertElement = function (token, namespaceURI) {
158
- attachableElementLocation = token.location;
159
- parserProto._insertElement.call(this, token, namespaceURI);
160
- };
161
-
162
- parser._insertTemplate = function (token) {
163
- attachableElementLocation = token.location;
164
- parserProto._insertTemplate.call(this, token);
165
-
166
- var tmplContent = this.treeAdapter.getTemplateContent(this.openElements.current);
167
-
168
- tmplContent.__location = null;
169
- };
170
-
171
- parser._insertFakeRootElement = function () {
172
- parserProto._insertFakeRootElement.call(this);
173
- this.openElements.current.__location = null;
174
- };
175
-
176
-
177
- //Comments
178
- parser._appendCommentNode = function (token, parent) {
179
- parserProto._appendCommentNode.call(this, token, parent);
180
-
181
- var children = this.treeAdapter.getChildNodes(parent),
182
- commentNode = children[children.length - 1];
183
-
184
- commentNode.__location = token.location;
185
- };
186
-
187
-
188
- //Text
189
- parser._findFosterParentingLocation = function () {
190
- //NOTE: store last foster parenting location, so we will be able to find inserted text
191
- //in case of foster parenting
192
- lastFosterParentingLocation = parserProto._findFosterParentingLocation.call(this);
193
- return lastFosterParentingLocation;
194
- };
195
-
196
- parser._insertCharacters = function (token) {
197
- parserProto._insertCharacters.call(this, token);
198
-
199
- var hasFosterParent = this._shouldFosterParentOnInsertion(),
200
- parent = hasFosterParent && lastFosterParentingLocation.parent ||
201
- this.openElements.currentTmplContent ||
202
- this.openElements.current,
203
- siblings = this.treeAdapter.getChildNodes(parent),
204
- textNodeIdx = hasFosterParent && lastFosterParentingLocation.beforeElement ?
205
- siblings.indexOf(lastFosterParentingLocation.beforeElement) - 1 :
206
- siblings.length - 1,
207
- textNode = siblings[textNodeIdx];
208
-
209
- //NOTE: if we have location assigned by another token, then just update end position
210
- if (textNode.__location)
211
- textNode.__location.endOffset = token.location.endOffset;
212
-
213
- else
214
- textNode.__location = token.location;
215
- };
216
- };
217
-
@@ -1,169 +0,0 @@
1
- 'use strict';
2
-
3
- var UNICODE = require('../common/unicode');
4
-
5
- //Aliases
6
- var $ = UNICODE.CODE_POINTS;
7
-
8
-
9
- exports.assign = function (tokenizer) {
10
- //NOTE: obtain Tokenizer proto this way to avoid module circular references
11
- var tokenizerProto = Object.getPrototypeOf(tokenizer),
12
- tokenStartOffset = -1,
13
- tokenCol = -1,
14
- tokenLine = 1,
15
- isEol = false,
16
- lineStartPosStack = [0],
17
- lineStartPos = 0,
18
- col = -1,
19
- line = 1;
20
-
21
- function attachLocationInfo(token) {
22
- /**
23
- * @typedef {Object} LocationInfo
24
- *
25
- * @property {Number} line - One-based line index
26
- * @property {Number} col - One-based column index
27
- * @property {Number} startOffset - Zero-based first character index
28
- * @property {Number} endOffset - Zero-based last character index
29
- */
30
- token.location = {
31
- line: tokenLine,
32
- col: tokenCol,
33
- startOffset: tokenStartOffset,
34
- endOffset: -1
35
- };
36
- }
37
-
38
- //NOTE: patch consumption method to track line/col information
39
- tokenizer._consume = function () {
40
- var cp = tokenizerProto._consume.call(this);
41
-
42
- //NOTE: LF should be in the last column of the line
43
- if (isEol) {
44
- isEol = false;
45
- line++;
46
- lineStartPosStack.push(this.preprocessor.sourcePos);
47
- lineStartPos = this.preprocessor.sourcePos;
48
- }
49
-
50
- if (cp === $.LINE_FEED)
51
- isEol = true;
52
-
53
- col = this.preprocessor.sourcePos - lineStartPos + 1;
54
-
55
- return cp;
56
- };
57
-
58
- tokenizer._unconsume = function () {
59
- tokenizerProto._unconsume.call(this);
60
- isEol = false;
61
-
62
- while (lineStartPos > this.preprocessor.sourcePos && lineStartPosStack.length > 1) {
63
- lineStartPos = lineStartPosStack.pop();
64
- line--;
65
- }
66
-
67
- col = this.preprocessor.sourcePos - lineStartPos + 1;
68
- };
69
-
70
- //NOTE: patch token creation methods and attach location objects
71
- tokenizer._createStartTagToken = function () {
72
- tokenizerProto._createStartTagToken.call(this);
73
- attachLocationInfo(this.currentToken);
74
- };
75
-
76
- tokenizer._createEndTagToken = function () {
77
- tokenizerProto._createEndTagToken.call(this);
78
- attachLocationInfo(this.currentToken);
79
- };
80
-
81
- tokenizer._createCommentToken = function () {
82
- tokenizerProto._createCommentToken.call(this);
83
- attachLocationInfo(this.currentToken);
84
- };
85
-
86
- tokenizer._createDoctypeToken = function (initialName) {
87
- tokenizerProto._createDoctypeToken.call(this, initialName);
88
- attachLocationInfo(this.currentToken);
89
- };
90
-
91
- tokenizer._createCharacterToken = function (type, ch) {
92
- tokenizerProto._createCharacterToken.call(this, type, ch);
93
- attachLocationInfo(this.currentCharacterToken);
94
- };
95
-
96
- tokenizer._createAttr = function (attrNameFirstCh) {
97
- tokenizerProto._createAttr.call(this, attrNameFirstCh);
98
- this.currentAttrLocation = {
99
- line: line,
100
- col: col,
101
- startOffset: this.preprocessor.sourcePos,
102
- endOffset: -1
103
- };
104
- };
105
-
106
- tokenizer._leaveAttrName = function (toState) {
107
- tokenizerProto._leaveAttrName.call(this, toState);
108
- this._attachCurrentAttrLocationInfo();
109
- };
110
-
111
- tokenizer._leaveAttrValue = function (toState) {
112
- tokenizerProto._leaveAttrValue.call(this, toState);
113
- this._attachCurrentAttrLocationInfo();
114
- };
115
-
116
- tokenizer._attachCurrentAttrLocationInfo = function () {
117
- this.currentAttrLocation.endOffset = this.preprocessor.sourcePos;
118
-
119
- if (!this.currentToken.location.attrs)
120
- this.currentToken.location.attrs = {};
121
-
122
- /**
123
- * @typedef {Object} StartTagLocationInfo
124
- * @extends LocationInfo
125
- *
126
- * @property {Dictionary<String, LocationInfo>} attrs - Start tag attributes' location info.
127
- */
128
- this.currentToken.location.attrs[this.currentAttr.name] = this.currentAttrLocation;
129
- };
130
-
131
- //NOTE: patch token emission methods to determine end location
132
- tokenizer._emitCurrentToken = function () {
133
- //NOTE: if we have pending character token make it's end location equal to the
134
- //current token's start location.
135
- if (this.currentCharacterToken)
136
- this.currentCharacterToken.location.endOffset = this.currentToken.location.startOffset;
137
-
138
- this.currentToken.location.endOffset = this.preprocessor.sourcePos + 1;
139
- tokenizerProto._emitCurrentToken.call(this);
140
- };
141
-
142
- tokenizer._emitCurrentCharacterToken = function () {
143
- //NOTE: if we have character token and it's location wasn't set in the _emitCurrentToken(),
144
- //then set it's location at the current preprocessor position.
145
- //We don't need to increment preprocessor position, since character token
146
- //emission is always forced by the start of the next character token here.
147
- //So, we already have advanced position.
148
- if (this.currentCharacterToken && this.currentCharacterToken.location.endOffset === -1)
149
- this.currentCharacterToken.location.endOffset = this.preprocessor.sourcePos;
150
-
151
- tokenizerProto._emitCurrentCharacterToken.call(this);
152
- };
153
-
154
- //NOTE: patch initial states for each mode to obtain token start position
155
- Object.keys(tokenizerProto.MODE)
156
-
157
- .map(function (modeName) {
158
- return tokenizerProto.MODE[modeName];
159
- })
160
-
161
- .forEach(function (state) {
162
- tokenizer[state] = function (cp) {
163
- tokenStartOffset = this.preprocessor.sourcePos;
164
- tokenLine = line;
165
- tokenCol = col;
166
- tokenizerProto[state].call(this, cp);
167
- };
168
- });
169
- };
@@ -1,140 +0,0 @@
1
- 'use strict';
2
-
3
- var WritableStream = require('stream').Writable,
4
- inherits = require('util').inherits,
5
- Parser = require('./index');
6
-
7
- /**
8
- * Streaming HTML parser with scripting support.
9
- * A [writable stream]{@link https://nodejs.org/api/stream.html#stream_class_stream_writable}.
10
- * @class ParserStream
11
- * @memberof parse5
12
- * @instance
13
- * @extends stream.Writable
14
- * @param {ParserOptions} options - Parsing options.
15
- * @example
16
- * var parse5 = require('parse5');
17
- * var http = require('http');
18
- *
19
- * // Fetch the google.com content and obtain it's <body> node
20
- * http.get('http://google.com', function(res) {
21
- * var parser = new parse5.ParserStream();
22
- *
23
- * parser.on('finish', function() {
24
- * var body = parser.document.childNodes[0].childNodes[1];
25
- * });
26
- *
27
- * res.pipe(parser);
28
- * });
29
- */
30
- var ParserStream = module.exports = function (options) {
31
- WritableStream.call(this);
32
-
33
- this.parser = new Parser(options);
34
-
35
- this.lastChunkWritten = false;
36
- this.writeCallback = null;
37
- this.pausedByScript = false;
38
-
39
- /**
40
- * The resulting document node.
41
- * @member {ASTNode<document>} document
42
- * @memberof parse5#ParserStream
43
- * @instance
44
- */
45
- this.document = this.parser.treeAdapter.createDocument();
46
-
47
- this.pendingHtmlInsertions = [];
48
-
49
- this._resume = this._resume.bind(this);
50
- this._documentWrite = this._documentWrite.bind(this);
51
- this._scriptHandler = this._scriptHandler.bind(this);
52
-
53
- this.parser._bootstrap(this.document, null);
54
- };
55
-
56
- inherits(ParserStream, WritableStream);
57
-
58
- //WritableStream implementation
59
- ParserStream.prototype._write = function (chunk, encoding, callback) {
60
- this.writeCallback = callback;
61
- this.parser.tokenizer.write(chunk.toString('utf8'), this.lastChunkWritten);
62
- this._runParsingLoop();
63
- };
64
-
65
- ParserStream.prototype.end = function (chunk, encoding, callback) {
66
- this.lastChunkWritten = true;
67
- WritableStream.prototype.end.call(this, chunk, encoding, callback);
68
- };
69
-
70
- //Scriptable parser implementation
71
- ParserStream.prototype._runParsingLoop = function () {
72
- this.parser._runParsingLoop(this.writeCallback, this._scriptHandler);
73
- };
74
-
75
- ParserStream.prototype._resume = function () {
76
- if (!this.pausedByScript)
77
- throw new Error('Parser was already resumed');
78
-
79
- while (this.pendingHtmlInsertions.length) {
80
- var html = this.pendingHtmlInsertions.pop();
81
-
82
- this.parser.tokenizer.insertHtmlAtCurrentPos(html);
83
- }
84
-
85
- this.pausedByScript = false;
86
-
87
- //NOTE: keep parsing if we don't wait for the next input chunk
88
- if (this.parser.tokenizer.active)
89
- this._runParsingLoop();
90
- };
91
-
92
- ParserStream.prototype._documentWrite = function (html) {
93
- if (!this.parser.stopped)
94
- this.pendingHtmlInsertions.push(html);
95
- };
96
-
97
- ParserStream.prototype._scriptHandler = function (scriptElement) {
98
- if (this.listeners('script').length) {
99
- this.pausedByScript = true;
100
-
101
- /**
102
- * Raised then parser encounters a `<script>` element.
103
- * If this event has listeners, parsing will be suspended once it is emitted.
104
- * So, if `<script>` has the `src` attribute, you can fetch it, execute and then resume parsing just like browsers do.
105
- * @event script
106
- * @memberof parse5#ParserStream
107
- * @instance
108
- * @type {Function}
109
- * @param {ASTNode} scriptElement - The script element that caused the event.
110
- * @param {Function} documentWrite(html) - Write additional `html` at the current parsing position.
111
- * Suitable for implementing the DOM `document.write` and `document.writeln` methods.
112
- * @param {Function} resume - Resumes parsing.
113
- * @example
114
- * var parse = require('parse5');
115
- * var http = require('http');
116
- *
117
- * var parser = new parse5.ParserStream();
118
- *
119
- * parser.on('script', function(scriptElement, documentWrite, resume) {
120
- * var src = parse5.treeAdapters.default.getAttrList(scriptElement)[0].value;
121
- *
122
- * http.get(src, function(res) {
123
- * // Fetch the script content, execute it with DOM built around `parser.document` and
124
- * // `document.write` implemented using `documentWrite`.
125
- * ...
126
- * // Then resume parsing.
127
- * resume();
128
- * });
129
- * });
130
- *
131
- * parser.end('<script src="example.com/script.js"></script>');
132
- */
133
-
134
-
135
- this.emit('script', scriptElement, this._documentWrite, this._resume);
136
- }
137
- else
138
- this._runParsingLoop();
139
- };
140
-