upg-100's first click: onLegendSelect was bailing on an unready layer, and the request was thrown away
rega's re-shoot on main27eed341answered it in one run, because the apply now reports its own verdict. Timeline, ms from navigation: t=2958 click 'Show Northwest India on the map' t=3015 select-zone = "asia-india-rajasthan" written on the map pane t=4887 data-select-zone-state = "applied-but-no-selection" t=4900 the same pair AGAIN, 13 ms later, still no selection t=5308 the doxa:select-zone listener first appears So delivery was fine, the id was right, the node WAS found, onLegendSelect WAS called — and the selection did not hold, twice. THE CAUSE is onLegendSelect's own first line: if (!map || !map.getLayer('tapestry-fill')) return It returns silently when the map's tapestry layer is not up yet, so selectedKey is never set. At t=4.9s that layer did not exist. Both applies came from watch([legendNodes, mapRef]), which is why they landed before the listener did. So the readiness signal was never legendNodes and never mapRef. It is THE LAYER, and I had guessed at the other two in turn. This is the THIRD layer of one defect — apply once against unready state and discard — and each layer hid the next because every failure was silent. Two changes, both from the measurement rather than a theory: 1. applySelectZone RETAINS the request when the effect did not take. It used to clear _pendingZoneId right after calling onLegendSelect, treating "called" as "done"; now a state of applied-but-no-selection keeps the id outstanding. 2. ensureLayers() drains it. That function adds the tapestry source and both layers, so it is the exact moment onLegendSelect can hold a selection. Coverage is complete either way round: if ensureLayers runs first the layer already exists and the ordinary apply succeeds; if it runs later, the retained request drains. A click after everything is up still goes through the attribute observer. Branch was RESET onto main27eed341and carries this one commit only — the handoff lesson from last time: a merged branch's tree holds my stale copies of everyone else's files, so replaying it (the sane thing for a recipient) reverts their work. Source only; my-upg-100-list needs a rebuild.
This commit is contained in:
parent
af436bff6f
commit
3345779bdb
1 changed files with 19 additions and 2 deletions
|
|
@ -626,6 +626,16 @@ function ensureLayers() {
|
|||
// F2-D2: brighter, thicker outline gives contrast on dark without washing out light.
|
||||
paint: { 'line-color': matchColorExpr, 'line-width': 1.2, 'line-opacity': 0.9 },
|
||||
})
|
||||
|
||||
// ★ THE REAL READINESS SIGNAL. onLegendSelect() returns early unless map.getLayer('tapestry-fill')
|
||||
// exists, so a "Show on map" request that arrives before this function runs cannot hold a
|
||||
// selection however correctly it was delivered. This is the third layer of the same defect --
|
||||
// apply once against unready state, then discard -- and this is the point where the state is
|
||||
// finally ready. Drains any request retained by applySelectZone().
|
||||
if (_pendingZoneId) {
|
||||
const id = _pendingZoneId
|
||||
nextTick(() => { if (_pendingZoneId === id) applySelectZone(id) })
|
||||
}
|
||||
}
|
||||
|
||||
// ── 09b shift-select tool: selection highlight layers (D-2) ──────────────────
|
||||
|
|
@ -1606,14 +1616,21 @@ function applySelectZone(zoneId) {
|
|||
const node = findLegendNode(legendNodes.value, zoneId);
|
||||
if (!node) { _pendingZoneId = zoneId; _markZoneState('unresolved', zoneId); return false; } // not ready -- REMEMBER it
|
||||
onLegendSelect(node);
|
||||
_pendingZoneId = undefined;
|
||||
// selectedKey (:163, "currently isolated zoneKey (or null)") is this component's own record of the
|
||||
// isolation, so 'applied-but-no-selection' means the path was REACHED and its EFFECT lost -- a
|
||||
// different bug from delivery, and the one rega's timeline points at.
|
||||
// ★ I first wrote selectedZoneKey here, which does not exist; the try/catch would have swallowed
|
||||
// the ReferenceError and reported 'applied' every time. A diagnostic that cannot report failure is
|
||||
// worse than none. main's check:no-free-identifiers (6b05f513) now catches this class.
|
||||
_markZoneState(!selectedKey.value ? 'applied-but-no-selection' : 'applied', zoneId);
|
||||
// ★ IF THE EFFECT DID NOT TAKE, THE REQUEST IS STILL OUTSTANDING. rega's re-shoot on 27eed341
|
||||
// read exactly this state twice, 13 ms apart, with the right id -- so the node WAS found and
|
||||
// onLegendSelect WAS called, and the selection still did not hold. The cause is onLegendSelect's
|
||||
// own first line: `if (!map || !map.getLayer('tapestry-fill')) return`. It bails silently when the
|
||||
// map's tapestry layer is not up, which at t=4.9s it was not. So the readiness signal was never
|
||||
// legendNodes or mapRef -- it is THE LAYER, and the old code cleared _pendingZoneId here as though
|
||||
// the work were done. Keeping it means ensureLayers() can drain it the moment the layer exists.
|
||||
if (!selectedKey.value) { _pendingZoneId = zoneId; _markZoneState('applied-but-no-selection', zoneId); return false; }
|
||||
_markZoneState('applied', zoneId);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue