diff --git a/src/components/dialogs/algorithm-dialog.tsx b/src/components/dialogs/algorithm-dialog.tsx index 6259bba..50d6a47 100644 --- a/src/components/dialogs/algorithm-dialog.tsx +++ b/src/components/dialogs/algorithm-dialog.tsx @@ -34,15 +34,13 @@ export function AlgorithmDialog({ adding, onClose }: { adding: boolean; onClose: if (cancelled) return; instance = createCodeEditor(host.current!); editor.current = instance; - instance.setValue( - adding - ? "" - : getFunctionBody( - algorithm === algorithms[sort as keyof typeof algorithms] - ? sources[sort as keyof typeof sources] - : algorithm, - ), - ); + const builtin = algorithm === algorithms[sort as keyof typeof algorithms]; + const body = adding + ? "" + : getFunctionBody(builtin ? sources[sort as keyof typeof sources] : algorithm); + // Built-ins use two-space function indentation. Preserve custom source verbatim, + // since changing whitespace inside a template literal can change its value. + instance.setValue(builtin ? body.replace(/^ {2}/gm, "").trim() : body); instance.clearSelection(); setStatus("ready"); }) diff --git a/test/browser/site.spec.mjs b/test/browser/site.spec.mjs index e4b8999..b7e7c86 100644 --- a/test/browser/site.spec.mjs +++ b/test/browser/site.spec.mjs @@ -510,6 +510,11 @@ test("all built-ins can be edited and saved from readable production source", as .locator("[data-panel=sort-algorithm] .js-editor.ace_editor") .evaluate((element) => globalThis.ace.edit(element).getValue()); expect(source).toContain("AS."); + expect(source).toBe(source.trim()); + if (id === "bubble") { + expect(source).toContain("\nlet swapped;"); + expect(source).toContain("\n swapped = false;"); + } await page.locator("#save-algorithm-edit").click(); await expect(page.locator("#modal-sort")).toBeHidden(); await page.locator(`#sort-options [data-sort="${id}"]`).click();