No India tab on the pilot by dev mode alone: the India preview (its tab and its whole-country poster) needs an explicit opt-in too, ?preview=india or localStorage 'dxm-preview', and every built bundle still compiles the whole read away. The gates hold the opt-in and that dev mode alone stays withheld.
This commit is contained in:
parent
649038a917
commit
daa757d972
4 changed files with 43 additions and 15 deletions
|
|
@ -92,12 +92,21 @@ const largeOf = (item) => (item && LARGE_SHEETS[String(item.iso3 || '').toUpperC
|
|||
*/
|
||||
// WHAT of a whole country is withheld: its POSTER, and/or its ROWS (its prayer list, packet and cards).
|
||||
// India's whole-country poster is withheld EVERYWHERE BY DEFAULT (it is not released yet). It prints only in an
|
||||
// explicit PREVIEW context: the Vite DEV server (the pilot's Plugin Studio, where it is reviewed), whose element
|
||||
// bootstrap sets globalThis.DXM_PREVIEW_UNRELEASED. The read is gated on import.meta.env.DEV too, so every BUILT bundle
|
||||
// compiles it away: no page, embed or console can set a global and print it from production. Never by a URL
|
||||
// parameter. Its rows (about a thousand pages) stay withheld everywhere.
|
||||
// explicit PREVIEW context, which needs ALL of:
|
||||
// - the Vite DEV server (the pilot), whose element bootstrap sets globalThis.DXM_PREVIEW_UNRELEASED;
|
||||
// - an explicit OPT-IN on that page: ?preview=india in its URL, or localStorage 'dxm-preview' containing 'india'.
|
||||
// The pilot runs in dev mode, so dev mode alone must NOT show it (the pilot shows what the release shows).
|
||||
// The whole read is gated on import.meta.env.DEV first, so every BUILT bundle compiles it away (the opt-in included):
|
||||
// no page, URL, embed or console can print it from production. Its rows (about a thousand pages) stay withheld
|
||||
// everywhere.
|
||||
export const WITHHELD = { IND: { poster: true, rows: true, preview: true } }
|
||||
export const previewUnreleased = () => Boolean(import.meta.env && import.meta.env.DEV && globalThis.DXM_PREVIEW_UNRELEASED === true)
|
||||
export const PREVIEW_KEY = 'india'
|
||||
export function previewOptedIn() {
|
||||
const has = (v) => String(v || '').split(',').map((x) => x.trim()).includes(PREVIEW_KEY)
|
||||
try { if (new URLSearchParams(globalThis.location?.search || '').getAll('preview').some(has)) return true } catch (_) { /* no URL */ }
|
||||
try { return has(globalThis.localStorage?.getItem('dxm-preview')) } catch (_) { return false }
|
||||
}
|
||||
export const previewUnreleased = () => Boolean(import.meta.env && import.meta.env.DEV && globalThis.DXM_PREVIEW_UNRELEASED === true && previewOptedIn())
|
||||
const withheldOf = (item) => (item && !item.indiaState && WITHHELD[String(item.iso3 || '').toUpperCase()]) || null
|
||||
// No caller can open it: the preview state is read HERE, never passed in (so a built bundle cannot print it).
|
||||
export function posterWithheld(item) { const w = withheldOf(item); return Boolean(w?.poster) && !(w.preview && previewUnreleased()) }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import { buildPaneColumn, PANE_GRID_STYLES } from '@map/layouts/pane-wrapper/pan
|
|||
import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
||||
import ViewSelect from '@map/components/ViewSelect.vue'
|
||||
import { countryName } from '@map/utils/countryName.js'
|
||||
import { previewOptedIn } from '@map/packet/countrySheet.js'
|
||||
import { getRuntimeLocale, detectLocale } from '@map/i18n/index.js'
|
||||
import ShareButton from '@map/components/map-controls/ShareButton.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
|
@ -70,8 +71,9 @@ const spec = computed(() => ({
|
|||
// strip desynchronises from the scroll column.
|
||||
panes: [
|
||||
{ id: 'wall', label: t('tabs.countryPosters'), at: [0, 0], config: { profile: 'country-poster-wall' } },
|
||||
// the same DEV-gated read as countrySheet.js previewUnreleased(), INLINE so every build drops the pane entirely
|
||||
...(import.meta.env && import.meta.env.DEV && globalThis.DXM_PREVIEW_UNRELEASED === true ? [INDIA_PANE] : []),
|
||||
// the same DEV-gated read as countrySheet.js previewUnreleased() (dev server AND the explicit opt-in), INLINE so
|
||||
// every build drops the pane entirely
|
||||
...(import.meta.env && import.meta.env.DEV && globalThis.DXM_PREVIEW_UNRELEASED === true && previewOptedIn() ? [INDIA_PANE] : []),
|
||||
{ id: 'map', label: t('tabs.map'), at: [2, 0], config: { profile: 'countries-map' } },
|
||||
],
|
||||
// The switcher lives in this element's own header, so the layout's "… below ↓"
|
||||
|
|
@ -80,9 +82,10 @@ const spec = computed(() => ({
|
|||
}))
|
||||
|
||||
// INDIA: the whole-India poster (66x66 by default) on its own tab, the same wall filtered to India, labelled with
|
||||
// India's own name in the reader's language (Intl). Shown ONLY in a preview context (countrySheet.js
|
||||
// previewUnreleased(): the Plugin Studio on the pilot), because the poster is not released; everywhere else the tab
|
||||
// is absent and India's card keeps the withheld sentence.
|
||||
// India's own name in the reader's language (Intl). Shown ONLY in an opted-in preview (countrySheet.js
|
||||
// previewUnreleased(): the pilot's dev server AND ?preview=india or localStorage 'dxm-preview'), because the poster is
|
||||
// not released; everywhere else (the pilot without the opt-in included) the tab is absent and India's card keeps the
|
||||
// withheld sentence.
|
||||
const INDIA_PANE = { id: 'india', label: countryName('IND', getRuntimeLocale() || detectLocale() || 'en') || 'India', at: [1, 0], config: { profile: 'country-poster-wall', countries: ['IND'] } }
|
||||
|
||||
const stage = ref(null)
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ export async function armG(cs, srcs, mfeSrc = '') {
|
|||
if (!/rowsWithheld\((?:c|item)\) \? (?:withheld\(\)|Promise\.reject\(keyedError\('messages\.countryPosterTooMany')/.test(src)) fails.push(`${name}: withheld ROWS are not withheld (its list/packet/cards would print)`)
|
||||
if (/sheetWithheld\(/.test(src)) fails.push(`${name}: still reads sheetWithheld() (ambiguous: poster or rows?)`)
|
||||
}
|
||||
if (mfeSrc && !/\.\.\.\(import\.meta\.env && import\.meta\.env\.DEV && globalThis\.DXM_PREVIEW_UNRELEASED === true \? \[INDIA_PANE\] : \[\]\)/.test(mfeSrc)) fails.push('country-posters-mfe: the India tab is not gated on the DEV-only preview read')
|
||||
if (mfeSrc && !/\.\.\.\(import\.meta\.env && import\.meta\.env\.DEV && globalThis\.DXM_PREVIEW_UNRELEASED === true && previewOptedIn\(\) \? \[INDIA_PANE\] : \[\]\)/.test(mfeSrc)) fails.push('country-posters-mfe: the India tab is not gated on the DEV-only preview read AND the explicit opt-in (previewOptedIn())')
|
||||
// the BUILT tree never mentions the flag (every read is compiled away)
|
||||
try {
|
||||
const pub = join(ROOT, 'public/dx-maps')
|
||||
|
|
@ -298,7 +298,8 @@ async function main() {
|
|||
['an opener argument comes back', async () => armG({ ...CS, posterWithheld: (it, open) => CS.posterWithheld(it) }, lists(files[wall]), MFE)],
|
||||
['the preview read without DEV (a global opens production)', async () => armG({ ...CS, previewUnreleased: () => globalThis.DXM_PREVIEW_UNRELEASED === true }, lists(files[wall]), MFE)],
|
||||
['India\'s rows un-withheld', async () => armG({ ...CS, rowsWithheld: () => false }, lists(files[wall]), MFE)],
|
||||
['the India tab shown without the preview flag', async () => armG(CS, lists(files[wall]), MFE.replace('...(import.meta.env && import.meta.env.DEV && globalThis.DXM_PREVIEW_UNRELEASED === true ? [INDIA_PANE] : []),', 'INDIA_PANE,'))],
|
||||
['the India tab shown without the preview flag', async () => armG(CS, lists(files[wall]), MFE.replace('...(import.meta.env && import.meta.env.DEV && globalThis.DXM_PREVIEW_UNRELEASED === true && previewOptedIn() ? [INDIA_PANE] : []),', 'INDIA_PANE,'))],
|
||||
['the India tab shown on the pilot by dev mode alone', async () => armG(CS, lists(files[wall]), MFE.replace(' && previewOptedIn() ? [INDIA_PANE]', ' ? [INDIA_PANE]'))],
|
||||
['the wall prints the list of a country whose rows are withheld', async () => armG(CS, lists(files[wall].replace('rowsWithheld(c) ? withheld() : ', '')))],
|
||||
['the library type prints withheld rows', () => armH(TYPE.replace('rowsWithheld(c) ? ', 'false ? '))],
|
||||
['the library type shows a withheld poster', () => armH(TYPE.replace('posterWithheld(c) ||', 'false ||'))],
|
||||
|
|
|
|||
|
|
@ -51,17 +51,31 @@ async function arms({ types, country, element, sectionSrc, viewSrc, cs }) {
|
|||
if (!/countryPosterTooMany/.test(String(why))) fails.push(`C: withheld India's rows are not withheld (${why})`)
|
||||
if (fetched) fails.push('C: withheld India fetched records')
|
||||
}
|
||||
// C2. THE PREVIEW, under Vite (import.meta.env.DEV is true here, as on the pilot's dev server): only with the global
|
||||
// set does India's whole-country poster open, at 60x96; its rows stay withheld; without it, withheld.
|
||||
// C2. THE PREVIEW, under Vite (import.meta.env.DEV is true here, as on the pilot's dev server): DEV MODE ALONE (the
|
||||
// global set by the dev bootstrap) does NOT open India: the pilot shows what the release shows. Only with the
|
||||
// explicit opt-in too (?preview=india, or localStorage 'dxm-preview') does the poster open, at 60x96; its rows
|
||||
// stay withheld; without the global, withheld.
|
||||
const was = globalThis.DXM_PREVIEW_UNRELEASED
|
||||
const loc = Object.getOwnPropertyDescriptor(globalThis, 'location'), ls = Object.getOwnPropertyDescriptor(globalThis, 'localStorage')
|
||||
const setLoc = (search) => Object.defineProperty(globalThis, 'location', { value: { search }, configurable: true, writable: true })
|
||||
const setLs = (v) => Object.defineProperty(globalThis, 'localStorage', { value: { getItem: (k) => (k === 'dxm-preview' ? v : null) }, configurable: true, writable: true })
|
||||
try {
|
||||
globalThis.DXM_PREVIEW_UNRELEASED = true
|
||||
setLoc(''); setLs(null)
|
||||
if (!cs.posterWithheld({ iso3: 'IND' }) || cs.largeSheet({ iso3: 'IND' })) fails.push('C2: dev mode ALONE (no opt-in) opens India: the pilot would show the withheld poster')
|
||||
setLs('india')
|
||||
if (cs.posterWithheld({ iso3: 'IND' })) fails.push("C2: localStorage 'dxm-preview'='india' does not open the preview")
|
||||
setLs(null); setLoc('?lang=en&preview=india')
|
||||
const big = cs.largeSheet({ iso3: 'IND' })
|
||||
if (cs.posterWithheld({ iso3: 'IND' }) || !big || big.format !== '60x96') fails.push(`C2: in a DEV preview India's poster does not open at 60x96 (${big && big.format})`)
|
||||
if (!cs.rowsWithheld({ iso3: 'IND' })) fails.push("C2: the preview also released India's rows")
|
||||
delete globalThis.DXM_PREVIEW_UNRELEASED
|
||||
if (!cs.posterWithheld({ iso3: 'IND' })) fails.push('C2: without the preview global India is not withheld')
|
||||
} finally { if (was === undefined) delete globalThis.DXM_PREVIEW_UNRELEASED; else globalThis.DXM_PREVIEW_UNRELEASED = was }
|
||||
} finally {
|
||||
if (was === undefined) delete globalThis.DXM_PREVIEW_UNRELEASED; else globalThis.DXM_PREVIEW_UNRELEASED = was
|
||||
if (loc) Object.defineProperty(globalThis, 'location', loc); else delete globalThis.location
|
||||
if (ls) Object.defineProperty(globalThis, 'localStorage', ls); else delete globalThis.localStorage
|
||||
}
|
||||
// D
|
||||
const fake = (attrs) => ({ getAttribute: (n) => (n in attrs ? attrs[n] : null), hasAttribute: (n) => n in attrs })
|
||||
const d0 = element.posterSectionConfig(fake({ scope: 'africa' }))
|
||||
|
|
@ -121,6 +135,7 @@ try {
|
|||
["a registry without 'country'", { ...real, types: { ...types, posterTypeNames: () => [] } }, /^A:/],
|
||||
['a region key without "&" → "and"', { ...real, country: { ...country, items: (s, l) => (/-and-/.test(String(s)) ? [] : country.items(s, l)) } }, /^B:/],
|
||||
['the preview ignored under DEV', { ...real, cs: { ...cs, posterWithheld: () => true, largeSheet: () => null } }, /^C2:/],
|
||||
['dev mode alone opens India (no opt-in)', { ...real, cs: { ...cs, posterWithheld: () => false, largeSheet: () => ({ format: '60x96', formats: ['60x96'] }) } }, /^C2: dev mode ALONE/],
|
||||
['a section that uses a name it does not inject', { ...real, sectionSrc: sectionSrc.replace('</template>', '{{ notProvided }}</template>') }, /^E:/],
|
||||
['an element config that drops show-header', { ...real, element: { posterSectionConfig: (el) => { const c = element.posterSectionConfig(el); delete c.showHeader; return c } } }, /^D: show-header="false"/],
|
||||
['a view that does not pass show-header to the wall', { ...real, viewSrc: viewSrc.replace(':section-heads="showHeader"', '') }, /^F:/],
|
||||
|
|
|
|||
Loading…
Reference in a new issue