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:
parent
ac71afaf55
commit
c21bcd2e13
4 changed files with 18 additions and 8 deletions
|
|
@ -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.
|
// 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.
|
// Never raise a number; never add a locale that is already complete.
|
||||||
const DEBT = {
|
const DEBT = {
|
||||||
// 2026-10-03, the Share menu's 10 new share.json keys (shareable pages P3), English only for now: the Driver
|
// 2026-10-03, the Share menu's 10 new share.json keys (shareable pages P3): localization is English-only for now.
|
||||||
// parked localization ("just English for now"). tStatic falls back to the English text, so these locales show
|
// tStatic falls back to the English text, so these locales show English until the translations arrive;
|
||||||
// English until the translations arrive; lower each to 0 then, and empty the map again.
|
// 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,
|
ar: 10, de: 10, es: 10, fr: 10, hi: 10, it: 10, pt: 10, ro: 10, ru: 10, zh: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@ if (!m) {
|
||||||
if (fn) {
|
if (fn) {
|
||||||
const body = code.match(new RegExp('function\\s+' + fn[1] + '\\s*\\(\\)\\s*\\{([\\s\\S]*?)\\n\\}'))
|
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
|
// 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)) || '')
|
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.`)
|
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.`)
|
else if (!rets.length) fails.push(`${fn[1]}() returns no named-area resolution, so this gate would pass blind.`)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ function place() {
|
||||||
// ★ THE BLOCK THAT CONTAINS IT IS MEASURED, NOT ASSUMED. The menu is position:absolute, so its coordinates are
|
// ★ 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
|
// 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
|
// 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.
|
// the containing block's own (its padding edge, scrolled), whatever element that turns out to be.
|
||||||
function placeBeside(tb) {
|
function placeBeside(tb) {
|
||||||
const vw = document.documentElement.clientWidth || window.innerWidth || 1024
|
const vw = document.documentElement.clientWidth || window.innerWidth || 1024
|
||||||
|
|
|
||||||
|
|
@ -411,8 +411,17 @@ function pageOwner() {
|
||||||
}
|
}
|
||||||
return false
|
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() {
|
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
|
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
|
★ 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
|
`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
|
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
|
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.
|
MapControlMenu resolves where the menu lives and where it goes when it OPENS, with layout known.
|
||||||
*/
|
*/
|
||||||
function bindAnchor(el) {
|
function bindAnchor(el) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue