mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-30 22:06:49 -06:00
* xtask: the test suite and clippy pass on Windows
Two Windows-only failures stopped `cargo xtask ci` before it got going on
a Windows checkout (CI runs the gate on Linux only, so neither showed):
- parity::tests::civil_dates built a SystemTime 115,740,740 days after
the epoch (year 318857). Windows' SystemTime ends in the year 30828, so
the addition panicked ("overflow when adding duration to `SystemTime`").
That case now checks `civil_from_days` on the day count, which is what
it was about, on every platform.
- stats.rs imported `walk` for a test that only exists on Unix, so the
import was unused on Windows and `clippy -D warnings` refused it. The
Unix test calls `super::walk`, as its neighbour calls `super::walk_inner`.
Checked on Windows 11 x64: `cargo test --workspace` and
`cargo clippy --workspace --all-targets -- -D warnings` both pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(web): persist validated browser panel layouts
CC-053: keep embedded floating, docked and hidden panels across reloads
through the existing host save cycle. Reject malformed/versioned records
atomically; native workspaces and drawings remain unchanged.
Validation: all seven cargo xtask ci gates passed (2558 pass, 0 fail,
1 ignored) on a2dd814 plus this exact change. Actual release Trunk bundle
and Edge floating/close/reload/reset/reload passed. Forced WebGL startup,
render and recovered layout passed; full edit cycle used default mode.
Dependency: original #2198 Windows test prerequisite. No #2226 dependency.
Revert this commit independently to stop using the optional storage key.
Upstream c3b8e7b adds nextest minimum configuration only; no runtime overlap.
---------
Co-authored-by: 2ez4gcx <108074836+2ez4gcx@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
102 lines
4.9 KiB
Markdown
102 lines
4.9 KiB
Markdown
# Hosting CADCraft for the web
|
|
|
|
`cadcraft-web-<version>.zip` (from the GitHub release, or `packaging/web/package.sh`) holds a
|
|
static site in `cadcraft-web-<version>/`:
|
|
|
|
| File | What it is |
|
|
|---|---|
|
|
| `index.html` | The page. It loads everything through relative URLs. |
|
|
| `cadcraft-web-<hash>.js` | wasm-bindgen glue (generated, ES module) |
|
|
| `cadcraft-web-<hash>_bg.wasm` | The app, about 13 MB, or 5 MB with compression |
|
|
| `_headers`, `.htaccess` | Sample header rules for Netlify/Cloudflare Pages and Apache |
|
|
|
|
There is no server-side code. Upload the folder's contents anywhere that serves static files.
|
|
|
|
## Any path works
|
|
|
|
All URLs in `index.html` are relative (`public_url = "./"` in `apps/cadcraft-web/Trunk.toml`),
|
|
so the site works at a domain root (`https://example.com/`), under a prefix
|
|
(`https://example.com/tools/cadcraft/`) and from a CDN bucket. The asset names carry a content
|
|
hash, so they can be cached forever. Only `index.html` needs revalidation.
|
|
|
|
## Required server settings
|
|
|
|
- **MIME type:** serve `.wasm` as `application/wasm`. Browsers refuse to stream-compile it under
|
|
any other type, and the app then loads slowly or not at all. Serve `.js` as `text/javascript`.
|
|
Most hosts already do both. For nginx, check that `mime.types` has `application/wasm wasm;`.
|
|
- **Compression:** turn on gzip or Brotli for `.wasm`, `.js` and `.html`. That takes the
|
|
download from about 13 MB to about 5 MB. You can also precompress (`brotli -k *.wasm`) and let
|
|
the server send `Content-Encoding: br`.
|
|
- **Caching:** `Cache-Control: public, max-age=31536000, immutable` on the hashed `.wasm` and
|
|
`.js` files, and `no-cache` on `index.html`.
|
|
- **HTTPS:** WebGPU (and the clipboard) only work in a secure context, which means `https://`
|
|
or `http://localhost`. Over plain HTTP elsewhere, the app falls back to WebGL2.
|
|
- **No special isolation headers:** CADCraft doesn't use `SharedArrayBuffer`, so it doesn't
|
|
need `Cross-Origin-Opener-Policy` or `Cross-Origin-Embedder-Policy`. If your site already sends
|
|
COEP `require-corp`, also send `Cross-Origin-Resource-Policy: same-origin` (or `cross-origin`
|
|
when the files live on a CDN) on the app's files.
|
|
|
|
nginx example:
|
|
|
|
```nginx
|
|
location /cadcraft/ {
|
|
types { application/wasm wasm; text/javascript js; text/html html; }
|
|
gzip on;
|
|
gzip_types application/wasm text/javascript text/html;
|
|
location ~* \.(wasm|js)$ { add_header Cache-Control "public, max-age=31536000, immutable"; }
|
|
location ~* index\.html$ { add_header Cache-Control "no-cache"; }
|
|
}
|
|
```
|
|
|
|
Local test: `python3 -m http.server 8765` inside the folder, then open http://localhost:8765/.
|
|
|
|
## Panel layout storage
|
|
|
|
The browser host saves docked, floating and hidden palette arrangements alongside interface
|
|
preferences in its local storage. Floating palettes remain embedded in the browser canvas;
|
|
they do not become native operating-system windows. Window > Reset Palettes restores the
|
|
default arrangement. This record contains panel placement and visibility, not drawing data.
|
|
|
|
The optional `cadcraft.panel-layout` record uses the shared docking layout version and is
|
|
limited to 64 KiB. Malformed, incompatible or invalid arrangements are ignored atomically,
|
|
leaving the startup defaults usable. Storage availability and autosave follow the browser
|
|
host's existing eframe persistence; clearing site data removes the saved layout.
|
|
|
|
## Embedding in a page (iframe)
|
|
|
|
```html
|
|
<iframe
|
|
src="https://example.com/cadcraft/"
|
|
title="CADCraft image editor"
|
|
style="width: 100%; height: 720px; border: 0;"
|
|
allow="fullscreen; clipboard-read; clipboard-write"
|
|
allowfullscreen>
|
|
</iframe>
|
|
```
|
|
|
|
- The app fills the iframe and follows its size, so size the iframe and not the app.
|
|
- Keyboard shortcuts go to the iframe after the user clicks into it, as with any embedded app.
|
|
- **Cross-origin embeds** work. Preferences are kept in the iframe's `localStorage`. Browsers
|
|
that partition or block third-party storage may forget them between visits, and the app
|
|
then starts with defaults.
|
|
- **Sandboxed iframes** need at least
|
|
`sandbox="allow-scripts allow-same-origin allow-downloads allow-popups"`. Without
|
|
`allow-same-origin` there's no storage. Without `allow-downloads`, Save and Export (browser
|
|
downloads) are blocked.
|
|
- Don't send `X-Frame-Options: DENY` or a `frame-ancestors` CSP that excludes the embedding page.
|
|
|
|
## Renderer selection and fallback flags
|
|
|
|
CADCraft renders with wgpu. It uses **WebGPU** when the browser has it and falls back to
|
|
**WebGL2** on its own. URL query flags override this, and they work on the iframe `src` too:
|
|
|
|
| Flag | Effect |
|
|
|---|---|
|
|
| *(none)* | WebGPU if available, otherwise WebGL2 |
|
|
| `?webgl` | Force the WebGL2 backend (useful when a WebGPU driver misbehaves) |
|
|
| `?cpu` | Force the CPU canvas path (slowest, most compatible) |
|
|
|
|
For example: `<iframe src="https://example.com/cadcraft/?webgl" ...>`.
|
|
|
|
A browser with neither WebGPU nor WebGL2 gets a message in place of the app.
|