Skip to content

Commit fe98530

Browse files
committed
fix: parsed text string literals
1 parent 0ef31cd commit fe98530

File tree

6 files changed

+98
-0
lines changed

6 files changed

+98
-0
lines changed

.changeset/eight-shirts-dream.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"htmljs-parser": patch
3+
---
4+
5+
Fixes an regression where string literals inside of parsed text nodes (eg `<script>`) were not properly changing the parser state. This caused issues when comment like syntax was embedded within these string literals"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
1╭─ <script>
2+
│ ││ ╰─ openTagEnd
3+
│ │╰─ tagName "script"
4+
╰─ ╰─ openTagStart
5+
2╭─ "this is a ${test}"
6+
│ │ │ ╰─ placeholder:escape.value "test"
7+
│ │ ╰─ placeholder:escape "${test}"
8+
╰─ ╰─ text "\n \"this is a "
9+
3╭─ "this is a \${test}"
10+
│ │ ╰─ text "${test}\"\n \"/*\"\n \"//\"\n 'this is a "
11+
╰─ ╰─ text "\n \"this is a "
12+
4├─ "/*"
13+
5├─ "//"
14+
6╭─ 'this is a ${test}'
15+
│ │ ╰─ placeholder:escape.value "test"
16+
╰─ ╰─ placeholder:escape "${test}"
17+
7╭─ 'this is a \${test}'
18+
│ │ ╰─ text "${test}'\n '/*'\n '//'\n `this is a ${test}`\n `this is a \\${test}`\n `/*`\n `//`\n"
19+
╰─ ╰─ text "\n 'this is a "
20+
8├─ '/*'
21+
9├─ '//'
22+
10├─ `this is a ${test}`
23+
11├─ `this is a \${test}`
24+
12├─ `/*`
25+
13├─ `//`
26+
14╭─ </script>
27+
│ │ │ ╰─ closeTagEnd(script)
28+
│ │ ╰─ closeTagName "script"
29+
╰─ ╰─ closeTagStart "</"
30+
15╰─
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script>
2+
"this is a ${test}"
3+
"this is a \${test}"
4+
"/*"
5+
"//"
6+
'this is a ${test}'
7+
'this is a \${test}'
8+
'/*'
9+
'//'
10+
`this is a ${test}`
11+
`this is a \${test}`
12+
`/*`
13+
`//`
14+
</script>

src/states/PARSED_STRING.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { CODE, ErrorCode, STATE, StateDefinition, Meta } from "../internal";
2+
3+
interface ParsedStringMeta extends Meta {
4+
quoteCharCode: number;
5+
}
6+
7+
export const PARSED_STRING: StateDefinition<ParsedStringMeta> = {
8+
name: "PARSED_STRING",
9+
10+
enter(parent, start) {
11+
return {
12+
state: PARSED_STRING,
13+
parent,
14+
start,
15+
end: start,
16+
quoteCharCode: CODE.DOUBLE_QUOTE,
17+
} as ParsedStringMeta;
18+
},
19+
20+
exit() {},
21+
22+
char(code, str) {
23+
if (code === str.quoteCharCode) {
24+
this.pos++; // skip end quote
25+
this.exitState();
26+
} else if (!STATE.checkForPlaceholder(this, code)) {
27+
this.startText();
28+
}
29+
},
30+
31+
eof(str) {
32+
this.emitError(
33+
str,
34+
ErrorCode.INVALID_TEMPLATE_STRING,
35+
"EOF reached while parsing string expression"
36+
);
37+
},
38+
39+
eol() {},
40+
41+
return() {},
42+
};

src/states/PARSED_TEXT_CONTENT.ts

+6
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ export const PARSED_TEXT_CONTENT: StateDefinition<ParsedTextContentMeta> = {
5050
this.startText();
5151
this.enterState(STATE.TEMPLATE_STRING);
5252
break;
53+
case CODE.DOUBLE_QUOTE:
54+
case CODE.SINGLE_QUOTE:
55+
this.startText();
56+
this.enterState(STATE.PARSED_STRING).quoteCharCode = code;
57+
break;
58+
5359
default:
5460
if (!STATE.checkForPlaceholder(this, code)) this.startText();
5561
break;

src/states/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ export * from "./REGULAR_EXPRESSION";
1717
export * from "./STRING";
1818
export * from "./TAG_NAME";
1919
export * from "./TEMPLATE_STRING";
20+
export * from "./PARSED_STRING";
2021
export * from "./OPEN_TAG";

0 commit comments

Comments
 (0)