umap-project 3.0.3__py3-none-any.whl → 3.0.5__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 (161) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/el/LC_MESSAGES/django.po +136 -56
  4. umap/locale/en/LC_MESSAGES/django.po +18 -18
  5. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/es/LC_MESSAGES/django.po +136 -56
  7. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/nl/LC_MESSAGES/django.po +1 -1
  9. umap/models.py +1 -0
  10. umap/settings/base.py +1 -0
  11. umap/static/umap/css/bar.css +1 -1
  12. umap/static/umap/css/form.css +44 -44
  13. umap/static/umap/css/tooltip.css +13 -0
  14. umap/static/umap/js/modules/autocomplete.js +7 -8
  15. umap/static/umap/js/modules/browser.js +89 -94
  16. umap/static/umap/js/modules/caption.js +6 -4
  17. umap/static/umap/js/modules/data/features.js +1 -19
  18. umap/static/umap/js/modules/data/layer.js +100 -61
  19. umap/static/umap/js/modules/facets.js +1 -1
  20. umap/static/umap/js/modules/form/fields.js +1 -1
  21. umap/static/umap/js/modules/importer.js +1 -1
  22. umap/static/umap/js/modules/managers.js +46 -0
  23. umap/static/umap/js/modules/permissions.js +1 -1
  24. umap/static/umap/js/modules/rendering/controls.js +251 -0
  25. umap/static/umap/js/modules/rendering/layers/heat.js +5 -0
  26. umap/static/umap/js/modules/rendering/map.js +21 -10
  27. umap/static/umap/js/modules/rendering/ui.js +0 -1
  28. umap/static/umap/js/modules/rules.js +56 -46
  29. umap/static/umap/js/modules/schema.js +5 -1
  30. umap/static/umap/js/modules/share.js +2 -2
  31. umap/static/umap/js/modules/slideshow.js +1 -1
  32. umap/static/umap/js/modules/sync/engine.js +23 -9
  33. umap/static/umap/js/modules/ui/bar.js +2 -2
  34. umap/static/umap/js/modules/ui/base.js +13 -0
  35. umap/static/umap/js/modules/umap.js +70 -113
  36. umap/static/umap/js/umap.controls.js +0 -310
  37. umap/static/umap/js/umap.core.js +0 -40
  38. umap/static/umap/locale/am_ET.js +8 -3
  39. umap/static/umap/locale/am_ET.json +8 -3
  40. umap/static/umap/locale/ar.js +8 -3
  41. umap/static/umap/locale/ar.json +8 -3
  42. umap/static/umap/locale/ast.js +8 -3
  43. umap/static/umap/locale/ast.json +8 -3
  44. umap/static/umap/locale/bg.js +8 -3
  45. umap/static/umap/locale/bg.json +8 -3
  46. umap/static/umap/locale/br.js +8 -3
  47. umap/static/umap/locale/br.json +8 -3
  48. umap/static/umap/locale/ca.js +27 -22
  49. umap/static/umap/locale/ca.json +27 -22
  50. umap/static/umap/locale/cs_CZ.js +5 -2
  51. umap/static/umap/locale/cs_CZ.json +5 -2
  52. umap/static/umap/locale/da.js +8 -3
  53. umap/static/umap/locale/da.json +8 -3
  54. umap/static/umap/locale/de.js +5 -2
  55. umap/static/umap/locale/de.json +5 -2
  56. umap/static/umap/locale/el.js +92 -87
  57. umap/static/umap/locale/el.json +92 -87
  58. umap/static/umap/locale/en.js +5 -2
  59. umap/static/umap/locale/en.json +5 -2
  60. umap/static/umap/locale/en_US.json +8 -3
  61. umap/static/umap/locale/es.js +18 -15
  62. umap/static/umap/locale/es.json +18 -15
  63. umap/static/umap/locale/et.js +8 -3
  64. umap/static/umap/locale/et.json +8 -3
  65. umap/static/umap/locale/eu.js +5 -2
  66. umap/static/umap/locale/eu.json +5 -2
  67. umap/static/umap/locale/fa_IR.js +5 -2
  68. umap/static/umap/locale/fa_IR.json +5 -2
  69. umap/static/umap/locale/fi.js +8 -3
  70. umap/static/umap/locale/fi.json +8 -3
  71. umap/static/umap/locale/fr.js +5 -2
  72. umap/static/umap/locale/fr.json +5 -2
  73. umap/static/umap/locale/gl.js +5 -2
  74. umap/static/umap/locale/gl.json +5 -2
  75. umap/static/umap/locale/he.js +8 -3
  76. umap/static/umap/locale/he.json +8 -3
  77. umap/static/umap/locale/hr.js +8 -3
  78. umap/static/umap/locale/hr.json +8 -3
  79. umap/static/umap/locale/hu.js +5 -2
  80. umap/static/umap/locale/hu.json +5 -2
  81. umap/static/umap/locale/id.js +8 -3
  82. umap/static/umap/locale/id.json +8 -3
  83. umap/static/umap/locale/is.js +8 -3
  84. umap/static/umap/locale/is.json +8 -3
  85. umap/static/umap/locale/it.js +5 -2
  86. umap/static/umap/locale/it.json +5 -2
  87. umap/static/umap/locale/ja.js +8 -3
  88. umap/static/umap/locale/ja.json +8 -3
  89. umap/static/umap/locale/ko.js +8 -3
  90. umap/static/umap/locale/ko.json +8 -3
  91. umap/static/umap/locale/lt.js +8 -3
  92. umap/static/umap/locale/lt.json +8 -3
  93. umap/static/umap/locale/ms.js +8 -3
  94. umap/static/umap/locale/ms.json +8 -3
  95. umap/static/umap/locale/nl.js +7 -4
  96. umap/static/umap/locale/nl.json +7 -4
  97. umap/static/umap/locale/no.js +8 -3
  98. umap/static/umap/locale/no.json +8 -3
  99. umap/static/umap/locale/pl.js +8 -3
  100. umap/static/umap/locale/pl.json +8 -3
  101. umap/static/umap/locale/pl_PL.json +8 -3
  102. umap/static/umap/locale/pt.js +5 -2
  103. umap/static/umap/locale/pt.json +5 -2
  104. umap/static/umap/locale/pt_BR.js +8 -3
  105. umap/static/umap/locale/pt_BR.json +8 -3
  106. umap/static/umap/locale/pt_PT.js +5 -2
  107. umap/static/umap/locale/pt_PT.json +5 -2
  108. umap/static/umap/locale/ro.js +8 -3
  109. umap/static/umap/locale/ro.json +8 -3
  110. umap/static/umap/locale/ru.js +8 -3
  111. umap/static/umap/locale/ru.json +8 -3
  112. umap/static/umap/locale/sk_SK.js +8 -3
  113. umap/static/umap/locale/sk_SK.json +8 -3
  114. umap/static/umap/locale/sl.js +8 -3
  115. umap/static/umap/locale/sl.json +8 -3
  116. umap/static/umap/locale/sr.js +8 -3
  117. umap/static/umap/locale/sr.json +8 -3
  118. umap/static/umap/locale/sv.js +8 -3
  119. umap/static/umap/locale/sv.json +8 -3
  120. umap/static/umap/locale/th_TH.js +8 -3
  121. umap/static/umap/locale/th_TH.json +8 -3
  122. umap/static/umap/locale/tr.js +8 -3
  123. umap/static/umap/locale/tr.json +8 -3
  124. umap/static/umap/locale/uk_UA.js +8 -3
  125. umap/static/umap/locale/uk_UA.json +8 -3
  126. umap/static/umap/locale/vi.js +8 -3
  127. umap/static/umap/locale/vi.json +8 -3
  128. umap/static/umap/locale/vi_VN.json +8 -3
  129. umap/static/umap/locale/zh.js +8 -3
  130. umap/static/umap/locale/zh.json +8 -3
  131. umap/static/umap/locale/zh_CN.json +8 -3
  132. umap/static/umap/locale/zh_TW.Big5.json +8 -3
  133. umap/static/umap/locale/zh_TW.js +5 -2
  134. umap/static/umap/locale/zh_TW.json +5 -2
  135. umap/static/umap/map.css +11 -33
  136. umap/static/umap/vars.css +4 -0
  137. umap/static/umap/vendors/togeojson/togeojson.es.js +350 -177
  138. umap/static/umap/vendors/togeojson/togeojson.es.mjs.map +1 -1
  139. umap/templates/umap/design_system.html +355 -0
  140. umap/tests/base.py +2 -2
  141. umap/tests/fixtures/heatmap_data.json +1044 -0
  142. umap/tests/integration/test_browser.py +3 -3
  143. umap/tests/integration/test_conditional_rules.py +2 -2
  144. umap/tests/integration/test_datalayer.py +0 -1
  145. umap/tests/integration/test_edit_map.py +7 -7
  146. umap/tests/integration/test_facets_browser.py +2 -2
  147. umap/tests/integration/test_heatmap.py +41 -0
  148. umap/tests/integration/test_iframe.py +25 -0
  149. umap/tests/integration/test_import.py +58 -1
  150. umap/tests/integration/test_map.py +7 -8
  151. umap/tests/integration/test_optimistic_merge.py +12 -4
  152. umap/tests/integration/test_querystring.py +1 -1
  153. umap/tests/integration/test_remote_data.py +79 -0
  154. umap/tests/integration/test_websocket_sync.py +2 -2
  155. umap/urls.py +1 -0
  156. umap/views.py +7 -0
  157. {umap_project-3.0.3.dist-info → umap_project-3.0.5.dist-info}/METADATA +8 -8
  158. {umap_project-3.0.3.dist-info → umap_project-3.0.5.dist-info}/RECORD +161 -154
  159. {umap_project-3.0.3.dist-info → umap_project-3.0.5.dist-info}/WHEEL +0 -0
  160. {umap_project-3.0.3.dist-info → umap_project-3.0.5.dist-info}/entry_points.txt +0 -0
  161. {umap_project-3.0.3.dist-info → umap_project-3.0.5.dist-info}/licenses/LICENSE +0 -0
@@ -59,3 +59,16 @@
59
59
  .tooltip-accent li:last-of-type {
60
60
  margin-bottom: 0;
61
61
  }
62
+
63
+ .umap-tooltip-container.tooltip-right:before {
64
+ right: 100%;
65
+ top: calc(50% - var(--arrow-size));
66
+ border: solid transparent;
67
+ content: " ";
68
+ height: 0;
69
+ width: 0;
70
+ position: absolute;
71
+ pointer-events: none;
72
+ border-right-color: var(--tooltip-color);
73
+ border-width: var(--arrow-size);
74
+ }
@@ -7,6 +7,7 @@ import {
7
7
  import { translate } from './i18n.js'
8
8
  import { Request, ServerRequest } from './request.js'
9
9
  import { escapeHTML, generateId } from './utils.js'
10
+ import * as Utils from './utils.js'
10
11
 
11
12
  export class BaseAutocomplete {
12
13
  constructor(parent, options) {
@@ -291,10 +292,9 @@ class BaseServerAjax extends BaseAjax {
291
292
  export const SingleMixin = (Base) =>
292
293
  class extends Base {
293
294
  initSelectedContainer() {
294
- return DomUtil.after(
295
- this.input,
296
- DomUtil.element({ tagName: 'div', className: 'umap-singleresult' })
297
- )
295
+ const el = Utils.loadTemplate('<div class="umap-singleresult"></div>')
296
+ this.input.parentNode.insertBefore(el, this.input.nextSibling)
297
+ return el
298
298
  }
299
299
 
300
300
  displaySelected(result) {
@@ -322,10 +322,9 @@ export const SingleMixin = (Base) =>
322
322
  export const MultipleMixin = (Base) =>
323
323
  class extends Base {
324
324
  initSelectedContainer() {
325
- return DomUtil.after(
326
- this.input,
327
- DomUtil.element({ tagName: 'ul', className: 'umap-multiresult' })
328
- )
325
+ const el = Utils.loadTemplate('<ul class="umap-multiresult"></ul>')
326
+ this.input.parentNode.insertBefore(el, this.input.nextSibling)
327
+ return el
329
328
  }
330
329
 
331
330
  displaySelected(result) {
@@ -5,6 +5,7 @@ import { translate } from './i18n.js'
5
5
  import * as Icon from './rendering/icon.js'
6
6
  import ContextMenu from './ui/contextmenu.js'
7
7
  import * as Utils from './utils.js'
8
+ import { SCHEMA } from './schema.js'
8
9
 
9
10
  export default class Browser {
10
11
  constructor(umap, leafletMap) {
@@ -21,35 +22,24 @@ export default class Browser {
21
22
  addFeature(feature, parent) {
22
23
  if (feature.isFiltered()) return
23
24
  if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return
24
- const row = DomUtil.create('li', `${feature.getClassName()} feature`)
25
- const zoom_to = DomUtil.createButtonIcon(
26
- row,
27
- 'icon-zoom',
28
- translate('Bring feature to center')
29
- )
30
- const edit = DomUtil.createButtonIcon(
31
- row,
32
- 'show-on-edit icon-edit',
33
- translate('Edit this feature')
34
- )
35
- const del = DomUtil.createButtonIcon(
36
- row,
37
- 'show-on-edit icon-delete',
38
- translate('Delete this feature')
39
- )
40
- const colorBox = DomUtil.create(
41
- 'i',
42
- `icon icon-16 icon-${feature.getClassName()} feature-color`,
43
- row
44
- )
45
- const title = DomUtil.create('span', 'feature-title', row)
25
+ const template = `
26
+ <li class="feature ${feature.getClassName()}">
27
+ <button class="icon icon-16 icon-zoom" title="${translate('Bring feature to center')}" data-ref=zoom></button>
28
+ <button class="icon icon-16 show-on-edit icon-edit" title="${translate('Edit this feature')}" data-ref=edit></button>
29
+ <button class="icon icon-16 show-on-edit icon-delete" title="${translate('Delete this feature')}" data-ref=remove></button>
30
+ <i class="icon icon-16 icon-${feature.getClassName()} feature-color" data-ref=colorBox></i>
31
+ <span class="feature-title" data-ref=label></span>
32
+ </li>
33
+ `
34
+ const [row, { zoom, edit, remove, colorBox, label }] =
35
+ Utils.loadTemplateWithRefs(template)
36
+ label.textContent = label.title = feature.getDisplayName() || '—'
46
37
  const symbol = feature._getIconUrl
47
38
  ? Icon.formatUrl(feature._getIconUrl(), feature)
48
39
  : null
49
- title.textContent = title.title = feature.getDisplayName() || '—'
50
40
  const bgcolor = feature.getPreviewColor()
51
41
  colorBox.style.backgroundColor = bgcolor
52
- if (symbol && symbol !== U.SCHEMA.iconUrl.default) {
42
+ if (symbol && symbol !== SCHEMA.iconUrl.default) {
53
43
  const icon = Icon.makeElement(symbol, colorBox)
54
44
  Icon.setContrast(icon, colorBox, symbol, bgcolor)
55
45
  } else if (DomUtil.contrastedColor(colorBox, bgcolor)) {
@@ -58,10 +48,10 @@ export default class Browser {
58
48
  const viewFeature = (e) => {
59
49
  feature.zoomTo({ ...e, callback: () => feature.view() })
60
50
  }
61
- DomEvent.on(zoom_to, 'click', viewFeature)
62
- DomEvent.on(title, 'click', viewFeature)
63
- DomEvent.on(edit, 'click', feature.edit, feature)
64
- DomEvent.on(del, 'click', feature.del, feature)
51
+ zoom.addEventListener('click', viewFeature)
52
+ label.addEventListener('click', viewFeature)
53
+ edit.addEventListener('click', () => feature.edit())
54
+ remove.addEventListener('click', () => feature.del())
65
55
  // HOTFIX. Remove when this is released:
66
56
  // https://github.com/Leaflet/Leaflet/pull/9052
67
57
  DomEvent.disableClickPropagation(row)
@@ -73,51 +63,51 @@ export default class Browser {
73
63
  }
74
64
 
75
65
  addDataLayer(datalayer, parent) {
76
- let className = `datalayer ${datalayer.getHidableClass()}`
77
- if (this.mode !== 'layers') className += ' show-list'
78
- const container = DomUtil.create('div', className, parent)
79
- const headline = DomUtil.create('h5', '', container)
80
- container.id = this.datalayerId(datalayer)
81
- const ul = DomUtil.create('ul', '', container)
66
+ const open = this.mode !== 'layers' ? ' open' : ''
67
+ const [container, { headline, toolbox, label }] = Utils.loadTemplateWithRefs(`
68
+ <details class="datalayer ${datalayer.getHidableClass()}" id="${this.datalayerId(datalayer)}"${open}>
69
+ <summary data-ref=headline>
70
+ <span data-ref=toolbox></span>
71
+ <span class="datalayer-name" data-id="${datalayer.id}" data-ref=label></span>
72
+ <span class="datalayer-counter"></span>
73
+ </summary>
74
+ <ul></ul>
75
+ </details>
76
+ `)
77
+ datalayer.renderToolbox(toolbox)
78
+ parent.appendChild(container)
82
79
  this.updateDatalayer(datalayer)
83
80
  }
84
81
 
85
82
  updateDatalayer(datalayer) {
86
83
  // Compute once, but use it for each feature later.
87
84
  this.bounds = this._leafletMap.getBounds()
88
- const parent = DomUtil.get(this.datalayerId(datalayer))
85
+ const id = this.datalayerId(datalayer)
86
+ const parent = document.getElementById(id)
89
87
  // Panel is not open
90
88
  if (!parent) return
91
89
  parent.classList.toggle('off', !datalayer.isVisible())
90
+ const label = parent.querySelector('.datalayer-name')
92
91
  const container = parent.querySelector('ul')
93
- const headline = parent.querySelector('h5')
94
- const toggleList = () => parent.classList.toggle('show-list')
95
- headline.innerHTML = ''
96
- const toggle = DomUtil.create('i', 'icon icon-16 datalayer-toggle-list', headline)
97
- DomEvent.on(toggle, 'click', toggleList)
98
- datalayer.renderToolbox(headline)
99
- const name = DomUtil.create('span', 'datalayer-name', headline)
100
- name.textContent = name.title = datalayer.options.name
101
- DomEvent.on(name, 'click', toggleList)
102
92
  container.innerHTML = ''
103
93
  datalayer.eachFeature((feature) => this.addFeature(feature, container))
104
-
94
+ datalayer.propagate(['properties.name'])
105
95
  const total = datalayer.count()
106
96
  if (!total) return
107
97
  const current = container.querySelectorAll('li').length
108
98
  const count = total === current ? total : `${current}/${total}`
109
- const counter = DomUtil.create('span', 'datalayer-counter', headline)
99
+ const counter = parent.querySelector('.datalayer-counter')
110
100
  counter.textContent = `(${count})`
111
101
  counter.title = translate(`Features in this layer: ${count}`)
112
102
  }
113
103
 
114
104
  toggleBadge() {
115
- U.Utils.toggleBadge(this.filtersTitle, this.hasFilters())
116
- U.Utils.toggleBadge('.umap-control-browse', this.hasFilters())
105
+ Utils.toggleBadge(this.filtersTitle, this.hasFilters())
106
+ Utils.toggleBadge('.umap-control-browse', this.hasFilters())
117
107
  }
118
108
 
119
109
  onFormChange() {
120
- this._umap.eachBrowsableDataLayer((datalayer) => {
110
+ this._umap.datalayers.browsable().map((datalayer) => {
121
111
  datalayer.resetLayer(true)
122
112
  this.updateDatalayer(datalayer)
123
113
  if (this._umap.fullPanel?.isOpen()) datalayer.tableEdit()
@@ -140,7 +130,7 @@ export default class Browser {
140
130
  onMoveEnd() {
141
131
  if (!this.isOpen()) return
142
132
  const isListDynamic = this.options.inBbox
143
- this._umap.eachBrowsableDataLayer((datalayer) => {
133
+ this._umap.datalayers.browsable().map((datalayer) => {
144
134
  if (!isListDynamic && !datalayer.hasDynamicData()) return
145
135
  this.updateDatalayer(datalayer)
146
136
  })
@@ -149,7 +139,7 @@ export default class Browser {
149
139
  update() {
150
140
  if (!this.isOpen()) return
151
141
  this.dataContainer.innerHTML = ''
152
- this._umap.eachBrowsableDataLayer((datalayer) => {
142
+ this._umap.datalayers.browsable().map((datalayer) => {
153
143
  this.addDataLayer(datalayer, this.dataContainer)
154
144
  })
155
145
  }
@@ -157,21 +147,51 @@ export default class Browser {
157
147
  open(mode) {
158
148
  // Force only if mode is known, otherwise keep current mode.
159
149
  if (mode) this.mode = mode
160
- const container = DomUtil.create('div')
150
+ const template = `
151
+ <div>
152
+ <h3><i class="icon icon-16 icon-layers"></i>${translate('Data browser')}</h3>
153
+ <details class="filters" data-ref="details">
154
+ <summary data-ref=filtersTitle><i class="icon icon-16 icon-filters"></i>${translate('Filters')}</summary>
155
+ <fieldset>
156
+ <div data-ref=formContainer>
157
+ </div>
158
+ <button class="flat" type="button" data-ref=reset><i class="icon icon-16 icon-restore" title=""></i>${translate('Reset all')}</button>
159
+ </fieldset>
160
+ </details>
161
+ <div class="main-toolbox">
162
+ <i class="icon icon-16 icon-eye" title="${translate('show/hide all layers')}" data-ref="toggle"></i>
163
+ <i class="icon icon-16 icon-zoom" title="${translate('zoom to data extent')}" data-ref="fitBounds"></i>
164
+ <i class="icon icon-16 icon-download" title="${translate('download visible data')}" data-ref="download"></i>
165
+ </div>
166
+ <div data-ref=dataContainer></div>
167
+ </div>
168
+ `
169
+ const [
170
+ container,
171
+ {
172
+ details,
173
+ filtersTitle,
174
+ toggle,
175
+ fitBounds,
176
+ download,
177
+ dataContainer,
178
+ formContainer,
179
+ reset,
180
+ },
181
+ ] = Utils.loadTemplateWithRefs(template)
161
182
  // HOTFIX. Remove when this is released:
162
183
  // https://github.com/Leaflet/Leaflet/pull/9052
163
184
  DomEvent.disableClickPropagation(container)
185
+ details.open = this.mode === 'filters'
186
+ toggle.addEventListener('click', () => this.toggleLayers())
187
+ fitBounds.addEventListener('click', () => this._umap.fitDataBounds())
188
+ download.addEventListener('click', () => this.downloadVisible(download))
189
+ download.hidden = this._umap.getProperty('embedControl') === false
164
190
 
165
- DomUtil.createTitle(container, translate('Data browser'), 'icon-layers')
166
- this.formContainer = DomUtil.createFieldset(container, L._('Filters'), {
167
- on: this.mode === 'filters',
168
- className: 'filters',
169
- icon: 'icon-filters',
170
- })
171
- this.filtersTitle = container.querySelector('summary')
191
+ this.filtersTitle = filtersTitle
192
+ this.dataContainer = dataContainer
193
+ this.formContainer = formContainer
172
194
  this.toggleBadge()
173
- this.addMainToolbox(container)
174
- this.dataContainer = DomUtil.create('div', '', container)
175
195
 
176
196
  let fields = [
177
197
  [
@@ -184,27 +204,19 @@ export default class Browser {
184
204
  builder.on('set', () => this.onFormChange())
185
205
  let filtersBuilder
186
206
  this.formContainer.appendChild(builder.build())
187
- DomEvent.on(builder.form, 'reset', () => {
207
+ builder.form.addEventListener('reset', () => {
188
208
  window.setTimeout(builder.syncAll.bind(builder))
189
209
  })
190
210
  if (this._umap.properties.facetKey) {
191
211
  fields = this._umap.facets.build()
192
212
  filtersBuilder = new Form(this._umap.facets, fields)
193
213
  filtersBuilder.on('set', () => this.onFormChange())
194
- DomEvent.on(filtersBuilder.form, 'reset', () => {
214
+ filtersBuilder.form.addEventListener('reset', () => {
195
215
  window.setTimeout(filtersBuilder.syncAll.bind(filtersBuilder))
196
216
  })
197
217
  this.formContainer.appendChild(filtersBuilder.build())
198
218
  }
199
- const reset = DomUtil.createButton('flat', this.formContainer, '', () =>
200
- this.resetFilters()
201
- )
202
- DomUtil.createIcon(reset, 'icon-restore')
203
- DomUtil.element({
204
- tagName: 'span',
205
- parent: reset,
206
- textContent: translate('Reset all'),
207
- })
219
+ reset.addEventListener('click', () => this.resetFilters())
208
220
 
209
221
  this._umap.panel.open({
210
222
  content: container,
@@ -220,21 +232,6 @@ export default class Browser {
220
232
  }
221
233
  }
222
234
 
223
- addMainToolbox(container) {
224
- const [toolbox, { toggle, fitBounds, download }] = Utils.loadTemplateWithRefs(`
225
- <div class="main-toolbox">
226
- <i class="icon icon-16 icon-eye" title="${translate('show/hide all layers')}" data-ref="toggle"></i>
227
- <i class="icon icon-16 icon-zoom" title="${translate('zoom to data extent')}" data-ref="fitBounds"></i>
228
- <i class="icon icon-16 icon-download" title="${translate('download visible data')}" data-ref="download"></i>
229
- </div>
230
- `)
231
- container.appendChild(toolbox)
232
- toggle.addEventListener('click', () => this.toggleLayers())
233
- fitBounds.addEventListener('click', () => this._umap.fitDataBounds())
234
- download.addEventListener('click', () => this.downloadVisible(download))
235
- download.hidden = this._umap.getProperty('embedControl') === false
236
- }
237
-
238
235
  downloadVisible(element) {
239
236
  const menu = new ContextMenu({ fixed: true })
240
237
  const items = []
@@ -251,10 +248,10 @@ export default class Browser {
251
248
  // If at least one layer is shown, hide it
252
249
  // otherwise show all
253
250
  let allHidden = true
254
- this._umap.eachBrowsableDataLayer((datalayer) => {
251
+ this._umap.datalayers.browsable().map((datalayer) => {
255
252
  if (datalayer.isVisible()) allHidden = false
256
253
  })
257
- this._umap.eachBrowsableDataLayer((datalayer) => {
254
+ this._umap.datalayers.browsable().map((datalayer) => {
258
255
  datalayer._forcedVisibility = true
259
256
  if (allHidden) {
260
257
  datalayer.show()
@@ -265,15 +262,13 @@ export default class Browser {
265
262
  }
266
263
 
267
264
  static backButton(umap) {
268
- const button = DomUtil.createButtonIcon(
269
- DomUtil.create('li', '', undefined),
270
- 'icon-back',
271
- translate('Back to browser')
265
+ const button = Utils.loadTemplate(
266
+ `<button class="icon icon-16 icon-back" title="${translate('Back to browser')}"></button>`
272
267
  )
273
268
  // Fixme: remove me when this is merged and released
274
269
  // https://github.com/Leaflet/Leaflet/pull/9052
275
270
  DomEvent.disableClickPropagation(button)
276
- DomEvent.on(button, 'click', () => umap.openBrowser())
271
+ button.addEventListener('click', () => umap.openBrowser())
277
272
  return button
278
273
  }
279
274
  }
@@ -68,9 +68,11 @@ export default class Caption extends Utils.WithTemplate {
68
68
  this.elements.description.hidden = true
69
69
  }
70
70
  this.elements.datalayersContainer.innerHTML = ''
71
- this._umap.eachDataLayerReverse((datalayer) =>
72
- this.addDataLayer(datalayer, this.elements.datalayersContainer)
73
- )
71
+ this._umap.datalayers
72
+ .reverse()
73
+ .map((datalayer) =>
74
+ this.addDataLayer(datalayer, this.elements.datalayersContainer)
75
+ )
74
76
  this.addCredits()
75
77
  if (this._umap.properties.created_at) {
76
78
  const created_at = translate('created at {date}', {
@@ -85,7 +87,7 @@ export default class Caption extends Utils.WithTemplate {
85
87
  }
86
88
  this._umap.panel.open({ content: this.element }).then(() => {
87
89
  // Create the legend when the panel is actually on the DOM
88
- this._umap.eachDataLayerReverse((datalayer) => datalayer.renderLegend())
90
+ this._umap.datalayers.reverse().map((datalayer) => datalayer.renderLegend())
89
91
  this._umap.propagate()
90
92
  })
91
93
  }
@@ -22,7 +22,6 @@ class Feature {
22
22
  constructor(umap, datalayer, geojson = {}, id = null) {
23
23
  this._umap = umap
24
24
  this.sync = umap.syncEngine.proxy(this)
25
- this._isDirty = false
26
25
  this._ui = null
27
26
 
28
27
  // DataLayer the feature belongs to
@@ -54,17 +53,6 @@ class Feature {
54
53
  }
55
54
  }
56
55
 
57
- set isDirty(status) {
58
- this._isDirty = status
59
- if (this.datalayer) {
60
- this.datalayer.isDirty = status
61
- }
62
- }
63
-
64
- get isDirty() {
65
- return this._isDirty
66
- }
67
-
68
56
  get ui() {
69
57
  if (!this._ui) this.makeUI()
70
58
  return this._ui
@@ -367,7 +355,6 @@ class Feature {
367
355
  }
368
356
 
369
357
  del(sync) {
370
- this.isDirty = true
371
358
  this._umap._leafletMap.closePopup()
372
359
  if (this.datalayer) {
373
360
  this.datalayer.removeFeature(this, sync)
@@ -412,13 +399,11 @@ class Feature {
412
399
 
413
400
  changeDataLayer(datalayer) {
414
401
  if (this.datalayer) {
415
- this.datalayer.isDirty = true
416
402
  this.datalayer.removeFeature(this)
417
403
  }
418
404
 
419
405
  datalayer.addFeature(this)
420
406
  this.sync.upsert(this.toGeoJSON())
421
- datalayer.isDirty = true
422
407
  this.redraw()
423
408
  }
424
409
 
@@ -485,7 +470,6 @@ class Feature {
485
470
 
486
471
  deleteProperty(property) {
487
472
  delete this.properties[property]
488
- this.isDirty = true
489
473
  }
490
474
 
491
475
  renameProperty(from, to) {
@@ -578,7 +562,6 @@ class Feature {
578
562
  delete geojson.id
579
563
  delete geojson.properties.id
580
564
  const feature = this.datalayer.makeFeature(geojson)
581
- feature.isDirty = true
582
565
  feature.edit()
583
566
  return feature
584
567
  }
@@ -614,7 +597,7 @@ class Feature {
614
597
  this.datalayer.hideFeature(this)
615
598
  this.makeUI()
616
599
  this.datalayer.showFeature(this)
617
- } else {
600
+ } else if (this.datalayer?.isBrowsable()) {
618
601
  this.ui._redraw()
619
602
  }
620
603
  }
@@ -1053,7 +1036,6 @@ export class LineString extends Path {
1053
1036
  this.pullGeometry()
1054
1037
  if (!this.ui.editEnabled()) this.edit()
1055
1038
  this.ui.editor.reset()
1056
- this.isDirty = true
1057
1039
  }
1058
1040
 
1059
1041
  isMulti() {