parse5-htmlparser2-tree-adapter 5.1.1 → 7.0.0

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.
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  <br>
17
17
 
18
18
  <p align="center">
19
- 📖 <a href="https://github.com/inikulin/parse5/tree/master/packages/parse5-htmlparser2-tree-adapter/docs/index.md"><b>Documentation</b></a> 📖
19
+ 📖 <a href="https://parse5.js.org/modules/parse5_htmlparser2_tree_adapter.html"><b>Documentation</b></a> 📖
20
20
  </p>
21
21
 
22
22
  ---
@@ -30,5 +30,5 @@
30
30
  </p>
31
31
 
32
32
  <p align="center">
33
- <a href="https://github.com/inikulin/parse5/tree/master/docs/version-history.md">Version history</a>
33
+ <a href="https://github.com/inikulin/parse5/releases">Changelog</a>
34
34
  </p>
@@ -0,0 +1,7 @@
1
+ import { type TreeAdapterTypeMap, type TreeAdapter } from 'parse5';
2
+ import { type AnyNode, type ParentNode, type ChildNode, Element, Document, ProcessingInstruction, Comment, Text } from 'domhandler';
3
+ export declare type Htmlparser2TreeAdapterMap = TreeAdapterTypeMap<AnyNode, ParentNode, ChildNode, Document, Document, Element, Comment, Text, Element, ProcessingInstruction>;
4
+ /** @internal */
5
+ export declare function serializeDoctypeContent(name: string, publicId: string, systemId: string): string;
6
+ export declare const adapter: TreeAdapter<Htmlparser2TreeAdapterMap>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.adapter = exports.serializeDoctypeContent = void 0;
4
+ const parse5_1 = require("parse5");
5
+ const domhandler_1 = require("domhandler");
6
+ function createTextNode(value) {
7
+ return new domhandler_1.Text(value);
8
+ }
9
+ function enquoteDoctypeId(id) {
10
+ const quote = id.includes('"') ? "'" : '"';
11
+ return quote + id + quote;
12
+ }
13
+ /** @internal */
14
+ function serializeDoctypeContent(name, publicId, systemId) {
15
+ let str = '!DOCTYPE ';
16
+ if (name) {
17
+ str += name;
18
+ }
19
+ if (publicId) {
20
+ str += ` PUBLIC ${enquoteDoctypeId(publicId)}`;
21
+ }
22
+ else if (systemId) {
23
+ str += ' SYSTEM';
24
+ }
25
+ if (systemId) {
26
+ str += ` ${enquoteDoctypeId(systemId)}`;
27
+ }
28
+ return str;
29
+ }
30
+ exports.serializeDoctypeContent = serializeDoctypeContent;
31
+ exports.adapter = {
32
+ // Re-exports from domhandler
33
+ isCommentNode: domhandler_1.isComment,
34
+ isElementNode: domhandler_1.isTag,
35
+ isTextNode: domhandler_1.isText,
36
+ //Node construction
37
+ createDocument() {
38
+ const node = new domhandler_1.Document([]);
39
+ node['x-mode'] = parse5_1.html.DOCUMENT_MODE.NO_QUIRKS;
40
+ return node;
41
+ },
42
+ createDocumentFragment() {
43
+ return new domhandler_1.Document([]);
44
+ },
45
+ createElement(tagName, namespaceURI, attrs) {
46
+ const attribs = Object.create(null);
47
+ const attribsNamespace = Object.create(null);
48
+ const attribsPrefix = Object.create(null);
49
+ for (let i = 0; i < attrs.length; i++) {
50
+ const attrName = attrs[i].name;
51
+ attribs[attrName] = attrs[i].value;
52
+ attribsNamespace[attrName] = attrs[i].namespace;
53
+ attribsPrefix[attrName] = attrs[i].prefix;
54
+ }
55
+ const node = new domhandler_1.Element(tagName, attribs, []);
56
+ node.namespace = namespaceURI;
57
+ node['x-attribsNamespace'] = attribsNamespace;
58
+ node['x-attribsPrefix'] = attribsPrefix;
59
+ return node;
60
+ },
61
+ createCommentNode(data) {
62
+ return new domhandler_1.Comment(data);
63
+ },
64
+ //Tree mutation
65
+ appendChild(parentNode, newNode) {
66
+ const prev = parentNode.children[parentNode.children.length - 1];
67
+ if (prev) {
68
+ prev.next = newNode;
69
+ newNode.prev = prev;
70
+ }
71
+ parentNode.children.push(newNode);
72
+ newNode.parent = parentNode;
73
+ },
74
+ insertBefore(parentNode, newNode, referenceNode) {
75
+ const insertionIdx = parentNode.children.indexOf(referenceNode);
76
+ const { prev } = referenceNode;
77
+ if (prev) {
78
+ prev.next = newNode;
79
+ newNode.prev = prev;
80
+ }
81
+ referenceNode.prev = newNode;
82
+ newNode.next = referenceNode;
83
+ parentNode.children.splice(insertionIdx, 0, newNode);
84
+ newNode.parent = parentNode;
85
+ },
86
+ setTemplateContent(templateElement, contentElement) {
87
+ exports.adapter.appendChild(templateElement, contentElement);
88
+ },
89
+ getTemplateContent(templateElement) {
90
+ return templateElement.children[0];
91
+ },
92
+ setDocumentType(document, name, publicId, systemId) {
93
+ const data = serializeDoctypeContent(name, publicId, systemId);
94
+ let doctypeNode = document.children.find((node) => (0, domhandler_1.isDirective)(node) && node.name === '!doctype');
95
+ if (doctypeNode) {
96
+ doctypeNode.data = data !== null && data !== void 0 ? data : null;
97
+ }
98
+ else {
99
+ doctypeNode = new domhandler_1.ProcessingInstruction('!doctype', data);
100
+ exports.adapter.appendChild(document, doctypeNode);
101
+ }
102
+ doctypeNode['x-name'] = name !== null && name !== void 0 ? name : undefined;
103
+ doctypeNode['x-publicId'] = publicId !== null && publicId !== void 0 ? publicId : undefined;
104
+ doctypeNode['x-systemId'] = systemId !== null && systemId !== void 0 ? systemId : undefined;
105
+ },
106
+ setDocumentMode(document, mode) {
107
+ document['x-mode'] = mode;
108
+ },
109
+ getDocumentMode(document) {
110
+ return document['x-mode'];
111
+ },
112
+ detachNode(node) {
113
+ if (node.parent) {
114
+ const idx = node.parent.children.indexOf(node);
115
+ const { prev, next } = node;
116
+ node.prev = null;
117
+ node.next = null;
118
+ if (prev) {
119
+ prev.next = next;
120
+ }
121
+ if (next) {
122
+ next.prev = prev;
123
+ }
124
+ node.parent.children.splice(idx, 1);
125
+ node.parent = null;
126
+ }
127
+ },
128
+ insertText(parentNode, text) {
129
+ const lastChild = parentNode.children[parentNode.children.length - 1];
130
+ if (lastChild && (0, domhandler_1.isText)(lastChild)) {
131
+ lastChild.data += text;
132
+ }
133
+ else {
134
+ exports.adapter.appendChild(parentNode, createTextNode(text));
135
+ }
136
+ },
137
+ insertTextBefore(parentNode, text, referenceNode) {
138
+ const prevNode = parentNode.children[parentNode.children.indexOf(referenceNode) - 1];
139
+ if (prevNode && (0, domhandler_1.isText)(prevNode)) {
140
+ prevNode.data += text;
141
+ }
142
+ else {
143
+ exports.adapter.insertBefore(parentNode, createTextNode(text), referenceNode);
144
+ }
145
+ },
146
+ adoptAttributes(recipient, attrs) {
147
+ for (let i = 0; i < attrs.length; i++) {
148
+ const attrName = attrs[i].name;
149
+ if (typeof recipient.attribs[attrName] === 'undefined') {
150
+ recipient.attribs[attrName] = attrs[i].value;
151
+ recipient['x-attribsNamespace'][attrName] = attrs[i].namespace;
152
+ recipient['x-attribsPrefix'][attrName] = attrs[i].prefix;
153
+ }
154
+ }
155
+ },
156
+ //Tree traversing
157
+ getFirstChild(node) {
158
+ return node.children[0];
159
+ },
160
+ getChildNodes(node) {
161
+ return node.children;
162
+ },
163
+ getParentNode(node) {
164
+ return node.parent;
165
+ },
166
+ getAttrList(element) {
167
+ return element.attributes;
168
+ },
169
+ //Node data
170
+ getTagName(element) {
171
+ return element.name;
172
+ },
173
+ getNamespaceURI(element) {
174
+ return element.namespace;
175
+ },
176
+ getTextNodeContent(textNode) {
177
+ return textNode.data;
178
+ },
179
+ getCommentNodeContent(commentNode) {
180
+ return commentNode.data;
181
+ },
182
+ getDocumentTypeNodeName(doctypeNode) {
183
+ var _a;
184
+ return (_a = doctypeNode['x-name']) !== null && _a !== void 0 ? _a : '';
185
+ },
186
+ getDocumentTypeNodePublicId(doctypeNode) {
187
+ var _a;
188
+ return (_a = doctypeNode['x-publicId']) !== null && _a !== void 0 ? _a : '';
189
+ },
190
+ getDocumentTypeNodeSystemId(doctypeNode) {
191
+ var _a;
192
+ return (_a = doctypeNode['x-systemId']) !== null && _a !== void 0 ? _a : '';
193
+ },
194
+ //Node types
195
+ isDocumentTypeNode(node) {
196
+ return (0, domhandler_1.isDirective)(node) && node.name === '!doctype';
197
+ },
198
+ // Source code location
199
+ setNodeSourceCodeLocation(node, location) {
200
+ if (location) {
201
+ node.startIndex = location.startOffset;
202
+ node.endIndex = location.endOffset;
203
+ }
204
+ node.sourceCodeLocation = location;
205
+ },
206
+ getNodeSourceCodeLocation(node) {
207
+ return node.sourceCodeLocation;
208
+ },
209
+ updateNodeSourceCodeLocation(node, endLocation) {
210
+ if (endLocation.endOffset != null)
211
+ node.endIndex = endLocation.endOffset;
212
+ node.sourceCodeLocation = Object.assign(Object.assign({}, node.sourceCodeLocation), endLocation);
213
+ },
214
+ };
215
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,7 @@
1
+ import { type TreeAdapterTypeMap, type TreeAdapter } from 'parse5';
2
+ import { type AnyNode, type ParentNode, type ChildNode, Element, Document, ProcessingInstruction, Comment, Text } from 'domhandler';
3
+ export declare type Htmlparser2TreeAdapterMap = TreeAdapterTypeMap<AnyNode, ParentNode, ChildNode, Document, Document, Element, Comment, Text, Element, ProcessingInstruction>;
4
+ /** @internal */
5
+ export declare function serializeDoctypeContent(name: string, publicId: string, systemId: string): string;
6
+ export declare const adapter: TreeAdapter<Htmlparser2TreeAdapterMap>;
7
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,214 @@
1
+ import { html } from 'parse5';
2
+ import { Element, Document, ProcessingInstruction, Comment, Text, isDirective, isText, isComment, isTag, } from 'domhandler';
3
+ function createTextNode(value) {
4
+ return new Text(value);
5
+ }
6
+ function enquoteDoctypeId(id) {
7
+ const quote = id.includes('"') ? "'" : '"';
8
+ return quote + id + quote;
9
+ }
10
+ /** @internal */
11
+ export function serializeDoctypeContent(name, publicId, systemId) {
12
+ let str = '!DOCTYPE ';
13
+ if (name) {
14
+ str += name;
15
+ }
16
+ if (publicId) {
17
+ str += ` PUBLIC ${enquoteDoctypeId(publicId)}`;
18
+ }
19
+ else if (systemId) {
20
+ str += ' SYSTEM';
21
+ }
22
+ if (systemId) {
23
+ str += ` ${enquoteDoctypeId(systemId)}`;
24
+ }
25
+ return str;
26
+ }
27
+ export const adapter = {
28
+ // Re-exports from domhandler
29
+ isCommentNode: isComment,
30
+ isElementNode: isTag,
31
+ isTextNode: isText,
32
+ //Node construction
33
+ createDocument() {
34
+ const node = new Document([]);
35
+ node['x-mode'] = html.DOCUMENT_MODE.NO_QUIRKS;
36
+ return node;
37
+ },
38
+ createDocumentFragment() {
39
+ return new Document([]);
40
+ },
41
+ createElement(tagName, namespaceURI, attrs) {
42
+ const attribs = Object.create(null);
43
+ const attribsNamespace = Object.create(null);
44
+ const attribsPrefix = Object.create(null);
45
+ for (let i = 0; i < attrs.length; i++) {
46
+ const attrName = attrs[i].name;
47
+ attribs[attrName] = attrs[i].value;
48
+ attribsNamespace[attrName] = attrs[i].namespace;
49
+ attribsPrefix[attrName] = attrs[i].prefix;
50
+ }
51
+ const node = new Element(tagName, attribs, []);
52
+ node.namespace = namespaceURI;
53
+ node['x-attribsNamespace'] = attribsNamespace;
54
+ node['x-attribsPrefix'] = attribsPrefix;
55
+ return node;
56
+ },
57
+ createCommentNode(data) {
58
+ return new Comment(data);
59
+ },
60
+ //Tree mutation
61
+ appendChild(parentNode, newNode) {
62
+ const prev = parentNode.children[parentNode.children.length - 1];
63
+ if (prev) {
64
+ prev.next = newNode;
65
+ newNode.prev = prev;
66
+ }
67
+ parentNode.children.push(newNode);
68
+ newNode.parent = parentNode;
69
+ },
70
+ insertBefore(parentNode, newNode, referenceNode) {
71
+ const insertionIdx = parentNode.children.indexOf(referenceNode);
72
+ const { prev } = referenceNode;
73
+ if (prev) {
74
+ prev.next = newNode;
75
+ newNode.prev = prev;
76
+ }
77
+ referenceNode.prev = newNode;
78
+ newNode.next = referenceNode;
79
+ parentNode.children.splice(insertionIdx, 0, newNode);
80
+ newNode.parent = parentNode;
81
+ },
82
+ setTemplateContent(templateElement, contentElement) {
83
+ adapter.appendChild(templateElement, contentElement);
84
+ },
85
+ getTemplateContent(templateElement) {
86
+ return templateElement.children[0];
87
+ },
88
+ setDocumentType(document, name, publicId, systemId) {
89
+ const data = serializeDoctypeContent(name, publicId, systemId);
90
+ let doctypeNode = document.children.find((node) => isDirective(node) && node.name === '!doctype');
91
+ if (doctypeNode) {
92
+ doctypeNode.data = data !== null && data !== void 0 ? data : null;
93
+ }
94
+ else {
95
+ doctypeNode = new ProcessingInstruction('!doctype', data);
96
+ adapter.appendChild(document, doctypeNode);
97
+ }
98
+ doctypeNode['x-name'] = name !== null && name !== void 0 ? name : undefined;
99
+ doctypeNode['x-publicId'] = publicId !== null && publicId !== void 0 ? publicId : undefined;
100
+ doctypeNode['x-systemId'] = systemId !== null && systemId !== void 0 ? systemId : undefined;
101
+ },
102
+ setDocumentMode(document, mode) {
103
+ document['x-mode'] = mode;
104
+ },
105
+ getDocumentMode(document) {
106
+ return document['x-mode'];
107
+ },
108
+ detachNode(node) {
109
+ if (node.parent) {
110
+ const idx = node.parent.children.indexOf(node);
111
+ const { prev, next } = node;
112
+ node.prev = null;
113
+ node.next = null;
114
+ if (prev) {
115
+ prev.next = next;
116
+ }
117
+ if (next) {
118
+ next.prev = prev;
119
+ }
120
+ node.parent.children.splice(idx, 1);
121
+ node.parent = null;
122
+ }
123
+ },
124
+ insertText(parentNode, text) {
125
+ const lastChild = parentNode.children[parentNode.children.length - 1];
126
+ if (lastChild && isText(lastChild)) {
127
+ lastChild.data += text;
128
+ }
129
+ else {
130
+ adapter.appendChild(parentNode, createTextNode(text));
131
+ }
132
+ },
133
+ insertTextBefore(parentNode, text, referenceNode) {
134
+ const prevNode = parentNode.children[parentNode.children.indexOf(referenceNode) - 1];
135
+ if (prevNode && isText(prevNode)) {
136
+ prevNode.data += text;
137
+ }
138
+ else {
139
+ adapter.insertBefore(parentNode, createTextNode(text), referenceNode);
140
+ }
141
+ },
142
+ adoptAttributes(recipient, attrs) {
143
+ for (let i = 0; i < attrs.length; i++) {
144
+ const attrName = attrs[i].name;
145
+ if (typeof recipient.attribs[attrName] === 'undefined') {
146
+ recipient.attribs[attrName] = attrs[i].value;
147
+ recipient['x-attribsNamespace'][attrName] = attrs[i].namespace;
148
+ recipient['x-attribsPrefix'][attrName] = attrs[i].prefix;
149
+ }
150
+ }
151
+ },
152
+ //Tree traversing
153
+ getFirstChild(node) {
154
+ return node.children[0];
155
+ },
156
+ getChildNodes(node) {
157
+ return node.children;
158
+ },
159
+ getParentNode(node) {
160
+ return node.parent;
161
+ },
162
+ getAttrList(element) {
163
+ return element.attributes;
164
+ },
165
+ //Node data
166
+ getTagName(element) {
167
+ return element.name;
168
+ },
169
+ getNamespaceURI(element) {
170
+ return element.namespace;
171
+ },
172
+ getTextNodeContent(textNode) {
173
+ return textNode.data;
174
+ },
175
+ getCommentNodeContent(commentNode) {
176
+ return commentNode.data;
177
+ },
178
+ getDocumentTypeNodeName(doctypeNode) {
179
+ var _a;
180
+ return (_a = doctypeNode['x-name']) !== null && _a !== void 0 ? _a : '';
181
+ },
182
+ getDocumentTypeNodePublicId(doctypeNode) {
183
+ var _a;
184
+ return (_a = doctypeNode['x-publicId']) !== null && _a !== void 0 ? _a : '';
185
+ },
186
+ getDocumentTypeNodeSystemId(doctypeNode) {
187
+ var _a;
188
+ return (_a = doctypeNode['x-systemId']) !== null && _a !== void 0 ? _a : '';
189
+ },
190
+ //Node types
191
+ isDocumentTypeNode(node) {
192
+ return isDirective(node) && node.name === '!doctype';
193
+ },
194
+ // Source code location
195
+ setNodeSourceCodeLocation(node, location) {
196
+ if (location) {
197
+ node.startIndex = location.startOffset;
198
+ node.endIndex = location.endOffset;
199
+ }
200
+ node.sourceCodeLocation = location;
201
+ },
202
+ getNodeSourceCodeLocation(node) {
203
+ return node.sourceCodeLocation;
204
+ },
205
+ updateNodeSourceCodeLocation(node, endLocation) {
206
+ if (endLocation.endOffset != null)
207
+ node.endIndex = endLocation.endOffset;
208
+ node.sourceCodeLocation = {
209
+ ...node.sourceCodeLocation,
210
+ ...endLocation,
211
+ };
212
+ },
213
+ };
214
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "parse5-htmlparser2-tree-adapter",
3
+ "type": "module",
3
4
  "description": "htmlparser2 tree adapter for parse5.",
4
- "version": "5.1.1",
5
+ "version": "7.0.0",
5
6
  "author": "Ivan Nikulin <ifaaan@gmail.com> (https://github.com/inikulin)",
6
7
  "contributors": "https://github.com/inikulin/parse5/graphs/contributors",
7
8
  "homepage": "https://github.com/inikulin/parse5",
9
+ "funding": "https://github.com/inikulin/parse5?sponsor=1",
8
10
  "keywords": [
9
11
  "parse5",
10
12
  "parser",
@@ -12,16 +14,26 @@
12
14
  "htmlparser2"
13
15
  ],
14
16
  "license": "MIT",
15
- "main": "./lib/index.js",
17
+ "main": "dist/cjs/index.js",
18
+ "module": "dist/index.js",
19
+ "types": "dist/index.d.ts",
20
+ "exports": {
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/cjs/index.js"
23
+ },
16
24
  "dependencies": {
17
- "parse5": "^5.1.1"
25
+ "domhandler": "^5.0.2",
26
+ "parse5": "^7.0.0"
27
+ },
28
+ "scripts": {
29
+ "build:cjs": "tsc --module CommonJS --target ES6 --outDir dist/cjs && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json"
18
30
  },
19
31
  "repository": {
20
32
  "type": "git",
21
33
  "url": "git://github.com/inikulin/parse5.git"
22
34
  },
23
35
  "files": [
24
- "lib"
25
- ],
26
- "gitHead": "9c7556ed05e4ff4d884ab2447e27ce3817c42e79"
36
+ "dist",
37
+ "!*.map"
38
+ ]
27
39
  }
package/lib/index.js DELETED
@@ -1,344 +0,0 @@
1
- 'use strict';
2
-
3
- const doctype = require('parse5/lib/common/doctype');
4
- const { DOCUMENT_MODE } = require('parse5/lib/common/html');
5
-
6
- //Conversion tables for DOM Level1 structure emulation
7
- const nodeTypes = {
8
- element: 1,
9
- text: 3,
10
- cdata: 4,
11
- comment: 8
12
- };
13
-
14
- const nodePropertyShorthands = {
15
- tagName: 'name',
16
- childNodes: 'children',
17
- parentNode: 'parent',
18
- previousSibling: 'prev',
19
- nextSibling: 'next',
20
- nodeValue: 'data'
21
- };
22
-
23
- //Node
24
- class 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
-
48
- Object.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
63
- exports.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
-
75
- exports.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
-
86
- exports.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
-
113
- exports.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
-
123
- const 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
134
- const 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
-
146
- const 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
-
162
- exports.setTemplateContent = function(templateElement, contentElement) {
163
- appendChild(templateElement, contentElement);
164
- };
165
-
166
- exports.getTemplateContent = function(templateElement) {
167
- return templateElement.children[0];
168
- };
169
-
170
- exports.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
-
201
- exports.setDocumentMode = function(document, mode) {
202
- document['x-mode'] = mode;
203
- };
204
-
205
- exports.getDocumentMode = function(document) {
206
- return document['x-mode'];
207
- };
208
-
209
- exports.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
-
231
- exports.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
-
241
- exports.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
-
251
- exports.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
264
- exports.getFirstChild = function(node) {
265
- return node.children[0];
266
- };
267
-
268
- exports.getChildNodes = function(node) {
269
- return node.children;
270
- };
271
-
272
- exports.getParentNode = function(node) {
273
- return node.parent;
274
- };
275
-
276
- exports.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
292
- exports.getTagName = function(element) {
293
- return element.name;
294
- };
295
-
296
- exports.getNamespaceURI = function(element) {
297
- return element.namespace;
298
- };
299
-
300
- exports.getTextNodeContent = function(textNode) {
301
- return textNode.data;
302
- };
303
-
304
- exports.getCommentNodeContent = function(commentNode) {
305
- return commentNode.data;
306
- };
307
-
308
- exports.getDocumentTypeNodeName = function(doctypeNode) {
309
- return doctypeNode['x-name'];
310
- };
311
-
312
- exports.getDocumentTypeNodePublicId = function(doctypeNode) {
313
- return doctypeNode['x-publicId'];
314
- };
315
-
316
- exports.getDocumentTypeNodeSystemId = function(doctypeNode) {
317
- return doctypeNode['x-systemId'];
318
- };
319
-
320
- //Node types
321
- exports.isTextNode = function(node) {
322
- return node.type === 'text';
323
- };
324
-
325
- exports.isCommentNode = function(node) {
326
- return node.type === 'comment';
327
- };
328
-
329
- exports.isDocumentTypeNode = function(node) {
330
- return node.type === 'directive' && node.name === '!doctype';
331
- };
332
-
333
- exports.isElementNode = function(node) {
334
- return !!node.attribs;
335
- };
336
-
337
- // Source code location
338
- exports.setNodeSourceCodeLocation = function(node, location) {
339
- node.sourceCodeLocation = location;
340
- };
341
-
342
- exports.getNodeSourceCodeLocation = function(node) {
343
- return node.sourceCodeLocation;
344
- };