1
0
mirror of https://github.com/alexandrev/xslt-lab.git synced 2026-09-18 19:43:16 +00:00

fix pagedev report

This commit is contained in:
2026-01-18 16:46:07 +01:00
parent 65dcfc7b10
commit 5e5619cc3b
3 changed files with 85 additions and 4 deletions
+68 -1
View File
@@ -22,6 +22,58 @@
<meta property="og:image" content="/logo.svg" />
<link rel="canonical" href="https://xsltplayground.com/" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
background: #f5f5f5;
color: #21426c;
}
.app-shell {
min-height: 100vh;
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1.25rem;
}
.shell-top {
display: flex;
align-items: center;
gap: 0.75rem;
}
.shell-logo {
width: 32px;
height: 32px;
}
.shell-title {
font-weight: 700;
font-size: 1.1rem;
}
.shell-subtitle {
font-size: 0.9rem;
color: #536084;
}
.shell-grid {
display: grid;
gap: 0.75rem;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.shell-pane,
.shell-bar {
border-radius: 12px;
background: linear-gradient(90deg, #eef3ff, #f8fbff, #eef3ff);
background-size: 200% 100%;
animation: shell-shimmer 1.6s ease-in-out infinite;
min-height: 160px;
}
.shell-bar {
min-height: 48px;
}
@keyframes shell-shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
</style>
<script type="module" src="/env.js"></script>
<script>
const loadAdsense = () => {
@@ -52,7 +104,22 @@
</script>
</head>
<body>
<div id="root"></div>
<div id="root">
<div class="app-shell" role="status" aria-live="polite">
<div class="shell-top">
<img src="/logo.svg" alt="XSLT Playground logo" class="shell-logo" />
<div>
<div class="shell-title">XSLT Playground</div>
<div class="shell-subtitle">Loading the editor...</div>
</div>
</div>
<div class="shell-grid">
<div class="shell-pane"></div>
<div class="shell-pane"></div>
</div>
<div class="shell-bar"></div>
</div>
</div>
<script type="module" src="/src/main.jsx"></script>
</body>
+15 -2
View File
@@ -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();
+2 -1
View File
@@ -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(<App />);
fireEvent.pointerDown(window);
await waitFor(() => expect(fetch).toHaveBeenCalled());
expect(screen.getByText(/xsltplayground\.com/i)).toBeInTheDocument();
});