-/*
- * Leaflet 1.1.0, a JS library for interactive maps. http://leafletjs.com
+/* @preserve
+ * Leaflet 1.2.0, a JS library for interactive maps. http://leafletjs.com
* (c) 2010-2017 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.L = global.L || {})));
+ (factory((global.L = {})));
}(this, (function (exports) { 'use strict';
-var version = "1.1.0";
+var version = "1.2.0";
/*
* @namespace Util
* Various utility functions, used by Leaflet internally.
*/
+var freeze = Object.freeze;
+Object.freeze = function (obj) { return obj; };
+
// @function extend(dest: Object, src?: Object): Object
// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.
function extend(dest) {
var Util = (Object.freeze || Object)({
+ freeze: freeze,
extend: extend,
create: create,
bind: bind,
}
delete obj[eventsKey];
}
+
+ return this;
}
function addOne(obj, type, fn, context) {
// @function disableScrollPropagation(el: HTMLElement): this
// Adds `stopPropagation` to the element's `'mousewheel'` events (plus browser variants).
function disableScrollPropagation(el) {
- return addOne(el, 'mousewheel', stopPropagation);
+ addOne(el, 'mousewheel', stopPropagation);
+ return this;
}
// @function disableClickPropagation(el: HTMLElement): this
on(link, 'focus', this.expand, this);
}
- // work around for Firefox Android issue https://github.com/Leaflet/Leaflet/issues/2033
- on(form, 'click', function () {
- setTimeout(bind(this._onInputClick, this), 0);
- }, this);
-
- // TODO keyboard accessibility
-
if (!collapsed) {
this.expand();
}
});
if (this.options.sortLayers) {
- this._layers.sort(L.bind(function (a, b) {
+ this._layers.sort(bind(function (a, b) {
return this.options.sortFunction(a.layer, b.layer, a.name, b.name);
}, this));
}
_onInputClick: function () {
var inputs = this._layerControlInputs,
- input, layer, hasLayer;
+ input, layer;
var addedLayers = [],
removedLayers = [];
for (var i = inputs.length - 1; i >= 0; i--) {
input = inputs[i];
layer = this._getLayer(input.layerId).layer;
- hasLayer = this._map.hasLayer(layer);
- if (input.checked && !hasLayer) {
+ if (input.checked) {
addedLayers.push(layer);
-
- } else if (!input.checked && hasLayer) {
+ } else if (!input.checked) {
removedLayers.push(layer);
}
}
// Bugfix issue 2318: Should remove all old layers before readding new ones
for (i = 0; i < removedLayers.length; i++) {
- this._map.removeLayer(removedLayers[i]);
+ if (this._map.hasLayer(removedLayers[i])) {
+ this._map.removeLayer(removedLayers[i]);
+ }
}
for (i = 0; i < addedLayers.length; i++) {
- this._map.addLayer(addedLayers[i]);
+ if (!this._map.hasLayer(addedLayers[i])) {
+ this._map.addLayer(addedLayers[i]);
+ }
}
this._handlingClick = false;
* ```
*/
-var _dragging = false;
var START = touch ? 'touchstart mousedown' : 'mousedown';
var END = {
mousedown: 'mouseup',
// If we're currently dragging this draggable,
// disabling it counts as first ending the drag.
- if (L.Draggable._dragging === this) {
+ if (Draggable._dragging === this) {
this.finishDrag();
}
if (hasClass(this._element, 'leaflet-zoom-anim')) { return; }
- if (_dragging || e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }
- _dragging = this; // Prevent dragging multiple objects at once.
+ if (Draggable._dragging || e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }
+ Draggable._dragging = this; // Prevent dragging multiple objects at once.
if (this._preventOutline) {
preventOutline(this._element);
}
this._moving = false;
- _dragging = false;
+ Draggable._dragging = false;
}
});
}
-function _flat(latlngs) {
- // true if it's a flat array of latlngs; false if nested
+// @function isFlat(latlngs: LatLng[]): Boolean
+// Returns true if `latlngs` is a flat array, false is nested.
+function isFlat(latlngs) {
return !isArray(latlngs[0]) || (typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined');
}
+function _flat(latlngs) {
+ console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.');
+ return isFlat(latlngs);
+}
+
var LineUtil = (Object.freeze || Object)({
simplify: simplify,
_getEdgeIntersection: _getEdgeIntersection,
_getBitCode: _getBitCode,
_sqClosestPointOnSegment: _sqClosestPointOnSegment,
+ isFlat: isFlat,
_flat: _flat
});
/* @section
* Classes extending `L.Layer` will inherit the following methods:
*
- * @method addTo(map: Map): this
- * Adds the layer to the given map
+ * @method addTo(map: Map|LayerGroup): this
+ * Adds the layer to the given map or layer group.
*/
addTo: function (map) {
map.addLayer(this);
// @method addLayer(layer: Layer): this
// Adds the given layer to the map
addLayer: function (layer) {
+ if (!layer._layerAdd) {
+ throw new Error('The provided object is not a Layer.');
+ }
+
var id = stamp(layer);
if (this._layers[id]) { return this; }
this._layers[id] = layer;
});
-// @factory L.layerGroup(layers: Layer[])
+// @factory L.layerGroup(layers?: Layer[])
// Create a layer group, optionally given an initial set of layers.
var layerGroup = function (layers) {
return new LayerGroup(layers);
},
_defaultShape: function () {
- return _flat(this._latlngs) ? this._latlngs : this._latlngs[0];
+ return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0];
},
// recursively convert latlngs input into actual LatLng instances; calculate bounds along the way
_convertLatLngs: function (latlngs) {
var result = [],
- flat = _flat(latlngs);
+ flat = isFlat(latlngs);
for (var i = 0, len = latlngs.length; i < len; i++) {
if (flat) {
return new Polyline(latlngs, options);
}
+// Retrocompat. Allow plugins to support Leaflet versions before and after 1.1.
+Polyline._flat = _flat;
+
/*
* @class Polygon
* @aka L.Polygon
_setLatLngs: function (latlngs) {
Polyline.prototype._setLatLngs.call(this, latlngs);
- if (_flat(this._latlngs)) {
+ if (isFlat(this._latlngs)) {
this._latlngs = [this._latlngs];
}
},
_defaultShape: function () {
- return _flat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0];
+ return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0];
},
_clipPoints: function () {
// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature).
Polyline.include({
toGeoJSON: function (precision) {
- var multi = !_flat(this._latlngs);
+ var multi = !isFlat(this._latlngs);
var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision);
// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature).
Polygon.include({
toGeoJSON: function (precision) {
- var holes = !_flat(this._latlngs),
- multi = holes && !_flat(this._latlngs[0]);
+ var holes = !isFlat(this._latlngs),
+ multi = holes && !isFlat(this._latlngs[0]);
var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision);
// @method setBounds(bounds: LatLngBounds): this
// Update the bounds that this ImageOverlay covers
setBounds: function (bounds) {
- this._bounds = bounds;
+ this._bounds = toLatLngBounds(bounds);
if (this._map) {
this._reset();
*
* ```js
* var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm',
- * imageBounds = [[ 32, -130], [ 13, -100]];
- * L.imageOverlay(imageUrl, imageBounds).addTo(map);
+ * videoBounds = [[ 32, -130], [ 13, -100]];
+ * L.VideoOverlay(videoUrl, videoBounds ).addTo(map);
* ```
*/
},
_initImage: function () {
- var vid = this._image = create$1('video',
- 'leaflet-image-layer ' + (this._zoomAnimated ? 'leaflet-zoom-animated' : ''));
+ var wasElementSupplied = this._url.tagName === 'VIDEO';
+ var vid = this._image = wasElementSupplied ? this._url : create$1('video');
+
+ vid.class = vid.class || '';
+ vid.class += 'leaflet-image-layer ' + (this._zoomAnimated ? 'leaflet-zoom-animated' : '');
vid.onselectstart = falseFn;
vid.onmousemove = falseFn;
// Fired when the video has finished loading the first frame
vid.onloadeddata = bind(this.fire, this, 'load');
+ if (wasElementSupplied) { return; }
+
if (!isArray(this._url)) { this._url = [this._url]; }
vid.autoplay = !!this.options.autoplay;
});
-// @factory L.videoOverlay(videoUrl: String|Array, bounds: LatLngBounds, options?: VideoOverlay options)
-// Instantiates an image overlay object given the URL of the video (or array of URLs) and the
+// @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options)
+// Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the
// geographical bounds it is tied to.
-function videoOverlay(url, bounds, options) {
- return new VideoOverlay(url, bounds, options);
+
+function videoOverlay(video, bounds, options) {
+ return new VideoOverlay(video, bounds, options);
}
/*
// @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this
// Binds a popup to the layer with the passed `content` and sets up the
- // neccessary event listeners. If a `Function` is passed it will receive
+ // necessary event listeners. If a `Function` is passed it will receive
// the layer as the first argument and should return a `String` or `HTMLElement`.
bindPopup: function (content, options) {
// @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this
// Binds a tooltip to the layer with the passed `content` and sets up the
- // neccessary event listeners. If a `Function` is passed it will receive
+ // necessary event listeners. If a `Function` is passed it will receive
// the layer as the first argument and should return a `String` or `HTMLElement`.
bindTooltip: function (content, options) {
// Opacity of the tiles. Can be used in the `createTile()` function.
opacity: 1,
- // @option updateWhenIdle: Boolean = depends
- // If `false`, new tiles are loaded during panning, otherwise only after it (for better performance). `true` by default on mobile browsers, otherwise `false`.
+ // @option updateWhenIdle: Boolean = (depends)
+ // Load new tiles only when panning ends.
+ // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation.
+ // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the
+ // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers.
updateWhenIdle: mobile,
// @option updateWhenZooming: Boolean = true
* 'http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png'
* ```
*
- * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` — zoom level, `{x}` and `{y}` — tile coordinates. `{r}` can be used to add @2x to the URL to load retina tiles.
+ * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` — zoom level, `{x}` and `{y}` — tile coordinates. `{r}` can be used to add "@2x" to the URL to load retina tiles.
*
* You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this:
*
// Always export us to window global (see #2364)
window.L = exports;
+Object.freeze = freeze;
+
exports.version = version;
exports.noConflict = noConflict;
exports.Control = Control;