umap-project 2.1.3__py3-none-any.whl → 2.2.0b0__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 (196) hide show
  1. umap/__init__.py +1 -1
  2. umap/context_processors.py +1 -0
  3. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/en/LC_MESSAGES/django.po +32 -32
  5. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  8. umap/migrations/0020_alter_tilelayer_url_template.py +19 -0
  9. umap/migrations/0021_remove_map_description.py +16 -0
  10. umap/models.py +8 -6
  11. umap/settings/base.py +1 -0
  12. umap/static/umap/base.css +29 -151
  13. umap/static/umap/content.css +7 -25
  14. umap/static/umap/css/icon.css +112 -0
  15. umap/static/umap/css/panel.css +140 -0
  16. umap/static/umap/img/16-white.svg +5 -1
  17. umap/static/umap/img/16.svg +7 -4
  18. umap/static/umap/img/24-white.svg +3 -1
  19. umap/static/umap/img/24.svg +3 -4
  20. umap/static/umap/img/source/16-white.svg +176 -940
  21. umap/static/umap/img/source/16.svg +8 -5
  22. umap/static/umap/img/source/24-white.svg +5 -3
  23. umap/static/umap/img/source/24.svg +6 -7
  24. umap/static/umap/js/modules/browser.js +82 -73
  25. umap/static/umap/js/modules/dompurify.js +12 -0
  26. umap/static/umap/js/modules/facets.js +148 -0
  27. umap/static/umap/js/modules/global.js +9 -1
  28. umap/static/umap/js/modules/i18n.js +7 -0
  29. umap/static/umap/js/modules/orderable.js +84 -0
  30. umap/static/umap/js/modules/panel.js +76 -0
  31. umap/static/umap/js/modules/request.js +0 -1
  32. umap/static/umap/js/modules/schema.js +324 -223
  33. umap/static/umap/js/modules/urls.js +1 -16
  34. umap/static/umap/js/modules/utils.js +340 -0
  35. umap/static/umap/js/umap.controls.js +183 -330
  36. umap/static/umap/js/umap.core.js +60 -364
  37. umap/static/umap/js/umap.datalayer.permissions.js +1 -1
  38. umap/static/umap/js/umap.features.js +60 -40
  39. umap/static/umap/js/umap.forms.js +111 -25
  40. umap/static/umap/js/umap.icon.js +11 -4
  41. umap/static/umap/js/umap.importer.js +24 -17
  42. umap/static/umap/js/umap.js +170 -145
  43. umap/static/umap/js/umap.layer.js +71 -40
  44. umap/static/umap/js/umap.permissions.js +9 -11
  45. umap/static/umap/js/umap.popup.js +10 -21
  46. umap/static/umap/js/umap.share.js +11 -8
  47. umap/static/umap/js/umap.tableeditor.js +4 -6
  48. umap/static/umap/js/umap.ui.js +0 -51
  49. umap/static/umap/locale/am_ET.js +242 -227
  50. umap/static/umap/locale/am_ET.json +18 -7
  51. umap/static/umap/locale/ar.js +242 -227
  52. umap/static/umap/locale/ar.json +18 -7
  53. umap/static/umap/locale/ast.js +242 -227
  54. umap/static/umap/locale/ast.json +18 -7
  55. umap/static/umap/locale/bg.js +242 -227
  56. umap/static/umap/locale/bg.json +18 -7
  57. umap/static/umap/locale/br.js +252 -237
  58. umap/static/umap/locale/br.json +22 -11
  59. umap/static/umap/locale/ca.js +242 -227
  60. umap/static/umap/locale/ca.json +18 -7
  61. umap/static/umap/locale/cs_CZ.js +242 -227
  62. umap/static/umap/locale/cs_CZ.json +18 -7
  63. umap/static/umap/locale/da.js +242 -227
  64. umap/static/umap/locale/da.json +18 -7
  65. umap/static/umap/locale/de.js +242 -227
  66. umap/static/umap/locale/de.json +18 -7
  67. umap/static/umap/locale/el.js +242 -227
  68. umap/static/umap/locale/el.json +18 -7
  69. umap/static/umap/locale/en.js +242 -234
  70. umap/static/umap/locale/en.json +19 -8
  71. umap/static/umap/locale/en_US.json +18 -7
  72. umap/static/umap/locale/es.js +242 -227
  73. umap/static/umap/locale/es.json +18 -7
  74. umap/static/umap/locale/et.js +242 -227
  75. umap/static/umap/locale/et.json +18 -7
  76. umap/static/umap/locale/eu.js +227 -199
  77. umap/static/umap/locale/eu.json +1 -1
  78. umap/static/umap/locale/fa_IR.js +242 -227
  79. umap/static/umap/locale/fa_IR.json +18 -7
  80. umap/static/umap/locale/fi.js +242 -227
  81. umap/static/umap/locale/fi.json +18 -7
  82. umap/static/umap/locale/fr.js +242 -234
  83. umap/static/umap/locale/fr.json +18 -7
  84. umap/static/umap/locale/gl.js +242 -227
  85. umap/static/umap/locale/gl.json +18 -7
  86. umap/static/umap/locale/he.js +242 -227
  87. umap/static/umap/locale/he.json +18 -7
  88. umap/static/umap/locale/hr.js +242 -227
  89. umap/static/umap/locale/hr.json +18 -7
  90. umap/static/umap/locale/hu.js +242 -234
  91. umap/static/umap/locale/hu.json +18 -7
  92. umap/static/umap/locale/id.js +242 -227
  93. umap/static/umap/locale/id.json +18 -7
  94. umap/static/umap/locale/is.js +242 -227
  95. umap/static/umap/locale/is.json +18 -7
  96. umap/static/umap/locale/it.js +242 -234
  97. umap/static/umap/locale/it.json +18 -7
  98. umap/static/umap/locale/ja.js +242 -227
  99. umap/static/umap/locale/ja.json +18 -7
  100. umap/static/umap/locale/ko.js +242 -227
  101. umap/static/umap/locale/ko.json +18 -7
  102. umap/static/umap/locale/lt.js +242 -227
  103. umap/static/umap/locale/lt.json +18 -7
  104. umap/static/umap/locale/ms.js +242 -234
  105. umap/static/umap/locale/ms.json +19 -8
  106. umap/static/umap/locale/nl.js +245 -230
  107. umap/static/umap/locale/nl.json +18 -7
  108. umap/static/umap/locale/no.js +242 -227
  109. umap/static/umap/locale/no.json +18 -7
  110. umap/static/umap/locale/pl.js +242 -227
  111. umap/static/umap/locale/pl.json +18 -7
  112. umap/static/umap/locale/pl_PL.json +18 -7
  113. umap/static/umap/locale/pt.js +242 -227
  114. umap/static/umap/locale/pt.json +18 -7
  115. umap/static/umap/locale/pt_BR.js +242 -227
  116. umap/static/umap/locale/pt_BR.json +18 -7
  117. umap/static/umap/locale/pt_PT.js +242 -227
  118. umap/static/umap/locale/pt_PT.json +18 -7
  119. umap/static/umap/locale/ro.js +242 -227
  120. umap/static/umap/locale/ro.json +18 -7
  121. umap/static/umap/locale/ru.js +242 -227
  122. umap/static/umap/locale/ru.json +18 -7
  123. umap/static/umap/locale/si.js +1 -1
  124. umap/static/umap/locale/si.json +1 -1
  125. umap/static/umap/locale/sk_SK.js +242 -227
  126. umap/static/umap/locale/sk_SK.json +18 -7
  127. umap/static/umap/locale/sl.js +242 -227
  128. umap/static/umap/locale/sl.json +18 -7
  129. umap/static/umap/locale/sr.js +242 -227
  130. umap/static/umap/locale/sr.json +18 -7
  131. umap/static/umap/locale/sv.js +242 -227
  132. umap/static/umap/locale/sv.json +18 -7
  133. umap/static/umap/locale/th_TH.js +242 -227
  134. umap/static/umap/locale/th_TH.json +18 -7
  135. umap/static/umap/locale/tr.js +242 -227
  136. umap/static/umap/locale/tr.json +18 -7
  137. umap/static/umap/locale/uk_UA.js +242 -227
  138. umap/static/umap/locale/uk_UA.json +18 -7
  139. umap/static/umap/locale/vi.js +242 -227
  140. umap/static/umap/locale/vi.json +18 -7
  141. umap/static/umap/locale/vi_VN.json +18 -7
  142. umap/static/umap/locale/zh.js +242 -227
  143. umap/static/umap/locale/zh.json +18 -7
  144. umap/static/umap/locale/zh_CN.json +18 -7
  145. umap/static/umap/locale/zh_TW.Big5.json +18 -7
  146. umap/static/umap/locale/zh_TW.js +242 -234
  147. umap/static/umap/locale/zh_TW.json +18 -7
  148. umap/static/umap/map.css +114 -265
  149. umap/static/umap/test/DataLayer.js +463 -0
  150. umap/static/umap/test/Feature.js +0 -226
  151. umap/static/umap/test/TableEditor.js +104 -0
  152. umap/static/umap/test/Util.js +0 -521
  153. umap/static/umap/test/index.html +0 -1
  154. umap/static/umap/unittests/URLs.js +1 -1
  155. umap/static/umap/unittests/utils.js +610 -0
  156. umap/static/umap/vars.css +9 -0
  157. umap/static/umap/vendors/dompurify/purify.es.mjs +1525 -0
  158. umap/static/umap/vendors/iconlayers/iconLayers.js +1 -1
  159. umap/templates/umap/css.html +2 -0
  160. umap/templates/umap/js.html +0 -1
  161. umap/templates/umap/map_detail.html +4 -0
  162. umap/templates/umap/map_table.html +12 -10
  163. umap/templatetags/umap_tags.py +5 -0
  164. umap/tests/integration/conftest.py +12 -1
  165. umap/tests/integration/test_anonymous_owned_map.py +6 -5
  166. umap/tests/integration/test_browser.py +12 -25
  167. umap/tests/integration/test_choropleth.py +1 -1
  168. umap/tests/integration/test_dashboard.py +10 -0
  169. umap/tests/integration/test_datalayer.py +8 -6
  170. umap/tests/integration/test_edit_datalayer.py +24 -19
  171. umap/tests/integration/test_edit_map.py +182 -2
  172. umap/tests/integration/test_edit_marker.py +120 -0
  173. umap/tests/integration/test_edit_polygon.py +122 -0
  174. umap/tests/integration/test_facets_browser.py +104 -14
  175. umap/tests/integration/test_import.py +70 -20
  176. umap/tests/integration/test_map.py +19 -17
  177. umap/tests/integration/test_map_list.py +28 -0
  178. umap/tests/integration/test_owned_map.py +10 -10
  179. umap/tests/integration/test_picto.py +5 -5
  180. umap/tests/integration/test_querystring.py +9 -15
  181. umap/tests/integration/test_slideshow.py +0 -5
  182. umap/tests/integration/test_statics.py +3 -2
  183. umap/tests/integration/test_tableeditor.py +1 -5
  184. umap/tests/integration/test_view_marker.py +64 -0
  185. umap/tests/integration/test_view_polygon.py +59 -0
  186. umap/tests/integration/test_view_polyline.py +51 -0
  187. umap/tests/test_map_views.py +13 -0
  188. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/METADATA +8 -8
  189. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/RECORD +194 -178
  190. umap/static/umap/vendors/dompurify/purify.min.js +0 -3
  191. umap/static/umap/vendors/dompurify/purify.min.js.map +0 -1
  192. /umap/tests/integration/{test_polygon.py → test_draw_polygon.py} +0 -0
  193. /umap/tests/integration/{test_polyline.py → test_draw_polyline.py} +0 -0
  194. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/WHEEL +0 -0
  195. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/entry_points.txt +0 -0
  196. {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,610 @@
1
+ import { describe, it } from 'mocha'
2
+ import * as Utils from '../js/modules/utils.js'
3
+ import pkg from 'chai'
4
+ const { assert, expect } = pkg
5
+
6
+ // Export JSDOM to the global namespace, to be able to check for its presence
7
+ // in the actual implementation. Avoiding monkeypatching the implementations here.
8
+ import { JSDOM } from 'jsdom'
9
+ global.JSDOM = JSDOM
10
+
11
+ describe('Utils', function () {
12
+ describe('#toHTML()', function () {
13
+ it('should handle title', function () {
14
+ assert.equal(Utils.toHTML('# A title'), '<h3>A title</h3>')
15
+ })
16
+
17
+ it('should handle title in the middle of the content', function () {
18
+ assert.equal(
19
+ Utils.toHTML('A phrase\n## A title'),
20
+ 'A phrase<br>\n<h4>A title</h4>'
21
+ )
22
+ })
23
+
24
+ it('should handle hr', function () {
25
+ assert.equal(Utils.toHTML('---'), '<hr>')
26
+ })
27
+
28
+ it('should handle bold', function () {
29
+ assert.equal(Utils.toHTML('Some **bold**'), 'Some <strong>bold</strong>')
30
+ })
31
+
32
+ it('should handle italic', function () {
33
+ assert.equal(Utils.toHTML('Some *italic*'), 'Some <em>italic</em>')
34
+ })
35
+
36
+ it('should handle newlines', function () {
37
+ assert.equal(Utils.toHTML('two\nlines'), 'two<br>\nlines')
38
+ })
39
+
40
+ it('should not change last newline', function () {
41
+ assert.equal(Utils.toHTML('two\nlines\n'), 'two<br>\nlines\n')
42
+ })
43
+
44
+ it('should handle two successive newlines', function () {
45
+ assert.equal(Utils.toHTML('two\n\nlines\n'), 'two<br>\n<br>\nlines\n')
46
+ })
47
+
48
+ it('should handle links without formatting', function () {
49
+ assert.equal(
50
+ Utils.toHTML('A simple http://osm.org link'),
51
+ 'A simple <a href="http://osm.org" target="_blank">http://osm.org</a> link'
52
+ )
53
+ })
54
+
55
+ it('should handle simple link in title', function () {
56
+ assert.equal(
57
+ Utils.toHTML('# http://osm.org'),
58
+ '<h3><a href="http://osm.org" target="_blank">http://osm.org</a></h3>'
59
+ )
60
+ })
61
+
62
+ it('should handle links with url parameter', function () {
63
+ assert.equal(
64
+ Utils.toHTML('A simple https://osm.org/?url=https%3A//anotherurl.com link'),
65
+ 'A simple <a href="https://osm.org/?url=https%3A//anotherurl.com" target="_blank">https://osm.org/?url=https%3A//anotherurl.com</a> link'
66
+ )
67
+ })
68
+
69
+ it('should handle simple link inside parenthesis', function () {
70
+ assert.equal(
71
+ Utils.toHTML('A simple link (http://osm.org)'),
72
+ 'A simple link (<a href="http://osm.org" target="_blank">http://osm.org</a>)'
73
+ )
74
+ })
75
+
76
+ it('should handle simple link with formatting', function () {
77
+ assert.equal(
78
+ Utils.toHTML('A simple [[http://osm.org]] link'),
79
+ 'A simple <a href="http://osm.org" target="_blank">http://osm.org</a> link'
80
+ )
81
+ })
82
+
83
+ it('should handle simple link with formatting and content', function () {
84
+ assert.equal(
85
+ Utils.toHTML('A simple [[http://osm.org|link]]'),
86
+ 'A simple <a href="http://osm.org" target="_blank">link</a>'
87
+ )
88
+ })
89
+
90
+ it('should handle simple link followed by a carriage return', function () {
91
+ assert.equal(
92
+ Utils.toHTML('A simple link http://osm.org\nAnother line'),
93
+ 'A simple link <a href="http://osm.org" target="_blank">http://osm.org</a><br>\nAnother line'
94
+ )
95
+ })
96
+
97
+ it('should handle target option', function () {
98
+ assert.equal(
99
+ Utils.toHTML('A simple http://osm.org link', { target: 'self' }),
100
+ 'A simple <a href="http://osm.org" target="_self">http://osm.org</a> link'
101
+ )
102
+ })
103
+
104
+ it('should handle image', function () {
105
+ assert.equal(
106
+ Utils.toHTML('A simple image: {{http://osm.org/pouet.png}}'),
107
+ 'A simple image: <img src="http://osm.org/pouet.png">'
108
+ )
109
+ })
110
+
111
+ it('should handle image without text', function () {
112
+ assert.equal(
113
+ Utils.toHTML('{{http://osm.org/pouet.png}}'),
114
+ '<img src="http://osm.org/pouet.png">'
115
+ )
116
+ })
117
+
118
+ it('should handle image with width', function () {
119
+ assert.equal(
120
+ Utils.toHTML('A simple image: {{http://osm.org/pouet.png|100}}'),
121
+ 'A simple image: <img style="width:100px;min-width:100px;" src="http://osm.org/pouet.png">'
122
+ )
123
+ })
124
+
125
+ it('should handle iframe', function () {
126
+ assert.equal(
127
+ Utils.toHTML('A simple iframe: {{{http://osm.org/pouet.html}}}'),
128
+ 'A simple iframe: <div><iframe height="300px" width="100%" src="http://osm.org/pouet.html" frameborder="0"></iframe></div>'
129
+ )
130
+ })
131
+
132
+ it('should handle iframe with height', function () {
133
+ assert.equal(
134
+ Utils.toHTML('A simple iframe: {{{http://osm.org/pouet.html|200}}}'),
135
+ 'A simple iframe: <div><iframe height="200px" width="100%" src="http://osm.org/pouet.html" frameborder="0"></iframe></div>'
136
+ )
137
+ })
138
+
139
+ it('should handle iframe with height and width', function () {
140
+ assert.equal(
141
+ Utils.toHTML('A simple iframe: {{{http://osm.org/pouet.html|200*400}}}'),
142
+ 'A simple iframe: <div><iframe height="200px" width="400px" src="http://osm.org/pouet.html" frameborder="0"></iframe></div>'
143
+ )
144
+ })
145
+
146
+ it('should handle iframe with height with px', function () {
147
+ assert.equal(
148
+ Utils.toHTML('A simple iframe: {{{http://osm.org/pouet.html|200px}}}'),
149
+ 'A simple iframe: <div><iframe height="200px" width="100%" src="http://osm.org/pouet.html" frameborder="0"></iframe></div>'
150
+ )
151
+ })
152
+
153
+ it('should handle iframe with url parameter', function () {
154
+ assert.equal(
155
+ Utils.toHTML(
156
+ 'A simple iframe: {{{https://osm.org/?url=https%3A//anotherurl.com}}}'
157
+ ),
158
+ 'A simple iframe: <div><iframe height="300px" width="100%" src="https://osm.org/?url=https%3A//anotherurl.com" frameborder="0"></iframe></div>'
159
+ )
160
+ })
161
+
162
+ it('should handle iframe with height with px', function () {
163
+ assert.equal(
164
+ Utils.toHTML(
165
+ 'A double iframe: {{{https://osm.org/pouet}}}{{{https://osm.org/boudin}}}'
166
+ ),
167
+ 'A double iframe: <div><iframe height="300px" width="100%" src="https://osm.org/pouet" frameborder="0"></iframe></div><div><iframe height="300px" width="100%" src="https://osm.org/boudin" frameborder="0"></iframe></div>'
168
+ )
169
+ })
170
+
171
+ it('http link with http link as parameter as variable', function () {
172
+ assert.equal(
173
+ Utils.toHTML('A phrase with a [[http://iframeurl.com?to=http://another.com]].'),
174
+ 'A phrase with a <a href="http://iframeurl.com?to=http://another.com" target="_blank">http://iframeurl.com?to=http://another.com</a>.'
175
+ )
176
+ })
177
+ })
178
+
179
+ describe('#escapeHTML', function () {
180
+ it('should escape HTML tags', function () {
181
+ assert.equal(Utils.escapeHTML('<span onload="alert(oups)">'), '<span></span>')
182
+ })
183
+
184
+ it('should not escape geo: links', function () {
185
+ assert.equal(Utils.escapeHTML('<a href="geo:1,2"></a>'), '<a href="geo:1,2"></a>')
186
+ })
187
+
188
+ it('should not fail with int value', function () {
189
+ assert.equal(Utils.escapeHTML(25), '25')
190
+ })
191
+
192
+ it('should not fail with null value', function () {
193
+ assert.equal(Utils.escapeHTML(null), '')
194
+ })
195
+ })
196
+
197
+ describe('#greedyTemplate', function () {
198
+ it('should replace simple props', function () {
199
+ assert.equal(
200
+ Utils.greedyTemplate('A phrase with a {variable}.', { variable: 'thing' }),
201
+ 'A phrase with a thing.'
202
+ )
203
+ })
204
+
205
+ it('should not fail when missing key', function () {
206
+ assert.equal(
207
+ Utils.greedyTemplate('A phrase with a {missing}', {}),
208
+ 'A phrase with a '
209
+ )
210
+ })
211
+
212
+ it('should process brakets in brakets', function () {
213
+ assert.equal(
214
+ Utils.greedyTemplate('A phrase with a {{{variable}}}.', { variable: 'value' }),
215
+ 'A phrase with a {{value}}.'
216
+ )
217
+ })
218
+
219
+ it('should not process http links', function () {
220
+ assert.equal(
221
+ Utils.greedyTemplate('A phrase with a {{{http://iframeurl.com}}}.', {
222
+ 'http://iframeurl.com': 'value',
223
+ }),
224
+ 'A phrase with a {{{http://iframeurl.com}}}.'
225
+ )
226
+ })
227
+
228
+ it('should not accept dash', function () {
229
+ assert.equal(
230
+ Utils.greedyTemplate('A phrase with a {var-iable}.', { 'var-iable': 'value' }),
231
+ 'A phrase with a {var-iable}.'
232
+ )
233
+ })
234
+
235
+ it('should accept colon', function () {
236
+ assert.equal(
237
+ Utils.greedyTemplate('A phrase with a {variable:fr}.', {
238
+ 'variable:fr': 'value',
239
+ }),
240
+ 'A phrase with a value.'
241
+ )
242
+ })
243
+
244
+ it('should accept arobase', function () {
245
+ assert.equal(
246
+ Utils.greedyTemplate('A phrase with a {@variable}.', {
247
+ '@variable': 'value',
248
+ }),
249
+ 'A phrase with a value.'
250
+ )
251
+ })
252
+
253
+ it('should accept space', function () {
254
+ assert.equal(
255
+ Utils.greedyTemplate('A phrase with a {var iable}.', {
256
+ 'var iable': 'value',
257
+ }),
258
+ 'A phrase with a value.'
259
+ )
260
+ })
261
+
262
+ it('should accept non ascii chars', function () {
263
+ assert.equal(
264
+ Utils.greedyTemplate('A phrase with a {Accessibilité} and {переменная}.', {
265
+ Accessibilité: 'value',
266
+ переменная: 'another',
267
+ }),
268
+ 'A phrase with a value and another.'
269
+ )
270
+ })
271
+
272
+ it('should replace even with ignore if key is found', function () {
273
+ assert.equal(
274
+ Utils.greedyTemplate(
275
+ 'A phrase with a {variable:fr}.',
276
+ { 'variable:fr': 'value' },
277
+ true
278
+ ),
279
+ 'A phrase with a value.'
280
+ )
281
+ })
282
+
283
+ it('should keep string when using ignore if key is not found', function () {
284
+ assert.equal(
285
+ Utils.greedyTemplate('A phrase with a {variable:fr}.', {}, true),
286
+ 'A phrase with a {variable:fr}.'
287
+ )
288
+ })
289
+
290
+ it('should replace nested variables', function () {
291
+ assert.equal(
292
+ Utils.greedyTemplate('A phrase with a {fr.var}.', { fr: { var: 'value' } }),
293
+ 'A phrase with a value.'
294
+ )
295
+ })
296
+
297
+ it('should not fail if nested variable is missing', function () {
298
+ assert.equal(
299
+ Utils.greedyTemplate('A phrase with a {fr.var.foo}.', {
300
+ fr: { var: 'value' },
301
+ }),
302
+ 'A phrase with a .'
303
+ )
304
+ })
305
+
306
+ it('should not fail with nested variables and no data', function () {
307
+ assert.equal(
308
+ Utils.greedyTemplate('A phrase with a {fr.var.foo}.', {}),
309
+ 'A phrase with a .'
310
+ )
311
+ })
312
+
313
+ it('should handle fallback value if any', function () {
314
+ assert.equal(
315
+ Utils.greedyTemplate('A phrase with a {fr.var.bar|"default"}.', {}),
316
+ 'A phrase with a default.'
317
+ )
318
+ })
319
+
320
+ it('should handle fallback var if any', function () {
321
+ assert.equal(
322
+ Utils.greedyTemplate('A phrase with a {fr.var.bar|fallback}.', {
323
+ fallback: 'default',
324
+ }),
325
+ 'A phrase with a default.'
326
+ )
327
+ })
328
+
329
+ it('should handle multiple fallbacks', function () {
330
+ assert.equal(
331
+ Utils.greedyTemplate('A phrase with a {fr.var.bar|try.again|"default"}.', {}),
332
+ 'A phrase with a default.'
333
+ )
334
+ })
335
+
336
+ it('should use the first defined value', function () {
337
+ assert.equal(
338
+ Utils.greedyTemplate('A phrase with a {fr.var.bar|try.again|"default"}.', {
339
+ try: { again: 'please' },
340
+ }),
341
+ 'A phrase with a please.'
342
+ )
343
+ })
344
+
345
+ it('should use the first defined value', function () {
346
+ assert.equal(
347
+ Utils.greedyTemplate('A phrase with a {fr.var.bar|try.again|"default"}.', {
348
+ try: { again: 'again' },
349
+ fr: { var: { bar: 'value' } },
350
+ }),
351
+ 'A phrase with a value.'
352
+ )
353
+ })
354
+
355
+ it('should support the first example from #820 when translated to final syntax', function () {
356
+ assert.equal(
357
+ Utils.greedyTemplate('# {name} ({ele|"-"} m ü. M.)', { name: 'Portalet' }),
358
+ '# Portalet (- m ü. M.)'
359
+ )
360
+ })
361
+
362
+ it('should support the first example from #820 when translated to final syntax when no fallback required', function () {
363
+ assert.equal(
364
+ Utils.greedyTemplate('# {name} ({ele|"-"} m ü. M.)', {
365
+ name: 'Portalet',
366
+ ele: 3344,
367
+ }),
368
+ '# Portalet (3344 m ü. M.)'
369
+ )
370
+ })
371
+
372
+ it('should support white space in fallback', function () {
373
+ assert.equal(
374
+ Utils.greedyTemplate('A phrase with {var|"white space in the fallback."}', {}),
375
+ 'A phrase with white space in the fallback.'
376
+ )
377
+ })
378
+
379
+ it('should support empty string as fallback', function () {
380
+ assert.equal(
381
+ Utils.greedyTemplate(
382
+ 'A phrase with empty string ("{var|""}") in the fallback.',
383
+ {}
384
+ ),
385
+ 'A phrase with empty string ("") in the fallback.'
386
+ )
387
+ })
388
+
389
+ it('should support e.g. links as fallback', function () {
390
+ assert.equal(
391
+ Utils.greedyTemplate(
392
+ 'A phrase with {var|"[[https://osm.org|link]]"} as fallback.',
393
+ {}
394
+ ),
395
+ 'A phrase with [[https://osm.org|link]] as fallback.'
396
+ )
397
+ })
398
+ })
399
+
400
+ describe('#flattenCoordinates()', function () {
401
+ it('should not alter already flat coords', function () {
402
+ var coords = [
403
+ [1, 2],
404
+ [3, 4],
405
+ ]
406
+ assert.deepEqual(Utils.flattenCoordinates(coords), coords)
407
+ })
408
+
409
+ it('should flatten nested coords', function () {
410
+ var coords = [
411
+ [
412
+ [1, 2],
413
+ [3, 4],
414
+ ],
415
+ ]
416
+ assert.deepEqual(Utils.flattenCoordinates(coords), coords[0])
417
+ coords = [
418
+ [
419
+ [
420
+ [1, 2],
421
+ [3, 4],
422
+ ],
423
+ ],
424
+ ]
425
+ assert.deepEqual(Utils.flattenCoordinates(coords), coords[0][0])
426
+ })
427
+
428
+ it('should not fail on empty coords', function () {
429
+ var coords = []
430
+ assert.deepEqual(Utils.flattenCoordinates(coords), coords)
431
+ })
432
+ })
433
+
434
+ describe('#usableOption()', function () {
435
+ it('should consider false', function () {
436
+ assert.ok(Utils.usableOption({ key: false }, 'key'))
437
+ })
438
+
439
+ it('should consider 0', function () {
440
+ assert.ok(Utils.usableOption({ key: 0 }, 'key'))
441
+ })
442
+
443
+ it('should not consider undefined', function () {
444
+ assert.notOk(Utils.usableOption({}, 'key'))
445
+ })
446
+
447
+ it('should not consider empty string', function () {
448
+ assert.notOk(Utils.usableOption({ key: '' }, 'key'))
449
+ })
450
+
451
+ it('should consider null', function () {
452
+ assert.ok(Utils.usableOption({ key: null }, 'key'))
453
+ })
454
+ })
455
+
456
+ describe('#normalize()', function () {
457
+ it('should remove accents',
458
+ function () {
459
+ // French é
460
+ assert.equal(Utils.normalize('aéroport'), 'aeroport')
461
+ // American é
462
+ assert.equal(Utils.normalize('aéroport'), 'aeroport')
463
+ })
464
+ })
465
+
466
+ describe('#sortFeatures()', function () {
467
+ let feat1, feat2, feat3
468
+ before(function () {
469
+ feat1 = { properties: {} }
470
+ feat2 = { properties: {} }
471
+ feat3 = { properties: {} }
472
+ })
473
+ it('should sort feature from custom key', function () {
474
+ feat1.properties.mykey = '13. foo'
475
+ feat2.properties.mykey = '7. foo'
476
+ feat3.properties.mykey = '111. foo'
477
+ let features = Utils.sortFeatures([feat1, feat2, feat3], 'mykey')
478
+ assert.equal(features[0], feat2)
479
+ assert.equal(features[1], feat1)
480
+ assert.equal(features[2], feat3)
481
+ })
482
+ it('should sort feature from multiple keys', function () {
483
+ feat1.properties.mykey = '13. foo'
484
+ feat2.properties.mykey = '111. foo'
485
+ feat3.properties.mykey = '111. foo'
486
+ feat1.properties.otherkey = 'C'
487
+ feat2.properties.otherkey = 'B'
488
+ feat3.properties.otherkey = 'A'
489
+ let features = Utils.sortFeatures([feat1, feat2, feat3], 'mykey,otherkey')
490
+ assert.equal(features[0], feat1)
491
+ assert.equal(features[1], feat3)
492
+ assert.equal(features[2], feat2)
493
+ })
494
+ it('should sort feature from custom key reverse', function () {
495
+ feat1.properties.mykey = '13. foo'
496
+ feat2.properties.mykey = '7. foo'
497
+ feat3.properties.mykey = '111. foo'
498
+ let features = Utils.sortFeatures([feat1, feat2, feat3], '-mykey')
499
+ assert.equal(features[0], feat3)
500
+ assert.equal(features[1], feat1)
501
+ assert.equal(features[2], feat2)
502
+ })
503
+ it('should sort feature from multiple keys with reverse', function () {
504
+ feat1.properties.mykey = '13. foo'
505
+ feat2.properties.mykey = '111. foo'
506
+ feat3.properties.mykey = '111. foo'
507
+ feat1.properties.otherkey = 'C'
508
+ feat2.properties.otherkey = 'B'
509
+ feat3.properties.otherkey = 'A'
510
+ let features = Utils.sortFeatures([feat1, feat2, feat3], 'mykey,-otherkey')
511
+ assert.equal(features[0], feat1)
512
+ assert.equal(features[1], feat2)
513
+ assert.equal(features[2], feat3)
514
+ })
515
+ it('should sort feature with space first', function () {
516
+ feat1.properties.mykey = '1 foo'
517
+ feat2.properties.mykey = '2 foo'
518
+ feat3.properties.mykey = '1a foo'
519
+ let features = Utils.sortFeatures([feat1, feat2, feat3], 'mykey')
520
+ assert.equal(features[0], feat1)
521
+ assert.equal(features[1], feat3)
522
+ assert.equal(features[2], feat2)
523
+ })
524
+ })
525
+
526
+ describe("#copyJSON", function () {
527
+ it('should actually copy the JSON', function () {
528
+ let originalJSON = { "some": "json" }
529
+ let returned = Utils.CopyJSON(originalJSON)
530
+
531
+ // Change the original JSON
532
+ originalJSON["anotherKey"] = "value"
533
+
534
+ // ensure the two aren't the same object
535
+ assert.notEqual(returned, originalJSON)
536
+ assert.deepEqual(returned, { "some": "json" })
537
+ })
538
+ })
539
+
540
+ describe('#getImpactsFromSchema()', function () {
541
+ let getImpactsFromSchema = Utils.getImpactsFromSchema
542
+ it('should return an array', function () {
543
+ expect(getImpactsFromSchema(['foo'], {})).to.be.an('array')
544
+ expect(getImpactsFromSchema(['foo'], { foo: {} })).to.be.an('array')
545
+ expect(getImpactsFromSchema(['foo'], { foo: { impacts: [] } })).to.be.an('array')
546
+ expect(getImpactsFromSchema(['foo'], { foo: { impacts: ['A'] } })).to.be.an(
547
+ 'array'
548
+ )
549
+ })
550
+
551
+ it('should return a list of unique impacted values', function () {
552
+ let schema = {
553
+ foo: { impacts: ['A'] },
554
+ bar: { impacts: ['A', 'B'] },
555
+ baz: { impacts: ['B', 'C'] },
556
+ }
557
+
558
+ assert.deepEqual(getImpactsFromSchema(['foo'], schema), ['A'])
559
+ assert.deepEqual(getImpactsFromSchema(['foo', 'bar'], schema), ['A', 'B'])
560
+ assert.deepEqual(getImpactsFromSchema(['foo', 'bar', 'baz'], schema), [
561
+ 'A',
562
+ 'B',
563
+ 'C',
564
+ ])
565
+ })
566
+ it('should return an empty list if nothing is found', function () {
567
+ let schema = {
568
+ foo: { impacts: ['A'] },
569
+ bar: { impacts: ['A', 'B'] },
570
+ baz: { impacts: ['B', 'C'] },
571
+ }
572
+
573
+ assert.deepEqual(getImpactsFromSchema(['bad'], schema), [])
574
+ })
575
+
576
+ it('should return an empty list if the schema key does not exist', function () {
577
+ let schema = {
578
+ foo: { impacts: ['A'] },
579
+ }
580
+
581
+ assert.deepEqual(getImpactsFromSchema(['bad'], schema), [])
582
+ })
583
+ it('should work if the "impacts" key is not defined', function () {
584
+ let schema = {
585
+ foo: {},
586
+ bar: { impacts: ['A'] },
587
+ baz: { impacts: ['B'] },
588
+ }
589
+
590
+ assert.deepEqual(getImpactsFromSchema(['foo', 'bar', 'baz'], schema), ['A', 'B'])
591
+ })
592
+ })
593
+ describe('parseNaiveDate', () => {
594
+ it('should parse a date', () => {
595
+ assert.equal(Utils.parseNaiveDate("2024/03/04").toISOString(), "2024-03-04T00:00:00.000Z")
596
+ })
597
+ it('should parse a datetime', () => {
598
+ assert.equal(Utils.parseNaiveDate("2024/03/04 12:13:14").toISOString(), "2024-03-04T00:00:00.000Z")
599
+ })
600
+ it('should parse an iso datetime', () => {
601
+ assert.equal(Utils.parseNaiveDate("2024-03-04T00:00:00.000Z").toISOString(), "2024-03-04T00:00:00.000Z")
602
+ })
603
+ it('should parse a GMT time', () => {
604
+ assert.equal(Utils.parseNaiveDate("04 Mar 2024 00:12:00 GMT").toISOString(), "2024-03-04T00:00:00.000Z")
605
+ })
606
+ it('should parse a GMT time with explicit timezone', () => {
607
+ assert.equal(Utils.parseNaiveDate("Thu, 04 Mar 2024 00:00:00 GMT+0300").toISOString(), "2024-03-03T00:00:00.000Z")
608
+ })
609
+ })
610
+ })
umap/static/umap/vars.css CHANGED
@@ -10,4 +10,13 @@
10
10
  --button-primary-color: var(--color-darkBlue);
11
11
  --button-neutral-background: var(--color-lightGray);
12
12
  --button-neutral-color: var(--color-darkGray);
13
+
14
+ /* Sizes and spaces */
15
+ --panel-gutter: 10px;
16
+ --panel-bottom: 40px;
17
+ --panel-header-height: 36px;
18
+ --panel-width: 400px;
19
+ --header-height: 46px;
20
+ --footer-height: 46px;
21
+ --control-size: 36px;
13
22
  }