umap-project 2.2.2__py3-none-any.whl → 2.3.1__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 (156) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/pl/LC_MESSAGES/django.po +83 -78
  4. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/pt/LC_MESSAGES/django.po +129 -123
  6. umap/static/umap/base.css +85 -44
  7. umap/static/umap/css/icon.css +6 -0
  8. umap/static/umap/css/panel.css +9 -4
  9. umap/static/umap/img/16.svg +2 -2
  10. umap/static/umap/img/source/16.svg +3 -3
  11. umap/static/umap/js/modules/browser.js +58 -24
  12. umap/static/umap/js/modules/caption.js +118 -0
  13. umap/static/umap/js/modules/facets.js +14 -39
  14. umap/static/umap/js/modules/global.js +2 -0
  15. umap/static/umap/js/modules/orderable.js +1 -1
  16. umap/static/umap/js/modules/panel.js +13 -7
  17. umap/static/umap/js/modules/schema.js +4 -4
  18. umap/static/umap/js/modules/urls.js +1 -1
  19. umap/static/umap/js/modules/utils.js +9 -1
  20. umap/static/umap/js/umap.controls.js +40 -110
  21. umap/static/umap/js/umap.core.js +19 -20
  22. umap/static/umap/js/umap.features.js +8 -2
  23. umap/static/umap/js/umap.forms.js +95 -34
  24. umap/static/umap/js/umap.js +47 -54
  25. umap/static/umap/js/umap.layer.js +5 -8
  26. umap/static/umap/js/umap.popup.js +1 -0
  27. umap/static/umap/locale/am_ET.js +11 -12
  28. umap/static/umap/locale/am_ET.json +11 -12
  29. umap/static/umap/locale/ar.js +11 -12
  30. umap/static/umap/locale/ar.json +11 -12
  31. umap/static/umap/locale/ast.js +11 -12
  32. umap/static/umap/locale/ast.json +11 -12
  33. umap/static/umap/locale/bg.js +11 -12
  34. umap/static/umap/locale/bg.json +11 -12
  35. umap/static/umap/locale/br.js +11 -12
  36. umap/static/umap/locale/br.json +11 -12
  37. umap/static/umap/locale/ca.js +11 -12
  38. umap/static/umap/locale/ca.json +11 -12
  39. umap/static/umap/locale/cs_CZ.js +11 -12
  40. umap/static/umap/locale/cs_CZ.json +11 -12
  41. umap/static/umap/locale/da.js +11 -12
  42. umap/static/umap/locale/da.json +11 -12
  43. umap/static/umap/locale/de.js +11 -12
  44. umap/static/umap/locale/de.json +11 -12
  45. umap/static/umap/locale/el.js +11 -12
  46. umap/static/umap/locale/el.json +11 -12
  47. umap/static/umap/locale/en.js +11 -12
  48. umap/static/umap/locale/en.json +11 -12
  49. umap/static/umap/locale/en_US.json +11 -12
  50. umap/static/umap/locale/es.js +11 -12
  51. umap/static/umap/locale/es.json +11 -12
  52. umap/static/umap/locale/et.js +11 -12
  53. umap/static/umap/locale/et.json +11 -12
  54. umap/static/umap/locale/eu.js +27 -16
  55. umap/static/umap/locale/eu.json +27 -16
  56. umap/static/umap/locale/fa_IR.js +11 -12
  57. umap/static/umap/locale/fa_IR.json +11 -12
  58. umap/static/umap/locale/fi.js +11 -12
  59. umap/static/umap/locale/fi.json +11 -12
  60. umap/static/umap/locale/fr.js +11 -12
  61. umap/static/umap/locale/fr.json +11 -12
  62. umap/static/umap/locale/gl.js +11 -12
  63. umap/static/umap/locale/gl.json +11 -12
  64. umap/static/umap/locale/he.js +11 -12
  65. umap/static/umap/locale/he.json +11 -12
  66. umap/static/umap/locale/hr.js +11 -12
  67. umap/static/umap/locale/hr.json +11 -12
  68. umap/static/umap/locale/hu.js +29 -30
  69. umap/static/umap/locale/hu.json +29 -30
  70. umap/static/umap/locale/id.js +11 -12
  71. umap/static/umap/locale/id.json +11 -12
  72. umap/static/umap/locale/is.js +11 -12
  73. umap/static/umap/locale/is.json +11 -12
  74. umap/static/umap/locale/it.js +11 -12
  75. umap/static/umap/locale/it.json +11 -12
  76. umap/static/umap/locale/ja.js +11 -12
  77. umap/static/umap/locale/ja.json +11 -12
  78. umap/static/umap/locale/ko.js +11 -12
  79. umap/static/umap/locale/ko.json +11 -12
  80. umap/static/umap/locale/lt.js +11 -12
  81. umap/static/umap/locale/lt.json +11 -12
  82. umap/static/umap/locale/ms.js +20 -21
  83. umap/static/umap/locale/ms.json +20 -21
  84. umap/static/umap/locale/nl.js +11 -12
  85. umap/static/umap/locale/nl.json +11 -12
  86. umap/static/umap/locale/no.js +11 -12
  87. umap/static/umap/locale/no.json +11 -12
  88. umap/static/umap/locale/pl.js +11 -12
  89. umap/static/umap/locale/pl.json +11 -12
  90. umap/static/umap/locale/pl_PL.json +11 -12
  91. umap/static/umap/locale/pt.js +11 -12
  92. umap/static/umap/locale/pt.json +11 -12
  93. umap/static/umap/locale/pt_BR.js +11 -12
  94. umap/static/umap/locale/pt_BR.json +11 -12
  95. umap/static/umap/locale/pt_PT.js +11 -12
  96. umap/static/umap/locale/pt_PT.json +11 -12
  97. umap/static/umap/locale/ro.js +11 -12
  98. umap/static/umap/locale/ro.json +11 -12
  99. umap/static/umap/locale/ru.js +11 -12
  100. umap/static/umap/locale/ru.json +11 -12
  101. umap/static/umap/locale/si.js +240 -227
  102. umap/static/umap/locale/si.json +240 -227
  103. umap/static/umap/locale/sk_SK.js +11 -12
  104. umap/static/umap/locale/sk_SK.json +11 -12
  105. umap/static/umap/locale/sl.js +11 -12
  106. umap/static/umap/locale/sl.json +11 -12
  107. umap/static/umap/locale/sr.js +11 -12
  108. umap/static/umap/locale/sr.json +11 -12
  109. umap/static/umap/locale/sv.js +11 -12
  110. umap/static/umap/locale/sv.json +11 -12
  111. umap/static/umap/locale/th_TH.js +11 -12
  112. umap/static/umap/locale/th_TH.json +11 -12
  113. umap/static/umap/locale/tr.js +11 -12
  114. umap/static/umap/locale/tr.json +11 -12
  115. umap/static/umap/locale/uk_UA.js +11 -12
  116. umap/static/umap/locale/uk_UA.json +11 -12
  117. umap/static/umap/locale/vi.js +11 -12
  118. umap/static/umap/locale/vi.json +11 -12
  119. umap/static/umap/locale/vi_VN.json +11 -12
  120. umap/static/umap/locale/zh.js +11 -12
  121. umap/static/umap/locale/zh.json +11 -12
  122. umap/static/umap/locale/zh_CN.json +11 -12
  123. umap/static/umap/locale/zh_TW.Big5.json +11 -12
  124. umap/static/umap/locale/zh_TW.js +11 -12
  125. umap/static/umap/locale/zh_TW.json +11 -12
  126. umap/static/umap/map.css +17 -2
  127. umap/static/umap/unittests/utils.js +7 -0
  128. umap/static/umap/vars.css +10 -0
  129. umap/static/umap/vendors/dompurify/purify.es.js +96 -12
  130. umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
  131. umap/tests/base.py +1 -0
  132. umap/tests/integration/conftest.py +5 -4
  133. umap/tests/integration/test_browser.py +11 -2
  134. umap/tests/integration/test_caption.py +27 -0
  135. umap/tests/integration/test_choropleth.py +1 -1
  136. umap/tests/integration/test_draw_polygon.py +6 -0
  137. umap/tests/integration/test_draw_polyline.py +6 -0
  138. umap/tests/integration/test_edit_datalayer.py +34 -5
  139. umap/tests/integration/test_edit_map.py +4 -4
  140. umap/tests/integration/test_edit_marker.py +6 -6
  141. umap/tests/integration/test_edit_polygon.py +6 -6
  142. umap/tests/integration/test_facets_browser.py +85 -13
  143. umap/tests/integration/test_map.py +0 -15
  144. umap/tests/integration/test_view_marker.py +17 -0
  145. {umap_project-2.2.2.dist-info → umap_project-2.3.1.dist-info}/METADATA +9 -8
  146. {umap_project-2.2.2.dist-info → umap_project-2.3.1.dist-info}/RECORD +149 -154
  147. {umap_project-2.2.2.dist-info → umap_project-2.3.1.dist-info}/WHEEL +1 -1
  148. umap/.DS_Store +0 -0
  149. umap/static/.DS_Store +0 -0
  150. umap/static/umap/.DS_Store +0 -0
  151. umap/static/umap/favicons/.DS_Store +0 -0
  152. umap/static/umap/fonts/.DS_Store +0 -0
  153. umap/tests/.DS_Store +0 -0
  154. umap/tests/integration/.DS_Store +0 -0
  155. {umap_project-2.2.2.dist-info → umap_project-2.3.1.dist-info}/entry_points.txt +0 -0
  156. {umap_project-2.2.2.dist-info → umap_project-2.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -10,15 +10,18 @@ export default class Facets {
10
10
 
11
11
  compute(names, defined) {
12
12
  const properties = {}
13
+ let selected
13
14
 
14
15
  names.forEach((name) => {
15
16
  const type = defined[name]['type']
16
17
  properties[name] = { type: type }
17
- this.selected[name] = { type: type }
18
+ selected = this.selected[name] || {}
19
+ selected.type = type
18
20
  if (!['date', 'datetime', 'number'].includes(type)) {
19
21
  properties[name].choices = []
20
- this.selected[name].choices = []
22
+ selected.choices = selected.choices || []
21
23
  }
24
+ this.selected[name] = selected
22
25
  })
23
26
 
24
27
  this.map.eachBrowsableDataLayer((datalayer) => {
@@ -53,42 +56,20 @@ export default class Facets {
53
56
  return properties
54
57
  }
55
58
 
56
- redraw() {
57
- if (this.isOpen()) this.open()
58
- }
59
-
60
- isOpen() {
61
- return !!document.querySelector('.umap-facet-search')
59
+ isActive() {
60
+ for (let { type, min, max, choices } of Object.values(this.selected)) {
61
+ if (min !== undefined || max != undefined || choices?.length) {
62
+ return true
63
+ }
64
+ }
65
+ return false
62
66
  }
63
67
 
64
- open() {
65
- const container = L.DomUtil.create('div', 'umap-facet-search')
66
- const title = L.DomUtil.add(
67
- 'h3',
68
- 'umap-filter-title',
69
- container,
70
- translate('Facet search')
71
- )
72
- this.map.browser.tabsMenu(container, 'facets')
68
+ build() {
73
69
  const defined = this.getDefined()
74
70
  const names = Object.keys(defined)
75
71
  const facetProperties = this.compute(names, defined)
76
72
 
77
- const filterFeatures = function () {
78
- let found = false
79
- this.map.eachBrowsableDataLayer((datalayer) => {
80
- datalayer.resetLayer(true)
81
- if (datalayer.hasDataVisible()) found = true
82
- })
83
- // TODO: display a results counter in the panel instead.
84
- if (!found) {
85
- this.map.ui.alert({
86
- content: translate('No results for these facets'),
87
- level: 'info',
88
- })
89
- }
90
- }
91
-
92
73
  const fields = names.map((name) => {
93
74
  let criteria = facetProperties[name]
94
75
  let handler = 'FacetSearchChoices'
@@ -114,13 +95,7 @@ export default class Facets {
114
95
  ]
115
96
  })
116
97
 
117
- const builder = new L.FormBuilder(this, fields, {
118
- callback: filterFeatures,
119
- callbackContext: this,
120
- })
121
- container.appendChild(builder.build())
122
-
123
- this.map.panel.open({ content: container })
98
+ return fields
124
99
  }
125
100
 
126
101
  getDefined() {
@@ -1,6 +1,7 @@
1
1
  import URLs from './urls.js'
2
2
  import Browser from './browser.js'
3
3
  import Facets from './facets.js'
4
+ import Caption from './caption.js'
4
5
  import { Panel, EditPanel, FullPanel } from './panel.js'
5
6
  import * as Utils from './utils.js'
6
7
  import { SCHEMA } from './schema.js'
@@ -25,4 +26,5 @@ window.U = {
25
26
  Utils,
26
27
  SCHEMA,
27
28
  Orderable,
29
+ Caption,
28
30
  }
@@ -33,7 +33,7 @@ export default class Orderable {
33
33
 
34
34
  onDragStart(e) {
35
35
  // e.target is the source node.
36
- const realSrc = document.elementFromPoint(e.clientX, e.clientY);
36
+ const realSrc = document.elementFromPoint(e.clientX, e.clientY)
37
37
  // Only allow drag from the handle
38
38
  if (!realSrc.classList.contains('icon-drag')) {
39
39
  e.preventDefault()
@@ -6,7 +6,9 @@ export class Panel {
6
6
  this.parent = map._controlContainer
7
7
  this.map = map
8
8
  this.container = DomUtil.create('div', '', this.parent)
9
- this.mode = 'condensed'
9
+ // This will be set once according to the panel configurated at load
10
+ // or by using panels as popups
11
+ this.mode = null
10
12
  this.classname = 'left'
11
13
  DomEvent.disableClickPropagation(this.container)
12
14
  DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu.
@@ -14,8 +16,12 @@ export class Panel {
14
16
  DomEvent.on(this.container, 'MozMousePixelScroll', DomEvent.stopPropagation)
15
17
  }
16
18
 
19
+ setDefaultMode(mode) {
20
+ if (!this.mode) this.mode = mode
21
+ }
22
+
17
23
  open({ content, className, actions = [] } = {}) {
18
- this.container.className = `with-transition panel ${this.classname} ${this.mode}`
24
+ this.container.className = `with-transition panel ${this.classname} ${this.mode || ''}`
19
25
  this.container.innerHTML = ''
20
26
  const actionsContainer = DomUtil.create('ul', 'toolbox', this.container)
21
27
  const body = DomUtil.create('div', 'body', this.container)
@@ -40,14 +46,14 @@ export class Panel {
40
46
  }
41
47
 
42
48
  resize() {
43
- if (this.mode === 'expanded') {
44
- this.mode = 'condensed'
45
- this.container.classList.remove('expanded')
46
- this.container.classList.add('condensed')
47
- } else {
49
+ if (this.mode === 'condensed') {
48
50
  this.mode = 'expanded'
49
51
  this.container.classList.remove('condensed')
50
52
  this.container.classList.add('expanded')
53
+ } else {
54
+ this.mode = 'condensed'
55
+ this.container.classList.remove('expanded')
56
+ this.container.classList.add('condensed')
51
57
  }
52
58
  }
53
59
 
@@ -83,7 +83,7 @@ export const SCHEMA = {
83
83
  easing: {
84
84
  type: Boolean,
85
85
  impacts: [],
86
- default: false
86
+ default: false,
87
87
  },
88
88
  editinosmControl: {
89
89
  type: Boolean,
@@ -272,9 +272,9 @@ export const SCHEMA = {
272
272
  choices: [
273
273
  ['none', translate('None')],
274
274
  ['caption', translate('Caption')],
275
- ['databrowser', translate('Data browser')],
276
- ['datalayers', translate('Layers')],
277
- ['facet', translate('Facet search')],
275
+ ['databrowser', translate('Browser in data mode')],
276
+ ['datalayers', translate('Browser in layers mode')],
277
+ ['datafilters', translate('Browser in filters mode')],
278
278
  ],
279
279
  default: 'none',
280
280
  },
@@ -1,4 +1,4 @@
1
- import { template } from "./utils.js"
1
+ import { template } from './utils.js'
2
2
 
3
3
  export default class URLs {
4
4
  constructor(serverUrls) {
@@ -88,7 +88,7 @@ export function escapeHTML(s) {
88
88
  'span',
89
89
  ],
90
90
  ADD_ATTR: ['target', 'allow', 'allowfullscreen', 'frameborder', 'scrolling'],
91
- ALLOWED_ATTR: ['href', 'src', 'width', 'height', 'style'],
91
+ ALLOWED_ATTR: ['href', 'src', 'width', 'height', 'style', 'dir', 'title'],
92
92
  // Added: `geo:` URL scheme as defined in RFC5870:
93
93
  // https://www.rfc-editor.org/rfc/rfc5870.html
94
94
  // The base RegExp comes from:
@@ -362,3 +362,11 @@ export function parseNaiveDate(value) {
362
362
  // Let's pretend naive date are UTC, and remove time…
363
363
  return new Date(Date.UTC(naive.getFullYear(), naive.getMonth(), naive.getDate()))
364
364
  }
365
+
366
+ export function toggleBadge(element, value) {
367
+ if (!element.nodeType) element = document.querySelector(element)
368
+ if (!element) return
369
+ // True means simple badge, without content
370
+ if (value) element.dataset.badge = value === true ? ' ' : value
371
+ else delete element.dataset.badge
372
+ }
@@ -196,8 +196,11 @@ U.ToggleEditAction = U.BaseFeatureAction.extend({
196
196
  },
197
197
 
198
198
  onClick: function (e) {
199
- if (this.feature._toggleEditing) this.feature._toggleEditing(e) // Path
200
- else this.feature.edit(e) // Marker
199
+ if (this.feature._toggleEditing) {
200
+ this.feature._toggleEditing(e) // Path
201
+ } else {
202
+ this.feature.edit(e) // Marker
203
+ }
201
204
  },
202
205
  })
203
206
 
@@ -496,8 +499,11 @@ L.Control.Button = L.Control.extend({
496
499
  this
497
500
  )
498
501
  L.DomEvent.on(button, 'dblclick', L.DomEvent.stopPropagation)
502
+ this.afterAdd(container)
499
503
  return container
500
504
  },
505
+
506
+ afterAdd: function (container) {},
501
507
  })
502
508
 
503
509
  U.DataLayersControl = L.Control.Button.extend({
@@ -507,6 +513,10 @@ U.DataLayersControl = L.Control.Button.extend({
507
513
  title: L._('See layers'),
508
514
  },
509
515
 
516
+ afterAdd: function (container) {
517
+ U.Utils.toggleBadge(container, this.map.browser.hasFilters())
518
+ },
519
+
510
520
  onClick: function () {
511
521
  this.map.openBrowser()
512
522
  },
@@ -520,7 +530,7 @@ U.CaptionControl = L.Control.Button.extend({
520
530
  },
521
531
 
522
532
  onClick: function () {
523
- this.map.displayCaption()
533
+ this.map.openCaption()
524
534
  },
525
535
  })
526
536
 
@@ -597,15 +607,14 @@ U.DataLayer.include({
597
607
  if (!this.isVisible()) return
598
608
  if (!confirm(L._('Are you sure you want to delete this layer?'))) return
599
609
  this._delete()
600
- this.map.editPanel.close()
601
610
  },
602
611
  this
603
612
  )
604
613
  }
605
614
  L.DomEvent.on(toggle, 'click', this.toggle, this)
606
615
  L.DomEvent.on(zoomTo, 'click', this.zoomTo, this)
607
- L.DomUtil.addClass(container, this.getHidableClass())
608
- L.DomUtil.classIf(container, 'off', !this.isVisible())
616
+ container.classList.add(this.getHidableClass())
617
+ container.classList.toggle('off', !this.isVisible())
609
618
  },
610
619
 
611
620
  getHidableElements: function () {
@@ -616,10 +625,17 @@ U.DataLayer.include({
616
625
  return `show_with_datalayer_${L.stamp(this)}`
617
626
  },
618
627
 
628
+ propagateDelete: function () {
629
+ const els = this.getHidableElements()
630
+ for (const el of els) {
631
+ L.DomUtil.remove(el)
632
+ }
633
+ },
634
+
619
635
  propagateRemote: function () {
620
636
  const els = this.getHidableElements()
621
- for (let i = 0; i < els.length; i++) {
622
- L.DomUtil.classIf(els[i], 'remotelayer', this.isRemoteLayer())
637
+ for (const el of els) {
638
+ el.classList.toggle('remotelayer', this.isRemoteLayer())
623
639
  }
624
640
  },
625
641
 
@@ -643,6 +659,7 @@ U.DataLayer.include({
643
659
  U.DataLayer.addInitHook(function () {
644
660
  this.on('hide', this.propagateHide)
645
661
  this.on('show', this.propagateShow)
662
+ this.on('erase', this.propagateDelete)
646
663
  if (this.isVisible()) this.propagateShow()
647
664
  })
648
665
 
@@ -660,100 +677,6 @@ const ControlsMixin = {
660
677
  'star',
661
678
  'tilelayers',
662
679
  ],
663
- _openFacet: function () {
664
- this.facets.open()
665
- },
666
-
667
- displayCaption: function () {
668
- const container = L.DomUtil.create('div', 'umap-caption')
669
- L.DomUtil.createTitle(container, this.options.name, 'icon-caption')
670
- this.permissions.addOwnerLink('h5', container)
671
- this.browser.tabsMenu(container, 'info')
672
- if (this.options.description) {
673
- const description = L.DomUtil.element({
674
- tagName: 'div',
675
- className: 'umap-map-description',
676
- safeHTML: U.Utils.toHTML(this.options.description),
677
- parent: container,
678
- })
679
- }
680
- const datalayerContainer = L.DomUtil.create('div', 'datalayer-container', container)
681
- this.eachVisibleDataLayer((datalayer) => {
682
- if (!datalayer.options.inCaption) return
683
- const p = L.DomUtil.create('p', 'datalayer-legend', datalayerContainer),
684
- legend = L.DomUtil.create('span', '', p),
685
- headline = L.DomUtil.create('strong', '', p)
686
- datalayer.onceLoaded(function () {
687
- datalayer.renderLegend(legend)
688
- if (datalayer.options.description) {
689
- L.DomUtil.element({
690
- tagName: 'span',
691
- parent: p,
692
- safeHTML: U.Utils.toHTML(datalayer.options.description),
693
- })
694
- }
695
- })
696
- datalayer.renderToolbox(headline)
697
- L.DomUtil.add('span', '', headline, `${datalayer.options.name} `)
698
- })
699
- const creditsContainer = L.DomUtil.create('div', 'credits-container', container),
700
- credits = L.DomUtil.createFieldset(creditsContainer, L._('Credits'))
701
- title = L.DomUtil.add('h5', '', credits, L._('User content credits'))
702
- if (this.options.shortCredit || this.options.longCredit) {
703
- L.DomUtil.element({
704
- tagName: 'p',
705
- parent: credits,
706
- safeHTML: U.Utils.toHTML(this.options.longCredit || this.options.shortCredit),
707
- })
708
- }
709
- if (this.options.licence) {
710
- const licence = L.DomUtil.add(
711
- 'p',
712
- '',
713
- credits,
714
- `${L._('Map user content has been published under licence')} `
715
- )
716
- L.DomUtil.createLink(
717
- '',
718
- licence,
719
- this.options.licence.name,
720
- this.options.licence.url
721
- )
722
- } else {
723
- L.DomUtil.add('p', '', credits, L._('No licence has been set'))
724
- }
725
- title = L.DomUtil.create('h5', '', credits)
726
- title.textContent = L._('Map background credits')
727
- const tilelayerCredit = L.DomUtil.create('p', '', credits)
728
- L.DomUtil.element({
729
- tagName: 'strong',
730
- parent: tilelayerCredit,
731
- textContent: `${this.selected_tilelayer.options.name} `,
732
- })
733
- L.DomUtil.element({
734
- tagName: 'span',
735
- parent: tilelayerCredit,
736
- safeHTML: this.selected_tilelayer.getAttribution(),
737
- })
738
- const urls = {
739
- leaflet: 'http://leafletjs.com',
740
- django: 'https://www.djangoproject.com',
741
- umap: 'http://wiki.openstreetmap.org/wiki/UMap',
742
- changelog: 'https://umap-project.readthedocs.io/en/master/changelog/',
743
- version: this.options.umap_version,
744
- }
745
- const creditHTML = L._(
746
- `
747
- Powered by <a href="{leaflet}">Leaflet</a> and
748
- <a href="{django}">Django</a>,
749
- glued by <a href="{umap}">uMap project</a>
750
- (version <a href="{changelog}">{version}</a>).
751
- `,
752
- urls
753
- )
754
- L.DomUtil.element({ tagName: 'p', innerHTML: creditHTML, parent: credits })
755
- this.panel.open({ content: container })
756
- },
757
680
 
758
681
  renderEditToolbar: function () {
759
682
  const container = L.DomUtil.create(
@@ -904,7 +827,7 @@ const ControlsMixin = {
904
827
  L.DomUtil.createIcon(row, 'icon-drag', L._('Drag to reorder'))
905
828
  datalayer.renderToolbox(row)
906
829
  const title = L.DomUtil.add('span', '', row, datalayer.options.name)
907
- L.DomUtil.classIf(row, 'off', !datalayer.isVisible())
830
+ row.classList.toggle('off', !datalayer.isVisible())
908
831
  title.textContent = datalayer.options.name
909
832
  row.dataset.id = L.stamp(datalayer)
910
833
  })
@@ -1071,7 +994,7 @@ U.AttributionControl = L.Control.Attribution.extend({
1071
994
  if (captionMenus) {
1072
995
  const link = L.DomUtil.add('a', '', container, ` — ${L._('About')}`)
1073
996
  L.DomEvent.on(link, 'click', L.DomEvent.stop)
1074
- .on(link, 'click', this._map.displayCaption, this._map)
997
+ .on(link, 'click', this._map.openCaption, this._map)
1075
998
  .on(link, 'dblclick', L.DomEvent.stop)
1076
999
  }
1077
1000
  if (window.top === window.self && captionMenus) {
@@ -1115,8 +1038,17 @@ U.Locate = L.Control.Locate.extend({
1115
1038
  _activate: function () {
1116
1039
  this._map = this.map
1117
1040
  L.Control.Locate.prototype._activate.call(this)
1118
- this._map = null
1119
1041
  },
1042
+
1043
+ remove: function () {
1044
+ // Prevent to call remove if the control is not really added to the map
1045
+ // This occurs because we do create the control and call its activate
1046
+ // method before adding the control button itself to the map, in the
1047
+ // case where the map defaultView is set to "location"
1048
+ if (!this._container || !this._container.parentNode) return
1049
+ return L.Control.Locate.prototype.remove.call(this)
1050
+ },
1051
+
1120
1052
  })
1121
1053
 
1122
1054
  U.Search = L.PhotonSearch.extend({
@@ -1255,7 +1187,7 @@ U.SearchControl = L.Control.extend({
1255
1187
  this.map.fire('dataload', { id: id })
1256
1188
  })
1257
1189
  this.search.resultsContainer = resultsContainer
1258
- this.map.panel.open({ content: container }).then(input.focus)
1190
+ this.map.panel.open({ content: container }).then(input.focus())
1259
1191
  },
1260
1192
  })
1261
1193
 
@@ -1316,16 +1248,14 @@ U.ContextMenu = L.Map.ContextMenu.extend({
1316
1248
  U.Editable = L.Editable.extend({
1317
1249
  initialize: function (map, options) {
1318
1250
  L.Editable.prototype.initialize.call(this, map, options)
1319
- this.on(
1320
- 'editable:drawing:start editable:drawing:click editable:drawing:move',
1321
- this.drawingTooltip
1322
- )
1251
+ this.on('editable:drawing:click editable:drawing:move', this.drawingTooltip)
1323
1252
  this.on('editable:drawing:end', (e) => {
1324
1253
  this.closeTooltip()
1325
1254
  // Leaflet.Editable will delete the drawn shape if invalid
1326
1255
  // (eg. line has only one drawn point)
1327
1256
  // So let's check if the layer has no more shape
1328
1257
  if (!e.layer.hasGeom()) e.layer.del()
1258
+ else e.layer.edit()
1329
1259
  })
1330
1260
  // Layer for items added by users
1331
1261
  this.on('editable:drawing:cancel', (e) => {
@@ -81,24 +81,26 @@ L.DomUtil.add = (tagName, className, container, content) => {
81
81
 
82
82
  L.DomUtil.createFieldset = (container, legend, options) => {
83
83
  options = options || {}
84
- const fieldset = L.DomUtil.create('div', 'fieldset toggle', container)
85
- const legendEl = L.DomUtil.add('h5', 'legend style_options_toggle', fieldset, legend)
86
- const fieldsEl = L.DomUtil.add('div', 'fields with-transition', fieldset)
87
- L.DomEvent.on(legendEl, 'click', function () {
88
- if (L.DomUtil.hasClass(fieldset, 'on')) {
89
- L.DomUtil.removeClass(fieldset, 'on')
90
- } else {
91
- L.DomUtil.addClass(fieldset, 'on')
92
- if (options.callback) options.callback.call(options.context || this)
93
- }
94
- })
95
- return fieldsEl
84
+ const details = L.DomUtil.create('details', options.className || '', container)
85
+ const summary = L.DomUtil.add('summary', '', details)
86
+ if (options.icon) L.DomUtil.createIcon(summary, options.icon)
87
+ L.DomUtil.add('span', '', summary, legend)
88
+ const fieldset = L.DomUtil.add('fieldset', '', details)
89
+ details.open = options.on === true
90
+ if (options.callback) {
91
+ L.DomEvent.on(details, 'toggle', () => {
92
+ if (details.open) options.callback.call(options.context || this)
93
+ })
94
+ }
95
+ return fieldset
96
96
  }
97
97
 
98
98
  L.DomUtil.createButton = (className, container, content, callback, context) => {
99
99
  const el = L.DomUtil.add('button', className, container, content)
100
100
  el.type = 'button'
101
- el.title = content
101
+ if (!content.nodeType) {
102
+ el.title = content
103
+ }
102
104
  if (callback) {
103
105
  L.DomEvent.on(el, 'click', L.DomEvent.stop).on(el, 'click', callback, context)
104
106
  }
@@ -160,11 +162,6 @@ L.DomUtil.createCopiableInput = (parent, label, value) => {
160
162
  return input
161
163
  }
162
164
 
163
- L.DomUtil.classIf = (el, className, bool) => {
164
- if (bool) L.DomUtil.addClass(el, className)
165
- else L.DomUtil.removeClass(el, className)
166
- }
167
-
168
165
  L.DomUtil.element = ({ tagName, parent, ...attrs }) => {
169
166
  const el = document.createElement(tagName)
170
167
  if (attrs.innerHTML) {
@@ -554,9 +551,11 @@ U.Help = L.Class.extend({
554
551
  'Comma separated list of properties to use for sorting features. To reverse the sort, put a minus sign (-) before. Eg. mykey,-otherkey.'
555
552
  ),
556
553
  slugKey: L._('The name of the property to use as feature unique identifier.'),
557
- filterKey: L._('Comma separated list of properties to use when filtering features'),
554
+ filterKey: L._(
555
+ 'Comma separated list of properties to use when filtering features by text input'
556
+ ),
558
557
  facetKey: L._(
559
- 'Comma separated list of properties to use for facet search (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key). To control input field type, add it after another | (eg.: mykey|My Key|checkbox,otherkey|Other Key|datetime). Allowed values for the input field type are checkbox (default), radio, number, date and datetime.'
558
+ 'Comma separated list of properties to use for filters (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key). To control input field type, add it after another | (eg.: mykey|My Key|checkbox,otherkey|Other Key|datetime). Allowed values for the input field type are checkbox (default), radio, number, date and datetime.'
560
559
  ),
561
560
  interactive: L._(
562
561
  'If false, the polygon or line will act as a part of the underlying map.'
@@ -494,6 +494,14 @@ U.FeatureMixin = {
494
494
  this.bindTooltip(U.Utils.escapeHTML(displayName), options)
495
495
  },
496
496
 
497
+ isFiltered: function () {
498
+ const filterKeys = this.map.getFilterKeys()
499
+ const filter = this.map.browser.options.filter
500
+ if (filter && !this.matchFilter(filter, filterKeys)) return true
501
+ if (!this.matchFacets()) return true
502
+ return false
503
+ },
504
+
497
505
  matchFilter: function (filter, keys) {
498
506
  filter = filter.toLowerCase()
499
507
  for (let i = 0, value; i < keys.length; i++) {
@@ -513,8 +521,6 @@ U.FeatureMixin = {
513
521
  case 'date':
514
522
  case 'datetime':
515
523
  case 'number':
516
- min = parser(min)
517
- max = parser(max)
518
524
  if (!isNaN(min) && !isNaN(value) && min > value) return false
519
525
  if (!isNaN(max) && !isNaN(value) && max < value) return false
520
526
  break