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
@@ -97,7 +97,7 @@ U.Layer.Cluster = L.MarkerClusterGroup.extend({
97
97
  },
98
98
 
99
99
  getEditableOptions: function () {
100
- if (!L.Util.isObject(this.datalayer.options.cluster)) {
100
+ if (!U.Utils.isObject(this.datalayer.options.cluster)) {
101
101
  this.datalayer.options.cluster = {}
102
102
  }
103
103
  return [
@@ -155,7 +155,7 @@ U.Layer.Choropleth = L.FeatureGroup.extend({
155
155
 
156
156
  initialize: function (datalayer) {
157
157
  this.datalayer = datalayer
158
- if (!L.Util.isObject(this.datalayer.options.choropleth)) {
158
+ if (!U.Utils.isObject(this.datalayer.options.choropleth)) {
159
159
  this.datalayer.options.choropleth = {}
160
160
  }
161
161
  L.FeatureGroup.prototype.initialize.call(
@@ -254,16 +254,18 @@ U.Layer.Choropleth = L.FeatureGroup.extend({
254
254
  },
255
255
 
256
256
  onEdit: function (field, builder) {
257
+ // Only compute the breaks if we're dealing with choropleth
258
+ if (!field.startsWith('options.choropleth')) return
257
259
  // If user touches the breaks, then force manual mode
258
260
  if (field === 'options.choropleth.breaks') {
259
261
  this.datalayer.options.choropleth.mode = 'manual'
260
- builder.helpers['options.choropleth.mode'].fetch()
262
+ if (builder) builder.helpers['options.choropleth.mode'].fetch()
261
263
  }
262
264
  this.computeBreaks()
263
265
  // If user changes the mode or the number of classes,
264
266
  // then update the breaks input value
265
267
  if (field === 'options.choropleth.mode' || field === 'options.choropleth.classes') {
266
- builder.helpers['options.choropleth.breaks'].fetch()
268
+ if (builder) builder.helpers['options.choropleth.breaks'].fetch()
267
269
  }
268
270
  },
269
271
 
@@ -381,7 +383,7 @@ U.Layer.Heat = L.HeatLayer.extend({
381
383
  },
382
384
 
383
385
  getEditableOptions: function () {
384
- if (!L.Util.isObject(this.datalayer.options.heat)) {
386
+ if (!U.Utils.isObject(this.datalayer.options.heat)) {
385
387
  this.datalayer.options.heat = {}
386
388
  }
387
389
  return [
@@ -592,6 +594,32 @@ U.DataLayer = L.Evented.extend({
592
594
  // Automatically, others will be shown manually, and thus will
593
595
  // be in the "forced visibility" mode
594
596
  if (this.autoLoaded()) this.map.on('zoomend', this.onZoomEnd, this)
597
+ this.on('datachanged', this.map.onDataLayersChanged, this.map)
598
+ },
599
+
600
+ render: function (fields, builder) {
601
+ let impacts = U.Utils.getImpactsFromSchema(fields)
602
+
603
+ for (let impact of impacts) {
604
+ switch (impact) {
605
+ case 'ui':
606
+ this.map.onDataLayersChanged()
607
+ break
608
+ case 'data':
609
+ if (fields.includes('options.type')) {
610
+ this.resetLayer()
611
+ }
612
+ this.hide()
613
+ fields.forEach((field) => {
614
+ this.layer.onEdit(field, builder)
615
+ })
616
+ this.show()
617
+ break
618
+ case 'remote-data':
619
+ this.fetchRemoteData()
620
+ break
621
+ }
622
+ }
595
623
  },
596
624
 
597
625
  onMoveEnd: function (e) {
@@ -609,12 +637,13 @@ U.DataLayer = L.Evented.extend({
609
637
  },
610
638
 
611
639
  autoLoaded: function () {
612
- return (
613
- (this.map.datalayersOnLoad &&
614
- this.umap_id &&
615
- this.map.datalayersOnLoad.indexOf(this.umap_id.toString()) !== -1) ||
616
- (!this.map.datalayersOnLoad && this.options.displayOnLoad)
617
- )
640
+ if (!this.map.datalayersFromQueryString) return this.options.displayOnLoad
641
+ const datalayerIds = this.map.datalayersFromQueryString
642
+ let loadMe = datalayerIds.includes(this.umap_id.toString())
643
+ if (this.options.old_id) {
644
+ loadMe = loadMe || datalayerIds.includes(this.options.old_id.toString())
645
+ }
646
+ return loadMe
618
647
  },
619
648
 
620
649
  insertBefore: function (other) {
@@ -723,13 +752,13 @@ U.DataLayer = L.Evented.extend({
723
752
  },
724
753
 
725
754
  backupData: function () {
726
- this._geojson_bk = L.Util.CopyJSON(this._geojson)
755
+ this._geojson_bk = U.Utils.CopyJSON(this._geojson)
727
756
  },
728
757
 
729
758
  reindex: function () {
730
759
  const features = []
731
760
  this.eachFeature((feature) => features.push(feature))
732
- L.Util.sortFeatures(features, this.map.getOption('sortKey'))
761
+ U.Utils.sortFeatures(features, this.map.getOption('sortKey'), L.lang)
733
762
  this._index = []
734
763
  for (let i = 0; i < features.length; i++) {
735
764
  this._index.push(L.Util.stamp(features[i]))
@@ -792,16 +821,16 @@ U.DataLayer = L.Evented.extend({
792
821
  },
793
822
 
794
823
  backupOptions: function () {
795
- this._backupOptions = L.Util.CopyJSON(this.options)
824
+ this._backupOptions = U.Utils.CopyJSON(this.options)
796
825
  },
797
826
 
798
827
  resetOptions: function () {
799
- this.options = L.Util.CopyJSON(this._backupOptions)
828
+ this.options = U.Utils.CopyJSON(this._backupOptions)
800
829
  },
801
830
 
802
831
  setOptions: function (options) {
803
832
  delete options.geojson
804
- this.options = L.Util.CopyJSON(U.DataLayer.prototype.options) // Start from fresh.
833
+ this.options = U.Utils.CopyJSON(U.DataLayer.prototype.options) // Start from fresh.
805
834
  this.updateOptions(options)
806
835
  },
807
836
 
@@ -816,14 +845,14 @@ U.DataLayer = L.Evented.extend({
816
845
  this.map.datalayers[id] = this
817
846
  if (L.Util.indexOf(this.map.datalayers_index, this) === -1)
818
847
  this.map.datalayers_index.push(this)
848
+ this.map.onDataLayersChanged()
819
849
  }
820
- this.map.updateDatalayersControl()
821
850
  },
822
851
 
823
852
  _dataUrl: function () {
824
853
  const template = this.map.options.urls.datalayer_view
825
854
 
826
- let url = L.Util.template(template, {
855
+ let url = U.Utils.template(template, {
827
856
  pk: this.umap_id,
828
857
  map_id: this.map.options.umap_id,
829
858
  })
@@ -918,6 +947,17 @@ U.DataLayer = L.Evented.extend({
918
947
  includeLatLon: false,
919
948
  },
920
949
  (err, result) => {
950
+ // csv2geojson fallback to null geometries when it cannot determine
951
+ // lat or lon columns. This is valid geojson, but unwanted from a user
952
+ // point of view.
953
+ if (result && result.features.length) {
954
+ if (result.features[0].geometry === null) {
955
+ err = {
956
+ type: 'Error',
957
+ message: L._('Cannot determine latitude and longitude columns.'),
958
+ }
959
+ }
960
+ }
921
961
  if (err) {
922
962
  let message
923
963
  if (err.type === 'Error') {
@@ -970,7 +1010,7 @@ U.DataLayer = L.Evented.extend({
970
1010
  let latlngs
971
1011
 
972
1012
  if (features) {
973
- L.Util.sortFeatures(features, this.map.getOption('sortKey'))
1013
+ U.Utils.sortFeatures(features, this.map.getOption('sortKey'), L.lang)
974
1014
  for (i = 0, len = features.length; i < len; i++) {
975
1015
  this.geojsonToFeatures(features[i])
976
1016
  }
@@ -1060,7 +1100,7 @@ U.DataLayer = L.Evented.extend({
1060
1100
 
1061
1101
  importFromFile: function (f, type) {
1062
1102
  const reader = new FileReader()
1063
- type = type || L.Util.detectFileType(f)
1103
+ type = type || U.Utils.detectFileType(f)
1064
1104
  reader.readAsText(f)
1065
1105
  reader.onload = (e) => this.importRaw(e.target.result, type)
1066
1106
  },
@@ -1078,21 +1118,21 @@ U.DataLayer = L.Evented.extend({
1078
1118
  },
1079
1119
 
1080
1120
  getDeleteUrl: function () {
1081
- return L.Util.template(this.map.options.urls.datalayer_delete, {
1121
+ return U.Utils.template(this.map.options.urls.datalayer_delete, {
1082
1122
  pk: this.umap_id,
1083
1123
  map_id: this.map.options.umap_id,
1084
1124
  })
1085
1125
  },
1086
1126
 
1087
1127
  getVersionsUrl: function () {
1088
- return L.Util.template(this.map.options.urls.datalayer_versions, {
1128
+ return U.Utils.template(this.map.options.urls.datalayer_versions, {
1089
1129
  pk: this.umap_id,
1090
1130
  map_id: this.map.options.umap_id,
1091
1131
  })
1092
1132
  },
1093
1133
 
1094
1134
  getVersionUrl: function (name) {
1095
- return L.Util.template(this.map.options.urls.datalayer_version, {
1135
+ return U.Utils.template(this.map.options.urls.datalayer_version, {
1096
1136
  pk: this.umap_id,
1097
1137
  map_id: this.map.options.umap_id,
1098
1138
  name: name,
@@ -1111,10 +1151,10 @@ U.DataLayer = L.Evented.extend({
1111
1151
  },
1112
1152
 
1113
1153
  clone: function () {
1114
- const options = L.Util.CopyJSON(this.options)
1154
+ const options = U.Utils.CopyJSON(this.options)
1115
1155
  options.name = L._('Clone of {name}', { name: this.options.name })
1116
1156
  delete options.id
1117
- const geojson = L.Util.CopyJSON(this._geojson),
1157
+ const geojson = U.Utils.CopyJSON(this._geojson),
1118
1158
  datalayer = this.map.createDataLayer(options)
1119
1159
  datalayer.fromGeoJSON(geojson)
1120
1160
  return datalayer
@@ -1125,7 +1165,8 @@ U.DataLayer = L.Evented.extend({
1125
1165
  delete this.map.datalayers[L.stamp(this)]
1126
1166
  this.map.datalayers_index.splice(this.getRank(), 1)
1127
1167
  this.parentPane.removeChild(this.pane)
1128
- this.map.updateDatalayersControl()
1168
+ this.map.onDataLayersChanged()
1169
+ this.off('datachanged', this.map.onDataLayersChanged, this.map)
1129
1170
  this.fire('erase')
1130
1171
  this._leaflet_events_bk = this._leaflet_events
1131
1172
  this.map.off('moveend', this.onMoveEnd, this)
@@ -1185,32 +1226,22 @@ U.DataLayer = L.Evented.extend({
1185
1226
  },
1186
1227
  ],
1187
1228
  ]
1188
- const title = L.DomUtil.add('h3', '', container, L._('Layer properties'))
1229
+ L.DomUtil.createTitle(container, L._('Layer properties'), 'icon-layers')
1189
1230
  let builder = new U.FormBuilder(this, metadataFields, {
1190
1231
  callback: function (e) {
1191
- this.map.updateDatalayersControl()
1232
+ this.map.onDataLayersChanged()
1192
1233
  if (e.helper.field === 'options.type') {
1193
- this.resetLayer()
1194
1234
  this.edit()
1195
1235
  }
1196
1236
  },
1197
1237
  })
1198
1238
  container.appendChild(builder.build())
1199
1239
 
1200
- const redrawCallback = function (e) {
1201
- const field = e.helper.field,
1202
- builder = e.helper.builder
1203
- this.hide()
1204
- this.layer.onEdit(field, builder)
1205
- this.show()
1206
- }
1207
-
1208
1240
  const layerOptions = this.layer.getEditableOptions()
1209
1241
 
1210
1242
  if (layerOptions.length) {
1211
1243
  builder = new U.FormBuilder(this, layerOptions, {
1212
1244
  id: 'datalayer-layer-properties',
1213
- callback: redrawCallback,
1214
1245
  })
1215
1246
  const layerProperties = L.DomUtil.createFieldset(
1216
1247
  container,
@@ -1234,7 +1265,6 @@ U.DataLayer = L.Evented.extend({
1234
1265
 
1235
1266
  builder = new U.FormBuilder(this, shapeOptions, {
1236
1267
  id: 'datalayer-advanced-properties',
1237
- callback: redrawCallback,
1238
1268
  })
1239
1269
  const shapeProperties = L.DomUtil.createFieldset(container, L._('Shape properties'))
1240
1270
  shapeProperties.appendChild(builder.build())
@@ -1250,7 +1280,6 @@ U.DataLayer = L.Evented.extend({
1250
1280
 
1251
1281
  builder = new U.FormBuilder(this, optionsFields, {
1252
1282
  id: 'datalayer-advanced-properties',
1253
- callback: redrawCallback,
1254
1283
  })
1255
1284
  const advancedProperties = L.DomUtil.createFieldset(
1256
1285
  container,
@@ -1268,14 +1297,14 @@ U.DataLayer = L.Evented.extend({
1268
1297
  'options.outlinkTarget',
1269
1298
  'options.interactive',
1270
1299
  ]
1271
- builder = new U.FormBuilder(this, popupFields, { callback: redrawCallback })
1300
+ builder = new U.FormBuilder(this, popupFields)
1272
1301
  const popupFieldset = L.DomUtil.createFieldset(
1273
1302
  container,
1274
1303
  L._('Interaction options')
1275
1304
  )
1276
1305
  popupFieldset.appendChild(builder.build())
1277
1306
 
1278
- if (!L.Util.isObject(this.options.remoteData)) {
1307
+ if (!U.Utils.isObject(this.options.remoteData)) {
1279
1308
  this.options.remoteData = {}
1280
1309
  }
1281
1310
  const remoteDataFields = [
@@ -1334,7 +1363,7 @@ U.DataLayer = L.Evented.extend({
1334
1363
  L._('Delete'),
1335
1364
  function () {
1336
1365
  this._delete()
1337
- this.map.ui.closePanel()
1366
+ this.map.editPanel.close()
1338
1367
  },
1339
1368
  this
1340
1369
  )
@@ -1366,11 +1395,22 @@ U.DataLayer = L.Evented.extend({
1366
1395
  '_blank'
1367
1396
  )
1368
1397
  }
1369
- this.map.ui.openPanel({ data: { html: container }, className: 'dark' })
1398
+ const button = L.DomUtil.create('li', '')
1399
+ L.DomUtil.create('i', 'icon icon-16 icon-back', button)
1400
+ button.title = L._('Back to layers')
1401
+ // Fixme: remove me when this is merged and released
1402
+ // https://github.com/Leaflet/Leaflet/pull/9052
1403
+ L.DomEvent.disableClickPropagation(button)
1404
+ L.DomEvent.on(button, 'click', this.map.editDatalayers, this.map)
1405
+
1406
+ this.map.editPanel.open({
1407
+ content: container,
1408
+ actions: [button],
1409
+ })
1370
1410
  },
1371
1411
 
1372
1412
  getOwnOption: function (option) {
1373
- if (L.Util.usableOption(this.options, option)) return this.options[option]
1413
+ if (U.Utils.usableOption(this.options, option)) return this.options[option]
1374
1414
  },
1375
1415
 
1376
1416
  getOption: function (option, feature) {
@@ -1667,6 +1707,6 @@ L.TileLayer.include({
1667
1707
  },
1668
1708
 
1669
1709
  getAttribution: function () {
1670
- return L.Util.toHTML(this.options.attribution)
1710
+ return U.Utils.toHTML(this.options.attribution)
1671
1711
  },
1672
1712
  })
@@ -57,15 +57,20 @@ U.MapPermissions = L.Class.extend({
57
57
  content: L._('Please save the map first'),
58
58
  level: 'info',
59
59
  })
60
- const container = L.DomUtil.create('div', 'permissions-panel'),
61
- fields = [],
62
- title = L.DomUtil.create('h3', '', container)
60
+ const container = L.DomUtil.create('div', 'permissions-panel')
61
+ const fields = []
62
+ L.DomUtil.createTitle(container, L._('Update permissions'), 'icon-key')
63
63
  if (this.isAnonymousMap()) {
64
64
  if (this.options.anonymous_edit_url) {
65
65
  const helpText = `${L._('Secret edit link:')}<br>${
66
66
  this.options.anonymous_edit_url
67
67
  }`
68
- L.DomUtil.add('p', 'help-text', container, helpText)
68
+ L.DomUtil.element({
69
+ tagName: 'p',
70
+ className: 'help-text',
71
+ innerHTML: helpText,
72
+ parent: container,
73
+ })
69
74
  fields.push([
70
75
  'options.edit_status',
71
76
  {
@@ -104,7 +109,6 @@ U.MapPermissions = L.Class.extend({
104
109
  { handler: 'ManageEditors', label: L._("Map's editors") },
105
110
  ])
106
111
  }
107
- title.textContent = L._('Update permissions')
108
112
  const builder = new U.FormBuilder(this, fields)
109
113
  const form = builder.build()
110
114
  container.appendChild(form)
@@ -128,7 +132,7 @@ U.MapPermissions = L.Class.extend({
128
132
  this.map.eachDataLayer((datalayer) => {
129
133
  datalayer.permissions.edit(container)
130
134
  })
131
- this.map.ui.openPanel({ data: { html: container }, className: 'dark' })
135
+ this.map.editPanel.open({ content: container, className: 'dark' })
132
136
  },
133
137
 
134
138
  attach: async function () {
@@ -139,7 +143,7 @@ U.MapPermissions = L.Class.extend({
139
143
  content: L._('Map has been attached to your account'),
140
144
  level: 'info',
141
145
  })
142
- this.map.ui.closePanel()
146
+ this.map.editPanel.close()
143
147
  }
144
148
  },
145
149
 
@@ -171,13 +175,13 @@ U.MapPermissions = L.Class.extend({
171
175
  },
172
176
 
173
177
  getUrl: function () {
174
- return L.Util.template(this.map.options.urls.map_update_permissions, {
178
+ return U.Utils.template(this.map.options.urls.map_update_permissions, {
175
179
  map_id: this.map.options.umap_id,
176
180
  })
177
181
  },
178
182
 
179
183
  getAttachUrl: function () {
180
- return L.Util.template(this.map.options.urls.map_attach_owner, {
184
+ return U.Utils.template(this.map.options.urls.map_attach_owner, {
181
185
  map_id: this.map.options.umap_id,
182
186
  })
183
187
  },
@@ -54,22 +54,10 @@ U.Popup.Panel = U.Popup.extend({
54
54
  zoomAnimation: false,
55
55
  },
56
56
 
57
- allButton: function () {
58
- const button = L.DomUtil.create('li', '')
59
- L.DomUtil.create('i', 'umap-icon-16 umap-list', button)
60
- const label = L.DomUtil.create('span', '', button)
61
- label.textContent = label.title = L._('See all')
62
- // Fixme: remove me when this is merged and released
63
- // https://github.com/Leaflet/Leaflet/pull/9052
64
- L.DomEvent.disableClickPropagation(button)
65
- L.DomEvent.on(button, 'click', this.feature.map.openBrowser, this.feature.map)
66
- return button
67
- },
68
-
69
57
  onAdd: function (map) {
70
- map.ui.openPanel({
71
- data: { html: this._content },
72
- actions: [this.allButton()],
58
+ map.panel.open({
59
+ content: this._content,
60
+ actions: [U.Browser.backButton(map)],
73
61
  })
74
62
 
75
63
  // fire events as in base class Popup.js:onAdd
@@ -83,7 +71,7 @@ U.Popup.Panel = U.Popup.extend({
83
71
  },
84
72
 
85
73
  onRemove: function (map) {
86
- map.ui.closePanel()
74
+ map.panel.close()
87
75
 
88
76
  // fire events as in base class Popup.js:onRemove
89
77
  map.fire('popupclose', { popup: this })
@@ -124,12 +112,12 @@ U.PopupTemplate.Default = L.Class.extend({
124
112
  let center
125
113
  properties = this.feature.extendedProperties()
126
114
  // Resolve properties inside description
127
- properties.description = L.Util.greedyTemplate(
115
+ properties.description = U.Utils.greedyTemplate(
128
116
  this.feature.properties.description || '',
129
117
  properties
130
118
  )
131
- content = L.Util.greedyTemplate(template, properties)
132
- content = L.Util.toHTML(content, { target: target })
119
+ content = U.Utils.greedyTemplate(template, properties)
120
+ content = U.Utils.toHTML(content, { target: target })
133
121
  container.innerHTML = content
134
122
  return container
135
123
  },
@@ -202,7 +190,11 @@ U.PopupTemplate.Table = U.PopupTemplate.BaseWithTitle.extend({
202
190
  addRow: function (container, key, value) {
203
191
  const tr = L.DomUtil.create('tr', '', container)
204
192
  L.DomUtil.add('th', '', tr, key)
205
- L.DomUtil.add('td', '', tr, this.formatRow(key, value))
193
+ L.DomUtil.element({
194
+ tagName: 'td',
195
+ parent: tr,
196
+ innerHTML: this.formatRow(key, value),
197
+ })
206
198
  },
207
199
 
208
200
  renderBody: function () {
@@ -211,7 +203,7 @@ U.PopupTemplate.Table = U.PopupTemplate.BaseWithTitle.extend({
211
203
  for (const key in this.feature.properties) {
212
204
  if (typeof this.feature.properties[key] === 'object' || key === 'name') continue
213
205
  // TODO, manage links (url, mailto, wikipedia...)
214
- this.addRow(table, key, L.Util.escapeHTML(this.feature.properties[key]).trim())
206
+ this.addRow(table, key, U.Utils.escapeHTML(this.feature.properties[key]).trim())
215
207
  }
216
208
  return table
217
209
  },
@@ -263,7 +255,8 @@ U.PopupTemplate.OSM = U.PopupTemplate.Default.extend({
263
255
 
264
256
  getName: function () {
265
257
  const props = this.feature.properties
266
- if (L.locale && props[`name:${L.locale}`]) return props[`name:${L.locale}`]
258
+ const locale = L.getLocale()
259
+ if (locale && props[`name:${locale}`]) return props[`name:${locale}`]
267
260
  return props.name
268
261
  },
269
262
 
@@ -292,11 +285,12 @@ U.PopupTemplate.OSM = U.PopupTemplate.Default.extend({
292
285
  }
293
286
  }
294
287
  if (props.website) {
295
- L.DomUtil.element(
296
- 'a',
297
- { href: props.website, textContent: props.website },
298
- container
299
- )
288
+ L.DomUtil.element({
289
+ tagName: 'a',
290
+ parent: container,
291
+ href: props.website,
292
+ textContent: props.website,
293
+ })
300
294
  }
301
295
  const phone = props.phone || props['contact:phone']
302
296
  if (phone) {
@@ -304,7 +298,7 @@ U.PopupTemplate.OSM = U.PopupTemplate.Default.extend({
304
298
  'div',
305
299
  '',
306
300
  container,
307
- L.DomUtil.element('a', { href: `tel:${phone}`, textContent: phone })
301
+ L.DomUtil.element({ tagName: 'a', href: `tel:${phone}`, textContent: phone })
308
302
  )
309
303
  }
310
304
  if (props.mobile) {
@@ -312,7 +306,8 @@ U.PopupTemplate.OSM = U.PopupTemplate.Default.extend({
312
306
  'div',
313
307
  '',
314
308
  container,
315
- L.DomUtil.element('a', {
309
+ L.DomUtil.element({
310
+ tagName: 'a',
316
311
  href: `tel:${props.mobile}`,
317
312
  textContent: props.mobile,
318
313
  })
@@ -333,7 +328,8 @@ U.PopupTemplate.OSM = U.PopupTemplate.Default.extend({
333
328
  'div',
334
329
  'osm-link',
335
330
  container,
336
- L.DomUtil.element('a', {
331
+ L.DomUtil.element({
332
+ tagName: 'a',
337
333
  href: `https://www.openstreetmap.org/${id}`,
338
334
  textContent: L._('See on OpenStreetMap'),
339
335
  })
@@ -44,14 +44,17 @@ U.Share = L.Class.extend({
44
44
  },
45
45
 
46
46
  build: function () {
47
- this.container = L.DomUtil.create('div', 'umap-share')
48
- this.title = L.DomUtil.create('h3', '', this.container)
49
- this.title.textContent = L._('Share and download')
47
+ this.container = L.DomUtil.create('div', '')
48
+ this.title = L.DomUtil.createTitle(
49
+ this.container,
50
+ L._('Share and download'),
51
+ 'icon-share'
52
+ )
50
53
 
51
54
  L.DomUtil.createCopiableInput(
52
55
  this.container,
53
56
  L._('Link to view the map'),
54
- window.location.protocol + L.Util.getBaseUrl()
57
+ window.location.protocol + U.Utils.getBaseUrl()
55
58
  )
56
59
 
57
60
  if (this.map.options.shortUrl) {
@@ -84,7 +87,7 @@ U.Share = L.Class.extend({
84
87
  this.container,
85
88
  L._('All data and settings of the map')
86
89
  )
87
- const downloadUrl = L.Util.template(this.map.options.urls.map_download, {
90
+ const downloadUrl = U.Utils.template(this.map.options.urls.map_download, {
88
91
  map_id: this.map.options.umap_id,
89
92
  })
90
93
  const link = L.DomUtil.createLink(
@@ -140,7 +143,7 @@ U.Share = L.Class.extend({
140
143
  }
141
144
  const iframeExporter = new U.IframeExporter(this.map)
142
145
  const buildIframeCode = () => {
143
- iframe.innerHTML = iframeExporter.build()
146
+ iframe.textContent = iframeExporter.build()
144
147
  exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
145
148
  }
146
149
  buildIframeCode()
@@ -156,7 +159,7 @@ U.Share = L.Class.extend({
156
159
 
157
160
  open: function () {
158
161
  if (!this.container) this.build()
159
- this.map.ui.openPanel({ data: { html: this.container } })
162
+ this.map.panel.open({ content: this.container })
160
163
  },
161
164
 
162
165
  format: function (mode) {
@@ -213,7 +216,7 @@ U.IframeExporter = L.Evented.extend({
213
216
 
214
217
  initialize: function (map) {
215
218
  this.map = map
216
- this.baseUrl = L.Util.getBaseUrl()
219
+ this.baseUrl = U.Utils.getBaseUrl()
217
220
  // Use map default, not generic default
218
221
  this.queryString.onLoadPanel = this.map.getOption('onLoadPanel')
219
222
  },
@@ -241,7 +244,7 @@ U.IframeExporter = L.Evented.extend({
241
244
  }
242
245
  const currentView = this.options.currentView ? window.location.hash : ''
243
246
  const queryString = L.extend({}, this.queryString, options)
244
- return `${this.baseUrl}?${L.Util.buildQueryString(queryString)}${currentView}`
247
+ return `${this.baseUrl}?${U.Utils.buildQueryString(queryString)}${currentView}`
245
248
  },
246
249
 
247
250
  build: function () {
@@ -94,13 +94,12 @@ U.TableEditor = L.Class.extend({
94
94
 
95
95
  edit: function () {
96
96
  const id = 'tableeditor:edit'
97
- this.datalayer.map.fire('dataloading', { id: id })
98
97
  this.compileProperties()
99
98
  this.renderHeaders()
100
99
  this.body.innerHTML = ''
101
100
  this.datalayer.eachLayer(this.renderRow, this)
102
101
  const addButton = L.DomUtil.create('li', 'add-property')
103
- L.DomUtil.create('i', 'umap-icon-16 umap-add', addButton)
102
+ L.DomUtil.createIcon(addButton, 'icon-add')
104
103
  const label = L.DomUtil.create('span', '', addButton)
105
104
  label.textContent = label.title = L._('Add a new property')
106
105
  const addProperty = function () {
@@ -110,11 +109,10 @@ U.TableEditor = L.Class.extend({
110
109
  this.edit()
111
110
  }
112
111
  L.DomEvent.on(addButton, 'click', addProperty, this)
113
- this.datalayer.map.ui.openPanel({
114
- data: { html: this.table },
115
- className: 'umap-table-editor fullwidth dark',
112
+ this.datalayer.map.fullPanel.open({
113
+ content: this.table,
114
+ className: 'umap-table-editor',
116
115
  actions: [addButton],
117
116
  })
118
- this.datalayer.map.fire('dataload', { id: id })
119
117
  },
120
118
  })