parse5 6.0.0 → 7.1.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.
Files changed (85) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/common/doctype.d.ts +5 -0
  3. package/dist/cjs/common/doctype.js +120 -0
  4. package/dist/cjs/common/error-codes.d.ts +68 -0
  5. package/dist/cjs/common/error-codes.js +67 -0
  6. package/dist/cjs/common/foreign-content.d.ts +10 -0
  7. package/dist/cjs/common/foreign-content.js +239 -0
  8. package/dist/cjs/common/html.d.ts +288 -0
  9. package/dist/cjs/common/html.js +529 -0
  10. package/dist/cjs/common/token.d.ts +85 -0
  11. package/dist/cjs/common/token.js +25 -0
  12. package/dist/cjs/common/unicode.d.ts +49 -0
  13. package/dist/cjs/common/unicode.js +77 -0
  14. package/dist/cjs/index.d.ts +60 -0
  15. package/dist/cjs/index.js +55 -0
  16. package/dist/cjs/parser/formatting-element-list.d.ts +37 -0
  17. package/dist/cjs/parser/formatting-element-list.js +115 -0
  18. package/dist/cjs/parser/index.d.ts +157 -0
  19. package/dist/cjs/parser/index.js +3053 -0
  20. package/dist/cjs/parser/open-element-stack.d.ts +53 -0
  21. package/dist/cjs/parser/open-element-stack.js +316 -0
  22. package/dist/cjs/serializer/index.d.ts +61 -0
  23. package/dist/cjs/serializer/index.js +173 -0
  24. package/dist/cjs/tokenizer/index.d.ts +248 -0
  25. package/dist/cjs/tokenizer/index.js +2907 -0
  26. package/dist/cjs/tokenizer/preprocessor.d.ts +37 -0
  27. package/dist/cjs/tokenizer/preprocessor.js +198 -0
  28. package/dist/cjs/tree-adapters/default.d.ts +85 -0
  29. package/dist/cjs/tree-adapters/default.js +177 -0
  30. package/dist/cjs/tree-adapters/interface.d.ts +250 -0
  31. package/dist/cjs/tree-adapters/interface.js +3 -0
  32. package/dist/common/doctype.d.ts +5 -0
  33. package/{lib → dist}/common/doctype.js +25 -72
  34. package/dist/common/error-codes.d.ts +68 -0
  35. package/dist/common/error-codes.js +64 -0
  36. package/dist/common/foreign-content.d.ts +10 -0
  37. package/dist/common/foreign-content.js +230 -0
  38. package/dist/common/html.d.ts +288 -0
  39. package/dist/common/html.js +523 -0
  40. package/dist/common/token.d.ts +85 -0
  41. package/dist/common/token.js +21 -0
  42. package/dist/common/unicode.d.ts +49 -0
  43. package/dist/common/unicode.js +69 -0
  44. package/dist/index.d.ts +60 -0
  45. package/dist/index.js +44 -0
  46. package/dist/parser/formatting-element-list.d.ts +37 -0
  47. package/dist/parser/formatting-element-list.js +111 -0
  48. package/dist/parser/index.d.ts +157 -0
  49. package/dist/parser/index.js +3058 -0
  50. package/dist/parser/open-element-stack.d.ts +53 -0
  51. package/dist/parser/open-element-stack.js +312 -0
  52. package/dist/serializer/index.d.ts +61 -0
  53. package/dist/serializer/index.js +168 -0
  54. package/dist/tokenizer/index.d.ts +248 -0
  55. package/dist/tokenizer/index.js +2903 -0
  56. package/dist/tokenizer/preprocessor.d.ts +37 -0
  57. package/dist/tokenizer/preprocessor.js +194 -0
  58. package/dist/tree-adapters/default.d.ts +85 -0
  59. package/dist/tree-adapters/default.js +174 -0
  60. package/dist/tree-adapters/interface.d.ts +250 -0
  61. package/dist/tree-adapters/interface.js +2 -0
  62. package/package.json +19 -5
  63. package/lib/common/error-codes.js +0 -65
  64. package/lib/common/foreign-content.js +0 -265
  65. package/lib/common/html.js +0 -272
  66. package/lib/common/unicode.js +0 -109
  67. package/lib/extensions/error-reporting/mixin-base.js +0 -43
  68. package/lib/extensions/error-reporting/parser-mixin.js +0 -52
  69. package/lib/extensions/error-reporting/preprocessor-mixin.js +0 -24
  70. package/lib/extensions/error-reporting/tokenizer-mixin.js +0 -17
  71. package/lib/extensions/location-info/open-element-stack-mixin.js +0 -35
  72. package/lib/extensions/location-info/parser-mixin.js +0 -223
  73. package/lib/extensions/location-info/tokenizer-mixin.js +0 -146
  74. package/lib/extensions/position-tracking/preprocessor-mixin.js +0 -64
  75. package/lib/index.js +0 -29
  76. package/lib/parser/formatting-element-list.js +0 -181
  77. package/lib/parser/index.js +0 -2956
  78. package/lib/parser/open-element-stack.js +0 -482
  79. package/lib/serializer/index.js +0 -176
  80. package/lib/tokenizer/index.js +0 -2196
  81. package/lib/tokenizer/named-entity-data.js +0 -5
  82. package/lib/tokenizer/preprocessor.js +0 -159
  83. package/lib/tree-adapters/default.js +0 -221
  84. package/lib/utils/merge-options.js +0 -13
  85. package/lib/utils/mixin.js +0 -39
@@ -0,0 +1,53 @@
1
+ import { TAG_ID as $ } from '../common/html.js';
2
+ import type { TreeAdapter, TreeAdapterTypeMap } from '../tree-adapters/interface.js';
3
+ export interface StackHandler<T extends TreeAdapterTypeMap> {
4
+ onItemPush: (node: T['parentNode'], tid: number, isTop: boolean) => void;
5
+ onItemPop: (node: T['parentNode'], isTop: boolean) => void;
6
+ }
7
+ export declare class OpenElementStack<T extends TreeAdapterTypeMap> {
8
+ private treeAdapter;
9
+ private handler;
10
+ items: T['parentNode'][];
11
+ tagIDs: $[];
12
+ current: T['parentNode'];
13
+ stackTop: number;
14
+ tmplCount: number;
15
+ currentTagId: $;
16
+ get currentTmplContentOrNode(): T['parentNode'];
17
+ constructor(document: T['document'], treeAdapter: TreeAdapter<T>, handler: StackHandler<T>);
18
+ private _indexOf;
19
+ private _isInTemplate;
20
+ private _updateCurrentElement;
21
+ push(element: T['element'], tagID: $): void;
22
+ pop(): void;
23
+ replace(oldElement: T['element'], newElement: T['element']): void;
24
+ insertAfter(referenceElement: T['element'], newElement: T['element'], newElementID: $): void;
25
+ popUntilTagNamePopped(tagName: $): void;
26
+ shortenToLength(idx: number): void;
27
+ popUntilElementPopped(element: T['element']): void;
28
+ private popUntilPopped;
29
+ popUntilNumberedHeaderPopped(): void;
30
+ popUntilTableCellPopped(): void;
31
+ popAllUpToHtmlElement(): void;
32
+ private _indexOfTagNames;
33
+ private clearBackTo;
34
+ clearBackToTableContext(): void;
35
+ clearBackToTableBodyContext(): void;
36
+ clearBackToTableRowContext(): void;
37
+ remove(element: T['element']): void;
38
+ tryPeekProperlyNestedBodyElement(): T['element'] | null;
39
+ contains(element: T['element']): boolean;
40
+ getCommonAncestor(element: T['element']): T['element'] | null;
41
+ isRootHtmlElementCurrent(): boolean;
42
+ hasInScope(tagName: $): boolean;
43
+ hasNumberedHeaderInScope(): boolean;
44
+ hasInListItemScope(tagName: $): boolean;
45
+ hasInButtonScope(tagName: $): boolean;
46
+ hasInTableScope(tagName: $): boolean;
47
+ hasTableBodyContextInTableScope(): boolean;
48
+ hasInSelectScope(tagName: $): boolean;
49
+ generateImpliedEndTags(): void;
50
+ generateImpliedEndTagsThoroughly(): void;
51
+ generateImpliedEndTagsWithExclusion(exclusionId: $): void;
52
+ }
53
+ //# sourceMappingURL=open-element-stack.d.ts.map
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenElementStack = void 0;
4
+ const html_js_1 = require("../common/html.js");
5
+ //Element utils
6
+ const IMPLICIT_END_TAG_REQUIRED = new Set([html_js_1.TAG_ID.DD, html_js_1.TAG_ID.DT, html_js_1.TAG_ID.LI, html_js_1.TAG_ID.OPTGROUP, html_js_1.TAG_ID.OPTION, html_js_1.TAG_ID.P, html_js_1.TAG_ID.RB, html_js_1.TAG_ID.RP, html_js_1.TAG_ID.RT, html_js_1.TAG_ID.RTC]);
7
+ const IMPLICIT_END_TAG_REQUIRED_THOROUGHLY = new Set([
8
+ ...IMPLICIT_END_TAG_REQUIRED,
9
+ html_js_1.TAG_ID.CAPTION,
10
+ html_js_1.TAG_ID.COLGROUP,
11
+ html_js_1.TAG_ID.TBODY,
12
+ html_js_1.TAG_ID.TD,
13
+ html_js_1.TAG_ID.TFOOT,
14
+ html_js_1.TAG_ID.TH,
15
+ html_js_1.TAG_ID.THEAD,
16
+ html_js_1.TAG_ID.TR,
17
+ ]);
18
+ const SCOPING_ELEMENT_NS = new Map([
19
+ [html_js_1.TAG_ID.APPLET, html_js_1.NS.HTML],
20
+ [html_js_1.TAG_ID.CAPTION, html_js_1.NS.HTML],
21
+ [html_js_1.TAG_ID.HTML, html_js_1.NS.HTML],
22
+ [html_js_1.TAG_ID.MARQUEE, html_js_1.NS.HTML],
23
+ [html_js_1.TAG_ID.OBJECT, html_js_1.NS.HTML],
24
+ [html_js_1.TAG_ID.TABLE, html_js_1.NS.HTML],
25
+ [html_js_1.TAG_ID.TD, html_js_1.NS.HTML],
26
+ [html_js_1.TAG_ID.TEMPLATE, html_js_1.NS.HTML],
27
+ [html_js_1.TAG_ID.TH, html_js_1.NS.HTML],
28
+ [html_js_1.TAG_ID.ANNOTATION_XML, html_js_1.NS.MATHML],
29
+ [html_js_1.TAG_ID.MI, html_js_1.NS.MATHML],
30
+ [html_js_1.TAG_ID.MN, html_js_1.NS.MATHML],
31
+ [html_js_1.TAG_ID.MO, html_js_1.NS.MATHML],
32
+ [html_js_1.TAG_ID.MS, html_js_1.NS.MATHML],
33
+ [html_js_1.TAG_ID.MTEXT, html_js_1.NS.MATHML],
34
+ [html_js_1.TAG_ID.DESC, html_js_1.NS.SVG],
35
+ [html_js_1.TAG_ID.FOREIGN_OBJECT, html_js_1.NS.SVG],
36
+ [html_js_1.TAG_ID.TITLE, html_js_1.NS.SVG],
37
+ ]);
38
+ const NAMED_HEADERS = [html_js_1.TAG_ID.H1, html_js_1.TAG_ID.H2, html_js_1.TAG_ID.H3, html_js_1.TAG_ID.H4, html_js_1.TAG_ID.H5, html_js_1.TAG_ID.H6];
39
+ const TABLE_ROW_CONTEXT = [html_js_1.TAG_ID.TR, html_js_1.TAG_ID.TEMPLATE, html_js_1.TAG_ID.HTML];
40
+ const TABLE_BODY_CONTEXT = [html_js_1.TAG_ID.TBODY, html_js_1.TAG_ID.TFOOT, html_js_1.TAG_ID.THEAD, html_js_1.TAG_ID.TEMPLATE, html_js_1.TAG_ID.HTML];
41
+ const TABLE_CONTEXT = [html_js_1.TAG_ID.TABLE, html_js_1.TAG_ID.TEMPLATE, html_js_1.TAG_ID.HTML];
42
+ const TABLE_CELLS = [html_js_1.TAG_ID.TD, html_js_1.TAG_ID.TH];
43
+ //Stack of open elements
44
+ class OpenElementStack {
45
+ constructor(document, treeAdapter, handler) {
46
+ this.treeAdapter = treeAdapter;
47
+ this.handler = handler;
48
+ this.items = [];
49
+ this.tagIDs = [];
50
+ this.stackTop = -1;
51
+ this.tmplCount = 0;
52
+ this.currentTagId = html_js_1.TAG_ID.UNKNOWN;
53
+ this.current = document;
54
+ }
55
+ get currentTmplContentOrNode() {
56
+ return this._isInTemplate() ? this.treeAdapter.getTemplateContent(this.current) : this.current;
57
+ }
58
+ //Index of element
59
+ _indexOf(element) {
60
+ return this.items.lastIndexOf(element, this.stackTop);
61
+ }
62
+ //Update current element
63
+ _isInTemplate() {
64
+ return this.currentTagId === html_js_1.TAG_ID.TEMPLATE && this.treeAdapter.getNamespaceURI(this.current) === html_js_1.NS.HTML;
65
+ }
66
+ _updateCurrentElement() {
67
+ this.current = this.items[this.stackTop];
68
+ this.currentTagId = this.tagIDs[this.stackTop];
69
+ }
70
+ //Mutations
71
+ push(element, tagID) {
72
+ this.stackTop++;
73
+ this.items[this.stackTop] = element;
74
+ this.current = element;
75
+ this.tagIDs[this.stackTop] = tagID;
76
+ this.currentTagId = tagID;
77
+ if (this._isInTemplate()) {
78
+ this.tmplCount++;
79
+ }
80
+ this.handler.onItemPush(element, tagID, true);
81
+ }
82
+ pop() {
83
+ const popped = this.current;
84
+ if (this.tmplCount > 0 && this._isInTemplate()) {
85
+ this.tmplCount--;
86
+ }
87
+ this.stackTop--;
88
+ this._updateCurrentElement();
89
+ this.handler.onItemPop(popped, true);
90
+ }
91
+ replace(oldElement, newElement) {
92
+ const idx = this._indexOf(oldElement);
93
+ this.items[idx] = newElement;
94
+ if (idx === this.stackTop) {
95
+ this.current = newElement;
96
+ }
97
+ }
98
+ insertAfter(referenceElement, newElement, newElementID) {
99
+ const insertionIdx = this._indexOf(referenceElement) + 1;
100
+ this.items.splice(insertionIdx, 0, newElement);
101
+ this.tagIDs.splice(insertionIdx, 0, newElementID);
102
+ this.stackTop++;
103
+ if (insertionIdx === this.stackTop) {
104
+ this._updateCurrentElement();
105
+ }
106
+ this.handler.onItemPush(this.current, this.currentTagId, insertionIdx === this.stackTop);
107
+ }
108
+ popUntilTagNamePopped(tagName) {
109
+ let targetIdx = this.stackTop + 1;
110
+ do {
111
+ targetIdx = this.tagIDs.lastIndexOf(tagName, targetIdx - 1);
112
+ } while (targetIdx > 0 && this.treeAdapter.getNamespaceURI(this.items[targetIdx]) !== html_js_1.NS.HTML);
113
+ this.shortenToLength(targetIdx < 0 ? 0 : targetIdx);
114
+ }
115
+ shortenToLength(idx) {
116
+ while (this.stackTop >= idx) {
117
+ const popped = this.current;
118
+ if (this.tmplCount > 0 && this._isInTemplate()) {
119
+ this.tmplCount -= 1;
120
+ }
121
+ this.stackTop--;
122
+ this._updateCurrentElement();
123
+ this.handler.onItemPop(popped, this.stackTop < idx);
124
+ }
125
+ }
126
+ popUntilElementPopped(element) {
127
+ const idx = this._indexOf(element);
128
+ this.shortenToLength(idx < 0 ? 0 : idx);
129
+ }
130
+ popUntilPopped(tagNames, targetNS) {
131
+ const idx = this._indexOfTagNames(tagNames, targetNS);
132
+ this.shortenToLength(idx < 0 ? 0 : idx);
133
+ }
134
+ popUntilNumberedHeaderPopped() {
135
+ this.popUntilPopped(NAMED_HEADERS, html_js_1.NS.HTML);
136
+ }
137
+ popUntilTableCellPopped() {
138
+ this.popUntilPopped(TABLE_CELLS, html_js_1.NS.HTML);
139
+ }
140
+ popAllUpToHtmlElement() {
141
+ //NOTE: here we assume that the root <html> element is always first in the open element stack, so
142
+ //we perform this fast stack clean up.
143
+ this.tmplCount = 0;
144
+ this.shortenToLength(1);
145
+ }
146
+ _indexOfTagNames(tagNames, namespace) {
147
+ for (let i = this.stackTop; i >= 0; i--) {
148
+ if (tagNames.includes(this.tagIDs[i]) && this.treeAdapter.getNamespaceURI(this.items[i]) === namespace) {
149
+ return i;
150
+ }
151
+ }
152
+ return -1;
153
+ }
154
+ clearBackTo(tagNames, targetNS) {
155
+ const idx = this._indexOfTagNames(tagNames, targetNS);
156
+ this.shortenToLength(idx + 1);
157
+ }
158
+ clearBackToTableContext() {
159
+ this.clearBackTo(TABLE_CONTEXT, html_js_1.NS.HTML);
160
+ }
161
+ clearBackToTableBodyContext() {
162
+ this.clearBackTo(TABLE_BODY_CONTEXT, html_js_1.NS.HTML);
163
+ }
164
+ clearBackToTableRowContext() {
165
+ this.clearBackTo(TABLE_ROW_CONTEXT, html_js_1.NS.HTML);
166
+ }
167
+ remove(element) {
168
+ const idx = this._indexOf(element);
169
+ if (idx >= 0) {
170
+ if (idx === this.stackTop) {
171
+ this.pop();
172
+ }
173
+ else {
174
+ this.items.splice(idx, 1);
175
+ this.tagIDs.splice(idx, 1);
176
+ this.stackTop--;
177
+ this._updateCurrentElement();
178
+ this.handler.onItemPop(element, false);
179
+ }
180
+ }
181
+ }
182
+ //Search
183
+ tryPeekProperlyNestedBodyElement() {
184
+ //Properly nested <body> element (should be second element in stack).
185
+ return this.stackTop >= 1 && this.tagIDs[1] === html_js_1.TAG_ID.BODY ? this.items[1] : null;
186
+ }
187
+ contains(element) {
188
+ return this._indexOf(element) > -1;
189
+ }
190
+ getCommonAncestor(element) {
191
+ const elementIdx = this._indexOf(element) - 1;
192
+ return elementIdx >= 0 ? this.items[elementIdx] : null;
193
+ }
194
+ isRootHtmlElementCurrent() {
195
+ return this.stackTop === 0 && this.tagIDs[0] === html_js_1.TAG_ID.HTML;
196
+ }
197
+ //Element in scope
198
+ hasInScope(tagName) {
199
+ for (let i = this.stackTop; i >= 0; i--) {
200
+ const tn = this.tagIDs[i];
201
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
202
+ if (tn === tagName && ns === html_js_1.NS.HTML) {
203
+ return true;
204
+ }
205
+ if (SCOPING_ELEMENT_NS.get(tn) === ns) {
206
+ return false;
207
+ }
208
+ }
209
+ return true;
210
+ }
211
+ hasNumberedHeaderInScope() {
212
+ for (let i = this.stackTop; i >= 0; i--) {
213
+ const tn = this.tagIDs[i];
214
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
215
+ if ((0, html_js_1.isNumberedHeader)(tn) && ns === html_js_1.NS.HTML) {
216
+ return true;
217
+ }
218
+ if (SCOPING_ELEMENT_NS.get(tn) === ns) {
219
+ return false;
220
+ }
221
+ }
222
+ return true;
223
+ }
224
+ hasInListItemScope(tagName) {
225
+ for (let i = this.stackTop; i >= 0; i--) {
226
+ const tn = this.tagIDs[i];
227
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
228
+ if (tn === tagName && ns === html_js_1.NS.HTML) {
229
+ return true;
230
+ }
231
+ if (((tn === html_js_1.TAG_ID.UL || tn === html_js_1.TAG_ID.OL) && ns === html_js_1.NS.HTML) || SCOPING_ELEMENT_NS.get(tn) === ns) {
232
+ return false;
233
+ }
234
+ }
235
+ return true;
236
+ }
237
+ hasInButtonScope(tagName) {
238
+ for (let i = this.stackTop; i >= 0; i--) {
239
+ const tn = this.tagIDs[i];
240
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
241
+ if (tn === tagName && ns === html_js_1.NS.HTML) {
242
+ return true;
243
+ }
244
+ if ((tn === html_js_1.TAG_ID.BUTTON && ns === html_js_1.NS.HTML) || SCOPING_ELEMENT_NS.get(tn) === ns) {
245
+ return false;
246
+ }
247
+ }
248
+ return true;
249
+ }
250
+ hasInTableScope(tagName) {
251
+ for (let i = this.stackTop; i >= 0; i--) {
252
+ const tn = this.tagIDs[i];
253
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
254
+ if (ns !== html_js_1.NS.HTML) {
255
+ continue;
256
+ }
257
+ if (tn === tagName) {
258
+ return true;
259
+ }
260
+ if (tn === html_js_1.TAG_ID.TABLE || tn === html_js_1.TAG_ID.TEMPLATE || tn === html_js_1.TAG_ID.HTML) {
261
+ return false;
262
+ }
263
+ }
264
+ return true;
265
+ }
266
+ hasTableBodyContextInTableScope() {
267
+ for (let i = this.stackTop; i >= 0; i--) {
268
+ const tn = this.tagIDs[i];
269
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
270
+ if (ns !== html_js_1.NS.HTML) {
271
+ continue;
272
+ }
273
+ if (tn === html_js_1.TAG_ID.TBODY || tn === html_js_1.TAG_ID.THEAD || tn === html_js_1.TAG_ID.TFOOT) {
274
+ return true;
275
+ }
276
+ if (tn === html_js_1.TAG_ID.TABLE || tn === html_js_1.TAG_ID.HTML) {
277
+ return false;
278
+ }
279
+ }
280
+ return true;
281
+ }
282
+ hasInSelectScope(tagName) {
283
+ for (let i = this.stackTop; i >= 0; i--) {
284
+ const tn = this.tagIDs[i];
285
+ const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
286
+ if (ns !== html_js_1.NS.HTML) {
287
+ continue;
288
+ }
289
+ if (tn === tagName) {
290
+ return true;
291
+ }
292
+ if (tn !== html_js_1.TAG_ID.OPTION && tn !== html_js_1.TAG_ID.OPTGROUP) {
293
+ return false;
294
+ }
295
+ }
296
+ return true;
297
+ }
298
+ //Implied end tags
299
+ generateImpliedEndTags() {
300
+ while (IMPLICIT_END_TAG_REQUIRED.has(this.currentTagId)) {
301
+ this.pop();
302
+ }
303
+ }
304
+ generateImpliedEndTagsThoroughly() {
305
+ while (IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
306
+ this.pop();
307
+ }
308
+ }
309
+ generateImpliedEndTagsWithExclusion(exclusionId) {
310
+ while (this.currentTagId !== exclusionId && IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
311
+ this.pop();
312
+ }
313
+ }
314
+ }
315
+ exports.OpenElementStack = OpenElementStack;
316
+ //# sourceMappingURL=open-element-stack.js.map
@@ -0,0 +1,61 @@
1
+ import type { TreeAdapter, TreeAdapterTypeMap } from '../tree-adapters/interface.js';
2
+ import { type DefaultTreeAdapterMap } from '../tree-adapters/default.js';
3
+ export interface SerializerOptions<T extends TreeAdapterTypeMap> {
4
+ /**
5
+ * Specifies input tree format.
6
+ *
7
+ * @default `treeAdapters.default`
8
+ */
9
+ treeAdapter?: TreeAdapter<T>;
10
+ /**
11
+ * The [scripting flag](https://html.spec.whatwg.org/multipage/parsing.html#scripting-flag). If set
12
+ * to `true`, `noscript` element content will not be escaped.
13
+ *
14
+ * @default `true`
15
+ */
16
+ scriptingEnabled?: boolean;
17
+ }
18
+ /**
19
+ * Serializes an AST node to an HTML string.
20
+ *
21
+ * @example
22
+ *
23
+ * ```js
24
+ * const parse5 = require('parse5');
25
+ *
26
+ * const document = parse5.parse('<!DOCTYPE html><html><head></head><body>Hi there!</body></html>');
27
+ *
28
+ * // Serializes a document.
29
+ * const html = parse5.serialize(document);
30
+ *
31
+ * // Serializes the <html> element content.
32
+ * const str = parse5.serialize(document.childNodes[1]);
33
+ *
34
+ * console.log(str); //> '<head></head><body>Hi there!</body>'
35
+ * ```
36
+ *
37
+ * @param node Node to serialize.
38
+ * @param options Serialization options.
39
+ */
40
+ export declare function serialize<T extends TreeAdapterTypeMap = DefaultTreeAdapterMap>(node: T['parentNode'], options?: SerializerOptions<T>): string;
41
+ /**
42
+ * Serializes an AST element node to an HTML string, including the element node.
43
+ *
44
+ * @example
45
+ *
46
+ * ```js
47
+ * const parse5 = require('parse5');
48
+ *
49
+ * const document = parse5.parseFragment('<div>Hello, <b>world</b>!</div>');
50
+ *
51
+ * // Serializes the <div> element.
52
+ * const html = parse5.serializeOuter(document.childNodes[0]);
53
+ *
54
+ * console.log(str); //> '<div>Hello, <b>world</b>!</div>'
55
+ * ```
56
+ *
57
+ * @param node Node to serialize.
58
+ * @param options Serialization options.
59
+ */
60
+ export declare function serializeOuter<T extends TreeAdapterTypeMap = DefaultTreeAdapterMap>(node: T['node'], options?: SerializerOptions<T>): string;
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serializeOuter = exports.serialize = void 0;
4
+ const html_js_1 = require("../common/html.js");
5
+ const escape_js_1 = require("entities/lib/escape.js");
6
+ const default_js_1 = require("../tree-adapters/default.js");
7
+ // Sets
8
+ const VOID_ELEMENTS = new Set([
9
+ html_js_1.TAG_NAMES.AREA,
10
+ html_js_1.TAG_NAMES.BASE,
11
+ html_js_1.TAG_NAMES.BASEFONT,
12
+ html_js_1.TAG_NAMES.BGSOUND,
13
+ html_js_1.TAG_NAMES.BR,
14
+ html_js_1.TAG_NAMES.COL,
15
+ html_js_1.TAG_NAMES.EMBED,
16
+ html_js_1.TAG_NAMES.FRAME,
17
+ html_js_1.TAG_NAMES.HR,
18
+ html_js_1.TAG_NAMES.IMG,
19
+ html_js_1.TAG_NAMES.INPUT,
20
+ html_js_1.TAG_NAMES.KEYGEN,
21
+ html_js_1.TAG_NAMES.LINK,
22
+ html_js_1.TAG_NAMES.META,
23
+ html_js_1.TAG_NAMES.PARAM,
24
+ html_js_1.TAG_NAMES.SOURCE,
25
+ html_js_1.TAG_NAMES.TRACK,
26
+ html_js_1.TAG_NAMES.WBR,
27
+ ]);
28
+ function isVoidElement(node, options) {
29
+ return (options.treeAdapter.isElementNode(node) &&
30
+ options.treeAdapter.getNamespaceURI(node) === html_js_1.NS.HTML &&
31
+ VOID_ELEMENTS.has(options.treeAdapter.getTagName(node)));
32
+ }
33
+ const defaultOpts = { treeAdapter: default_js_1.defaultTreeAdapter, scriptingEnabled: true };
34
+ /**
35
+ * Serializes an AST node to an HTML string.
36
+ *
37
+ * @example
38
+ *
39
+ * ```js
40
+ * const parse5 = require('parse5');
41
+ *
42
+ * const document = parse5.parse('<!DOCTYPE html><html><head></head><body>Hi there!</body></html>');
43
+ *
44
+ * // Serializes a document.
45
+ * const html = parse5.serialize(document);
46
+ *
47
+ * // Serializes the <html> element content.
48
+ * const str = parse5.serialize(document.childNodes[1]);
49
+ *
50
+ * console.log(str); //> '<head></head><body>Hi there!</body>'
51
+ * ```
52
+ *
53
+ * @param node Node to serialize.
54
+ * @param options Serialization options.
55
+ */
56
+ function serialize(node, options) {
57
+ const opts = Object.assign(Object.assign({}, defaultOpts), options);
58
+ if (isVoidElement(node, opts)) {
59
+ return '';
60
+ }
61
+ return serializeChildNodes(node, opts);
62
+ }
63
+ exports.serialize = serialize;
64
+ /**
65
+ * Serializes an AST element node to an HTML string, including the element node.
66
+ *
67
+ * @example
68
+ *
69
+ * ```js
70
+ * const parse5 = require('parse5');
71
+ *
72
+ * const document = parse5.parseFragment('<div>Hello, <b>world</b>!</div>');
73
+ *
74
+ * // Serializes the <div> element.
75
+ * const html = parse5.serializeOuter(document.childNodes[0]);
76
+ *
77
+ * console.log(str); //> '<div>Hello, <b>world</b>!</div>'
78
+ * ```
79
+ *
80
+ * @param node Node to serialize.
81
+ * @param options Serialization options.
82
+ */
83
+ function serializeOuter(node, options) {
84
+ const opts = Object.assign(Object.assign({}, defaultOpts), options);
85
+ return serializeNode(node, opts);
86
+ }
87
+ exports.serializeOuter = serializeOuter;
88
+ function serializeChildNodes(parentNode, options) {
89
+ let html = '';
90
+ // Get container of the child nodes
91
+ const container = options.treeAdapter.isElementNode(parentNode) &&
92
+ options.treeAdapter.getTagName(parentNode) === html_js_1.TAG_NAMES.TEMPLATE &&
93
+ options.treeAdapter.getNamespaceURI(parentNode) === html_js_1.NS.HTML
94
+ ? options.treeAdapter.getTemplateContent(parentNode)
95
+ : parentNode;
96
+ const childNodes = options.treeAdapter.getChildNodes(container);
97
+ if (childNodes) {
98
+ for (const currentNode of childNodes) {
99
+ html += serializeNode(currentNode, options);
100
+ }
101
+ }
102
+ return html;
103
+ }
104
+ function serializeNode(node, options) {
105
+ if (options.treeAdapter.isElementNode(node)) {
106
+ return serializeElement(node, options);
107
+ }
108
+ if (options.treeAdapter.isTextNode(node)) {
109
+ return serializeTextNode(node, options);
110
+ }
111
+ if (options.treeAdapter.isCommentNode(node)) {
112
+ return serializeCommentNode(node, options);
113
+ }
114
+ if (options.treeAdapter.isDocumentTypeNode(node)) {
115
+ return serializeDocumentTypeNode(node, options);
116
+ }
117
+ // Return an empty string for unknown nodes
118
+ return '';
119
+ }
120
+ function serializeElement(node, options) {
121
+ const tn = options.treeAdapter.getTagName(node);
122
+ return `<${tn}${serializeAttributes(node, options)}>${isVoidElement(node, options) ? '' : `${serializeChildNodes(node, options)}</${tn}>`}`;
123
+ }
124
+ function serializeAttributes(node, { treeAdapter }) {
125
+ let html = '';
126
+ for (const attr of treeAdapter.getAttrList(node)) {
127
+ html += ' ';
128
+ if (!attr.namespace) {
129
+ html += attr.name;
130
+ }
131
+ else
132
+ switch (attr.namespace) {
133
+ case html_js_1.NS.XML: {
134
+ html += `xml:${attr.name}`;
135
+ break;
136
+ }
137
+ case html_js_1.NS.XMLNS: {
138
+ if (attr.name !== 'xmlns') {
139
+ html += 'xmlns:';
140
+ }
141
+ html += attr.name;
142
+ break;
143
+ }
144
+ case html_js_1.NS.XLINK: {
145
+ html += `xlink:${attr.name}`;
146
+ break;
147
+ }
148
+ default: {
149
+ html += `${attr.prefix}:${attr.name}`;
150
+ }
151
+ }
152
+ html += `="${(0, escape_js_1.escapeAttribute)(attr.value)}"`;
153
+ }
154
+ return html;
155
+ }
156
+ function serializeTextNode(node, options) {
157
+ const { treeAdapter } = options;
158
+ const content = treeAdapter.getTextNodeContent(node);
159
+ const parent = treeAdapter.getParentNode(node);
160
+ const parentTn = parent && treeAdapter.isElementNode(parent) && treeAdapter.getTagName(parent);
161
+ return parentTn &&
162
+ treeAdapter.getNamespaceURI(parent) === html_js_1.NS.HTML &&
163
+ (0, html_js_1.hasUnescapedText)(parentTn, options.scriptingEnabled)
164
+ ? content
165
+ : (0, escape_js_1.escapeText)(content);
166
+ }
167
+ function serializeCommentNode(node, { treeAdapter }) {
168
+ return `<!--${treeAdapter.getCommentNodeContent(node)}-->`;
169
+ }
170
+ function serializeDocumentTypeNode(node, { treeAdapter }) {
171
+ return `<!DOCTYPE ${treeAdapter.getDocumentTypeNodeName(node)}>`;
172
+ }
173
+ //# sourceMappingURL=index.js.map