umap-project 1.14.0a1__py3-none-any.whl → 1.14.0a2__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 (182) hide show
  1. umap/__init__.py +1 -1
  2. umap/static/.gitignore +0 -0
  3. umap/static/umap/base.css +994 -0
  4. umap/static/umap/bitbucket.png +0 -0
  5. umap/static/umap/content.css +395 -0
  6. umap/static/umap/favicons/apple-touch-icon.png +0 -0
  7. umap/static/umap/favicons/favicon.ico +0 -0
  8. umap/static/umap/favicons/icon-192.png +0 -0
  9. umap/static/umap/favicons/icon-512.png +0 -0
  10. umap/static/umap/favicons/icon.svg +5 -0
  11. umap/static/umap/font/FiraSans-Light.woff +0 -0
  12. umap/static/umap/font/FiraSans-Light.woff2 +0 -0
  13. umap/static/umap/font/FiraSans-LightItalic.woff +0 -0
  14. umap/static/umap/font/FiraSans-LightItalic.woff2 +0 -0
  15. umap/static/umap/font/FiraSans-SemiBold.woff +0 -0
  16. umap/static/umap/font/FiraSans-SemiBold.woff2 +0 -0
  17. umap/static/umap/font.css +33 -0
  18. umap/static/umap/github.png +0 -0
  19. umap/static/umap/img/16-white.svg +190 -0
  20. umap/static/umap/img/16.svg +182 -0
  21. umap/static/umap/img/24-white.svg +62 -0
  22. umap/static/umap/img/24.svg +90 -0
  23. umap/static/umap/img/edit.svg +7 -0
  24. umap/static/umap/img/icon-bg.png +0 -0
  25. umap/static/umap/img/logo.svg +4 -0
  26. umap/static/umap/img/logo_filigree.png +0 -0
  27. umap/static/umap/img/logo_small.svg +14 -0
  28. umap/static/umap/img/marker.png +0 -0
  29. umap/static/umap/img/opensource.svg +7 -0
  30. umap/static/umap/img/osm.svg +7 -0
  31. umap/static/umap/img/search.gif +0 -0
  32. umap/static/umap/img/source/16-white.svg +980 -0
  33. umap/static/umap/img/source/16.svg +201 -0
  34. umap/static/umap/img/source/24-white.svg +83 -0
  35. umap/static/umap/img/source/24.svg +110 -0
  36. umap/static/umap/js/components/fragment.js +13 -0
  37. umap/static/umap/js/modules/global.js +8 -0
  38. umap/static/umap/js/modules/urls.js +29 -0
  39. umap/static/umap/js/umap.autocomplete.js +336 -0
  40. umap/static/umap/js/umap.browser.js +148 -0
  41. umap/static/umap/js/umap.controls.js +1542 -0
  42. umap/static/umap/js/umap.core.js +851 -0
  43. umap/static/umap/js/umap.datalayer.permissions.js +72 -0
  44. umap/static/umap/js/umap.features.js +1216 -0
  45. umap/static/umap/js/umap.forms.js +1267 -0
  46. umap/static/umap/js/umap.icon.js +234 -0
  47. umap/static/umap/js/umap.importer.js +166 -0
  48. umap/static/umap/js/umap.js +2010 -0
  49. umap/static/umap/js/umap.layer.js +1636 -0
  50. umap/static/umap/js/umap.permissions.js +212 -0
  51. umap/static/umap/js/umap.popup.js +340 -0
  52. umap/static/umap/js/umap.share.js +254 -0
  53. umap/static/umap/js/umap.slideshow.js +165 -0
  54. umap/static/umap/js/umap.tableeditor.js +120 -0
  55. umap/static/umap/js/umap.ui.js +240 -0
  56. umap/static/umap/js/umap.xhr.js +304 -0
  57. umap/static/umap/locale/am_ET.js +447 -0
  58. umap/static/umap/locale/am_ET.json +445 -0
  59. umap/static/umap/locale/ar.js +447 -0
  60. umap/static/umap/locale/ar.json +445 -0
  61. umap/static/umap/locale/ast.js +447 -0
  62. umap/static/umap/locale/ast.json +445 -0
  63. umap/static/umap/locale/bg.js +447 -0
  64. umap/static/umap/locale/bg.json +445 -0
  65. umap/static/umap/locale/br.js +447 -0
  66. umap/static/umap/locale/br.json +445 -0
  67. umap/static/umap/locale/ca.js +447 -0
  68. umap/static/umap/locale/ca.json +445 -0
  69. umap/static/umap/locale/cs_CZ.js +447 -0
  70. umap/static/umap/locale/cs_CZ.json +445 -0
  71. umap/static/umap/locale/da.js +447 -0
  72. umap/static/umap/locale/da.json +445 -0
  73. umap/static/umap/locale/de.js +447 -0
  74. umap/static/umap/locale/de.json +445 -0
  75. umap/static/umap/locale/el.js +447 -0
  76. umap/static/umap/locale/el.json +445 -0
  77. umap/static/umap/locale/en.js +447 -0
  78. umap/static/umap/locale/en.json +445 -0
  79. umap/static/umap/locale/en_US.json +445 -0
  80. umap/static/umap/locale/es.js +447 -0
  81. umap/static/umap/locale/es.json +445 -0
  82. umap/static/umap/locale/et.js +447 -0
  83. umap/static/umap/locale/et.json +445 -0
  84. umap/static/umap/locale/eu.js +413 -0
  85. umap/static/umap/locale/eu.json +411 -0
  86. umap/static/umap/locale/fa_IR.js +447 -0
  87. umap/static/umap/locale/fa_IR.json +445 -0
  88. umap/static/umap/locale/fi.js +447 -0
  89. umap/static/umap/locale/fi.json +445 -0
  90. umap/static/umap/locale/fr.js +447 -0
  91. umap/static/umap/locale/fr.json +445 -0
  92. umap/static/umap/locale/gl.js +447 -0
  93. umap/static/umap/locale/gl.json +445 -0
  94. umap/static/umap/locale/he.js +447 -0
  95. umap/static/umap/locale/he.json +445 -0
  96. umap/static/umap/locale/hr.js +447 -0
  97. umap/static/umap/locale/hr.json +445 -0
  98. umap/static/umap/locale/hu.js +447 -0
  99. umap/static/umap/locale/hu.json +445 -0
  100. umap/static/umap/locale/id.js +447 -0
  101. umap/static/umap/locale/id.json +445 -0
  102. umap/static/umap/locale/is.js +447 -0
  103. umap/static/umap/locale/is.json +445 -0
  104. umap/static/umap/locale/it.js +447 -0
  105. umap/static/umap/locale/it.json +445 -0
  106. umap/static/umap/locale/ja.js +447 -0
  107. umap/static/umap/locale/ja.json +445 -0
  108. umap/static/umap/locale/ko.js +447 -0
  109. umap/static/umap/locale/ko.json +445 -0
  110. umap/static/umap/locale/lt.js +447 -0
  111. umap/static/umap/locale/lt.json +445 -0
  112. umap/static/umap/locale/ms.js +447 -0
  113. umap/static/umap/locale/ms.json +445 -0
  114. umap/static/umap/locale/nl.js +447 -0
  115. umap/static/umap/locale/nl.json +445 -0
  116. umap/static/umap/locale/no.js +447 -0
  117. umap/static/umap/locale/no.json +445 -0
  118. umap/static/umap/locale/pl.js +447 -0
  119. umap/static/umap/locale/pl.json +445 -0
  120. umap/static/umap/locale/pl_PL.json +445 -0
  121. umap/static/umap/locale/pt.js +447 -0
  122. umap/static/umap/locale/pt.json +445 -0
  123. umap/static/umap/locale/pt_BR.js +447 -0
  124. umap/static/umap/locale/pt_BR.json +445 -0
  125. umap/static/umap/locale/pt_PT.js +447 -0
  126. umap/static/umap/locale/pt_PT.json +445 -0
  127. umap/static/umap/locale/ro.js +447 -0
  128. umap/static/umap/locale/ro.json +445 -0
  129. umap/static/umap/locale/ru.js +447 -0
  130. umap/static/umap/locale/ru.json +445 -0
  131. umap/static/umap/locale/si.js +439 -0
  132. umap/static/umap/locale/si.json +437 -0
  133. umap/static/umap/locale/sk_SK.js +447 -0
  134. umap/static/umap/locale/sk_SK.json +445 -0
  135. umap/static/umap/locale/sl.js +447 -0
  136. umap/static/umap/locale/sl.json +445 -0
  137. umap/static/umap/locale/sr.js +447 -0
  138. umap/static/umap/locale/sr.json +445 -0
  139. umap/static/umap/locale/sv.js +447 -0
  140. umap/static/umap/locale/sv.json +445 -0
  141. umap/static/umap/locale/th_TH.js +447 -0
  142. umap/static/umap/locale/th_TH.json +445 -0
  143. umap/static/umap/locale/tr.js +447 -0
  144. umap/static/umap/locale/tr.json +445 -0
  145. umap/static/umap/locale/uk_UA.js +447 -0
  146. umap/static/umap/locale/uk_UA.json +445 -0
  147. umap/static/umap/locale/vi.js +447 -0
  148. umap/static/umap/locale/vi.json +445 -0
  149. umap/static/umap/locale/vi_VN.json +445 -0
  150. umap/static/umap/locale/zh.js +447 -0
  151. umap/static/umap/locale/zh.json +445 -0
  152. umap/static/umap/locale/zh_CN.json +445 -0
  153. umap/static/umap/locale/zh_TW.Big5.json +445 -0
  154. umap/static/umap/locale/zh_TW.js +447 -0
  155. umap/static/umap/locale/zh_TW.json +445 -0
  156. umap/static/umap/map.css +1843 -0
  157. umap/static/umap/nav.css +81 -0
  158. umap/static/umap/openstreetmap.png +0 -0
  159. umap/static/umap/test/.eslintrc +22 -0
  160. umap/static/umap/test/Choropleth.js +243 -0
  161. umap/static/umap/test/Controls.js +100 -0
  162. umap/static/umap/test/DataLayer.js +495 -0
  163. umap/static/umap/test/Feature.js +382 -0
  164. umap/static/umap/test/Map.Export.js +106 -0
  165. umap/static/umap/test/Map.Init.js +46 -0
  166. umap/static/umap/test/Map.js +342 -0
  167. umap/static/umap/test/Marker.js +122 -0
  168. umap/static/umap/test/Permissions.js +74 -0
  169. umap/static/umap/test/Polygon.js +367 -0
  170. umap/static/umap/test/Polyline.js +402 -0
  171. umap/static/umap/test/TableEditor.js +100 -0
  172. umap/static/umap/test/URLs.js +54 -0
  173. umap/static/umap/test/Util.js +549 -0
  174. umap/static/umap/test/_pre.js +460 -0
  175. umap/static/umap/test/index.html +135 -0
  176. umap/static/umap/theme.css +1 -0
  177. umap/static/umap/twitter.png +0 -0
  178. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/METADATA +1 -1
  179. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/RECORD +182 -6
  180. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/WHEEL +0 -0
  181. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/entry_points.txt +0 -0
  182. {umap_project-1.14.0a1.dist-info → umap_project-1.14.0a2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,240 @@
1
+ /*
2
+ * Modals
3
+ */
4
+ L.U.UI = L.Evented.extend({
5
+ ALERTS: Array(),
6
+ ALERT_ID: null,
7
+ TOOLTIP_ID: null,
8
+
9
+ initialize: function (parent) {
10
+ this.parent = parent
11
+ this.container = L.DomUtil.create('div', 'leaflet-ui-container', this.parent)
12
+ L.DomEvent.disableClickPropagation(this.container)
13
+ L.DomEvent.on(this.container, 'contextmenu', L.DomEvent.stopPropagation) // Do not activate our custom context menu.
14
+ L.DomEvent.on(this.container, 'wheel', L.DomEvent.stopPropagation)
15
+ L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation)
16
+ this._panel = L.DomUtil.create('div', '', this.container)
17
+ this._panel.id = 'umap-ui-container'
18
+ this._alert = L.DomUtil.create('div', 'with-transition', this.container)
19
+ this._alert.id = 'umap-alert-container'
20
+ this._tooltip = L.DomUtil.create('div', '', this.container)
21
+ this._tooltip.id = 'umap-tooltip-container'
22
+ },
23
+
24
+ resetPanelClassName: function () {
25
+ this._panel.className = 'with-transition'
26
+ },
27
+
28
+ openPanel: function (e) {
29
+ this.fire('panel:open')
30
+ // We reset all because we can't know which class has been added
31
+ // by previous ui processes...
32
+ this.resetPanelClassName()
33
+ this._panel.innerHTML = ''
34
+ const actionsContainer = L.DomUtil.create('ul', 'toolbox', this._panel)
35
+ const body = L.DomUtil.create('div', 'body', this._panel)
36
+ if (e.data.html.nodeType && e.data.html.nodeType === 1)
37
+ body.appendChild(e.data.html)
38
+ else body.innerHTML = e.data.html
39
+ const closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer)
40
+ L.DomUtil.add('i', 'umap-close-icon', closeLink)
41
+ const label = L.DomUtil.create('span', '', closeLink)
42
+ label.title = label.textContent = L._('Close')
43
+ if (e.actions) {
44
+ for (let i = 0; i < e.actions.length; i++) {
45
+ actionsContainer.appendChild(e.actions[i])
46
+ }
47
+ }
48
+ if (e.className) L.DomUtil.addClass(this._panel, e.className)
49
+ if (L.DomUtil.hasClass(this.parent, 'umap-ui')) {
50
+ // Already open.
51
+ this.fire('panel:ready')
52
+ } else {
53
+ L.DomEvent.once(
54
+ this._panel,
55
+ 'transitionend',
56
+ function (e) {
57
+ this.fire('panel:ready')
58
+ },
59
+ this
60
+ )
61
+ L.DomUtil.addClass(this.parent, 'umap-ui')
62
+ }
63
+ L.DomEvent.on(closeLink, 'click', this.closePanel, this)
64
+ },
65
+
66
+ closePanel: function () {
67
+ if (L.DomUtil.hasClass(this.parent, 'umap-ui')) {
68
+ L.DomUtil.removeClass(this.parent, 'umap-ui')
69
+ this.fire('panel:closed')
70
+ }
71
+ },
72
+
73
+ alert: function (e) {
74
+ if (L.DomUtil.hasClass(this.parent, 'umap-alert')) this.ALERTS.push(e)
75
+ else this.popAlert(e)
76
+ },
77
+
78
+ popAlert: function (e) {
79
+ if (!e) {
80
+ if (this.ALERTS.length) e = this.ALERTS.pop()
81
+ else return
82
+ }
83
+ let timeoutID
84
+ const level_class = e.level && e.level == 'info' ? 'info' : 'error'
85
+ this._alert.innerHTML = ''
86
+ L.DomUtil.addClass(this.parent, 'umap-alert')
87
+ L.DomUtil.addClass(this._alert, level_class)
88
+ const close = () => {
89
+ if (timeoutID && timeoutID !== this.ALERT_ID) {
90
+ return
91
+ } // Another alert has been forced
92
+ this._alert.innerHTML = ''
93
+ L.DomUtil.removeClass(this.parent, 'umap-alert')
94
+ L.DomUtil.removeClass(this._alert, level_class)
95
+ if (timeoutID) window.clearTimeout(timeoutID)
96
+ this.popAlert()
97
+ }
98
+ const closeButton = L.DomUtil.createButton(
99
+ 'umap-close-link',
100
+ this._alert,
101
+ '',
102
+ close,
103
+ this
104
+ )
105
+ L.DomUtil.add('i', 'umap-close-icon', closeButton)
106
+ const label = L.DomUtil.create('span', '', closeButton)
107
+ label.title = label.textContent = L._('Close')
108
+ L.DomUtil.add('div', '', this._alert, e.content)
109
+ if (e.actions) {
110
+ let action, el, input
111
+ const form = L.DomUtil.add('div', 'umap-alert-actions', this._alert)
112
+ for (let i = 0; i < e.actions.length; i++) {
113
+ action = e.actions[i]
114
+ if (action.input) {
115
+ input = L.DomUtil.element(
116
+ 'input',
117
+ { className: 'umap-alert-input', placeholder: action.input },
118
+ form
119
+ )
120
+ }
121
+ el = L.DomUtil.createButton(
122
+ 'umap-action',
123
+ form,
124
+ action.label,
125
+ action.callback,
126
+ action.callbackContext || this.map
127
+ )
128
+ L.DomEvent.on(el, 'click', close, this)
129
+ }
130
+ }
131
+ if (e.duration !== Infinity) {
132
+ this.ALERT_ID = timeoutID = window.setTimeout(
133
+ L.bind(close, this),
134
+ e.duration || 3000
135
+ )
136
+ }
137
+ },
138
+
139
+ tooltip: function (opts) {
140
+ function showIt() {
141
+ if (opts.anchor && opts.position === 'top') {
142
+ this.anchorTooltipTop(opts.anchor)
143
+ } else if (opts.anchor && opts.position === 'left') {
144
+ this.anchorTooltipLeft(opts.anchor)
145
+ } else if (opts.anchor && opts.position === 'bottom') {
146
+ this.anchorTooltipBottom(opts.anchor)
147
+ } else {
148
+ this.anchorTooltipAbsolute()
149
+ }
150
+ L.DomUtil.addClass(this.parent, 'umap-tooltip')
151
+ this._tooltip.innerHTML = opts.content
152
+ }
153
+ this.TOOLTIP_ID = window.setTimeout(L.bind(showIt, this), opts.delay || 0)
154
+ const id = this.TOOLTIP_ID
155
+ function closeIt() {
156
+ this.closeTooltip(id)
157
+ }
158
+ if (opts.anchor) {
159
+ L.DomEvent.once(opts.anchor, 'mouseout', closeIt, this)
160
+ }
161
+ if (opts.duration !== Infinity) {
162
+ window.setTimeout(L.bind(closeIt, this), opts.duration || 3000)
163
+ }
164
+ },
165
+
166
+ anchorTooltipAbsolute: function () {
167
+ this._tooltip.className = ''
168
+ const left =
169
+ this.parent.offsetLeft +
170
+ this.parent.clientWidth / 2 -
171
+ this._tooltip.clientWidth / 2,
172
+ top = this.parent.offsetTop + 75
173
+ this.setTooltipPosition({ top: top, left: left })
174
+ },
175
+
176
+ anchorTooltipTop: function (el) {
177
+ this._tooltip.className = 'tooltip-top'
178
+ const coords = this.getPosition(el)
179
+ this.setTooltipPosition({
180
+ left: coords.left - 10,
181
+ bottom: this.getDocHeight() - coords.top + 11,
182
+ })
183
+ },
184
+
185
+ anchorTooltipBottom: function (el) {
186
+ this._tooltip.className = 'tooltip-bottom'
187
+ const coords = this.getPosition(el)
188
+ this.setTooltipPosition({
189
+ left: coords.left,
190
+ top: coords.bottom + 11,
191
+ })
192
+ },
193
+
194
+ anchorTooltipLeft: function (el) {
195
+ this._tooltip.className = 'tooltip-left'
196
+ const coords = this.getPosition(el)
197
+ this.setTooltipPosition({
198
+ top: coords.top,
199
+ right: document.documentElement.offsetWidth - coords.left + 11,
200
+ })
201
+ },
202
+
203
+ closeTooltip: function (id) {
204
+ // Clear timetout even if a new tooltip has been added
205
+ // in the meantime. Eg. after a mouseout from the anchor.
206
+ window.clearTimeout(id)
207
+ if (id && id !== this.TOOLTIP_ID) return
208
+ this._tooltip.className = ''
209
+ this._tooltip.innerHTML = ''
210
+ this.setTooltipPosition({})
211
+ L.DomUtil.removeClass(this.parent, 'umap-tooltip')
212
+ },
213
+
214
+ getPosition: function (el) {
215
+ return el.getBoundingClientRect()
216
+ },
217
+
218
+ setTooltipPosition: function (coords) {
219
+ if (coords.left) this._tooltip.style.left = `${coords.left}px`
220
+ else this._tooltip.style.left = 'initial'
221
+ if (coords.right) this._tooltip.style.right = `${coords.right}px`
222
+ else this._tooltip.style.right = 'initial'
223
+ if (coords.top) this._tooltip.style.top = `${coords.top}px`
224
+ else this._tooltip.style.top = 'initial'
225
+ if (coords.bottom) this._tooltip.style.bottom = `${coords.bottom}px`
226
+ else this._tooltip.style.bottom = 'initial'
227
+ },
228
+
229
+ getDocHeight: function () {
230
+ const D = document
231
+ return Math.max(
232
+ D.body.scrollHeight,
233
+ D.documentElement.scrollHeight,
234
+ D.body.offsetHeight,
235
+ D.documentElement.offsetHeight,
236
+ D.body.clientHeight,
237
+ D.documentElement.clientHeight
238
+ )
239
+ },
240
+ })
@@ -0,0 +1,304 @@
1
+ L.U.Xhr = L.Evented.extend({
2
+ initialize: function (ui) {
3
+ this.ui = ui
4
+ },
5
+
6
+ _wrapper: function () {
7
+ let wrapper
8
+ if (window.XMLHttpRequest === undefined) {
9
+ wrapper = () => {
10
+ try {
11
+ return new window.ActiveXObject('Microsoft.XMLHTTP.6.0')
12
+ } catch (e1) {
13
+ try {
14
+ return new window.ActiveXObject('Microsoft.XMLHTTP.3.0')
15
+ } catch (e2) {
16
+ throw new Error('XMLHttpRequest is not supported')
17
+ }
18
+ }
19
+ }
20
+ } else {
21
+ wrapper = window.XMLHttpRequest
22
+ }
23
+ return new wrapper()
24
+ },
25
+
26
+ _ajax: function (settings) {
27
+ const xhr = this._wrapper(),
28
+ id = Math.random(),
29
+ self = this
30
+ this.fire('dataloading', { id: id })
31
+ const loaded = () => {
32
+ self.fire('dataload', { id: id })
33
+ }
34
+
35
+ try {
36
+ xhr.open(settings.verb, settings.uri, true)
37
+ } catch (err) {
38
+ // Unknown protocol?
39
+ this.ui.alert({
40
+ content: L._('Error while fetching {url}', { url: settings.uri }),
41
+ level: 'error',
42
+ })
43
+ loaded()
44
+ return
45
+ }
46
+
47
+ if (
48
+ settings.uri.indexOf('http') !== 0 ||
49
+ settings.uri.indexOf(window.location.origin) === 0
50
+ ) {
51
+ // "X-" mode headers cause the request to be in preflight mode,
52
+ // we don"t want that by default for CORS requests
53
+ xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
54
+ }
55
+ if (settings.headers) {
56
+ for (const name in settings.headers) {
57
+ xhr.setRequestHeader(name, settings.headers[name])
58
+ }
59
+ }
60
+
61
+ xhr.onreadystatechange = () => {
62
+ if (xhr.readyState === 4) {
63
+ if (xhr.status == 200) {
64
+ settings.callback.call(settings.context || xhr, xhr.responseText, xhr)
65
+ } else if (xhr.status === 403) {
66
+ self.ui.alert({
67
+ content: xhr.responseText || L._('Action not allowed :('),
68
+ level: 'error',
69
+ })
70
+ } else if (xhr.status === 412) {
71
+ const msg = L._(
72
+ 'Woops! Someone else seems to have edited the data. You can save anyway, but this will erase the changes made by others.'
73
+ )
74
+ const actions = [
75
+ {
76
+ label: L._('Save anyway'),
77
+ callback: function () {
78
+ delete settings.headers['If-Match']
79
+ self._ajax(settings)
80
+ },
81
+ callbackContext: self,
82
+ },
83
+ {
84
+ label: L._('Cancel'),
85
+ },
86
+ ]
87
+ self.ui.alert({
88
+ content: msg,
89
+ level: 'error',
90
+ duration: 100000,
91
+ actions: actions,
92
+ })
93
+ } else {
94
+ if (xhr.status === 0) {
95
+ // 0 === request cut by user or CORS
96
+ self.ui.alert({
97
+ content: L._(
98
+ 'Issue reaching that URL (network problem or CORS protection): {url}',
99
+ { url: settings.uri }
100
+ ),
101
+ level: 'error',
102
+ })
103
+ } else {
104
+ self.ui.alert({ content: L._('Problem in the response'), level: 'error' })
105
+ }
106
+ }
107
+ loaded()
108
+ }
109
+ }
110
+
111
+ try {
112
+ xhr.send(settings.data)
113
+ } catch (e) {
114
+ // Pass
115
+ loaded()
116
+ console.error('Bad Request', e)
117
+ }
118
+ },
119
+
120
+ // supports only JSON as response data type
121
+ _json: function (verb, uri, options) {
122
+ const args = arguments,
123
+ self = this
124
+ const default_options = {
125
+ async: true,
126
+ callback: null,
127
+ responseType: 'text',
128
+ data: null,
129
+ listen_form: null, // optional form to listen in default callback
130
+ }
131
+ const settings = L.Util.extend({}, default_options, options)
132
+
133
+ if (verb === 'POST') {
134
+ // find a way not to make this django specific
135
+ const token = document.cookie.replace(
136
+ /(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/,
137
+ '$1'
138
+ )
139
+ if (token) {
140
+ settings.headers = settings.headers || {}
141
+ settings.headers['X-CSRFToken'] = token
142
+ }
143
+ }
144
+
145
+ const callback = function (responseText, response) {
146
+ let data
147
+ try {
148
+ data = JSON.parse(responseText)
149
+ } catch (err) {
150
+ console.log(err)
151
+ self.ui.alert({
152
+ content: L._('Problem in the response format'),
153
+ level: 'error',
154
+ })
155
+ return
156
+ }
157
+ if (data.errors) {
158
+ console.log(data.errors)
159
+ self.ui.alert({ content: L._('An error occured'), level: 'error' })
160
+ } else if (data.login_required) {
161
+ // login_required should be an URL for the login form
162
+ if (settings.login_callback) settings.login_callback(data)
163
+ else self.login(data, args)
164
+ } else {
165
+ if (settings.callback)
166
+ L.bind(settings.callback, settings.context || this)(data, response)
167
+ else self.default_callback(data, settings, response)
168
+ }
169
+ }
170
+
171
+ this._ajax({
172
+ verb: verb,
173
+ uri: uri,
174
+ data: settings.data,
175
+ callback: callback,
176
+ headers: settings.headers,
177
+ listener: settings.listener,
178
+ })
179
+ },
180
+
181
+ get: function (uri, options) {
182
+ this._json('GET', uri, options)
183
+ },
184
+
185
+ post: function (uri, options) {
186
+ this._json('POST', uri, options)
187
+ },
188
+
189
+ submit_form: function (form_id, options) {
190
+ if (typeof options === 'undefined') options = {}
191
+ const form = L.DomUtil.get(form_id)
192
+ const formData = new FormData(form)
193
+ if (options.extraFormData) formData.append(options.extraFormData)
194
+ options.data = formData
195
+ this.post(form.action, options)
196
+ return false
197
+ },
198
+
199
+ listen_form: function (form_id, options) {
200
+ const form = L.DomUtil.get(form_id),
201
+ self = this
202
+ if (!form) return
203
+ L.DomEvent.on(form, 'submit', L.DomEvent.stopPropagation)
204
+ .on(form, 'submit', L.DomEvent.preventDefault)
205
+ .on(form, 'submit', () => {
206
+ self.submit_form(form_id, options)
207
+ })
208
+ },
209
+
210
+ listen_link: function (link_id, options) {
211
+ const link = L.DomUtil.get(link_id),
212
+ self = this
213
+ if (link) {
214
+ L.DomEvent.on(link, 'click', L.DomEvent.stop).on(link, 'click', () => {
215
+ if (options.confirm && !confirm(options.confirm)) {
216
+ return
217
+ }
218
+ self.get(link.href, options)
219
+ })
220
+ }
221
+ },
222
+
223
+ default_callback: function (data, options) {
224
+ // default callback, to avoid boilerplate
225
+ if (data.redirect) {
226
+ const newPath = data.redirect
227
+ if (window.location.pathname == newPath)
228
+ window.location.reload() // Keep the hash, so the current view
229
+ else window.location = newPath
230
+ } else if (data.info) {
231
+ this.ui.alert({ content: data.info, level: 'info' })
232
+ this.ui.closePanel()
233
+ } else if (data.error) {
234
+ this.ui.alert({ content: data.error, level: 'error' })
235
+ } else if (data.html) {
236
+ const ui_options = { data: data }
237
+ let listen_options
238
+ if (options.className) ui_options.className = options.className
239
+ this.ui.openPanel(ui_options)
240
+ // To low boilerplate, if there is a form, listen it
241
+ if (options.listen_form) {
242
+ // Listen form again
243
+ listen_options = L.Util.extend({}, options, options.listen_form.options)
244
+ this.listen_form(options.listen_form.id, listen_options)
245
+ }
246
+ if (options.listen_link) {
247
+ for (let i = 0, l = options.listen_link.length; i < l; i++) {
248
+ // Listen link again
249
+ listen_options = L.Util.extend({}, options, options.listen_link[i].options)
250
+ this.listen_link(options.listen_link[i].id, listen_options)
251
+ }
252
+ }
253
+ } else if (options.success) {
254
+ // Success is called only if data contain no msg and no html
255
+ options.success(data)
256
+ }
257
+ },
258
+
259
+ login: function (data, args) {
260
+ // data.html: login form
261
+ // args: args of the first _json call, to call again at process end
262
+ const self = this
263
+ const proceed = () => {
264
+ self.ui.closePanel()
265
+ if (typeof args !== 'undefined') self._json.apply(self, args)
266
+ else self.default_callback(data, {})
267
+ }
268
+ const ask_for_login = (data) => {
269
+ self.ui.openPanel({ data: data, className: 'login-panel' })
270
+ self.listen_form('login_form', {
271
+ callback: function (data) {
272
+ if (data.html) ask_for_login(data) // Problem in the login - ask again
273
+ else proceed()
274
+ },
275
+ })
276
+ // Auth links
277
+ const links = document.getElementsByClassName('umap-login-popup')
278
+ Object.keys(links).forEach((el) => {
279
+ const link = links[el]
280
+ L.DomEvent.on(link, 'click', L.DomEvent.stop).on(link, 'click', () => {
281
+ self.ui.closePanel()
282
+ const win = window.open(link.href)
283
+ window.umap_proceed = () => {
284
+ proceed()
285
+ win.close()
286
+ }
287
+ })
288
+ })
289
+ }
290
+ if (data.login_required) {
291
+ this.get(data.login_required, {
292
+ callback: function (data) {
293
+ ask_for_login(data)
294
+ },
295
+ })
296
+ } else {
297
+ ask_for_login(data)
298
+ }
299
+ },
300
+
301
+ logout: function (url) {
302
+ this.get(url)
303
+ },
304
+ })