umap-project 2.5.1__py3-none-any.whl → 2.6.0__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 (276) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +6 -1
  3. umap/context_processors.py +2 -1
  4. umap/decorators.py +13 -2
  5. umap/forms.py +26 -2
  6. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/br/LC_MESSAGES/django.po +252 -146
  8. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/ca/LC_MESSAGES/django.po +274 -162
  10. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  11. umap/locale/cs_CZ/LC_MESSAGES/django.po +261 -150
  12. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/de/LC_MESSAGES/django.po +299 -187
  14. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/el/LC_MESSAGES/django.po +215 -159
  16. umap/locale/en/LC_MESSAGES/django.po +211 -155
  17. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/es/LC_MESSAGES/django.po +255 -144
  19. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/eu/LC_MESSAGES/django.po +254 -198
  21. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  22. umap/locale/fa_IR/LC_MESSAGES/django.po +347 -235
  23. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  24. umap/locale/fr/LC_MESSAGES/django.po +216 -160
  25. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  26. umap/locale/hu/LC_MESSAGES/django.po +215 -159
  27. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  28. umap/locale/it/LC_MESSAGES/django.po +252 -146
  29. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  30. umap/locale/ms/LC_MESSAGES/django.po +252 -146
  31. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  32. umap/locale/pl/LC_MESSAGES/django.po +254 -148
  33. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  34. umap/locale/pt/LC_MESSAGES/django.po +215 -159
  35. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  36. umap/locale/sv/LC_MESSAGES/django.po +254 -143
  37. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  38. umap/locale/th_TH/LC_MESSAGES/django.po +125 -70
  39. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  40. umap/locale/zh_TW/LC_MESSAGES/django.po +256 -145
  41. umap/migrations/0022_add_team.py +94 -0
  42. umap/models.py +45 -10
  43. umap/settings/__init__.py +2 -0
  44. umap/settings/base.py +9 -2
  45. umap/static/umap/base.css +32 -41
  46. umap/static/umap/content.css +19 -25
  47. umap/static/umap/css/icon.css +63 -37
  48. umap/static/umap/css/importers.css +1 -1
  49. umap/static/umap/css/slideshow.css +7 -5
  50. umap/static/umap/css/tableeditor.css +4 -3
  51. umap/static/umap/img/16-white.svg +1 -4
  52. umap/static/umap/img/16.svg +2 -6
  53. umap/static/umap/img/24-white.svg +4 -4
  54. umap/static/umap/img/24.svg +6 -6
  55. umap/static/umap/img/source/16-white.svg +2 -5
  56. umap/static/umap/img/source/16.svg +3 -7
  57. umap/static/umap/img/source/24-white.svg +7 -14
  58. umap/static/umap/img/source/24.svg +10 -17
  59. umap/static/umap/js/components/alerts/alert.css +20 -8
  60. umap/static/umap/js/modules/autocomplete.js +8 -12
  61. umap/static/umap/js/modules/browser.js +4 -3
  62. umap/static/umap/js/modules/caption.js +9 -11
  63. umap/static/umap/js/modules/data/features.js +993 -0
  64. umap/static/umap/js/modules/data/layer.js +1210 -0
  65. umap/static/umap/js/modules/formatter.js +12 -3
  66. umap/static/umap/js/modules/global.js +21 -5
  67. umap/static/umap/js/modules/importers/overpass.js +22 -8
  68. umap/static/umap/js/modules/permissions.js +280 -0
  69. umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
  70. umap/static/umap/js/modules/rendering/layers/base.js +105 -0
  71. umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
  72. umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
  73. umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
  74. umap/static/umap/js/modules/rendering/popup.js +99 -0
  75. umap/static/umap/js/modules/rendering/template.js +217 -0
  76. umap/static/umap/js/modules/rendering/ui.js +610 -0
  77. umap/static/umap/js/modules/rules.js +16 -3
  78. umap/static/umap/js/modules/schema.js +25 -1
  79. umap/static/umap/js/modules/share.js +66 -45
  80. umap/static/umap/js/modules/sync/updaters.js +9 -10
  81. umap/static/umap/js/modules/tableeditor.js +7 -7
  82. umap/static/umap/js/modules/ui/dialog.js +8 -4
  83. umap/static/umap/js/modules/utils.js +22 -13
  84. umap/static/umap/js/umap.controls.js +80 -146
  85. umap/static/umap/js/umap.core.js +9 -9
  86. umap/static/umap/js/umap.forms.js +41 -17
  87. umap/static/umap/js/umap.js +72 -65
  88. umap/static/umap/locale/am_ET.js +8 -2
  89. umap/static/umap/locale/am_ET.json +8 -2
  90. umap/static/umap/locale/ar.js +8 -2
  91. umap/static/umap/locale/ar.json +8 -2
  92. umap/static/umap/locale/ast.js +8 -2
  93. umap/static/umap/locale/ast.json +8 -2
  94. umap/static/umap/locale/bg.js +8 -2
  95. umap/static/umap/locale/bg.json +8 -2
  96. umap/static/umap/locale/br.js +42 -36
  97. umap/static/umap/locale/br.json +42 -36
  98. umap/static/umap/locale/ca.js +67 -61
  99. umap/static/umap/locale/ca.json +67 -61
  100. umap/static/umap/locale/cs_CZ.js +8 -2
  101. umap/static/umap/locale/cs_CZ.json +8 -2
  102. umap/static/umap/locale/da.js +8 -2
  103. umap/static/umap/locale/da.json +8 -2
  104. umap/static/umap/locale/de.js +143 -137
  105. umap/static/umap/locale/de.json +143 -137
  106. umap/static/umap/locale/el.js +54 -48
  107. umap/static/umap/locale/el.json +54 -48
  108. umap/static/umap/locale/en.js +10 -2
  109. umap/static/umap/locale/en.json +10 -2
  110. umap/static/umap/locale/en_US.json +8 -2
  111. umap/static/umap/locale/es.js +8 -2
  112. umap/static/umap/locale/es.json +8 -2
  113. umap/static/umap/locale/et.js +8 -2
  114. umap/static/umap/locale/et.json +8 -2
  115. umap/static/umap/locale/eu.js +346 -338
  116. umap/static/umap/locale/eu.json +346 -338
  117. umap/static/umap/locale/fa_IR.js +415 -407
  118. umap/static/umap/locale/fa_IR.json +415 -407
  119. umap/static/umap/locale/fi.js +8 -2
  120. umap/static/umap/locale/fi.json +8 -2
  121. umap/static/umap/locale/fr.js +11 -3
  122. umap/static/umap/locale/fr.json +11 -3
  123. umap/static/umap/locale/gl.js +8 -2
  124. umap/static/umap/locale/gl.json +8 -2
  125. umap/static/umap/locale/he.js +8 -2
  126. umap/static/umap/locale/he.json +8 -2
  127. umap/static/umap/locale/hr.js +8 -2
  128. umap/static/umap/locale/hr.json +8 -2
  129. umap/static/umap/locale/hu.js +31 -23
  130. umap/static/umap/locale/hu.json +31 -23
  131. umap/static/umap/locale/id.js +8 -2
  132. umap/static/umap/locale/id.json +8 -2
  133. umap/static/umap/locale/is.js +8 -2
  134. umap/static/umap/locale/is.json +8 -2
  135. umap/static/umap/locale/it.js +8 -2
  136. umap/static/umap/locale/it.json +8 -2
  137. umap/static/umap/locale/ja.js +8 -2
  138. umap/static/umap/locale/ja.json +8 -2
  139. umap/static/umap/locale/ko.js +8 -2
  140. umap/static/umap/locale/ko.json +8 -2
  141. umap/static/umap/locale/lt.js +8 -2
  142. umap/static/umap/locale/lt.json +8 -2
  143. umap/static/umap/locale/ms.js +8 -2
  144. umap/static/umap/locale/ms.json +8 -2
  145. umap/static/umap/locale/nl.js +8 -2
  146. umap/static/umap/locale/nl.json +8 -2
  147. umap/static/umap/locale/no.js +8 -2
  148. umap/static/umap/locale/no.json +8 -2
  149. umap/static/umap/locale/pl.js +54 -48
  150. umap/static/umap/locale/pl.json +54 -48
  151. umap/static/umap/locale/pl_PL.json +8 -2
  152. umap/static/umap/locale/pt.js +24 -18
  153. umap/static/umap/locale/pt.json +24 -18
  154. umap/static/umap/locale/pt_BR.js +8 -2
  155. umap/static/umap/locale/pt_BR.json +8 -2
  156. umap/static/umap/locale/pt_PT.js +214 -208
  157. umap/static/umap/locale/pt_PT.json +214 -208
  158. umap/static/umap/locale/ro.js +8 -2
  159. umap/static/umap/locale/ro.json +8 -2
  160. umap/static/umap/locale/ru.js +8 -2
  161. umap/static/umap/locale/ru.json +8 -2
  162. umap/static/umap/locale/sk_SK.js +8 -2
  163. umap/static/umap/locale/sk_SK.json +8 -2
  164. umap/static/umap/locale/sl.js +8 -2
  165. umap/static/umap/locale/sl.json +8 -2
  166. umap/static/umap/locale/sr.js +8 -2
  167. umap/static/umap/locale/sr.json +8 -2
  168. umap/static/umap/locale/sv.js +8 -2
  169. umap/static/umap/locale/sv.json +8 -2
  170. umap/static/umap/locale/th_TH.js +33 -27
  171. umap/static/umap/locale/th_TH.json +33 -27
  172. umap/static/umap/locale/tr.js +8 -2
  173. umap/static/umap/locale/tr.json +8 -2
  174. umap/static/umap/locale/uk_UA.js +8 -2
  175. umap/static/umap/locale/uk_UA.json +8 -2
  176. umap/static/umap/locale/vi.js +8 -2
  177. umap/static/umap/locale/vi.json +8 -2
  178. umap/static/umap/locale/vi_VN.json +8 -2
  179. umap/static/umap/locale/zh.js +8 -2
  180. umap/static/umap/locale/zh.json +8 -2
  181. umap/static/umap/locale/zh_CN.json +8 -2
  182. umap/static/umap/locale/zh_TW.Big5.json +8 -2
  183. umap/static/umap/locale/zh_TW.js +102 -96
  184. umap/static/umap/locale/zh_TW.json +102 -96
  185. umap/static/umap/map.css +111 -108
  186. umap/static/umap/nav.css +19 -10
  187. umap/static/umap/unittests/utils.js +230 -107
  188. umap/static/umap/vars.css +1 -0
  189. umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
  190. umap/static/umap/vendors/editable/Leaflet.Editable.js +2079 -1937
  191. umap/storage.py +1 -0
  192. umap/templates/404.html +5 -1
  193. umap/templates/500.html +3 -1
  194. umap/templates/auth/user_detail.html +8 -2
  195. umap/templates/auth/user_form.html +19 -10
  196. umap/templates/auth/user_stars.html +8 -2
  197. umap/templates/base.html +1 -0
  198. umap/templates/registration/login.html +18 -3
  199. umap/templates/umap/about.html +1 -0
  200. umap/templates/umap/about_summary.html +22 -7
  201. umap/templates/umap/components/alerts/alert.html +42 -21
  202. umap/templates/umap/content.html +2 -0
  203. umap/templates/umap/content_footer.html +7 -3
  204. umap/templates/umap/css.html +1 -0
  205. umap/templates/umap/dashboard_menu.html +15 -0
  206. umap/templates/umap/home.html +14 -4
  207. umap/templates/umap/js.html +4 -9
  208. umap/templates/umap/login_popup_end.html +10 -4
  209. umap/templates/umap/map_detail.html +8 -2
  210. umap/templates/umap/map_fragment.html +3 -1
  211. umap/templates/umap/map_init.html +2 -1
  212. umap/templates/umap/map_list.html +6 -3
  213. umap/templates/umap/map_table.html +36 -12
  214. umap/templates/umap/messages.html +0 -1
  215. umap/templates/umap/navigation.html +2 -1
  216. umap/templates/umap/password_change.html +5 -1
  217. umap/templates/umap/password_change_done.html +8 -2
  218. umap/templates/umap/search.html +8 -2
  219. umap/templates/umap/search_bar.html +1 -0
  220. umap/templates/umap/team_confirm_delete.html +19 -0
  221. umap/templates/umap/team_detail.html +27 -0
  222. umap/templates/umap/team_form.html +60 -0
  223. umap/templates/umap/user_dashboard.html +7 -9
  224. umap/templates/umap/user_teams.html +51 -0
  225. umap/tests/base.py +8 -1
  226. umap/tests/conftest.py +6 -0
  227. umap/tests/fixtures/test_circles_layer.geojson +219 -0
  228. umap/tests/fixtures/test_upload_georss.xml +20 -0
  229. umap/tests/integration/conftest.py +18 -4
  230. umap/tests/integration/helpers.py +12 -0
  231. umap/tests/integration/test_anonymous_owned_map.py +23 -0
  232. umap/tests/integration/test_basics.py +29 -0
  233. umap/tests/integration/test_browser.py +20 -0
  234. umap/tests/integration/test_caption.py +20 -0
  235. umap/tests/integration/test_circles_layer.py +69 -0
  236. umap/tests/integration/test_conditional_rules.py +102 -17
  237. umap/tests/integration/test_draw_polygon.py +138 -13
  238. umap/tests/integration/test_draw_polyline.py +8 -18
  239. umap/tests/integration/test_edit_datalayer.py +3 -3
  240. umap/tests/integration/test_import.py +124 -5
  241. umap/tests/integration/test_owned_map.py +21 -13
  242. umap/tests/integration/test_querystring.py +7 -0
  243. umap/tests/integration/test_team.py +47 -0
  244. umap/tests/integration/test_tilelayer.py +19 -2
  245. umap/tests/integration/test_view_marker.py +28 -1
  246. umap/tests/integration/test_websocket_sync.py +5 -5
  247. umap/tests/test_datalayer.py +32 -7
  248. umap/tests/test_datalayer_views.py +1 -1
  249. umap/tests/test_map.py +30 -4
  250. umap/tests/test_map_views.py +2 -2
  251. umap/tests/test_statics.py +40 -0
  252. umap/tests/test_team_views.py +131 -0
  253. umap/tests/test_views.py +15 -1
  254. umap/urls.py +23 -13
  255. umap/views.py +116 -10
  256. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/METADATA +14 -14
  257. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/RECORD +260 -253
  258. umap/static/umap/js/umap.datalayer.permissions.js +0 -70
  259. umap/static/umap/js/umap.features.js +0 -1290
  260. umap/static/umap/js/umap.layer.js +0 -1837
  261. umap/static/umap/js/umap.permissions.js +0 -208
  262. umap/static/umap/js/umap.popup.js +0 -341
  263. umap/static/umap/test/TableEditor.js +0 -104
  264. umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
  265. umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
  266. umap/static/umap/vendors/leaflet/leaflet.js +0 -6
  267. umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
  268. umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
  269. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
  270. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
  271. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
  272. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
  273. umap/tests/integration/test_statics.py +0 -47
  274. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/WHEEL +0 -0
  275. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/entry_points.txt +0 -0
  276. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,208 +0,0 @@
1
- // Dedicated object so we can deal with a separate dirty status, and thus
2
- // call the endpoint only when needed, saving one call at each save.
3
- U.MapPermissions = L.Class.extend({
4
- options: {
5
- owner: null,
6
- editors: [],
7
- share_status: null,
8
- edit_status: null,
9
- },
10
-
11
- initialize: function (map) {
12
- this.setOptions(map.options.permissions)
13
- this.map = map
14
- let isDirty = false
15
- try {
16
- Object.defineProperty(this, 'isDirty', {
17
- get: () => isDirty,
18
- set: (status) => {
19
- isDirty = status
20
- if (status) {
21
- this.map.isDirty = status
22
- }
23
- },
24
- })
25
- } catch (e) {
26
- // Certainly IE8, which has a limited version of defineProperty
27
- }
28
- },
29
-
30
- setOptions: function (options) {
31
- this.options = L.Util.setOptions(this, options)
32
- },
33
-
34
- isOwner: function () {
35
- return (
36
- this.map.options.user &&
37
- this.map.options.permissions.owner &&
38
- this.map.options.user.id === this.map.options.permissions.owner.id
39
- )
40
- },
41
-
42
- isAnonymousMap: function () {
43
- return !this.map.options.permissions.owner
44
- },
45
-
46
- getMap: function () {
47
- return this.map
48
- },
49
-
50
- edit: function () {
51
- if (this.map.options.editMode !== 'advanced') return
52
- if (!this.map.options.umap_id) {
53
- return U.Alert.info(L._('Please save the map first'))
54
- }
55
- const container = L.DomUtil.create('div', 'permissions-panel')
56
- const fields = []
57
- L.DomUtil.createTitle(container, L._('Update permissions'), 'icon-key')
58
- if (this.isAnonymousMap()) {
59
- if (this.options.anonymous_edit_url) {
60
- const helpText = `${L._('Secret edit link:')}<br>${
61
- this.options.anonymous_edit_url
62
- }`
63
- L.DomUtil.element({
64
- tagName: 'p',
65
- className: 'help-text',
66
- innerHTML: helpText,
67
- parent: container,
68
- })
69
- fields.push([
70
- 'options.edit_status',
71
- {
72
- handler: 'IntSelect',
73
- label: L._('Who can edit'),
74
- selectOptions: this.map.options.edit_statuses,
75
- helpText: helpText,
76
- },
77
- ])
78
- }
79
- } else {
80
- if (this.isOwner()) {
81
- fields.push([
82
- 'options.edit_status',
83
- {
84
- handler: 'IntSelect',
85
- label: L._('Who can edit'),
86
- selectOptions: this.map.options.edit_statuses,
87
- },
88
- ])
89
- fields.push([
90
- 'options.share_status',
91
- {
92
- handler: 'IntSelect',
93
- label: L._('Who can view'),
94
- selectOptions: this.map.options.share_statuses,
95
- },
96
- ])
97
- fields.push([
98
- 'options.owner',
99
- { handler: 'ManageOwner', label: L._("Map's owner") },
100
- ])
101
- }
102
- fields.push([
103
- 'options.editors',
104
- { handler: 'ManageEditors', label: L._("Map's editors") },
105
- ])
106
- }
107
-
108
- const builder = new U.FormBuilder(this, fields)
109
- const form = builder.build()
110
- container.appendChild(form)
111
- if (this.isAnonymousMap() && this.map.options.user) {
112
- // We have a user, and this user has come through here, so they can edit the map, so let's allow to own the map.
113
- // Note: real check is made on the back office anyway.
114
- const advancedActions = L.DomUtil.createFieldset(
115
- container,
116
- L._('Advanced actions')
117
- )
118
- const advancedButtons = L.DomUtil.create('div', 'button-bar', advancedActions)
119
- L.DomUtil.createButton(
120
- 'button',
121
- advancedButtons,
122
- L._('Attach the map to my account'),
123
- this.attach,
124
- this
125
- )
126
- }
127
- L.DomUtil.add('h4', '', container, L._('Datalayers'))
128
- this.map.eachDataLayer((datalayer) => {
129
- datalayer.permissions.edit(container)
130
- })
131
- this.map.editPanel.open({ content: container, className: 'dark' })
132
- },
133
-
134
- attach: async function () {
135
- const [data, response, error] = await this.map.server.post(this.getAttachUrl())
136
- if (!error) {
137
- this.options.owner = this.map.options.user
138
- U.Alert.success(L._('Map has been attached to your account'))
139
- this.map.editPanel.close()
140
- }
141
- },
142
-
143
- save: async function () {
144
- if (!this.isDirty) return this.map.continueSaving()
145
- const formData = new FormData()
146
- if (!this.isAnonymousMap() && this.options.editors) {
147
- const editors = this.options.editors.map((u) => u.id)
148
- for (let i = 0; i < this.options.editors.length; i++)
149
- formData.append('editors', this.options.editors[i].id)
150
- }
151
- if (this.isOwner() || this.isAnonymousMap())
152
- formData.append('edit_status', this.options.edit_status)
153
- if (this.isOwner()) {
154
- formData.append('owner', this.options.owner?.id)
155
- formData.append('share_status', this.options.share_status)
156
- }
157
- const [data, response, error] = await this.map.server.post(
158
- this.getUrl(),
159
- {},
160
- formData
161
- )
162
- if (!error) {
163
- this.commit()
164
- this.isDirty = false
165
- this.map.continueSaving()
166
- this.map.fire('postsync')
167
- }
168
- },
169
-
170
- getUrl: function () {
171
- return U.Utils.template(this.map.options.urls.map_update_permissions, {
172
- map_id: this.map.options.umap_id,
173
- })
174
- },
175
-
176
- getAttachUrl: function () {
177
- return U.Utils.template(this.map.options.urls.map_attach_owner, {
178
- map_id: this.map.options.umap_id,
179
- })
180
- },
181
-
182
- addOwnerLink: function (element, container) {
183
- if (this.options.owner?.name && this.options.owner.url) {
184
- const ownerContainer = L.DomUtil.add(
185
- element,
186
- 'umap-map-owner',
187
- container,
188
- ` ${L._('by')} `
189
- )
190
- L.DomUtil.createLink(
191
- '',
192
- ownerContainer,
193
- this.options.owner.name,
194
- this.options.owner.url
195
- )
196
- }
197
- },
198
-
199
- commit: function () {
200
- L.Util.extend(this.map.options.permissions, this.options)
201
- },
202
-
203
- getShareStatusDisplay: function () {
204
- return Object.fromEntries(this.map.options.share_statuses)[
205
- this.options.share_status
206
- ]
207
- },
208
- })
@@ -1,341 +0,0 @@
1
- /* Shapes */
2
-
3
- U.Popup = L.Popup.extend({
4
- options: {
5
- parseTemplate: true,
6
- },
7
-
8
- initialize: function (feature) {
9
- this.feature = feature
10
- this.container = L.DomUtil.create('div', 'umap-popup')
11
- this.format()
12
- L.Popup.prototype.initialize.call(this, {}, feature)
13
- this.setContent(this.container)
14
- },
15
-
16
- format: function () {
17
- const mode = this.feature.getOption('popupTemplate') || 'Default'
18
- const klass = U.PopupTemplate[mode] || U.PopupTemplate.Default
19
- this.content = new klass(this.feature, this.container)
20
- this.content.render()
21
- const els = this.container.querySelectorAll('img,iframe')
22
- for (let i = 0; i < els.length; i++) {
23
- this.onElementLoaded(els[i])
24
- }
25
- if (!els.length && this.container.textContent.replace('\n', '') === '') {
26
- this.container.innerHTML = ''
27
- L.DomUtil.add('h3', '', this.container, this.feature.getDisplayName())
28
- }
29
- },
30
-
31
- onElementLoaded: function (el) {
32
- L.DomEvent.on(
33
- el,
34
- 'load',
35
- function () {
36
- this._updateLayout()
37
- this._updatePosition()
38
- this._adjustPan()
39
- },
40
- this
41
- )
42
- },
43
- })
44
-
45
- U.Popup.Large = U.Popup.extend({
46
- options: {
47
- maxWidth: 500,
48
- className: 'umap-popup-large',
49
- },
50
- })
51
-
52
- U.Popup.Panel = U.Popup.extend({
53
- options: {
54
- zoomAnimation: false,
55
- },
56
-
57
- onAdd: function (map) {
58
- map.panel.setDefaultMode('expanded')
59
- map.panel.open({
60
- content: this._content,
61
- actions: [U.Browser.backButton(map)],
62
- })
63
-
64
- // fire events as in base class Popup.js:onAdd
65
- map.fire('popupopen', { popup: this })
66
- if (this._source) {
67
- this._source.fire('popupopen', { popup: this }, true)
68
- if (!(this._source instanceof L.Path)) {
69
- this._source.on('preclick', L.DomEvent.stopPropagation)
70
- }
71
- }
72
- },
73
-
74
- onRemove: function (map) {
75
- map.panel.close()
76
-
77
- // fire events as in base class Popup.js:onRemove
78
- map.fire('popupclose', { popup: this })
79
- if (this._source) {
80
- this._source.fire('popupclose', { popup: this }, true)
81
- if (!(this._source instanceof L.Path)) {
82
- this._source.off('preclick', L.DomEvent.stopPropagation)
83
- }
84
- }
85
- },
86
-
87
- update: () => {},
88
- _updateLayout: () => {},
89
- _updatePosition: () => {},
90
- _adjustPan: () => {},
91
- _animateZoom: () => {},
92
- })
93
- U.Popup.SimplePanel = U.Popup.Panel // Retrocompat.
94
-
95
- /* Content templates */
96
-
97
- U.PopupTemplate = {}
98
-
99
- U.PopupTemplate.Default = L.Class.extend({
100
- initialize: function (feature, container) {
101
- this.feature = feature
102
- this.container = container
103
- },
104
-
105
- renderTitle: () => {},
106
-
107
- renderBody: function () {
108
- const template = this.feature.getOption('popupContentTemplate')
109
- const target = this.feature.getOption('outlinkTarget')
110
- const container = L.DomUtil.create('div', 'umap-popup-container text')
111
- let content = ''
112
- let properties
113
- let center
114
- properties = this.feature.extendedProperties()
115
- // Resolve properties inside description
116
- properties.description = U.Utils.greedyTemplate(
117
- this.feature.properties.description || '',
118
- properties
119
- )
120
- content = U.Utils.greedyTemplate(template, properties)
121
- content = U.Utils.toHTML(content, { target: target })
122
- container.innerHTML = content
123
- return container
124
- },
125
-
126
- renderFooter: function () {
127
- if (this.feature.hasPopupFooter()) {
128
- const footer = L.DomUtil.create('ul', 'umap-popup-footer', this.container)
129
- const previousLi = L.DomUtil.create('li', 'previous', footer)
130
- const zoomLi = L.DomUtil.create('li', 'zoom', footer)
131
- const nextLi = L.DomUtil.create('li', 'next', footer)
132
- const next = this.feature.getNext()
133
- const prev = this.feature.getPrevious()
134
- // Fixme: remove me when this is merged and released
135
- // https://github.com/Leaflet/Leaflet/pull/9052
136
- L.DomEvent.disableClickPropagation(footer)
137
- if (next)
138
- nextLi.title = L._('Go to «{feature}»', {
139
- feature: next.properties.name || L._('next'),
140
- })
141
- if (prev)
142
- previousLi.title = L._('Go to «{feature}»', {
143
- feature: prev.properties.name || L._('previous'),
144
- })
145
- zoomLi.title = L._('Zoom to this feature')
146
- L.DomEvent.on(nextLi, 'click', () => {
147
- if (next) next.zoomTo({ callback: next.view })
148
- })
149
- L.DomEvent.on(previousLi, 'click', () => {
150
- if (prev) prev.zoomTo({ callback: prev.view })
151
- })
152
- L.DomEvent.on(
153
- zoomLi,
154
- 'click',
155
- function () {
156
- this.zoomTo()
157
- },
158
- this.feature
159
- )
160
- }
161
- },
162
-
163
- render: function () {
164
- const title = this.renderTitle()
165
- if (title) this.container.appendChild(title)
166
- const body = this.renderBody()
167
- if (body) L.DomUtil.add('div', 'umap-popup-content', this.container, body)
168
- this.renderFooter()
169
- },
170
- })
171
-
172
- U.PopupTemplate.BaseWithTitle = U.PopupTemplate.Default.extend({
173
- renderTitle: function () {
174
- let title
175
- if (this.feature.getDisplayName()) {
176
- title = L.DomUtil.create('h3', 'popup-title')
177
- title.textContent = this.feature.getDisplayName()
178
- }
179
- return title
180
- },
181
- })
182
-
183
- U.PopupTemplate.Table = U.PopupTemplate.BaseWithTitle.extend({
184
- formatRow: (key, value) => {
185
- if (value.indexOf('http') === 0) {
186
- value = `<a href="${value}" target="_blank">${value}</a>`
187
- }
188
- return value
189
- },
190
-
191
- addRow: function (container, key, value) {
192
- const tr = L.DomUtil.create('tr', '', container)
193
- L.DomUtil.add('th', '', tr, key)
194
- L.DomUtil.element({
195
- tagName: 'td',
196
- parent: tr,
197
- innerHTML: this.formatRow(key, value),
198
- })
199
- },
200
-
201
- renderBody: function () {
202
- const table = L.DomUtil.create('table')
203
-
204
- for (const key in this.feature.properties) {
205
- if (typeof this.feature.properties[key] === 'object' || key === 'name') continue
206
- // TODO, manage links (url, mailto, wikipedia...)
207
- this.addRow(table, key, U.Utils.escapeHTML(this.feature.properties[key]).trim())
208
- }
209
- return table
210
- },
211
- })
212
-
213
- U.PopupTemplate.GeoRSSImage = U.PopupTemplate.BaseWithTitle.extend({
214
- options: {
215
- minWidth: 300,
216
- maxWidth: 500,
217
- className: 'umap-popup-large umap-georss-image',
218
- },
219
-
220
- renderBody: function () {
221
- const container = L.DomUtil.create('a')
222
- container.href = this.feature.properties.link
223
- container.target = '_blank'
224
- if (this.feature.properties.img) {
225
- const img = L.DomUtil.create('img', '', container)
226
- img.src = this.feature.properties.img
227
- // Sadly, we are unable to override this from JS the clean way
228
- // See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
229
- img.style.maxWidth = `${this.options.maxWidth}px`
230
- img.style.maxHeight = `${this.options.maxWidth}px`
231
- this.onElementLoaded(img)
232
- }
233
- return container
234
- },
235
- })
236
-
237
- U.PopupTemplate.GeoRSSLink = U.PopupTemplate.Default.extend({
238
- options: {
239
- className: 'umap-georss-link',
240
- },
241
-
242
- renderBody: function () {
243
- const title = this.renderTitle(this)
244
- const a = L.DomUtil.add('a')
245
- a.href = this.feature.properties.link
246
- a.target = '_blank'
247
- a.appendChild(title)
248
- return a
249
- },
250
- })
251
-
252
- U.PopupTemplate.OSM = U.PopupTemplate.Default.extend({
253
- options: {
254
- className: 'umap-openstreetmap',
255
- },
256
-
257
- getName: function () {
258
- const props = this.feature.properties
259
- const locale = L.getLocale()
260
- if (locale && props[`name:${locale}`]) return props[`name:${locale}`]
261
- return props.name
262
- },
263
-
264
- renderBody: function () {
265
- const props = this.feature.properties
266
- const container = L.DomUtil.add('div')
267
- const title = L.DomUtil.add('h3', 'popup-title', container)
268
- const color = this.feature.getPreviewColor()
269
- title.style.backgroundColor = color
270
- const iconUrl = this.feature.getDynamicOption('iconUrl')
271
- const icon = U.Icon.makeIconElement(iconUrl, title)
272
- L.DomUtil.addClass(icon, 'icon')
273
- U.Icon.setIconContrast(icon, title, iconUrl, color)
274
- if (L.DomUtil.contrastedColor(title, color)) title.style.color = 'white'
275
- L.DomUtil.add('span', '', title, this.getName())
276
- const street = props['addr:street']
277
- if (street) {
278
- const row = L.DomUtil.add('address', 'address', container)
279
- const number = props['addr:housenumber']
280
- if (number) {
281
- // Poor way to deal with international forms of writting addresses
282
- L.DomUtil.add('span', '', row, `${L._('No.')}: ${number}`)
283
- L.DomUtil.add('span', '', row, `${L._('Street')}: ${street}`)
284
- } else {
285
- L.DomUtil.add('span', '', row, street)
286
- }
287
- }
288
- if (props.website) {
289
- L.DomUtil.element({
290
- tagName: 'a',
291
- parent: container,
292
- href: props.website,
293
- textContent: props.website,
294
- })
295
- }
296
- const phone = props.phone || props['contact:phone']
297
- if (phone) {
298
- L.DomUtil.add(
299
- 'div',
300
- '',
301
- container,
302
- L.DomUtil.element({ tagName: 'a', href: `tel:${phone}`, textContent: phone })
303
- )
304
- }
305
- if (props.mobile) {
306
- L.DomUtil.add(
307
- 'div',
308
- '',
309
- container,
310
- L.DomUtil.element({
311
- tagName: 'a',
312
- href: `tel:${props.mobile}`,
313
- textContent: props.mobile,
314
- })
315
- )
316
- }
317
- const email = props.email || props['contact:email']
318
- if (email) {
319
- L.DomUtil.add(
320
- 'div',
321
- '',
322
- container,
323
- L.DomUtil.element('a', { href: `mailto:${email}`, textContent: email })
324
- )
325
- }
326
- const id = props['@id'] || props.id
327
- if (id) {
328
- L.DomUtil.add(
329
- 'div',
330
- 'osm-link',
331
- container,
332
- L.DomUtil.element({
333
- tagName: 'a',
334
- href: `https://www.openstreetmap.org/${id}`,
335
- textContent: L._('See on OpenStreetMap'),
336
- })
337
- )
338
- }
339
- return container
340
- },
341
- })
@@ -1,104 +0,0 @@
1
- describe('L.TableEditor', () => {
2
- let path = '/map/99/datalayer/edit/62/',
3
- datalayer
4
-
5
- before(async () => {
6
- await fetchMock.mock(
7
- /\/datalayer\/62\/\?.*/,
8
- JSON.stringify(RESPONSES.datalayer62_GET)
9
- )
10
- this.options = {
11
- umap_id: 99,
12
- }
13
- map = initMap({ umap_id: 99 })
14
- const datalayer_options = defaultDatalayerData()
15
- await map.initDataLayers([datalayer_options])
16
- datalayer = map.getDataLayerByUmapId(62)
17
- enableEdit()
18
- })
19
- after(() => {
20
- fetchMock.restore()
21
- clickCancel()
22
- resetMap()
23
- })
24
-
25
- describe('#open()', () => {
26
- var button
27
-
28
- it('should exist table click on edit mode', () => {
29
- button = qs(
30
- '#browse_data_toggle_' + L.stamp(datalayer) + ' .icon-table'
31
- )
32
- expect(button).to.be.ok
33
- })
34
-
35
- it('should open table button click', () => {
36
- happen.click(button)
37
- expect(qs('.panel.full.on div.table')).to.be.ok
38
- expect(qsa('.panel.full.on div.table form').length).to.eql(3) // One per feature.
39
- expect(qsa('.panel.full.on div.table input').length).to.eql(3) // One per feature and per property.
40
- })
41
- })
42
- describe('#properties()', () => {
43
- var feature
44
-
45
- before(() => {
46
- var firstIndex = datalayer._index[0]
47
- feature = datalayer._layers[firstIndex]
48
- })
49
-
50
- it('should create new property column', () => {
51
- var newPrompt = () => {
52
- return 'newprop'
53
- }
54
- var oldPrompt = window.prompt
55
- window.prompt = newPrompt
56
- var button = qs('.panel.full.on .add-property')
57
- expect(button).to.be.ok
58
- happen.click(button)
59
- expect(qsa('.panel.full.on div.table input').length).to.eql(6) // One per feature and per property.
60
- window.prompt = oldPrompt
61
- })
62
-
63
- it('should populate feature property on fill', () => {
64
- var input = qs(
65
- 'form#umap-feature-properties_' + L.stamp(feature) + ' input[name=newprop]'
66
- )
67
- changeInputValue(input, 'the value')
68
- expect(feature.properties.newprop).to.eql('the value')
69
- })
70
-
71
- it('should update property name on update click', () => {
72
- var newPrompt = () => {
73
- return 'newname'
74
- }
75
- var oldPrompt = window.prompt
76
- window.prompt = newPrompt
77
- var button = qs('.panel.full.on div.thead div.tcell:last-of-type .umap-edit')
78
- expect(button).to.be.ok
79
- happen.click(button)
80
- expect(qsa('.panel.full.on div.table input').length).to.eql(6)
81
- expect(feature.properties.newprop).to.be.undefined
82
- expect(feature.properties.newname).to.eql('the value')
83
- window.prompt = oldPrompt
84
- })
85
-
86
- it('should update property on delete click', () => {
87
- var oldConfirm,
88
- newConfirm = () => {
89
- return true
90
- }
91
- oldConfirm = window.confirm
92
- window.confirm = newConfirm
93
- var button = qs(
94
- '.panel.full.on div.thead div.tcell:last-of-type .umap-delete'
95
- )
96
- expect(button).to.be.ok
97
- happen.click(button)
98
- FEATURE = feature
99
- expect(qsa('.panel.full.on div.table input').length).to.eql(3)
100
- expect(feature.properties.newname).to.be.undefined
101
- window.confirm = oldConfirm
102
- })
103
- })
104
- })