diff options
author | 2021-08-10 00:36:12 +0300 | |
---|---|---|
committer | 2021-08-09 16:36:12 -0500 | |
commit | 618ea3a8ea8155e80e61f6a4718f6661d6297997 (patch) | |
tree | a8b31dcd04e193bcabdae62381dbc2a8e4cd6ec6 | |
parent | bef7247812f6b446ffd5cd273452bacd2b032f73 (diff) | |
download | astro-618ea3a8ea8155e80e61f6a4718f6661d6297997.tar.gz astro-618ea3a8ea8155e80e61f6a4718f6661d6297997.tar.zst astro-618ea3a8ea8155e80e61f6a4718f6661d6297997.zip |
Fix nested client load directive (#1030)
* escape </script> in string literals
* add changeset
-rw-r--r-- | .changeset/fair-dogs-tie.md | 5 | ||||
-rw-r--r-- | packages/astro/src/internal/__astro_component.ts | 18 |
2 files changed, 21 insertions, 2 deletions
diff --git a/.changeset/fair-dogs-tie.md b/.changeset/fair-dogs-tie.md new file mode 100644 index 000000000..caf00c755 --- /dev/null +++ b/.changeset/fair-dogs-tie.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Properly escapes script tags with nested client:load directives when passing Astro components into framework components via props. Browsers interpret script end tags in strings as script end tags, resulting in syntax errors. diff --git a/packages/astro/src/internal/__astro_component.ts b/packages/astro/src/internal/__astro_component.ts index 9470e5b14..0543df203 100644 --- a/packages/astro/src/internal/__astro_component.ts +++ b/packages/astro/src/internal/__astro_component.ts @@ -1,12 +1,26 @@ import type { Renderer, AstroComponentMetadata } from '../@types/astro'; import hash from 'shorthash'; import { valueToEstree, Value } from 'estree-util-value-to-estree'; -import { generate } from 'astring'; +import { generate, GENERATOR, Generator } from 'astring'; import * as astroHtml from './renderer-html'; // A more robust version alternative to `JSON.stringify` that can handle most values // see https://github.com/remcohaszing/estree-util-value-to-estree#readme -const serialize = (value: Value) => generate(valueToEstree(value)); +const customGenerator: Generator = { + ...GENERATOR, + Literal(node, state) { + if (node.raw != null) { + // escape closing script tags in strings so browsers wouldn't interpret them as + // closing the actual end tag in HTML + state.write(node.raw.replace('</script>', '<\\/script>')); + } else { + GENERATOR.Literal(node, state); + } + }, +}; +const serialize = (value: Value) => generate(valueToEstree(value), { + generator: customGenerator, +}); export interface RendererInstance { source: string | null; |