X-Git-Url: https://git.openstreetmap.org/rails.git/blobdiff_plain/214ff28cd9df00154441f43ea18d2c043375dd3b..16f5a5ac0c674b258996fcbde1c3fda2e651906a:/vendor/assets/leaflet/leaflet.js diff --git a/vendor/assets/leaflet/leaflet.js b/vendor/assets/leaflet/leaflet.js index fa26f6e2c..d3d563574 100644 --- a/vendor/assets/leaflet/leaflet.js +++ b/vendor/assets/leaflet/leaflet.js @@ -7,7 +7,7 @@ var oldL = window.L, L = {}; -L.version = '0.7'; +L.version = '0.7.7'; // define Leaflet for Node module pattern loaders, including Browserify if (typeof module === 'object' && typeof module.exports === 'object') { @@ -134,21 +134,16 @@ L.Util = { } return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&'); }, - - compileTemplate: function (str, data) { - // based on https://gist.github.com/padolsey/6008842 - str = str.replace(/"/g, '\\\"'); - str = str.replace(/\{ *([\w_]+) *\}/g, function (str, key) { - return '" + o["' + key + '"]' + (typeof data[key] === 'function' ? '(o)' : '') + ' + "'; - }); - // jshint evil: true - return new Function('o', 'return "' + str + '";'); - }, - template: function (str, data) { - var cache = L.Util._templateCache = L.Util._templateCache || {}; - cache[str] = cache[str] || L.Util.compileTemplate(str, data); - return cache[str](data); + return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) { + var value = data[key]; + if (value === undefined) { + throw new Error('No value provided for variable ' + str); + } else if (typeof value === 'function') { + value = value(data); + } + return value; + }); }, isArray: Array.isArray || function (obj) { @@ -524,9 +519,8 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent; gecko = ua.indexOf('gecko') !== -1, mobile = typeof orientation !== undefined + '', - msPointer = window.navigator && window.navigator.msPointerEnabled && - window.navigator.msMaxTouchPoints && !window.PointerEvent, - pointer = (window.PointerEvent && window.navigator.pointerEnabled && window.navigator.maxTouchPoints) || + msPointer = !window.PointerEvent && window.MSPointerEvent, + pointer = (window.PointerEvent && window.navigator.pointerEnabled) || msPointer, retina = ('devicePixelRatio' in window && window.devicePixelRatio > 1) || ('matchMedia' in window && window.matchMedia('(min-resolution:144dpi)') && @@ -534,43 +528,13 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent; doc = document.documentElement, ie3d = ie && ('transition' in doc.style), - webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()), + webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23, gecko3d = 'MozPerspective' in doc.style, opera3d = 'OTransition' in doc.style, any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d) && !phantomjs; - - // PhantomJS has 'ontouchstart' in document.documentElement, but doesn't actually support touch. - // https://github.com/Leaflet/Leaflet/pull/1434#issuecomment-13843151 - - var touch = !window.L_NO_TOUCH && !phantomjs && (function () { - - var startName = 'ontouchstart'; - - // IE10+ (We simulate these into touch* events in L.DomEvent and L.DomEvent.Pointer) or WebKit, etc. - if (pointer || (startName in doc)) { - return true; - } - - // Firefox/Gecko - var div = document.createElement('div'), - supported = false; - - if (!div.setAttribute) { - return false; - } - div.setAttribute(startName, 'return;'); - - if (typeof div[startName] === 'function') { - supported = true; - } - - div.removeAttribute(startName); - div = null; - - return supported; - }()); - + var touch = !window.L_NO_TOUCH && !phantomjs && (pointer || 'ontouchstart' in window || + (window.DocumentTouch && document instanceof window.DocumentTouch)); L.Browser = { ie: ie, @@ -1070,11 +1034,6 @@ L.DomUtil = { if (!disable3D && L.Browser.any3d) { el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point); - - // workaround for Android 2/3 stability (https://github.com/CloudMade/Leaflet/issues/69) - if (L.Browser.mobileWebkit3d) { - el.style.WebkitBackfaceVisibility = 'hidden'; - } } else { el.style.left = point.x + 'px'; el.style.top = point.y + 'px'; @@ -1642,15 +1601,16 @@ L.Map = L.Class.extend({ var paddingTL = L.point(options.paddingTopLeft || options.padding || [0, 0]), paddingBR = L.point(options.paddingBottomRight || options.padding || [0, 0]), - zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR)), - paddingOffset = paddingBR.subtract(paddingTL).divideBy(2), + zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR)); + + zoom = (options.maxZoom) ? Math.min(options.maxZoom, zoom) : zoom; + + var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2), swPoint = this.project(bounds.getSouthWest(), zoom), nePoint = this.project(bounds.getNorthEast(), zoom), center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom); - zoom = options && options.maxZoom ? Math.min(options.maxZoom, zoom) : zoom; - return this.setView(center, zoom, options); }, @@ -1770,6 +1730,8 @@ L.Map = L.Class.extend({ }, invalidateSize: function (options) { + if (!this._loaded) { return this; } + options = L.extend({ animate: false, pan: true @@ -1779,8 +1741,6 @@ L.Map = L.Class.extend({ this._sizeChanged = true; this._initialCenter = null; - if (!this._loaded) { return this; } - var newSize = this.getSize(), oldCenter = oldSize.divideBy(2).round(), newCenter = newSize.divideBy(2).round(), @@ -2114,13 +2074,13 @@ L.Map = L.Class.extend({ var loading = !this._loaded; this._loaded = true; + this.fire('viewreset', {hard: !preserveMapOffset}); + if (loading) { this.fire('load'); this.eachLayer(this._layerAdd, this); } - this.fire('viewreset', {hard: !preserveMapOffset}); - this.fire('move'); if (zoomChanged || afterZoomAnim) { @@ -2792,7 +2752,7 @@ L.TileLayer = L.Class.extend({ } if (options.bounds) { - var tileSize = options.tileSize, + var tileSize = this._getTileSize(), nwPoint = tilePoint.multiplyBy(tileSize), sePoint = nwPoint.add([tileSize, tileSize]), nw = this._map.unproject(nwPoint), @@ -2857,11 +2817,9 @@ L.TileLayer = L.Class.extend({ /* Chrome 20 layouts much faster with top/left (verify with timeline, frames) Android 4 browser has display issues with top/left and requires transform instead - Android 2 browser requires top/left or tiles disappear on load or first drag - (reappear after zoom) https://github.com/CloudMade/Leaflet/issues/866 (other browsers don't currently care) - see debug/hacks/jitter.html for an example */ - L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome || L.Browser.android23); + L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome); this._tiles[tilePoint.x + ':' + tilePoint.y] = tile; @@ -2907,7 +2865,7 @@ L.TileLayer = L.Class.extend({ _getWrapTileNum: function () { var crs = this._map.options.crs, size = crs.getSize(this._map.getZoom()); - return size.divideBy(this.options.tileSize); + return size.divideBy(this._getTileSize())._floor(); }, _adjustTilePoint: function (tilePoint) { @@ -3579,10 +3537,8 @@ L.Marker = L.Class.extend({ update: function () { if (this._icon) { - var pos = this._map.latLngToLayerPoint(this._latlng).round(); - this._setPos(pos); + this._setPos(this._map.latLngToLayerPoint(this._latlng).round()); } - return this; }, @@ -3605,7 +3561,7 @@ L.Marker = L.Class.extend({ if (options.title) { icon.title = options.title; } - + if (options.alt) { icon.alt = options.alt; } @@ -4240,6 +4196,7 @@ L.Marker.include({ if (content instanceof L.Popup) { L.setOptions(content, options); this._popup = content; + content._source = this; } else { this._popup = new L.Popup(options, this) .setContent(content); @@ -4432,7 +4389,9 @@ L.FeatureGroup = L.LayerGroup.extend({ layer = this._layers[layer]; } - layer.off(L.FeatureGroup.EVENTS, this._propagateEvent, this); + if ('off' in layer) { + layer.off(L.FeatureGroup.EVENTS, this._propagateEvent, this); + } L.LayerGroup.prototype.removeLayer.call(this, layer); @@ -4481,10 +4440,10 @@ L.FeatureGroup = L.LayerGroup.extend({ }, _propagateEvent: function (e) { - e = L.extend({}, e, { + e = L.extend({ layer: e.target, target: this - }); + }, e); this.fire(e.type, e); } }); @@ -4752,7 +4711,7 @@ L.Path = L.Path.extend({ }, _fireMouseEvent: function (e) { - if (!this.hasEventListeners(e.type)) { return; } + if (!this._map || !this.hasEventListeners(e.type)) { return; } var map = this._map, containerPoint = map.mouseEventToContainerPoint(e), @@ -5095,7 +5054,8 @@ L.Path = (L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? L.Path : } this._requestUpdate(); - + + this.fire('remove'); this._map = null; }, @@ -5125,6 +5085,13 @@ L.Path = (L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? L.Path : if (options.fill) { this._ctx.fillStyle = options.fillColor || options.color; } + + if (options.lineCap) { + this._ctx.lineCap = options.lineCap; + } + if (options.lineJoin) { + this._ctx.lineJoin = options.lineJoin; + } }, _drawPath: function () { @@ -5162,7 +5129,7 @@ L.Path = (L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? L.Path : if (options.fill) { ctx.globalAlpha = options.fillOpacity; - ctx.fill(); + ctx.fill(options.fillRule || 'evenodd'); } if (options.stroke) { @@ -5177,15 +5144,14 @@ L.Path = (L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? L.Path : _initEvents: function () { if (this.options.clickable) { - // TODO dblclick this._map.on('mousemove', this._onMouseMove, this); - this._map.on('click', this._onClick, this); + this._map.on('click dblclick contextmenu', this._fireMouseEvent, this); } }, - _onClick: function (e) { + _fireMouseEvent: function (e) { if (this._containsPoint(e.layerPoint)) { - this.fire('click', e); + this.fire(e.type, e); } }, @@ -5255,7 +5221,7 @@ L.Map.include((L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? {} * and polylines (clipping, simplification, distances, etc.) */ -/*jshint bitwise:false */ // allow bitwise oprations for this file +/*jshint bitwise:false */ // allow bitwise operations for this file L.LineUtil = { @@ -5988,6 +5954,7 @@ L.CircleMarker = L.Circle.extend({ if (this._popup && this._popup._isOpen) { this._popup.setLatLng(latlng); } + return this; }, setRadius: function (radius) { @@ -6540,26 +6507,15 @@ L.DomEvent = { }, getMousePosition: function (e, container) { - var body = document.body, - docEl = document.documentElement, - //gecko makes scrollLeft more negative as you scroll in rtl, other browsers don't - //ref: https://code.google.com/p/closure-library/source/browse/closure/goog/style/bidi.js - x = L.DomUtil.documentIsLtr() ? - (e.pageX ? e.pageX - body.scrollLeft - docEl.scrollLeft : e.clientX) : - (L.Browser.gecko ? e.pageX - body.scrollLeft - docEl.scrollLeft : - e.pageX ? e.pageX - body.scrollLeft + docEl.scrollLeft : e.clientX), - y = e.pageY ? e.pageY - body.scrollTop - docEl.scrollTop: e.clientY, - pos = new L.Point(x, y); - if (!container) { - return pos; + return new L.Point(e.clientX, e.clientY); } - var rect = container.getBoundingClientRect(), - left = rect.left - container.clientLeft, - top = rect.top - container.clientTop; + var rect = container.getBoundingClientRect(); - return pos._subtract(new L.Point(left, top)); + return new L.Point( + e.clientX - rect.left - container.clientLeft, + e.clientY - rect.top - container.clientTop); }, getWheelDelta: function (e) { @@ -6627,12 +6583,12 @@ L.DomEvent = { var timeStamp = (e.timeStamp || e.originalEvent.timeStamp), elapsed = L.DomEvent._lastClick && (timeStamp - L.DomEvent._lastClick); - // are they closer together than 1000ms yet more than 100ms? + // are they closer together than 500ms yet more than 100ms? // Android typically triggers them ~300ms apart while multiple listeners // on the same event should be triggered far faster; // or check if click is simulated on the element, and if it is, reject any non-simulated events - if ((elapsed && elapsed > 100 && elapsed < 1000) || (e.target._simulatedClick && !e._simulated)) { + if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) { L.DomEvent.stop(e); return; } @@ -6730,6 +6686,7 @@ L.Draggable = L.Class.extend({ offset = newPoint.subtract(this._startPoint); if (!offset.x && !offset.y) { return; } + if (L.Browser.touch && Math.abs(offset.x) + Math.abs(offset.y) < 3) { return; } L.DomEvent.preventDefault(e); @@ -6740,7 +6697,8 @@ L.Draggable = L.Class.extend({ this._startPos = L.DomUtil.getPosition(this._element).subtract(offset); L.DomUtil.addClass(document.body, 'leaflet-dragging'); - L.DomUtil.addClass((e.target || e.srcElement), 'leaflet-drag-target'); + this._lastTarget = e.target || e.srcElement; + L.DomUtil.addClass(this._lastTarget, 'leaflet-drag-target'); } this._newPos = this._startPos.add(offset); @@ -6756,9 +6714,13 @@ L.Draggable = L.Class.extend({ this.fire('drag'); }, - _onUp: function (e) { + _onUp: function () { L.DomUtil.removeClass(document.body, 'leaflet-dragging'); - L.DomUtil.removeClass((e.target || e.srcElement), 'leaflet-drag-target'); + + if (this._lastTarget) { + L.DomUtil.removeClass(this._lastTarget, 'leaflet-drag-target'); + this._lastTarget = null; + } for (var i in L.Draggable.MOVE) { L.DomEvent @@ -6769,7 +6731,7 @@ L.Draggable = L.Class.extend({ L.DomUtil.enableImageDrag(); L.DomUtil.enableTextSelection(); - if (this._moved) { + if (this._moved && this._moving) { // ensure drag is not fired after dragend L.Util.cancelAnimFrame(this._animRequest); @@ -7207,8 +7169,9 @@ L.extend(L.DomEvent, { pointers = this._pointers; var cb = function (e) { - - L.DomEvent.preventDefault(e); + if (e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) { + L.DomEvent.preventDefault(e); + } var alreadyInArray = false; for (var i = 0; i < pointers.length; i++) { @@ -7413,7 +7376,7 @@ L.Map.TouchZoom = L.Handler.extend({ center = map.layerPointToLatLng(origin), zoom = map.getScaleZoom(this._scale); - map._animateZoom(center, zoom, this._startCenter, this._scale, this._delta); + map._animateZoom(center, zoom, this._startCenter, this._scale, this._delta, false, true); }, _onTouchEnd: function () { @@ -8398,8 +8361,8 @@ L.Control.Layers = L.Control.extend({ onRemove: function (map) { map - .off('layeradd', this._onLayerChange) - .off('layerremove', this._onLayerChange); + .off('layeradd', this._onLayerChange, this) + .off('layerremove', this._onLayerChange, this); }, addBaseLayer: function (layer, name) { @@ -8903,8 +8866,8 @@ if (L.DomUtil.TRANSITION) { L.Map.include(!L.DomUtil.TRANSITION ? {} : { - _catchTransitionEnd: function () { - if (this._animatingZoom) { + _catchTransitionEnd: function (e) { + if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) { this._onZoomTransitionEnd(); } }, @@ -8940,9 +8903,11 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : { return true; }, - _animateZoom: function (center, zoom, origin, scale, delta, backwards) { + _animateZoom: function (center, zoom, origin, scale, delta, backwards, forTouchZoom) { - this._animatingZoom = true; + if (!forTouchZoom) { + this._animatingZoom = true; + } // put transform transition on all layers with leaflet-zoom-animated class L.DomUtil.addClass(this._mapPane, 'leaflet-zoom-anim'); @@ -8956,27 +8921,34 @@ L.Map.include(!L.DomUtil.TRANSITION ? {} : { L.Draggable._disabled = true; } - this.fire('zoomanim', { - center: center, - zoom: zoom, - origin: origin, - scale: scale, - delta: delta, - backwards: backwards - }); + L.Util.requestAnimFrame(function () { + this.fire('zoomanim', { + center: center, + zoom: zoom, + origin: origin, + scale: scale, + delta: delta, + backwards: backwards + }); + // horrible hack to work around a Chrome bug https://github.com/Leaflet/Leaflet/issues/3689 + setTimeout(L.bind(this._onZoomTransitionEnd, this), 250); + }, this); }, _onZoomTransitionEnd: function () { + if (!this._animatingZoom) { return; } this._animatingZoom = false; L.DomUtil.removeClass(this._mapPane, 'leaflet-zoom-anim'); - this._resetView(this._animateToCenter, this._animateToZoom, true, true); + L.Util.requestAnimFrame(function () { + this._resetView(this._animateToCenter, this._animateToZoom, true, true); - if (L.Draggable) { - L.Draggable._disabled = false; - } + if (L.Draggable) { + L.Draggable._disabled = false; + } + }, this); } }); @@ -9012,6 +8984,11 @@ L.TileLayer.include({ // force reflow L.Util.falseFn(bg.offsetWidth); + var zoom = this._map.getZoom(); + if (zoom > this.options.maxZoom || zoom < this.options.minZoom) { + this._clearBgBuffer(); + } + this._animating = false; },