decidim 0.26.9 → 0.26.10

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim might be problematic. Click here for more details.

Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/lib/decidim/version.rb +1 -1
  3. data/package-lock.json +7 -7
  4. data/packages/browserslist-config/package.json +1 -1
  5. data/packages/core/node_modules/leaflet/CHANGELOG.md +2191 -0
  6. data/packages/core/node_modules/leaflet/LICENSE +26 -0
  7. data/packages/core/node_modules/leaflet/README.md +55 -0
  8. data/packages/core/node_modules/leaflet/dist/images/layers-2x.png +0 -0
  9. data/packages/core/node_modules/leaflet/dist/images/layers.png +0 -0
  10. data/packages/core/node_modules/leaflet/dist/images/marker-icon-2x.png +0 -0
  11. data/packages/core/node_modules/leaflet/dist/images/marker-icon.png +0 -0
  12. data/packages/core/node_modules/leaflet/dist/images/marker-shadow.png +0 -0
  13. data/packages/core/node_modules/leaflet/dist/leaflet-src.esm.js +14419 -0
  14. data/packages/core/node_modules/leaflet/dist/leaflet-src.esm.js.map +1 -0
  15. data/packages/core/node_modules/leaflet/dist/leaflet-src.js +14512 -0
  16. data/packages/core/node_modules/leaflet/dist/leaflet-src.js.map +1 -0
  17. data/packages/core/node_modules/leaflet/dist/leaflet.css +661 -0
  18. data/packages/core/node_modules/leaflet/dist/leaflet.js +6 -0
  19. data/packages/core/node_modules/leaflet/dist/leaflet.js.map +1 -0
  20. data/packages/core/node_modules/leaflet/package.json +149 -0
  21. data/packages/core/node_modules/leaflet/src/Leaflet.js +24 -0
  22. data/packages/core/node_modules/leaflet/src/control/Control.Attribution.js +148 -0
  23. data/packages/core/node_modules/leaflet/src/control/Control.Layers.js +443 -0
  24. data/packages/core/node_modules/leaflet/src/control/Control.Scale.js +132 -0
  25. data/packages/core/node_modules/leaflet/src/control/Control.Zoom.js +146 -0
  26. data/packages/core/node_modules/leaflet/src/control/Control.js +174 -0
  27. data/packages/core/node_modules/leaflet/src/control/index.js +17 -0
  28. data/packages/core/node_modules/leaflet/src/core/Browser.js +220 -0
  29. data/packages/core/node_modules/leaflet/src/core/Class.js +135 -0
  30. data/packages/core/node_modules/leaflet/src/core/Class.leafdoc +197 -0
  31. data/packages/core/node_modules/leaflet/src/core/Events.js +344 -0
  32. data/packages/core/node_modules/leaflet/src/core/Events.leafdoc +143 -0
  33. data/packages/core/node_modules/leaflet/src/core/Handler.js +57 -0
  34. data/packages/core/node_modules/leaflet/src/core/Util.js +241 -0
  35. data/packages/core/node_modules/leaflet/src/core/index.js +15 -0
  36. data/packages/core/node_modules/leaflet/src/dom/DomEvent.DoubleTap.js +91 -0
  37. data/packages/core/node_modules/leaflet/src/dom/DomEvent.Pointer.js +97 -0
  38. data/packages/core/node_modules/leaflet/src/dom/DomEvent.js +315 -0
  39. data/packages/core/node_modules/leaflet/src/dom/DomUtil.js +349 -0
  40. data/packages/core/node_modules/leaflet/src/dom/Draggable.js +220 -0
  41. data/packages/core/node_modules/leaflet/src/dom/PosAnimation.js +113 -0
  42. data/packages/core/node_modules/leaflet/src/dom/index.js +9 -0
  43. data/packages/core/node_modules/leaflet/src/geo/LatLng.js +137 -0
  44. data/packages/core/node_modules/leaflet/src/geo/LatLngBounds.js +251 -0
  45. data/packages/core/node_modules/leaflet/src/geo/crs/CRS.EPSG3395.js +20 -0
  46. data/packages/core/node_modules/leaflet/src/geo/crs/CRS.EPSG3857.js +27 -0
  47. data/packages/core/node_modules/leaflet/src/geo/crs/CRS.EPSG4326.js +23 -0
  48. data/packages/core/node_modules/leaflet/src/geo/crs/CRS.Earth.js +33 -0
  49. data/packages/core/node_modules/leaflet/src/geo/crs/CRS.Simple.js +36 -0
  50. data/packages/core/node_modules/leaflet/src/geo/crs/CRS.js +139 -0
  51. data/packages/core/node_modules/leaflet/src/geo/crs/index.js +15 -0
  52. data/packages/core/node_modules/leaflet/src/geo/index.js +7 -0
  53. data/packages/core/node_modules/leaflet/src/geo/projection/Projection.LonLat.js +28 -0
  54. data/packages/core/node_modules/leaflet/src/geo/projection/Projection.Mercator.js +49 -0
  55. data/packages/core/node_modules/leaflet/src/geo/projection/Projection.SphericalMercator.js +44 -0
  56. data/packages/core/node_modules/leaflet/src/geo/projection/index.js +26 -0
  57. data/packages/core/node_modules/leaflet/src/geometry/Bounds.js +219 -0
  58. data/packages/core/node_modules/leaflet/src/geometry/LineUtil.js +306 -0
  59. data/packages/core/node_modules/leaflet/src/geometry/Point.js +222 -0
  60. data/packages/core/node_modules/leaflet/src/geometry/PolyUtil.js +129 -0
  61. data/packages/core/node_modules/leaflet/src/geometry/Transformation.js +79 -0
  62. data/packages/core/node_modules/leaflet/src/geometry/index.js +8 -0
  63. data/packages/core/node_modules/leaflet/src/images/layers.svg +1 -0
  64. data/packages/core/node_modules/leaflet/src/images/logo.svg +1 -0
  65. data/packages/core/node_modules/leaflet/src/images/marker.svg +1 -0
  66. data/packages/core/node_modules/leaflet/src/layer/DivOverlay.js +348 -0
  67. data/packages/core/node_modules/leaflet/src/layer/FeatureGroup.js +94 -0
  68. data/packages/core/node_modules/leaflet/src/layer/GeoJSON.js +452 -0
  69. data/packages/core/node_modules/leaflet/src/layer/ImageOverlay.js +270 -0
  70. data/packages/core/node_modules/leaflet/src/layer/Layer.Interactive.leafdoc +39 -0
  71. data/packages/core/node_modules/leaflet/src/layer/Layer.js +275 -0
  72. data/packages/core/node_modules/leaflet/src/layer/LayerGroup.js +159 -0
  73. data/packages/core/node_modules/leaflet/src/layer/Popup.js +506 -0
  74. data/packages/core/node_modules/leaflet/src/layer/SVGOverlay.js +50 -0
  75. data/packages/core/node_modules/leaflet/src/layer/Tooltip.js +444 -0
  76. data/packages/core/node_modules/leaflet/src/layer/VideoOverlay.js +106 -0
  77. data/packages/core/node_modules/leaflet/src/layer/index.js +24 -0
  78. data/packages/core/node_modules/leaflet/src/layer/marker/DivIcon.js +74 -0
  79. data/packages/core/node_modules/leaflet/src/layer/marker/Icon.Default.js +66 -0
  80. data/packages/core/node_modules/leaflet/src/layer/marker/Icon.js +165 -0
  81. data/packages/core/node_modules/leaflet/src/layer/marker/Marker.Drag.js +161 -0
  82. data/packages/core/node_modules/leaflet/src/layer/marker/Marker.js +419 -0
  83. data/packages/core/node_modules/leaflet/src/layer/marker/index.js +8 -0
  84. data/packages/core/node_modules/leaflet/src/layer/tile/GridLayer.js +923 -0
  85. data/packages/core/node_modules/leaflet/src/layer/tile/TileLayer.WMS.js +137 -0
  86. data/packages/core/node_modules/leaflet/src/layer/tile/TileLayer.js +289 -0
  87. data/packages/core/node_modules/leaflet/src/layer/tile/index.js +6 -0
  88. data/packages/core/node_modules/leaflet/src/layer/vector/Canvas.js +492 -0
  89. data/packages/core/node_modules/leaflet/src/layer/vector/Circle.js +113 -0
  90. data/packages/core/node_modules/leaflet/src/layer/vector/CircleMarker.js +109 -0
  91. data/packages/core/node_modules/leaflet/src/layer/vector/Path.js +148 -0
  92. data/packages/core/node_modules/leaflet/src/layer/vector/Polygon.js +159 -0
  93. data/packages/core/node_modules/leaflet/src/layer/vector/Polyline.js +307 -0
  94. data/packages/core/node_modules/leaflet/src/layer/vector/Rectangle.js +57 -0
  95. data/packages/core/node_modules/leaflet/src/layer/vector/Renderer.getRenderer.js +45 -0
  96. data/packages/core/node_modules/leaflet/src/layer/vector/Renderer.js +133 -0
  97. data/packages/core/node_modules/leaflet/src/layer/vector/SVG.Util.js +39 -0
  98. data/packages/core/node_modules/leaflet/src/layer/vector/SVG.VML.js +144 -0
  99. data/packages/core/node_modules/leaflet/src/layer/vector/SVG.js +207 -0
  100. data/packages/core/node_modules/leaflet/src/layer/vector/index.js +14 -0
  101. data/packages/core/node_modules/leaflet/src/map/Map.js +1751 -0
  102. data/packages/core/node_modules/leaflet/src/map/Map.methodOptions.leafdoc +112 -0
  103. data/packages/core/node_modules/leaflet/src/map/handler/Map.BoxZoom.js +152 -0
  104. data/packages/core/node_modules/leaflet/src/map/handler/Map.DoubleClickZoom.js +55 -0
  105. data/packages/core/node_modules/leaflet/src/map/handler/Map.Drag.js +235 -0
  106. data/packages/core/node_modules/leaflet/src/map/handler/Map.Keyboard.js +183 -0
  107. data/packages/core/node_modules/leaflet/src/map/handler/Map.ScrollWheelZoom.js +91 -0
  108. data/packages/core/node_modules/leaflet/src/map/handler/Map.TapHold.js +102 -0
  109. data/packages/core/node_modules/leaflet/src/map/handler/Map.TouchZoom.js +130 -0
  110. data/packages/core/node_modules/leaflet/src/map/index.js +17 -0
  111. data/packages/core/package.json +1 -1
  112. data/packages/dev/package.json +1 -1
  113. data/packages/elections/package.json +1 -1
  114. data/packages/eslint-config/package.json +1 -1
  115. data/packages/stylelint-config/package.json +1 -1
  116. data/packages/webpacker/package.json +1 -1
  117. metadata +148 -42
@@ -0,0 +1,923 @@
1
+ import {Layer} from '../Layer';
2
+ import Browser from '../../core/Browser';
3
+ import * as Util from '../../core/Util';
4
+ import * as DomUtil from '../../dom/DomUtil';
5
+ import {Point} from '../../geometry/Point';
6
+ import {Bounds} from '../../geometry/Bounds';
7
+ import {LatLngBounds, toLatLngBounds as latLngBounds} from '../../geo/LatLngBounds';
8
+
9
+ /*
10
+ * @class GridLayer
11
+ * @inherits Layer
12
+ * @aka L.GridLayer
13
+ *
14
+ * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`.
15
+ * GridLayer can be extended to create a tiled grid of HTML elements like `<canvas>`, `<img>` or `<div>`. GridLayer will handle creating and animating these DOM elements for you.
16
+ *
17
+ *
18
+ * @section Synchronous usage
19
+ * @example
20
+ *
21
+ * To create a custom layer, extend GridLayer and implement the `createTile()` method, which will be passed a `Point` object with the `x`, `y`, and `z` (zoom level) coordinates to draw your tile.
22
+ *
23
+ * ```js
24
+ * var CanvasLayer = L.GridLayer.extend({
25
+ * createTile: function(coords){
26
+ * // create a <canvas> element for drawing
27
+ * var tile = L.DomUtil.create('canvas', 'leaflet-tile');
28
+ *
29
+ * // setup tile width and height according to the options
30
+ * var size = this.getTileSize();
31
+ * tile.width = size.x;
32
+ * tile.height = size.y;
33
+ *
34
+ * // get a canvas context and draw something on it using coords.x, coords.y and coords.z
35
+ * var ctx = tile.getContext('2d');
36
+ *
37
+ * // return the tile so it can be rendered on screen
38
+ * return tile;
39
+ * }
40
+ * });
41
+ * ```
42
+ *
43
+ * @section Asynchronous usage
44
+ * @example
45
+ *
46
+ * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. Once the tile is finished drawing it can be passed to the `done()` callback.
47
+ *
48
+ * ```js
49
+ * var CanvasLayer = L.GridLayer.extend({
50
+ * createTile: function(coords, done){
51
+ * var error;
52
+ *
53
+ * // create a <canvas> element for drawing
54
+ * var tile = L.DomUtil.create('canvas', 'leaflet-tile');
55
+ *
56
+ * // setup tile width and height according to the options
57
+ * var size = this.getTileSize();
58
+ * tile.width = size.x;
59
+ * tile.height = size.y;
60
+ *
61
+ * // draw something asynchronously and pass the tile to the done() callback
62
+ * setTimeout(function() {
63
+ * done(error, tile);
64
+ * }, 1000);
65
+ *
66
+ * return tile;
67
+ * }
68
+ * });
69
+ * ```
70
+ *
71
+ * @section
72
+ */
73
+
74
+
75
+ export var GridLayer = Layer.extend({
76
+
77
+ // @section
78
+ // @aka GridLayer options
79
+ options: {
80
+ // @option tileSize: Number|Point = 256
81
+ // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise.
82
+ tileSize: 256,
83
+
84
+ // @option opacity: Number = 1.0
85
+ // Opacity of the tiles. Can be used in the `createTile()` function.
86
+ opacity: 1,
87
+
88
+ // @option updateWhenIdle: Boolean = (depends)
89
+ // Load new tiles only when panning ends.
90
+ // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation.
91
+ // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the
92
+ // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers.
93
+ updateWhenIdle: Browser.mobile,
94
+
95
+ // @option updateWhenZooming: Boolean = true
96
+ // By default, a smooth zoom animation (during a [touch zoom](#map-touchzoom) or a [`flyTo()`](#map-flyto)) will update grid layers every integer zoom level. Setting this option to `false` will update the grid layer only when the smooth animation ends.
97
+ updateWhenZooming: true,
98
+
99
+ // @option updateInterval: Number = 200
100
+ // Tiles will not update more than once every `updateInterval` milliseconds when panning.
101
+ updateInterval: 200,
102
+
103
+ // @option zIndex: Number = 1
104
+ // The explicit zIndex of the tile layer.
105
+ zIndex: 1,
106
+
107
+ // @option bounds: LatLngBounds = undefined
108
+ // If set, tiles will only be loaded inside the set `LatLngBounds`.
109
+ bounds: null,
110
+
111
+ // @option minZoom: Number = 0
112
+ // The minimum zoom level down to which this layer will be displayed (inclusive).
113
+ minZoom: 0,
114
+
115
+ // @option maxZoom: Number = undefined
116
+ // The maximum zoom level up to which this layer will be displayed (inclusive).
117
+ maxZoom: undefined,
118
+
119
+ // @option maxNativeZoom: Number = undefined
120
+ // Maximum zoom number the tile source has available. If it is specified,
121
+ // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded
122
+ // from `maxNativeZoom` level and auto-scaled.
123
+ maxNativeZoom: undefined,
124
+
125
+ // @option minNativeZoom: Number = undefined
126
+ // Minimum zoom number the tile source has available. If it is specified,
127
+ // the tiles on all zoom levels lower than `minNativeZoom` will be loaded
128
+ // from `minNativeZoom` level and auto-scaled.
129
+ minNativeZoom: undefined,
130
+
131
+ // @option noWrap: Boolean = false
132
+ // Whether the layer is wrapped around the antimeridian. If `true`, the
133
+ // GridLayer will only be displayed once at low zoom levels. Has no
134
+ // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used
135
+ // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting
136
+ // tiles outside the CRS limits.
137
+ noWrap: false,
138
+
139
+ // @option pane: String = 'tilePane'
140
+ // `Map pane` where the grid layer will be added.
141
+ pane: 'tilePane',
142
+
143
+ // @option className: String = ''
144
+ // A custom class name to assign to the tile layer. Empty by default.
145
+ className: '',
146
+
147
+ // @option keepBuffer: Number = 2
148
+ // When panning the map, keep this many rows and columns of tiles before unloading them.
149
+ keepBuffer: 2
150
+ },
151
+
152
+ initialize: function (options) {
153
+ Util.setOptions(this, options);
154
+ },
155
+
156
+ onAdd: function () {
157
+ this._initContainer();
158
+
159
+ this._levels = {};
160
+ this._tiles = {};
161
+
162
+ this._resetView(); // implicit _update() call
163
+ },
164
+
165
+ beforeAdd: function (map) {
166
+ map._addZoomLimit(this);
167
+ },
168
+
169
+ onRemove: function (map) {
170
+ this._removeAllTiles();
171
+ DomUtil.remove(this._container);
172
+ map._removeZoomLimit(this);
173
+ this._container = null;
174
+ this._tileZoom = undefined;
175
+ },
176
+
177
+ // @method bringToFront: this
178
+ // Brings the tile layer to the top of all tile layers.
179
+ bringToFront: function () {
180
+ if (this._map) {
181
+ DomUtil.toFront(this._container);
182
+ this._setAutoZIndex(Math.max);
183
+ }
184
+ return this;
185
+ },
186
+
187
+ // @method bringToBack: this
188
+ // Brings the tile layer to the bottom of all tile layers.
189
+ bringToBack: function () {
190
+ if (this._map) {
191
+ DomUtil.toBack(this._container);
192
+ this._setAutoZIndex(Math.min);
193
+ }
194
+ return this;
195
+ },
196
+
197
+ // @method getContainer: HTMLElement
198
+ // Returns the HTML element that contains the tiles for this layer.
199
+ getContainer: function () {
200
+ return this._container;
201
+ },
202
+
203
+ // @method setOpacity(opacity: Number): this
204
+ // Changes the [opacity](#gridlayer-opacity) of the grid layer.
205
+ setOpacity: function (opacity) {
206
+ this.options.opacity = opacity;
207
+ this._updateOpacity();
208
+ return this;
209
+ },
210
+
211
+ // @method setZIndex(zIndex: Number): this
212
+ // Changes the [zIndex](#gridlayer-zindex) of the grid layer.
213
+ setZIndex: function (zIndex) {
214
+ this.options.zIndex = zIndex;
215
+ this._updateZIndex();
216
+
217
+ return this;
218
+ },
219
+
220
+ // @method isLoading: Boolean
221
+ // Returns `true` if any tile in the grid layer has not finished loading.
222
+ isLoading: function () {
223
+ return this._loading;
224
+ },
225
+
226
+ // @method redraw: this
227
+ // Causes the layer to clear all the tiles and request them again.
228
+ redraw: function () {
229
+ if (this._map) {
230
+ this._removeAllTiles();
231
+ var tileZoom = this._clampZoom(this._map.getZoom());
232
+ if (tileZoom !== this._tileZoom) {
233
+ this._tileZoom = tileZoom;
234
+ this._updateLevels();
235
+ }
236
+ this._update();
237
+ }
238
+ return this;
239
+ },
240
+
241
+ getEvents: function () {
242
+ var events = {
243
+ viewprereset: this._invalidateAll,
244
+ viewreset: this._resetView,
245
+ zoom: this._resetView,
246
+ moveend: this._onMoveEnd
247
+ };
248
+
249
+ if (!this.options.updateWhenIdle) {
250
+ // update tiles on move, but not more often than once per given interval
251
+ if (!this._onMove) {
252
+ this._onMove = Util.throttle(this._onMoveEnd, this.options.updateInterval, this);
253
+ }
254
+
255
+ events.move = this._onMove;
256
+ }
257
+
258
+ if (this._zoomAnimated) {
259
+ events.zoomanim = this._animateZoom;
260
+ }
261
+
262
+ return events;
263
+ },
264
+
265
+ // @section Extension methods
266
+ // Layers extending `GridLayer` shall reimplement the following method.
267
+ // @method createTile(coords: Object, done?: Function): HTMLElement
268
+ // Called only internally, must be overridden by classes extending `GridLayer`.
269
+ // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback
270
+ // is specified, it must be called when the tile has finished loading and drawing.
271
+ createTile: function () {
272
+ return document.createElement('div');
273
+ },
274
+
275
+ // @section
276
+ // @method getTileSize: Point
277
+ // Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method.
278
+ getTileSize: function () {
279
+ var s = this.options.tileSize;
280
+ return s instanceof Point ? s : new Point(s, s);
281
+ },
282
+
283
+ _updateZIndex: function () {
284
+ if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) {
285
+ this._container.style.zIndex = this.options.zIndex;
286
+ }
287
+ },
288
+
289
+ _setAutoZIndex: function (compare) {
290
+ // go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back)
291
+
292
+ var layers = this.getPane().children,
293
+ edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min
294
+
295
+ for (var i = 0, len = layers.length, zIndex; i < len; i++) {
296
+
297
+ zIndex = layers[i].style.zIndex;
298
+
299
+ if (layers[i] !== this._container && zIndex) {
300
+ edgeZIndex = compare(edgeZIndex, +zIndex);
301
+ }
302
+ }
303
+
304
+ if (isFinite(edgeZIndex)) {
305
+ this.options.zIndex = edgeZIndex + compare(-1, 1);
306
+ this._updateZIndex();
307
+ }
308
+ },
309
+
310
+ _updateOpacity: function () {
311
+ if (!this._map) { return; }
312
+
313
+ // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
314
+ if (Browser.ielt9) { return; }
315
+
316
+ DomUtil.setOpacity(this._container, this.options.opacity);
317
+
318
+ var now = +new Date(),
319
+ nextFrame = false,
320
+ willPrune = false;
321
+
322
+ for (var key in this._tiles) {
323
+ var tile = this._tiles[key];
324
+ if (!tile.current || !tile.loaded) { continue; }
325
+
326
+ var fade = Math.min(1, (now - tile.loaded) / 200);
327
+
328
+ DomUtil.setOpacity(tile.el, fade);
329
+ if (fade < 1) {
330
+ nextFrame = true;
331
+ } else {
332
+ if (tile.active) {
333
+ willPrune = true;
334
+ } else {
335
+ this._onOpaqueTile(tile);
336
+ }
337
+ tile.active = true;
338
+ }
339
+ }
340
+
341
+ if (willPrune && !this._noPrune) { this._pruneTiles(); }
342
+
343
+ if (nextFrame) {
344
+ Util.cancelAnimFrame(this._fadeFrame);
345
+ this._fadeFrame = Util.requestAnimFrame(this._updateOpacity, this);
346
+ }
347
+ },
348
+
349
+ _onOpaqueTile: Util.falseFn,
350
+
351
+ _initContainer: function () {
352
+ if (this._container) { return; }
353
+
354
+ this._container = DomUtil.create('div', 'leaflet-layer ' + (this.options.className || ''));
355
+ this._updateZIndex();
356
+
357
+ if (this.options.opacity < 1) {
358
+ this._updateOpacity();
359
+ }
360
+
361
+ this.getPane().appendChild(this._container);
362
+ },
363
+
364
+ _updateLevels: function () {
365
+
366
+ var zoom = this._tileZoom,
367
+ maxZoom = this.options.maxZoom;
368
+
369
+ if (zoom === undefined) { return undefined; }
370
+
371
+ for (var z in this._levels) {
372
+ z = Number(z);
373
+ if (this._levels[z].el.children.length || z === zoom) {
374
+ this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
375
+ this._onUpdateLevel(z);
376
+ } else {
377
+ DomUtil.remove(this._levels[z].el);
378
+ this._removeTilesAtZoom(z);
379
+ this._onRemoveLevel(z);
380
+ delete this._levels[z];
381
+ }
382
+ }
383
+
384
+ var level = this._levels[zoom],
385
+ map = this._map;
386
+
387
+ if (!level) {
388
+ level = this._levels[zoom] = {};
389
+
390
+ level.el = DomUtil.create('div', 'leaflet-tile-container leaflet-zoom-animated', this._container);
391
+ level.el.style.zIndex = maxZoom;
392
+
393
+ level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round();
394
+ level.zoom = zoom;
395
+
396
+ this._setZoomTransform(level, map.getCenter(), map.getZoom());
397
+
398
+ // force the browser to consider the newly added element for transition
399
+ Util.falseFn(level.el.offsetWidth);
400
+
401
+ this._onCreateLevel(level);
402
+ }
403
+
404
+ this._level = level;
405
+
406
+ return level;
407
+ },
408
+
409
+ _onUpdateLevel: Util.falseFn,
410
+
411
+ _onRemoveLevel: Util.falseFn,
412
+
413
+ _onCreateLevel: Util.falseFn,
414
+
415
+ _pruneTiles: function () {
416
+ if (!this._map) {
417
+ return;
418
+ }
419
+
420
+ var key, tile;
421
+
422
+ var zoom = this._map.getZoom();
423
+ if (zoom > this.options.maxZoom ||
424
+ zoom < this.options.minZoom) {
425
+ this._removeAllTiles();
426
+ return;
427
+ }
428
+
429
+ for (key in this._tiles) {
430
+ tile = this._tiles[key];
431
+ tile.retain = tile.current;
432
+ }
433
+
434
+ for (key in this._tiles) {
435
+ tile = this._tiles[key];
436
+ if (tile.current && !tile.active) {
437
+ var coords = tile.coords;
438
+ if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) {
439
+ this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2);
440
+ }
441
+ }
442
+ }
443
+
444
+ for (key in this._tiles) {
445
+ if (!this._tiles[key].retain) {
446
+ this._removeTile(key);
447
+ }
448
+ }
449
+ },
450
+
451
+ _removeTilesAtZoom: function (zoom) {
452
+ for (var key in this._tiles) {
453
+ if (this._tiles[key].coords.z !== zoom) {
454
+ continue;
455
+ }
456
+ this._removeTile(key);
457
+ }
458
+ },
459
+
460
+ _removeAllTiles: function () {
461
+ for (var key in this._tiles) {
462
+ this._removeTile(key);
463
+ }
464
+ },
465
+
466
+ _invalidateAll: function () {
467
+ for (var z in this._levels) {
468
+ DomUtil.remove(this._levels[z].el);
469
+ this._onRemoveLevel(Number(z));
470
+ delete this._levels[z];
471
+ }
472
+ this._removeAllTiles();
473
+
474
+ this._tileZoom = undefined;
475
+ },
476
+
477
+ _retainParent: function (x, y, z, minZoom) {
478
+ var x2 = Math.floor(x / 2),
479
+ y2 = Math.floor(y / 2),
480
+ z2 = z - 1,
481
+ coords2 = new Point(+x2, +y2);
482
+ coords2.z = +z2;
483
+
484
+ var key = this._tileCoordsToKey(coords2),
485
+ tile = this._tiles[key];
486
+
487
+ if (tile && tile.active) {
488
+ tile.retain = true;
489
+ return true;
490
+
491
+ } else if (tile && tile.loaded) {
492
+ tile.retain = true;
493
+ }
494
+
495
+ if (z2 > minZoom) {
496
+ return this._retainParent(x2, y2, z2, minZoom);
497
+ }
498
+
499
+ return false;
500
+ },
501
+
502
+ _retainChildren: function (x, y, z, maxZoom) {
503
+
504
+ for (var i = 2 * x; i < 2 * x + 2; i++) {
505
+ for (var j = 2 * y; j < 2 * y + 2; j++) {
506
+
507
+ var coords = new Point(i, j);
508
+ coords.z = z + 1;
509
+
510
+ var key = this._tileCoordsToKey(coords),
511
+ tile = this._tiles[key];
512
+
513
+ if (tile && tile.active) {
514
+ tile.retain = true;
515
+ continue;
516
+
517
+ } else if (tile && tile.loaded) {
518
+ tile.retain = true;
519
+ }
520
+
521
+ if (z + 1 < maxZoom) {
522
+ this._retainChildren(i, j, z + 1, maxZoom);
523
+ }
524
+ }
525
+ }
526
+ },
527
+
528
+ _resetView: function (e) {
529
+ var animating = e && (e.pinch || e.flyTo);
530
+ this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating);
531
+ },
532
+
533
+ _animateZoom: function (e) {
534
+ this._setView(e.center, e.zoom, true, e.noUpdate);
535
+ },
536
+
537
+ _clampZoom: function (zoom) {
538
+ var options = this.options;
539
+
540
+ if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) {
541
+ return options.minNativeZoom;
542
+ }
543
+
544
+ if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) {
545
+ return options.maxNativeZoom;
546
+ }
547
+
548
+ return zoom;
549
+ },
550
+
551
+ _setView: function (center, zoom, noPrune, noUpdate) {
552
+ var tileZoom = Math.round(zoom);
553
+ if ((this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom) ||
554
+ (this.options.minZoom !== undefined && tileZoom < this.options.minZoom)) {
555
+ tileZoom = undefined;
556
+ } else {
557
+ tileZoom = this._clampZoom(tileZoom);
558
+ }
559
+
560
+ var tileZoomChanged = this.options.updateWhenZooming && (tileZoom !== this._tileZoom);
561
+
562
+ if (!noUpdate || tileZoomChanged) {
563
+
564
+ this._tileZoom = tileZoom;
565
+
566
+ if (this._abortLoading) {
567
+ this._abortLoading();
568
+ }
569
+
570
+ this._updateLevels();
571
+ this._resetGrid();
572
+
573
+ if (tileZoom !== undefined) {
574
+ this._update(center);
575
+ }
576
+
577
+ if (!noPrune) {
578
+ this._pruneTiles();
579
+ }
580
+
581
+ // Flag to prevent _updateOpacity from pruning tiles during
582
+ // a zoom anim or a pinch gesture
583
+ this._noPrune = !!noPrune;
584
+ }
585
+
586
+ this._setZoomTransforms(center, zoom);
587
+ },
588
+
589
+ _setZoomTransforms: function (center, zoom) {
590
+ for (var i in this._levels) {
591
+ this._setZoomTransform(this._levels[i], center, zoom);
592
+ }
593
+ },
594
+
595
+ _setZoomTransform: function (level, center, zoom) {
596
+ var scale = this._map.getZoomScale(zoom, level.zoom),
597
+ translate = level.origin.multiplyBy(scale)
598
+ .subtract(this._map._getNewPixelOrigin(center, zoom)).round();
599
+
600
+ if (Browser.any3d) {
601
+ DomUtil.setTransform(level.el, translate, scale);
602
+ } else {
603
+ DomUtil.setPosition(level.el, translate);
604
+ }
605
+ },
606
+
607
+ _resetGrid: function () {
608
+ var map = this._map,
609
+ crs = map.options.crs,
610
+ tileSize = this._tileSize = this.getTileSize(),
611
+ tileZoom = this._tileZoom;
612
+
613
+ var bounds = this._map.getPixelWorldBounds(this._tileZoom);
614
+ if (bounds) {
615
+ this._globalTileRange = this._pxBoundsToTileRange(bounds);
616
+ }
617
+
618
+ this._wrapX = crs.wrapLng && !this.options.noWrap && [
619
+ Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x),
620
+ Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y)
621
+ ];
622
+ this._wrapY = crs.wrapLat && !this.options.noWrap && [
623
+ Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x),
624
+ Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y)
625
+ ];
626
+ },
627
+
628
+ _onMoveEnd: function () {
629
+ if (!this._map || this._map._animatingZoom) { return; }
630
+
631
+ this._update();
632
+ },
633
+
634
+ _getTiledPixelBounds: function (center) {
635
+ var map = this._map,
636
+ mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
637
+ scale = map.getZoomScale(mapZoom, this._tileZoom),
638
+ pixelCenter = map.project(center, this._tileZoom).floor(),
639
+ halfSize = map.getSize().divideBy(scale * 2);
640
+
641
+ return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
642
+ },
643
+
644
+ // Private method to load tiles in the grid's active zoom level according to map bounds
645
+ _update: function (center) {
646
+ var map = this._map;
647
+ if (!map) { return; }
648
+ var zoom = this._clampZoom(map.getZoom());
649
+
650
+ if (center === undefined) { center = map.getCenter(); }
651
+ if (this._tileZoom === undefined) { return; } // if out of minzoom/maxzoom
652
+
653
+ var pixelBounds = this._getTiledPixelBounds(center),
654
+ tileRange = this._pxBoundsToTileRange(pixelBounds),
655
+ tileCenter = tileRange.getCenter(),
656
+ queue = [],
657
+ margin = this.options.keepBuffer,
658
+ noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]),
659
+ tileRange.getTopRight().add([margin, -margin]));
660
+
661
+ // Sanity check: panic if the tile range contains Infinity somewhere.
662
+ if (!(isFinite(tileRange.min.x) &&
663
+ isFinite(tileRange.min.y) &&
664
+ isFinite(tileRange.max.x) &&
665
+ isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); }
666
+
667
+ for (var key in this._tiles) {
668
+ var c = this._tiles[key].coords;
669
+ if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) {
670
+ this._tiles[key].current = false;
671
+ }
672
+ }
673
+
674
+ // _update just loads more tiles. If the tile zoom level differs too much
675
+ // from the map's, let _setView reset levels and prune old tiles.
676
+ if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center, zoom); return; }
677
+
678
+ // create a queue of coordinates to load tiles from
679
+ for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
680
+ for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
681
+ var coords = new Point(i, j);
682
+ coords.z = this._tileZoom;
683
+
684
+ if (!this._isValidTile(coords)) { continue; }
685
+
686
+ var tile = this._tiles[this._tileCoordsToKey(coords)];
687
+ if (tile) {
688
+ tile.current = true;
689
+ } else {
690
+ queue.push(coords);
691
+ }
692
+ }
693
+ }
694
+
695
+ // sort tile queue to load tiles in order of their distance to center
696
+ queue.sort(function (a, b) {
697
+ return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
698
+ });
699
+
700
+ if (queue.length !== 0) {
701
+ // if it's the first batch of tiles to load
702
+ if (!this._loading) {
703
+ this._loading = true;
704
+ // @event loading: Event
705
+ // Fired when the grid layer starts loading tiles.
706
+ this.fire('loading');
707
+ }
708
+
709
+ // create DOM fragment to append tiles in one batch
710
+ var fragment = document.createDocumentFragment();
711
+
712
+ for (i = 0; i < queue.length; i++) {
713
+ this._addTile(queue[i], fragment);
714
+ }
715
+
716
+ this._level.el.appendChild(fragment);
717
+ }
718
+ },
719
+
720
+ _isValidTile: function (coords) {
721
+ var crs = this._map.options.crs;
722
+
723
+ if (!crs.infinite) {
724
+ // don't load tile if it's out of bounds and not wrapped
725
+ var bounds = this._globalTileRange;
726
+ if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
727
+ (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; }
728
+ }
729
+
730
+ if (!this.options.bounds) { return true; }
731
+
732
+ // don't load tile if it doesn't intersect the bounds in options
733
+ var tileBounds = this._tileCoordsToBounds(coords);
734
+ return latLngBounds(this.options.bounds).overlaps(tileBounds);
735
+ },
736
+
737
+ _keyToBounds: function (key) {
738
+ return this._tileCoordsToBounds(this._keyToTileCoords(key));
739
+ },
740
+
741
+ _tileCoordsToNwSe: function (coords) {
742
+ var map = this._map,
743
+ tileSize = this.getTileSize(),
744
+ nwPoint = coords.scaleBy(tileSize),
745
+ sePoint = nwPoint.add(tileSize),
746
+ nw = map.unproject(nwPoint, coords.z),
747
+ se = map.unproject(sePoint, coords.z);
748
+ return [nw, se];
749
+ },
750
+
751
+ // converts tile coordinates to its geographical bounds
752
+ _tileCoordsToBounds: function (coords) {
753
+ var bp = this._tileCoordsToNwSe(coords),
754
+ bounds = new LatLngBounds(bp[0], bp[1]);
755
+
756
+ if (!this.options.noWrap) {
757
+ bounds = this._map.wrapLatLngBounds(bounds);
758
+ }
759
+ return bounds;
760
+ },
761
+ // converts tile coordinates to key for the tile cache
762
+ _tileCoordsToKey: function (coords) {
763
+ return coords.x + ':' + coords.y + ':' + coords.z;
764
+ },
765
+
766
+ // converts tile cache key to coordinates
767
+ _keyToTileCoords: function (key) {
768
+ var k = key.split(':'),
769
+ coords = new Point(+k[0], +k[1]);
770
+ coords.z = +k[2];
771
+ return coords;
772
+ },
773
+
774
+ _removeTile: function (key) {
775
+ var tile = this._tiles[key];
776
+ if (!tile) { return; }
777
+
778
+ DomUtil.remove(tile.el);
779
+
780
+ delete this._tiles[key];
781
+
782
+ // @event tileunload: TileEvent
783
+ // Fired when a tile is removed (e.g. when a tile goes off the screen).
784
+ this.fire('tileunload', {
785
+ tile: tile.el,
786
+ coords: this._keyToTileCoords(key)
787
+ });
788
+ },
789
+
790
+ _initTile: function (tile) {
791
+ DomUtil.addClass(tile, 'leaflet-tile');
792
+
793
+ var tileSize = this.getTileSize();
794
+ tile.style.width = tileSize.x + 'px';
795
+ tile.style.height = tileSize.y + 'px';
796
+
797
+ tile.onselectstart = Util.falseFn;
798
+ tile.onmousemove = Util.falseFn;
799
+
800
+ // update opacity on tiles in IE7-8 because of filter inheritance problems
801
+ if (Browser.ielt9 && this.options.opacity < 1) {
802
+ DomUtil.setOpacity(tile, this.options.opacity);
803
+ }
804
+ },
805
+
806
+ _addTile: function (coords, container) {
807
+ var tilePos = this._getTilePos(coords),
808
+ key = this._tileCoordsToKey(coords);
809
+
810
+ var tile = this.createTile(this._wrapCoords(coords), Util.bind(this._tileReady, this, coords));
811
+
812
+ this._initTile(tile);
813
+
814
+ // if createTile is defined with a second argument ("done" callback),
815
+ // we know that tile is async and will be ready later; otherwise
816
+ if (this.createTile.length < 2) {
817
+ // mark tile as ready, but delay one frame for opacity animation to happen
818
+ Util.requestAnimFrame(Util.bind(this._tileReady, this, coords, null, tile));
819
+ }
820
+
821
+ DomUtil.setPosition(tile, tilePos);
822
+
823
+ // save tile in cache
824
+ this._tiles[key] = {
825
+ el: tile,
826
+ coords: coords,
827
+ current: true
828
+ };
829
+
830
+ container.appendChild(tile);
831
+ // @event tileloadstart: TileEvent
832
+ // Fired when a tile is requested and starts loading.
833
+ this.fire('tileloadstart', {
834
+ tile: tile,
835
+ coords: coords
836
+ });
837
+ },
838
+
839
+ _tileReady: function (coords, err, tile) {
840
+ if (err) {
841
+ // @event tileerror: TileErrorEvent
842
+ // Fired when there is an error loading a tile.
843
+ this.fire('tileerror', {
844
+ error: err,
845
+ tile: tile,
846
+ coords: coords
847
+ });
848
+ }
849
+
850
+ var key = this._tileCoordsToKey(coords);
851
+
852
+ tile = this._tiles[key];
853
+ if (!tile) { return; }
854
+
855
+ tile.loaded = +new Date();
856
+ if (this._map._fadeAnimated) {
857
+ DomUtil.setOpacity(tile.el, 0);
858
+ Util.cancelAnimFrame(this._fadeFrame);
859
+ this._fadeFrame = Util.requestAnimFrame(this._updateOpacity, this);
860
+ } else {
861
+ tile.active = true;
862
+ this._pruneTiles();
863
+ }
864
+
865
+ if (!err) {
866
+ DomUtil.addClass(tile.el, 'leaflet-tile-loaded');
867
+
868
+ // @event tileload: TileEvent
869
+ // Fired when a tile loads.
870
+ this.fire('tileload', {
871
+ tile: tile.el,
872
+ coords: coords
873
+ });
874
+ }
875
+
876
+ if (this._noTilesToLoad()) {
877
+ this._loading = false;
878
+ // @event load: Event
879
+ // Fired when the grid layer loaded all visible tiles.
880
+ this.fire('load');
881
+
882
+ if (Browser.ielt9 || !this._map._fadeAnimated) {
883
+ Util.requestAnimFrame(this._pruneTiles, this);
884
+ } else {
885
+ // Wait a bit more than 0.2 secs (the duration of the tile fade-in)
886
+ // to trigger a pruning.
887
+ setTimeout(Util.bind(this._pruneTiles, this), 250);
888
+ }
889
+ }
890
+ },
891
+
892
+ _getTilePos: function (coords) {
893
+ return coords.scaleBy(this.getTileSize()).subtract(this._level.origin);
894
+ },
895
+
896
+ _wrapCoords: function (coords) {
897
+ var newCoords = new Point(
898
+ this._wrapX ? Util.wrapNum(coords.x, this._wrapX) : coords.x,
899
+ this._wrapY ? Util.wrapNum(coords.y, this._wrapY) : coords.y);
900
+ newCoords.z = coords.z;
901
+ return newCoords;
902
+ },
903
+
904
+ _pxBoundsToTileRange: function (bounds) {
905
+ var tileSize = this.getTileSize();
906
+ return new Bounds(
907
+ bounds.min.unscaleBy(tileSize).floor(),
908
+ bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1]));
909
+ },
910
+
911
+ _noTilesToLoad: function () {
912
+ for (var key in this._tiles) {
913
+ if (!this._tiles[key].loaded) { return false; }
914
+ }
915
+ return true;
916
+ }
917
+ });
918
+
919
+ // @factory L.gridLayer(options?: GridLayer options)
920
+ // Creates a new instance of GridLayer with the supplied options.
921
+ export function gridLayer(options) {
922
+ return new GridLayer(options);
923
+ }