umap-project 2.8.0a2__py3-none-any.whl → 2.8.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 (134) hide show
  1. umap/__init__.py +1 -1
  2. umap/decorators.py +3 -1
  3. umap/locale/ar/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/ar/LC_MESSAGES/django.po +45 -30
  5. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/br/LC_MESSAGES/django.po +49 -34
  7. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/ca/LC_MESSAGES/django.po +45 -30
  9. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/cs_CZ/LC_MESSAGES/django.po +52 -37
  11. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  12. umap/locale/da/LC_MESSAGES/django.po +45 -30
  13. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  14. umap/locale/de/LC_MESSAGES/django.po +45 -30
  15. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  16. umap/locale/el/LC_MESSAGES/django.po +45 -30
  17. umap/locale/en/LC_MESSAGES/django.po +44 -29
  18. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  19. umap/locale/es/LC_MESSAGES/django.po +45 -30
  20. umap/locale/et/LC_MESSAGES/django.mo +0 -0
  21. umap/locale/et/LC_MESSAGES/django.po +45 -30
  22. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  23. umap/locale/eu/LC_MESSAGES/django.po +65 -50
  24. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  25. umap/locale/fa_IR/LC_MESSAGES/django.po +45 -30
  26. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  27. umap/locale/fr/LC_MESSAGES/django.po +45 -30
  28. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  29. umap/locale/gl/LC_MESSAGES/django.po +45 -30
  30. umap/locale/he/LC_MESSAGES/django.mo +0 -0
  31. umap/locale/he/LC_MESSAGES/django.po +45 -30
  32. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  33. umap/locale/hu/LC_MESSAGES/django.po +45 -30
  34. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  35. umap/locale/is/LC_MESSAGES/django.po +45 -30
  36. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  37. umap/locale/it/LC_MESSAGES/django.po +45 -30
  38. umap/locale/ja/LC_MESSAGES/django.mo +0 -0
  39. umap/locale/ja/LC_MESSAGES/django.po +45 -30
  40. umap/locale/ko/LC_MESSAGES/django.mo +0 -0
  41. umap/locale/ko/LC_MESSAGES/django.po +45 -30
  42. umap/locale/lt/LC_MESSAGES/django.mo +0 -0
  43. umap/locale/lt/LC_MESSAGES/django.po +45 -30
  44. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  45. umap/locale/ms/LC_MESSAGES/django.po +45 -30
  46. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  47. umap/locale/nl/LC_MESSAGES/django.po +45 -30
  48. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  49. umap/locale/pl/LC_MESSAGES/django.po +45 -30
  50. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  51. umap/locale/pt/LC_MESSAGES/django.po +45 -30
  52. umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  53. umap/locale/pt_BR/LC_MESSAGES/django.po +45 -30
  54. umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  55. umap/locale/pt_PT/LC_MESSAGES/django.po +45 -30
  56. umap/locale/ru/LC_MESSAGES/django.mo +0 -0
  57. umap/locale/ru/LC_MESSAGES/django.po +45 -30
  58. umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  59. umap/locale/sk_SK/LC_MESSAGES/django.po +45 -30
  60. umap/locale/sl/LC_MESSAGES/django.mo +0 -0
  61. umap/locale/sl/LC_MESSAGES/django.po +45 -30
  62. umap/locale/sr/LC_MESSAGES/django.mo +0 -0
  63. umap/locale/sr/LC_MESSAGES/django.po +45 -30
  64. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  65. umap/locale/sv/LC_MESSAGES/django.po +45 -30
  66. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  67. umap/locale/th_TH/LC_MESSAGES/django.po +45 -30
  68. umap/locale/tr/LC_MESSAGES/django.mo +0 -0
  69. umap/locale/tr/LC_MESSAGES/django.po +45 -30
  70. umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
  71. umap/locale/uk_UA/LC_MESSAGES/django.po +45 -30
  72. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  73. umap/locale/zh_TW/LC_MESSAGES/django.po +50 -35
  74. umap/settings/local_s3.py +45 -0
  75. umap/static/umap/content.css +18 -13
  76. umap/static/umap/css/bar.css +4 -0
  77. umap/static/umap/css/form.css +3 -0
  78. umap/static/umap/img/logo_lightcyan.svg +4 -0
  79. umap/static/umap/js/modules/caption.js +73 -73
  80. umap/static/umap/js/modules/data/features.js +20 -5
  81. umap/static/umap/js/modules/data/layer.js +17 -14
  82. umap/static/umap/js/modules/drop.js +55 -0
  83. umap/static/umap/js/modules/importer.js +20 -10
  84. umap/static/umap/js/modules/rendering/icon.js +2 -1
  85. umap/static/umap/js/modules/rendering/map.js +9 -8
  86. umap/static/umap/js/modules/rendering/popup.js +9 -10
  87. umap/static/umap/js/modules/rendering/template.js +53 -9
  88. umap/static/umap/js/modules/rendering/ui.js +6 -2
  89. umap/static/umap/js/modules/request.js +2 -2
  90. umap/static/umap/js/modules/schema.js +1 -0
  91. umap/static/umap/js/modules/sync/engine.js +56 -13
  92. umap/static/umap/js/modules/sync/updaters.js +4 -1
  93. umap/static/umap/js/modules/sync/websocket.js +47 -2
  94. umap/static/umap/js/modules/ui/bar.js +1 -1
  95. umap/static/umap/js/modules/ui/dialog.js +5 -0
  96. umap/static/umap/js/modules/umap.js +62 -25
  97. umap/static/umap/js/modules/utils.js +2 -0
  98. umap/static/umap/js/umap.controls.js +8 -55
  99. umap/static/umap/js/umap.forms.js +44 -0
  100. umap/static/umap/locale/cs_CZ.js +13 -11
  101. umap/static/umap/locale/cs_CZ.json +13 -11
  102. umap/static/umap/locale/en.js +2 -1
  103. umap/static/umap/locale/en.json +2 -1
  104. umap/static/umap/locale/fr.js +2 -1
  105. umap/static/umap/locale/fr.json +2 -1
  106. umap/static/umap/locale/zh_TW.js +13 -11
  107. umap/static/umap/locale/zh_TW.json +13 -11
  108. umap/static/umap/map.css +34 -166
  109. umap/static/umap/unittests/sync.js +4 -1
  110. umap/static/umap/vars.css +0 -1
  111. umap/templates/403.html +12 -0
  112. umap/templates/404.html +4 -13
  113. umap/templates/40x.html +9 -0
  114. umap/templates/base.html +2 -0
  115. umap/templates/umap/components/alerts/alert.html +4 -0
  116. umap/templates/umap/css.html +3 -0
  117. umap/templates/umap/js.html +2 -0
  118. umap/templates/umap/map_init.html +2 -0
  119. umap/templates/umap/user_dashboard.html +2 -0
  120. umap/tests/fixtures/test_upload_simple_marker.json +19 -0
  121. umap/tests/integration/conftest.py +3 -3
  122. umap/tests/integration/test_edit_datalayer.py +11 -0
  123. umap/tests/integration/test_import.py +20 -1
  124. umap/tests/integration/test_websocket_sync.py +69 -0
  125. umap/tests/test_dashboard.py +82 -0
  126. umap/tests/test_team_views.py +35 -1
  127. umap/tests/test_views.py +0 -74
  128. umap/views.py +5 -1
  129. umap/websocket_server.py +8 -1
  130. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/METADATA +5 -5
  131. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/RECORD +134 -127
  132. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/WHEEL +0 -0
  133. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/entry_points.txt +0 -0
  134. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/licenses/LICENSE +0 -0
@@ -110,7 +110,7 @@ export class TopBar extends WithTemplate {
110
110
  })
111
111
  })
112
112
 
113
- this.elements.help.addEventListener('click', () => this._umap.showGetStarted())
113
+ this.elements.help.addEventListener('click', () => this._umap.help.showGetStarted())
114
114
  this.elements.cancel.addEventListener('click', () => this._umap.askForReset())
115
115
  this.elements.cancel.addEventListener('mouseover', () => {
116
116
  this._umap.tooltip.open({
@@ -6,6 +6,7 @@ const TEMPLATE = `
6
6
  <form method="dialog" data-ref="form">
7
7
  <ul class="buttons">
8
8
  <li><i class="icon icon-16 icon-close" data-close></i></li>
9
+ <li hidden data-ref="back"><i class="icon icon-16 icon-back"></i></li>
9
10
  </ul>
10
11
  <h3 data-ref="message" id="${Math.round(Date.now()).toString(36)}"></h3>
11
12
  <fieldset data-ref="fieldset" role="document">
@@ -123,6 +124,10 @@ export default class Dialog extends WithTemplate {
123
124
  } else {
124
125
  this.elements.template.innerHTML = dialog.template || ''
125
126
  }
127
+ this.elements.back.hidden = !dialog.back
128
+ if (dialog.back) {
129
+ this.elements.back.addEventListener('click', dialog.back)
130
+ }
126
131
 
127
132
  this.focusable = this.getFocusable()
128
133
  this.hasFormData = this.elements.fieldset.elements.length > 0
@@ -61,8 +61,6 @@ export default class Umap extends ServerStored {
61
61
  )
62
62
  this.searchParams = new URLSearchParams(window.location.search)
63
63
 
64
- this.sync_engine = new SyncEngine(this)
65
- this.sync = this.sync_engine.proxy(this)
66
64
  // Locale name (pt_PT, en_US…)
67
65
  // To be used for Django localization
68
66
  if (geojson.properties.locale) setLocale(geojson.properties.locale)
@@ -124,6 +122,9 @@ export default class Umap extends ServerStored {
124
122
  this.share = new Share(this)
125
123
  this.rules = new Rules(this)
126
124
 
125
+ this.syncEngine = new SyncEngine(this)
126
+ this.sync = this.syncEngine.proxy(this)
127
+
127
128
  if (this.hasEditMode()) {
128
129
  this.editPanel = new EditPanel(this, this._leafletMap)
129
130
  this.fullPanel = new FullPanel(this, this._leafletMap)
@@ -218,6 +219,14 @@ export default class Umap extends ServerStored {
218
219
  this.fire('seteditedfeature')
219
220
  }
220
221
 
222
+ get activeFeature() {
223
+ return this._activeFeature
224
+ }
225
+
226
+ set activeFeature(feature) {
227
+ this._activeFeature = feature
228
+ }
229
+
221
230
  setPropertiesFromQueryString() {
222
231
  const asBoolean = (key) => {
223
232
  const value = this.searchParams.get(key)
@@ -315,14 +324,14 @@ export default class Umap extends ServerStored {
315
324
  dataUrl = decodeURIComponent(dataUrl)
316
325
  dataUrl = this.renderUrl(dataUrl)
317
326
  dataUrl = this.proxyUrl(dataUrl)
318
- const datalayer = this.createDataLayer()
327
+ const datalayer = this.createDirtyDataLayer()
319
328
  await datalayer
320
329
  .importFromUrl(dataUrl, dataFormat)
321
330
  .then(() => datalayer.zoomTo())
322
331
  }
323
332
  } else if (data) {
324
333
  data = decodeURIComponent(data)
325
- const datalayer = this.createDataLayer()
334
+ const datalayer = this.createDirtyDataLayer()
326
335
  await datalayer.importRaw(data, dataFormat).then(() => datalayer.zoomTo())
327
336
  }
328
337
  }
@@ -570,9 +579,15 @@ export default class Umap extends ServerStored {
570
579
  }
571
580
  this.datalayersLoaded = true
572
581
  this.fire('datalayersloaded')
582
+ const toLoad = []
573
583
  for (const datalayer of this.datalayersIndex) {
574
- if (datalayer.showAtLoad()) await datalayer.show()
584
+ if (datalayer.showAtLoad()) toLoad.push(() => datalayer.show())
575
585
  }
586
+ while (toLoad.length) {
587
+ const chunk = toLoad.splice(0, 10)
588
+ await Promise.all(chunk.map((func) => func()))
589
+ }
590
+
576
591
  this.dataloaded = true
577
592
  this.fire('dataloaded')
578
593
  }
@@ -588,8 +603,14 @@ export default class Umap extends ServerStored {
588
603
  return datalayer
589
604
  }
590
605
 
606
+ createDirtyDataLayer(options) {
607
+ const datalayer = this.createDataLayer(options, true)
608
+ datalayer.isDirty = true
609
+ return datalayer
610
+ }
611
+
591
612
  newDataLayer() {
592
- const datalayer = this.createDataLayer({})
613
+ const datalayer = this.createDirtyDataLayer({})
593
614
  datalayer.edit()
594
615
  }
595
616
 
@@ -643,6 +664,12 @@ export default class Umap extends ServerStored {
643
664
  // have changed, we'll be more subtil when we'll remove the
644
665
  // save action
645
666
  this.render(['name', 'user', 'permissions'])
667
+ if (!this._leafletMap.listens('saved')) {
668
+ // When we save only layers, we don't have the map feedback message
669
+ this._leafletMap.on('saved', () => {
670
+ Alert.success(translate('Map has been saved!'))
671
+ })
672
+ }
646
673
  this.fire('saved')
647
674
  }
648
675
 
@@ -1101,8 +1128,8 @@ export default class Umap extends ServerStored {
1101
1128
  }
1102
1129
  this.ensurePanesOrder()
1103
1130
  this._leafletMap.initTileLayers()
1104
- this.isDirty = false
1105
1131
  this.onDataLayersChanged()
1132
+ this.isDirty = !this.id
1106
1133
  }
1107
1134
 
1108
1135
  async save() {
@@ -1184,7 +1211,7 @@ export default class Umap extends ServerStored {
1184
1211
  geometry() {
1185
1212
  /* Return a GeoJSON geometry Object */
1186
1213
  const latlng = this._leafletMap.latLng(
1187
- this._leafletMap.options.center || this._leafletMap.getCenter()
1214
+ this.properties.center || this._leafletMap.getCenter()
1188
1215
  )
1189
1216
  return {
1190
1217
  type: 'Point',
@@ -1241,18 +1268,13 @@ export default class Umap extends ServerStored {
1241
1268
  }
1242
1269
 
1243
1270
  async initSyncEngine() {
1271
+ // this.properties.websocketEnabled is set by the server admin
1244
1272
  if (this.properties.websocketEnabled === false) return
1273
+ // this.properties.syncEnabled is set by the user in the map settings
1245
1274
  if (this.properties.syncEnabled !== true) {
1246
1275
  this.sync.stop()
1247
1276
  } else {
1248
- const ws_token_uri = this.urls.get('map_websocket_auth_token', {
1249
- map_id: this.id,
1250
- })
1251
- await this.sync.authenticate(
1252
- ws_token_uri,
1253
- this.properties.websocketURI,
1254
- this.server
1255
- )
1277
+ await this.sync.authenticate()
1256
1278
  }
1257
1279
  }
1258
1280
 
@@ -1327,7 +1349,17 @@ export default class Umap extends ServerStored {
1327
1349
  },
1328
1350
  numberOfConnectedPeers: () => {
1329
1351
  Utils.eachElement('.connected-peers span', (el) => {
1330
- el.textContent = this.sync.getNumberOfConnectedPeers()
1352
+ if (this.sync.websocketConnected) {
1353
+ el.textContent = this.sync.getNumberOfConnectedPeers()
1354
+ } else {
1355
+ el.textContent = translate('Disconnected')
1356
+ }
1357
+ el.parentElement.classList.toggle('off', !this.sync.websocketConnected)
1358
+ })
1359
+ },
1360
+ 'properties.starred': () => {
1361
+ Utils.eachElement('.map-star', (el) => {
1362
+ el.classList.toggle('starred', this.properties.starred)
1331
1363
  })
1332
1364
  },
1333
1365
  }
@@ -1367,7 +1399,7 @@ export default class Umap extends ServerStored {
1367
1399
  fallback.show()
1368
1400
  return fallback
1369
1401
  }
1370
- return this.createDataLayer()
1402
+ return this.createDirtyDataLayer()
1371
1403
  }
1372
1404
 
1373
1405
  findDataLayer(method, context) {
@@ -1426,9 +1458,14 @@ export default class Umap extends ServerStored {
1426
1458
  const row = DomUtil.create('li', 'orderable', ul)
1427
1459
  DomUtil.createIcon(row, 'icon-drag', translate('Drag to reorder'))
1428
1460
  datalayer.renderToolbox(row)
1429
- const title = DomUtil.add('span', '', row, datalayer.options.name)
1461
+ const builder = new U.FormBuilder(
1462
+ datalayer,
1463
+ [['options.name', { handler: 'EditableText' }]],
1464
+ { className: 'umap-form-inline' }
1465
+ )
1466
+ const form = builder.build()
1467
+ row.appendChild(form)
1430
1468
  row.classList.toggle('off', !datalayer.isVisible())
1431
- title.textContent = datalayer.options.name
1432
1469
  row.dataset.id = stamp(datalayer)
1433
1470
  })
1434
1471
  const onReorder = (src, dst, initialIndex, finalIndex) => {
@@ -1510,7 +1547,7 @@ export default class Umap extends ServerStored {
1510
1547
  ? translate('Map has been starred')
1511
1548
  : translate('Map has been unstarred')
1512
1549
  )
1513
- this.render(['starred'])
1550
+ this.render(['properties.starred'])
1514
1551
  }
1515
1552
 
1516
1553
  processFileToImport(file, layer, type) {
@@ -1526,7 +1563,7 @@ export default class Umap extends ServerStored {
1526
1563
  if (type === 'umap') {
1527
1564
  this.importUmapFile(file, 'umap')
1528
1565
  } else {
1529
- if (!layer) layer = this.createDataLayer({ name: file.name })
1566
+ if (!layer) layer = this.createDirtyDataLayer({ name: file.name })
1530
1567
  layer.importFromFile(file, type)
1531
1568
  }
1532
1569
  }
@@ -1552,7 +1589,7 @@ export default class Umap extends ServerStored {
1552
1589
  delete geojson._storage
1553
1590
  }
1554
1591
  delete geojson._umap_options?.id // Never trust an id at this stage
1555
- const dataLayer = this.createDataLayer(geojson._umap_options)
1592
+ const dataLayer = this.createDirtyDataLayer(geojson._umap_options)
1556
1593
  dataLayer.fromUmapGeoJSON(geojson)
1557
1594
  }
1558
1595
 
@@ -1662,8 +1699,8 @@ export default class Umap extends ServerStored {
1662
1699
  }
1663
1700
 
1664
1701
  _setCenterAndZoom() {
1665
- this._leafletMap.options.center = this._leafletMap.getCenter()
1666
- this._leafletMap.options.zoom = this._leafletMap.getZoom()
1702
+ this.properties.center = this._leafletMap.getCenter()
1703
+ this.properties.zoom = this._leafletMap.getZoom()
1667
1704
  this.isDirty = true
1668
1705
  this._defaultExtent = false
1669
1706
  }
@@ -115,6 +115,8 @@ export function escapeHTML(s) {
115
115
  'span',
116
116
  'dt',
117
117
  'dd',
118
+ 'b',
119
+ 'i',
118
120
  ],
119
121
  ADD_ATTR: [
120
122
  'target',
@@ -337,52 +337,6 @@ U.DrawToolbar = L.Toolbar.Control.extend({
337
337
  },
338
338
  })
339
339
 
340
- U.DropControl = L.Class.extend({
341
- initialize: function (map) {
342
- this.map = map
343
- this.dropzone = map._container
344
- },
345
-
346
- enable: function () {
347
- L.DomEvent.on(this.dropzone, 'dragenter', this.dragenter, this)
348
- L.DomEvent.on(this.dropzone, 'dragover', this.dragover, this)
349
- L.DomEvent.on(this.dropzone, 'drop', this.drop, this)
350
- L.DomEvent.on(this.dropzone, 'dragleave', this.dragleave, this)
351
- },
352
-
353
- disable: function () {
354
- L.DomEvent.off(this.dropzone, 'dragenter', this.dragenter, this)
355
- L.DomEvent.off(this.dropzone, 'dragover', this.dragover, this)
356
- L.DomEvent.off(this.dropzone, 'drop', this.drop, this)
357
- L.DomEvent.off(this.dropzone, 'dragleave', this.dragleave, this)
358
- },
359
-
360
- dragenter: function (event) {
361
- L.DomEvent.stop(event)
362
- this.map.scrollWheelZoom.disable()
363
- this.dropzone.classList.add('umap-dragover')
364
- },
365
-
366
- dragover: (event) => {
367
- L.DomEvent.stop(event)
368
- },
369
-
370
- drop: function (event) {
371
- this.map.scrollWheelZoom.enable()
372
- this.dropzone.classList.remove('umap-dragover')
373
- L.DomEvent.stop(event)
374
- for (const file of event.dataTransfer.files) {
375
- this.map._umap.processFileToImport(file)
376
- }
377
- this.map._umap.onceDataLoaded(this.map._umap.fitDataBounds)
378
- },
379
-
380
- dragleave: function () {
381
- this.map.scrollWheelZoom.enable()
382
- this.dropzone.classList.remove('umap-dragover')
383
- },
384
- })
385
-
386
340
  U.EditControl = L.Control.extend({
387
341
  options: {
388
342
  position: 'topright',
@@ -541,11 +495,7 @@ U.StarControl = L.Control.Button.extend({
541
495
  options: {
542
496
  position: 'topleft',
543
497
  title: L._('Star this map'),
544
- },
545
-
546
- getClassName: function () {
547
- const status = this._umap.properties.starred ? ' starred' : ''
548
- return `leaflet-control-star umap-control${status}`
498
+ className: 'leaflet-control-star map-star umap-control',
549
499
  },
550
500
 
551
501
  onClick: function () {
@@ -683,10 +633,13 @@ U.TileLayerChooser = L.Control.extend({
683
633
  L.DomEvent.on(
684
634
  el,
685
635
  'click',
686
- function () {
636
+ () => {
687
637
  this.map.selectTileLayer(tilelayer)
688
638
  this.map._controls.tilelayers.setLayers()
689
- if (options?.callback) options.callback(tilelayer)
639
+ if (options?.edit) {
640
+ this.map._umap.properties.tilelayer = tilelayer.toJSON()
641
+ this.map._umap.isDirty = true
642
+ }
690
643
  },
691
644
  this
692
645
  )
@@ -942,11 +895,11 @@ L.Control.Loading.include({
942
895
  },
943
896
 
944
897
  _showIndicator: function () {
945
- L.DomUtil.addClass(this._map._container, 'umap-loading')
898
+ this._map._container.classList.add('umap-loading')
946
899
  },
947
900
 
948
901
  _hideIndicator: function () {
949
- L.DomUtil.removeClass(this._map._container, 'umap-loading')
902
+ this._map._container.classList.remove('umap-loading')
950
903
  },
951
904
  })
952
905
 
@@ -259,6 +259,35 @@ L.FormBuilder.CheckBox.include({
259
259
  },
260
260
  })
261
261
 
262
+ L.FormBuilder.EditableText = L.FormBuilder.Element.extend({
263
+ build: function () {
264
+ this.input = L.DomUtil.create('span', this.options.className || '', this.parentNode)
265
+ this.input.contentEditable = true
266
+ this.fetch()
267
+ L.DomEvent.on(this.input, 'input', this.sync, this)
268
+ L.DomEvent.on(this.input, 'keypress', this.onKeyPress, this)
269
+ },
270
+
271
+ getParentNode: function () {
272
+ return this.form
273
+ },
274
+
275
+ value: function () {
276
+ return this.input.textContent
277
+ },
278
+
279
+ fetch: function () {
280
+ this.input.textContent = this.toHTML()
281
+ },
282
+
283
+ onKeyPress: function (event) {
284
+ if (event.keyCode === 13) {
285
+ event.preventDefault()
286
+ this.input.blur()
287
+ }
288
+ },
289
+ })
290
+
262
291
  L.FormBuilder.ColorPicker = L.FormBuilder.Input.extend({
263
292
  colors: U.COLORS,
264
293
  getParentNode: function () {
@@ -1192,6 +1221,21 @@ U.FormBuilder = L.FormBuilder.extend({
1192
1221
  }
1193
1222
  },
1194
1223
 
1224
+ getter: function (field) {
1225
+ const path = field.split('.')
1226
+ let value = this.obj
1227
+ let sub
1228
+ for (sub of path) {
1229
+ try {
1230
+ value = value[sub]
1231
+ } catch {
1232
+ console.log(field)
1233
+ }
1234
+ }
1235
+ if (value === undefined) values = U.SCHEMA[sub]?.default
1236
+ return value
1237
+ },
1238
+
1195
1239
  finish: (event) => {
1196
1240
  event.helper?.input?.blur()
1197
1241
  },
@@ -183,12 +183,12 @@ const locale = {
183
183
  "Icon shape": "Tvar ikony",
184
184
  "Icon symbol": "Symbol ikony",
185
185
  "If false, the polygon or line will act as a part of the underlying map.": "Pokud je hodnota false, polygon nebo linie bude fungovat jako součást podkladové mapy.",
186
- "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}",
187
- "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}",
186
+ "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe s vlastní výškou (v px): 1{{{https://iframe.url.com|výška}}}",
187
+ "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe s vlastní výškou a šířkou (v px): 1{{{https://iframe.url.com|výška*šířka}}}",
188
188
  "iframe": "iframe",
189
189
  "Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}",
190
- "Image with custom width (in px): {{https://image.url.com|width}}": "Image with custom width (in px): {{https://image.url.com|width}}",
191
- "Image: {{https://image.url.com}}": "Image: {{https://image.url.com}}",
190
+ "Image with custom width (in px): {{https://image.url.com|width}}": "Obrázek s vlastní šířkou (v px): 1{{{https://iframe.url.com|šířka}}}",
191
+ "Image: {{https://image.url.com}}": "Obrázek: 1{{https://obrázek.url.com}}",
192
192
  "Import data": "Import dat",
193
193
  "Import in a new layer": "Importovat do nové vrstvy",
194
194
  "Imports all umap data, including layers and settings.": "Importuje všechy data umapy, včetně vrstev a nastavení",
@@ -216,7 +216,7 @@ const locale = {
216
216
  "Limit bounds": "Hranice zobrazení",
217
217
  "Link to view the map": "Odkaz pro zobrazení mapy",
218
218
  "Link to…": "Odkaz na…",
219
- "Link with text: [[https://example.com|text of the link]]": "Link with text: [[https://example.com|text of the link]]",
219
+ "Link with text: [[https://example.com|text of the link]]": "Odkaz s textem: [[https://priklad.cz|text odkazu]]",
220
220
  "Long credits": "Dlouhý text autorství",
221
221
  "Longitude": "Délka",
222
222
  "Make main shape": "Učinit hlavním tvarem",
@@ -320,7 +320,7 @@ const locale = {
320
320
  "Show this layer in the caption": "Zobrazit tuto vrstvu v nadpisu",
321
321
  "Show/hide layer": "Skrytí/zobrazení vrstvy",
322
322
  "Side panel": "Boční panel",
323
- "Simple link: [[https://example.com]]": "Simple link: [[https://example.com]]",
323
+ "Simple link: [[https://example.com]]": "Jednoduchý odkaz: [[https://priklad.cz]]",
324
324
  "Simplify": "Zjednodušit",
325
325
  "Skipping unknown geometry.type: {type}": "Přeskakuji neznámý geometry.type: {type}",
326
326
  "Slideshow": "Prezentace",
@@ -516,11 +516,13 @@ const locale = {
516
516
  "show/hide all layers": "zobrazit/skrýt všechny vrstvy",
517
517
  "zoom to data extent": "přiblížit na rozsah dat",
518
518
  "download visible data": "stáhnout viditelná data",
519
- "{connectedPeers} peer(s) currently connected to this map": "{connectedPeers} peer(s) currently connected to this map",
520
- "Import helpers": "Import helpers",
521
- "Import helpers will fill the URL field for you.": "Import helpers will fill the URL field for you.",
522
- "Wikipedia": "Wikipedia",
523
- "Save draft": "Save draft"
519
+ "{connectedPeers} peer(s) currently connected to this map": "K této mapě je aktuálně připojeno {connectedPeers} vrstevník(ů)",
520
+ "Import helpers": "Pomocníci pro import",
521
+ "Import helpers will fill the URL field for you.": "Pomocníci pro import vyplní pole URL za vás.",
522
+ "Wikipedia": "Wikipedie",
523
+ "Save draft": "Uložit koncept",
524
+ "No data has been found for import": "Nebyla nalezena žádná data pro import",
525
+ "Successfully imported {count} feature(s)": "Počet úspěšně importovaných prvků: {count}"
524
526
  }
525
527
  L.registerLocale("cs_CZ", locale)
526
528
  L.setLocale("cs_CZ")
@@ -183,12 +183,12 @@
183
183
  "Icon shape": "Tvar ikony",
184
184
  "Icon symbol": "Symbol ikony",
185
185
  "If false, the polygon or line will act as a part of the underlying map.": "Pokud je hodnota false, polygon nebo linie bude fungovat jako součást podkladové mapy.",
186
- "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}",
187
- "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}",
186
+ "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe s vlastní výškou (v px): 1{{{https://iframe.url.com|výška}}}",
187
+ "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe s vlastní výškou a šířkou (v px): 1{{{https://iframe.url.com|výška*šířka}}}",
188
188
  "iframe": "iframe",
189
189
  "Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}",
190
- "Image with custom width (in px): {{https://image.url.com|width}}": "Image with custom width (in px): {{https://image.url.com|width}}",
191
- "Image: {{https://image.url.com}}": "Image: {{https://image.url.com}}",
190
+ "Image with custom width (in px): {{https://image.url.com|width}}": "Obrázek s vlastní šířkou (v px): 1{{{https://iframe.url.com|šířka}}}",
191
+ "Image: {{https://image.url.com}}": "Obrázek: 1{{https://obrázek.url.com}}",
192
192
  "Import data": "Import dat",
193
193
  "Import in a new layer": "Importovat do nové vrstvy",
194
194
  "Imports all umap data, including layers and settings.": "Importuje všechy data umapy, včetně vrstev a nastavení",
@@ -216,7 +216,7 @@
216
216
  "Limit bounds": "Hranice zobrazení",
217
217
  "Link to view the map": "Odkaz pro zobrazení mapy",
218
218
  "Link to…": "Odkaz na…",
219
- "Link with text: [[https://example.com|text of the link]]": "Link with text: [[https://example.com|text of the link]]",
219
+ "Link with text: [[https://example.com|text of the link]]": "Odkaz s textem: [[https://priklad.cz|text odkazu]]",
220
220
  "Long credits": "Dlouhý text autorství",
221
221
  "Longitude": "Délka",
222
222
  "Make main shape": "Učinit hlavním tvarem",
@@ -320,7 +320,7 @@
320
320
  "Show this layer in the caption": "Zobrazit tuto vrstvu v nadpisu",
321
321
  "Show/hide layer": "Skrytí/zobrazení vrstvy",
322
322
  "Side panel": "Boční panel",
323
- "Simple link: [[https://example.com]]": "Simple link: [[https://example.com]]",
323
+ "Simple link: [[https://example.com]]": "Jednoduchý odkaz: [[https://priklad.cz]]",
324
324
  "Simplify": "Zjednodušit",
325
325
  "Skipping unknown geometry.type: {type}": "Přeskakuji neznámý geometry.type: {type}",
326
326
  "Slideshow": "Prezentace",
@@ -516,9 +516,11 @@
516
516
  "show/hide all layers": "zobrazit/skrýt všechny vrstvy",
517
517
  "zoom to data extent": "přiblížit na rozsah dat",
518
518
  "download visible data": "stáhnout viditelná data",
519
- "{connectedPeers} peer(s) currently connected to this map": "{connectedPeers} peer(s) currently connected to this map",
520
- "Import helpers": "Import helpers",
521
- "Import helpers will fill the URL field for you.": "Import helpers will fill the URL field for you.",
522
- "Wikipedia": "Wikipedia",
523
- "Save draft": "Save draft"
519
+ "{connectedPeers} peer(s) currently connected to this map": "K této mapě je aktuálně připojeno {connectedPeers} vrstevník(ů)",
520
+ "Import helpers": "Pomocníci pro import",
521
+ "Import helpers will fill the URL field for you.": "Pomocníci pro import vyplní pole URL za vás.",
522
+ "Wikipedia": "Wikipedie",
523
+ "Save draft": "Uložit koncept",
524
+ "No data has been found for import": "Nebyla nalezena žádná data pro import",
525
+ "Successfully imported {count} feature(s)": "Počet úspěšně importovaných prvků: {count}"
524
526
  }
@@ -522,7 +522,8 @@ const locale = {
522
522
  "Wikipedia": "Wikipedia",
523
523
  "Save draft": "Save draft",
524
524
  "No data has been found for import": "No data has been found for import",
525
- "Successfully imported {count} feature(s)": "Successfully imported {count} feature(s)"
525
+ "Successfully imported {count} feature(s)": "Successfully imported {count} feature(s)",
526
+ "Disconnected": "Disconnected"
526
527
  }
527
528
  L.registerLocale("en", locale)
528
529
  L.setLocale("en")
@@ -522,5 +522,6 @@
522
522
  "Wikipedia": "Wikipedia",
523
523
  "Save draft": "Save draft",
524
524
  "No data has been found for import": "No data has been found for import",
525
- "Successfully imported {count} feature(s)": "Successfully imported {count} feature(s)"
525
+ "Successfully imported {count} feature(s)": "Successfully imported {count} feature(s)",
526
+ "Disconnected": "Disconnected"
526
527
  }
@@ -522,7 +522,8 @@ const locale = {
522
522
  "Wikipedia": "Wikipedia",
523
523
  "Save draft": "Enregistrer le brouillon",
524
524
  "No data has been found for import": "Aucunes données à importer",
525
- "Successfully imported {count} feature(s)": "{count} élément(s) ajouté(s) à la carte"
525
+ "Successfully imported {count} feature(s)": "{count} élément(s) ajouté(s) à la carte",
526
+ "Disconnected": "Déconnecté"
526
527
  }
527
528
  L.registerLocale("fr", locale)
528
529
  L.setLocale("fr")
@@ -522,5 +522,6 @@
522
522
  "Wikipedia": "Wikipedia",
523
523
  "Save draft": "Enregistrer le brouillon",
524
524
  "No data has been found for import": "Aucunes données à importer",
525
- "Successfully imported {count} feature(s)": "{count} élément(s) ajouté(s) à la carte"
525
+ "Successfully imported {count} feature(s)": "{count} élément(s) ajouté(s) à la carte",
526
+ "Disconnected": "Déconnecté"
526
527
  }
@@ -183,12 +183,12 @@ const locale = {
183
183
  "Icon shape": "圖示圖形",
184
184
  "Icon symbol": "圖示標誌",
185
185
  "If false, the polygon or line will act as a part of the underlying map.": "選擇「否」時,多邊形物件會被當成為底圖的一部分。",
186
- "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}",
187
- "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}",
186
+ "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "iframe 的自訂高度 (px){{{https://iframe.url.com|height}}}",
187
+ "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "iframe 的自訂高度與寬度 (px){{{https://iframe.url.com|height*width}}}",
188
188
  "iframe": "iframe",
189
- "Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}",
190
- "Image with custom width (in px): {{https://image.url.com|width}}": "Image with custom width (in px): {{https://image.url.com|width}}",
191
- "Image: {{https://image.url.com}}": "Image: {{https://image.url.com}}",
189
+ "Iframe: {{{https://iframe.url.com}}}": "iframe:{{{https://iframe.url.com}}}",
190
+ "Image with custom width (in px): {{https://image.url.com|width}}": "圖片有自訂寬度 (px){{https://image.url.com|width}}",
191
+ "Image: {{https://image.url.com}}": "圖片:{{https://image.url.com}}",
192
192
  "Import data": "匯入資料",
193
193
  "Import in a new layer": "匯入至新圖層",
194
194
  "Imports all umap data, including layers and settings.": "匯入所有 umap 資料,包含圖層與設定。",
@@ -216,7 +216,7 @@ const locale = {
216
216
  "Limit bounds": "限制範圍",
217
217
  "Link to view the map": "檢視地圖的連結",
218
218
  "Link to…": "連結至...",
219
- "Link with text: [[https://example.com|text of the link]]": "Link with text: [[https://example.com|text of the link]]",
219
+ "Link with text: [[https://example.com|text of the link]]": "有文字的連結:[[https://example.com|text of the link]]",
220
220
  "Long credits": "詳細工作人員名單",
221
221
  "Longitude": "經度",
222
222
  "Make main shape": "設為主要外形",
@@ -320,7 +320,7 @@ const locale = {
320
320
  "Show this layer in the caption": "在標題顯示此圖層",
321
321
  "Show/hide layer": "顯示/隱藏圖層",
322
322
  "Side panel": "側邊框",
323
- "Simple link: [[https://example.com]]": "Simple link: [[https://example.com]]",
323
+ "Simple link: [[https://example.com]]": "簡單連結: [[https://example.com]]",
324
324
  "Simplify": "簡化",
325
325
  "Skipping unknown geometry.type: {type}": "略過不明的 geometry.type: {type}",
326
326
  "Slideshow": "投影片",
@@ -517,10 +517,12 @@ const locale = {
517
517
  "zoom to data extent": "切換至資料範圍",
518
518
  "download visible data": "下載可視資料",
519
519
  "{connectedPeers} peer(s) currently connected to this map": "這份地圖已經有 {connectedPeers} 伙伴連線",
520
- "Import helpers": "Import helpers",
521
- "Import helpers will fill the URL field for you.": "Import helpers will fill the URL field for you.",
522
- "Wikipedia": "Wikipedia",
523
- "Save draft": "Save draft"
520
+ "Import helpers": "匯入幫手",
521
+ "Import helpers will fill the URL field for you.": "匯入幫會為你填入網址",
522
+ "Wikipedia": "維基百科",
523
+ "Save draft": "儲存草稿",
524
+ "No data has been found for import": "匯入時沒有找到資料",
525
+ "Successfully imported {count} feature(s)": "成功匯入 {count} 圖徵"
524
526
  }
525
527
  L.registerLocale("zh_TW", locale)
526
528
  L.setLocale("zh_TW")