Share this page never copies a token; neutral wording in the P3 comments

pageLink() drops ?tk= from the page's address: a leaf page reads a token from
there and leaves it in place, so pressing Share would have sent it. The URL is
rewritten only when tk is present; every other link is the address as it stands.
The comments name the page, not who measured it, and no longer cite a request.
check:map-menu-anchor strips a same-line comment before testing each return, so
a fallback named only in a comment no longer passes.
This commit is contained in:
Doxa Maps 2026-10-03 06:18:57 +00:00
parent ac71afaf55
commit c21bcd2e13
4 changed files with 18 additions and 8 deletions

View file

@ -68,9 +68,9 @@ const areas = readdirSync(join(ROOT, 'en')).filter((f) => f.endsWith('.json'))
// translations, add the locale here with its count and lower it as they arrive.
// Never raise a number; never add a locale that is already complete.
const DEBT = {
// 2026-10-03, the Share menu's 10 new share.json keys (shareable pages P3), English only for now: the Driver
// parked localization ("just English for now"). tStatic falls back to the English text, so these locales show
// English until the translations arrive; lower each to 0 then, and empty the map again.
// 2026-10-03, the Share menu's 10 new share.json keys (shareable pages P3): localization is English-only for now.
// tStatic falls back to the English text, so these locales show English until the translations arrive;
// lower each to 0 then, and empty the map again.
ar: 10, de: 10, es: 10, fr: 10, hi: 10, it: 10, pt: 10, ro: 10, ru: 10, zh: 10,
}

View file

@ -46,7 +46,8 @@ if (!m) {
if (fn) {
const body = code.match(new RegExp('function\\s+' + fn[1] + '\\s*\\(\\)\\s*\\{([\\s\\S]*?)\\n\\}'))
// every return that resolves a named area must carry its structural fallback on the SAME expression
const rets = body ? [...body[1].matchAll(/return\s+([^\n]*closest\([^\n]*)/g)].map((r) => r[1]) : []
// a same-line comment is not a fallback: strip `//…` before testing each return
const rets = body ? [...body[1].matchAll(/return\s+([^\n]*closest\([^\n]*)/g)].map((r) => r[1].replace(/\s*\/\/.*$/, '')) : []
expr = rets.length && rets.every((r) => /offsetParent|parentElement|document\.body/.test(r)) ? rets.join(' ;; ') : (rets.find((r) => !/offsetParent|parentElement|document\.body/.test(r)) || '')
if (!body) fails.push(`the area resolution calls ${fn[1]}(), and this gate cannot find that function to read it.`)
else if (!rets.length) fails.push(`${fn[1]}() returns no named-area resolution, so this gate would pass blind.`)

View file

@ -129,7 +129,7 @@ function place() {
// ★ THE BLOCK THAT CONTAINS IT IS MEASURED, NOT ASSUMED. The menu is position:absolute, so its coordinates are
// relative to its containing block, which the HOST's markup decides: an unpositioned wrapper hands it to the
// header above. Measuring against one element and positioning against another is what sent the header menu far
// to the left (upg100, 2026-10-03). So the target point is computed in viewport coordinates and converted into
// to the left (the UPG-100 list page, 2026-10-03). So the target point is computed in viewport coordinates and converted into
// the containing block's own (its padding edge, scrolled), whatever element that turns out to be.
function placeBeside(tb) {
const vw = document.documentElement.clientWidth || window.innerWidth || 1024

View file

@ -411,8 +411,17 @@ function pageOwner() {
}
return false
}
// A leaf page reads a token from ?tk= and leaves it in its address, so the page link drops it: a reader must
// never send a credential by pressing Share. The URL is rewritten only when tk is there, so every other link is
// the address exactly as it stands.
function pageLink() {
try { if (pageOwner() && window.location.href) return window.location.href } catch { /* no window */ }
try {
if (pageOwner() && window.location.href) {
const u = new URL(window.location.href)
if (u.searchParams.has('tk')) { u.searchParams.delete('tk'); return u.href }
return window.location.href
}
} catch { /* no window */ }
return shareUrl.value
}
@ -518,9 +527,9 @@ const hasOwnAnchor = !providedToolbar
★ THE ANCHOR IS THE BUTTON, AND NOTHING IS DECIDED AT RENDER TIME (shareable pages P3). This used to tag
`el.offsetParent || el.parentElement` as the menu's area DURING RENDER (a function ref, so it ran before
MapControlMenu latched its area). Before layout offsetParent is null, so the tag fell on the button's
immediate parent: in a header with a narrow, unpositioned wrapper (upg100 measured .hdr-btns) the menu
immediate parent: in a header with a narrow, unpositioned wrapper (measured on the UPG-100 list page: .hdr-btns) the menu
measured against that wrapper, clamped to its 200px floor, and was positioned against the header above
it: far to the left, and narrow (the Driver's report, 2026-10-03). Now the button only names itself;
it: far to the left, and narrow (reported 2026-10-03). Now the button only names itself;
MapControlMenu resolves where the menu lives and where it goes when it OPENS, with layout known.
*/
function bindAnchor(el) {