From b843fcade1b9db1f9d36177d5db9a958eedce179 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 3 Oct 2026 06:00:01 +0000 Subject: [PATCH 1/9] Gospel Resources: Show all drops only the table filter's own keys, keeping the tab, a partner's keys, the hash and the history state --- internal/check-gospel-all.mjs | 1 + package.json | 2 + .../gospel-resources/data-tables.vue | 5 +- plugin-designs/gospel-resources/filter-url.js | 16 +++++++ .../scripts/check-clear-filter-url.mjs | 48 +++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 plugin-designs/gospel-resources/filter-url.js create mode 100644 plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs diff --git a/internal/check-gospel-all.mjs b/internal/check-gospel-all.mjs index f5e52b9d0..07bca7464 100644 --- a/internal/check-gospel-all.mjs +++ b/internal/check-gospel-all.mjs @@ -37,6 +37,7 @@ const STATIC = [ ['check:click-sheet', 'the country sheet resolves, links are absolute'], ['check:snapshot-guard', 'no fetcher writes around the guard'], ['check:gospel-tables-staged', 'every asset the map fetches is in the shipped tree'], + ['check:gospel-clear-filter-url', 'Show all drops only the filter keys, not a partner\'s'], ] const BROWSER = [ ['check:leaves-mount', 'all five leaves actually mount'], diff --git a/package.json b/package.json index 9ddde7c9d..3fc918701 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,7 @@ "check:gospel-all": "node internal/check-gospel-all.mjs", "check:gospel-internet": "node plugin-designs/gospel-internet/scripts/check-gospel-internet-model.mjs && node plugin-designs/gospel-internet/scripts/check-gospel-internet-i18n.mjs && node plugin-designs/gospel-internet/scripts/check-language-tree.mjs && node plugin-designs/gospel-internet/scripts/check-gospel-internet-render.mjs", "check:gospel-tables-staged": "node internal/check-gospel-tables-staged.mjs", + "check:gospel-clear-filter-url": "node plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs && node plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs --poison", "check:gospel-whiteboard": "node internal/check-gospel-whiteboard.mjs", "check:hardcoded-english": "node internal/check-hardcoded-english.mjs", "check:hardcoded-english:self-test": "node internal/check-hardcoded-english.mjs --self-test", @@ -529,6 +530,7 @@ "check:gallery-embed:live-cors": "the Research Gallery on a foreign page under the LIVE static layer's CORS rule (Access-Control-Allow-Origin on files inside the tree's folders, NOT on the root manifest.json, measured on the live test host): it must still boot every tab, by reading the CORS-readable manifest copy generate-tree writes beside its bundle.", "check:gated-not-in-tree": "a GATED profile (the build config's gatedProfiles, today key-cities) never reaches the public tree: no public/// folder, no manifest.json entry, no page referencing /.js. vite.config.js builds a gated bundle into .gated// (ignored by git). Data tables are out of scope on purpose: key-cities.json also feeds the production Cities with Internet map. Two-sided: three planted leaks in a temporary tree, each caught. Node only.", "check:gospel-all": "EVERYTHING gospel-resources owns, in one command. Its ten gates were all hand-run, which is how a dead bundle shipped: a duplicate module killed all five leaves and the one gate run that day was pointed at the map. check:no-orphan-gates was right that they were reachable — reachable is not run. Deliberately NOT in gates:pre/post: three need a browser, the shared wave holds browser gates under load, and a bundle owner should not be able to slow everyone else's build by adding to a list they do not own. Static gates run first and stop the run on failure, so a scarce browser slot is never spent confirming a table is inconsistent. Exit 75 = NOT MEASURED, never folded into a pass.", + "check:gospel-clear-filter-url": "the gospel tables' Show all drops ONLY its own filter keys (iso, country, label, province): the page's ?tab=, a host's or partner's keys, the #hash and the history state stay. It used to replaceState the bare pathname, wiping a partner's query. Proves the pure helper (filter-url.js) and that data-tables.vue calls it; --poison runs the old wipe and must fail.", "check:gospel-internet": "the Gospel x Internet board, headless, against the REAL table and the REAL kit bus: the join table is what its builder makes from main (2,107 / 2,107, province placement agreeing with gospel-by-province), every facet count equals the rows the bus then keeps (the five-numbers-agree invariant), D1 OR-within-key, the country->province cascade, the 369 zero-access headline by band 220/45/45/59, URL state round-trip, CSV header-first/provenance-last with injection neutralised, no engagement column; then every catalogue key the bundle names exists in all 11 locales and is translated. Each half has a --poison arm that must fail. Plugin-local because check:i18n-keys-exist cannot see a useOptionalT-based alias.", "check:gospel-whiteboard": "the gospel set charts' geometry once drawn on a map: the bounded set's gap survives projection, the drawing stays inside the Mercator clamp, and three more properties, each with the arm that would catch its own defect. By the gospel owner. Headless.", "check:hardcoded-english": "English a reader sees that no locale can reach: template text, static title=, script-block sentences, template literals, and quoted literals inside BOUND attributes, across the production plugins. Quiet on translator calls (including discovered aliases and proxy-t misses), te()-guarded fallbacks, css, urls and developer error text. Deliberately NOT in gates:post yet: it reports 179 today (gospel-resources 148, my-upg-100-list 25, cities-internet 6 incl. one cross-area key), with English inside dir=ltr islands listed as deliberate and not counted; it joins when that reaches 0 or every hit is carded. The :self-test (28 assertions, fixtures validated first so a malformed sample cannot pass as silence) runs in gates:pre.", diff --git a/plugin-designs/gospel-resources/data-tables.vue b/plugin-designs/gospel-resources/data-tables.vue index 5d1f61681..eb4d139ce 100644 --- a/plugin-designs/gospel-resources/data-tables.vue +++ b/plugin-designs/gospel-resources/data-tables.vue @@ -27,6 +27,7 @@ import { EN_MESSAGES } from '@map/i18n/index.js' import DataTable from '@map/components/tables/DataTable.vue' import { useShadowStyles } from '@map/composables/useShadowStyles.js' import { resolveAssetsBase } from '@map/utils/embedBase.js' +import { withoutKeys, FILTER_KEYS } from './filter-url.js' const profileConfig = inject('profileConfig', ref(null)) @@ -148,9 +149,11 @@ const fLabel = ref((params.get('label') || '').trim()) const fProvince = ref((params.get('province') || '').trim()) const fold = (v) => String(v || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase().trim() const hasFilter = computed(() => !!(fIso.value || fCountry.value || fProvince.value)) +// "Show all" drops only the filter's own keys (filter-url.js): the tab, a host's or partner's keys, +// the hash and the history state stay as they were. function clearFilter() { fIso.value = ''; fCountry.value = ''; fLabel.value = ''; fProvince.value = '' - try { window.history.replaceState({}, '', window.location.pathname) } catch (_) {} + try { window.history.replaceState(window.history.state, '', withoutKeys(window.location.href, FILTER_KEYS)) } catch (_) {} } const active = ref(TABS.some((t) => t.id === params.get('tab')) ? params.get('tab') : 'links') diff --git a/plugin-designs/gospel-resources/filter-url.js b/plugin-designs/gospel-resources/filter-url.js new file mode 100644 index 000000000..38500d3c8 --- /dev/null +++ b/plugin-designs/gospel-resources/filter-url.js @@ -0,0 +1,16 @@ +/** + * filter-url.js — the address after this page drops its OWN filter keys. + * + * The tables page reads a deep-link filter from the query (?iso= / ?country= / ?label= / ?province=). + * "Show all" must remove exactly those keys: the page's ?tab=, any key a host or a partner put on the + * address, and the #hash are someone else's and stay as they were. Pure (no DOM), so a node check can + * prove it without a browser. + */ +export const FILTER_KEYS = ['iso', 'country', 'label', 'province'] + +/** `href` without `keys`, as pathname + search + hash (what history.replaceState takes). */ +export function withoutKeys(href, keys = FILTER_KEYS) { + const u = new URL(href) + for (const k of keys) u.searchParams.delete(k) + return u.pathname + u.search + u.hash +} diff --git a/plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs b/plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs new file mode 100644 index 000000000..2bd117479 --- /dev/null +++ b/plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs @@ -0,0 +1,48 @@ +#!/usr/bin/env node +/** + * check-clear-filter-url.mjs — "Show all" on the gospel tables drops ONLY the filter's own keys. + * + * WHY: clearFilter used to replaceState({}, '', pathname), which wiped the whole query and the hash — + * the page's own ?tab=, and any key a host or a partner had put on the address — and the history + * state with them. The address after "Show all" must differ from the one before by the filter keys + * alone. + * + * Proves it two ways: the pure helper (filter-url.js) on real-shaped addresses, and the component — + * data-tables.vue's clearFilter calls that helper and keeps history.state, and the old wipe is gone. + * `--poison` runs the old behaviour through the same assertions and requires them to FAIL. + * Exit 0 pass · 1 fail. + */ +import { readFileSync } from 'node:fs' +import { resolve, dirname } from 'node:path' +import { fileURLToPath } from 'node:url' +import { withoutKeys, FILTER_KEYS } from '../filter-url.js' + +const HERE = dirname(fileURLToPath(import.meta.url)) +const POISON = process.argv.includes('--poison') +const strip = POISON ? (href) => new URL(href).pathname : (href) => withoutKeys(href, FILTER_KEYS) + +let fails = 0 +const ok = (c, m) => { if (c) console.log('ok ' + m); else { fails++; console.log('FAIL ' + m) } } +const base = 'https://example.org/dx-maps/gospel-resources/data-tables/index.html' + +const a = strip(`${base}?tab=links&iso=hin&country=IND&label=Hindi&province=Bihar&partner=abc#tables`) +ok(!/[?&](iso|country|label|province)=/.test(a), `the filter keys are gone (${a})`) +ok(/[?&]tab=links\b/.test(a), 'the page\'s own ?tab= stays') +ok(/[?&]partner=abc\b/.test(a), 'a host\'s or partner\'s key stays') +ok(a.endsWith('#tables'), 'the #hash stays') +const b = strip(`${base}?iso=hin`) +ok(b === new URL(base).pathname, `only filter keys: no dangling "?" (${b})`) +const c = strip(`${base}?tab=countries`) +ok(c === new URL(base).pathname + '?tab=countries', 'no filter: the address is unchanged') + +if (!POISON) { + const vue = readFileSync(resolve(HERE, '../data-tables.vue'), 'utf8') + const fn = (vue.match(/function clearFilter\(\)\s*\{[\s\S]*?\n\}/) || [''])[0] + ok(/withoutKeys\(window\.location\.href,\s*FILTER_KEYS\)/.test(fn), 'data-tables.vue clearFilter uses the helper') + ok(/replaceState\(window\.history\.state,/.test(fn), 'and keeps history.state') + ok(!/replaceState\(\{\},\s*'',\s*window\.location\.pathname\)/.test(vue), 'the old whole-address wipe is gone') +} + +if (POISON) { console.log(fails ? `POISON OK: ${fails} caught` : 'POISON FAILED'); process.exit(fails ? 0 : 1) } +console.log(fails ? `FAIL check-clear-filter-url: ${fails}` : 'PASS check-clear-filter-url') +process.exit(fails ? 1 : 0) From 15d0ef35583489348907b055ead6a464d3f4217b Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 3 Oct 2026 06:54:24 +0000 Subject: [PATCH 2/9] Gospel Resources: Show all writes through the one history writer, only on a page it owns, and its check runs in gates:pre --- internal/check-view-address.mjs | 1 - package.json | 2 +- plugin-designs/gospel-resources/data-tables.vue | 10 ++++++---- plugin-designs/gospel-resources/filter-url.js | 16 ++++++++-------- .../scripts/check-clear-filter-url.mjs | 17 +++++++++++------ 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/internal/check-view-address.mjs b/internal/check-view-address.mjs index 96a44083e..88620d496 100644 --- a/internal/check-view-address.mjs +++ b/internal/check-view-address.mjs @@ -26,7 +26,6 @@ const KNOWN = { 'library/utils/languageRequest.js': [1, '?lang= on a generated page only (MAP_OWNS_PAGE); keeps state and every other param'], 'library/layouts/app-wrapper-material/index.html': [1, "the layout page's own #/ hash; a fragment-only URL keeps the query"], 'plugin-designs/gospel-internet/src/useBoard.js': [1, 'its own keys on its own leaves (writeUrl); keeps state, foreign params and the hash'], - 'plugin-designs/gospel-resources/data-tables.vue': [1, "clearFilter: replaceState({}, '', pathname) wipes the whole query and hash; reported to its owner"], 'plugin-designs/regions-dashboard/region-dashboards.vue': [2, '# on its own leaf (URL_SYNC); P2 moves it to `place`'], } // SOURCE files only: gates and node scripts may simulate history. A write is `.pushState(` / `.replaceState(` (an aliased diff --git a/package.json b/package.json index f62845bd6..43d6287d6 100644 --- a/package.json +++ b/package.json @@ -360,7 +360,7 @@ "fix:sri": "node internal/fix-sri.mjs", "gallery": "node internal/generate-gallery.mjs", "gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test check:preview-flag-dev-only:self-test check:poster-type-registry:self-test check:host-floor:self-test check:phone-print-keep:self-test check:pinned-fetch-fresh:self-test", - "gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:upg100-zone-copy check:upg100-zone-copy:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh check:view-address check:view-address:self-test", + "gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:upg100-zone-copy check:upg100-zone-copy:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh check:view-address check:view-address:self-test check:gospel-clear-filter-url", "gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs", "internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs", "library-index": "node internal/generate-library-index.mjs", diff --git a/plugin-designs/gospel-resources/data-tables.vue b/plugin-designs/gospel-resources/data-tables.vue index eb4d139ce..e92878bbe 100644 --- a/plugin-designs/gospel-resources/data-tables.vue +++ b/plugin-designs/gospel-resources/data-tables.vue @@ -27,7 +27,8 @@ import { EN_MESSAGES } from '@map/i18n/index.js' import DataTable from '@map/components/tables/DataTable.vue' import { useShadowStyles } from '@map/composables/useShadowStyles.js' import { resolveAssetsBase } from '@map/utils/embedBase.js' -import { withoutKeys, FILTER_KEYS } from './filter-url.js' +import { commitUrl, urlOwnerOf } from '@map/composables/useViewAddress.js' +import { searchWithout, FILTER_KEYS } from './filter-url.js' const profileConfig = inject('profileConfig', ref(null)) @@ -149,11 +150,12 @@ const fLabel = ref((params.get('label') || '').trim()) const fProvince = ref((params.get('province') || '').trim()) const fold = (v) => String(v || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase().trim() const hasFilter = computed(() => !!(fIso.value || fCountry.value || fProvince.value)) -// "Show all" drops only the filter's own keys (filter-url.js): the tab, a host's or partner's keys, -// the hash and the history state stay as they were. +// "Show all" drops only the filter's own keys (filter-url.js) through the one history writer, and only on a page +// this element owns (urlOwner 'app'); a partner's or a host's address is never written. The tab, every other key, +// the hash and the history state stay. function clearFilter() { fIso.value = ''; fCountry.value = ''; fLabel.value = ''; fProvince.value = '' - try { window.history.replaceState(window.history.state, '', withoutKeys(window.location.href, FILTER_KEYS)) } catch (_) {} + if (urlOwnerOf(profileConfig.value) === 'app') commitUrl({ search: searchWithout(window.location.search, FILTER_KEYS) }) } const active = ref(TABS.some((t) => t.id === params.get('tab')) ? params.get('tab') : 'links') diff --git a/plugin-designs/gospel-resources/filter-url.js b/plugin-designs/gospel-resources/filter-url.js index 38500d3c8..3e78e4ffb 100644 --- a/plugin-designs/gospel-resources/filter-url.js +++ b/plugin-designs/gospel-resources/filter-url.js @@ -1,16 +1,16 @@ /** - * filter-url.js — the address after this page drops its OWN filter keys. + * filter-url.js — the query after this page drops its OWN filter keys. * * The tables page reads a deep-link filter from the query (?iso= / ?country= / ?label= / ?province=). * "Show all" must remove exactly those keys: the page's ?tab=, any key a host or a partner put on the - * address, and the #hash are someone else's and stay as they were. Pure (no DOM), so a node check can - * prove it without a browser. + * address, and the #hash are someone else's and stay as they were. The result is in commitUrl's `search` + * shape ('' or '?…'), and every other parameter is kept as written, byte for byte. Pure (no DOM), so a node + * check can prove it without a browser. */ export const FILTER_KEYS = ['iso', 'country', 'label', 'province'] -/** `href` without `keys`, as pathname + search + hash (what history.replaceState takes). */ -export function withoutKeys(href, keys = FILTER_KEYS) { - const u = new URL(href) - for (const k of keys) u.searchParams.delete(k) - return u.pathname + u.search + u.hash +/** `search` ('' or '?…') without the parameters named in `keys`, in the same shape. */ +export function searchWithout(search, keys = FILTER_KEYS) { + const kept = String(search || '').replace(/^\?/, '').split('&').filter((p) => p && !keys.includes(p.split('=')[0])) + return kept.length ? '?' + kept.join('&') : '' } diff --git a/plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs b/plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs index 2bd117479..426df8022 100644 --- a/plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs +++ b/plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs @@ -8,18 +8,20 @@ * alone. * * Proves it two ways: the pure helper (filter-url.js) on real-shaped addresses, and the component — - * data-tables.vue's clearFilter calls that helper and keeps history.state, and the old wipe is gone. + * data-tables.vue's clearFilter writes through commitUrl (the one history writer, which keeps the hash and the + * state) only on a page it owns, with no direct history write left. * `--poison` runs the old behaviour through the same assertions and requires them to FAIL. * Exit 0 pass · 1 fail. */ import { readFileSync } from 'node:fs' import { resolve, dirname } from 'node:path' import { fileURLToPath } from 'node:url' -import { withoutKeys, FILTER_KEYS } from '../filter-url.js' +import { searchWithout, FILTER_KEYS } from '../filter-url.js' const HERE = dirname(fileURLToPath(import.meta.url)) const POISON = process.argv.includes('--poison') -const strip = POISON ? (href) => new URL(href).pathname : (href) => withoutKeys(href, FILTER_KEYS) +// The address after "Show all", as commitUrl writes it ({ search } given, the current hash kept). Poison: the old wipe. +const strip = POISON ? (href) => new URL(href).pathname : (href) => { const u = new URL(href); return u.pathname + searchWithout(u.search, FILTER_KEYS) + u.hash } let fails = 0 const ok = (c, m) => { if (c) console.log('ok ' + m); else { fails++; console.log('FAIL ' + m) } } @@ -34,13 +36,16 @@ const b = strip(`${base}?iso=hin`) ok(b === new URL(base).pathname, `only filter keys: no dangling "?" (${b})`) const c = strip(`${base}?tab=countries`) ok(c === new URL(base).pathname + '?tab=countries', 'no filter: the address is unchanged') +const d = strip(`${base}?tab=links&q=a%20b+c&iso=hin`) +ok(d.endsWith('?tab=links&q=a%20b+c'), `other parameters are kept as written, byte for byte (${d})`) if (!POISON) { const vue = readFileSync(resolve(HERE, '../data-tables.vue'), 'utf8') const fn = (vue.match(/function clearFilter\(\)\s*\{[\s\S]*?\n\}/) || [''])[0] - ok(/withoutKeys\(window\.location\.href,\s*FILTER_KEYS\)/.test(fn), 'data-tables.vue clearFilter uses the helper') - ok(/replaceState\(window\.history\.state,/.test(fn), 'and keeps history.state') - ok(!/replaceState\(\{\},\s*'',\s*window\.location\.pathname\)/.test(vue), 'the old whole-address wipe is gone') + ok(/import \{[^}]*\bcommitUrl\b[^}]*\burlOwnerOf\b[^}]*\} from '@map\/composables\/useViewAddress\.js'/.test(vue), 'data-tables.vue imports the one history writer (commitUrl) and urlOwnerOf') + ok(/commitUrl\(\{\s*search:\s*searchWithout\(window\.location\.search,\s*FILTER_KEYS\)\s*\}\)/.test(fn), 'clearFilter writes through commitUrl with only the filter keys dropped (the hash and state kept by commitUrl)') + ok(/urlOwnerOf\(profileConfig\.value\)\s*===\s*'app'/.test(fn), 'and only on a page it owns (urlOwner app): a partner\'s address is never written') + ok(!/\.(push|replace)State\s*\(/.test(vue), 'no direct history write is left in data-tables.vue') } if (POISON) { console.log(fails ? `POISON OK: ${fails} caught` : 'POISON FAILED'); process.exit(fails ? 0 : 1) } From 723cd53b4367ae2f1a0e07c3197806ad582384d1 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 3 Oct 2026 07:01:47 +0000 Subject: [PATCH 3/9] Gospel Resources tables: the loading line calls the page's own translator, so it no longer throws on every load; a gate keeps template translators bound --- package.json | 4 +- .../gospel-resources/data-tables.vue | 2 +- .../scripts/check-template-translators.mjs | 47 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 plugin-designs/gospel-resources/scripts/check-template-translators.mjs diff --git a/package.json b/package.json index 43d6287d6..636a24c70 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "check:gospel-internet": "node plugin-designs/gospel-internet/scripts/check-gospel-internet-model.mjs && node plugin-designs/gospel-internet/scripts/check-gospel-internet-i18n.mjs && node plugin-designs/gospel-internet/scripts/check-language-tree.mjs && node plugin-designs/gospel-internet/scripts/check-gospel-internet-render.mjs", "check:gospel-tables-staged": "node internal/check-gospel-tables-staged.mjs", "check:gospel-clear-filter-url": "node plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs && node plugin-designs/gospel-resources/scripts/check-clear-filter-url.mjs --poison", + "check:gospel-template-translators": "node plugin-designs/gospel-resources/scripts/check-template-translators.mjs && node plugin-designs/gospel-resources/scripts/check-template-translators.mjs --poison", "check:gospel-whiteboard": "node internal/check-gospel-whiteboard.mjs", "check:hardcoded-english": "node internal/check-hardcoded-english.mjs", "check:hardcoded-english:self-test": "node internal/check-hardcoded-english.mjs --self-test", @@ -360,7 +361,7 @@ "fix:sri": "node internal/fix-sri.mjs", "gallery": "node internal/generate-gallery.mjs", "gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test check:preview-flag-dev-only:self-test check:poster-type-registry:self-test check:host-floor:self-test check:phone-print-keep:self-test check:pinned-fetch-fresh:self-test", - "gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:upg100-zone-copy check:upg100-zone-copy:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh check:view-address check:view-address:self-test check:gospel-clear-filter-url", + "gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:upg100-zone-copy check:upg100-zone-copy:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh check:view-address check:view-address:self-test check:gospel-clear-filter-url check:gospel-template-translators", "gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs", "internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs", "library-index": "node internal/generate-library-index.mjs", @@ -533,6 +534,7 @@ "check:gated-not-in-tree": "a GATED profile (the build config's gatedProfiles, today key-cities) never reaches the public tree: no public/// folder, no manifest.json entry, no page referencing /.js. vite.config.js builds a gated bundle into .gated// (ignored by git). Data tables are out of scope on purpose: key-cities.json also feeds the production Cities with Internet map. Two-sided: three planted leaks in a temporary tree, each caught. Node only.", "check:gospel-all": "EVERYTHING gospel-resources owns, in one command. Its ten gates were all hand-run, which is how a dead bundle shipped: a duplicate module killed all five leaves and the one gate run that day was pointed at the map. check:no-orphan-gates was right that they were reachable — reachable is not run. Deliberately NOT in gates:pre/post: three need a browser, the shared wave holds browser gates under load, and a bundle owner should not be able to slow everyone else's build by adding to a list they do not own. Static gates run first and stop the run on failure, so a scarce browser slot is never spent confirming a table is inconsistent. Exit 75 = NOT MEASURED, never folded into a pass.", "check:gospel-clear-filter-url": "the gospel tables' Show all drops ONLY its own filter keys (iso, country, label, province): the page's ?tab=, a host's or partner's keys, the #hash and the history state stay. It used to replaceState the bare pathname, wiping a partner's query. Proves the pure helper (filter-url.js) and that data-tables.vue calls it; --poison runs the old wipe and must fail.", + "check:gospel-template-translators": "every translator a gospel-resources template calls (t, tr, T, tShared, tStatic) is a TOP-LEVEL binding of its \n\n\n" + "script": "\n\n\n" } }, { @@ -966,7 +966,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -982,8 +982,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -999,7 +999,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1015,8 +1015,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] diff --git a/public/dx-maps/gospel-resources/charts/index.html b/public/dx-maps/gospel-resources/charts/index.html index 34221a7ea..494f6f6b3 100644 --- a/public/dx-maps/gospel-resources/charts/index.html +++ b/public/dx-maps/gospel-resources/charts/index.html @@ -67,7 +67,7 @@ - + - + - + - + - + \n\n\n" + "script": "\n\n\n" } }, { @@ -966,7 +966,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -982,8 +982,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -999,7 +999,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1015,8 +1015,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] From a6c5ca5a8622802f3de17e8e388e74fca0888654 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 3 Oct 2026 07:05:01 +0000 Subject: [PATCH 5/9] Gospel Resources tables: the loading line names the table it is loading --- plugin-designs/gospel-resources/data-tables.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-designs/gospel-resources/data-tables.vue b/plugin-designs/gospel-resources/data-tables.vue index aa46774e6..9a651b182 100644 --- a/plugin-designs/gospel-resources/data-tables.vue +++ b/plugin-designs/gospel-resources/data-tables.vue @@ -458,7 +458,7 @@ useShadowStyles(
{{ loadErr }}
-
{{ tr('gospel.sheet.loadingTable', { table: current.label }) }}
+
{{ tr('gospel.sheet.loadingTable', { table: tabLabel(current) }) }}
Date: Sat, 3 Oct 2026 07:05:25 +0000 Subject: [PATCH 6/9] Rebuild gospel-resources for the loading line's table name --- public/dx-maps/doxa-maps-spa/manifest.json | 16 ++++++++-------- .../dx-maps/gospel-resources/charts/index.html | 2 +- .../gospel-resources/data-tables/index.html | 2 +- .../gospel-resources/gospel-dashboard/index.html | 2 +- .../dx-maps/gospel-resources/gospel-resources.js | 2 +- .../gospel-resources/resources-list/index.html | 2 +- .../gospel-resources/resources-map/index.html | 2 +- public/dx-maps/manifest.json | 16 ++++++++-------- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/public/dx-maps/doxa-maps-spa/manifest.json b/public/dx-maps/doxa-maps-spa/manifest.json index 6521286b4..d1145d6a6 100644 --- a/public/dx-maps/doxa-maps-spa/manifest.json +++ b/public/dx-maps/doxa-maps-spa/manifest.json @@ -927,7 +927,7 @@ "bundle": "gospel-resources", "scriptUrl": "./gospel-resources/gospel-resources.js", "output": "dx-maps/gospel-resources/gospel-resources.js", - "integrity": "sha384-rWwDViUvK2rNlEvMT0zhHzPaZ10Gw4URd02Ks/Br6ykYPNC6sazRMV7D/GgaC8yu", + "integrity": "sha384-7Wxen11BJloz0uFyJohMlwY24/cBKLu+7XOy/U3f348hO+TO2jfztto5kLiaQEfa", "elements": [ "gospel-resources-map" ], @@ -950,7 +950,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -966,7 +966,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -982,8 +982,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -999,7 +999,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1015,8 +1015,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] diff --git a/public/dx-maps/gospel-resources/charts/index.html b/public/dx-maps/gospel-resources/charts/index.html index 494f6f6b3..782d41e57 100644 --- a/public/dx-maps/gospel-resources/charts/index.html +++ b/public/dx-maps/gospel-resources/charts/index.html @@ -67,7 +67,7 @@ - + - + - + - + - + \n\n\n" + "script": "\n\n\n" } }, { @@ -966,7 +966,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -982,8 +982,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -999,7 +999,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1015,8 +1015,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] From f85e880b2c4a72afcb596d93f39f3c038a3caae7 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 3 Oct 2026 07:31:02 +0000 Subject: [PATCH 7/9] Gospel Resources: its two checks run in gates:pre again after the pilot merge --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 73ac19ea8..2667d641d 100644 --- a/package.json +++ b/package.json @@ -363,7 +363,7 @@ "fix:sri": "node internal/fix-sri.mjs", "gallery": "node internal/generate-gallery.mjs", "gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test check:pin-hint-floor:self-test check:poster-sizes:self-test check:shell-header:self-test check:preview-flag-dev-only:self-test check:poster-type-registry:self-test check:host-floor:self-test check:phone-print-keep:self-test check:pinned-fetch-fresh:self-test", - "gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:upg100-zone-copy check:upg100-zone-copy:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh check:view-address check:view-address:self-test check:dev-leaf-escape check:dev-leaf-escape:self-test", + "gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:pins-in-state check:fork-leaders check:circular-layout check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:side-lanes check:side-lanes:self-test check:poster-section check:poster-section:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-sections check:poster-sections:self-test check:poster-design-catalogue check:poster-design-catalogue:self-test check:upg100-zone-copy check:upg100-zone-copy:self-test check:wall-photo-weight check:no-fleet-names check:pin-hint-floor check:poster-sizes check:upg-count check:shell-header check:pg-name-gate check:preview-flag-dev-only check:poster-type-registry check:host-floor check:phone-print-keep check:pinned-fetch-fresh check:view-address check:view-address:self-test check:dev-leaf-escape check:dev-leaf-escape:self-test check:gospel-clear-filter-url check:gospel-template-translators", "gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs", "internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs", "library-index": "node internal/generate-library-index.mjs", From 32c6eb4fd4d7a64f3a9bbb09b8ef53f735d9a241 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 3 Oct 2026 07:34:30 +0000 Subject: [PATCH 8/9] Rebuild gospel-resources from the merged pilot, and regenerate the tree --- public/dx-maps/doxa-maps-spa/manifest.json | 16 +++---- .../gospel-resources/charts/index.html | 2 +- .../gospel-resources/data-tables/index.html | 2 +- .../gospel-dashboard/index.html | 2 +- .../gospel-resources/gospel-resources.js | 44 +++++++++---------- .../resources-list/index.html | 2 +- .../gospel-resources/resources-map/index.html | 2 +- public/dx-maps/manifest.json | 16 +++---- 8 files changed, 43 insertions(+), 43 deletions(-) diff --git a/public/dx-maps/doxa-maps-spa/manifest.json b/public/dx-maps/doxa-maps-spa/manifest.json index d304f9eec..5f68b8146 100644 --- a/public/dx-maps/doxa-maps-spa/manifest.json +++ b/public/dx-maps/doxa-maps-spa/manifest.json @@ -927,7 +927,7 @@ "bundle": "gospel-resources", "scriptUrl": "./gospel-resources/gospel-resources.js", "output": "dx-maps/gospel-resources/gospel-resources.js", - "integrity": "sha384-YsU1rWFd1E/U3jD/upPCjU107AjJuS7MqNfvX9C1QYc+x5wg3kodvJFBuAaCe1dT", + "integrity": "sha384-6IkN3wrfEU5b8F4191NNVZLbXyRNY/51lv/im3ljhmaEYNC7Z3qktfVLna6hSRZZ", "elements": [ "gospel-resources-map" ], @@ -950,7 +950,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -966,7 +966,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -982,8 +982,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -999,7 +999,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1015,8 +1015,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] diff --git a/public/dx-maps/gospel-resources/charts/index.html b/public/dx-maps/gospel-resources/charts/index.html index 45158d1d1..2acfe115e 100644 --- a/public/dx-maps/gospel-resources/charts/index.html +++ b/public/dx-maps/gospel-resources/charts/index.html @@ -67,7 +67,7 @@ - + - + - + - + - + \n\n\n" + "script": "\n\n\n" } }, { @@ -966,7 +966,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -982,8 +982,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } }, { @@ -999,7 +999,7 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n" + "script": "\n\n\n" } }, { @@ -1015,8 +1015,8 @@ "scriptUrl": "./gospel-resources/gospel-resources.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n\n", - "scriptMapbox": "\n\n\n\n\n\n" + "script": "\n\n\n\n\n\n", + "scriptMapbox": "\n\n\n\n\n\n" } } ] From 05ae488eac2004c827c5e1bed4b1c323f7914746 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 3 Oct 2026 07:58:01 +0000 Subject: [PATCH 9/9] The view-address census: data-tables.vue no longer writes history directly (Show all goes through commitUrl) --- internal/check-view-address.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/check-view-address.mjs b/internal/check-view-address.mjs index 019c453ef..d9483e772 100644 --- a/internal/check-view-address.mjs +++ b/internal/check-view-address.mjs @@ -39,7 +39,6 @@ const KNOWN = { 'library/utils/languageRequest.js': [1, '?lang= on a generated page only (MAP_OWNS_PAGE); keeps state and every other param'], 'library/layouts/app-wrapper-material/index.html': [1, "the layout page's own #/ hash; a fragment-only URL keeps the query"], 'plugin-designs/gospel-internet/src/useBoard.js': [1, 'its own keys on its own leaves (writeUrl); keeps state, foreign params and the hash'], - 'plugin-designs/gospel-resources/data-tables.vue': [1, "clearFilter: replaceState({}, '', pathname) wipes the whole query and hash; reported to its owner"], } // SOURCE files only: gates and node scripts may simulate history. A write is `.pushState(` / `.replaceState(` (an aliased // history included) or a computed `history[… 'pushState' …]`.