Skip to content

Commit

Permalink
fix: parsed text string literals
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Mar 13, 2023
1 parent 0ef31cd commit fe98530
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-shirts-dream.md
@@ -0,0 +1,5 @@
---
"htmljs-parser": patch
---

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"
@@ -0,0 +1,30 @@
1╭─ <script>
│ ││ ╰─ openTagEnd
│ │╰─ tagName "script"
╰─ ╰─ openTagStart
2╭─ "this is a ${test}"
│ │ │ ╰─ placeholder:escape.value "test"
│ │ ╰─ placeholder:escape "${test}"
╰─ ╰─ text "\n \"this is a "
3╭─ "this is a \${test}"
│ │ ╰─ text "${test}\"\n \"/*\"\n \"//\"\n 'this is a "
╰─ ╰─ text "\n \"this is a "
4├─ "/*"
5├─ "//"
6╭─ 'this is a ${test}'
│ │ ╰─ placeholder:escape.value "test"
╰─ ╰─ placeholder:escape "${test}"
7╭─ 'this is a \${test}'
│ │ ╰─ text "${test}'\n '/*'\n '//'\n `this is a ${test}`\n `this is a \\${test}`\n `/*`\n `//`\n"
╰─ ╰─ text "\n 'this is a "
8├─ '/*'
9├─ '//'
10├─ `this is a ${test}`
11├─ `this is a \${test}`
12├─ `/*`
13├─ `//`
14╭─ </script>
│ │ │ ╰─ closeTagEnd(script)
│ │ ╰─ closeTagName "script"
╰─ ╰─ closeTagStart "</"
15╰─
14 changes: 14 additions & 0 deletions src/__tests__/fixtures/script-with-strings/input.marko
@@ -0,0 +1,14 @@
<script>
"this is a ${test}"
"this is a \${test}"
"/*"
"//"
'this is a ${test}'
'this is a \${test}'
'/*'
'//'
`this is a ${test}`
`this is a \${test}`
`/*`
`//`
</script>
42 changes: 42 additions & 0 deletions src/states/PARSED_STRING.ts
@@ -0,0 +1,42 @@
import { CODE, ErrorCode, STATE, StateDefinition, Meta } from "../internal";

interface ParsedStringMeta extends Meta {
quoteCharCode: number;
}

export const PARSED_STRING: StateDefinition<ParsedStringMeta> = {
name: "PARSED_STRING",

enter(parent, start) {
return {
state: PARSED_STRING,
parent,
start,
end: start,
quoteCharCode: CODE.DOUBLE_QUOTE,
} as ParsedStringMeta;
},

exit() {},

char(code, str) {
if (code === str.quoteCharCode) {
this.pos++; // skip end quote
this.exitState();
} else if (!STATE.checkForPlaceholder(this, code)) {
this.startText();
}
},

eof(str) {
this.emitError(
str,
ErrorCode.INVALID_TEMPLATE_STRING,
"EOF reached while parsing string expression"
);
},

eol() {},

return() {},
};
6 changes: 6 additions & 0 deletions src/states/PARSED_TEXT_CONTENT.ts
Expand Up @@ -50,6 +50,12 @@ export const PARSED_TEXT_CONTENT: StateDefinition<ParsedTextContentMeta> = {
this.startText();
this.enterState(STATE.TEMPLATE_STRING);
break;
case CODE.DOUBLE_QUOTE:
case CODE.SINGLE_QUOTE:
this.startText();
this.enterState(STATE.PARSED_STRING).quoteCharCode = code;
break;

default:
if (!STATE.checkForPlaceholder(this, code)) this.startText();
break;
Expand Down
1 change: 1 addition & 0 deletions src/states/index.ts
Expand Up @@ -17,4 +17,5 @@ export * from "./REGULAR_EXPRESSION";
export * from "./STRING";
export * from "./TAG_NAME";
export * from "./TEMPLATE_STRING";
export * from "./PARSED_STRING";
export * from "./OPEN_TAG";

0 comments on commit fe98530

Please sign in to comment.