parse5 1.5.0 → 1.5.1

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.
@@ -1,107 +1,107 @@
1
- 'use strict';
2
-
3
- var Tokenizer = require('../tokenization/tokenizer'),
4
- TokenizerProxy = require('./tokenizer_proxy'),
5
- Utils = require('../common/utils');
6
-
7
- //Default options
8
- var DEFAULT_OPTIONS = {
9
- decodeHtmlEntities: true,
10
- locationInfo: false
11
- };
12
-
13
- //Skipping handler
14
- function skip() {
15
- //NOTE: do nothing =)
16
- }
17
-
18
- //SimpleApiParser
19
- var SimpleApiParser = module.exports = function (handlers, options) {
20
- this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
21
- this.handlers = {
22
- doctype: this._wrapHandler(handlers.doctype),
23
- startTag: this._wrapHandler(handlers.startTag),
24
- endTag: this._wrapHandler(handlers.endTag),
25
- text: this._wrapHandler(handlers.text),
26
- comment: this._wrapHandler(handlers.comment)
27
- };
28
- };
29
-
30
- SimpleApiParser.prototype._wrapHandler = function (handler) {
31
- var parser = this;
32
-
33
- handler = handler || skip;
34
-
35
- if (this.options.locationInfo) {
36
- return function () {
37
- var args = Array.prototype.slice.call(arguments);
38
- args.push(parser.currentTokenLocation);
39
- handler.apply(handler, args);
40
- };
41
- }
42
-
43
- return handler;
44
- };
45
-
46
- //API
47
- SimpleApiParser.prototype.parse = function (html) {
48
- var token = null;
49
-
50
- this._reset(html);
51
-
52
- do {
53
- token = this.tokenizerProxy.getNextToken();
54
-
55
- if (token.type === Tokenizer.CHARACTER_TOKEN ||
56
- token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN ||
57
- token.type === Tokenizer.NULL_CHARACTER_TOKEN) {
58
-
59
- if (this.options.locationInfo) {
60
- if (this.pendingText === null)
61
- this.currentTokenLocation = token.location;
62
-
63
- else
64
- this.currentTokenLocation.end = token.location.end;
65
- }
66
-
67
- this.pendingText = (this.pendingText || '') + token.chars;
68
- }
69
-
70
- else {
71
- this._emitPendingText();
72
- this._handleToken(token);
73
- }
74
- } while (token.type !== Tokenizer.EOF_TOKEN);
75
- };
76
-
77
- //Internals
78
- SimpleApiParser.prototype._handleToken = function (token) {
79
- if (this.options.locationInfo)
80
- this.currentTokenLocation = token.location;
81
-
82
- if (token.type === Tokenizer.START_TAG_TOKEN)
83
- this.handlers.startTag(token.tagName, token.attrs, token.selfClosing);
84
-
85
- else if (token.type === Tokenizer.END_TAG_TOKEN)
86
- this.handlers.endTag(token.tagName);
87
-
88
- else if (token.type === Tokenizer.COMMENT_TOKEN)
89
- this.handlers.comment(token.data);
90
-
91
- else if (token.type === Tokenizer.DOCTYPE_TOKEN)
92
- this.handlers.doctype(token.name, token.publicId, token.systemId);
93
-
94
- };
95
-
96
- SimpleApiParser.prototype._reset = function (html) {
97
- this.tokenizerProxy = new TokenizerProxy(html, this.options);
98
- this.pendingText = null;
99
- this.currentTokenLocation = null;
100
- };
101
-
102
- SimpleApiParser.prototype._emitPendingText = function () {
103
- if (this.pendingText !== null) {
104
- this.handlers.text(this.pendingText);
105
- this.pendingText = null;
106
- }
107
- };
1
+ 'use strict';
2
+
3
+ var Tokenizer = require('../tokenization/tokenizer'),
4
+ TokenizerProxy = require('./tokenizer_proxy'),
5
+ Utils = require('../common/utils');
6
+
7
+ //Default options
8
+ var DEFAULT_OPTIONS = {
9
+ decodeHtmlEntities: true,
10
+ locationInfo: false
11
+ };
12
+
13
+ //Skipping handler
14
+ function skip() {
15
+ //NOTE: do nothing =)
16
+ }
17
+
18
+ //SimpleApiParser
19
+ var SimpleApiParser = module.exports = function (handlers, options) {
20
+ this.options = Utils.mergeOptions(DEFAULT_OPTIONS, options);
21
+ this.handlers = {
22
+ doctype: this._wrapHandler(handlers.doctype),
23
+ startTag: this._wrapHandler(handlers.startTag),
24
+ endTag: this._wrapHandler(handlers.endTag),
25
+ text: this._wrapHandler(handlers.text),
26
+ comment: this._wrapHandler(handlers.comment)
27
+ };
28
+ };
29
+
30
+ SimpleApiParser.prototype._wrapHandler = function (handler) {
31
+ var parser = this;
32
+
33
+ handler = handler || skip;
34
+
35
+ if (this.options.locationInfo) {
36
+ return function () {
37
+ var args = Array.prototype.slice.call(arguments);
38
+ args.push(parser.currentTokenLocation);
39
+ handler.apply(handler, args);
40
+ };
41
+ }
42
+
43
+ return handler;
44
+ };
45
+
46
+ //API
47
+ SimpleApiParser.prototype.parse = function (html) {
48
+ var token = null;
49
+
50
+ this._reset(html);
51
+
52
+ do {
53
+ token = this.tokenizerProxy.getNextToken();
54
+
55
+ if (token.type === Tokenizer.CHARACTER_TOKEN ||
56
+ token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN ||
57
+ token.type === Tokenizer.NULL_CHARACTER_TOKEN) {
58
+
59
+ if (this.options.locationInfo) {
60
+ if (this.pendingText === null)
61
+ this.currentTokenLocation = token.location;
62
+
63
+ else
64
+ this.currentTokenLocation.end = token.location.end;
65
+ }
66
+
67
+ this.pendingText = (this.pendingText || '') + token.chars;
68
+ }
69
+
70
+ else {
71
+ this._emitPendingText();
72
+ this._handleToken(token);
73
+ }
74
+ } while (token.type !== Tokenizer.EOF_TOKEN);
75
+ };
76
+
77
+ //Internals
78
+ SimpleApiParser.prototype._handleToken = function (token) {
79
+ if (this.options.locationInfo)
80
+ this.currentTokenLocation = token.location;
81
+
82
+ if (token.type === Tokenizer.START_TAG_TOKEN)
83
+ this.handlers.startTag(token.tagName, token.attrs, token.selfClosing);
84
+
85
+ else if (token.type === Tokenizer.END_TAG_TOKEN)
86
+ this.handlers.endTag(token.tagName);
87
+
88
+ else if (token.type === Tokenizer.COMMENT_TOKEN)
89
+ this.handlers.comment(token.data);
90
+
91
+ else if (token.type === Tokenizer.DOCTYPE_TOKEN)
92
+ this.handlers.doctype(token.name, token.publicId, token.systemId);
93
+
94
+ };
95
+
96
+ SimpleApiParser.prototype._reset = function (html) {
97
+ this.tokenizerProxy = new TokenizerProxy(html, this.options);
98
+ this.pendingText = null;
99
+ this.currentTokenLocation = null;
100
+ };
101
+
102
+ SimpleApiParser.prototype._emitPendingText = function () {
103
+ if (this.pendingText !== null) {
104
+ this.handlers.text(this.pendingText);
105
+ this.pendingText = null;
106
+ }
107
+ };
@@ -1,122 +1,122 @@
1
- 'use strict';
2
-
3
- var Tokenizer = require('../tokenization/tokenizer'),
4
- ForeignContent = require('../common/foreign_content'),
5
- UNICODE = require('../common/unicode'),
6
- HTML = require('../common/html');
7
-
8
- //Aliases
9
- var $ = HTML.TAG_NAMES,
10
- NS = HTML.NAMESPACES;
11
-
12
-
13
- //Tokenizer proxy
14
- //NOTE: this proxy simulates adjustment of the Tokenizer which performed by standard parser during tree construction.
15
- var TokenizerProxy = module.exports = function (html, options) {
16
- this.tokenizer = new Tokenizer(html, options);
17
-
18
- this.namespaceStack = [];
19
- this.namespaceStackTop = -1;
20
- this.currentNamespace = null;
21
- this.inForeignContent = false;
22
- };
23
-
24
- //API
25
- TokenizerProxy.prototype.getNextToken = function () {
26
- var token = this.tokenizer.getNextToken();
27
-
28
- if (token.type === Tokenizer.START_TAG_TOKEN)
29
- this._handleStartTagToken(token);
30
-
31
- else if (token.type === Tokenizer.END_TAG_TOKEN)
32
- this._handleEndTagToken(token);
33
-
34
- else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN && this.inForeignContent) {
35
- token.type = Tokenizer.CHARACTER_TOKEN;
36
- token.chars = UNICODE.REPLACEMENT_CHARACTER;
37
- }
38
-
39
- return token;
40
- };
41
-
42
- //Namespace stack mutations
43
- TokenizerProxy.prototype._enterNamespace = function (namespace) {
44
- this.namespaceStackTop++;
45
- this.namespaceStack.push(namespace);
46
-
47
- this.inForeignContent = namespace !== NS.HTML;
48
- this.currentNamespace = namespace;
49
- this.tokenizer.allowCDATA = this.inForeignContent;
50
- };
51
-
52
- TokenizerProxy.prototype._leaveCurrentNamespace = function () {
53
- this.namespaceStackTop--;
54
- this.namespaceStack.pop();
55
-
56
- this.currentNamespace = this.namespaceStack[this.namespaceStackTop];
57
- this.inForeignContent = this.currentNamespace !== NS.HTML;
58
- this.tokenizer.allowCDATA = this.inForeignContent;
59
- };
60
-
61
- //Token handlers
62
- TokenizerProxy.prototype._ensureTokenizerMode = function (tn) {
63
- if (tn === $.TEXTAREA || tn === $.TITLE)
64
- this.tokenizer.state = Tokenizer.MODE.RCDATA;
65
-
66
- else if (tn === $.PLAINTEXT)
67
- this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
68
-
69
- else if (tn === $.SCRIPT)
70
- this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
71
-
72
- else if (tn === $.STYLE || tn === $.IFRAME || tn === $.XMP ||
73
- tn === $.NOEMBED || tn === $.NOFRAMES || tn === $.NOSCRIPT) {
74
- this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
75
- }
76
- };
77
-
78
- TokenizerProxy.prototype._handleStartTagToken = function (token) {
79
- var tn = token.tagName;
80
-
81
- if (tn === $.SVG)
82
- this._enterNamespace(NS.SVG);
83
-
84
- else if (tn === $.MATH)
85
- this._enterNamespace(NS.MATHML);
86
-
87
- else {
88
- if (this.inForeignContent) {
89
- if (ForeignContent.causesExit(token))
90
- this._leaveCurrentNamespace();
91
-
92
- else if (ForeignContent.isMathMLTextIntegrationPoint(tn, this.currentNamespace) ||
93
- ForeignContent.isHtmlIntegrationPoint(tn, this.currentNamespace, token.attrs)) {
94
- this._enterNamespace(NS.HTML);
95
- }
96
- }
97
-
98
- else
99
- this._ensureTokenizerMode(tn);
100
- }
101
- };
102
-
103
- TokenizerProxy.prototype._handleEndTagToken = function (token) {
104
- var tn = token.tagName;
105
-
106
- if (!this.inForeignContent) {
107
- var previousNs = this.namespaceStack[this.namespaceStackTop - 1];
108
-
109
- //NOTE: check for exit from integration point
110
- if (ForeignContent.isMathMLTextIntegrationPoint(tn, previousNs) ||
111
- ForeignContent.isHtmlIntegrationPoint(tn, previousNs, token.attrs)) {
112
- this._leaveCurrentNamespace();
113
- }
114
-
115
- else if (tn === $.SCRIPT)
116
- this.tokenizer.state = Tokenizer.MODE.DATA;
117
- }
118
-
119
- else if ((tn === $.SVG && this.currentNamespace === NS.SVG) ||
120
- (tn === $.MATH && this.currentNamespace === NS.MATHML))
121
- this._leaveCurrentNamespace();
122
- };
1
+ 'use strict';
2
+
3
+ var Tokenizer = require('../tokenization/tokenizer'),
4
+ ForeignContent = require('../common/foreign_content'),
5
+ UNICODE = require('../common/unicode'),
6
+ HTML = require('../common/html');
7
+
8
+ //Aliases
9
+ var $ = HTML.TAG_NAMES,
10
+ NS = HTML.NAMESPACES;
11
+
12
+
13
+ //Tokenizer proxy
14
+ //NOTE: this proxy simulates adjustment of the Tokenizer which performed by standard parser during tree construction.
15
+ var TokenizerProxy = module.exports = function (html, options) {
16
+ this.tokenizer = new Tokenizer(html, options);
17
+
18
+ this.namespaceStack = [];
19
+ this.namespaceStackTop = -1;
20
+ this.currentNamespace = null;
21
+ this.inForeignContent = false;
22
+ };
23
+
24
+ //API
25
+ TokenizerProxy.prototype.getNextToken = function () {
26
+ var token = this.tokenizer.getNextToken();
27
+
28
+ if (token.type === Tokenizer.START_TAG_TOKEN)
29
+ this._handleStartTagToken(token);
30
+
31
+ else if (token.type === Tokenizer.END_TAG_TOKEN)
32
+ this._handleEndTagToken(token);
33
+
34
+ else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN && this.inForeignContent) {
35
+ token.type = Tokenizer.CHARACTER_TOKEN;
36
+ token.chars = UNICODE.REPLACEMENT_CHARACTER;
37
+ }
38
+
39
+ return token;
40
+ };
41
+
42
+ //Namespace stack mutations
43
+ TokenizerProxy.prototype._enterNamespace = function (namespace) {
44
+ this.namespaceStackTop++;
45
+ this.namespaceStack.push(namespace);
46
+
47
+ this.inForeignContent = namespace !== NS.HTML;
48
+ this.currentNamespace = namespace;
49
+ this.tokenizer.allowCDATA = this.inForeignContent;
50
+ };
51
+
52
+ TokenizerProxy.prototype._leaveCurrentNamespace = function () {
53
+ this.namespaceStackTop--;
54
+ this.namespaceStack.pop();
55
+
56
+ this.currentNamespace = this.namespaceStack[this.namespaceStackTop];
57
+ this.inForeignContent = this.currentNamespace !== NS.HTML;
58
+ this.tokenizer.allowCDATA = this.inForeignContent;
59
+ };
60
+
61
+ //Token handlers
62
+ TokenizerProxy.prototype._ensureTokenizerMode = function (tn) {
63
+ if (tn === $.TEXTAREA || tn === $.TITLE)
64
+ this.tokenizer.state = Tokenizer.MODE.RCDATA;
65
+
66
+ else if (tn === $.PLAINTEXT)
67
+ this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
68
+
69
+ else if (tn === $.SCRIPT)
70
+ this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
71
+
72
+ else if (tn === $.STYLE || tn === $.IFRAME || tn === $.XMP ||
73
+ tn === $.NOEMBED || tn === $.NOFRAMES || tn === $.NOSCRIPT) {
74
+ this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
75
+ }
76
+ };
77
+
78
+ TokenizerProxy.prototype._handleStartTagToken = function (token) {
79
+ var tn = token.tagName;
80
+
81
+ if (tn === $.SVG)
82
+ this._enterNamespace(NS.SVG);
83
+
84
+ else if (tn === $.MATH)
85
+ this._enterNamespace(NS.MATHML);
86
+
87
+ else {
88
+ if (this.inForeignContent) {
89
+ if (ForeignContent.causesExit(token))
90
+ this._leaveCurrentNamespace();
91
+
92
+ else if (ForeignContent.isMathMLTextIntegrationPoint(tn, this.currentNamespace) ||
93
+ ForeignContent.isHtmlIntegrationPoint(tn, this.currentNamespace, token.attrs)) {
94
+ this._enterNamespace(NS.HTML);
95
+ }
96
+ }
97
+
98
+ else
99
+ this._ensureTokenizerMode(tn);
100
+ }
101
+ };
102
+
103
+ TokenizerProxy.prototype._handleEndTagToken = function (token) {
104
+ var tn = token.tagName;
105
+
106
+ if (!this.inForeignContent) {
107
+ var previousNs = this.namespaceStack[this.namespaceStackTop - 1];
108
+
109
+ //NOTE: check for exit from integration point
110
+ if (ForeignContent.isMathMLTextIntegrationPoint(tn, previousNs) ||
111
+ ForeignContent.isHtmlIntegrationPoint(tn, previousNs, token.attrs)) {
112
+ this._leaveCurrentNamespace();
113
+ }
114
+
115
+ else if (tn === $.SCRIPT)
116
+ this.tokenizer.state = Tokenizer.MODE.DATA;
117
+ }
118
+
119
+ else if ((tn === $.SVG && this.currentNamespace === NS.SVG) ||
120
+ (tn === $.MATH && this.currentNamespace === NS.MATHML))
121
+ this._leaveCurrentNamespace();
122
+ };