decidim 0.26.9 → 0.26.10

Sign up to get free protection for your applications and to get access to all the features.
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
+ }