bbcode-compiler 0.1.9 → 0.1.10
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/dist/generator/Generator.d.ts +0 -1
- package/dist/generator/Generator.d.ts.map +1 -1
- package/dist/generator/transforms/Transform.d.ts +0 -1
- package/dist/generator/transforms/htmlTransforms.d.ts +0 -1
- package/dist/generator/utils/getTagImmediateAttrVal.d.ts +0 -1
- package/dist/generator/utils/getTagImmediateText.d.ts +0 -1
- package/dist/generator/utils/getTagImmediateText.d.ts.map +1 -1
- package/dist/generator/utils/getWidthHeightAttr.d.ts +0 -1
- package/dist/generator/utils/isOrderedList.d.ts +0 -1
- package/dist/index.js +104 -165
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +107 -168
- package/dist/index.umd.cjs.map +1 -1
- package/dist/lexer/Lexer.d.ts +0 -1
- package/dist/lexer/Token.d.ts +0 -1
- package/dist/lexer/Token.d.ts.map +1 -1
- package/dist/lexer/TokenType.d.ts +1 -13
- package/dist/lexer/TokenType.d.ts.map +1 -1
- package/dist/parser/AstNode.d.ts +10 -18
- package/dist/parser/AstNode.d.ts.map +1 -1
- package/dist/parser/Parser.d.ts +0 -1
- package/dist/parser/Parser.d.ts.map +1 -1
- package/dist/parser/nodeIsType.d.ts +8 -9
- package/dist/parser/nodeIsType.d.ts.map +1 -1
- package/package.json +83 -82
- package/src/generator/Generator.ts +4 -4
- package/src/generator/utils/getTagImmediateText.ts +3 -3
- package/src/lexer/Lexer.ts +8 -8
- package/src/lexer/Token.ts +12 -12
- package/src/lexer/TokenType.ts +39 -40
- package/src/parser/AstNode.ts +29 -28
- package/src/parser/Parser.ts +26 -26
- package/src/parser/nodeIsType.ts +8 -8
package/dist/index.js
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
1
|
function nodeIsType(node, nodeType) {
|
|
5
2
|
return node.nodeType === nodeType;
|
|
6
3
|
}
|
|
7
|
-
var AstNodeType = /* @__PURE__ */ ((AstNodeType2) => {
|
|
8
|
-
AstNodeType2["RootNode"] = "RootNode";
|
|
9
|
-
AstNodeType2["TextNode"] = "TextNode";
|
|
10
|
-
AstNodeType2["LinebreakNode"] = "LinebreakNode";
|
|
11
|
-
AstNodeType2["TagNode"] = "TagNode";
|
|
12
|
-
AstNodeType2["StartTagNode"] = "StartTagNode";
|
|
13
|
-
AstNodeType2["EndTagNode"] = "EndTagNode";
|
|
14
|
-
AstNodeType2["AttrNode"] = "AttrNode";
|
|
15
|
-
return AstNodeType2;
|
|
16
|
-
})(AstNodeType || {});
|
|
17
4
|
class AstNode {
|
|
18
|
-
|
|
5
|
+
children;
|
|
6
|
+
constructor(children = new Array()) {
|
|
19
7
|
this.children = children;
|
|
20
8
|
}
|
|
21
9
|
addChild(node) {
|
|
@@ -52,10 +40,7 @@ class AstNode {
|
|
|
52
40
|
}
|
|
53
41
|
}
|
|
54
42
|
class RootNode extends AstNode {
|
|
55
|
-
|
|
56
|
-
super(...arguments);
|
|
57
|
-
__publicField(this, "nodeType", "RootNode");
|
|
58
|
-
}
|
|
43
|
+
nodeType = "RootNode";
|
|
59
44
|
isValid() {
|
|
60
45
|
for (const child of this.children) {
|
|
61
46
|
if (child.nodeType !== "TagNode" && child.nodeType !== "TextNode" && child.nodeType !== "LinebreakNode") {
|
|
@@ -66,10 +51,10 @@ class RootNode extends AstNode {
|
|
|
66
51
|
}
|
|
67
52
|
}
|
|
68
53
|
class TextNode extends AstNode {
|
|
54
|
+
nodeType = "TextNode";
|
|
55
|
+
str;
|
|
69
56
|
constructor(str) {
|
|
70
57
|
super();
|
|
71
|
-
__publicField(this, "nodeType", "TextNode");
|
|
72
|
-
__publicField(this, "str");
|
|
73
58
|
this.str = str;
|
|
74
59
|
}
|
|
75
60
|
isValid() {
|
|
@@ -87,30 +72,21 @@ class TextNode extends AstNode {
|
|
|
87
72
|
}
|
|
88
73
|
}
|
|
89
74
|
class LinebreakNode extends AstNode {
|
|
90
|
-
|
|
91
|
-
super(...arguments);
|
|
92
|
-
__publicField(this, "nodeType", "LinebreakNode");
|
|
93
|
-
}
|
|
75
|
+
nodeType = "LinebreakNode";
|
|
94
76
|
toShortString() {
|
|
95
77
|
return `${super.toShortString()} "\\n"`;
|
|
96
78
|
}
|
|
97
79
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
__publicField(this, "nodeType", "AttrNode");
|
|
102
|
-
}
|
|
80
|
+
class AttrNode extends AstNode {
|
|
81
|
+
nodeType = "AttrNode";
|
|
82
|
+
static DEFAULT_KEY = "default";
|
|
103
83
|
get key() {
|
|
104
84
|
switch (this.children.length) {
|
|
105
85
|
case 1: {
|
|
106
|
-
return
|
|
86
|
+
return AttrNode.DEFAULT_KEY;
|
|
107
87
|
}
|
|
108
88
|
case 2: {
|
|
109
|
-
if (!nodeIsType(
|
|
110
|
-
this.children[0],
|
|
111
|
-
"TextNode"
|
|
112
|
-
/* TextNode */
|
|
113
|
-
)) {
|
|
89
|
+
if (!nodeIsType(this.children[0], "TextNode")) {
|
|
114
90
|
throw new Error("Invalid TextNode");
|
|
115
91
|
}
|
|
116
92
|
return this.children[0].str.trim();
|
|
@@ -121,21 +97,13 @@ const _AttrNode = class _AttrNode extends AstNode {
|
|
|
121
97
|
get val() {
|
|
122
98
|
switch (this.children.length) {
|
|
123
99
|
case 1: {
|
|
124
|
-
if (!nodeIsType(
|
|
125
|
-
this.children[0],
|
|
126
|
-
"TextNode"
|
|
127
|
-
/* TextNode */
|
|
128
|
-
)) {
|
|
100
|
+
if (!nodeIsType(this.children[0], "TextNode")) {
|
|
129
101
|
throw new Error("Invalid TextNode");
|
|
130
102
|
}
|
|
131
103
|
return this.children[0].str.trim();
|
|
132
104
|
}
|
|
133
105
|
case 2: {
|
|
134
|
-
if (!nodeIsType(
|
|
135
|
-
this.children[1],
|
|
136
|
-
"TextNode"
|
|
137
|
-
/* TextNode */
|
|
138
|
-
)) {
|
|
106
|
+
if (!nodeIsType(this.children[1], "TextNode")) {
|
|
139
107
|
throw new Error("Invalid TextNode");
|
|
140
108
|
}
|
|
141
109
|
return this.children[1].str.trim();
|
|
@@ -181,15 +149,13 @@ const _AttrNode = class _AttrNode extends AstNode {
|
|
|
181
149
|
}
|
|
182
150
|
return json;
|
|
183
151
|
}
|
|
184
|
-
}
|
|
185
|
-
__publicField(_AttrNode, "DEFAULT_KEY", "default");
|
|
186
|
-
let AttrNode = _AttrNode;
|
|
152
|
+
}
|
|
187
153
|
class StartTagNode extends AstNode {
|
|
154
|
+
nodeType = "StartTagNode";
|
|
155
|
+
tagName;
|
|
156
|
+
ogTag;
|
|
188
157
|
constructor(tagName, ogTag, attrNodes = []) {
|
|
189
158
|
super(attrNodes);
|
|
190
|
-
__publicField(this, "nodeType", "StartTagNode");
|
|
191
|
-
__publicField(this, "tagName");
|
|
192
|
-
__publicField(this, "ogTag");
|
|
193
159
|
this.tagName = tagName.toLowerCase();
|
|
194
160
|
this.ogTag = ogTag;
|
|
195
161
|
}
|
|
@@ -213,11 +179,11 @@ class StartTagNode extends AstNode {
|
|
|
213
179
|
}
|
|
214
180
|
}
|
|
215
181
|
class EndTagNode extends AstNode {
|
|
182
|
+
nodeType = "EndTagNode";
|
|
183
|
+
tagName;
|
|
184
|
+
ogTag;
|
|
216
185
|
constructor(tagName, ogTag) {
|
|
217
186
|
super();
|
|
218
|
-
__publicField(this, "nodeType", "EndTagNode");
|
|
219
|
-
__publicField(this, "tagName");
|
|
220
|
-
__publicField(this, "ogTag");
|
|
221
187
|
this.tagName = tagName;
|
|
222
188
|
this.ogTag = ogTag;
|
|
223
189
|
}
|
|
@@ -236,11 +202,11 @@ class EndTagNode extends AstNode {
|
|
|
236
202
|
}
|
|
237
203
|
}
|
|
238
204
|
class TagNode extends AstNode {
|
|
205
|
+
nodeType = "TagNode";
|
|
206
|
+
_startTag;
|
|
207
|
+
_endTag;
|
|
239
208
|
constructor(startTag, endTag) {
|
|
240
209
|
super();
|
|
241
|
-
__publicField(this, "nodeType", "TagNode");
|
|
242
|
-
__publicField(this, "_startTag");
|
|
243
|
-
__publicField(this, "_endTag");
|
|
244
210
|
this._startTag = startTag;
|
|
245
211
|
this._endTag = endTag;
|
|
246
212
|
}
|
|
@@ -257,23 +223,14 @@ class TagNode extends AstNode {
|
|
|
257
223
|
if (!this._endTag) {
|
|
258
224
|
return "";
|
|
259
225
|
}
|
|
260
|
-
if (nodeIsType(
|
|
261
|
-
this._endTag,
|
|
262
|
-
"LinebreakNode"
|
|
263
|
-
/* LinebreakNode */
|
|
264
|
-
)) {
|
|
226
|
+
if (nodeIsType(this._endTag, "LinebreakNode")) {
|
|
265
227
|
return "\n";
|
|
266
228
|
} else {
|
|
267
229
|
return this._endTag.ogTag;
|
|
268
230
|
}
|
|
269
231
|
}
|
|
270
232
|
isValid() {
|
|
271
|
-
|
|
272
|
-
if (this._endTag && nodeIsType(
|
|
273
|
-
this._endTag,
|
|
274
|
-
"EndTagNode"
|
|
275
|
-
/* EndTagNode */
|
|
276
|
-
) && this._startTag.tagName !== this._endTag.tagName) {
|
|
233
|
+
if (this._endTag && nodeIsType(this._endTag, "EndTagNode") && this._startTag.tagName !== this._endTag.tagName) {
|
|
277
234
|
return false;
|
|
278
235
|
}
|
|
279
236
|
if (this.children.length === 1 && this.children[0].nodeType !== "RootNode") {
|
|
@@ -282,7 +239,7 @@ class TagNode extends AstNode {
|
|
|
282
239
|
if (this.children.length > 2) {
|
|
283
240
|
return false;
|
|
284
241
|
}
|
|
285
|
-
return super.isValid() && this._startTag.isValid() && (
|
|
242
|
+
return super.isValid() && this._startTag.isValid() && (this._endTag?.isValid() ?? true);
|
|
286
243
|
}
|
|
287
244
|
toString(depth = 0) {
|
|
288
245
|
let s = " ".repeat(depth * 2) + this.toShortString() + ` [${this.tagName}]`;
|
|
@@ -317,14 +274,14 @@ function getTagImmediateText(tagNode) {
|
|
|
317
274
|
return void 0;
|
|
318
275
|
}
|
|
319
276
|
const child = tagNode.children[0];
|
|
320
|
-
if (!nodeIsType(child,
|
|
277
|
+
if (!nodeIsType(child, "RootNode")) {
|
|
321
278
|
return void 0;
|
|
322
279
|
}
|
|
323
280
|
if (child.children.length !== 1) {
|
|
324
281
|
return void 0;
|
|
325
282
|
}
|
|
326
283
|
const textNode = child.children[0];
|
|
327
|
-
if (!nodeIsType(textNode,
|
|
284
|
+
if (!nodeIsType(textNode, "TextNode")) {
|
|
328
285
|
return void 0;
|
|
329
286
|
}
|
|
330
287
|
return textNode.str;
|
|
@@ -564,22 +521,21 @@ const htmlTransforms = [
|
|
|
564
521
|
}
|
|
565
522
|
];
|
|
566
523
|
class Generator {
|
|
524
|
+
transforms;
|
|
567
525
|
constructor(transforms = htmlTransforms) {
|
|
568
|
-
__publicField(this, "transforms");
|
|
569
526
|
this.transforms = new Map(transforms.map((transform) => [transform.name, transform]));
|
|
570
527
|
}
|
|
571
528
|
generate(root) {
|
|
572
529
|
const stringify = (node) => {
|
|
573
|
-
var _a;
|
|
574
530
|
let output = "";
|
|
575
|
-
if (nodeIsType(node,
|
|
531
|
+
if (nodeIsType(node, "TagNode")) {
|
|
576
532
|
const tagName = node.tagName;
|
|
577
533
|
const transform = this.transforms.get(tagName);
|
|
578
534
|
if (!transform) {
|
|
579
535
|
throw new Error(`Unrecognized bbcode ${node.tagName}`);
|
|
580
536
|
}
|
|
581
537
|
const renderedStartTag = transform.start(node);
|
|
582
|
-
const renderedEndTag =
|
|
538
|
+
const renderedEndTag = transform.end?.(node) ?? "";
|
|
583
539
|
const isInvalidTag = renderedStartTag === false;
|
|
584
540
|
if (isInvalidTag) {
|
|
585
541
|
output += node.ogStartTag;
|
|
@@ -596,9 +552,9 @@ class Generator {
|
|
|
596
552
|
} else {
|
|
597
553
|
output += renderedEndTag;
|
|
598
554
|
}
|
|
599
|
-
} else if (nodeIsType(node,
|
|
555
|
+
} else if (nodeIsType(node, "TextNode")) {
|
|
600
556
|
output += node.str;
|
|
601
|
-
} else if (nodeIsType(node,
|
|
557
|
+
} else if (nodeIsType(node, "LinebreakNode")) {
|
|
602
558
|
output += "\n";
|
|
603
559
|
} else {
|
|
604
560
|
for (const child of node.children) {
|
|
@@ -610,71 +566,56 @@ class Generator {
|
|
|
610
566
|
return stringify(root);
|
|
611
567
|
}
|
|
612
568
|
}
|
|
613
|
-
var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
614
|
-
TokenType2[TokenType2["STR"] = 0] = "STR";
|
|
615
|
-
TokenType2[TokenType2["LINEBREAK"] = 1] = "LINEBREAK";
|
|
616
|
-
TokenType2[TokenType2["L_BRACKET"] = 2] = "L_BRACKET";
|
|
617
|
-
TokenType2[TokenType2["R_BRACKET"] = 3] = "R_BRACKET";
|
|
618
|
-
TokenType2[TokenType2["BACKSLASH"] = 4] = "BACKSLASH";
|
|
619
|
-
TokenType2[TokenType2["EQUALS"] = 5] = "EQUALS";
|
|
620
|
-
TokenType2[TokenType2["XSS_AMP"] = 6] = "XSS_AMP";
|
|
621
|
-
TokenType2[TokenType2["XSS_LT"] = 7] = "XSS_LT";
|
|
622
|
-
TokenType2[TokenType2["XSS_GT"] = 8] = "XSS_GT";
|
|
623
|
-
TokenType2[TokenType2["XSS_D_QUOTE"] = 9] = "XSS_D_QUOTE";
|
|
624
|
-
TokenType2[TokenType2["XSS_S_QUOTE"] = 10] = "XSS_S_QUOTE";
|
|
625
|
-
return TokenType2;
|
|
626
|
-
})(TokenType || {});
|
|
627
569
|
function tokenTypeToString(tokenType) {
|
|
628
570
|
switch (tokenType) {
|
|
629
|
-
case
|
|
571
|
+
case "STR":
|
|
630
572
|
return "STR";
|
|
631
|
-
case
|
|
573
|
+
case "LINEBREAK":
|
|
632
574
|
return "LINEBREAK";
|
|
633
|
-
case
|
|
575
|
+
case "L_BRACKET":
|
|
634
576
|
return "L_BRACKET";
|
|
635
|
-
case
|
|
577
|
+
case "R_BRACKET":
|
|
636
578
|
return "R_BRACKET";
|
|
637
|
-
case
|
|
579
|
+
case "BACKSLASH":
|
|
638
580
|
return "BACKSLASH";
|
|
639
|
-
case
|
|
581
|
+
case "EQUALS":
|
|
640
582
|
return "EQUALS";
|
|
641
|
-
case
|
|
583
|
+
case "XSS_AMP":
|
|
642
584
|
return "XSS_AMP";
|
|
643
|
-
case
|
|
585
|
+
case "XSS_LT":
|
|
644
586
|
return "XSS_LT";
|
|
645
|
-
case
|
|
587
|
+
case "XSS_GT":
|
|
646
588
|
return "XSS_GT";
|
|
647
|
-
case
|
|
589
|
+
case "XSS_D_QUOTE":
|
|
648
590
|
return "XSS_D_QUOTE";
|
|
649
|
-
case
|
|
591
|
+
case "XSS_S_QUOTE":
|
|
650
592
|
return "XSS_S_QUOTE";
|
|
651
593
|
}
|
|
652
594
|
}
|
|
653
595
|
function isStringToken(tokenType) {
|
|
654
596
|
switch (tokenType) {
|
|
655
|
-
case
|
|
656
|
-
case
|
|
657
|
-
case
|
|
658
|
-
case
|
|
659
|
-
case
|
|
660
|
-
case
|
|
597
|
+
case "XSS_AMP":
|
|
598
|
+
case "XSS_LT":
|
|
599
|
+
case "XSS_GT":
|
|
600
|
+
case "XSS_D_QUOTE":
|
|
601
|
+
case "XSS_S_QUOTE":
|
|
602
|
+
case "STR": {
|
|
661
603
|
return true;
|
|
662
604
|
}
|
|
663
605
|
}
|
|
664
606
|
return false;
|
|
665
607
|
}
|
|
666
608
|
const symbolTable = {
|
|
667
|
-
"\n":
|
|
668
|
-
"[":
|
|
669
|
-
"]":
|
|
670
|
-
"/":
|
|
671
|
-
"=":
|
|
672
|
-
"&":
|
|
673
|
-
"<":
|
|
674
|
-
">":
|
|
675
|
-
'"':
|
|
676
|
-
"'":
|
|
677
|
-
/* XSS_S_QUOTE */
|
|
609
|
+
"\n": "LINEBREAK",
|
|
610
|
+
"[": "L_BRACKET",
|
|
611
|
+
"]": "R_BRACKET",
|
|
612
|
+
"/": "BACKSLASH",
|
|
613
|
+
"=": "EQUALS",
|
|
614
|
+
"&": "XSS_AMP",
|
|
615
|
+
"<": "XSS_LT",
|
|
616
|
+
">": "XSS_GT",
|
|
617
|
+
'"': "XSS_D_QUOTE",
|
|
618
|
+
"'": "XSS_S_QUOTE"
|
|
678
619
|
};
|
|
679
620
|
class Lexer {
|
|
680
621
|
tokenize(input) {
|
|
@@ -689,7 +630,7 @@ class Lexer {
|
|
|
689
630
|
const length2 = match.index - offset;
|
|
690
631
|
if (length2 > 0) {
|
|
691
632
|
tokens.push({
|
|
692
|
-
type:
|
|
633
|
+
type: "STR",
|
|
693
634
|
offset,
|
|
694
635
|
length: length2
|
|
695
636
|
});
|
|
@@ -697,34 +638,34 @@ class Lexer {
|
|
|
697
638
|
offset = match.index;
|
|
698
639
|
if (match[0] === "[/") {
|
|
699
640
|
tokens.push({
|
|
700
|
-
type:
|
|
641
|
+
type: "L_BRACKET",
|
|
701
642
|
offset,
|
|
702
643
|
length: 1
|
|
703
644
|
});
|
|
704
645
|
offset += 1;
|
|
705
646
|
tokens.push({
|
|
706
|
-
type:
|
|
647
|
+
type: "BACKSLASH",
|
|
707
648
|
offset,
|
|
708
649
|
length: 1
|
|
709
650
|
});
|
|
710
651
|
offset += 1;
|
|
711
652
|
} else if (match[0].startsWith("[")) {
|
|
712
653
|
tokens.push({
|
|
713
|
-
type:
|
|
654
|
+
type: "L_BRACKET",
|
|
714
655
|
offset,
|
|
715
656
|
length: 1
|
|
716
657
|
});
|
|
717
658
|
offset += 1;
|
|
718
659
|
const length3 = match[0].length - 1;
|
|
719
660
|
tokens.push({
|
|
720
|
-
type:
|
|
661
|
+
type: "STR",
|
|
721
662
|
offset,
|
|
722
663
|
length: length3
|
|
723
664
|
});
|
|
724
665
|
offset += length3;
|
|
725
666
|
} else {
|
|
726
667
|
tokens.push({
|
|
727
|
-
type: symbolTable[match[0]] ??
|
|
668
|
+
type: symbolTable[match[0]] ?? "STR",
|
|
728
669
|
offset,
|
|
729
670
|
length: 1
|
|
730
671
|
});
|
|
@@ -734,7 +675,7 @@ class Lexer {
|
|
|
734
675
|
const length = input.length - offset;
|
|
735
676
|
if (length > 0) {
|
|
736
677
|
tokens.push({
|
|
737
|
-
type:
|
|
678
|
+
type: "STR",
|
|
738
679
|
offset,
|
|
739
680
|
length
|
|
740
681
|
});
|
|
@@ -746,47 +687,47 @@ function stringifyTokens(ogText, tokens) {
|
|
|
746
687
|
let s = "";
|
|
747
688
|
for (const token of tokens) {
|
|
748
689
|
switch (token.type) {
|
|
749
|
-
case
|
|
690
|
+
case "STR": {
|
|
750
691
|
s += ogText.substring(token.offset, token.offset + token.length);
|
|
751
692
|
break;
|
|
752
693
|
}
|
|
753
|
-
case
|
|
694
|
+
case "LINEBREAK": {
|
|
754
695
|
s += "\n";
|
|
755
696
|
break;
|
|
756
697
|
}
|
|
757
|
-
case
|
|
698
|
+
case "L_BRACKET": {
|
|
758
699
|
s += "[";
|
|
759
700
|
break;
|
|
760
701
|
}
|
|
761
|
-
case
|
|
702
|
+
case "R_BRACKET": {
|
|
762
703
|
s += "]";
|
|
763
704
|
break;
|
|
764
705
|
}
|
|
765
|
-
case
|
|
706
|
+
case "BACKSLASH": {
|
|
766
707
|
s += "/";
|
|
767
708
|
break;
|
|
768
709
|
}
|
|
769
|
-
case
|
|
710
|
+
case "EQUALS": {
|
|
770
711
|
s += "=";
|
|
771
712
|
break;
|
|
772
713
|
}
|
|
773
|
-
case
|
|
714
|
+
case "XSS_AMP": {
|
|
774
715
|
s += "&";
|
|
775
716
|
break;
|
|
776
717
|
}
|
|
777
|
-
case
|
|
718
|
+
case "XSS_LT": {
|
|
778
719
|
s += "<";
|
|
779
720
|
break;
|
|
780
721
|
}
|
|
781
|
-
case
|
|
722
|
+
case "XSS_GT": {
|
|
782
723
|
s += ">";
|
|
783
724
|
break;
|
|
784
725
|
}
|
|
785
|
-
case
|
|
726
|
+
case "XSS_D_QUOTE": {
|
|
786
727
|
s += """;
|
|
787
728
|
break;
|
|
788
729
|
}
|
|
789
|
-
case
|
|
730
|
+
case "XSS_S_QUOTE": {
|
|
790
731
|
s += "'";
|
|
791
732
|
break;
|
|
792
733
|
}
|
|
@@ -795,10 +736,10 @@ function stringifyTokens(ogText, tokens) {
|
|
|
795
736
|
return s;
|
|
796
737
|
}
|
|
797
738
|
class Parser {
|
|
739
|
+
tags;
|
|
740
|
+
linebreakTerminatedTags;
|
|
741
|
+
standaloneTags;
|
|
798
742
|
constructor(transforms = htmlTransforms) {
|
|
799
|
-
__publicField(this, "tags");
|
|
800
|
-
__publicField(this, "linebreakTerminatedTags");
|
|
801
|
-
__publicField(this, "standaloneTags");
|
|
802
743
|
this.tags = new Set(transforms.map((transform) => transform.name));
|
|
803
744
|
this.linebreakTerminatedTags = new Set(transforms.filter((transform) => transform.isLinebreakTerminated).map((transform) => transform.name.toLowerCase()));
|
|
804
745
|
this.standaloneTags = new Set(transforms.filter((transform) => transform.isStandalone).map((transform) => transform.name.toLowerCase()));
|
|
@@ -817,7 +758,7 @@ class Parser {
|
|
|
817
758
|
if (!isStringToken(tokens[idx].type)) {
|
|
818
759
|
break;
|
|
819
760
|
}
|
|
820
|
-
if (endOnQuotes && (tokens[idx].type ===
|
|
761
|
+
if (endOnQuotes && (tokens[idx].type === "XSS_S_QUOTE" || tokens[idx].type === "XSS_D_QUOTE")) {
|
|
821
762
|
break;
|
|
822
763
|
}
|
|
823
764
|
if (endOnSpace && !endOnQuotes) {
|
|
@@ -825,12 +766,12 @@ class Parser {
|
|
|
825
766
|
const spaceIdx = origStr.indexOf(" ");
|
|
826
767
|
if (spaceIdx >= 0) {
|
|
827
768
|
const oldToken = {
|
|
828
|
-
type:
|
|
769
|
+
type: "STR",
|
|
829
770
|
offset: tokens[idx].offset,
|
|
830
771
|
length: spaceIdx
|
|
831
772
|
};
|
|
832
773
|
const newToken = {
|
|
833
|
-
type:
|
|
774
|
+
type: "STR",
|
|
834
775
|
offset: tokens[idx].offset + spaceIdx,
|
|
835
776
|
length: tokens[idx].length - spaceIdx
|
|
836
777
|
};
|
|
@@ -851,37 +792,37 @@ class Parser {
|
|
|
851
792
|
return null;
|
|
852
793
|
}
|
|
853
794
|
const attrNode = new AttrNode();
|
|
854
|
-
if (tokens[idx].type ===
|
|
795
|
+
if (tokens[idx].type === "EQUALS" && isStringToken(tokens[idx + 1].type)) {
|
|
855
796
|
idx += 1;
|
|
856
|
-
const openedWithQuotes = tokens[idx].type ===
|
|
797
|
+
const openedWithQuotes = tokens[idx].type === "XSS_S_QUOTE" || tokens[idx].type === "XSS_D_QUOTE";
|
|
857
798
|
if (openedWithQuotes) {
|
|
858
799
|
idx += 1;
|
|
859
800
|
}
|
|
860
801
|
const valNode = parseText(openedWithQuotes, true);
|
|
861
802
|
attrNode.addChild(valNode);
|
|
862
803
|
if (openedWithQuotes) {
|
|
863
|
-
if (tokens[idx].type !==
|
|
804
|
+
if (tokens[idx].type !== "XSS_S_QUOTE" && tokens[idx].type !== "XSS_D_QUOTE") {
|
|
864
805
|
return null;
|
|
865
806
|
}
|
|
866
807
|
idx += 1;
|
|
867
808
|
}
|
|
868
|
-
} else if (isStringToken(tokens[idx].type) && tokens[idx + 1].type ===
|
|
809
|
+
} else if (isStringToken(tokens[idx].type) && tokens[idx + 1].type === "EQUALS" && (idx + 2 < tokens.length && isStringToken(tokens[idx + 2].type))) {
|
|
869
810
|
const keyNode = parseText();
|
|
870
811
|
attrNode.addChild(keyNode);
|
|
871
812
|
idx += 1;
|
|
872
|
-
const openedWithQuotes = tokens[idx].type ===
|
|
813
|
+
const openedWithQuotes = tokens[idx].type === "XSS_S_QUOTE" || tokens[idx].type === "XSS_D_QUOTE";
|
|
873
814
|
if (openedWithQuotes) {
|
|
874
815
|
idx += 1;
|
|
875
816
|
}
|
|
876
817
|
const valNode = parseText(openedWithQuotes, true);
|
|
877
818
|
if (openedWithQuotes) {
|
|
878
|
-
if (tokens[idx].type !==
|
|
819
|
+
if (tokens[idx].type !== "XSS_S_QUOTE" && tokens[idx].type !== "XSS_D_QUOTE") {
|
|
879
820
|
return null;
|
|
880
821
|
}
|
|
881
822
|
idx += 1;
|
|
882
823
|
}
|
|
883
824
|
attrNode.addChild(valNode);
|
|
884
|
-
} else if (isStringToken(tokens[idx].type) && tokens[idx + 1].type !==
|
|
825
|
+
} else if (isStringToken(tokens[idx].type) && tokens[idx + 1].type !== "EQUALS") {
|
|
885
826
|
const valNode = parseText();
|
|
886
827
|
attrNode.addChild(valNode);
|
|
887
828
|
} else {
|
|
@@ -893,7 +834,7 @@ class Parser {
|
|
|
893
834
|
if (idx + 1 >= tokens.length) {
|
|
894
835
|
return null;
|
|
895
836
|
}
|
|
896
|
-
if (tokens[idx].type !==
|
|
837
|
+
if (tokens[idx].type !== "L_BRACKET") {
|
|
897
838
|
return null;
|
|
898
839
|
}
|
|
899
840
|
if (isStringToken(tokens[idx + 1].type)) {
|
|
@@ -911,7 +852,7 @@ class Parser {
|
|
|
911
852
|
}
|
|
912
853
|
attrNodes.push(attrNode);
|
|
913
854
|
}
|
|
914
|
-
if (tokens[idx].type !==
|
|
855
|
+
if (tokens[idx].type !== "R_BRACKET") {
|
|
915
856
|
return null;
|
|
916
857
|
}
|
|
917
858
|
idx += 1;
|
|
@@ -920,7 +861,7 @@ class Parser {
|
|
|
920
861
|
const startTagNode = new StartTagNode(labelText, ogTag, attrNodes);
|
|
921
862
|
return startTagNode;
|
|
922
863
|
}
|
|
923
|
-
if (tokens[idx + 1].type ===
|
|
864
|
+
if (tokens[idx + 1].type === "BACKSLASH") {
|
|
924
865
|
const startIdx = idx;
|
|
925
866
|
idx += 1;
|
|
926
867
|
idx += 1;
|
|
@@ -928,7 +869,7 @@ class Parser {
|
|
|
928
869
|
if (!this.tags.has(labelText)) {
|
|
929
870
|
return null;
|
|
930
871
|
}
|
|
931
|
-
if (tokens[idx].type !==
|
|
872
|
+
if (tokens[idx].type !== "R_BRACKET") {
|
|
932
873
|
return null;
|
|
933
874
|
}
|
|
934
875
|
idx += 1;
|
|
@@ -942,7 +883,7 @@ class Parser {
|
|
|
942
883
|
const parseRoot = () => {
|
|
943
884
|
const root2 = new RootNode();
|
|
944
885
|
while (idx < tokens.length) {
|
|
945
|
-
if (tokens[idx].type ===
|
|
886
|
+
if (tokens[idx].type === "L_BRACKET") {
|
|
946
887
|
const startIdx = idx;
|
|
947
888
|
const tagNode = parseTag();
|
|
948
889
|
if (tagNode !== null) {
|
|
@@ -953,12 +894,12 @@ class Parser {
|
|
|
953
894
|
const textNode = new TextNode(str);
|
|
954
895
|
root2.addChild(textNode);
|
|
955
896
|
}
|
|
956
|
-
} else if (tokens[idx].type ===
|
|
897
|
+
} else if (tokens[idx].type === "LINEBREAK") {
|
|
957
898
|
idx += 1;
|
|
958
899
|
root2.addChild(new LinebreakNode());
|
|
959
900
|
} else {
|
|
960
901
|
const startIdx = idx;
|
|
961
|
-
while (idx < tokens.length && tokens[idx].type !==
|
|
902
|
+
while (idx < tokens.length && tokens[idx].type !== "L_BRACKET" && tokens[idx].type !== "LINEBREAK") {
|
|
962
903
|
idx += 1;
|
|
963
904
|
}
|
|
964
905
|
const slice = tokens.slice(startIdx, idx);
|
|
@@ -979,11 +920,11 @@ class Parser {
|
|
|
979
920
|
const transformedRoot = new RootNode();
|
|
980
921
|
for (let i = 0; i < rootNode.children.length; i++) {
|
|
981
922
|
const child = rootNode.children[i];
|
|
982
|
-
if (nodeIsType(child,
|
|
923
|
+
if (nodeIsType(child, "StartTagNode")) {
|
|
983
924
|
const endTag = this.findMatchingEndTag(rootNode.children, i, child.tagName);
|
|
984
925
|
const isStandalone = this.standaloneTags.has(child.tagName);
|
|
985
926
|
if (endTag || isStandalone) {
|
|
986
|
-
const tagNode = new TagNode(child, endTag
|
|
927
|
+
const tagNode = new TagNode(child, endTag?.node);
|
|
987
928
|
transformedRoot.addChild(tagNode);
|
|
988
929
|
if (endTag) {
|
|
989
930
|
const subRoot = new RootNode(rootNode.children.slice(i + 1, endTag.idx));
|
|
@@ -994,11 +935,11 @@ class Parser {
|
|
|
994
935
|
} else {
|
|
995
936
|
transformedRoot.addChild(new TextNode(child.ogTag));
|
|
996
937
|
}
|
|
997
|
-
} else if (nodeIsType(child,
|
|
938
|
+
} else if (nodeIsType(child, "EndTagNode")) {
|
|
998
939
|
transformedRoot.addChild(new TextNode(child.ogTag));
|
|
999
|
-
} else if (nodeIsType(child,
|
|
940
|
+
} else if (nodeIsType(child, "TextNode")) {
|
|
1000
941
|
transformedRoot.addChild(child);
|
|
1001
|
-
} else if (nodeIsType(child,
|
|
942
|
+
} else if (nodeIsType(child, "LinebreakNode")) {
|
|
1002
943
|
transformedRoot.addChild(child);
|
|
1003
944
|
} else {
|
|
1004
945
|
throw new Error("Unexpected child of RootNode");
|
|
@@ -1012,7 +953,7 @@ class Parser {
|
|
|
1012
953
|
}
|
|
1013
954
|
for (let i = startIdx; i < siblings.length; i++) {
|
|
1014
955
|
const sibling = siblings[i];
|
|
1015
|
-
const isEndTag = nodeIsType(sibling,
|
|
956
|
+
const isEndTag = nodeIsType(sibling, "LinebreakNode") && this.linebreakTerminatedTags.has(tagName) || nodeIsType(sibling, "EndTagNode") && sibling.tagName === tagName;
|
|
1016
957
|
if (isEndTag) {
|
|
1017
958
|
return {
|
|
1018
959
|
idx: i,
|
|
@@ -1033,7 +974,6 @@ function generateHtml(input, transforms = htmlTransforms) {
|
|
|
1033
974
|
}
|
|
1034
975
|
export {
|
|
1035
976
|
AstNode,
|
|
1036
|
-
AstNodeType,
|
|
1037
977
|
AttrNode,
|
|
1038
978
|
EndTagNode,
|
|
1039
979
|
Generator,
|
|
@@ -1044,7 +984,6 @@ export {
|
|
|
1044
984
|
StartTagNode,
|
|
1045
985
|
TagNode,
|
|
1046
986
|
TextNode,
|
|
1047
|
-
TokenType,
|
|
1048
987
|
generateHtml,
|
|
1049
988
|
getTagImmediateAttrVal,
|
|
1050
989
|
getTagImmediateText,
|