umap-project 2.4.1__py3-none-any.whl → 2.4.2__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.
- umap/__init__.py +1 -1
- umap/locale/el/LC_MESSAGES/django.po +145 -90
- umap/locale/en/LC_MESSAGES/django.po +13 -13
- umap/locale/eu/LC_MESSAGES/django.po +145 -89
- umap/static/umap/base.css +1 -1
- umap/static/umap/content.css +2 -2
- umap/static/umap/css/dialog.css +1 -1
- umap/static/umap/css/importers.css +2 -0
- umap/static/umap/css/panel.css +2 -2
- umap/static/umap/css/tooltip.css +1 -1
- umap/static/umap/js/components/alerts/alert.css +1 -1
- umap/static/umap/js/components/alerts/alert.js +1 -1
- umap/static/umap/js/modules/autocomplete.js +4 -4
- umap/static/umap/js/modules/browser.js +6 -6
- umap/static/umap/js/modules/caption.js +4 -4
- umap/static/umap/js/modules/dompurify.js +2 -3
- umap/static/umap/js/modules/facets.js +16 -10
- umap/static/umap/js/modules/global.js +16 -16
- umap/static/umap/js/modules/help.js +2 -2
- umap/static/umap/js/modules/importer.js +6 -6
- umap/static/umap/js/modules/importers/geodatamine.js +4 -4
- umap/static/umap/js/modules/importers/overpass.js +2 -2
- umap/static/umap/js/modules/orderable.js +2 -2
- umap/static/umap/js/modules/request.js +1 -1
- umap/static/umap/js/modules/rules.js +13 -10
- umap/static/umap/js/modules/sync/engine.js +3 -3
- umap/static/umap/js/modules/sync/updaters.js +10 -11
- umap/static/umap/js/modules/sync/websocket.js +1 -1
- umap/static/umap/js/modules/ui/dialog.js +1 -1
- umap/static/umap/js/modules/ui/panel.js +1 -1
- umap/static/umap/js/modules/ui/tooltip.js +6 -6
- umap/static/umap/js/modules/urls.js +1 -2
- umap/static/umap/js/modules/utils.js +16 -16
- umap/static/umap/js/umap.controls.js +26 -28
- umap/static/umap/js/umap.core.js +19 -15
- umap/static/umap/js/umap.datalayer.permissions.js +15 -18
- umap/static/umap/js/umap.features.js +91 -117
- umap/static/umap/js/umap.forms.js +46 -74
- umap/static/umap/js/umap.icon.js +17 -22
- umap/static/umap/js/umap.js +79 -83
- umap/static/umap/js/umap.layer.js +151 -169
- umap/static/umap/js/umap.permissions.js +6 -9
- umap/static/umap/js/umap.popup.js +19 -19
- umap/static/umap/js/umap.share.js +9 -15
- umap/static/umap/js/umap.slideshow.js +12 -14
- umap/static/umap/js/umap.tableeditor.js +5 -5
- umap/static/umap/locale/am_ET.json +5 -2
- umap/static/umap/locale/ar.json +5 -2
- umap/static/umap/locale/ast.json +5 -2
- umap/static/umap/locale/bg.json +5 -2
- umap/static/umap/locale/br.json +5 -2
- umap/static/umap/locale/ca.json +5 -2
- umap/static/umap/locale/cs_CZ.json +5 -2
- umap/static/umap/locale/da.json +5 -2
- umap/static/umap/locale/de.json +5 -2
- umap/static/umap/locale/el.json +10 -7
- umap/static/umap/locale/en.json +4 -2
- umap/static/umap/locale/en_US.json +5 -2
- umap/static/umap/locale/es.json +4 -2
- umap/static/umap/locale/et.json +5 -2
- umap/static/umap/locale/fa_IR.json +5 -2
- umap/static/umap/locale/fi.json +5 -2
- umap/static/umap/locale/fr.json +4 -2
- umap/static/umap/locale/gl.json +5 -2
- umap/static/umap/locale/he.json +5 -2
- umap/static/umap/locale/hr.json +5 -2
- umap/static/umap/locale/hu.json +5 -2
- umap/static/umap/locale/id.json +5 -2
- umap/static/umap/locale/is.json +5 -2
- umap/static/umap/locale/it.json +5 -2
- umap/static/umap/locale/ja.json +5 -2
- umap/static/umap/locale/ko.json +5 -2
- umap/static/umap/locale/lt.json +5 -2
- umap/static/umap/locale/ms.json +5 -2
- umap/static/umap/locale/nl.json +5 -2
- umap/static/umap/locale/no.json +5 -2
- umap/static/umap/locale/pl.json +5 -2
- umap/static/umap/locale/pl_PL.json +5 -2
- umap/static/umap/locale/pt.json +4 -2
- umap/static/umap/locale/pt_BR.json +5 -2
- umap/static/umap/locale/pt_PT.json +5 -2
- umap/static/umap/locale/ro.json +5 -2
- umap/static/umap/locale/ru.json +5 -2
- umap/static/umap/locale/sk_SK.json +5 -2
- umap/static/umap/locale/sl.json +5 -2
- umap/static/umap/locale/sr.json +5 -2
- umap/static/umap/locale/sv.json +5 -2
- umap/static/umap/locale/th_TH.json +5 -2
- umap/static/umap/locale/tr.json +5 -2
- umap/static/umap/locale/uk_UA.json +5 -2
- umap/static/umap/locale/vi.json +5 -2
- umap/static/umap/locale/vi_VN.json +5 -2
- umap/static/umap/locale/zh.json +5 -2
- umap/static/umap/locale/zh_CN.json +5 -2
- umap/static/umap/locale/zh_TW.Big5.json +5 -2
- umap/static/umap/locale/zh_TW.json +5 -2
- umap/static/umap/map.css +8 -9
- umap/static/umap/vars.css +10 -0
- umap/static/umap/vendors/dompurify/purify.es.js +5 -59
- umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +2 -2
- umap/storage.py +1 -1
- umap/tests/integration/test_map_preview.py +36 -2
- umap/tests/test_views.py +2 -2
- umap/views.py +3 -2
- {umap_project-2.4.1.dist-info → umap_project-2.4.2.dist-info}/METADATA +2 -2
- {umap_project-2.4.1.dist-info → umap_project-2.4.2.dist-info}/RECORD +110 -110
- {umap_project-2.4.1.dist-info → umap_project-2.4.2.dist-info}/WHEEL +0 -0
- {umap_project-2.4.1.dist-info → umap_project-2.4.2.dist-info}/entry_points.txt +0 -0
- {umap_project-2.4.1.dist-info → umap_project-2.4.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -18,7 +18,7 @@ export default class Caption {
|
|
|
18
18
|
|
|
19
19
|
open() {
|
|
20
20
|
const container = DomUtil.create('div', 'umap-caption')
|
|
21
|
-
const hgroup = DomUtil.element({tagName: 'hgroup', parent: container})
|
|
21
|
+
const hgroup = DomUtil.element({ tagName: 'hgroup', parent: container })
|
|
22
22
|
DomUtil.createTitle(hgroup, this.map.options.name, 'icon-caption icon-block')
|
|
23
23
|
this.map.permissions.addOwnerLink('h4', hgroup)
|
|
24
24
|
if (this.map.options.description) {
|
|
@@ -40,9 +40,9 @@ export default class Caption {
|
|
|
40
40
|
|
|
41
41
|
addDataLayer(datalayer, container) {
|
|
42
42
|
if (!datalayer.options.inCaption) return
|
|
43
|
-
const p = DomUtil.create('p', 'datalayer-legend', container)
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
const p = DomUtil.create('p', 'datalayer-legend', container)
|
|
44
|
+
const legend = DomUtil.create('span', '', p)
|
|
45
|
+
const headline = DomUtil.create('strong', '', p)
|
|
46
46
|
datalayer.onceLoaded(() => {
|
|
47
47
|
datalayer.renderLegend(legend)
|
|
48
48
|
if (datalayer.options.description) {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { default as DOMPurifyInitializer } from '../../vendors/dompurify/purify.es.js'
|
|
2
1
|
import { JSDOM } from 'jsdom'
|
|
2
|
+
import { default as DOMPurifyInitializer } from '../../vendors/dompurify/purify.es.js'
|
|
3
3
|
|
|
4
4
|
console.log(DOMPurifyInitializer)
|
|
5
5
|
|
|
6
6
|
export default function getPurify() {
|
|
7
7
|
if (typeof window === 'undefined') {
|
|
8
8
|
return DOMPurifyInitializer(new JSDOM('').window)
|
|
9
|
-
} else {
|
|
10
|
-
return DOMPurifyInitializer(window)
|
|
11
9
|
}
|
|
10
|
+
return DOMPurifyInitializer(window)
|
|
12
11
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
2
|
import { translate } from './i18n.js'
|
|
3
3
|
import * as Utils from './utils.js'
|
|
4
4
|
|
|
@@ -13,7 +13,7 @@ export default class Facets {
|
|
|
13
13
|
let selected
|
|
14
14
|
|
|
15
15
|
names.forEach((name) => {
|
|
16
|
-
const type = defined[name]
|
|
16
|
+
const type = defined[name].type
|
|
17
17
|
properties[name] = { type: type }
|
|
18
18
|
selected = this.selected[name] || {}
|
|
19
19
|
selected.type = type
|
|
@@ -28,17 +28,23 @@ export default class Facets {
|
|
|
28
28
|
datalayer.eachFeature((feature) => {
|
|
29
29
|
names.forEach((name) => {
|
|
30
30
|
let value = feature.properties[name]
|
|
31
|
-
const type = defined[name]
|
|
31
|
+
const type = defined[name].type
|
|
32
32
|
const parser = this.getParser(type)
|
|
33
33
|
value = parser(value)
|
|
34
34
|
switch (type) {
|
|
35
35
|
case 'date':
|
|
36
36
|
case 'datetime':
|
|
37
37
|
case 'number':
|
|
38
|
-
if (!isNaN(value)) {
|
|
38
|
+
if (!Number.isNaN(value)) {
|
|
39
|
+
// Special cases where we want to be lousy when checking isNaN without
|
|
40
|
+
// coercing to a Number first because we handle multiple types.
|
|
41
|
+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/
|
|
42
|
+
// Reference/Global_Objects/Number/isNaN
|
|
43
|
+
// biome-ignore lint/suspicious/noGlobalIsNan: see above.
|
|
39
44
|
if (isNaN(properties[name].min) || properties[name].min > value) {
|
|
40
45
|
properties[name].min = value
|
|
41
46
|
}
|
|
47
|
+
// biome-ignore lint/suspicious/noGlobalIsNan: see above.
|
|
42
48
|
if (isNaN(properties[name].max) || properties[name].max < value) {
|
|
43
49
|
properties[name].max = value
|
|
44
50
|
}
|
|
@@ -57,8 +63,8 @@ export default class Facets {
|
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
isActive() {
|
|
60
|
-
for (
|
|
61
|
-
if (min !== undefined || max
|
|
66
|
+
for (const { type, min, max, choices } of Object.values(this.selected)) {
|
|
67
|
+
if (min !== undefined || max !== undefined || choices?.length) {
|
|
62
68
|
return true
|
|
63
69
|
}
|
|
64
70
|
}
|
|
@@ -71,9 +77,9 @@ export default class Facets {
|
|
|
71
77
|
const facetProperties = this.compute(names, defined)
|
|
72
78
|
|
|
73
79
|
const fields = names.map((name) => {
|
|
74
|
-
|
|
80
|
+
const criteria = facetProperties[name]
|
|
75
81
|
let handler = 'FacetSearchChoices'
|
|
76
|
-
switch (criteria
|
|
82
|
+
switch (criteria.type) {
|
|
77
83
|
case 'number':
|
|
78
84
|
handler = 'FacetSearchNumber'
|
|
79
85
|
break
|
|
@@ -84,7 +90,7 @@ export default class Facets {
|
|
|
84
90
|
handler = 'FacetSearchDateTime'
|
|
85
91
|
break
|
|
86
92
|
}
|
|
87
|
-
|
|
93
|
+
const label = defined[name].label
|
|
88
94
|
return [
|
|
89
95
|
`selected.${name}`,
|
|
90
96
|
{
|
|
@@ -112,7 +118,7 @@ export default class Facets {
|
|
|
112
118
|
getParser(type) {
|
|
113
119
|
switch (type) {
|
|
114
120
|
case 'number':
|
|
115
|
-
return parseFloat
|
|
121
|
+
return Number.parseFloat
|
|
116
122
|
case 'datetime':
|
|
117
123
|
return (v) => new Date(v)
|
|
118
124
|
case 'date':
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
uMapAlert as Alert,
|
|
3
|
+
uMapAlertConflict as AlertConflict,
|
|
4
|
+
uMapAlertCreation as AlertCreation,
|
|
5
|
+
} from '../components/alerts/alert.js'
|
|
6
|
+
import { AjaxAutocomplete, AjaxAutocompleteMultiple } from './autocomplete.js'
|
|
2
7
|
import Browser from './browser.js'
|
|
3
|
-
import Facets from './facets.js'
|
|
4
8
|
import Caption from './caption.js'
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
9
|
+
import Facets from './facets.js'
|
|
10
|
+
import Help from './help.js'
|
|
11
|
+
import Importer from './importer.js'
|
|
12
|
+
import Orderable from './orderable.js'
|
|
13
|
+
import { HTTPError, NOKError, Request, RequestError, ServerRequest } from './request.js'
|
|
8
14
|
import Rules from './rules.js'
|
|
9
|
-
import * as Utils from './utils.js'
|
|
10
15
|
import { SCHEMA } from './schema.js'
|
|
11
|
-
import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js'
|
|
12
|
-
import { AjaxAutocomplete, AjaxAutocompleteMultiple } from './autocomplete.js'
|
|
13
|
-
import Orderable from './orderable.js'
|
|
14
|
-
import Importer from './importer.js'
|
|
15
|
-
import Help from './help.js'
|
|
16
16
|
import { SyncEngine } from './sync/engine.js'
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
import Dialog from './ui/dialog.js'
|
|
18
|
+
import { EditPanel, FullPanel, Panel } from './ui/panel.js'
|
|
19
|
+
import Tooltip from './ui/tooltip.js'
|
|
20
|
+
import URLs from './urls.js'
|
|
21
|
+
import * as Utils from './utils.js'
|
|
22
22
|
|
|
23
23
|
// Import modules and export them to the global scope.
|
|
24
24
|
// For the not yet module-compatible JS out there.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
2
|
import { translate } from './i18n.js'
|
|
3
3
|
|
|
4
4
|
const SHORTCUTS = {
|
|
@@ -191,7 +191,7 @@ export default class Help {
|
|
|
191
191
|
const container = DomUtil.add('div')
|
|
192
192
|
DomUtil.createTitle(container, translate('Help'))
|
|
193
193
|
// Special dynamic case. Do we still think this dialog is usefull ?
|
|
194
|
-
if (entries
|
|
194
|
+
if (entries === 'edit') {
|
|
195
195
|
DomUtil.element({
|
|
196
196
|
tagName: 'div',
|
|
197
197
|
className: 'umap-help-entry',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { translate } from './i18n.js'
|
|
1
|
+
import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
3
2
|
import { uMapAlert as Alert } from '../components/alerts/alert.js'
|
|
4
|
-
import
|
|
3
|
+
import { translate } from './i18n.js'
|
|
5
4
|
import { SCHEMA } from './schema.js'
|
|
5
|
+
import Dialog from './ui/dialog.js'
|
|
6
6
|
import * as Utils from './utils.js'
|
|
7
7
|
|
|
8
8
|
const TEMPLATE = `
|
|
@@ -179,12 +179,12 @@ export default class Importer {
|
|
|
179
179
|
this.format === 'umap' || !this.url
|
|
180
180
|
)
|
|
181
181
|
this.qs('[name=layer-name]').toggleAttribute('hidden', Boolean(this.layerId))
|
|
182
|
-
this.qs('#clear').toggleAttribute('hidden', !
|
|
182
|
+
this.qs('#clear').toggleAttribute('hidden', !this.layerId)
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
onFileChange(e) {
|
|
186
|
-
let type = ''
|
|
187
|
-
|
|
186
|
+
let type = ''
|
|
187
|
+
let newType
|
|
188
188
|
for (const file of e.target.files) {
|
|
189
189
|
newType = U.Utils.detectFileType(file)
|
|
190
190
|
if (!type && newType) type = newType
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
|
+
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
2
3
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
|
3
4
|
import { translate } from '../i18n.js'
|
|
4
5
|
import * as Utils from '../utils.js'
|
|
5
|
-
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
6
6
|
|
|
7
7
|
const BOUNDARY_TYPES = {
|
|
8
8
|
admin_6: 'département',
|
|
@@ -52,9 +52,9 @@ export class Importer {
|
|
|
52
52
|
container.innerHTML = TEMPLATE
|
|
53
53
|
const response = await importer.map.request.get(`${this.baseUrl}/themes`)
|
|
54
54
|
const select = container.querySelector('select')
|
|
55
|
-
if (response
|
|
55
|
+
if (response?.ok) {
|
|
56
56
|
const { themes } = await response.json()
|
|
57
|
-
themes.sort((a, b) => Utils.naturalSort(a['name:fr'], b
|
|
57
|
+
themes.sort((a, b) => Utils.naturalSort(a['name:fr'], b['name:fr']))
|
|
58
58
|
for (const theme of themes) {
|
|
59
59
|
DomUtil.element({
|
|
60
60
|
tagName: 'option',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
|
+
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
2
3
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
|
3
4
|
import { translate } from '../i18n.js'
|
|
4
|
-
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
5
5
|
|
|
6
6
|
const TEMPLATE = `
|
|
7
7
|
<h3>Overpass</h3>
|
|
@@ -68,7 +68,7 @@ export class Importer {
|
|
|
68
68
|
if (!tags.startsWith('[')) tags = `[${tags}]`
|
|
69
69
|
let area = '{south},{west},{north},{east}'
|
|
70
70
|
if (boundary) area = `area:${boundary}`
|
|
71
|
-
|
|
71
|
+
const query = `[out:json];nwr${tags}(${area});out ${outMode};`
|
|
72
72
|
importer.url = `${this.baseUrl}?data=${query}`
|
|
73
73
|
if (boundary) importer.layerName = boundaryName
|
|
74
74
|
importer.format = 'osm'
|
|
@@ -59,8 +59,8 @@ export default class Orderable {
|
|
|
59
59
|
const dst = this.findTarget(e.target)
|
|
60
60
|
if (!dst || dst === this.src) return
|
|
61
61
|
this.dst = dst
|
|
62
|
-
const targetIndex = this.nodeIndex(this.dst)
|
|
63
|
-
|
|
62
|
+
const targetIndex = this.nodeIndex(this.dst)
|
|
63
|
+
const srcIndex = this.nodeIndex(this.src)
|
|
64
64
|
if (targetIndex > srcIndex) this.parent.insertBefore(this.dst, this.src)
|
|
65
65
|
else this.parent.insertBefore(this.src, this.dst)
|
|
66
66
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as Utils from './utils.js'
|
|
1
|
+
import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
3
2
|
import { translate } from './i18n.js'
|
|
3
|
+
import * as Utils from './utils.js'
|
|
4
4
|
|
|
5
5
|
class Rule {
|
|
6
|
-
|
|
7
6
|
get condition() {
|
|
8
7
|
return this._condition
|
|
9
8
|
}
|
|
@@ -13,7 +12,6 @@ class Rule {
|
|
|
13
12
|
this.parse()
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
|
|
17
15
|
get isDirty() {
|
|
18
16
|
return this._isDirty
|
|
19
17
|
}
|
|
@@ -51,7 +49,7 @@ class Rule {
|
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
not_equal(other) {
|
|
54
|
-
return this.expected
|
|
52
|
+
return this.expected !== other
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
gt(other) {
|
|
@@ -73,10 +71,15 @@ class Rule {
|
|
|
73
71
|
break
|
|
74
72
|
}
|
|
75
73
|
}
|
|
76
|
-
if (vars.length
|
|
74
|
+
if (vars.length !== 2) return
|
|
77
75
|
this.key = vars[0]
|
|
78
76
|
this.expected = vars[1]
|
|
79
|
-
|
|
77
|
+
// Special cases where we want to be lousy when checking isNaN without
|
|
78
|
+
// coercing to a Number first because we handle multiple types.
|
|
79
|
+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/
|
|
80
|
+
// Reference/Global_Objects/Number/isNaN
|
|
81
|
+
// biome-ignore lint/suspicious/noGlobalIsNan: expected might not be a number.
|
|
82
|
+
if (!isNaN(this.expected)) this.cast = Number.parseFloat
|
|
80
83
|
else if (['true', 'false'].includes(this.expected)) this.cast = (v) => !!v
|
|
81
84
|
this.expected = this.cast(this.expected)
|
|
82
85
|
}
|
|
@@ -163,7 +166,7 @@ class Rule {
|
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
_delete() {
|
|
166
|
-
this.map.rules.rules = this.map.rules.rules.filter((rule) => rule
|
|
169
|
+
this.map.rules.rules = this.map.rules.rules.filter((rule) => rule !== this)
|
|
167
170
|
}
|
|
168
171
|
}
|
|
169
172
|
|
|
@@ -183,8 +186,8 @@ export default class Rules {
|
|
|
183
186
|
}
|
|
184
187
|
|
|
185
188
|
onReorder(src, dst, initialIndex, finalIndex) {
|
|
186
|
-
const moved = this.rules.find((rule) => stamp(rule)
|
|
187
|
-
const reference = this.rules.find((rule) => stamp(rule)
|
|
189
|
+
const moved = this.rules.find((rule) => stamp(rule) === src.dataset.id)
|
|
190
|
+
const reference = this.rules.find((rule) => stamp(rule) === dst.dataset.id)
|
|
188
191
|
const movedIdx = this.rules.indexOf(moved)
|
|
189
192
|
let referenceIdx = this.rules.indexOf(reference)
|
|
190
193
|
const minIndex = Math.min(movedIdx, referenceIdx)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { DataLayerUpdater, FeatureUpdater, MapUpdater } from './updaters.js'
|
|
1
2
|
import { WebSocketTransport } from './websocket.js'
|
|
2
|
-
import { MapUpdater, DataLayerUpdater, FeatureUpdater } from './updaters.js'
|
|
3
3
|
|
|
4
4
|
export class SyncEngine {
|
|
5
5
|
constructor(map) {
|
|
@@ -36,8 +36,8 @@ export class SyncEngine {
|
|
|
36
36
|
|
|
37
37
|
// This method is called by the transport layer on new messages
|
|
38
38
|
receive({ kind, ...payload }) {
|
|
39
|
-
if (kind
|
|
40
|
-
|
|
39
|
+
if (kind === 'operation') {
|
|
40
|
+
const updater = this._getUpdater(payload.subject, payload.metadata)
|
|
41
41
|
updater.applyMessage(payload)
|
|
42
42
|
} else {
|
|
43
43
|
throw new Error(`Unknown dispatch kind: ${kind}`)
|
|
@@ -35,7 +35,7 @@ class BaseUpdater {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
applyMessage(payload) {
|
|
38
|
-
|
|
38
|
+
const { verb } = payload
|
|
39
39
|
return this[verb](payload)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -69,7 +69,7 @@ export class FeatureUpdater extends BaseUpdater {
|
|
|
69
69
|
|
|
70
70
|
// Create or update an object at a specific position
|
|
71
71
|
upsert({ metadata, value }) {
|
|
72
|
-
|
|
72
|
+
const { id, layerId } = metadata
|
|
73
73
|
const datalayer = this.getDataLayerFromID(layerId)
|
|
74
74
|
let feature = this.getFeatureFromMetadata(metadata, value)
|
|
75
75
|
|
|
@@ -84,17 +84,16 @@ export class FeatureUpdater extends BaseUpdater {
|
|
|
84
84
|
|
|
85
85
|
// Update a property of an object
|
|
86
86
|
update({ key, metadata, value }) {
|
|
87
|
-
|
|
87
|
+
const feature = this.getFeatureFromMetadata(metadata)
|
|
88
88
|
if (feature === undefined) {
|
|
89
89
|
console.error(`Unable to find feature with id = ${metadata.id}.`)
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
feature.datalayer.indexProperties(feature)
|
|
91
|
+
if (key === 'geometry') {
|
|
92
|
+
const datalayer = this.getDataLayerFromID(metadata.layerId)
|
|
93
|
+
datalayer.geoJSONToLeaflet({ geometry: value, id: metadata.id, feature })
|
|
94
|
+
} else {
|
|
95
|
+
this.updateObjectValue(feature, key, value)
|
|
96
|
+
feature.datalayer.indexProperties(feature)
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
feature.render([key])
|
|
@@ -103,7 +102,7 @@ export class FeatureUpdater extends BaseUpdater {
|
|
|
103
102
|
delete({ metadata }) {
|
|
104
103
|
// XXX Distinguish between properties getting deleted
|
|
105
104
|
// and the wole feature getting deleted
|
|
106
|
-
|
|
105
|
+
const feature = this.getFeatureFromMetadata(metadata)
|
|
107
106
|
if (feature) feature.del(false)
|
|
108
107
|
}
|
|
109
108
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
2
|
import { translate } from '../i18n.js'
|
|
3
3
|
|
|
4
4
|
export default class Tooltip {
|
|
@@ -34,7 +34,7 @@ export default class Tooltip {
|
|
|
34
34
|
if (opts.anchor) {
|
|
35
35
|
L.DomEvent.once(opts.anchor, 'mouseout', closeIt)
|
|
36
36
|
}
|
|
37
|
-
if (opts.duration !==
|
|
37
|
+
if (opts.duration !== Number.POSITIVE_INFINITY) {
|
|
38
38
|
window.setTimeout(closeIt, opts.duration || 3000)
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -42,10 +42,10 @@ export default class Tooltip {
|
|
|
42
42
|
anchorAbsolute() {
|
|
43
43
|
this.container.className = ''
|
|
44
44
|
const left =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
this.parent.offsetLeft +
|
|
46
|
+
this.parent.clientWidth / 2 -
|
|
47
|
+
this.container.clientWidth / 2
|
|
48
|
+
const top = this.parent.offsetTop + 75
|
|
49
49
|
this.setPosition({ top: top, left: left })
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -10,9 +10,8 @@ export default class URLs {
|
|
|
10
10
|
|
|
11
11
|
if (this.urls.hasOwnProperty(urlName)) {
|
|
12
12
|
return template(this.urls[urlName], params)
|
|
13
|
-
} else {
|
|
14
|
-
throw `Unable to find a URL for route ${urlName}`
|
|
15
13
|
}
|
|
14
|
+
throw `Unable to find a URL for route ${urlName}`
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
// Update if map_id is passed, create otherwise.
|
|
@@ -36,7 +36,7 @@ export function checkId(string) {
|
|
|
36
36
|
*/
|
|
37
37
|
export function getImpactsFromSchema(fields, schema) {
|
|
38
38
|
schema = schema || U.SCHEMA
|
|
39
|
-
|
|
39
|
+
const impacted = fields
|
|
40
40
|
.map((field) => {
|
|
41
41
|
// remove the option prefix for fields
|
|
42
42
|
// And only keep the first part in case of a subfield
|
|
@@ -63,9 +63,8 @@ export function getImpactsFromSchema(fields, schema) {
|
|
|
63
63
|
export default function getPurify() {
|
|
64
64
|
if (typeof window === 'undefined') {
|
|
65
65
|
return DOMPurifyInitializer(new global.JSDOM('').window)
|
|
66
|
-
} else {
|
|
67
|
-
return DOMPurifyInitializer(window)
|
|
68
66
|
}
|
|
67
|
+
return DOMPurifyInitializer(window)
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
export function escapeHTML(s) {
|
|
@@ -114,13 +113,13 @@ export function escapeHTML(s) {
|
|
|
114
113
|
|
|
115
114
|
export function toHTML(r, options) {
|
|
116
115
|
if (!r) return ''
|
|
117
|
-
const target =
|
|
116
|
+
const target = options?.target || 'blank'
|
|
118
117
|
|
|
119
118
|
// unordered lists
|
|
120
119
|
r = r.replace(/^\*\* (.*)/gm, '<ul><ul><li>$1</li></ul></ul>')
|
|
121
120
|
r = r.replace(/^\* (.*)/gm, '<ul><li>$1</li></ul>')
|
|
122
121
|
for (let ii = 0; ii < 3; ii++) {
|
|
123
|
-
r = r.replace(
|
|
122
|
+
r = r.replace(/<\/ul>(\r\n|\r|\n)<ul>/g, '')
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
// headings and hr
|
|
@@ -271,8 +270,8 @@ export function sortFeatures(features, sortKey, lang) {
|
|
|
271
270
|
const sortKeys = (sortKey || 'name').split(',')
|
|
272
271
|
|
|
273
272
|
const sort = (a, b, i) => {
|
|
274
|
-
let sortKey = sortKeys[i]
|
|
275
|
-
|
|
273
|
+
let sortKey = sortKeys[i]
|
|
274
|
+
let reverse = 1
|
|
276
275
|
if (sortKey[0] === '-') {
|
|
277
276
|
reverse = -1
|
|
278
277
|
sortKey = sortKey.substring(1)
|
|
@@ -315,19 +314,19 @@ export function getBaseUrl() {
|
|
|
315
314
|
}
|
|
316
315
|
|
|
317
316
|
export function hasVar(value) {
|
|
318
|
-
return typeof value === 'string' && value.indexOf('{')
|
|
317
|
+
return typeof value === 'string' && value.indexOf('{') !== -1
|
|
319
318
|
}
|
|
320
319
|
|
|
321
320
|
export function isPath(value) {
|
|
322
|
-
return value
|
|
321
|
+
return value?.length && value.startsWith('/')
|
|
323
322
|
}
|
|
324
323
|
|
|
325
324
|
export function isRemoteUrl(value) {
|
|
326
|
-
return value
|
|
325
|
+
return value?.length && value.startsWith('http')
|
|
327
326
|
}
|
|
328
327
|
|
|
329
328
|
export function isDataImage(value) {
|
|
330
|
-
return value
|
|
329
|
+
return value?.length && value.startsWith('data:image')
|
|
331
330
|
}
|
|
332
331
|
|
|
333
332
|
/**
|
|
@@ -349,15 +348,16 @@ export function normalize(s) {
|
|
|
349
348
|
|
|
350
349
|
// Vendorized from leaflet.utils
|
|
351
350
|
// https://github.com/Leaflet/Leaflet/blob/108c6717b70f57c63645498f9bd66b6677758786/src/core/Util.js#L132-L151
|
|
352
|
-
|
|
351
|
+
const templateRe = /\{ *([\w_ -]+) *\}/g
|
|
353
352
|
|
|
354
353
|
export function template(str, data) {
|
|
355
|
-
return str.replace(templateRe,
|
|
356
|
-
|
|
354
|
+
return str.replace(templateRe, (str, key) => {
|
|
355
|
+
let value = data[key]
|
|
357
356
|
|
|
358
357
|
if (value === undefined) {
|
|
359
|
-
throw new Error(
|
|
360
|
-
}
|
|
358
|
+
throw new Error(`No value provided for variable ${str}`)
|
|
359
|
+
}
|
|
360
|
+
if (typeof value === 'function') {
|
|
361
361
|
value = value(data)
|
|
362
362
|
}
|
|
363
363
|
return value
|