Pplr Data Maps: its verification hooks leave window when a view closes, so a closed view no longer keeps the whole app in memory
This commit is contained in:
parent
401b5d28d0
commit
c9c2280241
8 changed files with 31 additions and 15 deletions
|
|
@ -104,8 +104,10 @@ export function setProjectionFor(map, name) {
|
|||
// Verification handle (the gospel-resources __grState contract): what the ACTIVE view's map
|
||||
// actually did, so a check can assert "loaded" rather than inferring it from missing requests.
|
||||
// window.__pplrMap() -> { engine, loaded, styleLayers, pplrLayers }
|
||||
let _exposedMap = null // whose hook is on window, so releaseMap only clears its own
|
||||
export function exposeMap(map) {
|
||||
if (typeof window === 'undefined' || !map) return
|
||||
_exposedMap = map
|
||||
let loaded = false
|
||||
map.once('load', () => { loaded = true })
|
||||
window.__pplrMap = () => {
|
||||
|
|
@ -123,3 +125,11 @@ export function exposeMap(map) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Release the hook on unmount (a closure on window pins the whole app after the view is gone; rega
|
||||
// measured ~10 MB per mount). Only if it is still THIS map's: another view may have exposed its own since.
|
||||
export function releaseMap(map) {
|
||||
if (typeof window === 'undefined' || !map || _exposedMap !== map) return
|
||||
delete window.__pplrMap
|
||||
_exposedMap = null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { dataUrl, glFor, exposeMap, releaseMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { usePplrT } from '../composables/usePplrT.js'
|
||||
import { formatCount } from '@map/utils/formatCount.js' // counts stay fixed en-US: numerals are held for the Driver
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
|
|
@ -79,7 +79,7 @@ onMounted(async () => {
|
|||
map.value.getSource(sourceId).setData(fc)
|
||||
// Verification handle (the gospel-resources __grState contract): how many country
|
||||
// polygons found a coverage row. A key mismatch paints every country the "no data" grey.
|
||||
if (typeof window !== 'undefined') window.__pplrCoverage = () => ({
|
||||
if (typeof window !== 'undefined') window.__pplrCoverage = _coverageHook = () => ({
|
||||
polygons: fc.features.length,
|
||||
matched: fc.features.filter(f => f.properties.avgFilled != null).length,
|
||||
sampleUnmatched: fc.features.filter(f => f.properties.avgFilled == null).slice(0, 5).map(f => f.properties.GENCalpha3),
|
||||
|
|
@ -136,7 +136,13 @@ onMounted(async () => {
|
|||
}
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => destroy())
|
||||
let _coverageHook = null
|
||||
onBeforeUnmount(() => {
|
||||
releaseMap(map.value)
|
||||
// Release this view's own hook too (only if it is still ours).
|
||||
if (typeof window !== 'undefined' && window.__pplrCoverage === _coverageHook) delete window.__pplrCoverage
|
||||
destroy()
|
||||
})
|
||||
|
||||
const SCALE = [
|
||||
{ stop: '0', color: '#7f1d1d', label: '0 locales' },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn, setProjectionFor } from '../utils/pplrData.js'
|
||||
import { dataUrl, glFor, exposeMap, releaseMap, whenGeojsonDrawn, setProjectionFor } from '../utils/pplrData.js'
|
||||
import { usePplrT } from '../composables/usePplrT.js'
|
||||
import { useOptionalT } from '@map/composables/useOptionalT.js'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
|
|
@ -515,7 +515,7 @@ onMounted(async () => {
|
|||
}
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => { pinIndicator.destroy(); destroy() })
|
||||
onBeforeUnmount(() => { releaseMap(map.value); pinIndicator.destroy(); destroy() })
|
||||
|
||||
const LF_CSS = POPUP_CSS + `
|
||||
.pplr-popup h3 small { display: block; font-weight: 400; color: #6b7280; font-size: 11px; margin-top: 2px; }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Individual pins at all zoom levels; click pin for full Rosetta popup; hover country for highlight.
|
||||
*/
|
||||
import { inject, onMounted, onBeforeUnmount, ref } from 'vue'
|
||||
import { glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { glFor, exposeMap, releaseMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { usePplrT } from '../composables/usePplrT.js'
|
||||
import { formatCount } from '@map/utils/formatCount.js' // counts stay fixed en-US: numerals are held for the Driver
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
|
|
@ -68,7 +68,7 @@ onMounted(async () => {
|
|||
}
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => destroy())
|
||||
onBeforeUnmount(() => { releaseMap(map.value); destroy() })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn, setProjectionFor } from '../utils/pplrData.js'
|
||||
import { dataUrl, glFor, exposeMap, releaseMap, whenGeojsonDrawn, setProjectionFor } from '../utils/pplrData.js'
|
||||
import { usePplrT } from '../composables/usePplrT.js'
|
||||
import { religionFamilyLabel } from '@map/colors/religion.js'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
|
|
@ -296,7 +296,7 @@ onMounted(async () => {
|
|||
}
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => { pinIndicator.destroy(); destroy() })
|
||||
onBeforeUnmount(() => { releaseMap(map.value); pinIndicator.destroy(); destroy() })
|
||||
|
||||
const REL_CSS = POPUP_CSS + `
|
||||
.pplr-popup h3 small { display: block; font-weight: 400; color: #6b7280; font-size: 11px; margin-top: 2px; }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { dataUrl, glFor, exposeMap, setProjectionFor } from '../utils/pplrData.js'
|
||||
import { dataUrl, glFor, exposeMap, releaseMap, setProjectionFor } from '../utils/pplrData.js'
|
||||
import { usePplrT } from '../composables/usePplrT.js'
|
||||
import { useOptionalT } from '@map/composables/useOptionalT.js'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
|
|
@ -482,7 +482,7 @@ onMounted(async () => {
|
|||
}
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => { pinIndicator.destroy(); destroy() })
|
||||
onBeforeUnmount(() => { releaseMap(map.value); pinIndicator.destroy(); destroy() })
|
||||
|
||||
const TREE_POPUP_CSS = POPUP_CSS + `
|
||||
.pplr-popup h3 small { display: block; color: #6b7280; font-weight: 400; font-size: 11px; margin-top: 2px; }
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* Click any pin → popup with full Rosetta table.
|
||||
*/
|
||||
import { inject, onMounted, onBeforeUnmount, ref, computed } from 'vue'
|
||||
import { glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { glFor, exposeMap, releaseMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { usePplrT } from '../composables/usePplrT.js'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
import { useMapInstance } from '@map/composables/useMapInstance.js'
|
||||
|
|
@ -158,7 +158,7 @@ onMounted(async () => {
|
|||
}
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => destroy())
|
||||
onBeforeUnmount(() => { releaseMap(map.value); destroy() })
|
||||
|
||||
const LEGEND = computed(() => [
|
||||
{ color: '#fbbf24', label: t('pplr.rosetta.legend.all') },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { dataUrl, glFor, exposeMap, releaseMap, whenGeojsonDrawn } from '../utils/pplrData.js'
|
||||
import { usePplrT } from '../composables/usePplrT.js'
|
||||
import { tStatic } from '@map/i18n/index.js'
|
||||
/**
|
||||
|
|
@ -110,7 +110,7 @@ onMounted(async () => {
|
|||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => { pinIndicator.destroy(); destroy() })
|
||||
onBeforeUnmount(() => { releaseMap(map.value); pinIndicator.destroy(); destroy() })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
Loading…
Reference in a new issue