fix merge conflict

This commit is contained in:
Patrick Arlt 2014-10-15 08:36:22 -07:00
commit 2c7eda825d
35 changed files with 346 additions and 99 deletions

View File

@ -133,7 +133,6 @@ These changes were targeted at removing any hardcoded projection-specific logic
* Fixed `ImageOverlay` mercator distortion on lower zoom levels. * Fixed `ImageOverlay` mercator distortion on lower zoom levels.
* Fixed a bug where layers didn't fire `popupopen` and `popupclose` events when manually creating a popup object and passing it to `bindPopup`. [#2354](https://github.com/Leaflet/Leaflet/issues/2354) * Fixed a bug where layers didn't fire `popupopen` and `popupclose` events when manually creating a popup object and passing it to `bindPopup`. [#2354](https://github.com/Leaflet/Leaflet/issues/2354)
* Fixed box-zoom overlay appearing under markers. [#1813](https://github.com/Leaflet/Leaflet/issues/1813) * Fixed box-zoom overlay appearing under markers. [#1813](https://github.com/Leaflet/Leaflet/issues/1813)
* Fixed an issue where clicks on Android were skipped when happened too fast. [#2303](https://github.com/Leaflet/Leaflet/issues/2303)
### Misc improvements ### Misc improvements
@ -143,6 +142,19 @@ These changes were targeted at removing any hardcoded projection-specific logic
* Added reference to Leaflet CSS in `package.json` (by [@bclinkinbeard](https://github.com/bclinkinbeard)). [#2432](https://github.com/Leaflet/Leaflet/pull/2432) * Added reference to Leaflet CSS in `package.json` (by [@bclinkinbeard](https://github.com/bclinkinbeard)). [#2432](https://github.com/Leaflet/Leaflet/pull/2432)
## 0.7.3 (May 23, 2014)
* Added proper **bower** and **component** support (by [@calvinmetcalf](https://github.com/calvinmetcalf)). [#2561](https://github.com/Leaflet/Leaflet/pull/2561) [#1903](https://github.com/Leaflet/Leaflet/issues/1903)
* Fixed a bug where dragging the map outside the window caused an error on FF. [#2610](https://github.com/Leaflet/Leaflet/issues/2610)
* Fixed a bug where some taps on Android where not working, often falsely perceived as drags (by [@axefrog](https://github.com/axefrog)). [#2503](https://github.com/Leaflet/Leaflet/pull/2503)
* Fixed a bug where clicks on Android were skipped when happened too fast. [#2303](https://github.com/Leaflet/Leaflet/issues/2303)
* Fixed a bug where calling `setView` (or similar methods) several times in succession could freeze the map. [#2521](https://github.com/Leaflet/Leaflet/issues/2521) [#2236](https://github.com/Leaflet/Leaflet/issues/2236) [#2485](https://github.com/Leaflet/Leaflet/issues/2485)
* Fixed a bug where `Control.Layers` wasn't properly removed (by [@jack-kerouac](https://github.com/jack-kerouac)). [#2569](https://github.com/Leaflet/Leaflet/pull/2569)
* Fixed a bug that caused `TileLayer` `load` event not to fire properly. [#2510](https://github.com/Leaflet/Leaflet/issues/2510)
* Fixed Canvas-based paths not triggering `remove` event when removed (by @adimitrov). [#2486](https://github.com/Leaflet/Leaflet/pull/2486)
* Fixed a bug where you could end up with fractional zoom after pinch-zooming in some cases (by [@danzel](https://github.com/danzel). [#2400](https://github.com/Leaflet/Leaflet/pull/2400) [#1943](https://github.com/Leaflet/Leaflet/issues/1934)
## 0.7.2 (January 17, 2014) ## 0.7.2 (January 17, 2014)
* Fixed a bug that appeared with **Chrome 32 update** that made all **mouse events shifted on scrolled pages**. [#2352](https://github.com/Leaflet/Leaflet/issues/2352) * Fixed a bug that appeared with **Chrome 32 update** that made all **mouse events shifted on scrolled pages**. [#2352](https://github.com/Leaflet/Leaflet/issues/2352)

View File

@ -44,7 +44,7 @@ try asking [on the Leaflet forum](https://groups.google.com/forum/#!forum/leafle
### Considerations for Accepting Patches ### Considerations for Accepting Patches
While we happily accept patches, we're also commited to keeping Leaflet simple, lightweight and blazingly fast. While we happily accept patches, we're also committed to keeping Leaflet simple, lightweight and blazingly fast.
So bugfixes, performance optimizations and small improvements that don't add a lot of code So bugfixes, performance optimizations and small improvements that don't add a lot of code
are much more likely to get accepted quickly. are much more likely to get accepted quickly.
@ -53,7 +53,7 @@ Before sending a pull request with a new feature, first check if it's been discu
or [Leaflet UserVoice](http://leaflet.uservoice.com/)), or [Leaflet UserVoice](http://leaflet.uservoice.com/)),
and then ask yourself two questions: and then ask yourself two questions:
1. Are you sure that this new feature is important enough to justify its presense in the Leaflet core? 1. Are you sure that this new feature is important enough to justify its presence in the Leaflet core?
Or will it look better as a plugin in a separate repository? Or will it look better as a plugin in a separate repository?
2. Is it written in a simple, concise way that doesn't add bulk to the codebase? 2. Is it written in a simple, concise way that doesn't add bulk to the codebase?
@ -85,7 +85,7 @@ Please do not commit to the `master` branch, or your unrelated changes will go i
You should also follow the code style and whitespace conventions of the original codebase. You should also follow the code style and whitespace conventions of the original codebase.
In particular, use tabs for indentation and spaces for alignment. In particular, use tabs for indentation and spaces for alignment.
Before commiting your changes, run `jake lint` to catch any JS errors in the code and fix them. Before committing your changes, run `jake lint` to catch any JS errors in the code and fix them.
If you add any new files to the Leaflet source, make sure to also add them to `build/deps.js` If you add any new files to the Leaflet source, make sure to also add them to `build/deps.js`
so that the build system knows about them. so that the build system knows about them.
@ -142,7 +142,7 @@ If you need to make edits in a local repository to see how it looks in the proce
4. Open `localhost:4000` in your browser. 4. Open `localhost:4000` in your browser.
Now any file changes will be updated when you reload pages automatically. Now any file changes will be updated when you reload pages automatically.
After commiting the changes, just send a pull request. After committing the changes, just send a pull request.
If you need to update documentation according to a new feature that only appeared in the master version (not stable one), If you need to update documentation according to a new feature that only appeared in the master version (not stable one),
you need to make changes to `gh-pages-master` branch instead of `gh-pages`. you need to make changes to `gh-pages-master` branch instead of `gh-pages`.

6
FAQ.md
View File

@ -26,10 +26,10 @@ You can roll your own tiles as well.
but there are providers that use other sources. but there are providers that use other sources.
Check out [this example](http://leaflet-extras.github.io/leaflet-providers/preview/) Check out [this example](http://leaflet-extras.github.io/leaflet-providers/preview/)
with half a hundred different layers to choose from. with over seventy different layers to choose from.
Popular commercial options, free up to a particular number of requests, include Popular commercial options, free up to a particular number of requests, include
[MapBox](http://mapbox.com), [MapBox](http://mapbox.com),
[Bing Maps](http://www.microsoft.com/maps/choose-your-binge's-maps-API.aspx) (using a [plugin](https://github.com/shramov/leaflet-plugins)), [Bing Maps](http://www.microsoft.com/maps/choose-your-bing-maps-API.aspx) (using a [plugin](https://github.com/shramov/leaflet-plugins)),
[Esri ArcGIS](http://www.arcgis.com/features/maps/imagery.html) ([official plugin](https://github.com/Esri/esri-leaflet)) [Esri ArcGIS](http://www.arcgis.com/features/maps/imagery.html) ([official plugin](https://github.com/Esri/esri-leaflet))
and [Nokia Here](http://developer.here.com/web-experiences). and [Nokia Here](http://developer.here.com/web-experiences).
A notable exception is [MapQuest Open](http://developer.mapquest.com/web/products/open/map), which is free for any number of requests. A notable exception is [MapQuest Open](http://developer.mapquest.com/web/products/open/map), which is free for any number of requests.
@ -45,7 +45,7 @@ and [MapQuest Open](http://developer.mapquest.com/web/products/open/map) provide
#### I want to use Google Maps API tiles with Leaflet, can I do that? #### I want to use Google Maps API tiles with Leaflet, can I do that?
The problem with Google is that its [Terms of Use](https://developers.google.com/maps/terms?hl=ru) forbid any means of tile access other than through the Google Maps API. The problem with Google is that its [Terms of Use](https://developers.google.com/maps/terms) forbid any means of tile access other than through the Google Maps API.
You can add the Google Maps API as a Leaflet layer with a [plugin](https://github.com/shramov/leaflet-plugins). But note that the map experience will not be perfect, because Leaflet will just act as a proxy to the Google Maps JS engine, so you won't get all the performance and usability benefits of using Leaflet when the Google layer is on. You can add the Google Maps API as a Leaflet layer with a [plugin](https://github.com/shramov/leaflet-plugins). But note that the map experience will not be perfect, because Leaflet will just act as a proxy to the Google Maps JS engine, so you won't get all the performance and usability benefits of using Leaflet when the Google layer is on.

View File

@ -23,7 +23,7 @@ function hint(msg, paths) {
console.log('\tCheck passed.\n'); console.log('\tCheck passed.\n');
complete(); complete();
}); });
} };
} }
desc('Check Leaflet source for errors with JSHint'); desc('Check Leaflet source for errors with JSHint');
@ -36,12 +36,14 @@ desc('Combine and compress Leaflet source files');
task('build', {async: true}, function (compsBase32, buildName) { task('build', {async: true}, function (compsBase32, buildName) {
var v; var v;
jake.exec('git log -1 --pretty=format:"%h"', {}, function () { jake.exec('git log -1 --pretty=format:"%h"', {breakOnError: false}, function () {
build.build(complete, v, compsBase32, buildName); build.build(complete, v, compsBase32, buildName);
}).on('stdout', function (data) { }).on('stdout', function (data) {
v = version + ' (' + data.toString() + ')'; v = version + ' (' + data.toString() + ')';
}) }).on('error', function () {
v = version;
});
}); });
desc('Run PhantomJS tests'); desc('Run PhantomJS tests');

View File

@ -2,7 +2,6 @@
"name": "leaflet", "name": "leaflet",
"description": "JavaScript library for mobile-friendly interactive maps", "description": "JavaScript library for mobile-friendly interactive maps",
"main": [ "main": [
"dist/leaflet.js",
"dist/leaflet.css", "dist/leaflet.css",
"dist/leaflet-src.js", "dist/leaflet-src.js",
"dist/images/layers-2x.png", "dist/images/layers-2x.png",

68
debug/map/markers.html Normal file
View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/screen.css" />
<script type="text/javascript" src="../../build/deps.js"></script>
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
map = L.map('map', { center: [0, 0], zoom: 3, maxZoom: 4 });
L.Icon.Default.imagePath = 'http://cdn.leafletjs.com/leaflet-0.7.3/images';
var markerStatic = new L.Marker([0, -10], {
draggable: false,
title: 'Static'
});
map.addLayer(markerStatic);
markerStatic.bindPopup("Static");
var markerDraggable = new L.Marker([0, 10], {
draggable: true,
title: 'Draggable'
});
map.addLayer(markerDraggable);
markerDraggable.bindPopup("Draggable");
var poly = new L.Polygon([[0, 10], [0, 15.5], [0, 50], [20, 20.5]]);
map.addLayer(poly);
markerDraggable.on('click', function(e) {
console.log('markerDraggable click');
});
markerStatic.on('click', function(e) {
console.log('markerStatic click');
})
map.on('click', function(e) {
console.log('map click');
});
poly.on('click', function(e) {
console.log('poly click');
});
L.tileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
attribution: "Map: Tiles Courtesy of MapQuest (OpenStreetMap, CC-BY-SA)",
subdomains: ["otile1","otile2","otile3","otile4"],
maxZoom: 12,
minZoom: 2
}).addTo(map);
</script>
</body>
</html>

View File

@ -35,7 +35,7 @@
opacity: 1, opacity: 1,
smoothFactor: 1, smoothFactor: 1,
color: 'red', color: 'red',
clickable:true interactive:true
})); }));
polygons.on('click', function(m) { polygons.on('click', function(m) {

View File

@ -43,7 +43,7 @@
[51, 7.000], [51, 7.000],
[51.002, 7.004] [51.002, 7.004]
], ],
{ clickable:false,color:'#f00' } { interactive:false,color:'#f00' }
).addTo(map); ).addTo(map);
// when the mouse hovers over the red route2, you cannot click through the blue route1 beneath // when the mouse hovers over the red route2, you cannot click through the blue route1 beneath

10
dist/leaflet.css vendored
View File

@ -40,7 +40,9 @@
.leaflet-marker-shadow { .leaflet-marker-shadow {
display: block; display: block;
} }
/* map is broken in FF if you have max-width: 100% on tiles */ /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container svg,
.leaflet-container img { .leaflet-container img {
max-width: none !important; max-width: none !important;
} }
@ -171,7 +173,7 @@
/* cursors */ /* cursors */
.leaflet-clickable { .leaflet-interactive {
cursor: pointer; cursor: pointer;
} }
.leaflet-container { .leaflet-container {
@ -179,7 +181,7 @@
cursor: -moz-grab; cursor: -moz-grab;
} }
.leaflet-crosshair, .leaflet-crosshair,
.leaflet-crosshair .leaflet-clickable { .leaflet-crosshair .leaflet-interactive {
cursor: crosshair; cursor: crosshair;
} }
.leaflet-popup-pane, .leaflet-popup-pane,
@ -187,7 +189,7 @@
cursor: auto; cursor: auto;
} }
.leaflet-dragging .leaflet-container, .leaflet-dragging .leaflet-container,
.leaflet-dragging .leaflet-clickable { .leaflet-dragging .leaflet-interactive {
cursor: move; cursor: move;
cursor: -webkit-grabbing; cursor: -webkit-grabbing;
cursor: -moz-grabbing; cursor: -moz-grabbing;

View File

@ -3,18 +3,18 @@
"version": "0.7.0", "version": "0.7.0",
"description": "JavaScript library for mobile-friendly interactive maps", "description": "JavaScript library for mobile-friendly interactive maps",
"devDependencies": { "devDependencies": {
"jake": "~0.7.9", "jake": "~0.7.14",
"jshint": "~2.4.4", "jshint": "~2.5.1",
"uglify-js": "~2.4.13", "uglify-js": "~2.4.13",
"mocha": "~1.17.1", "mocha": "~1.19.0",
"happen": "~0.1.3", "happen": "~0.1.3",
"karma": "~0.12.0", "karma": "~0.12.16",
"karma-mocha": "~0.1.1", "karma-mocha": "~0.1.3",
"karma-coverage": "~0.2.0", "karma-coverage": "~0.2.3",
"karma-phantomjs-launcher": "^0.1.2", "karma-phantomjs-launcher": "^0.1.4",
"karma-chrome-launcher": "^0.1.2", "karma-chrome-launcher": "^0.1.4",
"tin": "^0.4.0", "tin": "^0.5.0",
"copyfiles": "0.0.1" "copyfiles": "0.1.0"
}, },
"main": "dist/leaflet-src.js", "main": "dist/leaflet-src.js",
"style": "dist/leaflet.css", "style": "dist/leaflet.css",

View File

@ -4,6 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Leaflet Spec Runner</title> <title>Leaflet Spec Runner</title>
<link rel="stylesheet" type="text/css" href="../node_modules/mocha/mocha.css"> <link rel="stylesheet" type="text/css" href="../node_modules/mocha/mocha.css">
<link rel="stylesheet" type="text/css" href="../dist/leaflet.css">
</head> </head>
<body> <body>
<div id="mocha"></div> <div id="mocha"></div>

View File

@ -64,6 +64,12 @@ describe('LatLng', function () {
expect(Math.abs(Math.round(a.distanceTo(b) / 1000) - 2084) < 5).to.eql(true); expect(Math.abs(Math.round(a.distanceTo(b) / 1000) - 2084) < 5).to.eql(true);
}); });
it('does not return NaN if input points are equal', function () {
var a = new L.LatLng(50.5, 30.5);
var b = new L.LatLng(50.5, 30.5);
expect(a.distanceTo(b)).to.eql(0);
});
}); });
describe('L.latLng factory', function () { describe('L.latLng factory', function () {

View File

@ -105,4 +105,98 @@ describe('TileLayer', function () {
}); });
}); });
}); });
describe("'loading' event", function() {
var tileUrl1 = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
tileUrl2 = 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png';
// Add map div to DOM. The map panning tests do not work reliably unless
// the Leaflet map is properly styled and part of the DOM
var mapDiv = document.createElement('div');
mapDiv.style.height = '256px';
mapDiv.style.width = '256px';
document.body.appendChild(mapDiv);
this.afterAll(function() {
document.body.removeChild(mapDiv);
});
// Set the map zoom high enough that panning by 256 pixels necessarily loads more tiles
var myMap = L.map(mapDiv).setView([0, 0], 13);
describe("after a tilelayer has been initialized with an empty string", function() {
var layer = L.tileLayer('');
var updateInterval = layer.options.updateInterval + 500;
var loadingSpy;
beforeEach(function() {
loadingSpy = sinon.spy();
layer.on('loading', function() { loadingSpy(); });
});
afterEach(function() {
layer.off('loading');
});
it("is fired when the tilelayer is added to the map", function() {
layer.addTo(myMap);
expect(loadingSpy.calledOnce).to.be.ok();
});
it("is fired again when the tilelayer has its url set to a real tile url", function(done) {
layer.setUrl(tileUrl2);
setTimeout(function() {
expect(loadingSpy.calledOnce).to.be.ok();
done();
}, updateInterval);
});
it("is fired again when the map is panned enough to load more tiles", function(done) {
myMap.panBy([256,256]);
setTimeout(function() {
expect(loadingSpy.calledOnce).to.be.ok();
done();
}, updateInterval);
});
});
describe("after a tilelayer has been initialized with a real tile url", function() {
var layer = L.tileLayer(tileUrl1);
var updateInterval = layer.options.updateInterval + 500;
var loadingSpy;
beforeEach(function() {
loadingSpy = sinon.spy();
layer.on('loading', function() { loadingSpy(); });
});
afterEach(function() {
layer.off('loading');
});
it("is fired when the tilelayer is added to the map", function() {
layer.addTo(myMap);
expect(loadingSpy.calledOnce).to.be.ok();
});
it("is fired again when the tilelayer has its url set to a real tile url", function(done) {
layer.setUrl(tileUrl2);
setTimeout(function() {
expect(loadingSpy.calledOnce).to.be.ok();
done();
}, updateInterval);
});
it("is fired again when the map is panned enough to load more tiles", function(done) {
myMap.panBy([256,256]);
setTimeout(function() {
expect(loadingSpy.calledOnce).to.be.ok();
done();
}, updateInterval);
});
});
});
}); });

View File

@ -21,8 +21,9 @@ if (typeof module === 'object' && typeof module.exports === 'object') {
// define Leaflet as an AMD module // define Leaflet as an AMD module
} else if (typeof define === 'function' && define.amd) { } else if (typeof define === 'function' && define.amd) {
define(L); define(L);
}
// define Leaflet as a global L variable, saving the original L to restore later if needed // define Leaflet as a global L variable, saving the original L to restore later if needed
} else { if (typeof window !== 'undefined') {
expose(); expose();
} }

View File

@ -124,8 +124,8 @@ L.Control.Layers = L.Control.extend({
_update: function () { _update: function () {
if (!this._container) { return; } if (!this._container) { return; }
this._baseLayersList.innerHTML = ''; L.DomUtil.empty(this._baseLayersList);
this._overlaysList.innerHTML = ''; L.DomUtil.empty(this._overlaysList);
var baseLayersPresent, overlaysPresent, i, obj; var baseLayersPresent, overlaysPresent, i, obj;

View File

@ -80,7 +80,7 @@ L.Control.Scale = L.Control.extend({
}, },
_updateScale: function (scale, text, ratio) { _updateScale: function (scale, text, ratio) {
scale.style.width = (Math.round(this.options.maxWidth * ratio) - 10) + 'px'; scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px';
scale.innerHTML = text; scale.innerHTML = text;
}, },

View File

@ -5,11 +5,10 @@
L.Util = { L.Util = {
// extend an object with properties of one or more other objects // extend an object with properties of one or more other objects
extend: function (dest) { extend: function (dest) {
var sources = Array.prototype.slice.call(arguments, 1), var i, j, len, src;
i, j, len, src;
for (j = 0, len = sources.length; j < len; j++) { for (j = 1, len = arguments.length; j < len; j++) {
src = sources[j]; src = arguments[j];
for (i in src) { for (i in src) {
dest[i] = src[i]; dest[i] = src[i];
} }
@ -174,11 +173,11 @@ L.Util = {
getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); }; getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); };
L.Util.requestAnimFrame = function (fn, context, immediate, element) { L.Util.requestAnimFrame = function (fn, context, immediate) {
if (immediate && requestFn === timeoutDefer) { if (immediate && requestFn === timeoutDefer) {
fn.call(context); fn.call(context);
} else { } else {
return requestFn.call(window, L.bind(fn, context), element); return requestFn.call(window, L.bind(fn, context));
} }
}; };

View File

@ -38,6 +38,12 @@ L.DomUtil = {
} }
}, },
empty: function (el) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
},
toFront: function (el) { toFront: function (el) {
el.parentNode.appendChild(el); el.parentNode.appendChild(el);
}, },

View File

@ -90,7 +90,9 @@ L.Draggable = L.Evented.extend({
this._startPos = L.DomUtil.getPosition(this._element).subtract(offset); this._startPos = L.DomUtil.getPosition(this._element).subtract(offset);
L.DomUtil.addClass(document.body, 'leaflet-dragging'); 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); this._newPos = this._startPos.add(offset);
@ -106,9 +108,13 @@ L.Draggable = L.Evented.extend({
this.fire('drag'); this.fire('drag');
}, },
_onUp: function (e) { _onUp: function () {
L.DomUtil.removeClass(document.body, 'leaflet-dragging'); 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) { for (var i in L.Draggable.MOVE) {
L.DomEvent L.DomEvent

View File

@ -19,9 +19,6 @@ L.PosAnimation = L.Evented.extend({
L.DomEvent.on(el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this); L.DomEvent.on(el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this);
L.DomUtil.setPosition(el, newPos); L.DomUtil.setPosition(el, newPos);
// toggle reflow, Chrome flickers for some reason if you don't do this
L.Util.falseFn(el.offsetWidth);
// there's no native way to track value updates of transitioned properties, so we imitate this // there's no native way to track value updates of transitioned properties, so we imitate this
this._stepTimer = setInterval(L.bind(this._onStep, this), 50); this._stepTimer = setInterval(L.bind(this._onStep, this), 50);
}, },
@ -32,8 +29,11 @@ L.PosAnimation = L.Evented.extend({
// if we just removed the transition property, the element would jump to its final position, // if we just removed the transition property, the element would jump to its final position,
// so we need to make it stay at the current position // so we need to make it stay at the current position
// Only setPosition if _getPos actually returns a valid position.
this._newPos = this._getPos(); this._newPos = this._getPos();
if (this._newPos) {
L.DomUtil.setPosition(this._el, this._newPos); L.DomUtil.setPosition(this._el, this._newPos);
}
this._onTransitionEnd(); this._onTransitionEnd();
L.Util.falseFn(this._el.offsetWidth); // force reflow in case we are about to start a new animation L.Util.falseFn(this._el.offsetWidth); // force reflow in case we are about to start a new animation

View File

@ -11,9 +11,10 @@ L.CRS.Earth = L.extend({}, L.CRS, {
distance: function (latlng1, latlng2) { distance: function (latlng1, latlng2) {
var rad = Math.PI / 180, var rad = Math.PI / 180,
lat1 = latlng1.lat * rad, lat1 = latlng1.lat * rad,
lat2 = latlng2.lat * rad; lat2 = latlng2.lat * rad,
a = Math.sin(lat1) * Math.sin(lat2) +
Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlng2.lng - latlng1.lng) * rad);
return this.R * Math.acos(Math.sin(lat1) * Math.sin(lat2) + return this.R * Math.acos(Math.min(a, 1));
Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlng2.lng - latlng1.lng) * rad));
} }
}); });

View File

@ -5,7 +5,8 @@
L.ImageOverlay = L.Layer.extend({ L.ImageOverlay = L.Layer.extend({
options: { options: {
opacity: 1 opacity: 1,
alt: ''
}, },
initialize: function (url, bounds, options) { // (String, LatLngBounds, Object) initialize: function (url, bounds, options) { // (String, LatLngBounds, Object)
@ -81,6 +82,10 @@ L.ImageOverlay = L.Layer.extend({
return events; return events;
}, },
getBounds: function() {
return this._bounds;
},
_initImage: function () { _initImage: function () {
var img = this._image = L.DomUtil.create('img', var img = this._image = L.DomUtil.create('img',
'leaflet-image-layer ' + (this._zoomAnimated ? 'leaflet-zoom-animated' : '')); 'leaflet-image-layer ' + (this._zoomAnimated ? 'leaflet-zoom-animated' : ''));
@ -90,6 +95,7 @@ L.ImageOverlay = L.Layer.extend({
img.onload = L.bind(this.fire, this, 'load'); img.onload = L.bind(this.fire, this, 'load');
img.src = this._url; img.src = this._url;
img.alt = this.options.alt;
}, },
_animateZoom: function (e) { _animateZoom: function (e) {

View File

@ -10,7 +10,7 @@ L.Marker = L.Layer.extend({
icon: new L.Icon.Default(), icon: new L.Icon.Default(),
// title: '', // title: '',
// alt: '', // alt: '',
clickable: true, interactive: true,
// draggable: false, // draggable: false,
keyboard: true, keyboard: true,
zIndexOffset: 0, zIndexOffset: 0,
@ -76,7 +76,7 @@ L.Marker = L.Layer.extend({
} }
if (this._popup) { if (this._popup) {
this.bindPopup(this._popup); this.bindPopup(this._popup, this._popup.options);
} }
return this; return this;
@ -201,14 +201,18 @@ L.Marker = L.Layer.extend({
_initInteraction: function () { _initInteraction: function () {
if (!this.options.clickable) { return; } if (!this.options.interactive) { return; }
L.DomUtil.addClass(this._icon, 'leaflet-clickable'); L.DomUtil.addClass(this._icon, 'leaflet-interactive');
L.DomEvent.on(this._icon, 'click dblclick mousedown mouseup mouseover mouseout contextmenu keypress', L.DomEvent.on(this._icon, 'click dblclick mousedown mouseup mouseover mousemove mouseout contextmenu keypress',
this._fireMouseEvent, this); this._fireMouseEvent, this);
if (L.Handler.MarkerDrag) { if (L.Handler.MarkerDrag) {
if (this.dragging) {
this.dragging.disable();
}
this.dragging = new L.Handler.MarkerDrag(this); this.dragging = new L.Handler.MarkerDrag(this);
if (this.options.draggable) { if (this.options.draggable) {
@ -223,8 +227,6 @@ L.Marker = L.Layer.extend({
L.DomEvent.preventDefault(e); L.DomEvent.preventDefault(e);
} }
if (e.type === 'click' && this.dragging && this.dragging.moved()) { return; }
if (e.type === 'keypress' && e.keyCode === 13) { if (e.type === 'keypress' && e.keyCode === 13) {
type = 'click'; type = 'click';
} }

View File

@ -191,11 +191,15 @@ L.GridLayer = L.Layer.extend({
}); });
} }
if (this._abortLoading) {
this._abortLoading();
}
this._tiles = {}; this._tiles = {};
this._tilesToLoad = 0; this._tilesToLoad = 0;
this._tilesTotal = 0; this._tilesTotal = 0;
this._tileContainer.innerHTML = ''; L.DomUtil.empty(this._tileContainer);
if (this._zoomAnimated && e && e.hard) { if (this._zoomAnimated && e && e.hard) {
this._clearBgBuffer(); this._clearBgBuffer();
@ -241,7 +245,10 @@ L.GridLayer = L.Layer.extend({
tileSize = this._getTileSize(); tileSize = this._getTileSize();
if (zoom > this.options.maxZoom || if (zoom > this.options.maxZoom ||
zoom < this.options.minZoom) { return; } zoom < this.options.minZoom) {
this._clearBgBuffer();
return;
}
// tile coordinates range for the current view // tile coordinates range for the current view
var tileBounds = L.bounds( var tileBounds = L.bounds(
@ -324,7 +331,7 @@ L.GridLayer = L.Layer.extend({
_tileCoordsToBounds: function (coords) { _tileCoordsToBounds: function (coords) {
var map = this._map, var map = this._map,
tileSize = this.options.tileSize, tileSize = this._getTileSize(),
nwPoint = coords.multiplyBy(tileSize), nwPoint = coords.multiplyBy(tileSize),
sePoint = nwPoint.add([tileSize, tileSize]), sePoint = nwPoint.add([tileSize, tileSize]),
@ -340,7 +347,7 @@ L.GridLayer = L.Layer.extend({
return coords.x + ':' + coords.y; return coords.x + ':' + coords.y;
}, },
// converts tile cache key to coordiantes // converts tile cache key to coordinates
_keyToTileCoords: function (key) { _keyToTileCoords: function (key) {
var kArr = key.split(':'), var kArr = key.split(':'),
x = parseInt(kArr[0], 10), x = parseInt(kArr[0], 10),
@ -494,7 +501,7 @@ L.GridLayer = L.Layer.extend({
bg = this._bgBuffer; bg = this._bgBuffer;
if (map && !map._animatingZoom && !map.touchZoom._zooming && bg) { if (map && !map._animatingZoom && !map.touchZoom._zooming && bg) {
bg.innerHTML = ''; L.DomUtil.empty(bg);
L.DomUtil.setTransform(bg); L.DomUtil.setTransform(bg);
} }
}, },

View File

@ -22,7 +22,9 @@ L.TileLayer.WMS = L.TileLayer.extend({
// all keys that are not TileLayer options go to WMS params // all keys that are not TileLayer options go to WMS params
for (var i in options) { for (var i in options) {
if (!this.options.hasOwnProperty(i) && i !== 'crs') { if (!this.options.hasOwnProperty(i) &&
i !== 'crs' &&
i !== 'uppercase') {
wmsParams[i] = options[i]; wmsParams[i] = options[i];
} }
} }
@ -38,6 +40,7 @@ L.TileLayer.WMS = L.TileLayer.extend({
onAdd: function (map) { onAdd: function (map) {
this._crs = this.options.crs || map.options.crs; this._crs = this.options.crs || map.options.crs;
this._uppercase = this.options.uppercase || false;
this._wmsVersion = parseFloat(this.wmsParams.version); this._wmsVersion = parseFloat(this.wmsParams.version);
@ -57,9 +60,11 @@ L.TileLayer.WMS = L.TileLayer.extend({
[se.y, nw.x, nw.y, se.x] : [se.y, nw.x, nw.y, se.x] :
[nw.x, se.y, se.x, nw.y]).join(','), [nw.x, se.y, se.x, nw.y]).join(','),
url = L.Util.template(this._url, {s: this._getSubdomain(coords)}); url = L.TileLayer.prototype.getTileUrl.call(this, coords);
return url + L.Util.getParamString(this.wmsParams, url, true) + '&BBOX=' + bbox; return url +
L.Util.getParamString(this.wmsParams, url, this._uppercase) +
(this._uppercase ? '&BBOX=' : '&bbox=') + bbox;
}, },
setParams: function (params, noRedraw) { setParams: function (params, noRedraw) {

View File

@ -16,7 +16,8 @@ L.TileLayer = L.GridLayer.extend({
maxNativeZoom: <Number>, maxNativeZoom: <Number>,
tms: <Boolean>, tms: <Boolean>,
zoomReverse: <Number>, zoomReverse: <Number>,
detectRetina: <Number>, detectRetina: <Boolean>,
crossOrigin: <Boolean>,
*/ */
}, },
@ -56,6 +57,10 @@ L.TileLayer = L.GridLayer.extend({
tile.onload = L.bind(this._tileOnLoad, this, done, tile); tile.onload = L.bind(this._tileOnLoad, this, done, tile);
tile.onerror = L.bind(this._tileOnError, this, done, tile); tile.onerror = L.bind(this._tileOnError, this, done, tile);
if (this.options.crossOrigin) {
tile.crossOrigin = '';
}
/* /*
Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
http://www.w3.org/TR/WCAG20-TECHS/H67 http://www.w3.org/TR/WCAG20-TECHS/H67
@ -138,11 +143,11 @@ L.TileLayer = L.GridLayer.extend({
for (i in this._tiles) { for (i in this._tiles) {
tile = this._tiles[i]; tile = this._tiles[i];
if (!tile.complete) {
tile.onload = L.Util.falseFn; tile.onload = L.Util.falseFn;
tile.onerror = L.Util.falseFn; tile.onerror = L.Util.falseFn;
tile.src = L.Util.emptyImageUrl;
if (!tile.complete) {
tile.src = L.Util.emptyImageUrl;
L.DomUtil.remove(tile); L.DomUtil.remove(tile);
} }
} }

View File

@ -207,12 +207,12 @@ L.Canvas = L.Renderer.extend({
}, },
_handleHover: function (layer, e, point) { _handleHover: function (layer, e, point) {
if (!layer.options.clickable) { return; } if (!layer.options.interactive) { return; }
if (layer._containsPoint(point)) { if (layer._containsPoint(point)) {
// if we just got inside the layer, fire mouseover // if we just got inside the layer, fire mouseover
if (!layer._mouseInside) { if (!layer._mouseInside) {
L.DomUtil.addClass(this._container, 'leaflet-clickable'); // change cursor L.DomUtil.addClass(this._container, 'leaflet-interactive'); // change cursor
layer._fireMouseEvent(e, 'mouseover'); layer._fireMouseEvent(e, 'mouseover');
layer._mouseInside = true; layer._mouseInside = true;
} }
@ -221,7 +221,7 @@ L.Canvas = L.Renderer.extend({
} else if (layer._mouseInside) { } else if (layer._mouseInside) {
// if we're leaving the layer, fire mouseout // if we're leaving the layer, fire mouseout
L.DomUtil.removeClass(this._container, 'leaflet-clickable'); L.DomUtil.removeClass(this._container, 'leaflet-interactive');
layer._fireMouseEvent(e, 'mouseout'); layer._fireMouseEvent(e, 'mouseout');
layer._mouseInside = false; layer._mouseInside = false;
} }

View File

@ -19,7 +19,7 @@ L.Path = L.Layer.extend({
fillOpacity: 0.2, fillOpacity: 0.2,
// className: '' // className: ''
clickable: true interactive: true
}, },
onAdd: function () { onAdd: function () {

View File

@ -106,7 +106,7 @@ L.SVG.include(!L.Browser.vml ? {} : {
}, },
_updateCircle: function (layer) { _updateCircle: function (layer) {
var p = layer._point, var p = layer._point.round(),
r = Math.round(layer._radius), r = Math.round(layer._radius),
r2 = Math.round(layer._radiusY || r); r2 = Math.round(layer._radiusY || r);

View File

@ -31,9 +31,15 @@ L.SVG = L.Renderer.extend({
L.DomUtil.setPosition(container, b.min); L.DomUtil.setPosition(container, b.min);
// update container viewBox so that we don't have to change coordinates of individual layers // set size of svg-container if changed
if (!this._svgSize || !this._svgSize.equals(size)) {
this._svgSize = size;
container.setAttribute('width', size.x); container.setAttribute('width', size.x);
container.setAttribute('height', size.y); container.setAttribute('height', size.y);
}
// movement: update container viewBox so that we don't have to change coordinates of individual layers
L.DomUtil.setPosition(container, b.min);
container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' ')); container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' '));
if (L.Browser.mobileWebkit) { if (L.Browser.mobileWebkit) {
@ -50,8 +56,8 @@ L.SVG = L.Renderer.extend({
L.DomUtil.addClass(path, layer.options.className); L.DomUtil.addClass(path, layer.options.className);
} }
if (layer.options.clickable) { if (layer.options.interactive) {
L.DomUtil.addClass(path, 'leaflet-clickable'); L.DomUtil.addClass(path, 'leaflet-interactive');
} }
this._updateStyle(layer); this._updateStyle(layer);
@ -110,7 +116,7 @@ L.SVG = L.Renderer.extend({
path.setAttribute('fill', 'none'); path.setAttribute('fill', 'none');
} }
path.setAttribute('pointer-events', options.pointerEvents || (options.clickable ? 'visiblePainted' : 'none')); path.setAttribute('pointer-events', options.pointerEvents || (options.interactive ? 'visiblePainted' : 'none'));
}, },
_updatePoly: function (layer, closed) { _updatePoly: function (layer, closed) {
@ -152,7 +158,10 @@ L.SVG = L.Renderer.extend({
}, },
_fireMouseEvent: function (e) { _fireMouseEvent: function (e) {
this._paths[L.stamp(e.target || e.srcElement)]._fireMouseEvent(e); var path = this._paths[L.stamp(e.target || e.srcElement)];
if (path) {
path._fireMouseEvent(e);
}
} }
}); });

View File

@ -33,6 +33,10 @@ L.Map = L.Evented.extend({
this.setMaxBounds(options.maxBounds); this.setMaxBounds(options.maxBounds);
} }
if (options.zoom !== undefined) {
this._zoom = this._limitZoom(options.zoom);
}
if (options.center && options.zoom !== undefined) { if (options.center && options.zoom !== undefined) {
this.setView(L.latLng(options.center), options.zoom, {reset: true}); this.setView(L.latLng(options.center), options.zoom, {reset: true});
} }
@ -566,9 +570,9 @@ L.Map = L.Evented.extend({
type = type || e.type; type = type || e.type;
if (L.DomEvent._skipped(e)) { return; } if (L.DomEvent._skipped(e)) { return; }
if (type === 'click') { if (type === 'click') {
if (!e._simulated && ((this.dragging && this.dragging.moved()) || var draggableObj = obj.options.draggable === true ? obj : this;
if (!e._simulated && ((draggableObj.dragging && draggableObj.dragging.moved()) ||
(this.boxZoom && this.boxZoom.moved()))) { return; } (this.boxZoom && this.boxZoom.moved()))) { return; }
obj.fire('preclick'); obj.fire('preclick');
} }

View File

@ -46,6 +46,11 @@ L.Map.include({
if (!offset.x && !offset.y) { if (!offset.x && !offset.y) {
return this; return this;
} }
//If we pan too far then chrome gets issues with tiles
// and makes them disappear or appear in the wrong place (slightly offset) #2602
if (options.animate !== true && !this.getSize().contains(offset)) {
return this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom());
}
if (!this._panAnim) { if (!this._panAnim) {
this._panAnim = new L.PosAnimation(); this._panAnim = new L.PosAnimation();

View File

@ -27,16 +27,17 @@ L.Map.BoxZoom = L.Handler.extend({
}, },
_onMouseDown: function (e) { _onMouseDown: function (e) {
this._moved = false;
if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; } if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
this._moved = false;
L.DomUtil.disableTextSelection(); L.DomUtil.disableTextSelection();
L.DomUtil.disableImageDrag(); L.DomUtil.disableImageDrag();
this._startPoint = this._map.mouseEventToContainerPoint(e); this._startPoint = this._map.mouseEventToContainerPoint(e);
L.DomEvent.on(document, { L.DomEvent.on(document, {
contextmenu: L.DomEvent.stop,
mousemove: this._onMouseMove, mousemove: this._onMouseMove,
mouseup: this._onMouseUp, mouseup: this._onMouseUp,
keydown: this._onKeyDown keydown: this._onKeyDown
@ -74,13 +75,15 @@ L.Map.BoxZoom = L.Handler.extend({
L.DomUtil.enableImageDrag(); L.DomUtil.enableImageDrag();
L.DomEvent.off(document, { L.DomEvent.off(document, {
contextmenu: L.DomEvent.stop,
mousemove: this._onMouseMove, mousemove: this._onMouseMove,
mouseup: this._onMouseUp, mouseup: this._onMouseUp,
keydown: this._onKeyDown keydown: this._onKeyDown
}, this); }, this);
}, },
_onMouseUp: function () { _onMouseUp: function (e) {
if ((e.which !== 1) && (e.button !== 1)) { return false; }
this._finish(); this._finish();

View File

@ -3,7 +3,8 @@
*/ */
L.Map.mergeOptions({ L.Map.mergeOptions({
scrollWheelZoom: true scrollWheelZoom: true,
wheelDebounceTime: 40
}); });
L.Map.ScrollWheelZoom = L.Handler.extend({ L.Map.ScrollWheelZoom = L.Handler.extend({
@ -25,6 +26,7 @@ L.Map.ScrollWheelZoom = L.Handler.extend({
_onWheelScroll: function (e) { _onWheelScroll: function (e) {
var delta = L.DomEvent.getWheelDelta(e); var delta = L.DomEvent.getWheelDelta(e);
var debounce = this._map.options.wheelDebounceTime;
this._delta += delta; this._delta += delta;
this._lastMousePos = this._map.mouseEventToContainerPoint(e); this._lastMousePos = this._map.mouseEventToContainerPoint(e);
@ -33,7 +35,7 @@ L.Map.ScrollWheelZoom = L.Handler.extend({
this._startTime = +new Date(); this._startTime = +new Date();
} }
var left = Math.max(40 - (+new Date() - this._startTime), 0); var left = Math.max(debounce - (+new Date() - this._startTime), 0);
clearTimeout(this._timer); clearTimeout(this._timer);
this._timer = setTimeout(L.bind(this._performZoom, this), left); this._timer = setTimeout(L.bind(this._performZoom, this), left);

View File

@ -54,9 +54,11 @@ L.Map.TouchZoom = L.Handler.extend({
this._scale = p1.distanceTo(p2) / this._startDist; this._scale = p1.distanceTo(p2) / this._startDist;
this._delta = p1._add(p2)._divideBy(2)._subtract(this._startCenter); this._delta = p1._add(p2)._divideBy(2)._subtract(this._startCenter);
if (!map.options.bounceAtZoomLimits && if (!map.options.bounceAtZoomLimits) {
((map.getZoom() === map.getMinZoom() && this._scale < 1) || var currentZoom = map.getScaleZoom(this._scale);
(map.getZoom() === map.getMaxZoom() && this._scale > 1))) { return; } if ((currentZoom <= map.getMinZoom() && this._scale < 1) ||
(currentZoom >= map.getMaxZoom() && this._scale > 1)) { return; }
}
if (!this._moved) { if (!this._moved) {
map map