diff --git a/apps/desktop/src-tauri/src/main.rs b/apps/desktop/src-tauri/src/main.rs index 4af64d55..8e2bbe87 100644 --- a/apps/desktop/src-tauri/src/main.rs +++ b/apps/desktop/src-tauri/src/main.rs @@ -38,8 +38,10 @@ fn application_url(url: &tauri::Url) -> bool { fn preview_url(url: &tauri::Url) -> bool { // Embedded PDF/HTML previews use blobs minted by the application itself. - url.scheme() == "blob" - && tauri::Url::parse(url.path()).is_ok_and(|origin| application_url(&origin)) + // HTML previews with JavaScript load the static oxbit-preview shell. + url.scheme() == "oxbit-preview" + || url.scheme() == "blob" + && tauri::Url::parse(url.path()).is_ok_and(|origin| application_url(&origin)) } #[cfg(test)] @@ -47,10 +49,15 @@ mod preview_tests { use super::preview_url; #[test] - fn only_application_blob_urls_can_navigate() { + fn only_application_previews_can_navigate() { assert!(preview_url( &"blob:tauri://localhost/preview".parse().unwrap() )); + assert!(preview_url( + &"oxbit-preview://localhost/preview-shell.html" + .parse() + .unwrap() + )); for url in [ "blob:https://example.com/preview", "blob:tauri://other/preview", diff --git a/tests/desktop/workbench.e2e.mjs b/tests/desktop/workbench.e2e.mjs index da82cffe..4c0fe6e9 100644 --- a/tests/desktop/workbench.e2e.mjs +++ b/tests/desktop/workbench.e2e.mjs @@ -215,6 +215,32 @@ describe("Oxbit native workbench", () => { assert.match(JSON.stringify(result.search), /hello.ts/); assert.equal(result.clipboard, "Oxbit native clipboard café"); }); + it("runs HTML preview JavaScript through the oxbit-preview shell in a trusted folder", async () => { + await browser.execute(async () => { + const { filesystem, runtime, workbench } = globalThis.__oxbit; + await runtime.trust(true); + addEventListener("message", (event) => { + if (event.data?.type === "native-preview-script") + globalThis.__nativePreviewScript = event.data.text; + }); + await filesystem.write( + "preview.html", + '

Static

', + { expectedRevision: null }, + ); + await workbench.openFile("preview.html", { preview: false }); + await workbench.run("preview.html"); + }); + await browser.waitUntil( + () => browser.execute(() => globalThis.__nativePreviewScript), + { timeout: 20000, timeoutMsg: "The preview page's script did not run" }, + ); + assert.equal( + await browser.execute(() => globalThis.__nativePreviewScript), + "Script ran", + ); + assert.equal(await $(".html-preview-scripts").isExisting(), false); + }); it("completes TypeScript, cancels a real task, and stages a Git file in the native host", async () => { const completion = await browser.execute(async () => { const z = globalThis.__oxbit;