umap-project 2.4.0b2__py3-none-any.whl → 2.4.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (129) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/el/LC_MESSAGES/django.po +145 -90
  3. umap/locale/en/LC_MESSAGES/django.po +3 -3
  4. umap/locale/eu/LC_MESSAGES/django.po +145 -89
  5. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/pt/LC_MESSAGES/django.po +87 -37
  7. umap/static/umap/base.css +20 -6
  8. umap/static/umap/content.css +2 -2
  9. umap/static/umap/css/dialog.css +1 -1
  10. umap/static/umap/css/importers.css +2 -0
  11. umap/static/umap/css/panel.css +2 -2
  12. umap/static/umap/css/tooltip.css +1 -1
  13. umap/static/umap/img/16-white.svg +1 -3
  14. umap/static/umap/img/source/16-white.svg +2 -4
  15. umap/static/umap/js/components/alerts/alert.css +1 -1
  16. umap/static/umap/js/components/alerts/alert.js +1 -1
  17. umap/static/umap/js/modules/autocomplete.js +4 -4
  18. umap/static/umap/js/modules/browser.js +11 -11
  19. umap/static/umap/js/modules/caption.js +5 -5
  20. umap/static/umap/js/modules/dompurify.js +2 -3
  21. umap/static/umap/js/modules/facets.js +16 -10
  22. umap/static/umap/js/modules/global.js +16 -16
  23. umap/static/umap/js/modules/help.js +2 -2
  24. umap/static/umap/js/modules/importer.js +6 -6
  25. umap/static/umap/js/modules/importers/geodatamine.js +4 -4
  26. umap/static/umap/js/modules/importers/overpass.js +2 -2
  27. umap/static/umap/js/modules/orderable.js +2 -2
  28. umap/static/umap/js/modules/request.js +1 -1
  29. umap/static/umap/js/modules/rules.js +13 -10
  30. umap/static/umap/js/modules/sync/engine.js +3 -3
  31. umap/static/umap/js/modules/sync/updaters.js +10 -11
  32. umap/static/umap/js/modules/sync/websocket.js +1 -1
  33. umap/static/umap/js/modules/ui/dialog.js +1 -1
  34. umap/static/umap/js/modules/ui/panel.js +1 -1
  35. umap/static/umap/js/modules/ui/tooltip.js +6 -6
  36. umap/static/umap/js/modules/urls.js +1 -2
  37. umap/static/umap/js/modules/utils.js +19 -19
  38. umap/static/umap/js/umap.controls.js +26 -28
  39. umap/static/umap/js/umap.core.js +19 -15
  40. umap/static/umap/js/umap.datalayer.permissions.js +15 -18
  41. umap/static/umap/js/umap.features.js +102 -120
  42. umap/static/umap/js/umap.forms.js +46 -74
  43. umap/static/umap/js/umap.icon.js +17 -22
  44. umap/static/umap/js/umap.js +126 -131
  45. umap/static/umap/js/umap.layer.js +159 -167
  46. umap/static/umap/js/umap.permissions.js +6 -9
  47. umap/static/umap/js/umap.popup.js +20 -20
  48. umap/static/umap/js/umap.share.js +9 -15
  49. umap/static/umap/js/umap.slideshow.js +12 -14
  50. umap/static/umap/js/umap.tableeditor.js +5 -5
  51. umap/static/umap/locale/am_ET.json +5 -2
  52. umap/static/umap/locale/ar.json +5 -2
  53. umap/static/umap/locale/ast.json +5 -2
  54. umap/static/umap/locale/bg.json +5 -2
  55. umap/static/umap/locale/br.json +5 -2
  56. umap/static/umap/locale/ca.json +5 -2
  57. umap/static/umap/locale/cs_CZ.json +5 -2
  58. umap/static/umap/locale/da.json +5 -2
  59. umap/static/umap/locale/de.json +5 -2
  60. umap/static/umap/locale/el.json +10 -7
  61. umap/static/umap/locale/en.js +2 -1
  62. umap/static/umap/locale/en.json +5 -2
  63. umap/static/umap/locale/en_US.json +5 -2
  64. umap/static/umap/locale/es.js +9 -8
  65. umap/static/umap/locale/es.json +12 -9
  66. umap/static/umap/locale/et.json +5 -2
  67. umap/static/umap/locale/fa_IR.json +5 -2
  68. umap/static/umap/locale/fi.json +5 -2
  69. umap/static/umap/locale/fr.js +2 -1
  70. umap/static/umap/locale/fr.json +5 -2
  71. umap/static/umap/locale/gl.json +5 -2
  72. umap/static/umap/locale/he.json +5 -2
  73. umap/static/umap/locale/hr.json +5 -2
  74. umap/static/umap/locale/hu.json +5 -2
  75. umap/static/umap/locale/id.json +5 -2
  76. umap/static/umap/locale/is.json +5 -2
  77. umap/static/umap/locale/it.json +5 -2
  78. umap/static/umap/locale/ja.json +5 -2
  79. umap/static/umap/locale/ko.json +5 -2
  80. umap/static/umap/locale/lt.json +5 -2
  81. umap/static/umap/locale/ms.json +5 -2
  82. umap/static/umap/locale/nl.json +5 -2
  83. umap/static/umap/locale/no.json +5 -2
  84. umap/static/umap/locale/pl.json +5 -2
  85. umap/static/umap/locale/pl_PL.json +5 -2
  86. umap/static/umap/locale/pt.js +61 -60
  87. umap/static/umap/locale/pt.json +64 -61
  88. umap/static/umap/locale/pt_BR.json +5 -2
  89. umap/static/umap/locale/pt_PT.json +5 -2
  90. umap/static/umap/locale/ro.json +5 -2
  91. umap/static/umap/locale/ru.json +5 -2
  92. umap/static/umap/locale/sk_SK.json +5 -2
  93. umap/static/umap/locale/sl.json +5 -2
  94. umap/static/umap/locale/sr.json +5 -2
  95. umap/static/umap/locale/sv.json +5 -2
  96. umap/static/umap/locale/th_TH.json +5 -2
  97. umap/static/umap/locale/tr.json +5 -2
  98. umap/static/umap/locale/uk_UA.json +5 -2
  99. umap/static/umap/locale/vi.json +5 -2
  100. umap/static/umap/locale/vi_VN.json +5 -2
  101. umap/static/umap/locale/zh.json +5 -2
  102. umap/static/umap/locale/zh_CN.json +5 -2
  103. umap/static/umap/locale/zh_TW.Big5.json +5 -2
  104. umap/static/umap/locale/zh_TW.json +5 -2
  105. umap/static/umap/map.css +22 -22
  106. umap/static/umap/unittests/utils.js +5 -5
  107. umap/static/umap/vars.css +12 -1
  108. umap/storage.py +1 -1
  109. umap/tests/integration/test_browser.py +76 -3
  110. umap/tests/integration/test_edit_polygon.py +11 -0
  111. umap/tests/integration/test_map.py +29 -0
  112. umap/tests/integration/test_map_preview.py +36 -2
  113. umap/tests/integration/test_view_marker.py +2 -2
  114. umap/tests/test_views.py +2 -2
  115. umap/views.py +3 -2
  116. {umap_project-2.4.0b2.dist-info → umap_project-2.4.2.dist-info}/METADATA +3 -3
  117. {umap_project-2.4.0b2.dist-info → umap_project-2.4.2.dist-info}/RECORD +120 -129
  118. {umap_project-2.4.0b2.dist-info → umap_project-2.4.2.dist-info}/WHEEL +1 -1
  119. umap/.DS_Store +0 -0
  120. umap/static/.DS_Store +0 -0
  121. umap/static/umap/.DS_Store +0 -0
  122. umap/static/umap/favicons/.DS_Store +0 -0
  123. umap/static/umap/fonts/.DS_Store +0 -0
  124. umap/static/umap/img/.DS_Store +0 -0
  125. umap/static/umap/img/source/.DS_Store +0 -0
  126. umap/tests/.DS_Store +0 -0
  127. umap/tests/integration/.DS_Store +0 -0
  128. {umap_project-2.4.0b2.dist-info → umap_project-2.4.2.dist-info}/entry_points.txt +0 -0
  129. {umap_project-2.4.0b2.dist-info → umap_project-2.4.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,5 @@
1
1
  L.Map.mergeOptions({
2
- overlay: null,
2
+ overlay: {},
3
3
  datalayers: [],
4
4
  hash: true,
5
5
  maxZoomLimit: 24,
@@ -13,7 +13,7 @@ L.Map.mergeOptions({
13
13
  // we cannot rely on this because of the y is overriden by Leaflet
14
14
  // See https://github.com/Leaflet/Leaflet/pull/9201
15
15
  // And let's remove this -y when this PR is merged and released.
16
- demoTileInfos: { 's': 'a', 'z': 9, 'x': 265, 'y': 181, '-y': 181, 'r': '' },
16
+ demoTileInfos: { s: 'a', z: 9, x: 265, y: 181, '-y': 181, r: '' },
17
17
  licences: [],
18
18
  licence: '',
19
19
  enableMarkerDraw: true,
@@ -83,18 +83,15 @@ U.Map = L.Map.extend({
83
83
  }
84
84
 
85
85
  let editedFeature = null
86
- const self = this
87
86
  try {
88
87
  Object.defineProperty(this, 'editedFeature', {
89
- get: function () {
90
- return editedFeature
91
- },
92
- set: function (feature) {
88
+ get: () => editedFeature,
89
+ set: (feature) => {
93
90
  if (editedFeature && editedFeature !== feature) {
94
91
  editedFeature.endEdit()
95
92
  }
96
93
  editedFeature = feature
97
- self.fire('seteditedfeature')
94
+ this.fire('seteditedfeature')
98
95
  },
99
96
  })
100
97
  } catch (e) {
@@ -102,11 +99,7 @@ U.Map = L.Map.extend({
102
99
  }
103
100
 
104
101
  // Retrocompat
105
- if (
106
- this.options.slideshow &&
107
- this.options.slideshow.delay &&
108
- this.options.slideshow.active === undefined
109
- ) {
102
+ if (this.options.slideshow?.delay && this.options.slideshow.active === undefined) {
110
103
  this.options.slideshow.active = true
111
104
  }
112
105
  if (this.options.advancedFilterKey) {
@@ -156,9 +149,7 @@ U.Map = L.Map.extend({
156
149
  let isDirty = false // self status
157
150
  try {
158
151
  Object.defineProperty(this, 'isDirty', {
159
- get: function () {
160
- return isDirty
161
- },
152
+ get: () => isDirty,
162
153
  set: function (status) {
163
154
  isDirty = status
164
155
  this.checkDirty()
@@ -184,14 +175,17 @@ U.Map = L.Map.extend({
184
175
  this._default_extent = true
185
176
  this.options.name = L._('Untitled map')
186
177
  let data = L.Util.queryString('data', null)
187
- let dataUrl = L.Util.queryString('dataUrl', null)
178
+ const url = new URL(window.location.href)
179
+ const dataUrls = new URLSearchParams(url.search).getAll('dataUrl')
188
180
  const dataFormat = L.Util.queryString('dataFormat', 'geojson')
189
- if (dataUrl) {
190
- dataUrl = decodeURIComponent(dataUrl)
191
- dataUrl = this.localizeUrl(dataUrl)
192
- dataUrl = this.proxyUrl(dataUrl)
193
- const datalayer = this.createDataLayer()
194
- datalayer.importFromUrl(dataUrl, dataFormat)
181
+ if (dataUrls.length) {
182
+ for (let dataUrl of dataUrls) {
183
+ dataUrl = decodeURIComponent(dataUrl)
184
+ dataUrl = this.localizeUrl(dataUrl)
185
+ dataUrl = this.proxyUrl(dataUrl)
186
+ const datalayer = this.createDataLayer()
187
+ datalayer.importFromUrl(dataUrl, dataFormat)
188
+ }
195
189
  } else if (data) {
196
190
  data = decodeURIComponent(data)
197
191
  const datalayer = this.createDataLayer()
@@ -205,49 +199,9 @@ U.Map = L.Map.extend({
205
199
  this.editTools = new U.Editable(this)
206
200
  this.renderEditToolbar()
207
201
  }
208
- if (!U.Utils.isObject(this.options.overlay)) {
209
- this.options.overlay = {}
210
- }
211
- if (!U.Utils.isObject(this.options.tilelayer)) {
212
- this.options.tilelayer = {}
213
- }
214
202
 
215
203
  this.initShortcuts()
216
- this.onceDataLoaded(function () {
217
- const slug = L.Util.queryString('feature')
218
- if (slug && this.features_index[slug]) this.features_index[slug].view()
219
- if (this.options.noControl) return
220
- this.initCaptionBar()
221
- if (L.Util.queryString('share')) {
222
- this.share.open()
223
- } else if (this.options.onLoadPanel === 'databrowser') {
224
- this.panel.setDefaultMode('expanded')
225
- this.openBrowser('data')
226
- } else if (this.options.onLoadPanel === 'datalayers') {
227
- this.panel.setDefaultMode('condensed')
228
- this.openBrowser('layers')
229
- } else if (this.options.onLoadPanel === 'datafilters') {
230
- this.panel.setDefaultMode('expanded')
231
- this.openBrowser('filters')
232
- } else if (this.options.onLoadPanel === 'caption') {
233
- this.panel.setDefaultMode('condensed')
234
- this.openCaption()
235
- }
236
- if (L.Util.queryString('edit')) {
237
- if (this.hasEditMode()) this.enableEdit()
238
- // Sometimes users share the ?edit link by mistake, let's remove
239
- // this search parameter from URL to prevent this
240
- const url = new URL(window.location)
241
- url.searchParams.delete('edit')
242
- history.pushState({}, '', url)
243
- }
244
- if (L.Util.queryString('download')) {
245
- const download_url = this.urls.get('map_download', {
246
- map_id: this.options.umap_id,
247
- })
248
- window.location = download_url
249
- }
250
- })
204
+ this.onceDataLoaded(this.setViewFromQueryString)
251
205
 
252
206
  window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null
253
207
  this.backup()
@@ -256,8 +210,8 @@ U.Map = L.Map.extend({
256
210
  },
257
211
 
258
212
  initSyncEngine: async function () {
259
- if (this.options.websocketEnabled == false) return
260
- if (this.options.syncEnabled != true) {
213
+ if (this.options.websocketEnabled === false) return
214
+ if (this.options.syncEnabled !== true) {
261
215
  this.sync.stop()
262
216
  } else {
263
217
  const ws_token_uri = this.urls.get('map_websocket_auth_token', {
@@ -275,9 +229,9 @@ U.Map = L.Map.extend({
275
229
  },
276
230
 
277
231
  render: function (fields) {
278
- let impacts = U.Utils.getImpactsFromSchema(fields)
232
+ const impacts = U.Utils.getImpactsFromSchema(fields)
279
233
 
280
- for (let impact of impacts) {
234
+ for (const impact of impacts) {
281
235
  switch (impact) {
282
236
  case 'ui':
283
237
  this.initCaptionBar()
@@ -314,7 +268,7 @@ U.Map = L.Map.extend({
314
268
  })
315
269
  },
316
270
 
317
- setOptionsFromQueryString: function (options) {
271
+ setOptionsFromQueryString: (options) => {
318
272
  // This is not an editable option
319
273
  L.Util.setFromQueryString(options, 'editMode')
320
274
  // FIXME retrocompat
@@ -341,9 +295,47 @@ U.Map = L.Map.extend({
341
295
  }
342
296
  },
343
297
 
298
+ setViewFromQueryString: function () {
299
+ if (this.options.noControl) return
300
+ this.initCaptionBar()
301
+ if (L.Util.queryString('share')) {
302
+ this.share.open()
303
+ } else if (this.options.onLoadPanel === 'databrowser') {
304
+ this.panel.setDefaultMode('expanded')
305
+ this.openBrowser('data')
306
+ } else if (this.options.onLoadPanel === 'datalayers') {
307
+ this.panel.setDefaultMode('condensed')
308
+ this.openBrowser('layers')
309
+ } else if (this.options.onLoadPanel === 'datafilters') {
310
+ this.panel.setDefaultMode('expanded')
311
+ this.openBrowser('filters')
312
+ } else if (this.options.onLoadPanel === 'caption') {
313
+ this.panel.setDefaultMode('condensed')
314
+ this.openCaption()
315
+ }
316
+ // Comes after default panels, so if it opens in a panel it will
317
+ // take precedence.
318
+ const slug = L.Util.queryString('feature')
319
+ if (slug && this.features_index[slug]) this.features_index[slug].view()
320
+ if (L.Util.queryString('edit')) {
321
+ if (this.hasEditMode()) this.enableEdit()
322
+ // Sometimes users share the ?edit link by mistake, let's remove
323
+ // this search parameter from URL to prevent this
324
+ const url = new URL(window.location)
325
+ url.searchParams.delete('edit')
326
+ history.pushState({}, '', url)
327
+ }
328
+ if (L.Util.queryString('download')) {
329
+ const download_url = this.urls.get('map_download', {
330
+ map_id: this.options.umap_id,
331
+ })
332
+ window.location = download_url
333
+ }
334
+ },
335
+
344
336
  // Merge the given schema with the default one
345
337
  // Missing keys inside the schema are merged with the default ones.
346
- overrideSchema: function (schema) {
338
+ overrideSchema: (schema) => {
347
339
  for (const [key, extra] of Object.entries(schema)) {
348
340
  U.SCHEMA[key] = L.extend({}, U.SCHEMA[key], extra)
349
341
  }
@@ -421,9 +413,7 @@ U.Map = L.Map.extend({
421
413
  },
422
414
 
423
415
  renderControls: function () {
424
- const hasSlideshow = Boolean(
425
- this.options.slideshow && this.options.slideshow.active
426
- )
416
+ const hasSlideshow = Boolean(this.options.slideshow?.active)
427
417
  const barEnabled = this.options.captionBar || hasSlideshow
428
418
  document.body.classList.toggle('umap-caption-bar-enabled', barEnabled)
429
419
  document.body.classList.toggle('umap-slideshow-enabled', hasSlideshow)
@@ -451,7 +441,9 @@ U.Map = L.Map.extend({
451
441
  }
452
442
  })
453
443
  }
454
- let name, status, control
444
+ let name
445
+ let status
446
+ let control
455
447
  for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
456
448
  name = this.HIDDABLE_CONTROLS[i]
457
449
  status = this.getOption(`${name}Control`)
@@ -472,7 +464,8 @@ U.Map = L.Map.extend({
472
464
  initDataLayers: async function (datalayers) {
473
465
  datalayers = datalayers || this.options.datalayers
474
466
  for (const options of datalayers) {
475
- this.createDataLayer(options)
467
+ // `false` to not propagate syncing elements served from uMap
468
+ this.createDataLayer(options, false)
476
469
  }
477
470
  await this.loadDataLayers()
478
471
  },
@@ -626,7 +619,7 @@ U.Map = L.Map.extend({
626
619
  initTileLayers: function () {
627
620
  this.tilelayers = []
628
621
  for (const props of this.options.tilelayers) {
629
- let layer = this.createTileLayer(props)
622
+ const layer = this.createTileLayer(props)
630
623
  this.tilelayers.push(layer)
631
624
  if (
632
625
  this.options.tilelayer &&
@@ -636,11 +629,7 @@ U.Map = L.Map.extend({
636
629
  this.options.tilelayer.attribution = props.attribution
637
630
  }
638
631
  }
639
- if (
640
- this.options.tilelayer &&
641
- this.options.tilelayer.url_template &&
642
- this.options.tilelayer.attribution
643
- ) {
632
+ if (this.options.tilelayer?.url_template && this.options.tilelayer.attribution) {
644
633
  this.customTilelayer = this.createTileLayer(this.options.tilelayer)
645
634
  this.selectTileLayer(this.customTilelayer)
646
635
  } else {
@@ -649,9 +638,7 @@ U.Map = L.Map.extend({
649
638
  if (this._controls) this._controls.tilelayers.setLayers()
650
639
  },
651
640
 
652
- createTileLayer: function (tilelayer) {
653
- return new L.TileLayer(tilelayer.url_template, tilelayer)
654
- },
641
+ createTileLayer: (tilelayer) => new L.TileLayer(tilelayer.url_template, tilelayer),
655
642
 
656
643
  selectTileLayer: function (tilelayer) {
657
644
  if (tilelayer === this.selected_tilelayer) {
@@ -665,13 +652,13 @@ U.Map = L.Map.extend({
665
652
  }
666
653
  this.selected_tilelayer = tilelayer
667
654
  if (
668
- !isNaN(this.selected_tilelayer.options.minZoom) &&
655
+ !Number.isNaN(this.selected_tilelayer.options.minZoom) &&
669
656
  this.getZoom() < this.selected_tilelayer.options.minZoom
670
657
  ) {
671
658
  this.setZoom(this.selected_tilelayer.options.minZoom)
672
659
  }
673
660
  if (
674
- !isNaN(this.selected_tilelayer.options.maxZoom) &&
661
+ !Number.isNaN(this.selected_tilelayer.options.maxZoom) &&
675
662
  this.getZoom() > this.selected_tilelayer.options.maxZoom
676
663
  ) {
677
664
  this.setZoom(this.selected_tilelayer.options.maxZoom)
@@ -758,7 +745,7 @@ U.Map = L.Map.extend({
758
745
  }
759
746
  },
760
747
 
761
- latLng: function (a, b, c) {
748
+ latLng: (a, b, c) => {
762
749
  // manage geojson case and call original method
763
750
  if (!(a instanceof L.LatLng) && a.coordinates) {
764
751
  // Guess it's a geojson
@@ -768,11 +755,16 @@ U.Map = L.Map.extend({
768
755
  },
769
756
 
770
757
  handleLimitBounds: function () {
771
- const south = parseFloat(this.options.limitBounds.south),
772
- west = parseFloat(this.options.limitBounds.west),
773
- north = parseFloat(this.options.limitBounds.north),
774
- east = parseFloat(this.options.limitBounds.east)
775
- if (!isNaN(south) && !isNaN(west) && !isNaN(north) && !isNaN(east)) {
758
+ const south = Number.parseFloat(this.options.limitBounds.south)
759
+ const west = Number.parseFloat(this.options.limitBounds.west)
760
+ const north = Number.parseFloat(this.options.limitBounds.north)
761
+ const east = Number.parseFloat(this.options.limitBounds.east)
762
+ if (
763
+ !Number.isNaN(south) &&
764
+ !Number.isNaN(west) &&
765
+ !Number.isNaN(north) &&
766
+ !Number.isNaN(east)
767
+ ) {
776
768
  const bounds = L.latLngBounds([
777
769
  [south, west],
778
770
  [north, east],
@@ -802,7 +794,7 @@ U.Map = L.Map.extend({
802
794
  return L.Map.prototype.setMaxBounds.call(this, bounds)
803
795
  },
804
796
 
805
- createDataLayer: function (options = {}, sync) {
797
+ createDataLayer: function (options = {}, sync = true) {
806
798
  options.name = options.name || `${L._('Layer')} ${this.datalayers_index.length + 1}`
807
799
  const datalayer = new U.DataLayer(this, options, sync)
808
800
 
@@ -817,9 +809,7 @@ U.Map = L.Map.extend({
817
809
  datalayer.edit()
818
810
  },
819
811
 
820
- getDefaultOption: function (option) {
821
- return U.SCHEMA[option] && U.SCHEMA[option].default
822
- },
812
+ getDefaultOption: (option) => U.SCHEMA[option]?.default,
823
813
 
824
814
  getOption: function (option, feature) {
825
815
  if (feature) {
@@ -843,11 +833,10 @@ U.Map = L.Map.extend({
843
833
  },
844
834
 
845
835
  updateTileLayers: function () {
846
- const self = this,
847
- callback = (tilelayer) => {
848
- self.options.tilelayer = tilelayer.toJSON()
849
- self.isDirty = true
850
- }
836
+ const callback = (tilelayer) => {
837
+ this.options.tilelayer = tilelayer.toJSON()
838
+ this.isDirty = true
839
+ }
851
840
  if (this._controls.tilelayersChooser)
852
841
  this._controls.tilelayersChooser.openSwitcher({
853
842
  callback: callback,
@@ -895,7 +884,7 @@ U.Map = L.Map.extend({
895
884
 
896
885
  importFromUrl: async function (uri) {
897
886
  const response = await this.request.get(uri)
898
- if (response && response.ok) {
887
+ if (response?.ok) {
899
888
  this.importRaw(await response.text())
900
889
  }
901
890
  },
@@ -913,14 +902,13 @@ U.Map = L.Map.extend({
913
902
  }
914
903
 
915
904
  if (importedData.geometry) this.options.center = this.latLng(importedData.geometry)
916
- const self = this
917
905
  importedData.layers.forEach((geojson) => {
918
906
  if (!geojson._umap_options && geojson._storage) {
919
907
  geojson._umap_options = geojson._storage
920
908
  delete geojson._storage
921
909
  }
922
910
  delete geojson._umap_options?.id // Never trust an id at this stage
923
- const dataLayer = self.createDataLayer(geojson._umap_options)
911
+ const dataLayer = this.createDataLayer(geojson._umap_options)
924
912
  dataLayer.fromUmapGeoJSON(geojson)
925
913
  })
926
914
 
@@ -938,11 +926,10 @@ U.Map = L.Map.extend({
938
926
  importFromFile: function (file) {
939
927
  const reader = new FileReader()
940
928
  reader.readAsText(file)
941
- const self = this
942
929
  reader.onload = (e) => {
943
930
  const rawData = e.target.result
944
931
  try {
945
- self.importRaw(rawData)
932
+ this.importRaw(rawData)
946
933
  } catch (e) {
947
934
  console.error('Error importing data', e)
948
935
  U.Alert.error(L._('Invalid umap data in {filename}', { filename: file.name }))
@@ -1148,7 +1135,8 @@ U.Map = L.Map.extend({
1148
1135
  // (edit and viewing)
1149
1136
  // cf https://github.com/umap-project/umap/issues/585
1150
1137
  defaultEditDataLayer: function () {
1151
- let datalayer, fallback
1138
+ let datalayer
1139
+ let fallback
1152
1140
  datalayer = this.lastUsedDataLayer
1153
1141
  if (
1154
1142
  datalayer &&
@@ -1174,7 +1162,7 @@ U.Map = L.Map.extend({
1174
1162
  },
1175
1163
 
1176
1164
  getDataLayerByUmapId: function (umap_id) {
1177
- return this.findDataLayer((d) => d.umap_id == umap_id)
1165
+ return this.findDataLayer((d) => d.umap_id === umap_id)
1178
1166
  },
1179
1167
 
1180
1168
  _editControls: function (container) {
@@ -1296,6 +1284,9 @@ U.Map = L.Map.extend({
1296
1284
  },
1297
1285
 
1298
1286
  _editTilelayer: function (container) {
1287
+ if (!U.Utils.isObject(this.options.tilelayer)) {
1288
+ this.options.tilelayer = {}
1289
+ }
1299
1290
  const tilelayerFields = [
1300
1291
  [
1301
1292
  'options.tilelayer.name',
@@ -1343,6 +1334,9 @@ U.Map = L.Map.extend({
1343
1334
  },
1344
1335
 
1345
1336
  _editOverlay: function (container) {
1337
+ if (!U.Utils.isObject(this.options.overlay)) {
1338
+ this.options.overlay = {}
1339
+ }
1346
1340
  const overlayFields = [
1347
1341
  [
1348
1342
  'options.overlay.url_template',
@@ -1350,7 +1344,7 @@ U.Map = L.Map.extend({
1350
1344
  handler: 'BlurInput',
1351
1345
  helpText: `${L._('Supported scheme')}: http://{s}.domain.com/{z}/{x}/{y}.png`,
1352
1346
  placeholder: 'url',
1353
- helpText: L._('Background overlay url'),
1347
+ label: L._('Background overlay url'),
1354
1348
  type: 'url',
1355
1349
  },
1356
1350
  ],
@@ -1501,8 +1495,15 @@ U.Map = L.Map.extend({
1501
1495
  L.DomUtil.createButton(
1502
1496
  'button umap-empty',
1503
1497
  advancedButtons,
1504
- L._('Empty'),
1505
- this.empty,
1498
+ L._('Clear data'),
1499
+ this.emptyDataLayers,
1500
+ this
1501
+ )
1502
+ L.DomUtil.createButton(
1503
+ 'button umap-empty',
1504
+ advancedButtons,
1505
+ L._('Remove layers'),
1506
+ this.removeDataLayers,
1506
1507
  this
1507
1508
  )
1508
1509
  }
@@ -1513,13 +1514,6 @@ U.Map = L.Map.extend({
1513
1514
  this.clone,
1514
1515
  this
1515
1516
  )
1516
- L.DomUtil.createButton(
1517
- 'button umap-empty',
1518
- advancedButtons,
1519
- L._('Delete all layers'),
1520
- this.empty,
1521
- this
1522
- )
1523
1517
  L.DomUtil.createButton(
1524
1518
  'button umap-download',
1525
1519
  advancedButtons,
@@ -1535,8 +1529,7 @@ U.Map = L.Map.extend({
1535
1529
  const container = L.DomUtil.create('div', 'umap-edit-container')
1536
1530
  const metadataFields = ['options.name', 'options.description']
1537
1531
 
1538
- const title = L.DomUtil.create('h3', '', container)
1539
- title.textContent = L._('Edit map details')
1532
+ L.DomUtil.createTitle(container, L._('Edit map details'), 'icon-caption')
1540
1533
  const builder = new U.FormBuilder(this, metadataFields, {
1541
1534
  className: 'map-metadata',
1542
1535
  })
@@ -1608,11 +1601,11 @@ U.Map = L.Map.extend({
1608
1601
 
1609
1602
  initCaptionBar: function () {
1610
1603
  const container = L.DomUtil.create(
1611
- 'div',
1612
- 'umap-caption-bar',
1613
- this._controlContainer
1614
- ),
1615
- name = L.DomUtil.create('h3', '', container)
1604
+ 'div',
1605
+ 'umap-caption-bar',
1606
+ this._controlContainer
1607
+ )
1608
+ const name = L.DomUtil.create('h3', '', container)
1616
1609
  L.DomEvent.disableClickPropagation(container)
1617
1610
  this.permissions.addOwnerLink('span', container)
1618
1611
  if (this.getOption('captionMenus')) {
@@ -1684,12 +1677,18 @@ U.Map = L.Map.extend({
1684
1677
  }
1685
1678
  },
1686
1679
 
1687
- empty: function () {
1680
+ removeDataLayers: function () {
1688
1681
  this.eachDataLayerReverse((datalayer) => {
1689
1682
  datalayer._delete()
1690
1683
  })
1691
1684
  },
1692
1685
 
1686
+ emptyDataLayers: function () {
1687
+ this.eachDataLayerReverse((datalayer) => {
1688
+ datalayer.empty()
1689
+ })
1690
+ },
1691
+
1693
1692
  initLoader: function () {
1694
1693
  this.loader = new L.Control.Loading()
1695
1694
  this.loader.onAdd(this)
@@ -1718,7 +1717,7 @@ U.Map = L.Map.extend({
1718
1717
  },
1719
1718
  })
1720
1719
  }
1721
- if (e && e.relatedTarget) {
1720
+ if (e?.relatedTarget) {
1722
1721
  if (e.relatedTarget.getContextMenuItems) {
1723
1722
  items = items.concat(e.relatedTarget.getContextMenuItems(e))
1724
1723
  }
@@ -1873,10 +1872,6 @@ U.Map = L.Map.extend({
1873
1872
  if (this._controls.search) this._controls.search.open()
1874
1873
  },
1875
1874
 
1876
- getFilterKeys: function () {
1877
- return (this.options.filterKey || this.options.sortKey || 'name').split(',')
1878
- },
1879
-
1880
1875
  getLayersBounds: function () {
1881
1876
  const bounds = new L.latLngBounds()
1882
1877
  this.eachBrowsableDataLayer((d) => {