diff --git a/.changeset/large-mangos-look.md b/.changeset/large-mangos-look.md new file mode 100644 index 000000000..65129ee98 --- /dev/null +++ b/.changeset/large-mangos-look.md @@ -0,0 +1,5 @@ +--- +"@astrojs/compiler": patch +--- + +Fixes a bug where the compiler couldn't correctly parse `select` elements, preventing elements from being incorrectly nested diff --git a/internal/parser.go b/internal/parser.go index 42d7eb0d8..ba607ea84 100644 --- a/internal/parser.go +++ b/internal/parser.go @@ -2319,6 +2319,8 @@ func inSelectIM(p *parser) bool { p.resetInsertionMode() case a.Template: return inHeadIM(p) + default: + return inBodyIM(p) } case CommentToken: p.addChild(&Node{ diff --git a/internal/printer/__printer_js__/select_with_2_options_containing_element.snap b/internal/printer/__printer_js__/select_with_2_options_containing_element.snap new file mode 100755 index 000000000..25bf28851 --- /dev/null +++ b/internal/printer/__printer_js__/select_with_2_options_containing_element.snap @@ -0,0 +1,41 @@ + +[TestPrinter/select_with_2_options_containing_element - 1] +## Input + +``` + +``` + +## Output + +```js +import { + Fragment, + render as $$render, + createAstro as $$createAstro, + createComponent as $$createComponent, + renderComponent as $$renderComponent, + renderHead as $$renderHead, + maybeRenderHead as $$maybeRenderHead, + unescapeHTML as $$unescapeHTML, + renderSlot as $$renderSlot, + mergeSlots as $$mergeSlots, + addAttribute as $$addAttribute, + spreadAttributes as $$spreadAttributes, + defineStyleVars as $$defineStyleVars, + defineScriptVars as $$defineScriptVars, + renderTransition as $$renderTransition, + createTransitionScope as $$createTransitionScope, + renderScript as $$renderScript, + createMetadata as $$createMetadata +} from "http://localhost:3000/"; + +export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] }); + +const $$Component = $$createComponent(($$result, $$props, $$slots) => { + +return $$render`${$$maybeRenderHead($$result)}`; +}, undefined, undefined); +export default $$Component; +``` +--- diff --git a/internal/printer/__printer_js__/select_with_2_options_containing_element_with_div_sibling.snap b/internal/printer/__printer_js__/select_with_2_options_containing_element_with_div_sibling.snap new file mode 100755 index 000000000..6e404e4b6 --- /dev/null +++ b/internal/printer/__printer_js__/select_with_2_options_containing_element_with_div_sibling.snap @@ -0,0 +1,41 @@ + +[TestPrinter/select_with_2_options_containing_element_with_div_sibling - 1] +## Input + +``` +
Orange
+``` + +## Output + +```js +import { + Fragment, + render as $$render, + createAstro as $$createAstro, + createComponent as $$createComponent, + renderComponent as $$renderComponent, + renderHead as $$renderHead, + maybeRenderHead as $$maybeRenderHead, + unescapeHTML as $$unescapeHTML, + renderSlot as $$renderSlot, + mergeSlots as $$mergeSlots, + addAttribute as $$addAttribute, + spreadAttributes as $$spreadAttributes, + defineStyleVars as $$defineStyleVars, + defineScriptVars as $$defineScriptVars, + renderTransition as $$renderTransition, + createTransitionScope as $$createTransitionScope, + renderScript as $$renderScript, + createMetadata as $$createMetadata +} from "http://localhost:3000/"; + +export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] }); + +const $$Component = $$createComponent(($$result, $$props, $$slots) => { + +return $$render`${$$maybeRenderHead($$result)}
Orange
`; +}, undefined, undefined); +export default $$Component; +``` +--- diff --git a/internal/printer/__printer_js__/select_with_option_containing_element.snap b/internal/printer/__printer_js__/select_with_option_containing_element.snap new file mode 100755 index 000000000..50d4fa234 --- /dev/null +++ b/internal/printer/__printer_js__/select_with_option_containing_element.snap @@ -0,0 +1,41 @@ + +[TestPrinter/select_with_option_containing_element - 1] +## Input + +``` + +``` + +## Output + +```js +import { + Fragment, + render as $$render, + createAstro as $$createAstro, + createComponent as $$createComponent, + renderComponent as $$renderComponent, + renderHead as $$renderHead, + maybeRenderHead as $$maybeRenderHead, + unescapeHTML as $$unescapeHTML, + renderSlot as $$renderSlot, + mergeSlots as $$mergeSlots, + addAttribute as $$addAttribute, + spreadAttributes as $$spreadAttributes, + defineStyleVars as $$defineStyleVars, + defineScriptVars as $$defineScriptVars, + renderTransition as $$renderTransition, + createTransitionScope as $$createTransitionScope, + renderScript as $$renderScript, + createMetadata as $$createMetadata +} from "http://localhost:3000/"; + +export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] }); + +const $$Component = $$createComponent(($$result, $$props, $$slots) => { + +return $$render`${$$maybeRenderHead($$result)}`; +}, undefined, undefined); +export default $$Component; +``` +--- diff --git a/internal/printer/__printer_js__/select_with_option_containing_element_and_button_containing_selected_content.snap b/internal/printer/__printer_js__/select_with_option_containing_element_and_button_containing_selected_content.snap new file mode 100755 index 000000000..eb1d207e8 --- /dev/null +++ b/internal/printer/__printer_js__/select_with_option_containing_element_and_button_containing_selected_content.snap @@ -0,0 +1,41 @@ + +[TestPrinter/select_with_option_containing_element_and_button_containing_selected_content - 1] +## Input + +``` + +``` + +## Output + +```js +import { + Fragment, + render as $$render, + createAstro as $$createAstro, + createComponent as $$createComponent, + renderComponent as $$renderComponent, + renderHead as $$renderHead, + maybeRenderHead as $$maybeRenderHead, + unescapeHTML as $$unescapeHTML, + renderSlot as $$renderSlot, + mergeSlots as $$mergeSlots, + addAttribute as $$addAttribute, + spreadAttributes as $$spreadAttributes, + defineStyleVars as $$defineStyleVars, + defineScriptVars as $$defineScriptVars, + renderTransition as $$renderTransition, + createTransitionScope as $$createTransitionScope, + renderScript as $$renderScript, + createMetadata as $$createMetadata +} from "http://localhost:3000/"; + +export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] }); + +const $$Component = $$createComponent(($$result, $$props, $$slots) => { + +return $$render`${$$maybeRenderHead($$result)}`; +}, undefined, undefined); +export default $$Component; +``` +--- diff --git a/internal/printer/__printer_js__/select_with_option_containing_element_with_div_sibling.snap b/internal/printer/__printer_js__/select_with_option_containing_element_with_div_sibling.snap new file mode 100755 index 000000000..f8b51d8b2 --- /dev/null +++ b/internal/printer/__printer_js__/select_with_option_containing_element_with_div_sibling.snap @@ -0,0 +1,41 @@ + +[TestPrinter/select_with_option_containing_element_with_div_sibling - 1] +## Input + +``` +
Orange
+``` + +## Output + +```js +import { + Fragment, + render as $$render, + createAstro as $$createAstro, + createComponent as $$createComponent, + renderComponent as $$renderComponent, + renderHead as $$renderHead, + maybeRenderHead as $$maybeRenderHead, + unescapeHTML as $$unescapeHTML, + renderSlot as $$renderSlot, + mergeSlots as $$mergeSlots, + addAttribute as $$addAttribute, + spreadAttributes as $$spreadAttributes, + defineStyleVars as $$defineStyleVars, + defineScriptVars as $$defineScriptVars, + renderTransition as $$renderTransition, + createTransitionScope as $$createTransitionScope, + renderScript as $$renderScript, + createMetadata as $$createMetadata +} from "http://localhost:3000/"; + +export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] }); + +const $$Component = $$createComponent(($$result, $$props, $$slots) => { + +return $$render`${$$maybeRenderHead($$result)}
Orange
`; +}, undefined, undefined); +export default $$Component; +``` +--- diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go index fedea94a3..73d28744c 100644 --- a/internal/printer/printer_test.go +++ b/internal/printer/printer_test.go @@ -1234,19 +1234,19 @@ import { Container, Col, Row } from 'react-bootstrap'; source: `
Default
Named
`, }, { - name: "Fragment with await", + name: "Fragment with await", source: ` { await Promise.resolve("Awaited") } `, }, { - name: "Fragment shorthand with await", + name: "Fragment shorthand with await", source: `<> { await Promise.resolve("Awaited") } `, }, { - name: "Fragment wrapping link with awaited href", + name: "Fragment wrapping link with awaited href", source: ``, }, { - name: "Component with await", + name: "Component with await", source: ` { await Promise.resolve("Awaited") } `, }, { @@ -2092,6 +2092,26 @@ const meta = { title: 'My App' }; name: "namespace is preserved when inside an expression", source: `{}`, }, + { + name: "select with option containing element", + source: ``, + }, + { + name: "select with 2 options containing element", + source: ``, + }, + { + name: "select with option containing element with div sibling", + source: `
Orange
`, + }, + { + name: "select with 2 options containing element with div sibling", + source: `
Orange
`, + }, + { + name: "select with option containing element and button containing selected content", + source: ``, + }, } for _, tt := range tests { if tt.only {