umap-project 2.3.0__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 (30) 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 +4 -2
  7. umap/static/umap/js/modules/browser.js +8 -15
  8. umap/static/umap/js/modules/caption.js +118 -0
  9. umap/static/umap/js/modules/global.js +2 -0
  10. umap/static/umap/js/modules/panel.js +13 -7
  11. umap/static/umap/js/umap.controls.js +25 -99
  12. umap/static/umap/js/umap.core.js +3 -6
  13. umap/static/umap/js/umap.forms.js +8 -6
  14. umap/static/umap/js/umap.js +32 -34
  15. umap/static/umap/js/umap.layer.js +2 -2
  16. umap/static/umap/js/umap.popup.js +1 -0
  17. umap/static/umap/vendors/dompurify/purify.es.js +50 -15
  18. umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
  19. umap/tests/base.py +1 -0
  20. umap/tests/integration/test_browser.py +4 -2
  21. umap/tests/integration/test_caption.py +27 -0
  22. umap/tests/integration/test_edit_datalayer.py +29 -0
  23. umap/tests/integration/test_facets_browser.py +4 -1
  24. umap/tests/integration/test_map.py +0 -15
  25. umap/tests/integration/test_view_marker.py +17 -0
  26. {umap_project-2.3.0.dist-info → umap_project-2.3.1.dist-info}/METADATA +5 -5
  27. {umap_project-2.3.0.dist-info → umap_project-2.3.1.dist-info}/RECORD +30 -28
  28. {umap_project-2.3.0.dist-info → umap_project-2.3.1.dist-info}/WHEEL +0 -0
  29. {umap_project-2.3.0.dist-info → umap_project-2.3.1.dist-info}/entry_points.txt +0 -0
  30. {umap_project-2.3.0.dist-info → umap_project-2.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,118 @@
1
+ import { DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
2
+ import { translate } from './i18n.js'
3
+ import * as Utils from './utils.js'
4
+
5
+ export default class Caption {
6
+ constructor(map) {
7
+ this.map = map
8
+ }
9
+
10
+ isOpen() {
11
+ return Boolean(document.querySelector('.on .umap-caption'))
12
+ }
13
+
14
+ refresh() {
15
+ if (!this.isOpen()) return
16
+ this.open()
17
+ }
18
+
19
+ open() {
20
+ const container = DomUtil.create('div', 'umap-caption')
21
+ DomUtil.createTitle(container, this.map.options.name, 'icon-caption')
22
+ this.map.permissions.addOwnerLink('h5', container)
23
+ if (this.map.options.description) {
24
+ const description = DomUtil.element({
25
+ tagName: 'div',
26
+ className: 'umap-map-description',
27
+ safeHTML: Utils.toHTML(this.map.options.description),
28
+ parent: container,
29
+ })
30
+ }
31
+ const datalayerContainer = DomUtil.create('div', 'datalayer-container', container)
32
+ this.map.eachDataLayer((datalayer) =>
33
+ this.addDataLayer(datalayer, datalayerContainer)
34
+ )
35
+ const creditsContainer = DomUtil.create('div', 'credits-container', container)
36
+ this.addCredits(creditsContainer)
37
+ this.map.panel.open({ content: container })
38
+ }
39
+
40
+ addDataLayer(datalayer, container) {
41
+ if (!datalayer.options.inCaption) return
42
+ const p = DomUtil.create('p', 'datalayer-legend', container),
43
+ legend = DomUtil.create('span', '', p),
44
+ headline = DomUtil.create('strong', '', p)
45
+ datalayer.onceLoaded(() => {
46
+ datalayer.renderLegend(legend)
47
+ if (datalayer.options.description) {
48
+ DomUtil.element({
49
+ tagName: 'span',
50
+ parent: p,
51
+ safeHTML: Utils.toHTML(datalayer.options.description),
52
+ })
53
+ }
54
+ })
55
+ datalayer.renderToolbox(headline)
56
+ DomUtil.add('span', '', headline, `${datalayer.options.name} `)
57
+ }
58
+
59
+ addCredits(container) {
60
+ const credits = DomUtil.createFieldset(container, translate('Credits'))
61
+ let title = DomUtil.add('h5', '', credits, translate('User content credits'))
62
+ if (this.map.options.shortCredit || this.map.options.longCredit) {
63
+ DomUtil.element({
64
+ tagName: 'p',
65
+ parent: credits,
66
+ safeHTML: Utils.toHTML(
67
+ this.map.options.longCredit || this.map.options.shortCredit
68
+ ),
69
+ })
70
+ }
71
+ if (this.map.options.licence) {
72
+ const licence = DomUtil.add(
73
+ 'p',
74
+ '',
75
+ credits,
76
+ `${translate('Map user content has been published under licence')} `
77
+ )
78
+ DomUtil.createLink(
79
+ '',
80
+ licence,
81
+ this.map.options.licence.name,
82
+ this.map.options.licence.url
83
+ )
84
+ } else {
85
+ DomUtil.add('p', '', credits, translate('No licence has been set'))
86
+ }
87
+ title = DomUtil.create('h5', '', credits)
88
+ title.textContent = translate('Map background credits')
89
+ const tilelayerCredit = DomUtil.create('p', '', credits)
90
+ DomUtil.element({
91
+ tagName: 'strong',
92
+ parent: tilelayerCredit,
93
+ textContent: `${this.map.selected_tilelayer.options.name} `,
94
+ })
95
+ DomUtil.element({
96
+ tagName: 'span',
97
+ parent: tilelayerCredit,
98
+ safeHTML: this.map.selected_tilelayer.getAttribution(),
99
+ })
100
+ const urls = {
101
+ leaflet: 'http://leafletjs.com',
102
+ django: 'https://www.djangoproject.com',
103
+ umap: 'https://umap-project.org/',
104
+ changelog: 'https://docs.umap-project.org/en/master/changelog/',
105
+ version: this.map.options.umap_version,
106
+ }
107
+ const creditHTML = translate(
108
+ `
109
+ Powered by <a href="{leaflet}">Leaflet</a> and
110
+ <a href="{django}">Django</a>,
111
+ glued by <a href="{umap}">uMap project</a>
112
+ (version <a href="{changelog}">{version}</a>).
113
+ `,
114
+ urls
115
+ )
116
+ DomUtil.element({ tagName: 'p', innerHTML: creditHTML, parent: credits })
117
+ }
118
+ }
@@ -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
  }
@@ -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
 
@@ -530,7 +530,7 @@ U.CaptionControl = L.Control.Button.extend({
530
530
  },
531
531
 
532
532
  onClick: function () {
533
- this.map.displayCaption()
533
+ this.map.openCaption()
534
534
  },
535
535
  })
536
536
 
@@ -607,15 +607,14 @@ U.DataLayer.include({
607
607
  if (!this.isVisible()) return
608
608
  if (!confirm(L._('Are you sure you want to delete this layer?'))) return
609
609
  this._delete()
610
- this.map.editPanel.close()
611
610
  },
612
611
  this
613
612
  )
614
613
  }
615
614
  L.DomEvent.on(toggle, 'click', this.toggle, this)
616
615
  L.DomEvent.on(zoomTo, 'click', this.zoomTo, this)
617
- L.DomUtil.addClass(container, this.getHidableClass())
618
- L.DomUtil.classIf(container, 'off', !this.isVisible())
616
+ container.classList.add(this.getHidableClass())
617
+ container.classList.toggle('off', !this.isVisible())
619
618
  },
620
619
 
621
620
  getHidableElements: function () {
@@ -626,10 +625,17 @@ U.DataLayer.include({
626
625
  return `show_with_datalayer_${L.stamp(this)}`
627
626
  },
628
627
 
628
+ propagateDelete: function () {
629
+ const els = this.getHidableElements()
630
+ for (const el of els) {
631
+ L.DomUtil.remove(el)
632
+ }
633
+ },
634
+
629
635
  propagateRemote: function () {
630
636
  const els = this.getHidableElements()
631
- for (let i = 0; i < els.length; i++) {
632
- L.DomUtil.classIf(els[i], 'remotelayer', this.isRemoteLayer())
637
+ for (const el of els) {
638
+ el.classList.toggle('remotelayer', this.isRemoteLayer())
633
639
  }
634
640
  },
635
641
 
@@ -653,6 +659,7 @@ U.DataLayer.include({
653
659
  U.DataLayer.addInitHook(function () {
654
660
  this.on('hide', this.propagateHide)
655
661
  this.on('show', this.propagateShow)
662
+ this.on('erase', this.propagateDelete)
656
663
  if (this.isVisible()) this.propagateShow()
657
664
  })
658
665
 
@@ -671,96 +678,6 @@ const ControlsMixin = {
671
678
  'tilelayers',
672
679
  ],
673
680
 
674
- displayCaption: function () {
675
- const container = L.DomUtil.create('div', 'umap-caption')
676
- L.DomUtil.createTitle(container, this.options.name, 'icon-caption')
677
- this.permissions.addOwnerLink('h5', container)
678
- if (this.options.description) {
679
- const description = L.DomUtil.element({
680
- tagName: 'div',
681
- className: 'umap-map-description',
682
- safeHTML: U.Utils.toHTML(this.options.description),
683
- parent: container,
684
- })
685
- }
686
- const datalayerContainer = L.DomUtil.create('div', 'datalayer-container', container)
687
- this.eachVisibleDataLayer((datalayer) => {
688
- if (!datalayer.options.inCaption) return
689
- const p = L.DomUtil.create('p', 'datalayer-legend', datalayerContainer),
690
- legend = L.DomUtil.create('span', '', p),
691
- headline = L.DomUtil.create('strong', '', p)
692
- datalayer.onceLoaded(function () {
693
- datalayer.renderLegend(legend)
694
- if (datalayer.options.description) {
695
- L.DomUtil.element({
696
- tagName: 'span',
697
- parent: p,
698
- safeHTML: U.Utils.toHTML(datalayer.options.description),
699
- })
700
- }
701
- })
702
- datalayer.renderToolbox(headline)
703
- L.DomUtil.add('span', '', headline, `${datalayer.options.name} `)
704
- })
705
- const creditsContainer = L.DomUtil.create('div', 'credits-container', container),
706
- credits = L.DomUtil.createFieldset(creditsContainer, L._('Credits'))
707
- title = L.DomUtil.add('h5', '', credits, L._('User content credits'))
708
- if (this.options.shortCredit || this.options.longCredit) {
709
- L.DomUtil.element({
710
- tagName: 'p',
711
- parent: credits,
712
- safeHTML: U.Utils.toHTML(this.options.longCredit || this.options.shortCredit),
713
- })
714
- }
715
- if (this.options.licence) {
716
- const licence = L.DomUtil.add(
717
- 'p',
718
- '',
719
- credits,
720
- `${L._('Map user content has been published under licence')} `
721
- )
722
- L.DomUtil.createLink(
723
- '',
724
- licence,
725
- this.options.licence.name,
726
- this.options.licence.url
727
- )
728
- } else {
729
- L.DomUtil.add('p', '', credits, L._('No licence has been set'))
730
- }
731
- title = L.DomUtil.create('h5', '', credits)
732
- title.textContent = L._('Map background credits')
733
- const tilelayerCredit = L.DomUtil.create('p', '', credits)
734
- L.DomUtil.element({
735
- tagName: 'strong',
736
- parent: tilelayerCredit,
737
- textContent: `${this.selected_tilelayer.options.name} `,
738
- })
739
- L.DomUtil.element({
740
- tagName: 'span',
741
- parent: tilelayerCredit,
742
- safeHTML: this.selected_tilelayer.getAttribution(),
743
- })
744
- const urls = {
745
- leaflet: 'http://leafletjs.com',
746
- django: 'https://www.djangoproject.com',
747
- umap: 'http://wiki.openstreetmap.org/wiki/UMap',
748
- changelog: 'https://umap-project.readthedocs.io/en/master/changelog/',
749
- version: this.options.umap_version,
750
- }
751
- const creditHTML = L._(
752
- `
753
- Powered by <a href="{leaflet}">Leaflet</a> and
754
- <a href="{django}">Django</a>,
755
- glued by <a href="{umap}">uMap project</a>
756
- (version <a href="{changelog}">{version}</a>).
757
- `,
758
- urls
759
- )
760
- L.DomUtil.element({ tagName: 'p', innerHTML: creditHTML, parent: credits })
761
- this.panel.open({ content: container })
762
- },
763
-
764
681
  renderEditToolbar: function () {
765
682
  const container = L.DomUtil.create(
766
683
  'div',
@@ -910,7 +827,7 @@ const ControlsMixin = {
910
827
  L.DomUtil.createIcon(row, 'icon-drag', L._('Drag to reorder'))
911
828
  datalayer.renderToolbox(row)
912
829
  const title = L.DomUtil.add('span', '', row, datalayer.options.name)
913
- L.DomUtil.classIf(row, 'off', !datalayer.isVisible())
830
+ row.classList.toggle('off', !datalayer.isVisible())
914
831
  title.textContent = datalayer.options.name
915
832
  row.dataset.id = L.stamp(datalayer)
916
833
  })
@@ -1077,7 +994,7 @@ U.AttributionControl = L.Control.Attribution.extend({
1077
994
  if (captionMenus) {
1078
995
  const link = L.DomUtil.add('a', '', container, ` — ${L._('About')}`)
1079
996
  L.DomEvent.on(link, 'click', L.DomEvent.stop)
1080
- .on(link, 'click', this._map.displayCaption, this._map)
997
+ .on(link, 'click', this._map.openCaption, this._map)
1081
998
  .on(link, 'dblclick', L.DomEvent.stop)
1082
999
  }
1083
1000
  if (window.top === window.self && captionMenus) {
@@ -1121,8 +1038,17 @@ U.Locate = L.Control.Locate.extend({
1121
1038
  _activate: function () {
1122
1039
  this._map = this.map
1123
1040
  L.Control.Locate.prototype._activate.call(this)
1124
- this._map = null
1125
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
+
1126
1052
  })
1127
1053
 
1128
1054
  U.Search = L.PhotonSearch.extend({
@@ -162,11 +162,6 @@ L.DomUtil.createCopiableInput = (parent, label, value) => {
162
162
  return input
163
163
  }
164
164
 
165
- L.DomUtil.classIf = (el, className, bool) => {
166
- if (bool) L.DomUtil.addClass(el, className)
167
- else L.DomUtil.removeClass(el, className)
168
- }
169
-
170
165
  L.DomUtil.element = ({ tagName, parent, ...attrs }) => {
171
166
  const el = document.createElement(tagName)
172
167
  if (attrs.innerHTML) {
@@ -556,7 +551,9 @@ U.Help = L.Class.extend({
556
551
  'Comma separated list of properties to use for sorting features. To reverse the sort, put a minus sign (-) before. Eg. mykey,-otherkey.'
557
552
  ),
558
553
  slugKey: L._('The name of the property to use as feature unique identifier.'),
559
- filterKey: L._('Comma separated list of properties to use when filtering features by text input'),
554
+ filterKey: L._(
555
+ 'Comma separated list of properties to use when filtering features by text input'
556
+ ),
560
557
  facetKey: L._(
561
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.'
562
559
  ),
@@ -745,14 +745,12 @@ L.FormBuilder.Switch = L.FormBuilder.CheckBox.extend({
745
745
  })
746
746
 
747
747
  L.FormBuilder.FacetSearchBase = L.FormBuilder.Element.extend({
748
-
749
748
  buildLabel: function () {
750
749
  this.label = L.DomUtil.element({
751
750
  tagName: 'legend',
752
751
  textContent: this.options.label,
753
752
  })
754
- }
755
-
753
+ },
756
754
  })
757
755
  L.FormBuilder.FacetSearchChoices = L.FormBuilder.FacetSearchBase.extend({
758
756
  build: function () {
@@ -865,13 +863,13 @@ L.FormBuilder.MinMaxBase = L.FormBuilder.FacetSearchBase.extend({
865
863
  },
866
864
 
867
865
  isMinModified: function () {
868
- const default_ = this.minInput.getAttribute("value")
866
+ const default_ = this.minInput.getAttribute('value')
869
867
  const current = this.minInput.value
870
868
  return current != default_
871
869
  },
872
870
 
873
871
  isMaxModified: function () {
874
- const default_ = this.maxInput.getAttribute("value")
872
+ const default_ = this.maxInput.getAttribute('value')
875
873
  const current = this.maxInput.value
876
874
  return current != default_
877
875
  },
@@ -943,7 +941,11 @@ L.FormBuilder.MultiChoice = L.FormBuilder.Element.extend({
943
941
  if (!this.container.querySelector(`input[type="radio"][value="${value}"]`)) {
944
942
  value = this.options.default !== undefined ? this.options.default : this.default
945
943
  }
946
- this.container.querySelector(`input[type="radio"][value="${value}"]`).checked = true
944
+ const choices = this.getChoices().map(([value, label]) => value)
945
+ if (choices.includes(value)) {
946
+ this.container.querySelector(`input[type="radio"][value="${value}"]`).checked =
947
+ true
948
+ }
947
949
  },
948
950
 
949
951
  value: function () {
@@ -214,15 +214,17 @@ U.Map = L.Map.extend({
214
214
  if (L.Util.queryString('share')) {
215
215
  this.share.open()
216
216
  } else if (this.options.onLoadPanel === 'databrowser') {
217
+ this.panel.setDefaultMode('expanded')
217
218
  this.openBrowser('data')
218
219
  } else if (this.options.onLoadPanel === 'datalayers') {
220
+ this.panel.setDefaultMode('condensed')
219
221
  this.openBrowser('layers')
220
222
  } else if (this.options.onLoadPanel === 'datafilters') {
221
- this.panel.mode = 'expanded'
223
+ this.panel.setDefaultMode('expanded')
222
224
  this.openBrowser('filters')
223
225
  } else if (this.options.onLoadPanel === 'caption') {
224
- this.panel.mode = 'condensed'
225
- this.displayCaption()
226
+ this.panel.setDefaultMode('condensed')
227
+ this.openCaption()
226
228
  }
227
229
  if (L.Util.queryString('edit')) {
228
230
  if (this.hasEditMode()) this.enableEdit()
@@ -382,6 +384,7 @@ U.Map = L.Map.extend({
382
384
  else this.scrollWheelZoom.disable()
383
385
  this.browser = new U.Browser(this)
384
386
  this.facets = new U.Facets(this)
387
+ this.caption = new U.Caption(this)
385
388
  this.importer = new U.Importer(this)
386
389
  this.drop = new U.DropControl(this)
387
390
  this.share = new U.Share(this)
@@ -389,17 +392,10 @@ U.Map = L.Map.extend({
389
392
  },
390
393
 
391
394
  renderControls: function () {
392
- L.DomUtil.classIf(
393
- document.body,
394
- 'umap-caption-bar-enabled',
395
- this.options.captionBar ||
396
- (this.options.slideshow && this.options.slideshow.active)
397
- )
398
- L.DomUtil.classIf(
399
- document.body,
400
- 'umap-slideshow-enabled',
401
- this.options.slideshow && this.options.slideshow.active
402
- )
395
+ const hasSlideshow = Boolean(this.options.slideshow && this.options.slideshow.active)
396
+ const barEnabled = this.options.captionBar || hasSlideshow
397
+ document.body.classList.toggle('umap-caption-bar-enabled', barEnabled)
398
+ document.body.classList.toggle('umap-slideshow-enabled', hasSlideshow)
403
399
  for (const control of Object.values(this._controls)) {
404
400
  this.removeControl(control)
405
401
  }
@@ -474,6 +470,7 @@ U.Map = L.Map.extend({
474
470
 
475
471
  onDataLayersChanged: function () {
476
472
  if (this.browser) this.browser.update()
473
+ this.caption.refresh()
477
474
  },
478
475
 
479
476
  ensurePanesOrder: function () {
@@ -517,11 +514,11 @@ U.Map = L.Map.extend({
517
514
 
518
515
  initShortcuts: function () {
519
516
  const globalShortcuts = function (e) {
520
- const key = e.keyCode,
521
- modifierKey = e.ctrlKey || e.metaKey
517
+ const key = e.keyCode
518
+ const hasModifier = (e.ctrlKey || e.metaKey) && !e.shiftKey
522
519
 
523
520
  /* Generic shortcuts */
524
- if (key === U.Keys.F && modifierKey) {
521
+ if (key === U.Keys.F && hasModifier) {
525
522
  L.DomEvent.stop(e)
526
523
  this.search()
527
524
  } else if (e.keyCode === U.Keys.ESC) {
@@ -537,44 +534,44 @@ U.Map = L.Map.extend({
537
534
  if (!this.hasEditMode()) return
538
535
 
539
536
  /* Edit mode only shortcuts */
540
- if (key === U.Keys.E && modifierKey && !this.editEnabled) {
537
+ if (key === U.Keys.E && hasModifier && !this.editEnabled) {
541
538
  L.DomEvent.stop(e)
542
539
  this.enableEdit()
543
- } else if (key === U.Keys.E && modifierKey && this.editEnabled && !this.isDirty) {
540
+ } else if (key === U.Keys.E && hasModifier && this.editEnabled && !this.isDirty) {
544
541
  L.DomEvent.stop(e)
545
542
  this.disableEdit()
546
543
  }
547
- if (key === U.Keys.S && modifierKey) {
544
+ if (key === U.Keys.S && hasModifier) {
548
545
  L.DomEvent.stop(e)
549
546
  if (this.isDirty) {
550
547
  this.save()
551
548
  }
552
549
  }
553
- if (key === U.Keys.Z && modifierKey && this.isDirty) {
550
+ if (key === U.Keys.Z && hasModifier && this.isDirty) {
554
551
  L.DomEvent.stop(e)
555
552
  this.askForReset()
556
553
  }
557
- if (key === U.Keys.M && modifierKey && this.editEnabled) {
554
+ if (key === U.Keys.M && hasModifier && this.editEnabled) {
558
555
  L.DomEvent.stop(e)
559
556
  this.editTools.startMarker()
560
557
  }
561
- if (key === U.Keys.P && modifierKey && this.editEnabled) {
558
+ if (key === U.Keys.P && hasModifier && this.editEnabled) {
562
559
  L.DomEvent.stop(e)
563
560
  this.editTools.startPolygon()
564
561
  }
565
- if (key === U.Keys.L && modifierKey && this.editEnabled) {
562
+ if (key === U.Keys.L && hasModifier && this.editEnabled) {
566
563
  L.DomEvent.stop(e)
567
564
  this.editTools.startPolyline()
568
565
  }
569
- if (key === U.Keys.I && modifierKey && this.editEnabled) {
566
+ if (key === U.Keys.I && hasModifier && this.editEnabled) {
570
567
  L.DomEvent.stop(e)
571
568
  this.importer.open()
572
569
  }
573
- if (key === U.Keys.O && modifierKey && this.editEnabled) {
570
+ if (key === U.Keys.O && hasModifier && this.editEnabled) {
574
571
  L.DomEvent.stop(e)
575
572
  this.importer.openFiles()
576
573
  }
577
- if (key === U.Keys.H && modifierKey && this.editEnabled) {
574
+ if (key === U.Keys.H && hasModifier && this.editEnabled) {
578
575
  L.DomEvent.stop(e)
579
576
  this.help.show('edit')
580
577
  }
@@ -911,9 +908,11 @@ U.Map = L.Map.extend({
911
908
  },
912
909
 
913
910
  openBrowser: function (mode) {
914
- this.onceDatalayersLoaded(function () {
915
- this.browser.open(mode)
916
- })
911
+ this.onceDatalayersLoaded(() => this.browser.open(mode))
912
+ },
913
+
914
+ openCaption: function () {
915
+ this.onceDatalayersLoaded(() => this.caption.open())
917
916
  },
918
917
 
919
918
  eachDataLayer: function (method, context) {
@@ -965,7 +964,7 @@ U.Map = L.Map.extend({
965
964
  },
966
965
 
967
966
  checkDirty: function () {
968
- L.DomUtil.classIf(this._container, 'umap-is-dirty', this.isDirty)
967
+ this._container.classList.toggle('umap-is-dirty', this.isDirty)
969
968
  },
970
969
 
971
970
  addDirtyDatalayer: function (datalayer) {
@@ -1060,7 +1059,6 @@ U.Map = L.Map.extend({
1060
1059
  else window.location = data.url
1061
1060
  alert.content = data.info || alert.content
1062
1061
  this.once('saved', () => this.ui.alert(alert))
1063
- this.editPanel.close()
1064
1062
  this.permissions.save()
1065
1063
  }
1066
1064
  },
@@ -1591,7 +1589,7 @@ U.Map = L.Map.extend({
1591
1589
  'umap-about-link flat',
1592
1590
  container,
1593
1591
  L._('About'),
1594
- this.displayCaption,
1592
+ this.openCaption,
1595
1593
  this
1596
1594
  )
1597
1595
  L.DomUtil.createButton(
@@ -1758,7 +1756,7 @@ U.Map = L.Map.extend({
1758
1756
  items.push(
1759
1757
  {
1760
1758
  text: L._('About'),
1761
- callback: this.displayCaption,
1759
+ callback: this.openCaption,
1762
1760
  },
1763
1761
  {
1764
1762
  text: this.help.displayLabel('SEARCH'),
@@ -863,7 +863,7 @@ U.DataLayer = L.Evented.extend({
863
863
  },
864
864
 
865
865
  isRemoteLayer: function () {
866
- return !!(
866
+ return Boolean(
867
867
  this.options.remoteData &&
868
868
  this.options.remoteData.url &&
869
869
  this.options.remoteData.format
@@ -1528,7 +1528,7 @@ U.DataLayer = L.Evented.extend({
1528
1528
  },
1529
1529
 
1530
1530
  isVisible: function () {
1531
- return this.layer && this.map.hasLayer(this.layer)
1531
+ return Boolean(this.layer && this.map.hasLayer(this.layer))
1532
1532
  },
1533
1533
 
1534
1534
  getFeatureByIndex: function (index) {
@@ -55,6 +55,7 @@ U.Popup.Panel = U.Popup.extend({
55
55
  },
56
56
 
57
57
  onAdd: function (map) {
58
+ map.panel.setDefaultMode('expanded')
58
59
  map.panel.open({
59
60
  content: this._content,
60
61
  actions: [U.Browser.backButton(map)],