Update Leaflet

This commit is contained in:
John Firebaugh 2012-10-31 21:27:28 -06:00
parent cd28b8dac5
commit e6afda8764
4 changed files with 324 additions and 48 deletions

View file

@ -1,6 +1,6 @@
folder 'vendor/assets' do
folder 'leaflet' do
from 'https://github.com/CloudMade/Leaflet.git' do
from 'https://github.com/jfirebaugh/Leaflet.git', :branch => 'osm' do
file 'leaflet.css', 'dist/leaflet.css'
file 'leaflet.ie.css', 'dist/leaflet.ie.css'
file 'leaflet.js', 'dist/leaflet-src.js'

View file

@ -14,10 +14,12 @@
.leaflet-image-layer,
.leaflet-layer { /* TODO optimize classes */
position: absolute;
left: 0;
}
.leaflet-container {
overflow: hidden;
outline: 0;
-ms-touch-action: none;
}
.leaflet-tile,
.leaflet-marker-icon,

View file

@ -41,4 +41,7 @@
}
.leaflet-control-attribution, .leaflet-control-layers {
background: white;
}
.leaflet-zoom-box {
filter: alpha(opacity=50);
}

View file

@ -346,28 +346,40 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent;
(function () {
var ua = navigator.userAgent.toLowerCase(),
ie = !!window.ActiveXObject,
var ie = !!window.ActiveXObject,
// http://tanalin.com/en/articles/ie-version-js/
ie6 = ie && !window.XMLHttpRequest,
ie7 = ie && !document.querySelector,
// terrible browser detection to work around Safari / iOS / Android browser bugs
// see TileLayer._addTile and debug/hacks/jitter.html
ua = navigator.userAgent.toLowerCase(),
webkit = ua.indexOf("webkit") !== -1,
gecko = ua.indexOf("gecko") !== -1,
//Terrible browser detection to work around a safari / iOS / android browser bug. See TileLayer._addTile and debug/hacks/jitter.html
chrome = ua.indexOf("chrome") !== -1,
opera = window.opera,
android = ua.indexOf("android") !== -1,
android23 = ua.search("android [23]") !== -1,
mobile = typeof orientation !== undefined + '' ? true : false,
mobile = typeof orientation !== undefined + '',
msTouch = (window.navigator && window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints),
retina = (('devicePixelRatio' in window && window.devicePixelRatio > 1) ||
('matchMedia' in window && window.matchMedia("(min-resolution:144dpi)").matches)),
doc = document.documentElement,
ie3d = ie && ('transition' in doc.style),
webkit3d = webkit && ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()),
gecko3d = gecko && ('MozPerspective' in doc.style),
opera3d = opera && ('OTransition' in doc.style);
webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()),
gecko3d = 'MozPerspective' in doc.style,
opera3d = 'OTransition' in doc.style,
any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d);
var touch = !window.L_NO_TOUCH && (function () {
var startName = 'ontouchstart';
// WebKit, etc
if (startName in doc) {
// IE10+ (We simulate these into touch* events in L.DomEvent and L.DomEvent.MsTouch) or WebKit, etc.
if (msTouch || (startName in doc)) {
return true;
}
@ -390,15 +402,12 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent;
return supported;
}());
var retina = (('devicePixelRatio' in window && window.devicePixelRatio > 1) || ('matchMedia' in window && window.matchMedia("(min-resolution:144dpi)").matches));
L.Browser = {
ua: ua,
ie: ie,
ie6: ie6,
ie7: ie7,
webkit: webkit,
gecko: gecko,
opera: opera,
android: android,
android23: android23,
@ -408,17 +417,19 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent;
webkit3d: webkit3d,
gecko3d: gecko3d,
opera3d: opera3d,
any3d: !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d),
any3d: any3d,
mobile: mobile,
mobileWebkit: mobile && webkit,
mobileWebkit3d: mobile && webkit3d,
mobileOpera: mobile && opera,
mobileOpera: mobile && window.opera,
touch: touch,
msTouch: msTouch,
retina: retina
};
}());
@ -674,7 +685,7 @@ L.DomUtil = {
value = el.currentStyle[style];
}
if (!value || value === 'auto') {
if ((!value || value === 'auto') && document.defaultView) {
var css = document.defaultView.getComputedStyle(el, null);
value = css ? css[style] : null;
}
@ -688,10 +699,11 @@ L.DomUtil = {
left = 0,
el = element,
docBody = document.body,
pos;
pos,
ie7 = L.Browser.ie7;
do {
top += el.offsetTop || 0;
top += el.offsetTop || 0;
left += el.offsetLeft || 0;
pos = L.DomUtil.getStyle(el, 'position');
@ -714,12 +726,32 @@ L.DomUtil = {
top -= el.scrollTop || 0;
left -= el.scrollLeft || 0;
//Webkit (and ie <= 7) handles RTL scrollLeft different to everyone else
// https://code.google.com/p/closure-library/source/browse/trunk/closure/goog/style/bidi.js
if (!L.DomUtil.documentIsLtr() && (L.Browser.webkit || ie7)) {
left += el.scrollWidth - el.clientWidth;
//ie7 shows the scrollbar by default and provides clientWidth counting it, so we need to add it back in if it is visible
// Scrollbar is on the left as we are RTL
if (ie7 && L.DomUtil.getStyle(el, 'overflow-y') !== 'hidden' && L.DomUtil.getStyle(el, 'overflow') !== 'hidden') {
left += 17;
}
}
el = el.parentNode;
} while (el);
return new L.Point(left, top);
},
documentIsLtr: function () {
if (!L.DomUtil._docIsLtrCached) {
L.DomUtil._docIsLtrCached = true;
L.DomUtil._docIsLtr = L.DomUtil.getStyle(document.body, 'direction') === "ltr";
}
return L.DomUtil._docIsLtr;
},
create: function (tagName, className, container) {
var el = document.createElement(tagName);
@ -777,7 +809,7 @@ L.DomUtil = {
if ('opacity' in el.style) {
el.style.opacity = value;
} else if (L.Browser.ie) {
} else if ('filter' in el.style) {
var filter = false,
filterName = 'DXImageTransform.Microsoft.Alpha';
@ -1156,6 +1188,13 @@ L.CRS = {
L.CRS.Simple = L.Util.extend({}, L.CRS, {
projection: L.Projection.LonLat,
transformation: new L.Transformation(1, 0, 1, 0)
});
L.CRS.EPSG3857 = L.Util.extend({}, L.CRS, {
code: 'EPSG:3857',
@ -2547,7 +2586,7 @@ L.TileLayer.Canvas = L.TileLayer.extend({
},
_redrawTile: function (tile) {
this.drawTile(tile, tile._tilePoint, tile._zoom);
this.drawTile(tile, tile._tilePoint, this._map._zoom);
},
_createTileProto: function () {
@ -2564,19 +2603,18 @@ L.TileLayer.Canvas = L.TileLayer.extend({
return tile;
},
_loadTile: function (tile, tilePoint, zoom) {
_loadTile: function (tile, tilePoint) {
tile._layer = this;
tile._tilePoint = tilePoint;
tile._zoom = zoom;
this.drawTile(tile, tilePoint, zoom);
this._redrawTile(tile);
if (!this.options.async) {
this.tileDrawn(tile);
}
},
drawTile: function (tile, tilePoint, zoom) {
drawTile: function (tile, tilePoint) {
// override with rendering code
},
@ -2872,7 +2910,9 @@ L.Marker = L.Class.extend({
clickable: true,
draggable: false,
zIndexOffset: 0,
opacity: 1
opacity: 1,
riseOnHover: false,
riseOffset: 250
},
initialize: function (latlng, options) {
@ -2966,7 +3006,14 @@ L.Marker = L.Class.extend({
needOpacityUpdate = (this.options.opacity < 1);
L.DomUtil.addClass(this._icon, classToAdd);
if (options.riseOnHover) {
L.DomEvent
.on(this._icon, 'mouseover', this._bringToFront, this)
.on(this._icon, 'mouseout', this._resetZIndex, this);
}
}
if (!this._shadow) {
this._shadow = options.icon.createShadow();
@ -2992,6 +3039,12 @@ L.Marker = L.Class.extend({
_removeIcon: function () {
var panes = this._map._panes;
if (this.options.riseOnHover) {
L.DomEvent
.off(this._icon, 'mouseover', this._bringToFront)
.off(this._icon, 'mouseout', this._resetZIndex);
}
panes.markerPane.removeChild(this._icon);
if (this._shadow) {
@ -3008,7 +3061,13 @@ L.Marker = L.Class.extend({
L.DomUtil.setPosition(this._shadow, pos);
}
this._icon.style.zIndex = pos.y + this.options.zIndexOffset;
this._zIndex = pos.y + this.options.zIndexOffset;
this._resetZIndex();
},
_updateZIndex: function (offset) {
this._icon.style.zIndex = this._zIndex + offset;
},
_animateZoom: function (opt) {
@ -3073,6 +3132,14 @@ L.Marker = L.Class.extend({
if (this._shadow) {
L.DomUtil.setOpacity(this._shadow, this.options.opacity);
}
},
_bringToFront: function () {
this._updateZIndex(this.options.riseOffset);
},
_resetZIndex: function () {
this._updateZIndex(0);
}
});
@ -3311,6 +3378,8 @@ L.Popup = L.Class.extend({
},
_updatePosition: function () {
if (!this._map) { return; }
var pos = this._map.latLngToLayerPoint(this._latlng),
is3d = L.Browser.any3d,
offset = this.options.offset;
@ -3908,11 +3977,11 @@ L.Map.include({
_animatePathZoom: function (opt) {
var scale = this.getZoomScale(opt.zoom),
offset = this._getCenterOffset(opt.center).divideBy(1 - 1 / scale),
viewportPos = this.containerPointToLayerPoint(this.getSize().multiplyBy(-L.Path.CLIP_PADDING)),
origin = viewportPos.add(offset).round();
offset = this._getCenterOffset(opt.center),
translate = offset.multiplyBy(-scale)._add(this._pathViewport.min);
this._pathRoot.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString((origin.multiplyBy(-1).add(L.DomUtil.getPosition(this._pathRoot)).multiplyBy(scale).add(origin))) + ' scale(' + scale + ') ';
this._pathRoot.style[L.DomUtil.TRANSFORM] =
L.DomUtil.getTranslateString(translate) + ' scale(' + scale + ') ';
this._pathZooming = true;
},
@ -5294,7 +5363,9 @@ L.DomEvent = {
return fn.call(context || obj, e || L.DomEvent._getEvent());
};
if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
if (L.Browser.msTouch && type.indexOf('touch') === 0) {
return this.addMsTouchListener(obj, type, handler, id);
} else if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
return this.addDoubleTapListener(obj, handler, id);
} else if ('addEventListener' in obj) {
@ -5336,7 +5407,9 @@ L.DomEvent = {
if (!handler) { return; }
if (L.Browser.touch && (type === 'dblclick') && this.removeDoubleTapListener) {
if (L.Browser.msTouch && type.indexOf('touch') === 0) {
this.removeMsTouchListener(obj, type, id);
} else if (L.Browser.touch && (type === 'dblclick') && this.removeDoubleTapListener) {
this.removeDoubleTapListener(obj, id);
} else if ('removeEventListener' in obj) {
@ -5563,6 +5636,7 @@ L.Draggable = L.Class.extend({
},
_onUp: function (e) {
var simulateClickTouch;
if (this._simulateClick && e.changedTouches) {
var first = e.changedTouches[0],
el = first.target,
@ -5573,7 +5647,7 @@ L.Draggable = L.Class.extend({
}
if (dist < L.Draggable.TAP_TOLERANCE) {
this._simulateEvent('click', first);
simulateClickTouch = first;
}
}
@ -5592,6 +5666,11 @@ L.Draggable = L.Class.extend({
this.fire('dragend');
}
this._moving = false;
if (simulateClickTouch) {
this._moved = false;
this._simulateEvent('click', simulateClickTouch);
}
},
_setMovingCursor: function () {
@ -5824,7 +5903,7 @@ L.Map.addInitHook('addHandler', 'doubleClickZoom', L.Map.DoubleClickZoom);
*/
L.Map.mergeOptions({
scrollWheelZoom: !L.Browser.touch
scrollWheelZoom: !L.Browser.touch || L.Browser.msTouch
});
L.Map.ScrollWheelZoom = L.Handler.extend({
@ -5891,6 +5970,10 @@ L.Map.addInitHook('addHandler', 'scrollWheelZoom', L.Map.ScrollWheelZoom);
L.Util.extend(L.DomEvent, {
_touchstart: L.Browser.msTouch ? 'MSPointerDown' : 'touchstart',
_touchend: L.Browser.msTouch ? 'MSPointerUp' : 'touchend',
// inspired by Zepto touch code by Thomas Fuchs
addDoubleTapListener: function (obj, handler, id) {
var last,
@ -5898,23 +5981,55 @@ L.Util.extend(L.DomEvent, {
delay = 250,
touch,
pre = '_leaflet_',
touchstart = 'touchstart',
touchend = 'touchend';
touchstart = this._touchstart,
touchend = this._touchend,
trackedTouches = [];
function onTouchStart(e) {
if (e.touches.length !== 1) {
var count;
if (L.Browser.msTouch) {
trackedTouches.push(e.pointerId);
count = trackedTouches.length;
} else {
count = e.touches.length;
}
if (count > 1) {
return;
}
var now = Date.now(),
delta = now - (last || now);
touch = e.touches[0];
touch = e.touches ? e.touches[0] : e;
doubleTap = (delta > 0 && delta <= delay);
last = now;
}
function onTouchEnd(e) {
if (L.Browser.msTouch) {
var idx = trackedTouches.indexOf(e.pointerId);
if (idx === -1) {
return;
}
trackedTouches.splice(idx, 1);
}
if (doubleTap) {
if (L.Browser.msTouch) {
//Work around .type being readonly with MSPointer* events
var newTouch = { },
prop;
for (var i in touch) {
if (true) { //Make JSHint happy, we want to copy all properties
prop = touch[i];
if (typeof prop === 'function') {
newTouch[i] = prop.bind(touch);
} else {
newTouch[i] = prop;
}
}
}
touch = newTouch;
}
touch.type = 'dblclick';
handler(touch);
last = null;
@ -5923,15 +6038,171 @@ L.Util.extend(L.DomEvent, {
obj[pre + touchstart + id] = onTouchStart;
obj[pre + touchend + id] = onTouchEnd;
//On msTouch we need to listen on the document otherwise a drag starting on the map and moving off screen will not come through to us
// so we will lose track of how many touches are ongoing
var endElement = L.Browser.msTouch ? document.documentElement : obj;
obj.addEventListener(touchstart, onTouchStart, false);
obj.addEventListener(touchend, onTouchEnd, false);
endElement.addEventListener(touchend, onTouchEnd, false);
if (L.Browser.msTouch) {
endElement.addEventListener('MSPointerCancel', onTouchEnd, false);
}
return this;
},
removeDoubleTapListener: function (obj, id) {
var pre = '_leaflet_';
obj.removeEventListener(obj, obj[pre + 'touchstart' + id], false);
obj.removeEventListener(obj, obj[pre + 'touchend' + id], false);
obj.removeEventListener(this._touchstart, obj[pre + this._touchstart + id], false);
(L.Browser.msTouch ? document.documentElement : obj).removeEventListener(this._touchend, obj[pre + this._touchend + id], false);
if (L.Browser.msTouch) {
document.documentElement.removeEventListener('MSPointerCancel', obj[pre + this._touchend + id], false);
}
return this;
}
});
L.Util.extend(L.DomEvent, {
_msTouches: [],
_msDocumentListener: false,
// Provides a touch events wrapper for msPointer events.
// Based on changes by veproza https://github.com/CloudMade/Leaflet/pull/1019
addMsTouchListener: function (obj, type, handler, id) {
switch (type) {
case 'touchstart':
return this.addMsTouchListenerStart(obj, type, handler, id);
case 'touchend':
return this.addMsTouchListenerEnd(obj, type, handler, id);
case 'touchmove':
return this.addMsTouchListenerMove(obj, type, handler, id);
default:
throw 'Unknown touch event type';
}
},
addMsTouchListenerStart: function (obj, type, handler, id) {
var pre = '_leaflet_',
touches = this._msTouches;
var cb = function (e) {
var alreadyInArray = false;
for (var i = 0; i < touches.length; i++) {
if (touches[i].pointerId === e.pointerId) {
alreadyInArray = true;
break;
}
}
if (!alreadyInArray) {
touches.push(e);
}
e.touches = touches.slice();
e.changedTouches = [e];
handler(e);
};
obj[pre + 'touchstart' + id] = cb;
obj.addEventListener('MSPointerDown', cb, false);
//Need to also listen for end events to keep the _msTouches list accurate
//this needs to be on the body and never go away
if (!this._msDocumentListener) {
var internalCb = function (e) {
for (var i = 0; i < touches.length; i++) {
if (touches[i].pointerId === e.pointerId) {
touches.splice(i, 1);
break;
}
}
};
//We listen on the documentElement as any drags that end by moving the touch off the screen get fired there
document.documentElement.addEventListener('MSPointerUp', internalCb, false);
document.documentElement.addEventListener('MSPointerCancel', internalCb, false);
this._msDocumentListener = true;
}
return this;
},
addMsTouchListenerMove: function (obj, type, handler, id) {
var pre = '_leaflet_';
var touches = this._msTouches;
var cb = function (e) {
//Don't fire touch moves when mouse isn't down
if (e.pointerType === e.MSPOINTER_TYPE_MOUSE && e.buttons === 0) {
return;
}
for (var i = 0; i < touches.length; i++) {
if (touches[i].pointerId === e.pointerId) {
touches[i] = e;
break;
}
}
e.touches = touches.slice();
e.changedTouches = [e];
handler(e);
};
obj[pre + 'touchmove' + id] = cb;
obj.addEventListener('MSPointerMove', cb, false);
return this;
},
addMsTouchListenerEnd: function (obj, type, handler, id) {
var pre = '_leaflet_',
touches = this._msTouches;
var cb = function (e) {
for (var i = 0; i < touches.length; i++) {
if (touches[i].pointerId === e.pointerId) {
touches.splice(i, 1);
break;
}
}
e.touches = touches.slice();
e.changedTouches = [e];
handler(e);
};
obj[pre + 'touchend' + id] = cb;
obj.addEventListener('MSPointerUp', cb, false);
obj.addEventListener('MSPointerCancel', cb, false);
return this;
},
removeMsTouchListener: function (obj, type, id) {
var pre = '_leaflet_',
cb = obj[pre + type + id];
switch (type) {
case 'touchstart':
obj.removeEventListener('MSPointerDown', cb, false);
break;
case 'touchmove':
obj.removeEventListener('MSPointerMove', cb, false);
break;
case 'touchend':
obj.removeEventListener('MSPointerUp', cb, false);
obj.removeEventListener('MSPointerCancel', cb, false);
break;
}
return this;
}
});
@ -6125,8 +6396,8 @@ L.Map.BoxZoom = L.Handler.extend({
L.DomUtil.setPosition(box, newPos);
// TODO refactor: remove hardcoded 4 pixels
box.style.width = (Math.abs(offset.x) - 4) + 'px';
box.style.height = (Math.abs(offset.y) - 4) + 'px';
box.style.width = (Math.max(0, Math.abs(offset.x) - 4)) + 'px';
box.style.height = (Math.max(0, Math.abs(offset.y) - 4)) + 'px';
},
_onMouseUp: function (e) {