From a85ddb9541246431b16d46ad61c812646fafc549 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Wed, 30 Sep 2026 22:04:50 +0000 Subject: [PATCH] UPG-100: the map init returns quietly when its pane is released while the engine script or stylesheet loads (both shells destroy heavy panes on deactivate), instead of throwing "'container' must be a String or HTMLElement"; the same guard library/composables/useMapInstance.js keeps after every await --- plugin-designs/my-upg-100-list/upg-100-list.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugin-designs/my-upg-100-list/upg-100-list.vue b/plugin-designs/my-upg-100-list/upg-100-list.vue index a8807637e..af5af4fcc 100644 --- a/plugin-designs/my-upg-100-list/upg-100-list.vue +++ b/plugin-designs/my-upg-100-list/upg-100-list.vue @@ -2402,6 +2402,11 @@ onMounted(async () => { bootstrapLegend() // Load the engine the PROVIDER selects, not the one this file used to assume. try { await ensureEngineScript(upgProvider) } catch (_) { /* fall through to the !gl notice below */ } + // ★ THE PANE MAY BE GONE BY NOW. Both shells (Posterverse, the Research Gallery) DESTROY a heavy pane on + // deactivate, so a switch while the engine loads nulls mapEl, and `new gl.Map({ container: null })` threw + // "Invalid type: 'container' must be a String or HTMLElement". An unmounted pane is normal, so return silently: + // the same guard library/composables/useMapInstance.js keeps after every await (check:map-unmount-mid-init). + if (!mapEl.value) return // ★ NEVER SWITCH ENGINES SILENTLY. This read `engineGlobal(upgProvider) || window.mapboxgl`, and that // fallback can ONLY fire when the requested provider is 'maplibre' and MapLibre failed to load — // engineGlobal already resolves mapbox's own global for the mapbox case (useMapInstance.js:115 falls back @@ -2493,6 +2498,7 @@ onMounted(async () => { const css = engineStylesheetUrl(upgProvider) if (css) await ensureEngineCSS(mapEl.value, css) } catch (_) { /* a stylesheet must never stop the map painting */ } + if (!mapEl.value) return // gone while the stylesheet loaded (see the guard after ensureEngineScript) // The legacy shadow-root injection stays ONLY as the belt to that braces: ensureEngineCSS returns early // for light DOM on the assumption a wrapper exists, and a partner embedding the custom element // directly may have no wrapper at all. Harmless when ensureEngineCSS already added the same href — both