The real reason Mesh:Tool ignored the theme: set_darkmode() runs inside
restore_space(), which only fires on the non-CMMS boot path
(motoClient 'ready' -> restore_space). The CMMS path
(motoClient 'ready' -> cmms_load_from_url) never called it, so #app never
got the .dark class and the #app:not(.dark) light CSS always won ->
white, regardless of theme. Now cmms_load_from_url()'s finally block
calls set_darkmode(config.dark ?? true).
Upstream 913977ec hard-wired set_darkmode() to dark and rewrote
web/mesh/index.css to be dark-only. Restored the dark-conditional body of
set_darkmode() from 913977ec^; the boot call now takes its arg from
MESH_TOOL_CONFIG.dark (parsed from a new cmms_dark=1|0 query param that
public/mesh-edit.php sets from theme_is_dark()), defaulting to dark when
absent so the freestanding app is unchanged. Added a scoped
#app:not(.dark) light-chrome layer to index.css (additive; never matches
in the always-dark freestanding app).
restoreOrCreate() revives whatever document this browser last had open in
IndexedDB - the opposite of what a job-scoped CMMS launch wants (load
this exact file, not whatever was last open in this browser, per the
comment already above in init()). It only looked fixed on a browser with
no prior Mesh:Tool history (falls through to a blank "Untitled" doc in
that case) - any browser with real history would have shown a stale
name instead of the real filename.
document_new({name}) is what actually creates a fresh document with a
given name (mirrors what File > New does), so this uses that instead,
and drops the now-redundant separate set_doc_name() call since
document_new() already does that itself.
restore_space() (the normal boot path, restoring a previous IndexedDB
session) is intentionally skipped for a CMMS-scoped launch - but its
finalization tail (hide the loading curtain via boot_done(), enable
handles, publish app_ready) only ever ran inside restore_space() itself.
Skipping it meant the curtain never went away even after cmms_load_from_url
fetched and loaded the file successfully underneath it. app_ready
subscribers never fired either - mesh/history.js's undo-tracking enable,
mesh/build.js's doc-name label - a second, less visible bug from the same
cause.
Wrapped in try/finally so this always runs, even on a failed fetch -
a file that can't load shouldn't leave the user stuck behind the
curtain either. Also calls api.document.restoreOrCreate() first, since
restore_space() always does that before any file-load in normal use.
A parent iframe cannot inject window.MESH_TOOL_CONFIG into this app's
window before init() runs - by the time the iframe's load event fires
(the only cross-frame signal available for a same-origin page this app's
own server generates, not the CMMS), init() has already executed and
already decided to call restore_space() instead. Query params are read
synchronously during init() itself, before the existing 'hide url params'
cleanup strips them - self.MESH_TOOL_CONFIG is still set from them so
util.download() (src/mesh/build.js) has one stable place to read from.
Additive only, gated entirely on window.MESH_TOOL_CONFIG being present (set
by the CMMS's public/mesh-edit.php host page, absent everywhere else -
standalone use is unaffected).
- src/main/mesh.js: cmms_load_from_url() fetches bytes from the
host-provided loadUrl and feeds them through the existing load_files()
path (same one drag-and-drop and the Import button use) - skips
restore_space() when embedded, since job-scoped launch means "load this
exact file", not whatever was last open in this browser's IndexedDB.
- src/mesh/build.js: util.download() calls cmms_save_to_host() instead of
triggering a browser download when embedded - POSTs to the same
job/manufacturing_project-scoped save endpoint pattern as the CAD editor
fork's post_bytes_to_host().