Merge pull request #1463 from umap-project/almet/js/client-routing

Add support for JS modules (+module for URLs handling)
This commit is contained in:
Yohan Boniface 2024-01-15 14:46:56 +01:00 committed by GitHub
commit 9054d35f0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 321 additions and 237 deletions

View file

@ -0,0 +1,13 @@
class UmapFragment extends HTMLElement {
connectedCallback() {
new L.U.Map(this.firstElementChild.id, JSON.parse(this.dataset.settings))
}
}
function register(Class, tagName) {
if ('customElements' in window && !customElements.get(tagName)) {
customElements.define(tagName, Class)
}
}
register(UmapFragment, 'umap-fragment')

View file

@ -0,0 +1,8 @@
import * as L from '../../vendors/leaflet/leaflet-src.esm.js'
import URLs from './urls.js'
// Import modules and export them to the global scope.
// For the not yet module-compatible JS out there.
// Copy the leaflet module, it's expected by leaflet plugins to be writeable.
window.L = { ...L }
window.umap = { URLs }

View file

@ -0,0 +1,29 @@
import { Util } from '../../vendors/leaflet/leaflet-src.esm.js'
export default class URLs {
constructor(serverUrls) {
this.urls = serverUrls
}
get(urlName, params) {
if (typeof this[urlName] === 'function') return this[urlName](params)
if (this.urls.hasOwnProperty(urlName)) {
return Util.template(this.urls[urlName], params)
} else {
throw `Unable to find a URL for route ${urlName}`
}
}
// Update if map_id is passed, create otherwise.
map_save({ map_id, ...options }) {
if (map_id) return this.get('map_update', { map_id, ...options })
return this.get('map_create')
}
// Update the layer if pk is passed, create otherwise.
datalayer_save({ map_id, pk }, ...options) {
if (pk) return this.get('datalayer_update', { map_id, pk }, ...options)
return this.get('datalayer_create', { map_id, pk }, ...options)
}
}

View file

@ -95,6 +95,7 @@ L.U.Map.include({
// After calling parent initialize, as we are doing initCenter our-selves // After calling parent initialize, as we are doing initCenter our-selves
if (geojson.geometry) this.options.center = this.latLng(geojson.geometry) if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
this.urls = new window.umap.URLs(this.options.urls)
this.ui = new L.U.UI(this._container) this.ui = new L.U.UI(this._container)
this.xhr = new L.U.Xhr(this.ui) this.xhr = new L.U.Xhr(this.ui)
@ -279,10 +280,12 @@ L.U.Map.include({
url.searchParams.delete('edit') url.searchParams.delete('edit')
history.pushState({}, '', url) history.pushState({}, '', url)
} }
if (L.Util.queryString('download')) if (L.Util.queryString('download')) {
window.location = L.Util.template(this.options.urls.map_download, { const download_url = this.urls.get('map_download', {
map_id: this.options.umap_id, map_id: this.options.umap_id,
}) })
window.location = download_url
}
}) })
window.onbeforeunload = () => this.isDirty || null window.onbeforeunload = () => this.isDirty || null
@ -1085,7 +1088,7 @@ L.U.Map.include({
formData.append('name', this.options.name) formData.append('name', this.options.name)
formData.append('center', JSON.stringify(this.geometry())) formData.append('center', JSON.stringify(this.geometry()))
formData.append('settings', JSON.stringify(geojson)) formData.append('settings', JSON.stringify(geojson))
this.post(this.getSaveUrl(), { this.post(this.urls.get('map_save', { map_id: this.options.umap_id }), {
data: formData, data: formData,
context: this, context: this,
callback: function (data) { callback: function (data) {
@ -1161,42 +1164,25 @@ L.U.Map.include({
}, },
sendEditLink: function () { sendEditLink: function () {
const url = L.Util.template(this.options.urls.map_send_edit_link, { const input = this.ui._alert.querySelector('input')
map_id: this.options.umap_id, const email = input.value
}),
input = this.ui._alert.querySelector('input'),
email = input.value
const formData = new FormData() const formData = new FormData()
formData.append('email', email) formData.append('email', email)
const url = this.urls.get('map_send_edit_link', { map_id: this.options.umap_id })
this.post(url, { this.post(url, {
data: formData, data: formData,
}) })
}, },
getEditUrl: function () {
return L.Util.template(this.options.urls.map_update, {
map_id: this.options.umap_id,
})
},
getCreateUrl: function () {
return L.Util.template(this.options.urls.map_create)
},
getSaveUrl: function () {
return (this.options.umap_id && this.getEditUrl()) || this.getCreateUrl()
},
star: function () { star: function () {
if (!this.options.umap_id) if (!this.options.umap_id)
return this.ui.alert({ return this.ui.alert({
content: L._('Please save the map first'), content: L._('Please save the map first'),
level: 'error', level: 'error',
}) })
let url = L.Util.template(this.options.urls.map_star, { const url = this.urls.get('map_star', { map_id: this.options.umap_id })
map_id: this.options.umap_id,
})
this.post(url, { this.post(url, {
context: this, context: this,
callback: function (data) { callback: function (data) {
@ -1804,9 +1790,7 @@ L.U.Map.include({
del: function () { del: function () {
if (confirm(L._('Are you sure you want to delete this map?'))) { if (confirm(L._('Are you sure you want to delete this map?'))) {
const url = L.Util.template(this.options.urls.map_delete, { const url = this.urls.get('map_delete', { map_id: this.options.umap_id })
map_id: this.options.umap_id,
})
this.post(url) this.post(url)
} }
}, },
@ -1815,9 +1799,7 @@ L.U.Map.include({
if ( if (
confirm(L._('Are you sure you want to clone this map and all its datalayers?')) confirm(L._('Are you sure you want to clone this map and all its datalayers?'))
) { ) {
const url = L.Util.template(this.options.urls.map_clone, { const url = this.urls.get('map_clone', { map_id: this.options.umap_id })
map_id: this.options.umap_id,
})
this.post(url) this.post(url)
} }
}, },
@ -1952,17 +1934,13 @@ L.U.Map.include({
}, },
openExternalRouting: function (e) { openExternalRouting: function (e) {
const url = this.options.urls.routing const url = this.urls.get('routing', {
if (url) {
const params = {
lat: e.latlng.lat, lat: e.latlng.lat,
lng: e.latlng.lng, lng: e.latlng.lng,
locale: L.locale, locale: L.locale,
zoom: this.getZoom(), zoom: this.getZoom(),
} })
window.open(L.Util.template(url, params)) if (url) window.open(url)
}
return
}, },
getMap: function () { getMap: function () {

View file

@ -1069,23 +1069,6 @@ L.U.DataLayer = L.Evented.extend({
}) })
}, },
getEditUrl: function () {
return L.Util.template(this.map.options.urls.datalayer_update, {
map_id: this.map.options.umap_id,
pk: this.umap_id,
})
},
getCreateUrl: function () {
return L.Util.template(this.map.options.urls.datalayer_create, {
map_id: this.map.options.umap_id,
})
},
getSaveUrl: function () {
return (this.umap_id && this.getEditUrl()) || this.getCreateUrl()
},
getColor: function () { getColor: function () {
return this.options.color || this.map.getOption('color') return this.options.color || this.map.getOption('color')
}, },
@ -1577,7 +1560,11 @@ L.U.DataLayer = L.Evented.extend({
// Filename support is shaky, don't do it for now. // Filename support is shaky, don't do it for now.
const blob = new Blob([JSON.stringify(geojson)], { type: 'application/json' }) const blob = new Blob([JSON.stringify(geojson)], { type: 'application/json' })
formData.append('geojson', blob) formData.append('geojson', blob)
this.map.post(this.getSaveUrl(), { const saveUrl = this.map.urls.get('datalayer_save', {
map_id: this.map.options.umap_id,
pk: this.umap_id,
})
this.map.post(saveUrl, {
data: formData, data: formData,
callback: function (data, response) { callback: function (data, response) {
// Response contains geojson only if save has conflicted and conflicts have // Response contains geojson only if save has conflicted and conflicts have

View file

@ -0,0 +1,54 @@
import URLs from '../js/modules/urls.js'
describe('URLs', () => {
// Mock server URLs that will be used for testing
const mockServerUrls = {
map_create: '/maps/create',
map_update: '/maps/{map_id}/update',
datalayer_create: '/maps/{map_id}/datalayers/create',
datalayer_update: '/maps/{map_id}/datalayers/{pk}/update',
}
let urls = new URLs(mockServerUrls)
describe('get()', () => {
it('should throw an error if the urlName does not exist', () => {
expect(() => urls.get('non_existent')).to.throw()
})
it('should return the correct templated URL for known urlNames', () => {
expect(urls.get('map_create')).to.be.equal('/maps/create')
expect(urls.get('map_update', { map_id: '123' })).to.be.equal('/maps/123/update')
})
it('should return the correct templated URL when provided with parameters', () => {
expect(urls.get('datalayer_update', { map_id: '123', pk: '456' })).to.be.equal(
'/maps/123/datalayers/456/update'
)
})
})
describe('map_save()', () => {
it('should return the create URL if no map_id is provided', () => {
expect(urls.map_save({})).to.be.equal('/maps/create')
})
it('should return the update URL if a map_id is provided', () => {
expect(urls.map_save({ map_id: '123' })).to.be.equal('/maps/123/update')
})
})
describe('datalayer_save()', () => {
it('should return the create URL if no pk is provided', () => {
expect(urls.datalayer_save({ map_id: '123' })).to.be.equal(
'/maps/123/datalayers/create'
)
})
it('should return the update URL if a pk is provided', () => {
expect(urls.datalayer_save({ map_id: '123', pk: '456' })).to.be.equal(
'/maps/123/datalayers/456/update'
)
})
})
})

View file

@ -86,7 +86,7 @@ describe('L.Util', function () {
it('should handle target option', function () { it('should handle target option', function () {
assert.equal( assert.equal(
L.Util.toHTML('A simple http://osm.org link', {target: 'self'}), L.Util.toHTML('A simple http://osm.org link', { target: 'self' }),
'A simple <a href="http://osm.org" target="_self">http://osm.org</a> link' 'A simple <a href="http://osm.org" target="_self">http://osm.org</a> link'
) )
}) })
@ -257,8 +257,8 @@ describe('L.Util', function () {
it('should accept non ascii chars', function () { it('should accept non ascii chars', function () {
assert.equal( assert.equal(
L.Util.greedyTemplate('A phrase with a {Accessibilité} and {переменная}.', { L.Util.greedyTemplate('A phrase with a {Accessibilité} and {переменная}.', {
'Accessibilité': 'value', Accessibilité: 'value',
'переменная': 'another', переменная: 'another',
}), }),
'A phrase with a value and another.' 'A phrase with a value and another.'
) )
@ -475,70 +475,72 @@ describe('L.Util', function () {
}) })
}) })
describe("#normalize()", function () { describe('#normalize()', function () {
if (
if('should remove accents', function () { ('should remove accents',
function () {
// French é // French é
assert.equal(L.Util.normalize('aéroport'), 'aeroport') assert.equal(L.Util.normalize('aéroport'), 'aeroport')
// American é // American é
assert.equal(L.Util.normalize('aéroport'), 'aeroport') assert.equal(L.Util.normalize('aéroport'), 'aeroport')
}) })
);
}) })
describe("#sortFeatures()", function () { describe('#sortFeatures()', function () {
let feat1, feat2, feat3 let feat1, feat2, feat3
before(function () { before(function () {
feat1 = {properties: {}} feat1 = { properties: {} }
feat2 = {properties: {}} feat2 = { properties: {} }
feat3 = {properties: {}} feat3 = { properties: {} }
}) })
it('should sort feature from custom key', function () { it('should sort feature from custom key', function () {
feat1.properties.mykey = "13. foo" feat1.properties.mykey = '13. foo'
feat2.properties.mykey = "7. foo" feat2.properties.mykey = '7. foo'
feat3.properties.mykey = "111. foo" feat3.properties.mykey = '111. foo'
let features = L.Util.sortFeatures([feat1, feat2, feat3], "mykey") let features = L.Util.sortFeatures([feat1, feat2, feat3], 'mykey')
assert.equal(features[0], feat2) assert.equal(features[0], feat2)
assert.equal(features[1], feat1) assert.equal(features[1], feat1)
assert.equal(features[2], feat3) assert.equal(features[2], feat3)
}) })
it('should sort feature from multiple keys', function () { it('should sort feature from multiple keys', function () {
feat1.properties.mykey = "13. foo" feat1.properties.mykey = '13. foo'
feat2.properties.mykey = "111. foo" feat2.properties.mykey = '111. foo'
feat3.properties.mykey = "111. foo" feat3.properties.mykey = '111. foo'
feat1.properties.otherkey = "C" feat1.properties.otherkey = 'C'
feat2.properties.otherkey = "B" feat2.properties.otherkey = 'B'
feat3.properties.otherkey = "A" feat3.properties.otherkey = 'A'
let features = L.Util.sortFeatures([feat1, feat2, feat3], "mykey,otherkey") let features = L.Util.sortFeatures([feat1, feat2, feat3], 'mykey,otherkey')
assert.equal(features[0], feat1) assert.equal(features[0], feat1)
assert.equal(features[1], feat3) assert.equal(features[1], feat3)
assert.equal(features[2], feat2) assert.equal(features[2], feat2)
}) })
it('should sort feature from custom key reverse', function () { it('should sort feature from custom key reverse', function () {
feat1.properties.mykey = "13. foo" feat1.properties.mykey = '13. foo'
feat2.properties.mykey = "7. foo" feat2.properties.mykey = '7. foo'
feat3.properties.mykey = "111. foo" feat3.properties.mykey = '111. foo'
let features = L.Util.sortFeatures([feat1, feat2, feat3], "-mykey") let features = L.Util.sortFeatures([feat1, feat2, feat3], '-mykey')
assert.equal(features[0], feat3) assert.equal(features[0], feat3)
assert.equal(features[1], feat1) assert.equal(features[1], feat1)
assert.equal(features[2], feat2) assert.equal(features[2], feat2)
}) })
it('should sort feature from multiple keys with reverse', function () { it('should sort feature from multiple keys with reverse', function () {
feat1.properties.mykey = "13. foo" feat1.properties.mykey = '13. foo'
feat2.properties.mykey = "111. foo" feat2.properties.mykey = '111. foo'
feat3.properties.mykey = "111. foo" feat3.properties.mykey = '111. foo'
feat1.properties.otherkey = "C" feat1.properties.otherkey = 'C'
feat2.properties.otherkey = "B" feat2.properties.otherkey = 'B'
feat3.properties.otherkey = "A" feat3.properties.otherkey = 'A'
let features = L.Util.sortFeatures([feat1, feat2, feat3], "mykey,-otherkey") let features = L.Util.sortFeatures([feat1, feat2, feat3], 'mykey,-otherkey')
assert.equal(features[0], feat1) assert.equal(features[0], feat1)
assert.equal(features[1], feat2) assert.equal(features[1], feat2)
assert.equal(features[2], feat3) assert.equal(features[2], feat3)
}) })
it('should sort feature with space first', function () { it('should sort feature with space first', function () {
feat1.properties.mykey = "1 foo" feat1.properties.mykey = '1 foo'
feat2.properties.mykey = "2 foo" feat2.properties.mykey = '2 foo'
feat3.properties.mykey = "1a foo" feat3.properties.mykey = '1a foo'
let features = L.Util.sortFeatures([feat1, feat2, feat3], "mykey") let features = L.Util.sortFeatures([feat1, feat2, feat3], 'mykey')
assert.equal(features[0], feat1) assert.equal(features[0], feat1)
assert.equal(features[1], feat3) assert.equal(features[1], feat3)
assert.equal(features[2], feat2) assert.equal(features[2], feat2)

View file

@ -1,57 +1,60 @@
<!DOCTYPE html>
<html> <html>
<head> <head>
<title>Umap front Tests</title> <title>Umap front Tests</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<script src="../vendors/leaflet/leaflet-src.js"></script> <script type="module" src="../js/modules/global.js" defer></script>
<script src="../vendors/editable/Path.Drag.js"></script> <script src="../vendors/editable/Path.Drag.js" defer></script>
<script src="../vendors/editable/Leaflet.Editable.js"></script> <script src="../vendors/editable/Leaflet.Editable.js" defer></script>
<script src="../vendors/hash/leaflet-hash.js"></script> <script src="../vendors/hash/leaflet-hash.js" defer></script>
<script src="../vendors/i18n/Leaflet.i18n.js"></script> <script src="../vendors/i18n/Leaflet.i18n.js" defer></script>
<script src="../vendors/editinosm/Leaflet.EditInOSM.js"></script> <script src="../vendors/editinosm/Leaflet.EditInOSM.js" defer></script>
<script src="../vendors/minimap/Control.MiniMap.js"></script> <script src="../vendors/minimap/Control.MiniMap.js" defer></script>
<script src="../vendors/csv2geojson/csv2geojson.js"></script> <script src="../vendors/csv2geojson/csv2geojson.js" defer></script>
<script src="../vendors/togeojson/togeojson.js"></script> <script src="../vendors/togeojson/togeojson.js" defer></script>
<script src="../vendors/osmtogeojson/osmtogeojson.js"></script> <script src="../vendors/osmtogeojson/osmtogeojson.js" defer></script>
<script src="../vendors/contextmenu/leaflet.contextmenu.js"></script> <script src="../vendors/contextmenu/leaflet.contextmenu.js" defer></script>
<script src="../vendors/loading/Control.Loading.js"></script> <script src="../vendors/loading/Control.Loading.js" defer></script>
<script src="../vendors/markercluster/leaflet.markercluster-src.js"></script> <script src="../vendors/markercluster/leaflet.markercluster-src.js" defer></script>
<script src="../vendors/photon/leaflet.photon.js"></script> <script src="../vendors/photon/leaflet.photon.js" defer></script>
<script src="../vendors/heat/leaflet-heat.js"></script> <script src="../vendors/heat/leaflet-heat.js" defer></script>
<script src="../vendors/fullscreen/Leaflet.fullscreen.js"></script> <script src="../vendors/fullscreen/Leaflet.fullscreen.js" defer></script>
<script src="../vendors/toolbar/leaflet.toolbar-src.js"></script> <script src="../vendors/toolbar/leaflet.toolbar-src.js" defer></script>
<script src="../vendors/formbuilder/Leaflet.FormBuilder.js"></script> <script src="../vendors/formbuilder/Leaflet.FormBuilder.js" defer></script>
<script src="../vendors/measurable/Leaflet.Measurable.js"></script> <script src="../vendors/measurable/Leaflet.Measurable.js" defer></script>
<script src="../vendors/iconlayers/iconLayers.js"></script> <script src="../vendors/locatecontrol/L.Control.Locate.js" defer></script>
<script src="../vendors/locatecontrol/L.Control.Locate.js"></script> <script src="../vendors/dompurify/purify.js" defer></script>
<script src="../vendors/dompurify/purify.js"></script> <script src="../vendors/togpx/togpx.js" defer></script>
<script src="../vendors/togpx/togpx.js"></script> <script src="../vendors/tokml/tokml.js" defer></script>
<script src="../vendors/tokml/tokml.js"></script> <script src="../vendors/iconlayers/iconLayers.js" defer></script>
<script src="../vendors/simple-statistics/simple-statistics.min.js"></script> <script src="../vendors/simple-statistics/simple-statistics.min.js" defer></script>
<script src="../vendors/colorbrewer/colorbrewer.js"></script> <script src="../vendors/colorbrewer/colorbrewer.js" defer></script>
<script src="../js/umap.core.js"></script> <script src="../js/umap.core.js" defer></script>
<script src="../js/umap.autocomplete.js"></script> <script src="../js/umap.autocomplete.js" defer></script>
<script src="../js/umap.popup.js"></script> <script src="../js/umap.popup.js" defer></script>
<script src="../js/umap.xhr.js"></script> <script src="../js/umap.xhr.js" defer></script>
<script src="../js/umap.forms.js"></script> <script src="../js/umap.forms.js" defer></script>
<script src="../js/umap.icon.js"></script> <script src="../js/umap.icon.js" defer></script>
<script src="../js/umap.features.js"></script> <script src="../js/umap.features.js" defer></script>
<script src="../js/umap.layer.js"></script> <script src="../js/umap.layer.js" defer></script>
<script src="../js/umap.controls.js"></script> <script src="../js/umap.controls.js" defer></script>
<script src="../js/umap.slideshow.js"></script> <script src="../js/umap.slideshow.js" defer></script>
<script src="../js/umap.tableeditor.js"></script> <script src="../js/umap.tableeditor.js" defer></script>
<script src="../js/umap.permissions.js"></script> <script src="../js/umap.permissions.js" defer></script>
<script src="../js/umap.datalayer.permissions.js"></script> <script src="../js/umap.datalayer.permissions.js" defer></script>
<script src="../js/umap.browser.js"></script> <script src="../js/umap.browser.js" defer></script>
<script src="../js/umap.importer.js"></script> <script src="../js/umap.importer.js" defer></script>
<script src="../js/umap.share.js"></script> <script src="../js/umap.share.js" defer></script>
<script src="../js/umap.js"></script> <script src="../js/umap.js" defer></script>
<script src="../js/umap.ui.js"></script> <script src="../js/umap.ui.js" defer></script>
<link rel="stylesheet" href="../vendors/leaflet/leaflet.css" /> <link rel="stylesheet" href="../vendors/leaflet/leaflet.css" />
<link rel="stylesheet" href="../vendors/minimap/Control.MiniMap.css" /> <link rel="stylesheet" href="../vendors/minimap/Control.MiniMap.css" />
<link rel="stylesheet" href="../vendors/editinosm/Leaflet.EditInOSM.css" /> <link rel="stylesheet" href="../vendors/editinosm/Leaflet.EditInOSM.css" />
<link rel="stylesheet" href="../vendors/markercluster/MarkerCluster.css" /> <link rel="stylesheet" href="../vendors/markercluster/MarkerCluster.css" />
<link rel="stylesheet" href="../vendors/markercluster/MarkerCluster.Default.css" /> <link rel="stylesheet"
<link rel="stylesheet" href="../vendors/contextmenu/leaflet.contextmenu.css" /> href="../vendors/markercluster/MarkerCluster.Default.css" />
<link rel="stylesheet"
href="../vendors/contextmenu/leaflet.contextmenu.css" />
<link rel="stylesheet" href="../vendors/toolbar/leaflet.toolbar.css" /> <link rel="stylesheet" href="../vendors/toolbar/leaflet.toolbar.css" />
<link rel="stylesheet" href="../vendors/measurable/Leaflet.Measurable.css" /> <link rel="stylesheet" href="../vendors/measurable/Leaflet.Measurable.css" />
<link rel="stylesheet" href="../vendors/iconlayers/iconLayers.css" /> <link rel="stylesheet" href="../vendors/iconlayers/iconLayers.css" />
@ -61,7 +64,6 @@
<link rel="stylesheet" href="../../umap/nav.css" /> <link rel="stylesheet" href="../../umap/nav.css" />
<link rel="stylesheet" href="../../umap/map.css" /> <link rel="stylesheet" href="../../umap/map.css" />
<link rel="stylesheet" href="../../umap/theme.css" /> <link rel="stylesheet" href="../../umap/theme.css" />
<script src="../../../../node_modules/sinon/pkg/sinon.js"></script> <script src="../../../../node_modules/sinon/pkg/sinon.js"></script>
<script src="../../../../node_modules/mocha/mocha.js"></script> <script src="../../../../node_modules/mocha/mocha.js"></script>
<script src="../../../../node_modules/chai/chai.js"></script> <script src="../../../../node_modules/chai/chai.js"></script>
@ -75,20 +77,21 @@
}) })
chai.config.includeStack = true chai.config.includeStack = true
</script> </script>
<script src="./_pre.js"></script> <script src="./_pre.js" defer></script>
<script src="./Map.js"></script> <script src="./Map.js" defer></script>
<script src="./Map.Init.js"></script> <script src="./Map.Init.js" defer></script>
<script src="./Map.Export.js"></script> <script src="./Map.Export.js" defer></script>
<script src="./DataLayer.js"></script> <script src="./DataLayer.js" defer></script>
<script src="./TableEditor.js"></script> <script src="./TableEditor.js" defer></script>
<script src="./Feature.js"></script> <script src="./Feature.js" defer></script>
<script src="./Marker.js"></script> <script src="./Marker.js" defer></script>
<script src="./Polyline.js"></script> <script src="./Polyline.js" defer></script>
<script src="./Polygon.js"></script> <script src="./Polygon.js" defer></script>
<script src="./Util.js"></script> <script src="./Util.js" defer></script>
<script src="./Controls.js"></script> <script src="./Controls.js" defer></script>
<script src="./Permissions.js"></script> <script src="./Permissions.js" defer></script>
<script src="./Choropleth.js"></script> <script src="./Choropleth.js" defer></script>
<script type="module" src="./URLs.js" defer></script>
<style type="text/css"> <style type="text/css">
#mocha { #mocha {
position: absolute; position: absolute;
@ -102,6 +105,7 @@
overflow-y: auto; overflow-y: auto;
display: none; display: none;
} }
#mocha-stats { #mocha-stats {
position: absolute; position: absolute;
} }

View file

@ -38,6 +38,8 @@
{% block bottom_js %} {% block bottom_js %}
{{ block.super }} {{ block.super }}
<script type="text/javascript"> <script type="text/javascript">
window.addEventListener('DOMContentLoaded', (event => {
!(function () { !(function () {
const ui = new L.U.UI(document.querySelector('header')) const ui = new L.U.UI(document.querySelector('header'))
const xhr = new L.U.Xhr(ui) const xhr = new L.U.Xhr(ui)
@ -66,12 +68,6 @@
callback: function (data) { callback: function (data) {
const container = this.parentNode const container = this.parentNode
container.innerHTML = data container.innerHTML = data
Array.prototype.forEach.call(
container.querySelectorAll('script:not([type="application/json"])'),
function (item) {
eval(item.firstChild.textContent)
}
)
const more = document.querySelector('.more_button') const more = document.querySelector('.more_button')
if (more) { if (more) {
L.DomEvent.on(more, 'click', getMore, more) L.DomEvent.on(more, 'click', getMore, more)
@ -85,6 +81,8 @@
L.DomEvent.on(more, 'click', getMore, more) L.DomEvent.on(more, 'click', getMore, more)
} }
})(this) })(this)
}
))
</script> </script>
{% endblock bottom_js %} {% endblock bottom_js %}
{% block footer %} {% block footer %}

View file

@ -1,51 +1,62 @@
{% load compress %} {% load compress %}
{% compress js %} {% compress js %}
<script src="{{ STATIC_URL }}umap/vendors/leaflet/leaflet-src.js"></script> <script type="module" src="{{ STATIC_URL }}umap/js/modules/global.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/editable/Path.Drag.js"></script> <script src="{{ STATIC_URL }}umap/vendors/editable/Path.Drag.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/editable/Leaflet.Editable.js"></script> <script src="{{ STATIC_URL }}umap/vendors/editable/Leaflet.Editable.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/hash/leaflet-hash.js"></script> <script src="{{ STATIC_URL }}umap/vendors/hash/leaflet-hash.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/i18n/Leaflet.i18n.js"></script> <script src="{{ STATIC_URL }}umap/vendors/i18n/Leaflet.i18n.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/editinosm/Leaflet.EditInOSM.js"></script> <script src="{{ STATIC_URL }}umap/vendors/editinosm/Leaflet.EditInOSM.js"
<script src="{{ STATIC_URL }}umap/vendors/minimap/Control.MiniMap.js"></script> defer></script>
<script src="{{ STATIC_URL }}umap/vendors/csv2geojson/csv2geojson.js"></script> <script src="{{ STATIC_URL }}umap/vendors/minimap/Control.MiniMap.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/togeojson/togeojson.js"></script> <script src="{{ STATIC_URL }}umap/vendors/csv2geojson/csv2geojson.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/osmtogeojson/osmtogeojson.js"></script> <script src="{{ STATIC_URL }}umap/vendors/togeojson/togeojson.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/loading/Control.Loading.js"></script> <script src="{{ STATIC_URL }}umap/vendors/osmtogeojson/osmtogeojson.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/markercluster/leaflet.markercluster-src.js"></script> <script src="{{ STATIC_URL }}umap/vendors/loading/Control.Loading.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/contextmenu/leaflet.contextmenu.js"></script> <script src="{{ STATIC_URL }}umap/vendors/markercluster/leaflet.markercluster-src.js"
<script src="{{ STATIC_URL }}umap/vendors/photon/leaflet.photon.js"></script> defer></script>
<script src="{{ STATIC_URL }}umap/vendors/georsstogeojson/GeoRSSToGeoJSON.js"></script> <script src="{{ STATIC_URL }}umap/vendors/contextmenu/leaflet.contextmenu.js"
<script src="{{ STATIC_URL }}umap/vendors/heat/leaflet-heat.js"></script> defer></script>
<script src="{{ STATIC_URL }}umap/vendors/fullscreen/Leaflet.fullscreen.js"></script> <script src="{{ STATIC_URL }}umap/vendors/photon/leaflet.photon.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/toolbar/leaflet.toolbar-src.js"></script> <script src="{{ STATIC_URL }}umap/vendors/georsstogeojson/GeoRSSToGeoJSON.js"
<script src="{{ STATIC_URL }}umap/vendors/formbuilder/Leaflet.FormBuilder.js"></script> defer></script>
<script src="{{ STATIC_URL }}umap/vendors/measurable/Leaflet.Measurable.js"></script> <script src="{{ STATIC_URL }}umap/vendors/heat/leaflet-heat.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/iconlayers/iconLayers.js"></script> <script src="{{ STATIC_URL }}umap/vendors/fullscreen/Leaflet.fullscreen.js"
<script src="{{ STATIC_URL }}umap/vendors/togpx/togpx.js"></script> defer></script>
<script src="{{ STATIC_URL }}umap/vendors/tokml/tokml.js"></script> <script src="{{ STATIC_URL }}umap/vendors/toolbar/leaflet.toolbar-src.js"
<script src="{{ STATIC_URL }}umap/vendors/locatecontrol/L.Control.Locate.js"></script> defer></script>
<script src="{{ STATIC_URL }}umap/vendors/dompurify/purify.js"></script> <script src="{{ STATIC_URL }}umap/vendors/formbuilder/Leaflet.FormBuilder.js"
<script src="{{ STATIC_URL }}umap/vendors/colorbrewer/colorbrewer.js"></script> defer></script>
<script src="{{ STATIC_URL }}umap/vendors/simple-statistics/simple-statistics.min.js"></script> <script src="{{ STATIC_URL }}umap/vendors/measurable/Leaflet.Measurable.js"
defer></script>
<script src="{{ STATIC_URL }}umap/vendors/togpx/togpx.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/iconlayers/iconLayers.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/tokml/tokml.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/locatecontrol/L.Control.Locate.js"
defer></script>
<script src="{{ STATIC_URL }}umap/vendors/dompurify/purify.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/colorbrewer/colorbrewer.js" defer></script>
<script src="{{ STATIC_URL }}umap/vendors/simple-statistics/simple-statistics.min.js"
defer></script>
{% endcompress %} {% endcompress %}
{% if locale %}<script src="{{ STATIC_URL }}umap/locale/{{ locale }}.js"></script>{% endif %} {% if locale %}<script src="{{ STATIC_URL }}umap/locale/{{ locale }}.js" defer></script>{% endif %}
{% compress js %} {% compress js %}
<script src="{{ STATIC_URL }}umap/js/umap.core.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.core.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.autocomplete.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.autocomplete.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.popup.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.popup.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.xhr.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.xhr.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.forms.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.forms.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.icon.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.icon.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.features.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.features.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.permissions.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.permissions.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.datalayer.permissions.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.datalayer.permissions.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.layer.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.layer.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.controls.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.controls.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.slideshow.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.slideshow.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.tableeditor.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.tableeditor.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.browser.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.browser.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.importer.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.importer.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.share.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.share.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/umap.ui.js"></script> <script src="{{ STATIC_URL }}umap/js/umap.ui.js" defer></script>
<script src="{{ STATIC_URL }}umap/js/components/fragment.js" defer></script>
{% endcompress %} {% endcompress %}

View file

@ -1,7 +1,4 @@
{% load umap_tags %} {% load umap_tags %}
<div id="{{ unique_id }}" class="map_fragment"></div> <umap-fragment data-settings='{{ map_settings|escape }}'>
<!-- djlint:off --> <div id="{{ unique_id }}" class="map_fragment"></div>
<script type="text/javascript"> </umap-fragment>
new L.U.Map("{{ unique_id }}", {{ map_settings|notag|safe }})
</script>
<!-- djlint:on -->

View file

@ -1,7 +1,10 @@
{% load umap_tags %} {% load umap_tags %}
<div id="map"></div> <div id="map"></div>
<!-- djlint:off --> <!-- djlint:off -->
<script type="text/javascript"> <script defer type="text/javascript">
let MAP = new L.U.Map("map", {{ map_settings|notag|safe }}) let MAP
window.addEventListener('DOMContentLoaded', (event) => {
MAP = new L.U.Map("map", {{ map_settings|notag|safe }});
});
</script> </script>
<!-- djlint:on --> <!-- djlint:on -->