umap-project 2.1.2__py3-none-any.whl → 2.2.0__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 (211) hide show
  1. umap/__init__.py +1 -1
  2. umap/context_processors.py +1 -0
  3. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/en/LC_MESSAGES/django.po +32 -32
  5. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  8. umap/migrations/0020_alter_tilelayer_url_template.py +19 -0
  9. umap/migrations/0021_remove_map_description.py +16 -0
  10. umap/models.py +10 -6
  11. umap/settings/base.py +1 -0
  12. umap/static/umap/base.css +43 -156
  13. umap/static/umap/content.css +7 -25
  14. umap/static/umap/css/icon.css +112 -0
  15. umap/static/umap/css/panel.css +140 -0
  16. umap/static/umap/img/16-white.svg +5 -1
  17. umap/static/umap/img/16.svg +7 -4
  18. umap/static/umap/img/24-white.svg +3 -1
  19. umap/static/umap/img/24.svg +3 -4
  20. umap/static/umap/img/source/16-white.svg +176 -940
  21. umap/static/umap/img/source/16.svg +8 -5
  22. umap/static/umap/img/source/24-white.svg +5 -3
  23. umap/static/umap/img/source/24.svg +6 -7
  24. umap/static/umap/js/modules/browser.js +97 -73
  25. umap/static/umap/js/modules/dompurify.js +12 -0
  26. umap/static/umap/js/modules/facets.js +149 -0
  27. umap/static/umap/js/modules/global.js +9 -1
  28. umap/static/umap/js/modules/i18n.js +7 -0
  29. umap/static/umap/js/modules/orderable.js +84 -0
  30. umap/static/umap/js/modules/panel.js +76 -0
  31. umap/static/umap/js/modules/request.js +0 -1
  32. umap/static/umap/js/modules/schema.js +324 -223
  33. umap/static/umap/js/modules/urls.js +1 -16
  34. umap/static/umap/js/modules/utils.js +340 -0
  35. umap/static/umap/js/umap.autocomplete.js +40 -25
  36. umap/static/umap/js/umap.controls.js +248 -361
  37. umap/static/umap/js/umap.core.js +77 -366
  38. umap/static/umap/js/umap.datalayer.permissions.js +1 -1
  39. umap/static/umap/js/umap.features.js +65 -43
  40. umap/static/umap/js/umap.forms.js +128 -36
  41. umap/static/umap/js/umap.icon.js +11 -4
  42. umap/static/umap/js/umap.importer.js +78 -58
  43. umap/static/umap/js/umap.js +206 -192
  44. umap/static/umap/js/umap.layer.js +86 -46
  45. umap/static/umap/js/umap.permissions.js +13 -9
  46. umap/static/umap/js/umap.popup.js +26 -30
  47. umap/static/umap/js/umap.share.js +12 -9
  48. umap/static/umap/js/umap.tableeditor.js +4 -6
  49. umap/static/umap/js/umap.ui.js +10 -60
  50. umap/static/umap/locale/am_ET.js +243 -227
  51. umap/static/umap/locale/am_ET.json +21 -9
  52. umap/static/umap/locale/ar.js +243 -227
  53. umap/static/umap/locale/ar.json +21 -9
  54. umap/static/umap/locale/ast.js +243 -227
  55. umap/static/umap/locale/ast.json +21 -9
  56. umap/static/umap/locale/bg.js +243 -227
  57. umap/static/umap/locale/bg.json +21 -9
  58. umap/static/umap/locale/br.js +253 -237
  59. umap/static/umap/locale/br.json +25 -13
  60. umap/static/umap/locale/ca.js +243 -227
  61. umap/static/umap/locale/ca.json +21 -9
  62. umap/static/umap/locale/cs_CZ.js +243 -227
  63. umap/static/umap/locale/cs_CZ.json +21 -9
  64. umap/static/umap/locale/da.js +243 -227
  65. umap/static/umap/locale/da.json +21 -9
  66. umap/static/umap/locale/de.js +243 -227
  67. umap/static/umap/locale/de.json +21 -9
  68. umap/static/umap/locale/el.js +243 -227
  69. umap/static/umap/locale/el.json +21 -9
  70. umap/static/umap/locale/en.js +243 -234
  71. umap/static/umap/locale/en.json +22 -10
  72. umap/static/umap/locale/en_US.json +21 -9
  73. umap/static/umap/locale/es.js +243 -227
  74. umap/static/umap/locale/es.json +21 -9
  75. umap/static/umap/locale/et.js +243 -227
  76. umap/static/umap/locale/et.json +21 -9
  77. umap/static/umap/locale/eu.js +227 -199
  78. umap/static/umap/locale/eu.json +1 -1
  79. umap/static/umap/locale/fa_IR.js +243 -227
  80. umap/static/umap/locale/fa_IR.json +21 -9
  81. umap/static/umap/locale/fi.js +243 -227
  82. umap/static/umap/locale/fi.json +21 -9
  83. umap/static/umap/locale/fr.js +243 -234
  84. umap/static/umap/locale/fr.json +21 -9
  85. umap/static/umap/locale/gl.js +243 -227
  86. umap/static/umap/locale/gl.json +21 -9
  87. umap/static/umap/locale/he.js +243 -227
  88. umap/static/umap/locale/he.json +21 -9
  89. umap/static/umap/locale/hr.js +243 -227
  90. umap/static/umap/locale/hr.json +21 -9
  91. umap/static/umap/locale/hu.js +243 -234
  92. umap/static/umap/locale/hu.json +21 -9
  93. umap/static/umap/locale/id.js +243 -227
  94. umap/static/umap/locale/id.json +21 -9
  95. umap/static/umap/locale/is.js +243 -227
  96. umap/static/umap/locale/is.json +21 -9
  97. umap/static/umap/locale/it.js +243 -234
  98. umap/static/umap/locale/it.json +21 -9
  99. umap/static/umap/locale/ja.js +243 -227
  100. umap/static/umap/locale/ja.json +21 -9
  101. umap/static/umap/locale/ko.js +243 -227
  102. umap/static/umap/locale/ko.json +21 -9
  103. umap/static/umap/locale/lt.js +243 -227
  104. umap/static/umap/locale/lt.json +21 -9
  105. umap/static/umap/locale/ms.js +243 -234
  106. umap/static/umap/locale/ms.json +22 -10
  107. umap/static/umap/locale/nl.js +246 -230
  108. umap/static/umap/locale/nl.json +21 -9
  109. umap/static/umap/locale/no.js +243 -227
  110. umap/static/umap/locale/no.json +21 -9
  111. umap/static/umap/locale/pl.js +243 -227
  112. umap/static/umap/locale/pl.json +21 -9
  113. umap/static/umap/locale/pl_PL.json +21 -9
  114. umap/static/umap/locale/pt.js +243 -227
  115. umap/static/umap/locale/pt.json +21 -9
  116. umap/static/umap/locale/pt_BR.js +243 -227
  117. umap/static/umap/locale/pt_BR.json +21 -9
  118. umap/static/umap/locale/pt_PT.js +243 -227
  119. umap/static/umap/locale/pt_PT.json +21 -9
  120. umap/static/umap/locale/ro.js +243 -227
  121. umap/static/umap/locale/ro.json +21 -9
  122. umap/static/umap/locale/ru.js +243 -227
  123. umap/static/umap/locale/ru.json +21 -9
  124. umap/static/umap/locale/si.js +1 -1
  125. umap/static/umap/locale/si.json +1 -1
  126. umap/static/umap/locale/sk_SK.js +243 -227
  127. umap/static/umap/locale/sk_SK.json +21 -9
  128. umap/static/umap/locale/sl.js +243 -227
  129. umap/static/umap/locale/sl.json +21 -9
  130. umap/static/umap/locale/sr.js +243 -227
  131. umap/static/umap/locale/sr.json +21 -9
  132. umap/static/umap/locale/sv.js +243 -227
  133. umap/static/umap/locale/sv.json +21 -9
  134. umap/static/umap/locale/th_TH.js +243 -227
  135. umap/static/umap/locale/th_TH.json +21 -9
  136. umap/static/umap/locale/tr.js +243 -227
  137. umap/static/umap/locale/tr.json +21 -9
  138. umap/static/umap/locale/uk_UA.js +243 -227
  139. umap/static/umap/locale/uk_UA.json +21 -9
  140. umap/static/umap/locale/vi.js +243 -227
  141. umap/static/umap/locale/vi.json +21 -9
  142. umap/static/umap/locale/vi_VN.json +21 -9
  143. umap/static/umap/locale/zh.js +243 -227
  144. umap/static/umap/locale/zh.json +21 -9
  145. umap/static/umap/locale/zh_CN.json +21 -9
  146. umap/static/umap/locale/zh_TW.Big5.json +21 -9
  147. umap/static/umap/locale/zh_TW.js +243 -234
  148. umap/static/umap/locale/zh_TW.json +21 -9
  149. umap/static/umap/map.css +124 -264
  150. umap/static/umap/test/DataLayer.js +1 -1
  151. umap/static/umap/test/Feature.js +0 -226
  152. umap/static/umap/test/Map.js +0 -304
  153. umap/static/umap/test/Polygon.js +0 -256
  154. umap/static/umap/test/Polyline.js +0 -116
  155. umap/static/umap/test/TableEditor.js +10 -10
  156. umap/static/umap/test/Util.js +0 -521
  157. umap/static/umap/test/index.html +1 -5
  158. umap/static/umap/unittests/URLs.js +1 -1
  159. umap/static/umap/unittests/utils.js +610 -0
  160. umap/static/umap/vars.css +9 -0
  161. umap/static/umap/vendors/dompurify/purify.es.mjs +1525 -0
  162. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +1 -0
  163. umap/static/umap/vendors/iconlayers/iconLayers.js +1 -1
  164. umap/templates/umap/css.html +2 -0
  165. umap/templates/umap/js.html +0 -1
  166. umap/templates/umap/map_detail.html +4 -0
  167. umap/templates/umap/map_table.html +12 -10
  168. umap/templatetags/umap_tags.py +5 -0
  169. umap/tests/conftest.py +9 -0
  170. umap/tests/fixtures/test_upload_data.csv +2 -1
  171. umap/tests/fixtures/test_upload_data.umap +171 -0
  172. umap/tests/fixtures/test_upload_data_osm.json +33 -0
  173. umap/tests/integration/conftest.py +16 -0
  174. umap/tests/integration/test_anonymous_owned_map.py +30 -5
  175. umap/tests/integration/test_basics.py +21 -0
  176. umap/tests/integration/test_browser.py +16 -36
  177. umap/tests/integration/test_choropleth.py +89 -0
  178. umap/tests/integration/test_collaborative_editing.py +30 -1
  179. umap/tests/integration/test_dashboard.py +10 -0
  180. umap/tests/integration/test_datalayer.py +132 -0
  181. umap/tests/integration/test_draw_polygon.py +363 -0
  182. umap/tests/integration/test_draw_polyline.py +325 -0
  183. umap/tests/integration/test_edit_datalayer.py +145 -6
  184. umap/tests/integration/test_edit_map.py +202 -0
  185. umap/tests/integration/test_edit_marker.py +120 -0
  186. umap/tests/integration/test_edit_polygon.py +122 -0
  187. umap/tests/integration/test_facets_browser.py +132 -11
  188. umap/tests/integration/test_import.py +407 -10
  189. umap/tests/integration/test_map.py +36 -54
  190. umap/tests/integration/test_map_list.py +28 -0
  191. umap/tests/integration/test_owned_map.py +24 -6
  192. umap/tests/integration/test_picto.py +25 -38
  193. umap/tests/integration/test_querystring.py +9 -15
  194. umap/tests/integration/test_slideshow.py +0 -5
  195. umap/tests/integration/test_statics.py +3 -2
  196. umap/tests/integration/test_tableeditor.py +23 -0
  197. umap/tests/integration/test_tilelayer.py +10 -0
  198. umap/tests/integration/test_view_marker.py +64 -0
  199. umap/tests/integration/test_view_polygon.py +59 -0
  200. umap/tests/integration/test_view_polyline.py +51 -0
  201. umap/tests/test_map_views.py +13 -0
  202. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/METADATA +12 -12
  203. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/RECORD +206 -187
  204. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/WHEEL +1 -1
  205. umap/static/umap/test/Choropleth.js +0 -245
  206. umap/static/umap/test/Permissions.js +0 -74
  207. umap/static/umap/vendors/dompurify/purify.min.js +0 -3
  208. umap/static/umap/vendors/dompurify/purify.min.js.map +0 -1
  209. umap/tests/integration/test_drawing.py +0 -243
  210. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/entry_points.txt +0 -0
  211. {umap_project-2.1.2.dist-info → umap_project-2.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -29,38 +29,51 @@ U.ImportAction = U.BaseAction.extend({
29
29
  },
30
30
  })
31
31
 
32
- U.EditPropertiesAction = U.BaseAction.extend({
32
+ U.EditLayersAction = U.BaseAction.extend({
33
33
  options: {
34
34
  helpMenu: true,
35
- className: 'update-map-settings dark',
36
- tooltip: L._('Edit map properties'),
35
+ className: 'umap-control-browse dark',
36
+ tooltip: L._('Manage layers'),
37
37
  },
38
38
 
39
39
  addHooks: function () {
40
- this.map.edit()
40
+ this.map.editDatalayers()
41
41
  },
42
42
  })
43
43
 
44
- U.ChangeTileLayerAction = U.BaseAction.extend({
44
+ U.EditCaptionAction = U.BaseAction.extend({
45
45
  options: {
46
46
  helpMenu: true,
47
- className: 'dark update-map-tilelayers',
48
- tooltip: L._('Change tilelayers'),
47
+ className: 'umap-control-caption dark',
48
+ tooltip: L._('Edit map name and caption'),
49
49
  },
50
50
 
51
51
  addHooks: function () {
52
- this.map.updateTileLayers()
52
+ this.map.editCaption()
53
53
  },
54
54
  })
55
55
 
56
- U.ManageDatalayersAction = U.BaseAction.extend({
56
+ U.EditPropertiesAction = U.BaseAction.extend({
57
57
  options: {
58
- className: 'dark manage-datalayers',
59
- tooltip: L._('Manage layers'),
58
+ helpMenu: true,
59
+ className: 'update-map-settings dark',
60
+ tooltip: L._('Map advanced properties'),
61
+ },
62
+
63
+ addHooks: function () {
64
+ this.map.edit()
65
+ },
66
+ })
67
+
68
+ U.ChangeTileLayerAction = U.BaseAction.extend({
69
+ options: {
70
+ helpMenu: true,
71
+ className: 'dark update-map-tilelayers',
72
+ tooltip: L._('Change tilelayers'),
60
73
  },
61
74
 
62
75
  addHooks: function () {
63
- this.map.manageDatalayers()
76
+ this.map.updateTileLayers()
64
77
  },
65
78
  })
66
79
 
@@ -279,12 +292,7 @@ U.ContinueLineAction = U.BaseVertexAction.extend({
279
292
  })
280
293
 
281
294
  // Leaflet.Toolbar doesn't allow twice same toolbar class…
282
- U.SettingsToolbar = L.Toolbar.Control.extend({
283
- addTo: function (map) {
284
- if (map.options.editMode !== 'advanced') return
285
- L.Toolbar.Control.prototype.addTo.call(this, map)
286
- },
287
- })
295
+ U.SettingsToolbar = L.Toolbar.Control.extend({})
288
296
  U.DrawToolbar = L.Toolbar.Control.extend({
289
297
  initialize: function (options) {
290
298
  L.Toolbar.Control.prototype.initialize.call(this, options)
@@ -384,7 +392,7 @@ U.EditControl = L.Control.extend({
384
392
  'mouseover',
385
393
  function () {
386
394
  map.ui.tooltip({
387
- content: `${L._('Switch to edit mode')} (<kbd>Ctrl+E</kbd>)`,
395
+ content: map.help.displayLabel('TOGGLE_EDIT'),
388
396
  anchor: enableEditing,
389
397
  position: 'bottom',
390
398
  delay: 750,
@@ -398,26 +406,6 @@ U.EditControl = L.Control.extend({
398
406
  },
399
407
  })
400
408
 
401
- /* Share control */
402
- L.Control.Embed = L.Control.extend({
403
- options: {
404
- position: 'topleft',
405
- },
406
-
407
- onAdd: function (map) {
408
- const container = L.DomUtil.create('div', 'leaflet-control-embed umap-control')
409
- const shareButton = L.DomUtil.createButton(
410
- '',
411
- container,
412
- L._('Share and download'),
413
- map.share.open,
414
- map.share
415
- )
416
- L.DomEvent.on(shareButton, 'dblclick', L.DomEvent.stopPropagation)
417
- return container
418
- },
419
- })
420
-
421
409
  U.MoreControls = L.Control.extend({
422
410
  options: {
423
411
  position: 'topleft',
@@ -476,7 +464,7 @@ U.PermanentCreditsControl = L.Control.extend({
476
464
  },
477
465
 
478
466
  setCredits: function () {
479
- this.paragraphContainer.innerHTML = L.Util.toHTML(this.map.options.permanentCredit)
467
+ this.paragraphContainer.innerHTML = U.Utils.toHTML(this.map.options.permanentCredit)
480
468
  },
481
469
 
482
470
  setBackground: function () {
@@ -488,174 +476,79 @@ U.PermanentCreditsControl = L.Control.extend({
488
476
  },
489
477
  })
490
478
 
491
- U.DataLayersControl = L.Control.extend({
492
- options: {
493
- position: 'topleft',
494
- },
495
-
496
- labels: {
497
- zoomToLayer: L._('Zoom to layer extent'),
498
- toggleLayer: L._('Show/hide layer'),
499
- editLayer: L._('Edit'),
500
- },
501
-
479
+ L.Control.Button = L.Control.extend({
502
480
  initialize: function (map, options) {
503
481
  this.map = map
504
482
  L.Control.prototype.initialize.call(this, options)
505
483
  },
506
484
 
507
- _initLayout: function (map) {
508
- const container = (this._container = L.DomUtil.create(
509
- 'div',
510
- 'leaflet-control-browse umap-control'
511
- )),
512
- actions = L.DomUtil.create('div', 'umap-browse-actions', container)
513
- this._datalayers_container = L.DomUtil.create(
514
- 'ul',
515
- 'umap-browse-datalayers',
516
- actions
517
- )
518
-
519
- L.DomUtil.createButton(
520
- 'umap-browse-link',
521
- actions,
522
- L._('Browse data'),
523
- map.openBrowser,
524
- map
525
- )
485
+ getClassName: function () {
486
+ return this.options.className
487
+ },
526
488
 
527
- const toggleButton = L.DomUtil.createButton(
528
- 'umap-browse-toggle',
489
+ onAdd: function (map) {
490
+ const container = L.DomUtil.create('div', `${this.getClassName()} umap-control`)
491
+ const button = L.DomUtil.createButton(
492
+ '',
529
493
  container,
530
- L._('See data layers')
494
+ this.options.title,
495
+ this.onClick,
496
+ this
531
497
  )
532
- L.DomEvent.on(toggleButton, 'click', L.DomEvent.stop)
533
-
534
- map.whenReady(function () {
535
- this.update()
536
- }, this)
537
-
538
- if (L.Browser.pointer) {
539
- L.DomEvent.disableClickPropagation(container)
540
- L.DomEvent.on(container, 'wheel', L.DomEvent.stopPropagation)
541
- L.DomEvent.on(container, 'MozMousePixelScroll', L.DomEvent.stopPropagation)
542
- }
543
- if (!L.Browser.touch) {
544
- L.DomEvent.on(
545
- container,
546
- {
547
- mouseenter: this.expand,
548
- mouseleave: this.collapse,
549
- },
550
- this
551
- )
552
- } else {
553
- L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation)
554
- L.DomEvent.on(toggleButton, 'click', L.DomEvent.stop).on(
555
- toggleButton,
556
- 'click',
557
- this.expand,
558
- this
559
- )
560
- map.on('click', this.collapse, this)
561
- }
562
-
498
+ L.DomEvent.on(button, 'dblclick', L.DomEvent.stopPropagation)
563
499
  return container
564
500
  },
501
+ })
565
502
 
566
- onAdd: function (map) {
567
- if (!this._container) this._initLayout(map)
568
- if (map.options.datalayersControl === 'expanded') this.expand()
569
- return this._container
503
+ U.DataLayersControl = L.Control.Button.extend({
504
+ options: {
505
+ position: 'topleft',
506
+ className: 'umap-control-browse',
507
+ title: L._('See layers'),
570
508
  },
571
509
 
572
- onRemove: function (map) {
573
- this.collapse()
510
+ onClick: function () {
511
+ this.map.openBrowser()
574
512
  },
513
+ })
575
514
 
576
- update: function () {
577
- if (this._datalayers_container && this._map) {
578
- this._datalayers_container.innerHTML = ''
579
- this.map.eachDataLayerReverse(function (datalayer) {
580
- this.addDataLayer(this._datalayers_container, datalayer)
581
- }, this)
582
- }
515
+ U.CaptionControl = L.Control.Button.extend({
516
+ options: {
517
+ position: 'topleft',
518
+ className: 'umap-control-caption',
519
+ title: L._('About'),
583
520
  },
584
521
 
585
- expand: function () {
586
- L.DomUtil.addClass(this._container, 'expanded')
522
+ onClick: function () {
523
+ this.map.displayCaption()
587
524
  },
525
+ })
588
526
 
589
- collapse: function () {
590
- if (this.map.options.datalayersControl === 'expanded') return
591
- L.DomUtil.removeClass(this._container, 'expanded')
527
+ U.StarControl = L.Control.Button.extend({
528
+ options: {
529
+ position: 'topleft',
530
+ title: L._('Star this map'),
592
531
  },
593
532
 
594
- addDataLayer: function (container, datalayer, draggable) {
595
- const datalayerLi = L.DomUtil.create('li', '', container)
596
- if (draggable)
597
- L.DomUtil.element(
598
- 'i',
599
- { className: 'drag-handle', title: L._('Drag to reorder') },
600
- datalayerLi
601
- )
602
- datalayer.renderToolbox(datalayerLi)
603
- const title = L.DomUtil.add(
604
- 'span',
605
- 'layer-title',
606
- datalayerLi,
607
- datalayer.options.name
608
- )
609
-
610
- datalayerLi.id = `browse_data_toggle_${L.stamp(datalayer)}`
611
- L.DomUtil.classIf(datalayerLi, 'off', !datalayer.isVisible())
612
-
613
- title.textContent = datalayer.options.name
533
+ getClassName: function () {
534
+ const status = this.map.options.starred ? ' starred' : ''
535
+ return `leaflet-control-star umap-control${status}`
614
536
  },
615
537
 
616
- newDataLayer: function () {
617
- const datalayer = this.map.createDataLayer({})
618
- datalayer.edit()
538
+ onClick: function () {
539
+ this.map.star()
619
540
  },
541
+ })
620
542
 
621
- openPanel: function () {
622
- if (!this.map.editEnabled) return
623
- const container = L.DomUtil.create('ul', 'umap-browse-datalayers')
624
- const title = L.DomUtil.create('h3', '', container)
625
- title.textContent = L._('Manage layers')
626
- this.map.eachDataLayerReverse(function (datalayer) {
627
- this.addDataLayer(container, datalayer, true)
628
- }, this)
629
- const orderable = new U.Orderable(container)
630
- orderable.on(
631
- 'drop',
632
- function (e) {
633
- const layer = this.map.datalayers[e.src.dataset.id],
634
- other = this.map.datalayers[e.dst.dataset.id],
635
- minIndex = Math.min(layer.getRank(), other.getRank()),
636
- maxIndex = Math.max(layer.getRank(), other.getRank())
637
- if (e.finalIndex === 0) layer.bringToTop()
638
- else if (e.finalIndex > e.initialIndex) layer.insertBefore(other)
639
- else layer.insertAfter(other)
640
- this.map.eachDataLayerReverse((datalayer) => {
641
- if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex)
642
- datalayer.isDirty = true
643
- })
644
- this.map.indexDatalayers()
645
- },
646
- this
647
- )
648
-
649
- const bar = L.DomUtil.create('div', 'button-bar', container)
650
- L.DomUtil.createButton(
651
- 'show-on-edit block add-datalayer button',
652
- bar,
653
- L._('Add a layer'),
654
- this.newDataLayer,
655
- this
656
- )
543
+ L.Control.Embed = L.Control.Button.extend({
544
+ options: {
545
+ position: 'topleft',
546
+ title: L._('Share and download'),
547
+ className: 'leaflet-control-embed umap-control',
548
+ },
657
549
 
658
- this.map.ui.openPanel({ data: { html: container }, className: 'dark' })
550
+ onClick: function () {
551
+ this.map.share.open()
659
552
  },
660
553
  })
661
554
 
@@ -667,16 +560,31 @@ U.DataLayer.include({
667
560
  },
668
561
 
669
562
  renderToolbox: function (container) {
670
- const toggle = L.DomUtil.create('i', 'layer-toggle', container),
671
- zoomTo = L.DomUtil.create('i', 'layer-zoom_to', container),
672
- edit = L.DomUtil.create('i', 'layer-edit show-on-edit', container),
673
- table = L.DomUtil.create('i', 'layer-table-edit show-on-edit', container),
674
- remove = L.DomUtil.create('i', 'layer-delete show-on-edit', container)
675
- zoomTo.title = L._('Zoom to layer extent')
676
- toggle.title = L._('Show/hide layer')
677
- edit.title = L._('Edit')
678
- table.title = L._('Edit properties in a table')
679
- remove.title = L._('Delete layer')
563
+ const toggle = L.DomUtil.createButtonIcon(
564
+ container,
565
+ 'icon-eye',
566
+ L._('Show/hide layer')
567
+ )
568
+ const zoomTo = L.DomUtil.createButtonIcon(
569
+ container,
570
+ 'icon-zoom',
571
+ L._('Zoom to layer extent')
572
+ )
573
+ const edit = L.DomUtil.createButtonIcon(
574
+ container,
575
+ 'icon-edit show-on-edit',
576
+ L._('Edit')
577
+ )
578
+ const table = L.DomUtil.createButtonIcon(
579
+ container,
580
+ 'icon-table show-on-edit',
581
+ L._('Edit properties in a table')
582
+ )
583
+ const remove = L.DomUtil.createButtonIcon(
584
+ container,
585
+ 'icon-delete show-on-edit',
586
+ L._('Delete layer')
587
+ )
680
588
  if (this.isReadOnly()) {
681
589
  L.DomUtil.addClass(container, 'readonly')
682
590
  } else {
@@ -689,7 +597,7 @@ U.DataLayer.include({
689
597
  if (!this.isVisible()) return
690
598
  if (!confirm(L._('Are you sure you want to delete this layer?'))) return
691
599
  this._delete()
692
- this.map.ui.closePanel()
600
+ this.map.editPanel.close()
693
601
  },
694
602
  this
695
603
  )
@@ -698,7 +606,6 @@ U.DataLayer.include({
698
606
  L.DomEvent.on(zoomTo, 'click', this.zoomTo, this)
699
607
  L.DomUtil.addClass(container, this.getHidableClass())
700
608
  L.DomUtil.classIf(container, 'off', !this.isVisible())
701
- container.dataset.id = L.stamp(this)
702
609
  },
703
610
 
704
611
  getHidableElements: function () {
@@ -745,94 +652,45 @@ const ControlsMixin = {
745
652
  'search',
746
653
  'fullscreen',
747
654
  'embed',
655
+ 'datalayers',
656
+ 'caption',
748
657
  'locate',
749
658
  'measure',
750
659
  'editinosm',
751
- 'datalayers',
752
660
  'star',
753
661
  'tilelayers',
754
662
  ],
755
663
  _openFacet: function () {
756
- const container = L.DomUtil.create('div', 'umap-facet-search'),
757
- title = L.DomUtil.add('h3', 'umap-filter-title', container, L._('Facet search')),
758
- keys = Object.keys(this.getFacetKeys())
759
-
760
- const knownValues = {}
761
-
762
- keys.forEach((key) => {
763
- knownValues[key] = []
764
- if (!this.facets[key]) this.facets[key] = []
765
- })
766
-
767
- this.eachBrowsableDataLayer((datalayer) => {
768
- datalayer.eachFeature((feature) => {
769
- keys.forEach((key) => {
770
- let value = feature.properties[key]
771
- if (typeof value !== 'undefined' && !knownValues[key].includes(value)) {
772
- knownValues[key].push(value)
773
- }
774
- })
775
- })
776
- })
777
-
778
- const filterFeatures = function () {
779
- let found = false
780
- this.eachBrowsableDataLayer((datalayer) => {
781
- datalayer.resetLayer(true)
782
- if (datalayer.hasDataVisible()) found = true
783
- })
784
- // TODO: display a results counter in the panel instead.
785
- if (!found)
786
- this.ui.alert({ content: L._('No results for these facets'), level: 'info' })
787
- }
788
-
789
- const fields = keys.map((current) => [
790
- `facets.${current}`,
791
- {
792
- handler: 'FacetSearch',
793
- choices: knownValues[current],
794
- label: this.getFacetKeys()[current],
795
- },
796
- ])
797
- const builder = new U.FormBuilder(this, fields, {
798
- makeDirty: false,
799
- callback: filterFeatures,
800
- callbackContext: this,
801
- })
802
- container.appendChild(builder.build())
803
-
804
- this.ui.openPanel({ data: { html: container }, actions: [this._aboutLink()] })
805
- },
806
-
807
- _aboutLink: function () {
808
- const link = L.DomUtil.create('li', '')
809
- L.DomUtil.create('i', 'umap-icon-16 umap-caption', link)
810
- const label = L.DomUtil.create('span', '', link)
811
- label.textContent = label.title = L._('About')
812
- L.DomEvent.on(link, 'click', this.displayCaption, this)
813
- return link
664
+ this.facets.open()
814
665
  },
815
666
 
816
667
  displayCaption: function () {
817
668
  const container = L.DomUtil.create('div', 'umap-caption')
818
- let title = L.DomUtil.create('h3', '', container)
819
- title.textContent = this.options.name
669
+ L.DomUtil.createTitle(container, this.options.name, 'icon-caption')
820
670
  this.permissions.addOwnerLink('h5', container)
671
+ this.browser.tabsMenu(container, 'info')
821
672
  if (this.options.description) {
822
- const description = L.DomUtil.create('div', 'umap-map-description', container)
823
- description.innerHTML = L.Util.toHTML(this.options.description)
673
+ const description = L.DomUtil.element({
674
+ tagName: 'div',
675
+ className: 'umap-map-description',
676
+ safeHTML: U.Utils.toHTML(this.options.description),
677
+ parent: container,
678
+ })
824
679
  }
825
680
  const datalayerContainer = L.DomUtil.create('div', 'datalayer-container', container)
826
681
  this.eachVisibleDataLayer((datalayer) => {
827
682
  if (!datalayer.options.inCaption) return
828
683
  const p = L.DomUtil.create('p', 'datalayer-legend', datalayerContainer),
829
684
  legend = L.DomUtil.create('span', '', p),
830
- headline = L.DomUtil.create('strong', '', p),
831
- description = L.DomUtil.create('span', '', p)
685
+ headline = L.DomUtil.create('strong', '', p)
832
686
  datalayer.onceLoaded(function () {
833
687
  datalayer.renderLegend(legend)
834
688
  if (datalayer.options.description) {
835
- description.innerHTML = L.Util.toHTML(datalayer.options.description)
689
+ L.DomUtil.element({
690
+ tagName: 'span',
691
+ parent: p,
692
+ safeHTML: U.Utils.toHTML(datalayer.options.description),
693
+ })
836
694
  }
837
695
  })
838
696
  datalayer.renderToolbox(headline)
@@ -842,12 +700,11 @@ const ControlsMixin = {
842
700
  credits = L.DomUtil.createFieldset(creditsContainer, L._('Credits'))
843
701
  title = L.DomUtil.add('h5', '', credits, L._('User content credits'))
844
702
  if (this.options.shortCredit || this.options.longCredit) {
845
- L.DomUtil.add(
846
- 'p',
847
- '',
848
- credits,
849
- L.Util.toHTML(this.options.longCredit || this.options.shortCredit)
850
- )
703
+ L.DomUtil.element({
704
+ tagName: 'p',
705
+ parent: credits,
706
+ safeHTML: U.Utils.toHTML(this.options.longCredit || this.options.shortCredit),
707
+ })
851
708
  }
852
709
  if (this.options.licence) {
853
710
  const licence = L.DomUtil.add(
@@ -865,24 +722,27 @@ const ControlsMixin = {
865
722
  } else {
866
723
  L.DomUtil.add('p', '', credits, L._('No licence has been set'))
867
724
  }
868
- L.DomUtil.create('hr', '', credits)
869
725
  title = L.DomUtil.create('h5', '', credits)
870
726
  title.textContent = L._('Map background credits')
871
- const tilelayerCredit = L.DomUtil.create('p', '', credits),
872
- name = L.DomUtil.create('strong', '', tilelayerCredit),
873
- attribution = L.DomUtil.create('span', '', tilelayerCredit)
874
- name.textContent = `${this.selected_tilelayer.options.name} `
875
- attribution.innerHTML = this.selected_tilelayer.getAttribution()
876
- L.DomUtil.create('hr', '', credits)
877
- const umapCredit = L.DomUtil.create('p', '', credits),
878
- urls = {
879
- leaflet: 'http://leafletjs.com',
880
- django: 'https://www.djangoproject.com',
881
- umap: 'http://wiki.openstreetmap.org/wiki/UMap',
882
- changelog: 'https://umap-project.readthedocs.io/en/master/changelog/',
883
- version: this.options.umap_version,
884
- }
885
- umapCredit.innerHTML = L._(
727
+ const tilelayerCredit = L.DomUtil.create('p', '', credits)
728
+ L.DomUtil.element({
729
+ tagName: 'strong',
730
+ parent: tilelayerCredit,
731
+ textContent: `${this.selected_tilelayer.options.name} `,
732
+ })
733
+ L.DomUtil.element({
734
+ tagName: 'span',
735
+ parent: tilelayerCredit,
736
+ safeHTML: this.selected_tilelayer.getAttribution(),
737
+ })
738
+ const urls = {
739
+ leaflet: 'http://leafletjs.com',
740
+ django: 'https://www.djangoproject.com',
741
+ umap: 'http://wiki.openstreetmap.org/wiki/UMap',
742
+ changelog: 'https://umap-project.readthedocs.io/en/master/changelog/',
743
+ version: this.options.umap_version,
744
+ }
745
+ const creditHTML = L._(
886
746
  `
887
747
  Powered by <a href="{leaflet}">Leaflet</a> and
888
748
  <a href="{django}">Django</a>,
@@ -891,21 +751,8 @@ const ControlsMixin = {
891
751
  `,
892
752
  urls
893
753
  )
894
- const browser = L.DomUtil.create('li', '')
895
- L.DomUtil.create('i', 'umap-icon-16 umap-list', browser)
896
- const labelBrowser = L.DomUtil.create('span', '', browser)
897
- labelBrowser.textContent = labelBrowser.title = L._('Browse data')
898
- L.DomEvent.on(browser, 'click', this.openBrowser, this)
899
- const actions = [browser]
900
- if (this.options.facetKey) {
901
- const filter = L.DomUtil.create('li', '')
902
- L.DomUtil.create('i', 'umap-icon-16 umap-add', filter)
903
- const labelFilter = L.DomUtil.create('span', '', filter)
904
- labelFilter.textContent = labelFilter.title = L._('Facet search')
905
- L.DomEvent.on(filter, 'click', this.openFacet, this)
906
- actions.push(filter)
907
- }
908
- this.ui.openPanel({ data: { html: container }, actions: actions })
754
+ L.DomUtil.element({ tagName: 'p', innerHTML: creditHTML, parent: credits })
755
+ this.panel.open({ content: container })
909
756
  },
910
757
 
911
758
  renderEditToolbar: function () {
@@ -918,13 +765,7 @@ const ControlsMixin = {
918
765
  const rightContainer = L.DomUtil.create('div', 'umap-right-edit-toolbox', container)
919
766
  const logo = L.DomUtil.create('div', 'logo', leftContainer)
920
767
  L.DomUtil.createLink('', logo, 'uMap', '/', null, L._('Go to the homepage'))
921
- const nameButton = L.DomUtil.createButton(
922
- 'map-name',
923
- leftContainer,
924
- '',
925
- this.edit,
926
- this
927
- )
768
+ const nameButton = L.DomUtil.createButton('map-name', leftContainer, '')
928
769
  L.DomEvent.on(
929
770
  nameButton,
930
771
  'mouseover',
@@ -973,7 +814,7 @@ const ControlsMixin = {
973
814
  update()
974
815
  this.once('saved', L.bind(update, this))
975
816
  if (this.options.editMode === 'advanced') {
976
- L.DomEvent.on(nameButton, 'click', this.edit, this)
817
+ L.DomEvent.on(nameButton, 'click', this.editCaption, this)
977
818
  L.DomEvent.on(shareStatusButton, 'click', this.permissions.edit, this.permissions)
978
819
  }
979
820
  this.on('postsync', L.bind(update, this))
@@ -981,7 +822,7 @@ const ControlsMixin = {
981
822
  L.DomUtil.createLink(
982
823
  'umap-user',
983
824
  rightContainer,
984
- L._(`My Dashboard <span>({username})</span>`, {
825
+ L._(`My Dashboard ({username})`, {
985
826
  username: this.options.user.name,
986
827
  }),
987
828
  this.options.user.url
@@ -1013,10 +854,7 @@ const ControlsMixin = {
1013
854
  'leaflet-control-edit-disable',
1014
855
  rightContainer,
1015
856
  L.DomUtil.add('span', '', null, L._('View')),
1016
- function (e) {
1017
- this.disableEdit(e)
1018
- this.ui.closePanel()
1019
- },
857
+ this.disableEdit,
1020
858
  this
1021
859
  )
1022
860
  L.DomEvent.on(
@@ -1055,6 +893,48 @@ const ControlsMixin = {
1055
893
  this
1056
894
  )
1057
895
  },
896
+
897
+ editDatalayers: function () {
898
+ if (!this.editEnabled) return
899
+ const container = L.DomUtil.create('div')
900
+ L.DomUtil.createTitle(container, L._('Manage layers'), 'icon-layers')
901
+ const ul = L.DomUtil.create('ul', '', container)
902
+ this.eachDataLayerReverse((datalayer) => {
903
+ const row = L.DomUtil.create('li', 'orderable', ul)
904
+ L.DomUtil.createIcon(row, 'icon-drag', L._('Drag to reorder'))
905
+ datalayer.renderToolbox(row)
906
+ const title = L.DomUtil.add('span', '', row, datalayer.options.name)
907
+ L.DomUtil.classIf(row, 'off', !datalayer.isVisible())
908
+ title.textContent = datalayer.options.name
909
+ row.dataset.id = L.stamp(datalayer)
910
+ })
911
+ const onReorder = (src, dst, initialIndex, finalIndex) => {
912
+ const layer = this.datalayers[src.dataset.id],
913
+ other = this.datalayers[dst.dataset.id],
914
+ minIndex = Math.min(layer.getRank(), other.getRank()),
915
+ maxIndex = Math.max(layer.getRank(), other.getRank())
916
+ if (finalIndex === 0) layer.bringToTop()
917
+ else if (finalIndex > initialIndex) layer.insertBefore(other)
918
+ else layer.insertAfter(other)
919
+ this.eachDataLayerReverse((datalayer) => {
920
+ if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex)
921
+ datalayer.isDirty = true
922
+ })
923
+ this.indexDatalayers()
924
+ }
925
+ const orderable = new U.Orderable(ul, onReorder)
926
+
927
+ const bar = L.DomUtil.create('div', 'button-bar', container)
928
+ L.DomUtil.createButton(
929
+ 'show-on-edit block add-datalayer button',
930
+ bar,
931
+ L._('Add a layer'),
932
+ this.newDataLayer,
933
+ this
934
+ )
935
+
936
+ this.editPanel.open({ content: container })
937
+ },
1058
938
  }
1059
939
 
1060
940
  /* Used in view mode to define the current tilelayer */
@@ -1077,7 +957,7 @@ U.TileLayerControl = L.Control.IconLayers.extend({
1077
957
  // when the tilelayer is actually added to the map (needs this._tileZoom
1078
958
  // to be defined)
1079
959
  // Fixme when https://github.com/Leaflet/Leaflet/pull/9201 is released
1080
- const icon = L.Util.template(
960
+ const icon = U.Utils.template(
1081
961
  layer.options.url_template,
1082
962
  this.map.demoTileInfos
1083
963
  )
@@ -1124,12 +1004,11 @@ U.TileLayerChooser = L.Control.extend({
1124
1004
 
1125
1005
  openSwitcher: function (options) {
1126
1006
  const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container')
1127
- const title = L.DomUtil.create('h3', '', container)
1128
- title.textContent = L._('Change tilelayers')
1007
+ L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer')
1129
1008
  this._tilelayers_container = L.DomUtil.create('ul', '', container)
1130
1009
  this.buildList(options)
1131
- this.map.ui.openPanel({
1132
- data: { html: container },
1010
+ this.map.editPanel.open({
1011
+ content: container,
1133
1012
  className: options.className,
1134
1013
  })
1135
1014
  },
@@ -1150,7 +1029,7 @@ U.TileLayerChooser = L.Control.extend({
1150
1029
  el = L.DomUtil.create('li', selectedClass, this._tilelayers_container),
1151
1030
  img = L.DomUtil.create('img', '', el),
1152
1031
  name = L.DomUtil.create('div', '', el)
1153
- img.src = L.Util.template(tilelayer.options.url_template, this.map.demoTileInfos)
1032
+ img.src = U.Utils.template(tilelayer.options.url_template, this.map.demoTileInfos)
1154
1033
  img.loading = 'lazy'
1155
1034
  name.textContent = tilelayer.options.name
1156
1035
  L.DomEvent.on(
@@ -1178,16 +1057,16 @@ U.AttributionControl = L.Control.Attribution.extend({
1178
1057
  // Use our own container, so we can hide/show on small screens
1179
1058
  const credits = this._container.innerHTML
1180
1059
  this._container.innerHTML = ''
1181
- const container = L.DomUtil.add(
1182
- 'div',
1183
- 'attribution-container',
1184
- this._container,
1185
- credits
1186
- )
1060
+ const container = L.DomUtil.create('div', 'attribution-container', this._container)
1061
+ container.innerHTML = credits
1187
1062
  const shortCredit = this._map.getOption('shortCredit'),
1188
1063
  captionMenus = this._map.getOption('captionMenus')
1189
1064
  if (shortCredit) {
1190
- L.DomUtil.add('span', '', container, ` — ${L.Util.toHTML(shortCredit)}`)
1065
+ L.DomUtil.element({
1066
+ tagName: 'span',
1067
+ parent: container,
1068
+ safeHTML: ` — ${U.Utils.toHTML(shortCredit)}`,
1069
+ })
1191
1070
  }
1192
1071
  if (captionMenus) {
1193
1072
  const link = L.DomUtil.add('a', '', container, ` — ${L._('About')}`)
@@ -1211,27 +1090,33 @@ U.AttributionControl = L.Control.Attribution.extend({
1211
1090
  },
1212
1091
  })
1213
1092
 
1214
- U.StarControl = L.Control.extend({
1215
- options: {
1216
- position: 'topleft',
1093
+ /*
1094
+ * Take control over L.Control.Locate to be able to
1095
+ * call start() before adding the control (and thus the button) to the map.
1096
+ */
1097
+ U.Locate = L.Control.Locate.extend({
1098
+ initialize: function (map, options) {
1099
+ // When calling start(), it will try to add a location marker
1100
+ // on the layer, which is normally added in the addTo/onAdd method
1101
+ this._layer = this.options.layer = new L.LayerGroup()
1102
+ // When calling start(), it will call _activate(), which then adds
1103
+ // location related event listeners on the map
1104
+ this.map = map
1105
+ L.Control.Locate.prototype.initialize.call(this, options)
1217
1106
  },
1218
1107
 
1219
1108
  onAdd: function (map) {
1220
- const status = map.options.starred ? ' starred' : ''
1221
- const container = L.DomUtil.create(
1222
- 'div',
1223
- `leaflet-control-star umap-control${status}`
1224
- )
1225
- const starMapButton = L.DomUtil.createButton(
1226
- '',
1227
- container,
1228
- L._('Star this map'),
1229
- map.star,
1230
- map
1231
- )
1232
- L.DomEvent.on(starMapButton, 'dblclick', L.DomEvent.stopPropagation)
1109
+ const active = this._active
1110
+ const container = L.Control.Locate.prototype.onAdd.call(this, map)
1111
+ this._active = active
1233
1112
  return container
1234
1113
  },
1114
+
1115
+ _activate: function () {
1116
+ this._map = this.map
1117
+ L.Control.Locate.prototype._activate.call(this)
1118
+ this._map = null
1119
+ },
1235
1120
  })
1236
1121
 
1237
1122
  U.Search = L.PhotonSearch.extend({
@@ -1287,21 +1172,26 @@ U.Search = L.PhotonSearch.extend({
1287
1172
  },
1288
1173
 
1289
1174
  formatResult: function (feature, el) {
1290
- const self = this
1291
- const tools = L.DomUtil.create('span', 'search-result-tools', el),
1292
- zoom = L.DomUtil.create('i', 'feature-zoom_to', tools),
1293
- edit = L.DomUtil.create('i', 'feature-edit show-on-edit', tools)
1294
- zoom.title = L._('Zoom to this place')
1295
- edit.title = L._('Save this location as new feature')
1175
+ const tools = L.DomUtil.create('span', 'search-result-tools', el)
1176
+ const zoom = L.DomUtil.createButtonIcon(
1177
+ tools,
1178
+ 'icon-zoom',
1179
+ L._('Zoom to this place')
1180
+ )
1181
+ const edit = L.DomUtil.createButtonIcon(
1182
+ tools,
1183
+ 'icon-edit',
1184
+ L._('Save this location as new feature')
1185
+ )
1296
1186
  // We need to use "mousedown" because Leaflet.Photon listen to mousedown
1297
1187
  // on el.
1298
1188
  L.DomEvent.on(zoom, 'mousedown', (e) => {
1299
1189
  L.DomEvent.stop(e)
1300
- self.zoomToFeature(feature)
1190
+ this.zoomToFeature(feature)
1301
1191
  })
1302
1192
  L.DomEvent.on(edit, 'mousedown', (e) => {
1303
1193
  L.DomEvent.stop(e)
1304
- const datalayer = self.map.defaultEditDataLayer()
1194
+ const datalayer = this.map.defaultEditDataLayer()
1305
1195
  const layer = datalayer.geojsonToFeatures(feature)
1306
1196
  layer.isDirty = true
1307
1197
  layer.edit()
@@ -1319,7 +1209,7 @@ U.Search = L.PhotonSearch.extend({
1319
1209
 
1320
1210
  onSelected: function (feature) {
1321
1211
  this.zoomToFeature(feature)
1322
- this.map.ui.closePanel()
1212
+ this.map.panel.close()
1323
1213
  },
1324
1214
  })
1325
1215
 
@@ -1329,6 +1219,7 @@ U.SearchControl = L.Control.extend({
1329
1219
  },
1330
1220
 
1331
1221
  onAdd: function (map) {
1222
+ this.map = map
1332
1223
  const container = L.DomUtil.create('div', 'leaflet-control-search umap-control')
1333
1224
  L.DomEvent.disableClickPropagation(container)
1334
1225
  L.DomUtil.createButton(
@@ -1337,38 +1228,34 @@ U.SearchControl = L.Control.extend({
1337
1228
  L._('Search location'),
1338
1229
  (e) => {
1339
1230
  L.DomEvent.stop(e)
1340
- this.openPanel(map)
1231
+ this.open()
1341
1232
  },
1342
1233
  this
1343
1234
  )
1344
1235
  return container
1345
1236
  },
1346
1237
 
1347
- openPanel: function (map) {
1238
+ open: function () {
1348
1239
  const options = {
1349
1240
  limit: 10,
1350
1241
  noResultLabel: L._('No results'),
1351
1242
  }
1352
- if (map.options.photonUrl) options.url = map.options.photonUrl
1353
- const container = L.DomUtil.create('div', 'umap-search')
1243
+ if (this.map.options.photonUrl) options.url = this.map.options.photonUrl
1244
+ const container = L.DomUtil.create('div', '')
1354
1245
 
1355
- const title = L.DomUtil.create('h3', '', container)
1356
- title.textContent = L._('Search location')
1246
+ L.DomUtil.createTitle(container, L._('Search location'), 'icon-search')
1357
1247
  const input = L.DomUtil.create('input', 'photon-input', container)
1358
1248
  const resultsContainer = L.DomUtil.create('div', 'photon-autocomplete', container)
1359
- this.search = new U.Search(map, input, options)
1249
+ this.search = new U.Search(this.map, input, options)
1360
1250
  const id = Math.random()
1361
1251
  this.search.on('ajax:send', () => {
1362
- map.fire('dataloading', { id: id })
1252
+ this.map.fire('dataloading', { id: id })
1363
1253
  })
1364
1254
  this.search.on('ajax:return', () => {
1365
- map.fire('dataload', { id: id })
1255
+ this.map.fire('dataload', { id: id })
1366
1256
  })
1367
1257
  this.search.resultsContainer = resultsContainer
1368
- map.ui.once('panel:ready', () => {
1369
- input.focus()
1370
- })
1371
- map.ui.openPanel({ data: { html: container } })
1258
+ this.map.panel.open({ content: container }).then(input.focus)
1372
1259
  },
1373
1260
  })
1374
1261