diff --git a/e2e-tests/options.test.ts b/e2e-tests/options.test.ts index 636ede59..a63e2e8c 100644 --- a/e2e-tests/options.test.ts +++ b/e2e-tests/options.test.ts @@ -109,6 +109,14 @@ test("should switch language and show options for each", async ({ page }) => { await expect( page.getByRole("combobox", { exact: true, name: "Front Matter" }), ).toBeVisible(); + + // `Math` Switch + await expect( + page.getByRole("switch", { + exact: true, + name: "Math", + }), + ).toBeVisible(); }); // CSS diff --git a/e2e-tests/persistence.test.ts b/e2e-tests/persistence.test.ts index 4306e214..8dd6f841 100644 --- a/e2e-tests/persistence.test.ts +++ b/e2e-tests/persistence.test.ts @@ -27,16 +27,15 @@ async function getPersistedJavaScriptCode(page: Page): Promise { } async function getPersistedExplorerState(page: Page): Promise { - const persistedValue = await page.evaluate( - key => window.localStorage.getItem(key), - storageKey, - ); + return page.evaluate(key => { + const storedValue = window.localStorage.getItem(key); - if (!persistedValue) { - throw new Error("Expected explorer state to be persisted"); - } + if (!storedValue) { + throw new Error("No persisted state found in localStorage"); + } - return persistedValue; + return storedValue; + }, storageKey); } async function getStoredHashValue(page: Page): Promise { @@ -163,3 +162,37 @@ test("should fall back to localStorage when a v2 hash is malformed", async ({ await expect(codeEditor).toContainText(fallbackCode); }); + +test("should patch legacy Markdown options without math", async ({ page }) => { + await page.addInitScript(key => { + window.localStorage.setItem( + key, + JSON.stringify({ + state: { + language: "markdown", + markdownOptions: { + markdownMode: "commonmark", + markdownFrontmatter: "off", + }, + }, + version: 0, + }), + ); + }, storageKey); + await page.goto("/"); + + await expect + .poll(async () => { + const explorerState = JSON.parse( + await getPersistedExplorerState(page), + ); + return explorerState.state.markdownOptions.markdownMath; + }) + .toBe(false); + + await page.getByRole("button", { name: "Language Options" }).click(); + + await expect( + page.getByRole("switch", { exact: true, name: "Math" }), + ).toHaveAttribute("aria-checked", "false"); +}); diff --git a/src/components/options.tsx b/src/components/options.tsx index a6777cd2..3c45711d 100644 --- a/src/components/options.tsx +++ b/src/components/options.tsx @@ -67,7 +67,7 @@ const JSONPanel: FC = () => { const MarkdownPanel: FC = () => { const explorer = useExplorer(); const { markdownOptions, setMarkdownOptions } = explorer; - const { markdownMode, markdownFrontmatter } = markdownOptions; + const { markdownMode, markdownFrontmatter, markdownMath } = markdownOptions; return ( <> { items={markdownFrontmatters} placeholder="Front Matter" /> + + { + setMarkdownOptions({ + ...markdownOptions, + markdownMath: value, + }); + }} + /> ); }; diff --git a/src/hooks/use-ast.ts b/src/hooks/use-ast.ts index 20094bec..0f92c687 100644 --- a/src/hooks/use-ast.ts +++ b/src/hooks/use-ast.ts @@ -66,7 +66,8 @@ export function useAST() { } case "markdown": { - const { markdownMode, markdownFrontmatter } = markdownOptions; + const { markdownMode, markdownFrontmatter, markdownMath } = + markdownOptions; const language = markdown.languages[markdownMode]; astParseResult = language.parse( { body: code.markdown, path: "", physicalPath: "", bom: false }, @@ -76,6 +77,7 @@ export function useAST() { markdownFrontmatter === "off" ? false : markdownFrontmatter, + math: markdownMath, }, }, ); diff --git a/src/hooks/use-explorer.ts b/src/hooks/use-explorer.ts index d7405f36..76c0d7d9 100644 --- a/src/hooks/use-explorer.ts +++ b/src/hooks/use-explorer.ts @@ -48,6 +48,7 @@ export type JsonOptions = { export type MarkdownOptions = { markdownMode: MarkdownMode; markdownFrontmatter: MarkdownFrontmatter; + markdownMath: boolean; }; export type CssOptions = { @@ -287,6 +288,27 @@ export const useExplorer = create()( if (needsPatching) { state.setCode(patchedCode); } + + state.setJsOptions({ + ...defaultJsOptions, + ...state.jsOptions, + }); + state.setJsonOptions({ + ...defaultJsonOptions, + ...state.jsonOptions, + }); + state.setMarkdownOptions({ + ...defaultMarkdownOptions, + ...state.markdownOptions, + }); + state.setCssOptions({ + ...defaultCssOptions, + ...state.cssOptions, + }); + state.setHtmlOptions({ + ...defaultHtmlOptions, + ...state.htmlOptions, + }); }, }, ), diff --git a/src/lib/const.ts b/src/lib/const.ts index 25fb385a..7a7f7a4a 100644 --- a/src/lib/const.ts +++ b/src/lib/const.ts @@ -484,6 +484,7 @@ export const defaultJsonOptions: JsonOptions = { export const defaultMarkdownOptions: MarkdownOptions = { markdownMode: "commonmark", markdownFrontmatter: "off", + markdownMath: false, }; export const defaultCssOptions: CssOptions = {