P2b: a refused tab claim (a hole) keeps the rest of its announcement (studio's 5B note); 53 poisons

This commit is contained in:
Doxa Maps 2026-10-03 08:00:32 +00:00
parent 00f7d349eb
commit 728970b2bf
2 changed files with 13 additions and 4 deletions

View file

@ -300,6 +300,15 @@ async function arms({ va, sv, counts, pw, src }, { skipF = false } = {}) {
if (b.at() !== '/?tab=posterverse__posterverse' || b.writes.push !== pushes + 1) fails.push(`H: the owner's tab change did not drop every subtab segment: ${b.at()}`)
off()
}
{
// a tab claim that is refused (a hole) must not take the rest of its announcement with it
const b = browser('https://x.test/?tab=doxa-maps-spa__doxa-maps-spa')
const el = new EventTarget()
const off = va.ownAddress(el, () => 'app')
el.dispatchEvent(new CustomEvent(va.VIEW_EVENT, { bubbles: true, composed: true, detail: { changes: { tab: 'x', place: 'benin' }, push: false, depth: 3 } }))
if (b.q().get('place') !== 'benin' || b.q().get('subtab')) fails.push(`H: a refused tab claim dropped the pane/place announced with it: ${b.at()}`)
off()
}
// ── F. pane-wrapper's address, on a simulated column (the slow arm: it waits out the scroll debounce) ──
globalThis.document = { createElement: () => new FakeEl() }
@ -527,8 +536,9 @@ if (process.argv.includes('--self-test')) {
// P2b: nested shells at any depth
['a nested shell\'s tab dropped (the P2 behaviour)', { ...real, va: await vaVariant(' if (tab) {', ' if (false) {') }, /^H: a depth-1 first-paint claim/],
['a depth-2 claim that ignores its depth (overwrites segment 1)', { ...real, va: await vaVariant('path.slice(0, depth - 1).concat(tab)', '[tab]') }, /^H: depth 2 is not the second segment|^H: a depth-2 claim with no depth-1/],
['a hole that is not refused', { ...real, va: await vaVariant('if (path.length < depth - 1 || path[depth - 1] === tab) return', 'if (path[depth - 1] === tab) return') }, /^H: a depth-2 claim with no depth-1 segment/],
['the same tab claimed again is not a no-op', { ...real, va: await vaVariant('if (path.length < depth - 1 || path[depth - 1] === tab) return', 'if (path.length < depth - 1) return') }, /^H: the same tab claimed again dropped deeper/],
['a hole that is not refused', { ...real, va: await vaVariant('if (path.length >= depth - 1 && path[depth - 1] !== tab)', 'if (path[depth - 1] !== tab)') }, /^H: a depth-2 claim with no depth-1 segment/],
['a refused tab claim that drops the rest of its announcement', { ...real, va: await vaVariant('if (path.length >= depth - 1 && path[depth - 1] !== tab) changes.subtab', 'if (path.length < depth - 1 || path[depth - 1] === tab) return; changes.subtab') }, /^H: a refused tab claim dropped/],
['the same tab claimed again is not a no-op', { ...real, va: await vaVariant('if (path.length >= depth - 1 && path[depth - 1] !== tab)', 'if (path.length >= depth - 1)') }, /^H: the same tab claimed again dropped deeper/],
['a subtab change that keeps pane and place', { ...real, va: await vaVariant('const LEVEL = { tab: 0, subtab: 1, pane: 2, place: 2 }', 'const LEVEL = { tab: 0, subtab: 2, pane: 2, place: 2 }') }, /^A: a subtab change drops pane and place|^H: depth 2 is not the second segment, or the depth-1 change kept/],
["an owner's tab change that keeps subtab", { ...real, va: await vaVariant('const LEVEL = { tab: 0, subtab: 1, pane: 2, place: 2 }', 'const LEVEL = { tab: 0, subtab: 0, pane: 2, place: 2 }') }, /^A: a tab change drops subtab|^H: the owner's tab change did not drop/],
['a subtab path longer than 6', { ...real, va: await vaVariant('return p.length <= MAX_DEPTH && p.every', 'return p.length <= 99 && p.every') }, /^A: a subtab path reads segment by segment/],

View file

@ -151,8 +151,7 @@ export function ownAddress(el, getOwner) {
if (tab) {
const depth = Math.min(MAX_DEPTH, Math.max(1, Math.floor(e.detail.depth) || 1))
const path = readViewKeys(location.search).subtab.split('.').filter(Boolean)
if (path.length < depth - 1 || path[depth - 1] === tab) return
changes.subtab = path.slice(0, depth - 1).concat(tab).join('.')
if (path.length >= depth - 1 && path[depth - 1] !== tab) changes.subtab = path.slice(0, depth - 1).concat(tab).join('.')
}
if (Object.keys(changes).length) writeViewKeys(changes, { owner, el, push: e.detail.push !== false })
}