umap-project 2.8.0__py3-none-any.whl → 2.8.0a1__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 (44) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/en/LC_MESSAGES/django.po +13 -13
  3. umap/management/commands/empty_trash.py +2 -5
  4. umap/static/umap/css/form.css +0 -3
  5. umap/static/umap/js/modules/data/features.js +4 -19
  6. umap/static/umap/js/modules/data/layer.js +19 -41
  7. umap/static/umap/js/modules/importer.js +20 -65
  8. umap/static/umap/js/modules/rendering/icon.js +1 -2
  9. umap/static/umap/js/modules/rendering/map.js +7 -7
  10. umap/static/umap/js/modules/rendering/popup.js +10 -9
  11. umap/static/umap/js/modules/rendering/template.js +9 -53
  12. umap/static/umap/js/modules/rendering/ui.js +2 -6
  13. umap/static/umap/js/modules/request.js +2 -2
  14. umap/static/umap/js/modules/schema.js +0 -1
  15. umap/static/umap/js/modules/ui/dialog.js +0 -5
  16. umap/static/umap/js/modules/umap.js +10 -33
  17. umap/static/umap/js/modules/utils.js +0 -2
  18. umap/static/umap/js/umap.controls.js +4 -7
  19. umap/static/umap/js/umap.forms.js +0 -44
  20. umap/static/umap/locale/en.js +1 -3
  21. umap/static/umap/locale/en.json +1 -3
  22. umap/static/umap/locale/fr.js +1 -3
  23. umap/static/umap/locale/fr.json +1 -3
  24. umap/static/umap/map.css +166 -34
  25. umap/static/umap/vars.css +1 -0
  26. umap/templates/base.html +0 -2
  27. umap/templates/umap/components/alerts/alert.html +0 -4
  28. umap/templates/umap/css.html +0 -3
  29. umap/templates/umap/js.html +0 -2
  30. umap/templates/umap/map_init.html +0 -2
  31. umap/templates/umap/user_dashboard.html +0 -2
  32. umap/tests/integration/test_edit_datalayer.py +0 -11
  33. umap/tests/integration/test_import.py +1 -20
  34. umap/tests/test_team_views.py +1 -35
  35. umap/tests/test_views.py +74 -0
  36. umap/views.py +15 -20
  37. {umap_project-2.8.0.dist-info → umap_project-2.8.0a1.dist-info}/METADATA +1 -1
  38. {umap_project-2.8.0.dist-info → umap_project-2.8.0a1.dist-info}/RECORD +41 -44
  39. umap/settings/local_s3.py +0 -45
  40. umap/tests/fixtures/test_upload_simple_marker.json +0 -19
  41. umap/tests/test_dashboard.py +0 -82
  42. {umap_project-2.8.0.dist-info → umap_project-2.8.0a1.dist-info}/WHEEL +0 -0
  43. {umap_project-2.8.0.dist-info → umap_project-2.8.0a1.dist-info}/entry_points.txt +0 -0
  44. {umap_project-2.8.0.dist-info → umap_project-2.8.0a1.dist-info}/licenses/LICENSE +0 -0
umap/__init__.py CHANGED
@@ -1 +1 @@
1
- VERSION = "2.8.0"
1
+ VERSION = "2.8.0a1"
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2024-12-13 08:26+0000\n"
11
+ "POT-Creation-Date: 2024-12-11 17:05+0000\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -617,57 +617,57 @@ msgstr ""
617
617
  msgid "View the map"
618
618
  msgstr ""
619
619
 
620
- #: views.py:821
620
+ #: views.py:820
621
621
  msgid "See full screen"
622
622
  msgstr ""
623
623
 
624
- #: views.py:964
624
+ #: views.py:963
625
625
  msgid "Map editors updated with success!"
626
626
  msgstr ""
627
627
 
628
- #: views.py:1000
628
+ #: views.py:999
629
629
  #, python-format
630
630
  msgid "The uMap edit link for your map: %(map_name)s"
631
631
  msgstr ""
632
632
 
633
- #: views.py:1003
633
+ #: views.py:1002
634
634
  #, python-format
635
635
  msgid "Here is your secret edit link: %(link)s"
636
636
  msgstr ""
637
637
 
638
- #: views.py:1010
638
+ #: views.py:1009
639
639
  #, python-format
640
640
  msgid "Can't send email to %(email)s"
641
641
  msgstr ""
642
642
 
643
- #: views.py:1013
643
+ #: views.py:1012
644
644
  #, python-format
645
645
  msgid "Email sent to %(email)s"
646
646
  msgstr ""
647
647
 
648
- #: views.py:1024
648
+ #: views.py:1023
649
649
  msgid "Only its owner can delete the map."
650
650
  msgstr ""
651
651
 
652
- #: views.py:1027
652
+ #: views.py:1026
653
653
  msgid "Map successfully deleted."
654
654
  msgstr ""
655
655
 
656
- #: views.py:1053
656
+ #: views.py:1052
657
657
  #, python-format
658
658
  msgid ""
659
659
  "Your map has been cloned! If you want to edit this map from another "
660
660
  "computer, please use this link: %(anonymous_url)s"
661
661
  msgstr ""
662
662
 
663
- #: views.py:1058
663
+ #: views.py:1057
664
664
  msgid "Congratulations, your map has been cloned!"
665
665
  msgstr ""
666
666
 
667
- #: views.py:1309
667
+ #: views.py:1308
668
668
  msgid "Layer successfully deleted."
669
669
  msgstr ""
670
670
 
671
- #: views.py:1331
671
+ #: views.py:1330
672
672
  msgid "Permissions updated with success!"
673
673
  msgstr ""
@@ -23,13 +23,10 @@ class Command(BaseCommand):
23
23
 
24
24
  def handle(self, *args, **options):
25
25
  days = options["days"]
26
- since = (datetime.utcnow() - timedelta(days=days)).date()
26
+ since = datetime.utcnow() - timedelta(days=days)
27
27
  print(f"Deleting map in trash since {since}")
28
28
  maps = Map.objects.filter(share_status=Map.DELETED, modified_at__lt=since)
29
29
  for map in maps:
30
- map_id = map.id
31
- map_name = map.name
32
- trashed_at = map.modified_at.date()
33
30
  if not options["dry_run"]:
34
31
  map.delete()
35
- print(f"Deleted map {map_name} ({map_id}), trashed at {trashed_at}")
32
+ print(f"Deleted map {map.name} ({map.id}), trashed on {map.modified_at}")
@@ -1,6 +1,3 @@
1
- .umap-form-inline {
2
- display: inline;
3
- }
4
1
  input[type="text"], input[type="password"], input[type="date"],
5
2
  input[type="datetime-local"], input[type="email"], input[type="number"],
6
3
  input[type="search"], input[type="tel"], input[type="time"], input[type="file"],
@@ -199,9 +199,8 @@ class Feature {
199
199
  this._umap.slideshow.current = this
200
200
  }
201
201
  this._umap.currentFeature = this
202
- this.attachPopup().then(() => {
203
- this.ui.openPopup(latlng || this.center)
204
- })
202
+ this.attachPopup()
203
+ this.ui.openPopup(latlng || this.center)
205
204
  }
206
205
 
207
206
  render(fields) {
@@ -356,11 +355,9 @@ class Feature {
356
355
  return loadPopup(this.getOption('popupShape') || old)
357
356
  }
358
357
 
359
- async attachPopup() {
358
+ attachPopup() {
360
359
  const Class = this.getPopupClass()
361
- const popup = new Class(this)
362
- this.ui.bindPopup(popup)
363
- return popup.loadContent()
360
+ this.ui.bindPopup(new Class(this))
364
361
  }
365
362
 
366
363
  async confirmDelete() {
@@ -661,18 +658,6 @@ class Feature {
661
658
  )
662
659
  return items
663
660
  }
664
-
665
- isActive() {
666
- return this._umap.activeFeature === this
667
- }
668
-
669
- activate() {
670
- this._umap.activeFeature = this
671
- }
672
-
673
- deactivate() {
674
- if (this._umap.activeFeature === this) this._umap.activeFeature = undefined
675
- }
676
661
  }
677
662
 
678
663
  export class Point extends Feature {
@@ -252,11 +252,10 @@ export class DataLayer extends ServerStored {
252
252
  }
253
253
 
254
254
  fromGeoJSON(geojson, sync = true) {
255
- const features = this.addData(geojson, sync)
255
+ this.addData(geojson, sync)
256
256
  this._geojson = geojson
257
257
  this.onDataLoaded()
258
258
  this.dataChanged()
259
- return features
260
259
  }
261
260
 
262
261
  onDataLoaded() {
@@ -316,7 +315,7 @@ export class DataLayer extends ServerStored {
316
315
  const response = await this._umap.request.get(url)
317
316
  if (response?.ok) {
318
317
  this.clear()
319
- return this._umap.formatter
318
+ this._umap.formatter
320
319
  .parse(await response.text(), this.options.remoteData.format)
321
320
  .then((geojson) => this.fromGeoJSON(geojson))
322
321
  }
@@ -444,11 +443,10 @@ export class DataLayer extends ServerStored {
444
443
  try {
445
444
  // Do not fail if remote data is somehow invalid,
446
445
  // otherwise the layer becomes uneditable.
447
- return this.makeFeatures(geojson, sync)
446
+ this.makeFeatures(geojson, sync)
448
447
  } catch (err) {
449
448
  console.log('Error with DataLayer', this.id)
450
449
  console.error(err)
451
- return []
452
450
  }
453
451
  }
454
452
 
@@ -465,13 +463,10 @@ export class DataLayer extends ServerStored {
465
463
  ? geojson
466
464
  : geojson.features || geojson.geometries
467
465
  if (!collection) return
468
- const features = []
469
466
  this.sortFeatures(collection)
470
- for (const featureJson of collection) {
471
- const feature = this.makeFeature(featureJson, sync)
472
- if (feature) features.push(feature)
467
+ for (const feature of collection) {
468
+ this.makeFeature(feature, sync)
473
469
  }
474
- return features
475
470
  }
476
471
 
477
472
  makeFeature(geojson = {}, sync = true, id = null) {
@@ -508,45 +503,31 @@ export class DataLayer extends ServerStored {
508
503
  }
509
504
 
510
505
  async importRaw(raw, format) {
511
- return this._umap.formatter
506
+ this._umap.formatter
512
507
  .parse(raw, format)
513
508
  .then((geojson) => this.addData(geojson))
514
- .then((data) => {
515
- if (data?.length) this.isDirty = true
516
- return data
517
- })
518
- }
519
-
520
- readFile(f) {
521
- return new Promise((resolve) => {
522
- const reader = new FileReader()
523
- reader.onloadend = () => resolve(reader.result)
524
- reader.readAsText(f)
525
- })
509
+ .then(() => this.zoomTo())
510
+ this.isDirty = true
526
511
  }
527
512
 
528
- async importFromFiles(files, type) {
529
- const toLoad = []
530
- for (const file of files) {
531
- toLoad.push(this.importFromFile(file, type))
513
+ importFromFiles(files, type) {
514
+ for (const f of files) {
515
+ this.importFromFile(f, type)
532
516
  }
533
- const features = await Promise.all(toLoad)
534
- return new Promise((resolve) => {
535
- resolve([].concat(...features))
536
- })
537
517
  }
538
518
 
539
- async importFromFile(file, type) {
519
+ importFromFile(f, type) {
520
+ const reader = new FileReader()
540
521
  type = type || Utils.detectFileType(f)
541
- const raw = await this.readFile(file)
542
- return this.importRaw(raw, type)
522
+ reader.readAsText(f)
523
+ reader.onload = (e) => this.importRaw(e.target.result, type)
543
524
  }
544
525
 
545
526
  async importFromUrl(uri, type) {
546
527
  uri = this._umap.renderUrl(uri)
547
528
  const response = await this._umap.request.get(uri)
548
529
  if (response?.ok) {
549
- return this.importRaw(await response.text(), type)
530
+ this.importRaw(await response.text(), type)
550
531
  }
551
532
  }
552
533
 
@@ -611,10 +592,7 @@ export class DataLayer extends ServerStored {
611
592
  }
612
593
 
613
594
  reset() {
614
- if (!this.createdOnServer) {
615
- this.erase()
616
- return
617
- }
595
+ if (!this.createdOnServer) this.erase()
618
596
 
619
597
  this.resetOptions()
620
598
  this.parentPane.appendChild(this.pane)
@@ -952,9 +930,9 @@ export class DataLayer extends ServerStored {
952
930
  else this.hide()
953
931
  }
954
932
 
955
- zoomTo(bounds) {
933
+ zoomTo() {
956
934
  if (!this.isVisible()) return
957
- bounds = bounds || this.layer.getBounds()
935
+ const bounds = this.layer.getBounds()
958
936
  if (bounds.isValid()) {
959
937
  const options = { maxZoom: this.getOption('zoomTo') }
960
938
  this._leafletMap.fitBounds(bounds, options)
@@ -1,8 +1,4 @@
1
- import {
2
- DomEvent,
3
- DomUtil,
4
- LatLngBounds,
5
- } from '../../vendors/leaflet/leaflet-src.esm.js'
1
+ import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
6
2
  import { uMapAlert as Alert } from '../components/alerts/alert.js'
7
3
  import { translate } from './i18n.js'
8
4
  import { SCHEMA } from './schema.js'
@@ -64,10 +60,7 @@ export default class Importer extends Utils.WithTemplate {
64
60
  this.TYPES = ['geojson', 'csv', 'gpx', 'kml', 'osm', 'georss', 'umap']
65
61
  this.IMPORTERS = []
66
62
  this.loadImporters()
67
- this.dialog = new Dialog({
68
- className: 'importers dark',
69
- back: () => this.showImporters(),
70
- })
63
+ this.dialog = new Dialog({ className: 'importers dark' })
71
64
  }
72
65
 
73
66
  loadImporters() {
@@ -175,7 +168,7 @@ export default class Importer extends Utils.WithTemplate {
175
168
  button.addEventListener('click', () => plugin.open(this))
176
169
  grid.appendChild(button)
177
170
  }
178
- this.dialog.open({ template: element, cancel: false, accept: false, back: false })
171
+ this.dialog.open({ template: element, cancel: false, accept: false })
179
172
  }
180
173
 
181
174
  build() {
@@ -277,12 +270,16 @@ export default class Importer extends Utils.WithTemplate {
277
270
  }
278
271
 
279
272
  submit() {
273
+ let hasErrors
280
274
  if (this.format === 'umap') {
281
- this.full()
275
+ hasErrors = !this.full()
282
276
  } else if (!this.url) {
283
- this.copy()
277
+ hasErrors = !this.copy()
284
278
  } else if (this.action) {
285
- this[this.action]()
279
+ hasErrors = !this[this.action]()
280
+ }
281
+ if (hasErrors === false) {
282
+ Alert.info(translate('Data successfully imported!'))
286
283
  }
287
284
  }
288
285
 
@@ -297,9 +294,8 @@ export default class Importer extends Utils.WithTemplate {
297
294
  } else if (this.url) {
298
295
  this._umap.importFromUrl(this.url, this.format)
299
296
  }
300
- this.onSuccess()
301
297
  } catch (e) {
302
- this.onError(translate('Invalid umap data'))
298
+ Alert.error(translate('Invalid umap data'))
303
299
  console.error(e)
304
300
  return false
305
301
  }
@@ -310,7 +306,7 @@ export default class Importer extends Utils.WithTemplate {
310
306
  return false
311
307
  }
312
308
  if (!this.format) {
313
- this.onError(translate('Please choose a format'))
309
+ Alert.error(translate('Please choose a format'))
314
310
  return false
315
311
  }
316
312
  const layer = this.layer
@@ -322,67 +318,26 @@ export default class Importer extends Utils.WithTemplate {
322
318
  layer.options.remoteData.proxy = true
323
319
  layer.options.remoteData.ttl = SCHEMA.ttl.default
324
320
  }
325
- layer.fetchRemoteData(true).then((features) => {
326
- if (features?.length) {
327
- layer.zoomTo()
328
- this.onSuccess()
329
- } else {
330
- this.onError()
331
- }
332
- })
321
+ layer.fetchRemoteData(true)
333
322
  }
334
323
 
335
- async copy() {
324
+ copy() {
336
325
  // Format may be guessed from file later.
337
326
  // Usefull in case of multiple files with different formats.
338
327
  if (!this.format && !this.files.length) {
339
- this.onError(translate('Please choose a format'))
328
+ Alert.error(translate('Please choose a format'))
340
329
  return false
341
330
  }
342
- let promise
343
331
  const layer = this.layer
344
332
  if (this.clear) layer.empty()
345
333
  if (this.files.length) {
346
- promise = layer.importFromFiles(this.files, this.format)
334
+ for (const file of this.files) {
335
+ this._umap.processFileToImport(file, layer, this.format)
336
+ }
347
337
  } else if (this.raw) {
348
- promise = layer.importRaw(this.raw, this.format)
338
+ layer.importRaw(this.raw, this.format)
349
339
  } else if (this.url) {
350
- promise = layer.importFromUrl(this.url, this.format)
351
- }
352
- if (promise) promise.then((data) => this.onCopyFinished(layer, data))
353
- }
354
-
355
- onError(message = translate('No data has been found for import')) {
356
- Alert.error(message)
357
- }
358
-
359
- onSuccess(count) {
360
- if (count) {
361
- Alert.success(
362
- translate('Successfully imported {count} feature(s)', {
363
- count: count,
364
- })
365
- )
366
- } else {
367
- Alert.success(translate('Data successfully imported!'))
368
- }
369
- }
370
-
371
- onCopyFinished(layer, features) {
372
- // undefined features means error, let original error message pop
373
- if (!features) return
374
- if (!features.length) {
375
- this.onError()
376
- } else {
377
- const bounds = new LatLngBounds()
378
- for (const feature of features) {
379
- const featureBounds = feature.ui.getBounds
380
- ? feature.ui.getBounds()
381
- : feature.ui.getCenter()
382
- bounds.extend(featureBounds)
383
- }
384
- this.onSuccess(features.length)
385
- layer.zoomTo(bounds)
340
+ layer.importFromUrl(this.url, this.format)
386
341
  }
387
342
  }
388
343
  }
@@ -22,7 +22,7 @@ export function getClass(name) {
22
22
 
23
23
  export const RECENT = []
24
24
 
25
- const BaseIcon = DivIcon.extend({
25
+ const BaseIcon = L.DivIcon.extend({
26
26
  initialize: function (options) {
27
27
  const default_options = {
28
28
  iconSize: null, // Made in css
@@ -86,7 +86,6 @@ const DefaultIcon = BaseIcon.extend({
86
86
  },
87
87
 
88
88
  _setIconStyles: function (img, name) {
89
- if (this.feature.isActive()) this.options.className += ' umap-icon-active'
90
89
  BaseIcon.prototype._setIconStyles.call(this, img, name)
91
90
  const color = this._getColor()
92
91
  const opacity = this._getOpacity()
@@ -233,8 +233,12 @@ const ManageTilelayerMixin = {
233
233
  },
234
234
 
235
235
  updateTileLayers: function () {
236
+ const callback = (tilelayer) => {
237
+ this.options.tilelayer = tilelayer.toJSON()
238
+ this._umap.isDirty = true
239
+ }
236
240
  if (this._controls.tilelayersChooser) {
237
- this._controls.tilelayersChooser.openSwitcher({ edit: true })
241
+ this._controls.tilelayersChooser.openSwitcher({ callback, edit: true })
238
242
  }
239
243
  },
240
244
  }
@@ -259,12 +263,8 @@ export const LeafletMap = BaseMap.extend({
259
263
  this.loader.onAdd(this)
260
264
 
261
265
  if (!this.options.noControl) {
262
- DomEvent.on(document.body, 'dataloading', (event) =>
263
- this.fire('dataloading', event.detail)
264
- )
265
- DomEvent.on(document.body, 'dataload', (event) =>
266
- this.fire('dataload', event.detail)
267
- )
266
+ DomEvent.on(document.body, 'dataloading', (e) => this.fire('dataloading', e))
267
+ DomEvent.on(document.body, 'dataload', (e) => this.fire('dataload', e))
268
268
  this.on('click', this.closeInplaceToolbar)
269
269
  }
270
270
 
@@ -21,22 +21,23 @@ export default function loadPopup(name) {
21
21
  const Popup = BasePopup.extend({
22
22
  initialize: function (feature) {
23
23
  this.feature = feature
24
- BasePopup.prototype.initialize.call(this, {}, feature.ui)
24
+ this.container = DomUtil.create('div', 'umap-popup')
25
+ this.format()
26
+ BasePopup.prototype.initialize.call(this, {}, feature)
27
+ this.setContent(this.container)
25
28
  },
26
29
 
27
- loadContent: async function () {
28
- const container = DomUtil.create('div', 'umap-popup')
30
+ format: function () {
29
31
  const name = this.feature.getOption('popupTemplate')
30
- this.content = await loadTemplate(name, this.feature, container)
31
- const elements = container.querySelectorAll('img,iframe')
32
+ this.content = loadTemplate(name, this.feature, this.container)
33
+ const elements = this.container.querySelectorAll('img,iframe')
32
34
  for (const element of elements) {
33
35
  this.onElementLoaded(element)
34
36
  }
35
- if (!elements.length && container.textContent.replace('\n', '') === '') {
36
- container.innerHTML = ''
37
- DomUtil.add('h3', '', container, this.feature.getDisplayName())
37
+ if (!elements.length && this.container.textContent.replace('\n', '') === '') {
38
+ this.container.innerHTML = ''
39
+ DomUtil.add('h3', '', this.container, this.feature.getDisplayName())
38
40
  }
39
- this.setContent(container)
40
41
  },
41
42
 
42
43
  onElementLoaded: function (el) {
@@ -2,9 +2,8 @@ import { DomUtil, DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
2
2
  import { translate, getLocale } from '../i18n.js'
3
3
  import * as Utils from '../utils.js'
4
4
  import * as Icon from './icon.js'
5
- import { Request } from '../request.js'
6
5
 
7
- export default async function loadTemplate(name, feature, container) {
6
+ export default function loadTemplate(name, feature, container) {
8
7
  let klass = PopupTemplate
9
8
  switch (name) {
10
9
  case 'GeoRSSLink':
@@ -19,12 +18,9 @@ export default async function loadTemplate(name, feature, container) {
19
18
  case 'OSM':
20
19
  klass = OSM
21
20
  break
22
- case 'Wikipedia':
23
- klass = Wikipedia
24
- break
25
21
  }
26
22
  const content = new klass()
27
- return await content.render(feature, container)
23
+ return content.render(feature, container)
28
24
  }
29
25
 
30
26
  class PopupTemplate {
@@ -80,10 +76,10 @@ class PopupTemplate {
80
76
  }
81
77
  }
82
78
 
83
- async render(feature, container) {
79
+ render(feature, container) {
84
80
  const title = this.renderTitle(feature)
85
81
  if (title) container.appendChild(title)
86
- const body = await this.renderBody(feature)
82
+ const body = this.renderBody(feature)
87
83
  if (body) DomUtil.add('div', 'umap-popup-content', container, body)
88
84
  const footer = this.renderFooter(feature)
89
85
  if (footer) container.appendChild(footer)
@@ -115,7 +111,7 @@ class Table extends TitleMixin(PopupTemplate) {
115
111
  )
116
112
  }
117
113
 
118
- async renderBody(feature) {
114
+ renderBody(feature) {
119
115
  const table = document.createElement('table')
120
116
 
121
117
  for (const key in feature.properties) {
@@ -129,7 +125,7 @@ class Table extends TitleMixin(PopupTemplate) {
129
125
  }
130
126
 
131
127
  class GeoRSSImage extends TitleMixin(PopupTemplate) {
132
- async renderBody(feature) {
128
+ renderBody(feature) {
133
129
  const body = DomUtil.create('a')
134
130
  body.href = feature.properties.link
135
131
  body.target = '_blank'
@@ -146,7 +142,7 @@ class GeoRSSImage extends TitleMixin(PopupTemplate) {
146
142
  }
147
143
 
148
144
  class GeoRSSLink extends PopupTemplate {
149
- async renderBody(feature) {
145
+ renderBody(feature) {
150
146
  if (feature.properties.link) {
151
147
  return Utils.loadTemplate(
152
148
  `<a href="${feature.properties.link}" target="_blank"><h3>${feature.getDisplayName()}</h3></a>`
@@ -155,7 +151,7 @@ class GeoRSSLink extends PopupTemplate {
155
151
  }
156
152
  }
157
153
 
158
- class OSM extends PopupTemplate {
154
+ class OSM extends TitleMixin(PopupTemplate) {
159
155
  renderTitle(feature) {
160
156
  const title = DomUtil.add('h3', 'popup-title')
161
157
  const color = feature.getPreviewColor()
@@ -176,7 +172,7 @@ class OSM extends PopupTemplate {
176
172
  return props.name
177
173
  }
178
174
 
179
- async renderBody(feature) {
175
+ renderBody(feature) {
180
176
  const props = feature.properties
181
177
  const body = document.createElement('div')
182
178
  const locale = getLocale()
@@ -242,43 +238,3 @@ class OSM extends PopupTemplate {
242
238
  return body
243
239
  }
244
240
  }
245
-
246
- const _WIKIPEDIA_CACHE = {}
247
-
248
- class Wikipedia extends PopupTemplate {
249
- async callWikipedia(wikipedia) {
250
- if (wikipedia && _WIKIPEDIA_CACHE[wikipedia]) return _WIKIPEDIA_CACHE[wikipedia]
251
- // Wikipedia value should be in form of "{locale}:{title}", according to https://wiki.openstreetmap.org/wiki/Key:wikipedia
252
- const [locale, page] = wikipedia.split(':')
253
- const url = `https://${locale}.wikipedia.org/w/api.php?action=query&format=json&origin=*&pithumbsize=500&prop=extracts|pageimages&titles=${page}`
254
- const request = new Request()
255
- const response = await request.get(url)
256
- if (response?.ok) {
257
- const data = await response.json()
258
- _WIKIPEDIA_CACHE[wikipedia] = data
259
- return data
260
- }
261
- }
262
-
263
- async renderBody(feature) {
264
- const body = document.createElement('div')
265
- const wikipedia = feature.properties.wikipedia
266
- if (!wikipedia) return ''
267
- const data = await this.callWikipedia(wikipedia)
268
- if (data) {
269
- const page = Object.values(data.query.pages)[0]
270
- const title = page.title || feature.getDisplayName()
271
- const extract = page.extract || ''
272
- const thumbnail = page.thumbnail?.source
273
- const [content, { image }] = Utils.loadTemplateWithRefs(
274
- `<div><h3>${Utils.escapeHTML(title)}</h3><img data-ref="image" hidden src="" />${Utils.escapeHTML(extract)}</div>`
275
- )
276
- if (thumbnail) {
277
- image.src = thumbnail
278
- image.hidden = false
279
- }
280
- body.appendChild(content)
281
- }
282
- return body
283
- }
284
- }
@@ -238,15 +238,11 @@ export const LeafletMarker = Marker.extend({
238
238
  },
239
239
 
240
240
  highlight: function () {
241
- this.feature.activate()
242
- this._redraw()
243
- this._bringToFront()
241
+ DomUtil.addClass(this.options.icon.elements.main, 'umap-icon-active')
244
242
  },
245
243
 
246
244
  resetHighlight: function () {
247
- this.feature.deactivate()
248
- this._redraw()
249
- this._resetZIndex()
245
+ DomUtil.removeClass(this.options.icon.elements.main, 'umap-icon-active')
250
246
  },
251
247
 
252
248
  getPopupToolbarAnchor: function () {
@@ -47,8 +47,8 @@ class BaseRequest {
47
47
  // In case of error, an alert is sent, but non 20X status are not handled
48
48
  // The consumer must check the response status by hand
49
49
  export class Request extends BaseRequest {
50
- fire(name, detail) {
51
- document.body.dispatchEvent(new CustomEvent(name, { detail }))
50
+ fire(name, params) {
51
+ document.body.dispatchEvent(new CustomEvent(name, params))
52
52
  }
53
53
 
54
54
  async _fetch(method, uri, headers, data) {
@@ -404,7 +404,6 @@ export const SCHEMA = {
404
404
  ['GeoRSSImage', translate('GeoRSS (title + image)')],
405
405
  ['GeoRSSLink', translate('GeoRSS (only link)')],
406
406
  ['OSM', translate('OpenStreetMap')],
407
- ['Wikipedia', translate('Wikipedia')],
408
407
  ],
409
408
  default: 'Default',
410
409
  },