parse5 2.2.2 → 3.0.2

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,327 +1,338 @@
1
- 'use strict';
2
-
3
- var doctype = require('../common/doctype');
4
-
5
- //Conversion tables for DOM Level1 structure emulation
6
- var nodeTypes = {
7
- element: 1,
8
- text: 3,
9
- cdata: 4,
10
- comment: 8
11
- };
12
-
13
- var nodePropertyShorthands = {
14
- tagName: 'name',
15
- childNodes: 'children',
16
- parentNode: 'parent',
17
- previousSibling: 'prev',
18
- nextSibling: 'next',
19
- nodeValue: 'data'
20
- };
21
-
22
- //Node
23
- var Node = function (props) {
24
- for (var key in props) {
25
- if (props.hasOwnProperty(key))
26
- this[key] = props[key];
27
- }
28
- };
29
-
30
- Node.prototype = {
31
- get firstChild() {
32
- var children = this.children;
33
-
34
- return children && children[0] || null;
35
- },
36
-
37
- get lastChild() {
38
- var children = this.children;
39
-
40
- return children && children[children.length - 1] || null;
41
- },
42
-
43
- get nodeType() {
44
- return nodeTypes[this.type] || nodeTypes.element;
45
- }
46
- };
47
-
48
- Object.keys(nodePropertyShorthands).forEach(function (key) {
49
- var shorthand = nodePropertyShorthands[key];
50
-
51
- Object.defineProperty(Node.prototype, key, {
52
- get: function () {
53
- return this[shorthand] || null;
54
- },
55
- set: function (val) {
56
- this[shorthand] = val;
57
- return val;
58
- }
59
- });
60
- });
61
-
62
-
63
- //Node construction
64
- exports.createDocument =
65
- exports.createDocumentFragment = function () {
66
- return new Node({
67
- type: 'root',
68
- name: 'root',
69
- parent: null,
70
- prev: null,
71
- next: null,
72
- children: []
73
- });
74
- };
75
-
76
- exports.createElement = function (tagName, namespaceURI, attrs) {
77
- var attribs = {},
78
- attribsNamespace = {},
79
- attribsPrefix = {};
80
-
81
- for (var i = 0; i < attrs.length; i++) {
82
- var attrName = attrs[i].name;
83
-
84
- attribs[attrName] = attrs[i].value;
85
- attribsNamespace[attrName] = attrs[i].namespace;
86
- attribsPrefix[attrName] = attrs[i].prefix;
87
- }
88
-
89
- return new Node({
90
- type: tagName === 'script' || tagName === 'style' ? tagName : 'tag',
91
- name: tagName,
92
- namespace: namespaceURI,
93
- attribs: attribs,
94
- 'x-attribsNamespace': attribsNamespace,
95
- 'x-attribsPrefix': attribsPrefix,
96
- children: [],
97
- parent: null,
98
- prev: null,
99
- next: null
100
- });
101
- };
102
-
103
- exports.createCommentNode = function (data) {
104
- return new Node({
105
- type: 'comment',
106
- data: data,
107
- parent: null,
108
- prev: null,
109
- next: null
110
- });
111
- };
112
-
113
- var createTextNode = function (value) {
114
- return new Node({
115
- type: 'text',
116
- data: value,
117
- parent: null,
118
- prev: null,
119
- next: null
120
- });
121
- };
122
-
123
-
124
- //Tree mutation
125
- var appendChild = exports.appendChild = function (parentNode, newNode) {
126
- var prev = parentNode.children[parentNode.children.length - 1];
127
-
128
- if (prev) {
129
- prev.next = newNode;
130
- newNode.prev = prev;
131
- }
132
-
133
- parentNode.children.push(newNode);
134
- newNode.parent = parentNode;
135
- };
136
-
137
- var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
138
- var insertionIdx = parentNode.children.indexOf(referenceNode),
139
- prev = referenceNode.prev;
140
-
141
- if (prev) {
142
- prev.next = newNode;
143
- newNode.prev = prev;
144
- }
145
-
146
- referenceNode.prev = newNode;
147
- newNode.next = referenceNode;
148
-
149
- parentNode.children.splice(insertionIdx, 0, newNode);
150
- newNode.parent = parentNode;
151
- };
152
-
153
- exports.setTemplateContent = function (templateElement, contentElement) {
154
- appendChild(templateElement, contentElement);
155
- };
156
-
157
- exports.getTemplateContent = function (templateElement) {
158
- return templateElement.children[0];
159
- };
160
-
161
- exports.setDocumentType = function (document, name, publicId, systemId) {
162
- var data = doctype.serializeContent(name, publicId, systemId),
163
- doctypeNode = null;
164
-
165
- for (var i = 0; i < document.children.length; i++) {
166
- if (document.children[i].type === 'directive' && document.children[i].name === '!doctype') {
167
- doctypeNode = document.children[i];
168
- break;
169
- }
170
- }
171
-
172
- if (doctypeNode) {
173
- doctypeNode.data = data;
174
- doctypeNode['x-name'] = name;
175
- doctypeNode['x-publicId'] = publicId;
176
- doctypeNode['x-systemId'] = systemId;
177
- }
178
-
179
- else {
180
- appendChild(document, new Node({
181
- type: 'directive',
182
- name: '!doctype',
183
- data: data,
184
- 'x-name': name,
185
- 'x-publicId': publicId,
186
- 'x-systemId': systemId
187
- }));
188
- }
189
-
190
- };
191
-
192
- exports.setQuirksMode = function (document) {
193
- document.quirksMode = true;
194
- };
195
-
196
- exports.isQuirksMode = function (document) {
197
- return document.quirksMode;
198
- };
199
-
200
- exports.detachNode = function (node) {
201
- if (node.parent) {
202
- var idx = node.parent.children.indexOf(node),
203
- prev = node.prev,
204
- next = node.next;
205
-
206
- node.prev = null;
207
- node.next = null;
208
-
209
- if (prev)
210
- prev.next = next;
211
-
212
- if (next)
213
- next.prev = prev;
214
-
215
- node.parent.children.splice(idx, 1);
216
- node.parent = null;
217
- }
218
- };
219
-
220
- exports.insertText = function (parentNode, text) {
221
- var lastChild = parentNode.children[parentNode.children.length - 1];
222
-
223
- if (lastChild && lastChild.type === 'text')
224
- lastChild.data += text;
225
- else
226
- appendChild(parentNode, createTextNode(text));
227
- };
228
-
229
- exports.insertTextBefore = function (parentNode, text, referenceNode) {
230
- var prevNode = parentNode.children[parentNode.children.indexOf(referenceNode) - 1];
231
-
232
- if (prevNode && prevNode.type === 'text')
233
- prevNode.data += text;
234
- else
235
- insertBefore(parentNode, createTextNode(text), referenceNode);
236
- };
237
-
238
- exports.adoptAttributes = function (recipientNode, attrs) {
239
- for (var i = 0; i < attrs.length; i++) {
240
- var attrName = attrs[i].name;
241
-
242
- if (typeof recipientNode.attribs[attrName] === 'undefined') {
243
- recipientNode.attribs[attrName] = attrs[i].value;
244
- recipientNode['x-attribsNamespace'][attrName] = attrs[i].namespace;
245
- recipientNode['x-attribsPrefix'][attrName] = attrs[i].prefix;
246
- }
247
- }
248
- };
249
-
250
-
251
- //Tree traversing
252
- exports.getFirstChild = function (node) {
253
- return node.children[0];
254
- };
255
-
256
- exports.getChildNodes = function (node) {
257
- return node.children;
258
- };
259
-
260
- exports.getParentNode = function (node) {
261
- return node.parent;
262
- };
263
-
264
- exports.getAttrList = function (node) {
265
- var attrList = [];
266
-
267
- for (var name in node.attribs) {
268
- if (node.attribs.hasOwnProperty(name)) {
269
- attrList.push({
270
- name: name,
271
- value: node.attribs[name],
272
- namespace: node['x-attribsNamespace'][name],
273
- prefix: node['x-attribsPrefix'][name]
274
- });
275
- }
276
- }
277
-
278
- return attrList;
279
- };
280
-
281
-
282
- //Node data
283
- exports.getTagName = function (element) {
284
- return element.name;
285
- };
286
-
287
- exports.getNamespaceURI = function (element) {
288
- return element.namespace;
289
- };
290
-
291
- exports.getTextNodeContent = function (textNode) {
292
- return textNode.data;
293
- };
294
-
295
- exports.getCommentNodeContent = function (commentNode) {
296
- return commentNode.data;
297
- };
298
-
299
- exports.getDocumentTypeNodeName = function (doctypeNode) {
300
- return doctypeNode['x-name'];
301
- };
302
-
303
- exports.getDocumentTypeNodePublicId = function (doctypeNode) {
304
- return doctypeNode['x-publicId'];
305
- };
306
-
307
- exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
308
- return doctypeNode['x-systemId'];
309
- };
310
-
311
-
312
- //Node types
313
- exports.isTextNode = function (node) {
314
- return node.type === 'text';
315
- };
316
-
317
- exports.isCommentNode = function (node) {
318
- return node.type === 'comment';
319
- };
320
-
321
- exports.isDocumentTypeNode = function (node) {
322
- return node.type === 'directive' && node.name === '!doctype';
323
- };
324
-
325
- exports.isElementNode = function (node) {
326
- return !!node.attribs;
327
- };
1
+ 'use strict';
2
+
3
+ var doctype = require('../common/doctype'),
4
+ DOCUMENT_MODE = require('../common/html').DOCUMENT_MODE;
5
+
6
+
7
+ //Conversion tables for DOM Level1 structure emulation
8
+ var nodeTypes = {
9
+ element: 1,
10
+ text: 3,
11
+ cdata: 4,
12
+ comment: 8
13
+ };
14
+
15
+ var nodePropertyShorthands = {
16
+ tagName: 'name',
17
+ childNodes: 'children',
18
+ parentNode: 'parent',
19
+ previousSibling: 'prev',
20
+ nextSibling: 'next',
21
+ nodeValue: 'data'
22
+ };
23
+
24
+ //Node
25
+ var Node = function (props) {
26
+ for (var key in props) {
27
+ if (props.hasOwnProperty(key))
28
+ this[key] = props[key];
29
+ }
30
+ };
31
+
32
+ Node.prototype = {
33
+ get firstChild() {
34
+ var children = this.children;
35
+
36
+ return children && children[0] || null;
37
+ },
38
+
39
+ get lastChild() {
40
+ var children = this.children;
41
+
42
+ return children && children[children.length - 1] || null;
43
+ },
44
+
45
+ get nodeType() {
46
+ return nodeTypes[this.type] || nodeTypes.element;
47
+ }
48
+ };
49
+
50
+ Object.keys(nodePropertyShorthands).forEach(function (key) {
51
+ var shorthand = nodePropertyShorthands[key];
52
+
53
+ Object.defineProperty(Node.prototype, key, {
54
+ get: function () {
55
+ return this[shorthand] || null;
56
+ },
57
+ set: function (val) {
58
+ this[shorthand] = val;
59
+ return val;
60
+ }
61
+ });
62
+ });
63
+
64
+
65
+ //Node construction
66
+ exports.createDocument = function () {
67
+ return new Node({
68
+ type: 'root',
69
+ name: 'root',
70
+ parent: null,
71
+ prev: null,
72
+ next: null,
73
+ children: [],
74
+ 'x-mode': DOCUMENT_MODE.NO_QUIRKS
75
+ });
76
+ };
77
+
78
+ exports.createDocumentFragment = function () {
79
+ return new Node({
80
+ type: 'root',
81
+ name: 'root',
82
+ parent: null,
83
+ prev: null,
84
+ next: null,
85
+ children: []
86
+ });
87
+ };
88
+
89
+ exports.createElement = function (tagName, namespaceURI, attrs) {
90
+ var attribs = Object.create(null),
91
+ attribsNamespace = Object.create(null),
92
+ attribsPrefix = Object.create(null);
93
+
94
+ for (var i = 0; i < attrs.length; i++) {
95
+ var attrName = attrs[i].name;
96
+
97
+ attribs[attrName] = attrs[i].value;
98
+ attribsNamespace[attrName] = attrs[i].namespace;
99
+ attribsPrefix[attrName] = attrs[i].prefix;
100
+ }
101
+
102
+ return new Node({
103
+ type: tagName === 'script' || tagName === 'style' ? tagName : 'tag',
104
+ name: tagName,
105
+ namespace: namespaceURI,
106
+ attribs: attribs,
107
+ 'x-attribsNamespace': attribsNamespace,
108
+ 'x-attribsPrefix': attribsPrefix,
109
+ children: [],
110
+ parent: null,
111
+ prev: null,
112
+ next: null
113
+ });
114
+ };
115
+
116
+ exports.createCommentNode = function (data) {
117
+ return new Node({
118
+ type: 'comment',
119
+ data: data,
120
+ parent: null,
121
+ prev: null,
122
+ next: null
123
+ });
124
+ };
125
+
126
+ var createTextNode = function (value) {
127
+ return new Node({
128
+ type: 'text',
129
+ data: value,
130
+ parent: null,
131
+ prev: null,
132
+ next: null
133
+ });
134
+ };
135
+
136
+
137
+ //Tree mutation
138
+ var appendChild = exports.appendChild = function (parentNode, newNode) {
139
+ var prev = parentNode.children[parentNode.children.length - 1];
140
+
141
+ if (prev) {
142
+ prev.next = newNode;
143
+ newNode.prev = prev;
144
+ }
145
+
146
+ parentNode.children.push(newNode);
147
+ newNode.parent = parentNode;
148
+ };
149
+
150
+ var insertBefore = exports.insertBefore = function (parentNode, newNode, referenceNode) {
151
+ var insertionIdx = parentNode.children.indexOf(referenceNode),
152
+ prev = referenceNode.prev;
153
+
154
+ if (prev) {
155
+ prev.next = newNode;
156
+ newNode.prev = prev;
157
+ }
158
+
159
+ referenceNode.prev = newNode;
160
+ newNode.next = referenceNode;
161
+
162
+ parentNode.children.splice(insertionIdx, 0, newNode);
163
+ newNode.parent = parentNode;
164
+ };
165
+
166
+ exports.setTemplateContent = function (templateElement, contentElement) {
167
+ appendChild(templateElement, contentElement);
168
+ };
169
+
170
+ exports.getTemplateContent = function (templateElement) {
171
+ return templateElement.children[0];
172
+ };
173
+
174
+ exports.setDocumentType = function (document, name, publicId, systemId) {
175
+ var data = doctype.serializeContent(name, publicId, systemId),
176
+ doctypeNode = null;
177
+
178
+ for (var i = 0; i < document.children.length; i++) {
179
+ if (document.children[i].type === 'directive' && document.children[i].name === '!doctype') {
180
+ doctypeNode = document.children[i];
181
+ break;
182
+ }
183
+ }
184
+
185
+ if (doctypeNode) {
186
+ doctypeNode.data = data;
187
+ doctypeNode['x-name'] = name;
188
+ doctypeNode['x-publicId'] = publicId;
189
+ doctypeNode['x-systemId'] = systemId;
190
+ }
191
+
192
+ else {
193
+ appendChild(document, new Node({
194
+ type: 'directive',
195
+ name: '!doctype',
196
+ data: data,
197
+ 'x-name': name,
198
+ 'x-publicId': publicId,
199
+ 'x-systemId': systemId
200
+ }));
201
+ }
202
+
203
+ };
204
+
205
+ exports.setDocumentMode = function (document, mode) {
206
+ document['x-mode'] = mode;
207
+ };
208
+
209
+ exports.getDocumentMode = function (document) {
210
+ return document['x-mode'];
211
+ };
212
+
213
+ exports.detachNode = function (node) {
214
+ if (node.parent) {
215
+ var idx = node.parent.children.indexOf(node),
216
+ prev = node.prev,
217
+ next = node.next;
218
+
219
+ node.prev = null;
220
+ node.next = null;
221
+
222
+ if (prev)
223
+ prev.next = next;
224
+
225
+ if (next)
226
+ next.prev = prev;
227
+
228
+ node.parent.children.splice(idx, 1);
229
+ node.parent = null;
230
+ }
231
+ };
232
+
233
+ exports.insertText = function (parentNode, text) {
234
+ var lastChild = parentNode.children[parentNode.children.length - 1];
235
+
236
+ if (lastChild && lastChild.type === 'text')
237
+ lastChild.data += text;
238
+ else
239
+ appendChild(parentNode, createTextNode(text));
240
+ };
241
+
242
+ exports.insertTextBefore = function (parentNode, text, referenceNode) {
243
+ var prevNode = parentNode.children[parentNode.children.indexOf(referenceNode) - 1];
244
+
245
+ if (prevNode && prevNode.type === 'text')
246
+ prevNode.data += text;
247
+ else
248
+ insertBefore(parentNode, createTextNode(text), referenceNode);
249
+ };
250
+
251
+ exports.adoptAttributes = function (recipient, attrs) {
252
+ for (var i = 0; i < attrs.length; i++) {
253
+ var attrName = attrs[i].name;
254
+
255
+ if (typeof recipient.attribs[attrName] === 'undefined') {
256
+ recipient.attribs[attrName] = attrs[i].value;
257
+ recipient['x-attribsNamespace'][attrName] = attrs[i].namespace;
258
+ recipient['x-attribsPrefix'][attrName] = attrs[i].prefix;
259
+ }
260
+ }
261
+ };
262
+
263
+
264
+ //Tree traversing
265
+ exports.getFirstChild = function (node) {
266
+ return node.children[0];
267
+ };
268
+
269
+ exports.getChildNodes = function (node) {
270
+ return node.children;
271
+ };
272
+
273
+ exports.getParentNode = function (node) {
274
+ return node.parent;
275
+ };
276
+
277
+ exports.getAttrList = function (element) {
278
+ var attrList = [];
279
+
280
+ for (var name in element.attribs) {
281
+ attrList.push({
282
+ name: name,
283
+ value: element.attribs[name],
284
+ namespace: element['x-attribsNamespace'][name],
285
+ prefix: element['x-attribsPrefix'][name]
286
+ });
287
+ }
288
+
289
+ return attrList;
290
+ };
291
+
292
+
293
+ //Node data
294
+ exports.getTagName = function (element) {
295
+ return element.name;
296
+ };
297
+
298
+ exports.getNamespaceURI = function (element) {
299
+ return element.namespace;
300
+ };
301
+
302
+ exports.getTextNodeContent = function (textNode) {
303
+ return textNode.data;
304
+ };
305
+
306
+ exports.getCommentNodeContent = function (commentNode) {
307
+ return commentNode.data;
308
+ };
309
+
310
+ exports.getDocumentTypeNodeName = function (doctypeNode) {
311
+ return doctypeNode['x-name'];
312
+ };
313
+
314
+ exports.getDocumentTypeNodePublicId = function (doctypeNode) {
315
+ return doctypeNode['x-publicId'];
316
+ };
317
+
318
+ exports.getDocumentTypeNodeSystemId = function (doctypeNode) {
319
+ return doctypeNode['x-systemId'];
320
+ };
321
+
322
+
323
+ //Node types
324
+ exports.isTextNode = function (node) {
325
+ return node.type === 'text';
326
+ };
327
+
328
+ exports.isCommentNode = function (node) {
329
+ return node.type === 'comment';
330
+ };
331
+
332
+ exports.isDocumentTypeNode = function (node) {
333
+ return node.type === 'directive' && node.name === '!doctype';
334
+ };
335
+
336
+ exports.isElementNode = function (node) {
337
+ return !!node.attribs;
338
+ };