UPG-100: delete the orphaned copy-to-clipboard path and its red gate
fc93847bb ("Batch selection builds a packet, instead of recolouring regions")
replaced copy-to-clipboard with packet-building and left four pieces behind: the
button's handler, its execCommand fallback, the window global they wrote, and the
gate check that read it. This removes all four.
copySelection had exactly ONE reference in the file — its own definition — and
legacyCopy was called only from it, so both were unreachable. The minifier was
already dropping them: __UPG_LAST_CLIPBOARD__, which copySelection set
unconditionally, appears 0 times in the built bundle.
THE GATE HALF MATTERED MORE. visual-gate check (15) asserted the Copy payload,
guarding on .upg-hud-btn.copy existing — a button that no longer exists. But the
guard skipped only the MEASUREMENT: copyOk was initialised false and check() ran
unconditionally, so it reported FAIL ("no .upg-hud-btn.copy in HUD") on every run
since the button went. A permanently red assertion for a deliberately deleted
feature teaches readers to ignore red, which is worse than no check at all.
formatClipboard SURVIVES — 3 references, and one is live: __UPG_SELECT__
.clipboardText, the headless probe surface the gate still uses. Deleting the
"clipboard code" wholesale would have broken it.
Also corrects the D-8 comment, which still named "Copy + Clear" as the HUD
buttons; they are Prayer List / Poster Map / Clear.
VERIFIED BY THE BUILD NOT MOVING: rebuilt after deleting 43 lines of source and
the bundle is byte-identical to its parent (sha 3dda630d5cf5e647, 992356 bytes).
That is the test of the claim — if the output had changed, the code was not dead.
This commit is contained in:
parent
02230d3eb8
commit
4dd4d7328e
2 changed files with 16 additions and 77 deletions
|
|
@ -1046,36 +1046,15 @@ async function main() {
|
|||
&& colorState.fill.toLowerCase().includes('0072b2') && colorState.rendered > 0,
|
||||
colorState.err || `swatchClicked=${swatchClicked} handleColor=${colorState.handleColor} fill=${colorState.fill} opacity=${colorState.opacity} renderedSelFeatures=${colorState.rendered}`);
|
||||
|
||||
// ── (15) toolA §1(d) + R1.1 (h): Copy → names + total + trailing "· #hex" ──
|
||||
// The Copy button click is a REAL Playwright click (user gesture → the live
|
||||
// navigator.clipboard path runs; its success/fallback is reported via the
|
||||
// flash label). The payload assertion reads __UPG_LAST_CLIPBOARD__ — the
|
||||
// exact string the handler wrote (headless clipboard READ permission is not
|
||||
// grantable in Firefox, so the write-side record is the assertable surface).
|
||||
let copied = null;
|
||||
const copyBtn = page.locator(`${EL} .upg-hud-btn.copy`);
|
||||
if (await copyBtn.count()) {
|
||||
await copyBtn.first().click().catch(() => {});
|
||||
await page.waitForTimeout(600);
|
||||
copied = await page.evaluate((elName) => {
|
||||
const host = document.querySelector(elName);
|
||||
const root = host && host.shadowRoot ? host.shadowRoot : document;
|
||||
const f = root.querySelector('.upg-hud-flash');
|
||||
return { text: window.__UPG_LAST_CLIPBOARD__ || '', flash: f ? f.textContent.trim() : '' };
|
||||
}, EL);
|
||||
}
|
||||
let copyOk = false, copyDetail = 'no .upg-hud-btn.copy in HUD';
|
||||
if (copied) {
|
||||
const line1 = (copied.text.split('\n')[0]) || '';
|
||||
const names = shiftSel.err ? [] : shiftSel.list.map((x) => x.name);
|
||||
const allNames = names.length === 3 && names.every((n) => line1.includes(n));
|
||||
const hasTotal = line1.includes('— ' + expectSum + ' UUPG');
|
||||
const hasColor = line1.endsWith('· #0072b2');
|
||||
copyOk = allNames && hasTotal && hasColor;
|
||||
copyDetail = `line1=${JSON.stringify(line1)} allNames=${allNames} hasTotal(Σ=${expectSum})=${hasTotal} endsWith"· #0072b2"=${hasColor} clipboardApi=${JSON.stringify(copied.flash)}`;
|
||||
}
|
||||
check('(15) toolA: Copy → payload carries all 3 names + the independent total + trailing "· #0072b2"',
|
||||
copyOk, copyDetail);
|
||||
// ── (15) REMOVED 2026-09-28: the Copy payload assertion. It guarded on
|
||||
// .upg-hud-btn.copy existing, but that button went with fc93847bb (batch
|
||||
// selection builds a packet now). The guard skipped only the MEASUREMENT —
|
||||
// copyOk was initialised false and check() ran unconditionally — so this
|
||||
// reported FAIL ("no .upg-hud-btn.copy in HUD") on every run since. A
|
||||
// permanently red assertion for a deleted feature teaches readers to ignore
|
||||
// red, which is worse than no check. Its handler (copySelection/legacyCopy)
|
||||
// and the window.__UPG_LAST_CLIPBOARD__ it read are deleted in the same
|
||||
// commit. formatClipboard survives: __UPG_SELECT__.clipboardText still uses it.
|
||||
|
||||
// ── (16) toolA R1.4 (a‴/f′ + L4): batch mode OFF → a PLAIN tap is NOT a
|
||||
// multi-select AND not a clear. Tap the RAIL button again ("Done") to LEAVE
|
||||
|
|
|
|||
|
|
@ -889,54 +889,14 @@ function clearSelection() {
|
|||
refreshSelectionPaint()
|
||||
}
|
||||
|
||||
// ── 09b §1(d): copy the selection to the clipboard (D-1 format) ──────────────
|
||||
// "Name1, Name2, … — {total} UUPG" + a 2nd line per-territory breakdown.
|
||||
// navigator.clipboard on the click gesture; textarea+execCommand fallback for a
|
||||
// non-secure context (where navigator.clipboard is undefined). Exposed on window
|
||||
// for the firefox gate to read back the exact string the handler built.
|
||||
async function copySelection() {
|
||||
if (!selectedTerritories.value.length) return
|
||||
// R1.1 (h): the payload ends with " · #hex" when a color is picked — the exact
|
||||
// string toolB parses to regroup+recolor in one command.
|
||||
const text = formatClipboard(selectedTerritories.value, { color: selectedColor.value })
|
||||
if (typeof window !== 'undefined') window.__UPG_LAST_CLIPBOARD__ = text
|
||||
let ok = false
|
||||
try {
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
await navigator.clipboard.writeText(text)
|
||||
ok = true
|
||||
} else {
|
||||
ok = legacyCopy(text)
|
||||
}
|
||||
} catch (err) {
|
||||
ok = legacyCopy(text) // secure-context / permission failure → fallback
|
||||
}
|
||||
// ⚠ THE OLD GUARD ONLY MATCHED THE SUCCESS BRANCH — `startsWith('Copied')` — so "Copy failed" NEVER
|
||||
// CLEARED, in English, before any of this was translated. A pre-existing bug that the prose fix would
|
||||
// have widened to both branches in ten languages. Found by exp-shepherd sweeping the whole tree for the
|
||||
// PATTERN (a branch on a user-visible string's content) after I had only grepped for the exact shape I
|
||||
// already knew, `status.value.startsWith` — which is why I missed the ternary form in my own file.
|
||||
flashRef(copyFlash, ok ? t('messages.copied') : t('messages.copyFailed'), 1800)
|
||||
}
|
||||
|
||||
// textarea + execCommand('copy') fallback (non-secure context, no clipboard API).
|
||||
function legacyCopy(text) {
|
||||
try {
|
||||
const ta = document.createElement('textarea')
|
||||
ta.value = text
|
||||
ta.style.position = 'fixed'; ta.style.opacity = '0'; ta.style.top = '0'
|
||||
document.body.appendChild(ta)
|
||||
ta.focus(); ta.select()
|
||||
const ok = document.execCommand && document.execCommand('copy')
|
||||
document.body.removeChild(ta)
|
||||
return !!ok
|
||||
} catch (_) { return false }
|
||||
}
|
||||
|
||||
// ── R1.2 PIVOT (D-8): the Ctrl/Cmd-C + Escape keyboard handler is REMOVED. The
|
||||
// the brief explicitly asked to drop modifier-key gestures for mobile parity — Copy
|
||||
// + Clear are the on-screen HUD buttons (≥40px tap targets) and are the ONLY
|
||||
// selection-action surface now. No code path depends on a keyboard modifier.
|
||||
// ── R1.2 PIVOT (D-8): the Ctrl/Cmd-C + Escape keyboard handler is REMOVED — the
|
||||
// brief asked to drop modifier-key gestures for mobile parity. The on-screen HUD
|
||||
// buttons (≥40px tap targets) are the ONLY selection-action surface, and no code
|
||||
// path depends on a keyboard modifier.
|
||||
// Those buttons are Prayer List / Poster Map / Clear (:2856-2860). This comment
|
||||
// used to name "Copy + Clear"; Copy went with fc93847bb, which is the same commit
|
||||
// that orphaned the copySelection/legacyCopy pair deleted just above.
|
||||
|
||||
// ── 09b-search-bar §1(a/c): build the unified index once records are loaded ──
|
||||
// PG rows come from the LIVE records (slug+name+lat/lng) — the same record set
|
||||
|
|
|
|||
Loading…
Reference in a new issue