8 lines
5.3 KiB
TypeScript
8 lines
5.3 KiB
TypeScript
import { createReverseEngineeringInspectRequest, REVERSEENGINEERING_INSPECT_FIXTURE, ReverseEngineeringInspectResponse } from "./reverseengineering-inspect-facade.js";
|
|
declare global { interface Window { __freecadReverseEngineeringInspectState: { stage: string; requestId: string | null; response: ReverseEngineeringInspectResponse | null; workerMessages: number } } }
|
|
const root = document.querySelector<HTMLDivElement>("#app")!; root.innerHTML = `<main><header><b>FC</b><span>FreeCAD 1.2 Web</span><strong>ReverseEngineering inventory</strong></header><section><aside><h2>Source</h2><p>Mod/ReverseEngineering/App/AppReverseEngineering.cpp</p><p>GUI-free App target</p><p>PCL-only APIs excluded</p></aside><main class="stage"><div class="mesh">RE</div><h1>Source inventory</h1><div id="status">Starting worker</div></main><aside><h2>Result</h2><dl><div><dt>Bindings</dt><dd id="bindings">-</dd></div><div><dt>Native types</dt><dd id="types">-</dd></div><div><dt>APIs</dt><dd id="apis">-</dd></div><div><dt>Request</dt><dd id="request">-</dd></div></dl><button id="run" disabled>Run</button><button id="error" disabled>Invalid</button><button id="reset" disabled>Reset</button></aside></section></main>`;
|
|
const style = document.createElement("style"); style.textContent = `:root{color-scheme:dark;font-family:system-ui;background:#111820;color:#e6edf3}*{box-sizing:border-box}body{margin:0;min-width:320px}header{display:flex;align-items:center;gap:18px;padding:16px 22px;background:#18242d;border-bottom:1px solid #33434e}header b{background:#3f9aa8;color:#081217;padding:7px 9px;border-radius:5px}header strong{margin-left:auto}section{display:grid;grid-template-columns:270px 1fr 300px;min-height:calc(100vh - 58px)}aside{padding:22px;background:#18242d;border-right:1px solid #33434e}section>aside:last-child{border-left:1px solid #33434e;border-right:0}h2{font-size:12px;color:#a4bdc6;text-transform:uppercase;letter-spacing:.08em}aside p{font-size:13px;line-height:1.5;color:#b4c5cc}.stage{display:flex;flex-direction:column;justify-content:center;align-items:center;background:#0e141a}.mesh{width:128px;height:128px;display:grid;place-items:center;border:1px solid #67b4c3;color:#9ee3e7;font-weight:700;font-size:34px;letter-spacing:.08em}#status{margin-top:22px;color:#a4bdc6}#status[data-level=error]{color:#ff9d9d}#status[data-level=ok]{color:#9ce0bd}dl{margin:0}dl div{display:flex;justify-content:space-between;gap:16px;border-bottom:1px solid #33434e;padding:11px 0}dd{margin:0;max-width:190px;text-align:right;overflow-wrap:anywhere}button{margin:18px 4px 0;padding:8px 12px;background:#22323d;border:1px solid #50616b;border-radius:4px;color:#e6edf3}button:disabled{opacity:.45}@media(max-width:820px){section{grid-template-columns:1fr}section>aside:first-child{display:none}.stage{min-height:58vh}section>aside:last-child{border-top:1px solid #33434e}}`; document.head.append(style);
|
|
const status = document.querySelector<HTMLElement>("#status")!, bindings = document.querySelector<HTMLElement>("#bindings")!, types = document.querySelector<HTMLElement>("#types")!, apis = document.querySelector<HTMLElement>("#apis")!, request = document.querySelector<HTMLElement>("#request")!, run = document.querySelector<HTMLButtonElement>("#run")!, error = document.querySelector<HTMLButtonElement>("#error")!, reset = document.querySelector<HTMLButtonElement>("#reset")!, worker = new Worker(new URL("./reverseengineering-inspect.worker.ts", import.meta.url), { type: "module" }); let sequence = 0; window.__freecadReverseEngineeringInspectState = { stage: "starting", requestId: null, response: null, workerMessages: 0 }; const setStatus = (value: string, level: "normal" | "ok" | "error" = "normal") => { status.textContent = value; status.dataset.level = level; };
|
|
worker.onmessage = (event: MessageEvent<ReverseEngineeringInspectResponse | { kind: "ready"; action: string } | { kind: "reset"; requestId: string }>) => { const state = window.__freecadReverseEngineeringInspectState; state.workerMessages += 1; const message = event.data; if (message.kind === "ready") { state.stage = "ready"; run.disabled = false; error.disabled = false; reset.disabled = false; setStatus("Worker ready", "ok"); return; } if (message.kind === "reset") { state.stage = "reset"; state.requestId = message.requestId; state.response = null; setStatus("State reset", "ok"); return; } state.response = message; state.requestId = message.requestId; request.textContent = message.requestId; if (message.kind === "error") { state.stage = message.error.code === "revision_mismatch" ? "expected-error" : "error"; setStatus(message.error.code, state.stage === "expected-error" ? "ok" : "error"); return; } state.stage = "success"; bindings.textContent = String(message.result.pythonBindingCount); types.textContent = String(message.result.registeredTypeCount); apis.textContent = message.result.pythonApiNames; setStatus("Inventory complete", "ok"); };
|
|
worker.onerror = event => setStatus(`Worker error: ${event.message}`, "error"); run.onclick = () => worker.postMessage(createReverseEngineeringInspectRequest(`rev-inspect-chrome-${++sequence}`)); error.onclick = () => worker.postMessage(createReverseEngineeringInspectRequest(`rev-inspect-error-${++sequence}`, { ...REVERSEENGINEERING_INSPECT_FIXTURE, sourceEntry: "src/Mod/ReverseEngineering/App/Missing.cpp" })); reset.onclick = () => worker.postMessage({ kind: "reset", requestId: `rev-inspect-reset-${++sequence}` });
|