umap-project 3.4.0b3__py3-none-any.whl → 3.6.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.
Files changed (222) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/br/LC_MESSAGES/django.po +71 -57
  4. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/da/LC_MESSAGES/django.po +18 -14
  6. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/de/LC_MESSAGES/django.po +20 -16
  8. umap/locale/en/LC_MESSAGES/django.po +18 -14
  9. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/es/LC_MESSAGES/django.po +20 -16
  11. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  12. umap/locale/fr/LC_MESSAGES/django.po +18 -14
  13. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  14. umap/locale/hu/LC_MESSAGES/django.po +20 -16
  15. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  16. umap/locale/pl/LC_MESSAGES/django.po +101 -95
  17. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/zh_TW/LC_MESSAGES/django.po +20 -16
  19. umap/management/commands/clean_tilelayer.py +0 -1
  20. umap/management/commands/search_maps.py +95 -0
  21. umap/settings/__init__.py +9 -1
  22. umap/settings/base.py +7 -6
  23. umap/static/umap/content.css +0 -3
  24. umap/static/umap/css/bar.css +9 -6
  25. umap/static/umap/css/form.css +25 -9
  26. umap/static/umap/css/icon.css +8 -0
  27. umap/static/umap/css/popup.css +1 -0
  28. umap/static/umap/img/16-white.svg +5 -2
  29. umap/static/umap/img/16.svg +1 -1
  30. umap/static/umap/img/source/16-white.svg +7 -4
  31. umap/static/umap/img/source/16.svg +1 -1
  32. umap/static/umap/js/components/copiable.js +47 -0
  33. umap/static/umap/js/modules/autocomplete.js +32 -67
  34. umap/static/umap/js/modules/browser.js +31 -14
  35. umap/static/umap/js/modules/data/features.js +34 -36
  36. umap/static/umap/js/modules/data/fields.js +199 -23
  37. umap/static/umap/js/modules/data/layer.js +85 -96
  38. umap/static/umap/js/modules/domutils.js +25 -1
  39. umap/static/umap/js/modules/filters.js +24 -50
  40. umap/static/umap/js/modules/form/builder.js +17 -16
  41. umap/static/umap/js/modules/form/fields.js +20 -20
  42. umap/static/umap/js/modules/formatter.js +9 -1
  43. umap/static/umap/js/modules/help.js +12 -13
  44. umap/static/umap/js/modules/importer.js +17 -26
  45. umap/static/umap/js/modules/importers/banfr.js +0 -1
  46. umap/static/umap/js/modules/importers/cadastrefr.js +19 -19
  47. umap/static/umap/js/modules/importers/communesfr.js +7 -8
  48. umap/static/umap/js/modules/importers/datasets.js +14 -14
  49. umap/static/umap/js/modules/importers/geodatamine.js +20 -22
  50. umap/static/umap/js/modules/importers/opendata.js +10 -0
  51. umap/static/umap/js/modules/importers/overpass.js +19 -18
  52. umap/static/umap/js/modules/managers.js +1 -1
  53. umap/static/umap/js/modules/permissions.js +15 -5
  54. umap/static/umap/js/modules/rendering/controls.js +203 -10
  55. umap/static/umap/js/modules/rendering/icon.js +5 -9
  56. umap/static/umap/js/modules/rendering/layers/base.js +1 -1
  57. umap/static/umap/js/modules/rendering/layers/classified.js +16 -11
  58. umap/static/umap/js/modules/rendering/layers/heat.js +1 -0
  59. umap/static/umap/js/modules/rendering/map.js +67 -57
  60. umap/static/umap/js/modules/rendering/popup.js +6 -3
  61. umap/static/umap/js/modules/rendering/template.js +40 -40
  62. umap/static/umap/js/modules/rendering/ui.js +1 -2
  63. umap/static/umap/js/modules/rules.js +34 -41
  64. umap/static/umap/js/modules/schema.js +0 -7
  65. umap/static/umap/js/modules/share.js +36 -69
  66. umap/static/umap/js/modules/slideshow.js +3 -3
  67. umap/static/umap/js/modules/tableeditor.js +0 -1
  68. umap/static/umap/js/modules/ui/bar.js +53 -33
  69. umap/static/umap/js/modules/ui/hash.js +36 -0
  70. umap/static/umap/js/modules/ui/loader.js +26 -0
  71. umap/static/umap/js/modules/ui/panel.js +33 -21
  72. umap/static/umap/js/modules/ui/tooltip.js +1 -1
  73. umap/static/umap/js/modules/umap.js +81 -80
  74. umap/static/umap/js/modules/utils.js +13 -3
  75. umap/static/umap/js/umap.controls.js +16 -179
  76. umap/static/umap/locale/am_ET.js +7 -8
  77. umap/static/umap/locale/am_ET.json +7 -8
  78. umap/static/umap/locale/ar.js +7 -8
  79. umap/static/umap/locale/ar.json +7 -8
  80. umap/static/umap/locale/ast.js +7 -8
  81. umap/static/umap/locale/ast.json +7 -8
  82. umap/static/umap/locale/bg.js +7 -8
  83. umap/static/umap/locale/bg.json +7 -8
  84. umap/static/umap/locale/br.js +44 -36
  85. umap/static/umap/locale/br.json +44 -36
  86. umap/static/umap/locale/ca.js +7 -8
  87. umap/static/umap/locale/ca.json +7 -8
  88. umap/static/umap/locale/cs_CZ.js +7 -8
  89. umap/static/umap/locale/cs_CZ.json +7 -8
  90. umap/static/umap/locale/da.js +8 -9
  91. umap/static/umap/locale/da.json +8 -9
  92. umap/static/umap/locale/de.js +62 -63
  93. umap/static/umap/locale/de.json +62 -63
  94. umap/static/umap/locale/el.js +7 -8
  95. umap/static/umap/locale/el.json +7 -8
  96. umap/static/umap/locale/en.js +7 -8
  97. umap/static/umap/locale/en.json +7 -8
  98. umap/static/umap/locale/en_US.json +7 -8
  99. umap/static/umap/locale/es.js +19 -20
  100. umap/static/umap/locale/es.json +19 -20
  101. umap/static/umap/locale/et.js +7 -8
  102. umap/static/umap/locale/et.json +7 -8
  103. umap/static/umap/locale/eu.js +23 -24
  104. umap/static/umap/locale/eu.json +23 -24
  105. umap/static/umap/locale/fa_IR.js +7 -8
  106. umap/static/umap/locale/fa_IR.json +7 -8
  107. umap/static/umap/locale/fi.js +7 -8
  108. umap/static/umap/locale/fi.json +7 -8
  109. umap/static/umap/locale/fr.js +11 -12
  110. umap/static/umap/locale/fr.json +11 -12
  111. umap/static/umap/locale/gl.js +147 -148
  112. umap/static/umap/locale/gl.json +147 -148
  113. umap/static/umap/locale/he.js +7 -8
  114. umap/static/umap/locale/he.json +7 -8
  115. umap/static/umap/locale/hr.js +7 -8
  116. umap/static/umap/locale/hr.json +7 -8
  117. umap/static/umap/locale/hu.js +8 -9
  118. umap/static/umap/locale/hu.json +8 -9
  119. umap/static/umap/locale/id.js +7 -8
  120. umap/static/umap/locale/id.json +7 -8
  121. umap/static/umap/locale/is.js +7 -8
  122. umap/static/umap/locale/is.json +7 -8
  123. umap/static/umap/locale/it.js +7 -8
  124. umap/static/umap/locale/it.json +7 -8
  125. umap/static/umap/locale/ja.js +7 -8
  126. umap/static/umap/locale/ja.json +7 -8
  127. umap/static/umap/locale/ko.js +7 -8
  128. umap/static/umap/locale/ko.json +7 -8
  129. umap/static/umap/locale/lt.js +7 -8
  130. umap/static/umap/locale/lt.json +7 -8
  131. umap/static/umap/locale/ms.js +7 -8
  132. umap/static/umap/locale/ms.json +7 -8
  133. umap/static/umap/locale/nl.js +7 -8
  134. umap/static/umap/locale/nl.json +7 -8
  135. umap/static/umap/locale/no.js +7 -8
  136. umap/static/umap/locale/no.json +7 -8
  137. umap/static/umap/locale/pl.js +53 -54
  138. umap/static/umap/locale/pl.json +53 -54
  139. umap/static/umap/locale/pl_PL.json +7 -8
  140. umap/static/umap/locale/pt.js +7 -8
  141. umap/static/umap/locale/pt.json +7 -8
  142. umap/static/umap/locale/pt_BR.js +7 -8
  143. umap/static/umap/locale/pt_BR.json +7 -8
  144. umap/static/umap/locale/pt_PT.js +7 -8
  145. umap/static/umap/locale/pt_PT.json +7 -8
  146. umap/static/umap/locale/ro.js +7 -8
  147. umap/static/umap/locale/ro.json +7 -8
  148. umap/static/umap/locale/ru.js +7 -8
  149. umap/static/umap/locale/ru.json +7 -8
  150. umap/static/umap/locale/sk_SK.js +7 -8
  151. umap/static/umap/locale/sk_SK.json +7 -8
  152. umap/static/umap/locale/sl.js +7 -8
  153. umap/static/umap/locale/sl.json +7 -8
  154. umap/static/umap/locale/sr.js +7 -8
  155. umap/static/umap/locale/sr.json +7 -8
  156. umap/static/umap/locale/sv.js +7 -8
  157. umap/static/umap/locale/sv.json +7 -8
  158. umap/static/umap/locale/th_TH.js +7 -8
  159. umap/static/umap/locale/th_TH.json +7 -8
  160. umap/static/umap/locale/tr.js +7 -8
  161. umap/static/umap/locale/tr.json +7 -8
  162. umap/static/umap/locale/uk_UA.js +7 -8
  163. umap/static/umap/locale/uk_UA.json +7 -8
  164. umap/static/umap/locale/vi.js +7 -8
  165. umap/static/umap/locale/vi.json +7 -8
  166. umap/static/umap/locale/vi_VN.json +7 -8
  167. umap/static/umap/locale/zh.js +7 -8
  168. umap/static/umap/locale/zh.json +7 -8
  169. umap/static/umap/locale/zh_CN.json +7 -8
  170. umap/static/umap/locale/zh_TW.Big5.json +7 -8
  171. umap/static/umap/locale/zh_TW.js +20 -21
  172. umap/static/umap/locale/zh_TW.json +20 -21
  173. umap/static/umap/map.css +6 -21
  174. umap/static/umap/unittests/utils.js +7 -7
  175. umap/static/umap/vendors/locatecontrol/L.Control.Locate.esm.js +942 -0
  176. umap/static/umap/vendors/photon/leaflet.photon.esm.js +472 -0
  177. umap/sync/app.py +4 -1
  178. umap/templates/umap/content_footer.html +1 -0
  179. umap/templates/umap/css.html +0 -4
  180. umap/templates/umap/js.html +1 -8
  181. umap/templates/umap/team_form.html +2 -1
  182. umap/tests/integration/conftest.py +3 -2
  183. umap/tests/integration/test_anonymous_owned_map.py +1 -1
  184. umap/tests/integration/test_conditional_rules.py +106 -51
  185. umap/tests/integration/test_draw_polygon.py +4 -0
  186. umap/tests/integration/test_draw_polyline.py +11 -0
  187. umap/tests/integration/test_edit_datalayer.py +1 -1
  188. umap/tests/integration/test_edit_map.py +2 -0
  189. umap/tests/integration/test_fields.py +19 -0
  190. umap/tests/integration/test_filters.py +24 -0
  191. umap/tests/integration/test_iframe.py +1 -1
  192. umap/tests/integration/test_import.py +26 -0
  193. umap/tests/integration/test_map.py +3 -3
  194. umap/tests/integration/test_optimistic_merge.py +7 -1
  195. umap/tests/integration/test_owned_map.py +2 -2
  196. umap/tests/integration/test_popup.py +31 -0
  197. umap/tests/integration/test_remote_data.py +5 -5
  198. umap/tests/integration/test_search.py +41 -0
  199. umap/tests/integration/test_share.py +2 -2
  200. umap/tests/integration/test_team.py +1 -1
  201. umap/tests/integration/test_websocket_sync.py +6 -1
  202. umap/tests/test_search_maps_command.py +44 -0
  203. umap/tests/test_utils.py +4 -1
  204. umap/utils.py +10 -3
  205. umap/views.py +17 -4
  206. {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/METADATA +29 -23
  207. {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/RECORD +210 -214
  208. {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/WHEEL +1 -1
  209. umap/static/umap/js/umap.core.js +0 -93
  210. umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.css +0 -46
  211. umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.js +0 -240
  212. umap/static/umap/vendors/editinosm/edit-in-osm.png +0 -0
  213. umap/static/umap/vendors/hash/leaflet-hash.js +0 -162
  214. umap/static/umap/vendors/loading/Control.Loading.css +0 -26
  215. umap/static/umap/vendors/loading/Control.Loading.js +0 -351
  216. umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.css +0 -1
  217. umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.css.map +0 -1
  218. umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js +0 -4
  219. umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js.map +0 -1
  220. umap/static/umap/vendors/photon/leaflet.photon.js +0 -487
  221. {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/entry_points.txt +0 -0
  222. {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,3 @@
1
- import { DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
2
1
  import { MutatingForm } from './form/builder.js'
3
2
  import { EXPORT_FORMATS } from './formatter.js'
4
3
  import { translate } from './i18n.js'
@@ -11,39 +10,35 @@ export default class Share {
11
10
  }
12
11
 
13
12
  build() {
14
- this.container = DomUtil.create('div', '')
15
- this.title = DomUtil.createTitle(
16
- this.container,
17
- translate('Share and download'),
18
- 'icon-share'
19
- )
20
-
21
- DOMUtils.copiableInput(
22
- this.container,
23
- translate('Link to view the map'),
24
- window.location.protocol + Utils.getBaseUrl()
25
- )
26
-
13
+ const downloadUrl = this._umap.urls.get('map_download', {
14
+ map_id: this._umap.id,
15
+ })
16
+ const [container, { shortUrl, list, customLink, textarea, iframeOptionsWrapper }] =
17
+ DOMUtils.loadTemplateWithRefs(`
18
+ <div>
19
+ <h3><i class="icon icon-16 icon-share"></i> ${translate('Share and download')}</h3>
20
+ <h4>${translate('Share')}</h4>
21
+ <copiable-input data-label="${translate('Link to view the map')}" data-value="${window.location.protocol + Utils.getBaseUrl()}"></copiable-input>
22
+ <copiable-input data-label="${translate('Short link')}" data-value="${this._umap.properties.shortUrl}" data-ref="shortUrl" hidden></copiable-input>
23
+ <copiable-textarea data-label="${translate('Customized link')}" data-ref="customLink"></copiable-textarea>
24
+ <copiable-textarea data-label="${translate('Iframe')}" data-ref="textarea"></copiable-textarea>
25
+ <div data-ref="iframeOptionsWrapper"></div>
26
+ <hr>
27
+ <h4>${translate('Download')}</h4>
28
+ <h5>${translate("Only visible layers' data")}</h5>
29
+ <ul data-ref="list" class="downloads"></ul>
30
+ <h5>${translate('All data and settings of the map')}</h5>
31
+ <p>
32
+ <a href="${downloadUrl}" download="backup.umap">
33
+ <i class="icon icon-16 icon-backup"></i>${translate('full backup')}
34
+ </a>
35
+ </p>
36
+ </div>
37
+ `)
38
+ this.container = container
27
39
  if (this._umap.properties.shortUrl) {
28
- DOMUtils.copiableInput(
29
- this.container,
30
- translate('Short link'),
31
- this._umap.properties.shortUrl
32
- )
40
+ shortUrl.hidden = false
33
41
  }
34
-
35
- DomUtil.create('hr', '', this.container)
36
-
37
- DomUtil.add('h4', '', this.container, translate('Download'))
38
- DomUtil.add(
39
- 'small',
40
- 'label',
41
- this.container,
42
- translate("Only visible layers' data")
43
- )
44
- const list = document.createElement('ul')
45
- list.classList.add('downloads')
46
- this.container.appendChild(list)
47
42
  for (const format of Object.keys(EXPORT_FORMATS).concat('jpg', 'png')) {
48
43
  const button = Utils.loadTemplate(`
49
44
  <li>
@@ -55,38 +50,7 @@ export default class Share {
55
50
  button.addEventListener('click', () => this.download(format))
56
51
  list.appendChild(button)
57
52
  }
58
- DomUtil.create('div', 'vspace', this.container)
59
- DomUtil.add(
60
- 'small',
61
- 'label',
62
- this.container,
63
- translate('All data and settings of the map')
64
- )
65
- const downloadUrl = this._umap.urls.get('map_download', {
66
- map_id: this._umap.id,
67
- })
68
- const link = Utils.loadTemplate(`
69
- <div>
70
- <a href="${downloadUrl}">
71
- <i class="icon icon-16 icon-backup"></i>${translate('full backup')}
72
- </a>
73
- </div>
74
- `)
75
- this.container.appendChild(link)
76
- // File will be named by back-office
77
- link.setAttribute('download', 'backup.umap')
78
- DomUtil.create('hr', '', this.container)
79
53
 
80
- const embedTitle = DomUtil.add('h4', '', this.container, translate('Embed the map'))
81
- const iframe = DomUtil.create('textarea', 'umap-share-iframe', this.container)
82
- const urlTitle = DomUtil.add('h4', '', this.container, translate('Direct link'))
83
- const exportUrl = DOMUtils.copiableInput(
84
- this.container,
85
- translate('Share this link to open a customized map view'),
86
- ''
87
- )
88
-
89
- exportUrl.type = 'text'
90
54
  const UIFields = [
91
55
  ['dimensions.width', { handler: 'Input', label: translate('width') }],
92
56
  ['dimensions.height', { handler: 'Input', label: translate('height') }],
@@ -123,14 +87,17 @@ export default class Share {
123
87
  }
124
88
  const iframeExporter = new IframeExporter(this._umap)
125
89
  const buildIframeCode = () => {
126
- iframe.textContent = iframeExporter.build()
127
- exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
90
+ textarea.setAttribute('value', iframeExporter.build())
91
+ customLink.setAttribute(
92
+ 'value',
93
+ window.location.protocol + iframeExporter.buildUrl()
94
+ )
128
95
  }
129
96
  buildIframeCode()
130
97
  const builder = new MutatingForm(iframeExporter, UIFields)
131
98
  builder.on('set', buildIframeCode)
132
- const iframeOptions = DomUtil.createFieldset(
133
- this.container,
99
+ const iframeOptions = DOMUtils.createFieldset(
100
+ iframeOptionsWrapper,
134
101
  translate('Embed and link options')
135
102
  )
136
103
  iframeOptions.appendChild(builder.build())
@@ -222,13 +189,13 @@ class IframeExporter {
222
189
  delete this.queryString.datalayers
223
190
  }
224
191
  const currentView = this.options.currentView ? window.location.hash : ''
225
- const queryString = L.extend({}, this.queryString, options)
192
+ const queryString = Object.assign({}, this.queryString, options)
226
193
  return `${this.baseUrl}?${Utils.buildQueryString(queryString)}${currentView}`
227
194
  }
228
195
 
229
196
  build() {
230
197
  const iframeUrl = this.buildUrl()
231
- let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
198
+ let code = `<iframe style="width: ${this.dimensions.width}; height: ${this.dimensions.height}; border: 0;" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
232
199
  if (this.options.includeFullScreenLink) {
233
200
  const fullUrl = this.buildUrl({ scrollWheelZoom: true })
234
201
  code += `<p><a href="${fullUrl}">${translate('See full screen')}</a></p>`
@@ -89,8 +89,8 @@ export default class Slideshow extends WithTemplate {
89
89
  play() {
90
90
  if (this._id) return
91
91
  if (this._umap.editEnabled || !this.isEnabled()) return
92
- L.DomUtil.addClass(document.body, this.CLASSNAME)
93
- this._id = window.setInterval(L.bind(this.loop, this), this.properties.delay)
92
+ document.body.classList.add(this.CLASSNAME)
93
+ this._id = window.setInterval(() => this.loop(), this.properties.delay)
94
94
  this.startSpinner()
95
95
  this.loop()
96
96
  }
@@ -103,7 +103,7 @@ export default class Slideshow extends WithTemplate {
103
103
  pause() {
104
104
  if (this._id) {
105
105
  this.stopSpinner()
106
- L.DomUtil.removeClass(document.body, this.CLASSNAME)
106
+ document.body.classList.remove(this.CLASSNAME)
107
107
  window.clearInterval(this._id)
108
108
  this._id = null
109
109
  }
@@ -1,4 +1,3 @@
1
- import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
2
1
  import { MutatingForm } from './form/builder.js'
3
2
  import { translate } from './i18n.js'
4
3
  import ContextMenu from './ui/contextmenu.js'
@@ -9,7 +9,7 @@ import TemplateImporter from '../templates.js'
9
9
  const TOP_BAR_TEMPLATE = `
10
10
  <div class="umap-main-edit-toolbox with-transition dark">
11
11
  <div class="umap-left-edit-toolbox" data-ref="left">
12
- <div class="logo"><a class="" href="/" title="${translate('Go to the homepage')}">uMap</a></div>
12
+ <div class="logo"><a class="" href="#" title="${translate('Go to the homepage')}" data-ref="home">uMap</a></div>
13
13
  <button class="map-name flat truncate" type="button" data-ref="name"></button>
14
14
  <button class="flat truncate" type="button" data-ref="share">
15
15
  <i class="icon icon-16 icon-draft show-on-draft"></i><span class="share-status"></span>
@@ -59,6 +59,7 @@ export class TopBar extends WithTemplate {
59
59
 
60
60
  setup() {
61
61
  this.parent.appendChild(this.element)
62
+ this.elements.home.href = this._umap.urls.get('home')
62
63
  this.elements.name.addEventListener('mouseover', () => {
63
64
  this._umap.tooltip.open({
64
65
  content: translate('Edit the title of the map'),
@@ -236,12 +237,18 @@ export class BottomBar extends WithTemplate {
236
237
  this.elements.layers.addEventListener('change', () => {
237
238
  const select = this.elements.layers
238
239
  const selected = select.options[select.selectedIndex].value
239
- if (!selected) return
240
- this._umap.datalayers.active().map((datalayer) => {
240
+ for (const datalayer of this._umap.datalayers.active()) {
241
241
  if (datalayer.properties.inCaption !== false) {
242
- datalayer.toggle(datalayer.id === selected)
242
+ if (!selected) {
243
+ datalayer.autoVisibility = true
244
+ if (datalayer.showAtZoom() && !datalayer.isVisible()) {
245
+ datalayer.show()
246
+ }
247
+ } else {
248
+ datalayer.toggle(datalayer.id === selected)
249
+ }
243
250
  }
244
- })
251
+ }
245
252
  })
246
253
  }
247
254
 
@@ -263,7 +270,9 @@ export class BottomBar extends WithTemplate {
263
270
  if (datalayers.length < 2) {
264
271
  this.elements.layers.hidden = true
265
272
  } else {
266
- this.elements.layers.appendChild(Utils.loadTemplate(`<option value=""></option>`))
273
+ this.elements.layers.appendChild(
274
+ Utils.loadTemplate(`<option value="">${translate('All layers')}</option>`)
275
+ )
267
276
  this.elements.layers.hidden = !this._umap.getProperty('layerSwitcher')
268
277
  const visible = datalayers.filter((datalayer) => datalayer.isVisible())
269
278
  for (const datalayer of datalayers) {
@@ -279,27 +288,30 @@ export class BottomBar extends WithTemplate {
279
288
  }
280
289
 
281
290
  const EDIT_BAR_TEMPLATE = `
282
- <ul class="umap-edit-bar dark with-transition">
283
- <li data-ref="marker"><button type="button" data-getstarted><i class="icon icon-24 icon-marker"></i></button></li>
284
- <li data-ref="polyline"><button type="button" data-getstarted><i class="icon icon-24 icon-polyline"></i></button></li>
285
- <li data-ref="multiline" hidden>
286
- <button type="button" title="${translate('Add a line to the current multi')}"><i class="icon icon-24 icon-multiline"></i></button>
287
- </li>
288
- <li data-ref="polygon"><button type="button" data-getstarted><i class="icon icon-24 icon-polygon"></i></button></li>
289
- <li data-ref="multipolygon" hidden>
290
- <button type="button" title="${translate('Add a polygon to the current multi')}"><i class="icon icon-24 icon-multipolygon"></i></button>
291
- </li>
292
- <li data-ref="route" hidden><button type="button" data-getstarted title="${translate('Draw along routes')}"><i class="icon icon-24 icon-route"></i></button></li>
293
- <hr>
294
- <li data-ref="caption" hidden><button data-getstarted type="button" title="${translate('Edit map name and caption')}"><i class="icon icon-24 icon-info"></i></button></li>
295
- <li data-ref="import" hidden><button type="button"><i class="icon icon-24 icon-upload"></i></button></li>
296
- <li data-ref="templates" hidden><button type="button" title="${translate('Load template')}" data-getstarted><i class="icon icon-24 icon-template"></i></button></li>
297
- <li data-ref="layers" hidden><button type="button" title="${translate('Manage layers')}"><i class="icon icon-24 icon-layers"></i></button></li>
298
- <li data-ref="tilelayers" hidden><button type="button" title="${translate('Change tilelayers')}"><i class="icon icon-24 icon-tilelayer"></i></button></li>
299
- <li data-ref="center" hidden><button type="button"><i class="icon icon-24 icon-center"></i></button></li>
300
- <li data-ref="permissions" hidden><button type="button" title="${translate('Update permissions and editors')}"><i class="icon icon-24 icon-key"></i></button></li>
301
- <li data-ref="settings" hidden><button data-getstarted type="button" title="${translate('Map advanced properties')}"><i class="icon icon-24 icon-settings"></i></button></li>
302
- </ul>
291
+ <div class="umap-edit-bar dark with-transition">
292
+ <ul>
293
+ <li data-ref="marker"><button class="drawing-tool" type="button" data-getstarted><i class="icon icon-24 icon-marker"></i></button></li>
294
+ <li data-ref="polyline"><button class="drawing-tool" type="button" data-getstarted><i class="icon icon-24 icon-polyline"></i></button></li>
295
+ <li data-ref="multiline" hidden>
296
+ <button class="drawing-tool" type="button" title="${translate('Add a line to the current multi')}"><i class="icon icon-24 icon-multiline"></i></button>
297
+ </li>
298
+ <li data-ref="polygon"><button class="drawing-tool" type="button" data-getstarted><i class="icon icon-24 icon-polygon"></i></button></li>
299
+ <li data-ref="multipolygon" hidden>
300
+ <button class="drawing-tool" type="button" title="${translate('Add a polygon to the current multi')}"><i class="icon icon-24 icon-multipolygon"></i></button>
301
+ </li>
302
+ <li data-ref="route" hidden><button class="drawing-tool" type="button" data-getstarted title="${translate('Draw along routes')}"><i class="icon icon-24 icon-route"></i></button></li>
303
+ </ul>
304
+ <ul>
305
+ <li data-ref="caption" hidden><button data-getstarted type="button" title="${translate('Edit map name and caption')}"><i class="icon icon-24 icon-info"></i></button></li>
306
+ <li data-ref="import" hidden><button type="button"><i class="icon icon-24 icon-upload"></i></button></li>
307
+ <li data-ref="templates" hidden><button type="button" title="${translate('Load template')}" data-getstarted><i class="icon icon-24 icon-template"></i></button></li>
308
+ <li data-ref="layers" hidden><button type="button" title="${translate('Manage layers')}"><i class="icon icon-24 icon-layers"></i></button></li>
309
+ <li data-ref="tilelayers" hidden><button type="button" title="${translate('Change tilelayers')}"><i class="icon icon-24 icon-tilelayer"></i></button></li>
310
+ <li data-ref="center" hidden><button type="button"><i class="icon icon-24 icon-center"></i></button></li>
311
+ <li data-ref="permissions" hidden><button type="button" title="${translate('Update permissions and editors')}"><i class="icon icon-24 icon-key"></i></button></li>
312
+ <li data-ref="settings" hidden><button data-getstarted type="button" title="${translate('Map advanced properties')}"><i class="icon icon-24 icon-settings"></i></button></li>
313
+ </ul>
314
+ </div>
303
315
  `
304
316
 
305
317
  export class EditBar extends WithTemplate {
@@ -315,12 +327,12 @@ export class EditBar extends WithTemplate {
315
327
  setup() {
316
328
  this.parent.appendChild(this.element)
317
329
  DomEvent.disableClickPropagation(this.element)
318
- this._onClick('marker', () => this._leafletMap.editTools.startMarker())
319
- this._onClick('polyline', () => this._leafletMap.editTools.startPolyline())
320
- this._onClick('multiline', () => this._umap.editedFeature.ui.editor.newShape())
321
- this._onClick('polygon', () => this._leafletMap.editTools.startPolygon())
322
- this._onClick('multipolygon', () => this._umap.editedFeature.ui.editor.newShape())
323
- this._onClick('route', () => this._leafletMap.editTools.startRoute())
330
+ this._onDrawing('marker', () => this._leafletMap.editTools.startMarker())
331
+ this._onDrawing('polyline', () => this._leafletMap.editTools.startPolyline())
332
+ this._onDrawing('multiline', () => this._umap.editedFeature.ui.editor.newShape())
333
+ this._onDrawing('polygon', () => this._leafletMap.editTools.startPolygon())
334
+ this._onDrawing('multipolygon', () => this._umap.editedFeature.ui.editor.newShape())
335
+ this._onDrawing('route', () => this._leafletMap.editTools.startRoute())
324
336
  this._onClick('caption', () => this._umap.editCaption())
325
337
  this._onClick('import', () => this._umap.importer.open())
326
338
  this._onClick('templates', () => this.templateIimporter.open())
@@ -359,6 +371,14 @@ export class EditBar extends WithTemplate {
359
371
  )
360
372
  }
361
373
 
374
+ _onDrawing(ref, realAction) {
375
+ const action = (event) => {
376
+ event.target.closest('button').classList.add('on')
377
+ realAction(event)
378
+ }
379
+ this._onClick(ref, action)
380
+ }
381
+
362
382
  _onClick(ref, action) {
363
383
  // Put the click on the button, not on the li, but keep the data-ref on the li
364
384
  // so to hide/show it when needed.
@@ -0,0 +1,36 @@
1
+ export default class Hash {
2
+ constructor() {
3
+ document.body.addEventListener('mapview:updated', (event) => {
4
+ this._updating = true
5
+ this.update(event.detail)
6
+ })
7
+ window.addEventListener('hashchange', () => this.parse())
8
+ }
9
+
10
+ update({ zoom, latlng }) {
11
+ const [lat, lng] = latlng
12
+ window.location.hash = `#${zoom}/${lat}/${lng}`
13
+ }
14
+
15
+ parse() {
16
+ // Do not parse and re-update the map when we change the hash ourselves
17
+ // after a move from the user.
18
+ if (this._updating) {
19
+ this._updating = false
20
+ return
21
+ }
22
+ let hash = window.location.hash
23
+ if (hash.indexOf('#') === 0) {
24
+ hash = hash.substr(1)
25
+ }
26
+ const args = hash.split('/')
27
+ if (args.length !== 3) return
28
+ const zoom = parseInt(args[0], 10)
29
+ const lat = parseFloat(args[1])
30
+ const lng = parseFloat(args[2])
31
+ if (isNaN(zoom) || isNaN(lat) || isNaN(lng)) return
32
+ document.body.dispatchEvent(
33
+ new CustomEvent('mapview:update', { detail: { zoom, latlng: [lat, lng] } })
34
+ )
35
+ }
36
+ }
@@ -0,0 +1,26 @@
1
+ import { loadTemplate } from '../domutils.js'
2
+
3
+ export default class Loader {
4
+ constructor(parent) {
5
+ this.parent = parent
6
+ this.element = loadTemplate('<div class="umap-loader"></div>')
7
+ this.parent.appendChild(this.element)
8
+ document.body.addEventListener('dataloading', (event) =>
9
+ this.start(event.detail.id)
10
+ )
11
+ document.body.addEventListener('dataload', (event) => this.stop(event.detail.id))
12
+ this._counter = new Set()
13
+ }
14
+
15
+ start(id) {
16
+ this._counter.add(id)
17
+ this.parent.classList.add('umap-loading')
18
+ }
19
+
20
+ stop(id) {
21
+ this._counter.delete(id)
22
+ if (!this._counter.size) {
23
+ this.parent.classList.remove('umap-loading')
24
+ }
25
+ }
26
+ }
@@ -1,12 +1,14 @@
1
- import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
1
+ import { DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
2
2
  import { translate } from '../i18n.js'
3
+ import * as DOMUtils from '../domutils.js'
3
4
 
4
5
  export class Panel {
5
6
  constructor(umap, leafletMap) {
6
7
  this.parent = leafletMap._controlContainer
7
8
  this._umap = umap
8
9
  this._leafletMap = leafletMap
9
- this.container = DomUtil.create('div', '', this.parent)
10
+ this.container = document.createElement('div')
11
+ this.parent.appendChild(this.container)
10
12
  // This will be set once according to the panel configured at load
11
13
  // or by using panels as popups
12
14
  this.mode = null
@@ -37,30 +39,33 @@ export class Panel {
37
39
  }
38
40
  document.body.classList.add(`panel-${this.className.split(' ')[0]}-on`)
39
41
  this.container.innerHTML = ''
40
- const actionsContainer = DomUtil.create('ul', 'buttons', this.container)
41
- const body = DomUtil.create('div', 'body', this.container)
42
+ const template = `
43
+ <div>
44
+ <ul class="buttons" data-ref="buttons">
45
+ <li><button class="icon icon-16 icon-close" data-ref="close" title="${translate('Close')}"></button></li>
46
+ <li><button class="icon icon-16 icon-resize" data-ref="resize" title="${translate('Toggle size')}"></button></li>
47
+ </ul>
48
+ <div class="body" data-ref="body">
49
+ </div>
50
+ </div>
51
+ `
52
+ const [root, { close, resize, body, buttons }] =
53
+ DOMUtils.loadTemplateWithRefs(template)
42
54
  body.appendChild(content)
43
- const closeButton = DomUtil.createButtonIcon(
44
- DomUtil.create('li', '', actionsContainer),
45
- 'icon-close',
46
- translate('Close')
47
- )
48
- const resizeButton = DomUtil.createButtonIcon(
49
- DomUtil.create('li', '', actionsContainer),
50
- 'icon-resize',
51
- translate('Toggle size')
52
- )
55
+ this.container.appendChild(root)
53
56
  for (const action of actions) {
54
- const element = DomUtil.element({ tagName: 'li', parent: actionsContainer })
55
- element.appendChild(action)
57
+ const li = document.createElement('li')
58
+ li.appendChild(action)
59
+ buttons.appendChild(li)
56
60
  }
57
- if (className) DomUtil.addClass(body, className)
61
+ if (className) body.classList.add(className)
58
62
  const promise = new Promise((resolve, reject) => {
59
63
  if (isOpen) {
60
64
  resolve(this)
61
65
  } else {
66
+ this.container.classList.add('on')
62
67
  Promise.all(
63
- this.container.getAnimations().map((animation) => animation.finished)
68
+ this.container.getAnimations?.().map((animation) => animation.finished)
64
69
  )
65
70
  .then(() => {
66
71
  resolve(this)
@@ -70,11 +75,10 @@ export class Panel {
70
75
  // were cancelled, we want the new panel callback to be called anyway.
71
76
  resolve(this)
72
77
  })
73
- this.container.classList.add('on')
74
78
  }
75
79
  })
76
- DomEvent.on(closeButton, 'click', this.close, this)
77
- DomEvent.on(resizeButton, 'click', this.resize, this)
80
+ close.addEventListener('click', () => this.close())
81
+ resize.addEventListener('click', () => this.resize())
78
82
  return promise
79
83
  }
80
84
 
@@ -94,6 +98,13 @@ export class Panel {
94
98
  document.body.classList.remove(`panel-${this.className.split(' ')[0]}-on`)
95
99
  this.container.dataset.highlight = null
96
100
  this.onClose()
101
+ Promise.all(
102
+ this.container.getAnimations?.().map((animation) => animation.finished)
103
+ ).then(() => {
104
+ if (!this.isOpen()) {
105
+ this.container.innerHTML = ''
106
+ }
107
+ })
97
108
  }
98
109
 
99
110
  onClose() {
@@ -102,6 +113,7 @@ export class Panel {
102
113
  this._leafletMap.invalidateSize({ pan: false })
103
114
  }
104
115
  }
116
+
105
117
  scrollTo(selector) {
106
118
  const fieldset = this.container.querySelector(selector)
107
119
  if (!fieldset) return
@@ -27,7 +27,7 @@ export default class Tooltip extends Positioned {
27
27
  this.parent.appendChild(this.container)
28
28
  this.openAt(opts)
29
29
  }
30
- this.TOOLTIP_ID = window.setTimeout(L.bind(showIt, this), opts.delay || 0)
30
+ this.TOOLTIP_ID = window.setTimeout(() => showIt(), opts.delay || 0)
31
31
  const id = this.TOOLTIP_ID
32
32
  const closeIt = () => {
33
33
  this.close(id)