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,197 +1,197 @@
1
- 'use strict';
2
-
3
- var OpenElementStack = require('./open_element_stack'),
4
- Tokenizer = require('../tokenization/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
- if (!loc.startTag) {
19
- loc.startTag = {
20
- start: loc.start,
21
- end: loc.end
22
- };
23
- }
24
-
25
- if (closingToken.location) {
26
- var tn = treeAdapter.getTagName(element),
27
- // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing tag and
28
- // for cases like <td> <p> </td> - 'p' closes without a closing tag
29
- isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN &&
30
- tn === closingToken.tagName;
31
-
32
- if (isClosingEndTag) {
33
- loc.endTag = {
34
- start: closingToken.location.start,
35
- end: closingToken.location.end
36
- };
37
- }
38
-
39
- loc.end = closingToken.location.end;
40
- }
41
- }
42
-
43
- //NOTE: patch open elements stack, so we can assign end location for the elements
44
- function patchOpenElementsStack(stack, parser) {
45
- var treeAdapter = parser.treeAdapter;
46
-
47
- stack.pop = function () {
48
- setEndLocation(this.current, parser.currentToken, treeAdapter);
49
- OpenElementStack.prototype.pop.call(this);
50
- };
51
-
52
- stack.popAllUpToHtmlElement = function () {
53
- for (var i = this.stackTop; i > 0; i--)
54
- setEndLocation(this.items[i], parser.currentToken, treeAdapter);
55
-
56
- OpenElementStack.prototype.popAllUpToHtmlElement.call(this);
57
- };
58
-
59
- stack.remove = function (element) {
60
- setEndLocation(element, parser.currentToken, treeAdapter);
61
- OpenElementStack.prototype.remove.call(this, element);
62
- };
63
- }
64
-
65
- exports.assign = function (parser) {
66
- //NOTE: obtain Parser proto this way to avoid module circular references
67
- var parserProto = Object.getPrototypeOf(parser),
68
- treeAdapter = parser.treeAdapter;
69
-
70
-
71
- //NOTE: patch _reset method
72
- parser._reset = function (html, document, fragmentContext) {
73
- parserProto._reset.call(this, html, document, fragmentContext);
74
-
75
- this.attachableElementLocation = null;
76
- this.lastFosterParentingLocation = null;
77
- this.currentToken = null;
78
-
79
- patchOpenElementsStack(this.openElements, parser);
80
- };
81
-
82
- parser._processTokenInForeignContent = function (token) {
83
- this.currentToken = token;
84
- parserProto._processTokenInForeignContent.call(this, token);
85
- };
86
-
87
- parser._processToken = function (token) {
88
- this.currentToken = token;
89
- parserProto._processToken.call(this, token);
90
-
91
- //NOTE: <body> and <html> are never popped from the stack, so we need to updated
92
- //their end location explicitly.
93
- if (token.type === Tokenizer.END_TAG_TOKEN &&
94
- (token.tagName === $.HTML ||
95
- (token.tagName === $.BODY && this.openElements.hasInScope($.BODY)))) {
96
- for (var i = this.openElements.stackTop; i >= 0; i--) {
97
- var element = this.openElements.items[i];
98
-
99
- if (this.treeAdapter.getTagName(element) === token.tagName) {
100
- setEndLocation(element, token, treeAdapter);
101
- break;
102
- }
103
- }
104
- }
105
- };
106
-
107
- //Doctype
108
- parser._setDocumentType = function (token) {
109
- parserProto._setDocumentType.call(this, token);
110
-
111
- var documentChildren = this.treeAdapter.getChildNodes(this.document),
112
- cnLength = documentChildren.length;
113
-
114
- for (var i = 0; i < cnLength; i++) {
115
- var node = documentChildren[i];
116
-
117
- if (this.treeAdapter.isDocumentTypeNode(node)) {
118
- node.__location = token.location;
119
- break;
120
- }
121
- }
122
- };
123
-
124
- //Elements
125
- parser._attachElementToTree = function (element) {
126
- //NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
127
- //So we will use token location stored in this methods for the element.
128
- element.__location = this.attachableElementLocation || null;
129
- this.attachableElementLocation = null;
130
- parserProto._attachElementToTree.call(this, element);
131
- };
132
-
133
- parser._appendElement = function (token, namespaceURI) {
134
- this.attachableElementLocation = token.location;
135
- parserProto._appendElement.call(this, token, namespaceURI);
136
- };
137
-
138
- parser._insertElement = function (token, namespaceURI) {
139
- this.attachableElementLocation = token.location;
140
- parserProto._insertElement.call(this, token, namespaceURI);
141
- };
142
-
143
- parser._insertTemplate = function (token) {
144
- this.attachableElementLocation = token.location;
145
- parserProto._insertTemplate.call(this, token);
146
-
147
- var tmplContent = this.treeAdapter.getChildNodes(this.openElements.current)[0];
148
-
149
- tmplContent.__location = null;
150
- };
151
-
152
- parser._insertFakeRootElement = function () {
153
- parserProto._insertFakeRootElement.call(this);
154
- this.openElements.current.__location = null;
155
- };
156
-
157
- //Comments
158
- parser._appendCommentNode = function (token, parent) {
159
- parserProto._appendCommentNode.call(this, token, parent);
160
-
161
- var children = this.treeAdapter.getChildNodes(parent),
162
- commentNode = children[children.length - 1];
163
-
164
- commentNode.__location = token.location;
165
- };
166
-
167
- //Text
168
- parser._findFosterParentingLocation = function () {
169
- //NOTE: store last foster parenting location, so we will be able to find inserted text
170
- //in case of foster parenting
171
- this.lastFosterParentingLocation = parserProto._findFosterParentingLocation.call(this);
172
- return this.lastFosterParentingLocation;
173
- };
174
-
175
- parser._insertCharacters = function (token) {
176
- parserProto._insertCharacters.call(this, token);
177
-
178
- var hasFosterParent = this._shouldFosterParentOnInsertion(),
179
- parentingLocation = this.lastFosterParentingLocation,
180
- parent = (hasFosterParent && parentingLocation.parent) ||
181
- this.openElements.currentTmplContent ||
182
- this.openElements.current,
183
- siblings = this.treeAdapter.getChildNodes(parent),
184
- textNodeIdx = hasFosterParent && parentingLocation.beforeElement ?
185
- siblings.indexOf(parentingLocation.beforeElement) - 1 :
186
- siblings.length - 1,
187
- textNode = siblings[textNodeIdx];
188
-
189
- //NOTE: if we have location assigned by another token, then just update end position
190
- if (textNode.__location)
191
- textNode.__location.end = token.location.end;
192
-
193
- else
194
- textNode.__location = token.location;
195
- };
196
- };
197
-
1
+ 'use strict';
2
+
3
+ var OpenElementStack = require('./open_element_stack'),
4
+ Tokenizer = require('../tokenization/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
+ if (!loc.startTag) {
19
+ loc.startTag = {
20
+ start: loc.start,
21
+ end: loc.end
22
+ };
23
+ }
24
+
25
+ if (closingToken.location) {
26
+ var tn = treeAdapter.getTagName(element),
27
+ // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing tag and
28
+ // for cases like <td> <p> </td> - 'p' closes without a closing tag
29
+ isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN &&
30
+ tn === closingToken.tagName;
31
+
32
+ if (isClosingEndTag) {
33
+ loc.endTag = {
34
+ start: closingToken.location.start,
35
+ end: closingToken.location.end
36
+ };
37
+ }
38
+
39
+ loc.end = closingToken.location.end;
40
+ }
41
+ }
42
+
43
+ //NOTE: patch open elements stack, so we can assign end location for the elements
44
+ function patchOpenElementsStack(stack, parser) {
45
+ var treeAdapter = parser.treeAdapter;
46
+
47
+ stack.pop = function () {
48
+ setEndLocation(this.current, parser.currentToken, treeAdapter);
49
+ OpenElementStack.prototype.pop.call(this);
50
+ };
51
+
52
+ stack.popAllUpToHtmlElement = function () {
53
+ for (var i = this.stackTop; i > 0; i--)
54
+ setEndLocation(this.items[i], parser.currentToken, treeAdapter);
55
+
56
+ OpenElementStack.prototype.popAllUpToHtmlElement.call(this);
57
+ };
58
+
59
+ stack.remove = function (element) {
60
+ setEndLocation(element, parser.currentToken, treeAdapter);
61
+ OpenElementStack.prototype.remove.call(this, element);
62
+ };
63
+ }
64
+
65
+ exports.assign = function (parser) {
66
+ //NOTE: obtain Parser proto this way to avoid module circular references
67
+ var parserProto = Object.getPrototypeOf(parser),
68
+ treeAdapter = parser.treeAdapter;
69
+
70
+
71
+ //NOTE: patch _reset method
72
+ parser._reset = function (html, document, fragmentContext) {
73
+ parserProto._reset.call(this, html, document, fragmentContext);
74
+
75
+ this.attachableElementLocation = null;
76
+ this.lastFosterParentingLocation = null;
77
+ this.currentToken = null;
78
+
79
+ patchOpenElementsStack(this.openElements, parser);
80
+ };
81
+
82
+ parser._processTokenInForeignContent = function (token) {
83
+ this.currentToken = token;
84
+ parserProto._processTokenInForeignContent.call(this, token);
85
+ };
86
+
87
+ parser._processToken = function (token) {
88
+ this.currentToken = token;
89
+ parserProto._processToken.call(this, token);
90
+
91
+ //NOTE: <body> and <html> are never popped from the stack, so we need to updated
92
+ //their end location explicitly.
93
+ if (token.type === Tokenizer.END_TAG_TOKEN &&
94
+ (token.tagName === $.HTML ||
95
+ (token.tagName === $.BODY && this.openElements.hasInScope($.BODY)))) {
96
+ for (var i = this.openElements.stackTop; i >= 0; i--) {
97
+ var element = this.openElements.items[i];
98
+
99
+ if (this.treeAdapter.getTagName(element) === token.tagName) {
100
+ setEndLocation(element, token, treeAdapter);
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ };
106
+
107
+ //Doctype
108
+ parser._setDocumentType = function (token) {
109
+ parserProto._setDocumentType.call(this, token);
110
+
111
+ var documentChildren = this.treeAdapter.getChildNodes(this.document),
112
+ cnLength = documentChildren.length;
113
+
114
+ for (var i = 0; i < cnLength; i++) {
115
+ var node = documentChildren[i];
116
+
117
+ if (this.treeAdapter.isDocumentTypeNode(node)) {
118
+ node.__location = token.location;
119
+ break;
120
+ }
121
+ }
122
+ };
123
+
124
+ //Elements
125
+ parser._attachElementToTree = function (element) {
126
+ //NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
127
+ //So we will use token location stored in this methods for the element.
128
+ element.__location = this.attachableElementLocation || null;
129
+ this.attachableElementLocation = null;
130
+ parserProto._attachElementToTree.call(this, element);
131
+ };
132
+
133
+ parser._appendElement = function (token, namespaceURI) {
134
+ this.attachableElementLocation = token.location;
135
+ parserProto._appendElement.call(this, token, namespaceURI);
136
+ };
137
+
138
+ parser._insertElement = function (token, namespaceURI) {
139
+ this.attachableElementLocation = token.location;
140
+ parserProto._insertElement.call(this, token, namespaceURI);
141
+ };
142
+
143
+ parser._insertTemplate = function (token) {
144
+ this.attachableElementLocation = token.location;
145
+ parserProto._insertTemplate.call(this, token);
146
+
147
+ var tmplContent = this.treeAdapter.getChildNodes(this.openElements.current)[0];
148
+
149
+ tmplContent.__location = null;
150
+ };
151
+
152
+ parser._insertFakeRootElement = function () {
153
+ parserProto._insertFakeRootElement.call(this);
154
+ this.openElements.current.__location = null;
155
+ };
156
+
157
+ //Comments
158
+ parser._appendCommentNode = function (token, parent) {
159
+ parserProto._appendCommentNode.call(this, token, parent);
160
+
161
+ var children = this.treeAdapter.getChildNodes(parent),
162
+ commentNode = children[children.length - 1];
163
+
164
+ commentNode.__location = token.location;
165
+ };
166
+
167
+ //Text
168
+ parser._findFosterParentingLocation = function () {
169
+ //NOTE: store last foster parenting location, so we will be able to find inserted text
170
+ //in case of foster parenting
171
+ this.lastFosterParentingLocation = parserProto._findFosterParentingLocation.call(this);
172
+ return this.lastFosterParentingLocation;
173
+ };
174
+
175
+ parser._insertCharacters = function (token) {
176
+ parserProto._insertCharacters.call(this, token);
177
+
178
+ var hasFosterParent = this._shouldFosterParentOnInsertion(),
179
+ parentingLocation = this.lastFosterParentingLocation,
180
+ parent = (hasFosterParent && parentingLocation.parent) ||
181
+ this.openElements.currentTmplContent ||
182
+ this.openElements.current,
183
+ siblings = this.treeAdapter.getChildNodes(parent),
184
+ textNodeIdx = hasFosterParent && parentingLocation.beforeElement ?
185
+ siblings.indexOf(parentingLocation.beforeElement) - 1 :
186
+ siblings.length - 1,
187
+ textNode = siblings[textNodeIdx];
188
+
189
+ //NOTE: if we have location assigned by another token, then just update end position
190
+ if (textNode.__location)
191
+ textNode.__location.end = token.location.end;
192
+
193
+ else
194
+ textNode.__location = token.location;
195
+ };
196
+ };
197
+