diff --git a/frontend/index.html b/frontend/index.html
index f2ca0abd..bb5ec3e1 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -22,6 +22,58 @@
+
-
+
+
+
+

+
+
XSLT Playground
+
Loading the editor...
+
+
+
+
+
+
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 8fb9d774..34e86337 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -298,6 +298,7 @@ export default function App() {
typeof window !== "undefined" ? window.innerWidth : 0,
);
const [widgetsReady, setWidgetsReady] = useState(false);
+ const [autoRunReady, setAutoRunReady] = useState(false);
const ethicalSlotRef = useRef(null);
const isLocalhost =
typeof window !== "undefined" &&
@@ -343,6 +344,18 @@ export default function App() {
return () => cancelIdle?.();
}, []);
+ useEffect(() => {
+ const enable = () => setAutoRunReady(true);
+ const cancelIdle = runWhenIdle(enable, 2000);
+ window.addEventListener("pointerdown", enable, { once: true });
+ window.addEventListener("keydown", enable, { once: true });
+ return () => {
+ cancelIdle?.();
+ window.removeEventListener("pointerdown", enable);
+ window.removeEventListener("keydown", enable);
+ };
+ }, []);
+
// Persist workspace on change
useEffect(() => {
try {
@@ -1012,14 +1025,14 @@ export default function App() {
}, 500);
useEffect(() => {
- if (!activeTab) return;
+ if (!activeTab || !autoRunReady) return;
runTransform(
injectParamBlock(activeTab.xslt, activeTab.params),
activeTab.version,
activeTab.params,
activeTab.id,
);
- }, [activeTab, traceEnabled]);
+ }, [activeTab, traceEnabled, autoRunReady]);
useEffect(() => {
syncParams();
diff --git a/frontend/src/App.test.jsx b/frontend/src/App.test.jsx
index e84d57a1..449cf243 100644
--- a/frontend/src/App.test.jsx
+++ b/frontend/src/App.test.jsx
@@ -1,4 +1,4 @@
-import { render, screen, waitFor, cleanup } from "@testing-library/react";
+import { render, screen, waitFor, cleanup, fireEvent } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import App from "./App";
@@ -47,6 +47,7 @@ afterEach(() => {
describe("App bootstrap", () => {
it("renders without crashing", async () => {
render();
+ fireEvent.pointerDown(window);
await waitFor(() => expect(fetch).toHaveBeenCalled());
expect(screen.getByText(/xsltplayground\.com/i)).toBeInTheDocument();
});