source: trip-planner-front/node_modules/parse5-htmlparser2-tree-adapter/lib/index.js@ 76712b2

Last change on this file since 76712b2 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

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