From fe985307a2112ba48c1317a16481c321ba256619 Mon Sep 17 00:00:00 2001 From: Dylan Piercey Date: Mon, 13 Mar 2023 14:37:17 -0700 Subject: [PATCH] fix: parsed text string literals --- .changeset/eight-shirts-dream.md | 5 +++ .../script-with-strings.expected.txt | 30 +++++++++++++ .../fixtures/script-with-strings/input.marko | 14 +++++++ src/states/PARSED_STRING.ts | 42 +++++++++++++++++++ src/states/PARSED_TEXT_CONTENT.ts | 6 +++ src/states/index.ts | 1 + 6 files changed, 98 insertions(+) create mode 100644 .changeset/eight-shirts-dream.md create mode 100644 src/__tests__/fixtures/script-with-strings/__snapshots__/script-with-strings.expected.txt create mode 100644 src/__tests__/fixtures/script-with-strings/input.marko create mode 100644 src/states/PARSED_STRING.ts diff --git a/.changeset/eight-shirts-dream.md b/.changeset/eight-shirts-dream.md new file mode 100644 index 00000000..39537b27 --- /dev/null +++ b/.changeset/eight-shirts-dream.md @@ -0,0 +1,5 @@ +--- +"htmljs-parser": patch +--- + +Fixes an regression where string literals inside of parsed text nodes (eg ` + │ │ │ ╰─ closeTagEnd(script) + │ │ ╰─ closeTagName "script" + ╰─ ╰─ closeTagStart " + "this is a ${test}" + "this is a \${test}" + "/*" + "//" + 'this is a ${test}' + 'this is a \${test}' + '/*' + '//' + `this is a ${test}` + `this is a \${test}` + `/*` + `//` + diff --git a/src/states/PARSED_STRING.ts b/src/states/PARSED_STRING.ts new file mode 100644 index 00000000..7ef88e29 --- /dev/null +++ b/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 = { + 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() {}, +}; diff --git a/src/states/PARSED_TEXT_CONTENT.ts b/src/states/PARSED_TEXT_CONTENT.ts index 4904354c..299d6cbf 100644 --- a/src/states/PARSED_TEXT_CONTENT.ts +++ b/src/states/PARSED_TEXT_CONTENT.ts @@ -50,6 +50,12 @@ export const PARSED_TEXT_CONTENT: StateDefinition = { 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; diff --git a/src/states/index.ts b/src/states/index.ts index db5eb50f..33471b5c 100644 --- a/src/states/index.ts +++ b/src/states/index.ts @@ -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";