Merge branch 'oldie-fixes' of http://github.com/danzel/Leaflet into oldie-fixes
This commit is contained in:
commit
eea61a6a56
36
CHANGELOG.md
36
CHANGELOG.md
@ -7,12 +7,21 @@ Leaflet Changelog
|
||||
|
||||
An in-progress version being developed on the master branch.
|
||||
|
||||
### Breaking changes
|
||||
|
||||
* Moved polyline editing code into [Leaflet.draw](https://github.com/Leaflet/Leaflet.draw) plugin (where it fits much better along with all other editing and drawing handlers). The API remains the same.
|
||||
|
||||
### Improvements
|
||||
|
||||
#### Usability and performance improvements
|
||||
|
||||
* **Improved zoom control design** once more - cleaner, simpler, more accessible (mostly by [@jacobtoye](https://github.com/jacobtoye)). [#1313](https://github.com/Leaflet/Leaflet/issues/1313)
|
||||
* Improved `TileLayer` zoom animation to eliminate flickering in case one tile layer on top of another or when zooming several times quickly. [#1140](https://github.com/Leaflet/Leaflet/issues/1140) [#1437](https://github.com/Leaflet/Leaflet/issues/1437) [#52](https://github.com/Leaflet/Leaflet/issues/52)
|
||||
* Significantly improved mass layer removal performance (by [@jfgirard](https://github.com/jfgirard)). [#1141](https://github.com/Leaflet/Leaflet/pull/1141)
|
||||
* Improved paths with `clickable: false` to allow mouse events to pass through to objects underneath (by [@snkashis](https://github.com/snkashis)). [#1384](https://github.com/Leaflet/Leaflet/pull/1384) [#1281](https://github.com/Leaflet/Leaflet/issues/1281)
|
||||
* Improved attribution control to be much less obtrusive (no "powered by", just a Leaflet link). You can still remove the prefix with `map.attributionControl.setPrefix('')` if you need.
|
||||
* Improved zoom behavior so that there's no drift of coordinates when you change zoom back and forth without panning. [#426](https://github.com/Leaflet/Leaflet/issues/426)
|
||||
* Improved box zoom to be cancelable by pressing Escape (by [@yohanboniface](https://github.com/yohanboniface)). [#1438](https://github.com/Leaflet/Leaflet/issues/1438)
|
||||
|
||||
#### API improvements
|
||||
|
||||
@ -24,6 +33,13 @@ An in-progress version being developed on the master branch.
|
||||
* Added `Path` `pointerEvents` option for setting pointer-events on SVG-powered vector layers (by [@inpursuit](https://github.com/inpursuit)). [#1053](https://github.com/Leaflet/Leaflet/pull/1053)
|
||||
* Added `LatLngBounds` `getNorth`, `getEast`, `getSouth`, `getWest` methods (by [@yohanboniface](https://github.com/yohanboniface)). [#1318](https://github.com/Leaflet/Leaflet/issues/1318)
|
||||
* Updated `TileLayer.Canvas` `redraw` method to return `this` (by [@jieter](https://github.com/jieter)). [#1287](https://github.com/Leaflet/Leaflet/pull/1287)
|
||||
* Improved `Marker` and `Path` `bindPopup` method to also accept `Popup` objects (by [@snkashis](https://github.com/snkashis)). [#1385](https://github.com/Leaflet/Leaflet/pull/1385) [#1208](https://github.com/Leaflet/Leaflet/issues/1208) [#1402](https://github.com/Leaflet/Leaflet/pull/1402)
|
||||
* Added `Map` `zoomlevelschange` event that triggers when the current zoom range (min/max) changes (by [@moonlite](https://github.com/moonlite)). [#1376](https://github.com/Leaflet/Leaflet/pull/1376)
|
||||
* Added `Marker` `setPopupContent` method (by [@snkashis](https://github.com/snkashis)). [#1373](https://github.com/Leaflet/Leaflet/pull/1373)
|
||||
* Added `Control` `getContainer` method. [#1409](https://github.com/Leaflet/Leaflet/issues/1409)
|
||||
* Added ability to pass coordinates as simple objects (`{lat: 50, lon: 30}` or `{lat: 50, lng: 30}`). [#1412](https://github.com/Leaflet/Leaflet/issues/1412)
|
||||
* Added `Map` `remove` method to properly destroy the map and clean up all events (by [@jfirebaugh](https://github.com/jfirebaugh)). [#1434](https://github.com/Leaflet/Leaflet/issues/1434) [#1101](https://github.com/Leaflet/Leaflet/issues/1101)
|
||||
* Added `TileLayer` `getContainer` method (by [@tmcw](https://github.com/tmcw)). [#1433](https://github.com/Leaflet/Leaflet/pull/1433)
|
||||
|
||||
#### Development workflow improvements
|
||||
|
||||
@ -32,15 +48,33 @@ An in-progress version being developed on the master branch.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
#### General bugfixes
|
||||
|
||||
* Fixed a bug where clicking on a marker with an open popup caused the popup to faded in again (by [@snkashis](https://github.com/snkashis)). [#506](https://github.com/Leaflet/Leaflet/issues/560) [#1386](https://github.com/Leaflet/Leaflet/pull/1386)
|
||||
* Fixed a bug where zoom buttons disabled state didn't update on min/max zoom change (by [@snkashis](https://github.com/snkashis)). [#1372](https://github.com/Leaflet/Leaflet/pull/1372) [#1328](https://github.com/Leaflet/Leaflet/issues/1328)
|
||||
|
||||
#### Browser bugfixes
|
||||
|
||||
* Fixed a bug in Android WebView where click was triggered twice on one tap (by [@jerel](https://github.com/jerel)). [#1227](https://github.com/Leaflet/Leaflet/pull/1227) [#1263](https://github.com/Leaflet/Leaflet/issues/1263)
|
||||
* Fixed a bug where `TileLayer` opacity didn't work in IE 7-8 (by [@javisantana](https://github.com/javisantana) & [@danzel](https://gi
|
||||
.com/danzel)). [#1084](https://github.com/Leaflet/Leaflet/issues/1084) [#1396](https://github.com/Leaflet/Leaflet/pull/1396) [#1371](https://github.com/Leaflet/Leaflet/issues/1371)
|
||||
* Fixed a bug in Android WebView where click was triggered twice on one tap (by [@jerel](https://github.com/jerel)). [#1227](https://github.com/Leaflet/Leaflet/pull/1227) [#1263](https://github.com/Leaflet/Leaflet/issues/1263)
|
||||
* Fixed a bug where mouse coordinates where shifted in Firefox if the map was inside a positioned block on a scrolled page (by [@joschka](https://github.com/joschka)). [#1365](https://github.com/Leaflet/Leaflet/pull/1365) [#1322](https://github.com/Leaflet/Leaflet/issues/1322)
|
||||
* Fixed a bug where box zoom didn't work in some cases in Firefox 18+ (by [@fabriceds](https://github.com/fabriceds)). [#1405](https://github.com/Leaflet/Leaflet/pull/1405)
|
||||
* Fixed a bug where tile layer z-index order sometimes broke after view reset. [#1422](https://github.com/Leaflet/Leaflet/issues/1422)
|
||||
|
||||
#### API bugfixes
|
||||
|
||||
* Fixed a bug where default marker icon path wasn't properly detected in some cases in IE6-7 (by [@calvinmetcalf](https://github.com/calvinmetcalf)). [#1294](https://github.com/Leaflet/Leaflet/pull/1294)
|
||||
* Fixed a bug where `Map` `hasLayer` wasn't handling `null` objects (by [@rvlasveld](https://github.com/rvlasveld)). [#1282](https://github.com/Leaflet/Leaflet/issues/1282) [#1302](https://github.com/Leaflet/Leaflet/pull/1302)
|
||||
* Fixed a bug where `TileLayer.WMS` param values weren't escaped in URLs (by [@yohanboniface](https://github.com/yohanboniface)). [#1317](https://github.com/Leaflet/Leaflet/issues/1317)
|
||||
* Fixed a bug where `Map` `moveend` fired before `dragend` on drag (by [@oslek](https://github.com/oslek)). [#1374](https://github.com/Leaflet/Leaflet/pull/1374)
|
||||
* Fixed a bug where panning with inertia produced an excessive `Map` `movestart` event on inertia start (by [@oslek](https://github.com/oslek)). [#1374](https://github.com/Leaflet/Leaflet/pull/1374)
|
||||
* Fixed a bug where `Map` `moveend` fired repeatedly on window resize even if the actual map size didn't change (by [@oslek](https://github.com/oslek)). [#1374](https://github.com/Leaflet/Leaflet/pull/1374)
|
||||
* Fixed a bug where `L.point` and `L.latLng` factories weren't passing `null` and `undefined` values through.
|
||||
* Fixed a bug where layers that belong to multiple feature groups didn't propagate events correctly (by [@danzel](https://github.com/danzel)). [#1359](https://github.com/Leaflet/Leaflet/pull/1359)
|
||||
* Fixed a bug where `Control.Attribution` `removeAttribution` of inexistant attribution corrupted the attribution text. [#1410](https://github.com/Leaflet/Leaflet/issues/1410)
|
||||
* Fixed a bug where `TileLayer.WMS` `tileSize` option was ignored (by [@brianhatchl](https://github.com/brianhatchl)). [#1080](https://github.com/brianhatchl)
|
||||
* Fixed a bug where `Polyline` constructor could overwrite the source array (by [@snkashis](https://github.com/snkashis) and [@danzel](https://github.com/danzel)). [#1439](https://github.com/Leaflet/Leaflet/pull/1439) [#1092](https://github.com/Leaflet/Leaflet/issues/1092) [#1246](https://github.com/Leaflet/Leaflet/issues/1246) [#1426](https://github.com/Leaflet/Leaflet/issues/1426)
|
||||
|
||||
## 0.5.1 (February 6, 2013)
|
||||
|
||||
|
@ -86,6 +86,8 @@ Before commiting your changes, run `jake lint` to catch any JS errors in the cod
|
||||
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.
|
||||
|
||||
Also, please make sure that you have [line endings configured properly](https://help.github.com/articles/dealing-with-line-endings) in Git! Otherwise the diff will show that all lines of a file were changed even if you touched only one.
|
||||
|
||||
Happy coding!
|
||||
|
||||
## Improving Documentation
|
||||
|
@ -22,7 +22,6 @@ var deps = {
|
||||
desc: 'The core of the library, including OOP, events, DOM facilities, basic units, projections (EPSG:3857 and EPSG:4326) and the base Map class.'
|
||||
},
|
||||
|
||||
|
||||
EPSG3395: {
|
||||
src: ['geo/projection/Projection.Mercator.js',
|
||||
'geo/crs/CRS.EPSG3395.js'],
|
||||
@ -85,7 +84,6 @@ var deps = {
|
||||
desc: 'Extends LayerGroup with mouse events and bindPopup method shared between layers.'
|
||||
},
|
||||
|
||||
|
||||
Path: {
|
||||
src: ['layer/vector/Path.js',
|
||||
'layer/vector/Path.SVG.js',
|
||||
@ -201,13 +199,6 @@ var deps = {
|
||||
desc: 'Makes markers draggable (by mouse or touch).'
|
||||
},
|
||||
|
||||
PolyEdit: {
|
||||
src: ['layer/vector/Polyline.Edit.js'],
|
||||
deps: ['Polyline', 'DivIcon'],
|
||||
desc: 'Polyline and polygon editing.'
|
||||
},
|
||||
|
||||
|
||||
ControlZoom: {
|
||||
src: ['control/Control.js',
|
||||
'map/ext/Map.Control.js',
|
||||
@ -237,7 +228,6 @@ var deps = {
|
||||
desc: 'Layer Switcher control.'
|
||||
},
|
||||
|
||||
|
||||
AnimationPan: {
|
||||
src: [
|
||||
'dom/DomEvent.js',
|
||||
@ -255,7 +245,7 @@ var deps = {
|
||||
},
|
||||
|
||||
AnimationZoom: {
|
||||
src: ['map/anim/Map.ZoomAnimation.js'],
|
||||
src: ['map/anim/Map.ZoomAnimation.js', 'layer/tile/TileLayer.Anim.js'],
|
||||
deps: ['AnimationPan'],
|
||||
desc: 'Smooth zooming animation. Works only on browsers that support CSS3 Transitions.'
|
||||
},
|
||||
|
@ -14,11 +14,16 @@
|
||||
<script>
|
||||
L_PREFER_CANVAS = true;
|
||||
$(document).ready(function() {
|
||||
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
|
||||
cloudmadeAttribution = 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade',
|
||||
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution});
|
||||
|
||||
var map = L.map('map', {
|
||||
minZoom: 1,
|
||||
maxZoom: 19,
|
||||
center: [51.505, -0.09],
|
||||
zoom: 9
|
||||
zoom: 9,
|
||||
layers: [cloudmade]
|
||||
});
|
||||
|
||||
var polygons = new L.FeatureGroup();
|
||||
@ -27,10 +32,11 @@
|
||||
polygons.addLayer(
|
||||
new L.Polyline(
|
||||
points, {
|
||||
weight: 2,
|
||||
weight: 10,
|
||||
opacity: 1,
|
||||
smoothFactor: 1,
|
||||
color: 'red'
|
||||
color: 'red',
|
||||
clickable:true
|
||||
}));
|
||||
|
||||
polygons.on('click', function(m) {
|
||||
@ -43,6 +49,8 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/javascript" src="../../build/deps.js"></script>
|
||||
<script src="../leaflet-include.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
29
debug/tests/remove_while_dragging.html
Normal file
29
debug/tests/remove_while_dragging.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet debug page</title>
|
||||
|
||||
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
|
||||
|
||||
<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" style="width: 600px; height: 600px; border: 1px solid #ccc"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map = L.map('map').setView( [50, 50], 10);
|
||||
var marker = L.marker([50, 50], {draggable: true}).addTo(map);
|
||||
|
||||
setTimeout(function() {
|
||||
map.removeLayer(marker);
|
||||
}, 3000);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
41
debug/tests/reuse_popups.html
Normal file
41
debug/tests/reuse_popups.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet debug page</title>
|
||||
|
||||
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
|
||||
|
||||
<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" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
|
||||
|
||||
<script>
|
||||
var map = L.map('map');
|
||||
|
||||
var marker = L.marker([51.5, -0.09])
|
||||
.bindPopup("<b>Hello world!</b><br />I am a popup.")
|
||||
.addTo(map);
|
||||
//.openPopup();
|
||||
|
||||
var marker2 = L.marker([51.525, -0.09])
|
||||
.addTo(map);
|
||||
|
||||
map.setView([51.505, -0.09], 13);
|
||||
|
||||
var cloudmade = L.tileLayer('http://{s}.tile.cloudmade.com/{key}/{styleId}/256/{z}/{x}/{y}.png', {
|
||||
attribution: 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade',
|
||||
maxZoom: 18,
|
||||
key: 'BC9A493B41014CAABB98F0471D759707',
|
||||
styleId: 997
|
||||
}).addTo(map);
|
||||
|
||||
var a_popup = L.popup().setContent('Previously created')
|
||||
|
||||
marker2.bindPopup(a_popup);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
55
debug/tests/svg_clicks.html
Normal file
55
debug/tests/svg_clicks.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet debug page</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
|
||||
|
||||
<link rel="stylesheet" href="../css/screen.css" />
|
||||
<script type="text/javascript" src="../../build/deps.js"></script>
|
||||
<script src="../leaflet-include.js"></script>
|
||||
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.0.js'></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map;
|
||||
var myLayerGroup = new L.LayerGroup();
|
||||
|
||||
initmap();
|
||||
|
||||
function initmap() {
|
||||
// set up the map
|
||||
map = new L.Map('map');
|
||||
|
||||
// create the tile layer with correct attribution
|
||||
var osmUrl = 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osm = new L.TileLayer(osmUrl, { minZoom: 1, maxZoom: 17 });
|
||||
map.addLayer(osm);
|
||||
map.fitBounds(new L.LatLngBounds([51,7],[51,7]));
|
||||
|
||||
var route = L.polyline([
|
||||
[51, 7.000],
|
||||
[51.002, 7.004],
|
||||
[51.004, 7.006]
|
||||
]).addTo(map).on('click',function(e){console.log('bottom')})
|
||||
|
||||
var route2 = L.polyline([
|
||||
[51, 7.000],
|
||||
[51.002, 7.004]
|
||||
],
|
||||
{ clickable:false,color:'#f00' }
|
||||
).addTo(map);
|
||||
|
||||
// when the mouse hovers over the red route2, you cannot click through the blue route1 beneath
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,53 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet debug page</title>
|
||||
|
||||
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="../../dist/leaflet.ie.css" /><![endif]-->
|
||||
|
||||
<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" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
|
||||
|
||||
<script src="route.js"></script>
|
||||
<script>
|
||||
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
|
||||
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18}),
|
||||
map = new L.Map('map', {layers: [cloudmade], center: new L.LatLng(51.505, -0.04), zoom: 13});
|
||||
|
||||
|
||||
var polygon = new L.Polygon([
|
||||
[51.51, -0.1],
|
||||
[51.5, -0.06],
|
||||
[51.52, -0.03]
|
||||
]);
|
||||
|
||||
polygon.editing.enable();
|
||||
|
||||
map.addLayer(polygon);
|
||||
|
||||
var polyline = new L.Polyline([
|
||||
[51.50, -0.04],
|
||||
[51.49, -0.02],
|
||||
[51.51, 0],
|
||||
[51.52, -0.02]
|
||||
]);
|
||||
|
||||
polyline.editing.enable();
|
||||
|
||||
map.addLayer(polyline);
|
||||
|
||||
polygon.on('edit', function() {
|
||||
console.log('Polygon was edited!');
|
||||
});
|
||||
polyline.on('edit', function() {
|
||||
console.log('Polyline was edited!');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
898
dist/leaflet-src.js
vendored
898
dist/leaflet-src.js
vendored
File diff suppressed because it is too large
Load Diff
30
dist/leaflet.css
vendored
30
dist/leaflet.css
vendored
@ -5,6 +5,7 @@
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-pane,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-overlay-pane,
|
||||
.leaflet-shadow-pane,
|
||||
.leaflet-marker-pane,
|
||||
@ -27,6 +28,7 @@
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
@ -216,12 +218,16 @@
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
-webkit-border-radius: 4px 4px 0 0;
|
||||
border-radius: 4px 4px 0 0;
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
-webkit-border-radius: 0 0 4px 4px;
|
||||
border-radius: 0 0 4px 4px;
|
||||
-webkit-border-bottom-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
-webkit-border-bottom-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
@ -239,22 +245,22 @@
|
||||
height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
-webkit-border-radius: 7px 7px 0 0;
|
||||
border-radius: 7px 7px 0 0;
|
||||
-webkit-border-top-left-radius: 7px;
|
||||
border-top-left-radius: 7px;
|
||||
-webkit-border-top-right-radius: 7px;
|
||||
border-top-right-radius: 7px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
-webkit-border-radius: 0 0 7px 7px;
|
||||
border-radius: 0 0 7px 7px;
|
||||
-webkit-border-bottom-left-radius: 7px;
|
||||
border-bottom-left-radius: 7px;
|
||||
-webkit-border-bottom-right-radius: 7px;
|
||||
border-bottom-right-radius: 7px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-container .leaflet-control-zoom {
|
||||
margin-left: 13px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.leaflet-control-zoom-in {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
}
|
||||
|
8
dist/leaflet.js
vendored
8
dist/leaflet.js
vendored
File diff suppressed because one or more lines are too long
@ -2,12 +2,13 @@
|
||||
"name": "Leaflet",
|
||||
"version": "0.6.0",
|
||||
"description": "JavaScript library for mobile-friendly interactive maps",
|
||||
"dependencies": {
|
||||
"devDependencies": {
|
||||
"jshint": "~0.9.1",
|
||||
"testacular": "latest",
|
||||
"uglify-js": "~2.2.3",
|
||||
"jake": "latest"
|
||||
},
|
||||
"main": "dist/leaflet.js",
|
||||
"scripts": {
|
||||
"test": "node ./node_modules/jake/bin/cli test"
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
<script type="text/javascript" src="happen.js"></script>
|
||||
|
||||
<!-- source files -->
|
||||
<script type="text/javascript" src="context.js"></script>
|
||||
<script type="text/javascript" src="before.js"></script>
|
||||
<script type="text/javascript" src="../build/deps.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../debug/leaflet-include.js"></script>
|
||||
@ -22,6 +22,7 @@
|
||||
<!-- /control -->
|
||||
<script type="text/javascript" src="suites/control/Control.LayersSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/control/Control.ScaleSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/control/Control.AttributionSpec.js"></script>
|
||||
|
||||
<!-- /core -->
|
||||
<script type="text/javascript" src="suites/core/UtilSpec.js"></script>
|
||||
@ -32,6 +33,8 @@
|
||||
<script type="text/javascript" src="suites/geometry/PointSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/geometry/BoundsSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/geometry/TransformationSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/geometry/LineUtilSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/geometry/PolyUtilSpec.js"></script>
|
||||
|
||||
<!-- /geo -->
|
||||
<script type="text/javascript" src="suites/geo/LatLngSpec.js"></script>
|
||||
@ -44,11 +47,14 @@
|
||||
|
||||
<!-- /layer -->
|
||||
<script type="text/javascript" src="suites/layer/FeatureGroupSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/layer/LayerGroupSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/layer/TileLayerSpec.js"></script>
|
||||
|
||||
<!-- /layer/vector/ -->
|
||||
<script type="text/javascript" src="suites/layer/vector/CircleSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/layer/vector/CircleMarkerSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/layer/vector/PolygonSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/layer/vector/PolylineSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/layer/vector/PolylineGeometrySpec.js"></script>
|
||||
|
||||
<!-- /map -->
|
||||
|
@ -1,5 +1,5 @@
|
||||
describe('L#noConflict', function() {
|
||||
it('should restore the previous L value and return Leaflet namespace', function(){
|
||||
it('restores the previous L value and returns Leaflet namespace', function(){
|
||||
|
||||
expect(L.version).toBeDefined();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
function noSpecs() {
|
||||
xit('should have specs');
|
||||
xit('has no specs');
|
||||
}
|
||||
|
||||
if (!Array.prototype.map) {
|
||||
|
68
spec/suites/control/Control.AttributionSpec.js
Normal file
68
spec/suites/control/Control.AttributionSpec.js
Normal file
@ -0,0 +1,68 @@
|
||||
describe("Control.Attribution", function () {
|
||||
|
||||
var map, control, container;
|
||||
|
||||
beforeEach(function () {
|
||||
map = L.map(document.createElement('div'));
|
||||
control = new L.Control.Attribution({
|
||||
prefix: 'prefix'
|
||||
}).addTo(map);
|
||||
container = control.getContainer();
|
||||
});
|
||||
|
||||
it("contains just prefix if no attributions added", function () {
|
||||
expect(container.innerHTML).toEqual('prefix');
|
||||
});
|
||||
|
||||
describe('#addAttribution', function () {
|
||||
it('adds one attribution correctly', function () {
|
||||
control.addAttribution('foo');
|
||||
expect(container.innerHTML).toEqual('prefix | foo');
|
||||
});
|
||||
|
||||
it('adds no duplicate attributions', function () {
|
||||
control.addAttribution('foo');
|
||||
control.addAttribution('foo');
|
||||
expect(container.innerHTML).toEqual('prefix | foo');
|
||||
});
|
||||
|
||||
it('adds several attributions listed with comma', function () {
|
||||
control.addAttribution('foo');
|
||||
control.addAttribution('bar');
|
||||
expect(container.innerHTML).toEqual('prefix | foo, bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#removeAttribution', function () {
|
||||
it('removes attribution correctly', function () {
|
||||
control.addAttribution('foo');
|
||||
control.addAttribution('bar');
|
||||
control.removeAttribution('foo');
|
||||
expect(container.innerHTML).toEqual('prefix | bar');
|
||||
});
|
||||
it('does nothing if removing attribution that was not present', function () {
|
||||
control.addAttribution('foo');
|
||||
control.addAttribution('baz');
|
||||
control.removeAttribution('bar');
|
||||
control.removeAttribution('baz');
|
||||
control.removeAttribution('baz');
|
||||
control.removeAttribution('');
|
||||
expect(container.innerHTML).toEqual('prefix | foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#setPrefix', function () {
|
||||
it('changes prefix', function () {
|
||||
control.setPrefix('bla');
|
||||
expect(container.innerHTML).toEqual('bla');
|
||||
});
|
||||
});
|
||||
|
||||
describe('control.attribution factory', function () {
|
||||
it('creates Control.Attribution instance', function () {
|
||||
var options = {prefix: 'prefix'};
|
||||
expect(L.control.attribution(options)).toEqual(new L.Control.Attribution(options));
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -2,5 +2,5 @@ describe("Control.Scale", function () {
|
||||
it("can be added to an unloaded map", function () {
|
||||
var map = L.map(document.createElement('div'));
|
||||
new L.Control.Scale().addTo(map);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
@ -19,7 +19,7 @@ describe("Class", function() {
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a class with the given constructor & properties", function() {
|
||||
it("creates a class with the given constructor & properties", function() {
|
||||
var a = new Klass();
|
||||
|
||||
expect(constructor).toHaveBeenCalled();
|
||||
@ -30,7 +30,7 @@ describe("Class", function() {
|
||||
expect(method).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should inherit parent classes' constructor & properties", function() {
|
||||
it("inherits parent classes' constructor & properties", function() {
|
||||
var Klass2 = Klass.extend({baz: 2});
|
||||
|
||||
var b = new Klass2();
|
||||
@ -46,28 +46,28 @@ describe("Class", function() {
|
||||
expect(method).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should support static properties", function() {
|
||||
it("supports static properties", function() {
|
||||
expect(Klass.bla).toEqual(1);
|
||||
});
|
||||
|
||||
it("should inherit parent static properties", function() {
|
||||
it("inherits parent static properties", function() {
|
||||
var Klass2 = Klass.extend({});
|
||||
|
||||
expect(Klass2.bla).toEqual(1);
|
||||
});
|
||||
|
||||
it("should override parent static properties", function() {
|
||||
it("overrides parent static properties", function() {
|
||||
var Klass2 = Klass.extend({statics: {bla: 2}});
|
||||
|
||||
expect(Klass2.bla).toEqual(2);
|
||||
});
|
||||
|
||||
it("should include the given mixin", function() {
|
||||
it("includes the given mixin", function() {
|
||||
var a = new Klass();
|
||||
expect(a.mixin).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should be able to include multiple mixins", function() {
|
||||
it("includes multiple mixins", function() {
|
||||
var Klass2 = L.Class.extend({
|
||||
includes: [{mixin: true}, {mixin2: true}]
|
||||
});
|
||||
@ -77,14 +77,14 @@ describe("Class", function() {
|
||||
expect(a.mixin2).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should grant the ability to include the given mixin", function() {
|
||||
it("grants the ability to include the given mixin", function() {
|
||||
Klass.include({mixin2: true});
|
||||
|
||||
var a = new Klass();
|
||||
expect(a.mixin2).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should merge options instead of replacing them", function() {
|
||||
it("merges options instead of replacing them", function() {
|
||||
var KlassWithOptions1 = L.Class.extend({
|
||||
options: {
|
||||
foo1: 1,
|
||||
@ -107,7 +107,7 @@ describe("Class", function() {
|
||||
});
|
||||
});
|
||||
|
||||
it("should add constructor hooks correctly", function () {
|
||||
it("adds constructor hooks correctly", function () {
|
||||
var spy1 = jasmine.createSpy("init hook 1");
|
||||
|
||||
Klass.addInitHook(spy1);
|
||||
@ -119,7 +119,7 @@ describe("Class", function() {
|
||||
expect(method).toHaveBeenCalledWith(1, 2, 3);
|
||||
});
|
||||
|
||||
it("should inherit constructor hooks", function () {
|
||||
it("inherits constructor hooks", function () {
|
||||
var spy1 = jasmine.createSpy("init hook 1"),
|
||||
spy2 = jasmine.createSpy("init hook 2");
|
||||
|
||||
@ -134,7 +134,7 @@ describe("Class", function() {
|
||||
expect(spy2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not call child constructor hooks", function () {
|
||||
it("does not call child constructor hooks", function () {
|
||||
var spy1 = jasmine.createSpy("init hook 1"),
|
||||
spy2 = jasmine.createSpy("init hook 2");
|
||||
|
||||
|
@ -9,7 +9,7 @@ describe('Events', function() {
|
||||
|
||||
describe('#fireEvent', function() {
|
||||
|
||||
it('should fire all listeners added through #addEventListener', function() {
|
||||
it('fires all listeners added through #addEventListener', function() {
|
||||
var obj = new Klass(),
|
||||
spy = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
@ -22,7 +22,7 @@ describe('Events', function() {
|
||||
obj.addEventListener('test', spy2);
|
||||
obj.addEventListener('other', spy3);
|
||||
obj.addEventListener({ test: spy4, other: spy5 });
|
||||
obj.addEventListener({'test other': spy6 })
|
||||
obj.addEventListener({'test other': spy6 });
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
expect(spy2).not.toHaveBeenCalled();
|
||||
@ -42,7 +42,7 @@ describe('Events', function() {
|
||||
expect(spy6.calls.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should provide event object to listeners and execute them in the right context', function() {
|
||||
it('provides event object to listeners and executes them in the right context', function() {
|
||||
var obj = new Klass(),
|
||||
obj2 = new Klass(),
|
||||
obj3 = new Klass(),
|
||||
@ -88,7 +88,7 @@ describe('Events', function() {
|
||||
obj4.fireEvent('test', {baz: 4});
|
||||
});
|
||||
|
||||
it('should not call listeners removed through #removeEventListener', function() {
|
||||
it('calls no listeners removed through #removeEventListener', function() {
|
||||
var obj = new Klass(),
|
||||
spy = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
@ -127,7 +127,7 @@ describe('Events', function() {
|
||||
});
|
||||
|
||||
// added due to context-sensitive removeListener optimization
|
||||
it('should fire multiple listeners with the same context with id properly', function () {
|
||||
it('fires multiple listeners with the same context with id', function () {
|
||||
var obj = new Klass(),
|
||||
spy = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
@ -144,7 +144,7 @@ describe('Events', function() {
|
||||
expect(spy2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should remove listeners with stamped contexts properly', function () {
|
||||
it('removes listeners with stamped contexts', function () {
|
||||
var obj = new Klass(),
|
||||
spy = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
@ -166,7 +166,7 @@ describe('Events', function() {
|
||||
|
||||
describe('#on, #off & #fire', function() {
|
||||
|
||||
it('should work like #addEventListener && #removeEventListener', function() {
|
||||
it('works like #addEventListener && #removeEventListener', function() {
|
||||
var obj = new Klass(),
|
||||
spy = jasmine.createSpy();
|
||||
|
||||
@ -181,7 +181,7 @@ describe('Events', function() {
|
||||
expect(spy.callCount).toBeLessThan(2);
|
||||
});
|
||||
|
||||
it('should not override existing methods with the same name', function() {
|
||||
it('does not override existing methods with the same name', function() {
|
||||
var spy1 = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
spy3 = jasmine.createSpy();
|
||||
|
@ -10,7 +10,7 @@ describe('Util', function() {
|
||||
};
|
||||
});
|
||||
|
||||
it('should extend the first argument with the properties of the second', function() {
|
||||
it('extends the first argument with the properties of the second', function() {
|
||||
L.Util.extend(a, {
|
||||
bar: 7,
|
||||
baz: 3
|
||||
@ -23,7 +23,7 @@ describe('Util', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with more than 2 arguments', function() {
|
||||
it('accepts more than 2 arguments', function() {
|
||||
L.Util.extend(a, {bar: 7}, {baz: 3});
|
||||
|
||||
expect(a).toEqual({
|
||||
@ -35,7 +35,7 @@ describe('Util', function() {
|
||||
});
|
||||
|
||||
describe('#bind', function() {
|
||||
it('should return the given function with the given context', function() {
|
||||
it('returns the given function with the given context', function() {
|
||||
var fn = function() {
|
||||
return this;
|
||||
};
|
||||
@ -45,7 +45,7 @@ describe('Util', function() {
|
||||
expect(fn2()).toEqual(5);
|
||||
});
|
||||
|
||||
it('should pass additional arguments to the bound function', function () {
|
||||
it('passes additional arguments to the bound function', function () {
|
||||
var fn = jasmine.createSpy(),
|
||||
foo = {},
|
||||
a = {},
|
||||
@ -60,7 +60,7 @@ describe('Util', function() {
|
||||
});
|
||||
|
||||
describe('#stamp', function() {
|
||||
it('should set a unique id on the given object and return it', function() {
|
||||
it('sets a unique id on the given object and returns it', function() {
|
||||
var a = {},
|
||||
id = L.Util.stamp(a);
|
||||
|
||||
@ -75,13 +75,13 @@ describe('Util', function() {
|
||||
});
|
||||
|
||||
describe('#falseFn', function () {
|
||||
it('should just return false', function () {
|
||||
it('returns false', function () {
|
||||
expect(L.Util.falseFn()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#formatNum', function () {
|
||||
it('should format numbers with a given precision', function () {
|
||||
it('formats numbers with a given precision', function () {
|
||||
expect(L.Util.formatNum(13.12325555, 3)).toEqual(13.123);
|
||||
expect(L.Util.formatNum(13.12325555)).toEqual(13.12326);
|
||||
});
|
||||
@ -89,7 +89,7 @@ describe('Util', function() {
|
||||
|
||||
|
||||
describe('#getParamString', function() {
|
||||
it('should create a valid query string for appending depending on url input', function() {
|
||||
it('creates a valid query string for appending depending on url input', function() {
|
||||
var a = {
|
||||
url: "http://example.com/get",
|
||||
obj: {bar: 7, baz: 3},
|
||||
@ -117,7 +117,7 @@ describe('Util', function() {
|
||||
});
|
||||
|
||||
describe('#requestAnimFrame', function () {
|
||||
it('should call a function on next frame, unless canceled', function () {
|
||||
it('calles a function on next frame, unless canceled', function () {
|
||||
var spy = jasmine.createSpy(),
|
||||
spy2 = jasmine.createSpy(),
|
||||
called = false,
|
||||
@ -147,7 +147,7 @@ describe('Util', function() {
|
||||
});
|
||||
|
||||
describe('#limitExecByInterval', function() {
|
||||
it('should limit execution to not more often than specified time interval', function () {
|
||||
it('limits execution to not more often than specified time interval', function () {
|
||||
var spy = jasmine.createSpy(),
|
||||
check = false;
|
||||
|
||||
@ -176,15 +176,15 @@ describe('Util', function() {
|
||||
});
|
||||
|
||||
describe('#splitWords', function () {
|
||||
it('should split words into an array', function () {
|
||||
it('splits words into an array', function () {
|
||||
expect(L.Util.splitWords('foo bar baz')).toEqual(['foo', 'bar', 'baz']);
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
// TODO setOptions
|
||||
|
||||
describe('#template', function () {
|
||||
it('should evaluate templates with a given data object', function () {
|
||||
it('evaluates templates with a given data object', function () {
|
||||
var tpl = 'Hello {foo} and {bar}!';
|
||||
|
||||
var str = L.Util.template(tpl, {
|
||||
@ -193,7 +193,13 @@ describe('Util', function() {
|
||||
});
|
||||
|
||||
expect(str).toEqual('Hello Vlad and Dave!');
|
||||
});
|
||||
|
||||
it('does not modify text without a token variable', function () {
|
||||
expect(L.Util.template('foo', {})).toEqual('foo');
|
||||
});
|
||||
|
||||
it('throws when a template token is not given', function () {
|
||||
expect(function () {
|
||||
L.Util.template(tpl, {foo: 'bar'});
|
||||
}).toThrow();
|
||||
|
@ -24,7 +24,7 @@ describe('DomEvent', function() {
|
||||
});
|
||||
|
||||
describe('#addListener', function() {
|
||||
it('should add a listener and call it on event', function() {
|
||||
it('adds a listener and calls it on event', function() {
|
||||
var listener1 = jasmine.createSpy('listener1'),
|
||||
listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
@ -37,7 +37,7 @@ describe('DomEvent', function() {
|
||||
expect(listener2).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should have "this" keyword point to the given context', function() {
|
||||
it('binds "this" to the given context', function() {
|
||||
var obj = {foo: 'bar'},
|
||||
result;
|
||||
|
||||
@ -50,7 +50,7 @@ describe('DomEvent', function() {
|
||||
expect(result).toEqual(obj);
|
||||
});
|
||||
|
||||
it('should pass an event object to the listener', function() {
|
||||
it('passes an event object to the listener', function() {
|
||||
var type;
|
||||
|
||||
L.DomEvent.addListener(el, 'click', function(e) {
|
||||
@ -63,7 +63,7 @@ describe('DomEvent', function() {
|
||||
});
|
||||
|
||||
describe('#removeListener', function() {
|
||||
it('should remove previously added listener', function() {
|
||||
it('removes a previously added listener', function() {
|
||||
var listener = jasmine.createSpy('listener');
|
||||
|
||||
L.DomEvent.addListener(el, 'click', listener);
|
||||
@ -76,7 +76,7 @@ describe('DomEvent', function() {
|
||||
});
|
||||
|
||||
describe('#stopPropagation', function() {
|
||||
it('should stop propagation of the given event', function() {
|
||||
it('stops propagation of the given event', function() {
|
||||
var child = document.createElement('div'),
|
||||
listener = jasmine.createSpy('listener');
|
||||
|
||||
@ -93,7 +93,7 @@ describe('DomEvent', function() {
|
||||
});
|
||||
});
|
||||
describe('#preventDefault', function() {
|
||||
it('should prevent the default action of event', function() {
|
||||
it('prevents the default action of event', function() {
|
||||
L.DomEvent.addListener(el, 'click', L.DomEvent.preventDefault);
|
||||
|
||||
expect(simulateClick(el)).toBe(false);
|
||||
|
@ -13,18 +13,18 @@ describe('DomUtil', function() {
|
||||
});
|
||||
|
||||
describe('#get', function() {
|
||||
it('should get element by id if the given argument is string', function() {
|
||||
it('gets element by id if the given argument is string', function() {
|
||||
el.id = 'testId';
|
||||
expect(L.DomUtil.get(el.id)).toBe(el);
|
||||
});
|
||||
|
||||
it('should return the element if it is given as an argument', function() {
|
||||
it('returns the element if it is given as an argument', function() {
|
||||
expect(L.DomUtil.get(el)).toBe(el);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#addClass, #removeClass, #hasClass', function() {
|
||||
it('should has defined class for test element', function() {
|
||||
it('has defined class for test element', function() {
|
||||
el.className = 'bar foo baz ';
|
||||
expect(L.DomUtil.hasClass(el, 'foo')).toBeTruthy();
|
||||
expect(L.DomUtil.hasClass(el, 'bar')).toBeTruthy();
|
||||
@ -32,7 +32,7 @@ describe('DomUtil', function() {
|
||||
expect(L.DomUtil.hasClass(el, 'boo')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should properly addClass and removeClass for element', function() {
|
||||
it('adds or removes the class', function() {
|
||||
el.className = '';
|
||||
L.DomUtil.addClass(el, 'foo');
|
||||
|
||||
@ -50,17 +50,18 @@ describe('DomUtil', function() {
|
||||
el.className = 'foo bar barz';
|
||||
L.DomUtil.removeClass(el, 'bar');
|
||||
expect(el.className).toEqual('foo barz');
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('#documentIsLtr', function () {
|
||||
it('should return true if doc direction is ltr', function () {
|
||||
it('returns true if doc direction is ltr', function () {
|
||||
expect(L.DomUtil.documentIsLtr()).toBe(true);
|
||||
expect(L.DomUtil.documentIsLtr()).toBe(true); // cached
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getViewportOffset', function () {
|
||||
it('calculates the viewport offset of an element', function () {
|
||||
var div = document.createElement('div');
|
||||
div.style.position = 'absolute';
|
||||
div.style.top = '100px';
|
||||
@ -80,6 +81,7 @@ describe('DomUtil', function() {
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#setPosition', noSpecs);
|
||||
|
||||
|
@ -9,7 +9,7 @@ describe('LatLngBounds', function() {
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
it('should instantiate properly either passing two latlngs or an array of latlngs', function () {
|
||||
it('instantiates either passing two latlngs or an array of latlngs', function () {
|
||||
var b = new L.LatLngBounds([
|
||||
new L.LatLng(14, 12),
|
||||
new L.LatLng(30, 40)
|
||||
@ -20,12 +20,12 @@ describe('LatLngBounds', function() {
|
||||
});
|
||||
|
||||
describe('#extend', function () {
|
||||
it('should extend the bounds by a given point', function () {
|
||||
it('extends the bounds by a given point', function () {
|
||||
a.extend(new L.LatLng(20, 50));
|
||||
expect(a.getNorthEast()).toEqual(new L.LatLng(30, 50));
|
||||
});
|
||||
|
||||
it('should extend the bounds by given bounds', function () {
|
||||
it('extends the bounds by given bounds', function () {
|
||||
a.extend([[20, 50], [8, 40]]);
|
||||
|
||||
expect(a.getSouthEast()).toEqual(new L.LatLng(8, 50));
|
||||
@ -33,13 +33,13 @@ describe('LatLngBounds', function() {
|
||||
});
|
||||
|
||||
describe('#getCenter', function () {
|
||||
it('should return the bounds center', function () {
|
||||
it('returns the bounds center', function () {
|
||||
expect(a.getCenter()).toEqual(new L.LatLng(22, 26));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pad', function () {
|
||||
it('should pad the bounds by a given ratio', function () {
|
||||
it('pads the bounds by a given ratio', function () {
|
||||
var b = a.pad(0.5);
|
||||
|
||||
expect(b).toEqual(L.latLngBounds([[6, -2], [38, 54]]));
|
||||
@ -47,7 +47,7 @@ describe('LatLngBounds', function() {
|
||||
});
|
||||
|
||||
describe('#equals', function () {
|
||||
it('should return true if bounds equal', function () {
|
||||
it('returns true if bounds equal', function () {
|
||||
expect(a.equals([[14, 12], [30, 40]])).toBe(true);
|
||||
expect(a.equals([[14, 13], [30, 40]])).toBe(false);
|
||||
expect(a.equals(null)).toBe(false);
|
||||
@ -55,79 +55,79 @@ describe('LatLngBounds', function() {
|
||||
});
|
||||
|
||||
describe('#isValid', function() {
|
||||
it('should return true if properly set up', function() {
|
||||
it('returns true if properly set up', function() {
|
||||
expect(a.isValid()).toBeTruthy();
|
||||
});
|
||||
it('should return false if is invalid', function() {
|
||||
it('returns false if is invalid', function() {
|
||||
expect(c.isValid()).toBeFalsy();
|
||||
});
|
||||
it('should be valid if extended', function() {
|
||||
it('returns true if extended', function() {
|
||||
c.extend([0, 0]);
|
||||
expect(c.isValid()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getWest', function () {
|
||||
it('should return a proper bbox west value', function() {
|
||||
it('returns a proper bbox west value', function() {
|
||||
expect(a.getWest()).toEqual(12);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getSouth', function () {
|
||||
it('should return a proper bbox south value', function() {
|
||||
it('returns a proper bbox south value', function() {
|
||||
expect(a.getSouth()).toEqual(14);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getEast', function () {
|
||||
it('should return a proper bbox east value', function() {
|
||||
it('returns a proper bbox east value', function() {
|
||||
expect(a.getEast()).toEqual(40);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getNorth', function () {
|
||||
it('should return a proper bbox north value', function() {
|
||||
it('returns a proper bbox north value', function() {
|
||||
expect(a.getNorth()).toEqual(30);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#toBBoxString', function () {
|
||||
it('should return a proper left,bottom,right,top bbox', function() {
|
||||
it('returns a proper left,bottom,right,top bbox', function() {
|
||||
expect(a.toBBoxString()).toEqual("12,14,40,30");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getNorthWest', function () {
|
||||
it('should return a proper north-west LatLng', function() {
|
||||
it('returns a proper north-west LatLng', function() {
|
||||
expect(a.getNorthWest()).toEqual(new L.LatLng(a.getNorth(), a.getWest()));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getSouthEast', function () {
|
||||
it('should return a proper south-east LatLng', function() {
|
||||
it('returns a proper south-east LatLng', function() {
|
||||
expect(a.getSouthEast()).toEqual(new L.LatLng(a.getSouth(), a.getEast()));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#contains', function () {
|
||||
it('should return true if contains latlng point', function () {
|
||||
it('returns true if contains latlng point', function () {
|
||||
expect(a.contains([16, 20])).toBe(true);
|
||||
expect(L.latLngBounds(a).contains([5, 20])).toBe(false);
|
||||
});
|
||||
|
||||
it('should accept bounds', function () {
|
||||
it('returns true if contains bounds', function () {
|
||||
expect(a.contains([[16, 20], [20, 40]])).toBe(true);
|
||||
expect(a.contains([[16, 50], [8, 40]])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#intersects', function () {
|
||||
it('should return true if intersects the given bounds', function () {
|
||||
it('returns true if intersects the given bounds', function () {
|
||||
expect(a.intersects([[16, 20], [50, 60]])).toBe(true);
|
||||
expect(a.contains([[40, 50], [50, 60]])).toBe(false);
|
||||
});
|
||||
|
@ -1,16 +1,16 @@
|
||||
describe('LatLng', function() {
|
||||
describe('constructor', function() {
|
||||
it("should set lat and lng", function() {
|
||||
it("sets lat and lng", function() {
|
||||
var a = new L.LatLng(25, 74);
|
||||
expect(a.lat).toEqual(25);
|
||||
expect(a.lng).toEqual(74);
|
||||
|
||||
var a = new L.LatLng(-25, -74);
|
||||
expect(a.lat).toEqual(-25);
|
||||
expect(a.lng).toEqual(-74);
|
||||
var b = new L.LatLng(-25, -74);
|
||||
expect(b.lat).toEqual(-25);
|
||||
expect(b.lng).toEqual(-74);
|
||||
});
|
||||
|
||||
it('should throw error if invalid lat or lng', function () {
|
||||
it('throws an error if invalid lat or lng', function () {
|
||||
expect(function () {
|
||||
var a = new L.LatLng(NaN, NaN);
|
||||
}).toThrow();
|
||||
@ -18,26 +18,26 @@ describe('LatLng', function() {
|
||||
});
|
||||
|
||||
describe('#equals', function() {
|
||||
it("should return true if compared objects are equal within a certain margin", function() {
|
||||
it("returns true if compared objects are equal within a certain margin", function() {
|
||||
var a = new L.LatLng(10, 20);
|
||||
var b = new L.LatLng(10 + 1.0E-10, 20 - 1.0E-10);
|
||||
expect(a.equals(b)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if compared objects are not equal within a certain margin", function() {
|
||||
it("returns false if compared objects are not equal within a certain margin", function() {
|
||||
var a = new L.LatLng(10, 20);
|
||||
var b = new L.LatLng(10, 23.3);
|
||||
expect(a.equals(b)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if passed non-valid object', function () {
|
||||
it('returns false if passed non-valid object', function () {
|
||||
var a = new L.LatLng(10, 20);
|
||||
expect(a.equals(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#wrap', function () {
|
||||
it("#wrap should wrap longitude to lie between -180 and 180 by default", function() {
|
||||
it("wraps longitude to lie between -180 and 180 by default", function() {
|
||||
var a = new L.LatLng(0, 190).wrap().lng;
|
||||
expect(a).toEqual(-170);
|
||||
|
||||
@ -63,7 +63,7 @@ describe('LatLng', function() {
|
||||
expect(h).toEqual(180);
|
||||
});
|
||||
|
||||
it("#wrap should wrap longitude within the given range", function() {
|
||||
it("wraps longitude within the given range", function() {
|
||||
var a = new L.LatLng(0, 190).wrap(-100, 100).lng;
|
||||
expect(a).toEqual(-10);
|
||||
});
|
||||
@ -71,14 +71,14 @@ describe('LatLng', function() {
|
||||
});
|
||||
|
||||
describe('#toString', function () {
|
||||
it('should format to string', function () {
|
||||
it('formats a string', function () {
|
||||
var a = new L.LatLng(10.333333333, 20.2222222);
|
||||
expect(a.toString(3)).toEqual('LatLng(10.333, 20.222)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#distanceTo', function () {
|
||||
it('should calculate distance in meters', function () {
|
||||
it('calculates distance in meters', function () {
|
||||
var a = new L.LatLng(50.5, 30.5);
|
||||
var b = new L.LatLng(50, 1);
|
||||
|
||||
@ -87,24 +87,32 @@ describe('LatLng', function() {
|
||||
});
|
||||
|
||||
describe('L.latLng factory', function () {
|
||||
it('should return LatLng instance as is', function () {
|
||||
it('returns LatLng instance as is', function () {
|
||||
var a = new L.LatLng(50, 30);
|
||||
|
||||
expect(L.latLng(a)).toBe(a);
|
||||
});
|
||||
|
||||
it('should accept an array of coordinates', function () {
|
||||
it('accepts an array of coordinates', function () {
|
||||
expect(L.latLng([50, 30])).toEqual(new L.LatLng(50, 30));
|
||||
});
|
||||
|
||||
it('should pass null or undefined as is', function () {
|
||||
it('passes null or undefined as is', function () {
|
||||
expect(L.latLng(undefined)).toBe(undefined);
|
||||
expect(L.latLng(null)).toBe(null);
|
||||
});
|
||||
|
||||
it('should create a LatLng object from two coordinates', function () {
|
||||
it('creates a LatLng object from two coordinates', function () {
|
||||
expect(L.latLng(50, 30)).toEqual(new L.LatLng(50, 30));
|
||||
});
|
||||
|
||||
it('accepts an object with lat/lng', function () {
|
||||
expect(L.latLng({lat: 50, lng: 30})).toEqual(new L.LatLng(50, 30));
|
||||
});
|
||||
|
||||
it('accepts an object with lat/lon', function () {
|
||||
expect(L.latLng({lat: 50, lon: 30})).toEqual(new L.LatLng(50, 30));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -4,7 +4,7 @@ xdescribe("Projection.Mercator", function() {
|
||||
beforeEach(function() {
|
||||
function almostEqual(a, b, p) {
|
||||
return Math.abs(a - b) <= (p || 1.0E-12);
|
||||
};
|
||||
}
|
||||
this.addMatchers({
|
||||
toAlmostEqual: function(expected, margin) {
|
||||
var p1 = this.actual,
|
||||
@ -16,7 +16,7 @@ xdescribe("Projection.Mercator", function() {
|
||||
|
||||
|
||||
describe("#project", function() {
|
||||
it("should do projection properly", function() {
|
||||
it("projects", function() {
|
||||
//edge cases
|
||||
expect(p.project(new L.LatLng(0, 0))).toAlmostEqual(new L.Point(0, 0));
|
||||
expect(p.project(new L.LatLng(90, 180))).toAlmostEqual(new L.Point(-Math.PI, Math.PI));
|
||||
@ -27,7 +27,7 @@ xdescribe("Projection.Mercator", function() {
|
||||
});
|
||||
|
||||
describe("#unproject", function() {
|
||||
it("should do unprojection properly", function() {
|
||||
it("unprojects", function() {
|
||||
function pr(point) {
|
||||
return p.project(p.unproject(point));
|
||||
}
|
||||
|
@ -14,18 +14,18 @@ describe('Bounds', function() {
|
||||
});
|
||||
|
||||
describe('constructor', function() {
|
||||
it('should create bounds with proper min & max on (Point, Point)', function() {
|
||||
it('creates bounds with proper min & max on (Point, Point)', function() {
|
||||
expect(a.min).toEqual(new L.Point(14, 12));
|
||||
expect(a.max).toEqual(new L.Point(30, 40));
|
||||
});
|
||||
it('should create bounds with proper min & max on (Point[])', function() {
|
||||
it('creates bounds with proper min & max on (Point[])', function() {
|
||||
expect(b.min).toEqual(new L.Point(14, 12));
|
||||
expect(b.max).toEqual(new L.Point(30, 40));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#extend', function() {
|
||||
it('should extend the bounds to contain the given point', function() {
|
||||
it('extends the bounds to contain the given point', function() {
|
||||
a.extend(new L.Point(50, 20));
|
||||
expect(a.min).toEqual(new L.Point(14, 12));
|
||||
expect(a.max).toEqual(new L.Point(50, 40));
|
||||
@ -37,13 +37,13 @@ describe('Bounds', function() {
|
||||
});
|
||||
|
||||
describe('#getCenter', function() {
|
||||
it('should return the center point', function() {
|
||||
it('returns the center point', function() {
|
||||
expect(a.getCenter()).toEqual(new L.Point(22, 26));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#contains', function() {
|
||||
it('should contains other bounds or point', function() {
|
||||
it('contains other bounds or point', function() {
|
||||
a.extend(new L.Point(50, 10));
|
||||
expect(a.contains(b)).toBeTruthy();
|
||||
expect(b.contains(a)).toBeFalsy();
|
||||
@ -53,33 +53,33 @@ describe('Bounds', function() {
|
||||
});
|
||||
|
||||
describe('#isValid', function() {
|
||||
it('should return true if properly set up', function() {
|
||||
it('returns true if properly set up', function() {
|
||||
expect(a.isValid()).toBeTruthy();
|
||||
});
|
||||
it('should return false if is invalid', function() {
|
||||
it('returns false if is invalid', function() {
|
||||
expect(c.isValid()).toBeFalsy();
|
||||
});
|
||||
it('should be valid if extended', function() {
|
||||
it('returns true if extended', function() {
|
||||
c.extend([0, 0]);
|
||||
expect(c.isValid()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getSize', function () {
|
||||
it('should return the size of the bounds as point', function () {
|
||||
it('returns the size of the bounds as point', function () {
|
||||
expect(a.getSize()).toEqual(new L.Point(16, 28));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#intersects', function () {
|
||||
it('should return true if bounds intersect', function () {
|
||||
it('returns true if bounds intersect', function () {
|
||||
expect(a.intersects(b)).toBe(true);
|
||||
expect(a.intersects(new L.Bounds(new L.Point(100, 100), new L.Point(120, 120)))).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('L.bounds factory', function () {
|
||||
it('should create bounds from array of number arrays', function () {
|
||||
it('creates bounds from array of number arrays', function () {
|
||||
var bounds = L.bounds([[14, 12], [30, 40]]);
|
||||
expect(bounds).toEqual(a);
|
||||
});
|
||||
|
@ -8,7 +8,7 @@ describe('LineUtil', function () {
|
||||
bounds = L.bounds([5, 0], [15, 10]);
|
||||
});
|
||||
|
||||
it('should clip segment by bounds correctly', function () {
|
||||
it('clips a segment by bounds', function () {
|
||||
var a = new L.Point(0, 0);
|
||||
var b = new L.Point(15, 15);
|
||||
|
||||
@ -26,7 +26,7 @@ describe('LineUtil', function () {
|
||||
expect(segment2[1]).toEqual(new L.Point(15, 5));
|
||||
});
|
||||
|
||||
it('should use last bit code and reject segments out of bounds', function () {
|
||||
it('uses last bit code and reject segments out of bounds', function () {
|
||||
var a = new L.Point(15, 15);
|
||||
var b = new L.Point(25, 20);
|
||||
var segment = L.LineUtil.clipSegment(a, b, bounds, true);
|
||||
@ -41,17 +41,17 @@ describe('LineUtil', function () {
|
||||
var p2 = new L.Point(10, 0);
|
||||
var p = new L.Point(0, 0);
|
||||
|
||||
it('should calculate distance from point to segment', function () {
|
||||
it('calculates distance from point to segment', function () {
|
||||
expect(L.LineUtil.pointToSegmentDistance(p, p1, p2)).toEqual(Math.sqrt(200) / 2);
|
||||
});
|
||||
|
||||
it('should get point closest to segment', function () {
|
||||
it('calculates point closest to segment', function () {
|
||||
expect(L.LineUtil.closestPointOnSegment(p, p1, p2)).toEqual(new L.Point(5, 5));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#simplify', function () {
|
||||
it('should simplify polylines according to tolerance', function () {
|
||||
it('simplifies polylines according to tolerance', function () {
|
||||
var points = [
|
||||
new L.Point(0, 0),
|
||||
new L.Point(0.01, 0),
|
||||
|
@ -2,13 +2,13 @@ describe("Point", function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it("should create a point with the given x and y", function() {
|
||||
it("creates a point with the given x and y", function() {
|
||||
var p = new L.Point(1.5, 2.5);
|
||||
expect(p.x).toEqual(1.5);
|
||||
expect(p.y).toEqual(2.5);
|
||||
});
|
||||
|
||||
it("should round the given x and y if the third argument is true", function() {
|
||||
it("rounds the given x and y if the third argument is true", function() {
|
||||
var p = new L.Point(1.3, 2.7, true);
|
||||
expect(p.x).toEqual(1);
|
||||
expect(p.y).toEqual(3);
|
||||
@ -16,7 +16,7 @@ describe("Point", function() {
|
||||
});
|
||||
|
||||
describe('#subtract', function() {
|
||||
it('should subtract the given point from this one', function() {
|
||||
it('subtracts the given point from this one', function() {
|
||||
var a = new L.Point(50, 30),
|
||||
b = new L.Point(20, 10);
|
||||
expect(a.subtract(b)).toEqual(new L.Point(30, 20));
|
||||
@ -24,31 +24,31 @@ describe("Point", function() {
|
||||
});
|
||||
|
||||
describe('#add', function() {
|
||||
it('should add the given point to this one', function() {
|
||||
it('adds given point to this one', function() {
|
||||
expect(new L.Point(50, 30).add(new L.Point(20, 10))).toEqual(new L.Point(70, 40));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#divideBy', function() {
|
||||
it('should divide this point by the given amount', function() {
|
||||
it('divides this point by the given amount', function() {
|
||||
expect(new L.Point(50, 30).divideBy(5)).toEqual(new L.Point(10, 6));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#multiplyBy', function() {
|
||||
it('should multiply this point by the given amount', function() {
|
||||
it('multiplies this point by the given amount', function() {
|
||||
expect(new L.Point(50, 30).multiplyBy(2)).toEqual(new L.Point(100, 60));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#floor', function () {
|
||||
it('should return a new point with floored coordinates', function () {
|
||||
it('returns a new point with floored coordinates', function () {
|
||||
expect(new L.Point(50.56, 30.123).floor()).toEqual(new L.Point(50, 30));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#distanceTo', function () {
|
||||
it('should calculate distance between two points', function () {
|
||||
it('calculates distance between two points', function () {
|
||||
var p1 = new L.Point(0, 30);
|
||||
var p2 = new L.Point(40, 0);
|
||||
expect(p1.distanceTo(p2)).toEqual(50.0);
|
||||
@ -56,7 +56,7 @@ describe("Point", function() {
|
||||
});
|
||||
|
||||
describe('#equals', function () {
|
||||
it('should return true if points are equal', function () {
|
||||
it('returns true if points are equal', function () {
|
||||
var p1 = new L.Point(20.4, 50.12);
|
||||
var p2 = new L.Point(20.4, 50.12);
|
||||
var p3 = new L.Point(20.5, 50.13);
|
||||
@ -66,24 +66,37 @@ describe("Point", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#contains', function () {
|
||||
it('returns true if the point is bigger in absolute dimensions than the passed one', function () {
|
||||
var p1 = new L.Point(50, 30),
|
||||
p2 = new L.Point(-40, 20),
|
||||
p3 = new L.Point(60, -20),
|
||||
p4 = new L.Point(-40, -40);
|
||||
|
||||
expect(p1.contains(p2)).toBe(true);
|
||||
expect(p1.contains(p3)).toBe(false);
|
||||
expect(p1.contains(p4)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#toString', function () {
|
||||
it('should format a string out of point coordinates', function () {
|
||||
it('formats a string out of point coordinates', function () {
|
||||
expect(new L.Point(50, 30) + '').toEqual('Point(50, 30)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('L.point factory', function () {
|
||||
it('should leave L.Point instances as is', function () {
|
||||
it('leaves L.Point instances as is', function () {
|
||||
var p = new L.Point(50, 30);
|
||||
expect(L.point(p)).toBe(p);
|
||||
});
|
||||
it('should create a point out of three arguments', function () {
|
||||
it('creates a point out of three arguments', function () {
|
||||
expect(L.point(50.1, 30.1, true)).toEqual(new L.Point(50, 30));
|
||||
});
|
||||
it('should create a point from an array of coordinates', function () {
|
||||
it('creates a point from an array of coordinates', function () {
|
||||
expect(L.point([50, 30])).toEqual(new L.Point(50, 30));
|
||||
});
|
||||
it('should not fail on invalid arguments', function () {
|
||||
it('does not fail on invalid arguments', function () {
|
||||
expect(L.point(undefined)).toBe(undefined);
|
||||
expect(L.point(null)).toBe(null);
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
describe('PolyUtil', function () {
|
||||
|
||||
describe('#clipPolygon', function () {
|
||||
it('should clip polygon by bounds correctly', function () {
|
||||
it('clips polygon by bounds', function () {
|
||||
var bounds = L.bounds([0, 0], [10, 10]);
|
||||
|
||||
var points = [
|
||||
|
@ -7,23 +7,23 @@ describe("Transformation", function() {
|
||||
});
|
||||
|
||||
describe('#transform', function () {
|
||||
it("should perform a transformation", function() {
|
||||
it("performs a transformation", function() {
|
||||
var p2 = t.transform(p, 2);
|
||||
expect(p2).toEqual(new L.Point(24, 128));
|
||||
});
|
||||
it('should assume scale of 1 if not specified', function () {
|
||||
it('assumes a scale of 1 if not specified', function () {
|
||||
var p2 = t.transform(p);
|
||||
expect(p2).toEqual(new L.Point(12, 64));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#untransform', function () {
|
||||
it("should perform a reverse transformation", function() {
|
||||
it("performs a reverse transformation", function() {
|
||||
var p2 = t.transform(p, 2);
|
||||
var p3 = t.untransform(p2, 2);
|
||||
expect(p3).toEqual(p);
|
||||
});
|
||||
it('should assume scale of 1 if not specified', function () {
|
||||
it('assumes a scale of 1 if not specified', function () {
|
||||
var p2 = t.transform(p);
|
||||
expect(t.untransform(new L.Point(12, 64))).toEqual(new L.Point(10, 20));
|
||||
});
|
||||
|
@ -16,14 +16,14 @@
|
||||
|
||||
var wasClicked = 0;
|
||||
fg2.on('click', function(e) {
|
||||
expect(e.layer == marker).toBe(true);
|
||||
expect(e.target === fg2).toBe(true);
|
||||
expect(e.layer).toBe(marker);
|
||||
expect(e.target).toBe(fg2);
|
||||
wasClicked |= 1;
|
||||
});
|
||||
|
||||
fg1.on('click', function (e) {
|
||||
expect(e.layer == marker).toBe(true);
|
||||
expect(e.target === fg1).toBe(true);
|
||||
expect(e.layer).toBe(marker);
|
||||
expect(e.target).toBe(fg1);
|
||||
wasClicked |= 2;
|
||||
});
|
||||
|
||||
|
58
spec/suites/layer/LayerGroupSpec.js
Normal file
58
spec/suites/layer/LayerGroupSpec.js
Normal file
@ -0,0 +1,58 @@
|
||||
describe('LayerGroup', function () {
|
||||
describe("#addLayer", function () {
|
||||
it('adds a layer', function() {
|
||||
var lg = L.layerGroup(),
|
||||
marker = L.marker([0, 0]);
|
||||
|
||||
expect(lg.addLayer(marker)).toEqual(lg);
|
||||
|
||||
expect(lg.hasLayer(marker)).toBe(true);
|
||||
});
|
||||
});
|
||||
describe("#removeLayer", function () {
|
||||
it('removes a layer', function() {
|
||||
var lg = L.layerGroup(),
|
||||
marker = L.marker([0, 0]);
|
||||
|
||||
lg.addLayer(marker);
|
||||
expect(lg.removeLayer(marker)).toEqual(lg);
|
||||
|
||||
expect(lg.hasLayer(marker)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe("#clearLayers", function () {
|
||||
it('removes all layers', function() {
|
||||
var lg = L.layerGroup(),
|
||||
marker = L.marker([0, 0]);
|
||||
|
||||
lg.addLayer(marker);
|
||||
expect(lg.clearLayers()).toEqual(lg);
|
||||
|
||||
expect(lg.hasLayer(marker)).toBe(false);
|
||||
});
|
||||
});
|
||||
describe("#getLayers", function () {
|
||||
it('gets all layers', function() {
|
||||
var lg = L.layerGroup(),
|
||||
marker = L.marker([0, 0]);
|
||||
|
||||
lg.addLayer(marker);
|
||||
|
||||
expect(lg.getLayers()).toEqual([marker]);
|
||||
});
|
||||
});
|
||||
describe("#eachLayer", function () {
|
||||
it('iterates over all layers', function() {
|
||||
var lg = L.layerGroup(),
|
||||
marker = L.marker([0, 0]),
|
||||
ctx = { foo: 'bar' };
|
||||
|
||||
lg.addLayer(marker);
|
||||
|
||||
lg.eachLayer(function(layer) {
|
||||
expect(layer).toEqual(marker);
|
||||
expect(this).toEqual(ctx);
|
||||
}, ctx);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,53 +1,65 @@
|
||||
|
||||
describe('TileLayer', function () {
|
||||
var tileUrl = '';
|
||||
|
||||
describe("#getMaxZoom, #getMinZoom", function () {
|
||||
var map;
|
||||
beforeEach(function () {
|
||||
map = L.map(document.createElement('div'));
|
||||
});
|
||||
describe("when a tilelayer is added to a map with no other layers", function () {
|
||||
it("should have the same zoomlevels as the tilelayer", function () {
|
||||
it("has the same zoomlevels as the tilelayer", function () {
|
||||
var maxZoom = 10,
|
||||
minZoom = 5;
|
||||
map.setView([0, 0], 1);
|
||||
|
||||
L.tileLayer("{z}{x}{y}", {
|
||||
L.tileLayer(tileUrl, {
|
||||
maxZoom: maxZoom,
|
||||
minZoom: minZoom
|
||||
}).addTo(map);
|
||||
expect(map.getMaxZoom() === maxZoom).toBeTruthy();
|
||||
expect(map.getMinZoom() === minZoom).toBeTruthy();
|
||||
expect(map.getMaxZoom()).toBe(maxZoom);
|
||||
expect(map.getMinZoom()).toBe(minZoom);
|
||||
});
|
||||
});
|
||||
describe("when a tilelayer is added to a map that already has a tilelayer", function () {
|
||||
it("should have its zoomlevels updated to fit the new layer", function () {
|
||||
|
||||
describe("accessing a tilelayer's properties", function () {
|
||||
it('provides a container', function () {
|
||||
map.setView([0, 0], 1);
|
||||
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:10, maxZoom: 15 }).addTo(map);
|
||||
var layer = L.tileLayer(tileUrl).addTo(map);
|
||||
expect(layer.getContainer()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a tilelayer is added to a map that already has a tilelayer", function () {
|
||||
it("has its zoomlevels updated to fit the new layer", function () {
|
||||
map.setView([0, 0], 1);
|
||||
|
||||
L.tileLayer(tileUrl, { minZoom:10, maxZoom: 15 }).addTo(map);
|
||||
expect(map.getMinZoom()).toBe(10);
|
||||
expect(map.getMaxZoom()).toBe(15);
|
||||
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:5, maxZoom: 10 }).addTo(map);
|
||||
L.tileLayer(tileUrl, { minZoom:5, maxZoom: 10 }).addTo(map);
|
||||
expect(map.getMinZoom()).toBe(5); // changed
|
||||
expect(map.getMaxZoom()).toBe(15); // unchanged
|
||||
|
||||
|
||||
L.tileLayer("{z}{x}{y}",{ minZoom:10, maxZoom: 20 }).addTo(map);
|
||||
L.tileLayer(tileUrl,{ minZoom:10, maxZoom: 20 }).addTo(map);
|
||||
expect(map.getMinZoom()).toBe(5); // unchanged
|
||||
expect(map.getMaxZoom()).toBe(20); // changed
|
||||
|
||||
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 25 }).addTo(map);
|
||||
L.tileLayer(tileUrl, { minZoom:0, maxZoom: 25 }).addTo(map);
|
||||
expect(map.getMinZoom()).toBe(0); // changed
|
||||
expect(map.getMaxZoom()).toBe(25); // changed
|
||||
});
|
||||
});
|
||||
describe("when a tilelayer is removed from a map", function () {
|
||||
it("it should have its zoomlevels updated to only fit the layers it currently has", function () {
|
||||
var tiles = [ L.tileLayer("{z}{x}{y}", { minZoom:10, maxZoom: 15 }).addTo(map),
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:5, maxZoom: 10 }).addTo(map),
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:10, maxZoom: 20 }).addTo(map),
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 25 }).addTo(map)
|
||||
it("has its zoomlevels updated to only fit the layers it currently has", function () {
|
||||
var tiles = [ L.tileLayer(tileUrl, { minZoom:10, maxZoom: 15 }).addTo(map),
|
||||
L.tileLayer(tileUrl, { minZoom:5, maxZoom: 10 }).addTo(map),
|
||||
L.tileLayer(tileUrl, { minZoom:10, maxZoom: 20 }).addTo(map),
|
||||
L.tileLayer(tileUrl, { minZoom:0, maxZoom: 25 }).addTo(map)
|
||||
];
|
||||
map.whenReady(function() {
|
||||
expect(map.getMinZoom()).toBe(0);
|
||||
|
@ -7,7 +7,7 @@
|
||||
});
|
||||
describe("when a CircleMarker is added to the map ", function() {
|
||||
describe("with a radius set as an option", function() {
|
||||
it("should take that radius", function() {
|
||||
it("takes that radius", function() {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 }).addTo(map);
|
||||
|
||||
expect(marker._radius).toBe(20);
|
||||
@ -15,7 +15,7 @@
|
||||
});
|
||||
|
||||
describe("and radius is set before adding it", function () {
|
||||
it("should take that radius", function () {
|
||||
it("takes that radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
marker.setRadius(15);
|
||||
marker.addTo(map);
|
||||
@ -24,7 +24,7 @@
|
||||
});
|
||||
|
||||
describe("and radius is set after adding it", function () {
|
||||
it("should take that radius", function () {
|
||||
it("takes that radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
marker.addTo(map);
|
||||
marker.setRadius(15);
|
||||
@ -33,7 +33,7 @@
|
||||
});
|
||||
|
||||
describe("and setStyle is used to change the radius after adding", function () {
|
||||
it("should take the given radius", function() {
|
||||
it("takes the given radius", function() {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
marker.addTo(map);
|
||||
marker.setStyle({ radius: 15 });
|
||||
@ -41,7 +41,7 @@
|
||||
});
|
||||
});
|
||||
describe("and setStyle is used to change the radius before adding", function () {
|
||||
it("should take the given radius", function () {
|
||||
it("takes the given radius", function () {
|
||||
var marker = L.circleMarker([0, 0], { radius: 20 });
|
||||
marker.setStyle({ radius: 15 });
|
||||
marker.addTo(map);
|
||||
|
@ -7,7 +7,7 @@ describe('Circle', function () {
|
||||
circle = L.circle([50, 30], 200);
|
||||
});
|
||||
|
||||
it('should return correct bounds', function () {
|
||||
it('returns bounds', function () {
|
||||
var bounds = circle.getBounds();
|
||||
|
||||
expect(bounds.getSouthWest().equals([49.998203369, 29.997204939])).toBeTruthy();
|
||||
|
55
spec/suites/layer/vector/PolygonSpec.js
Normal file
55
spec/suites/layer/vector/PolygonSpec.js
Normal file
@ -0,0 +1,55 @@
|
||||
describe('Polygon', function() {
|
||||
|
||||
var c = document.createElement('div');
|
||||
c.style.width = '400px';
|
||||
c.style.height = '400px';
|
||||
var map = new L.Map(c);
|
||||
map.setView(new L.LatLng(55.8, 37.6), 6);
|
||||
|
||||
describe("#initialize", function() {
|
||||
it("doesn't overwrite the given latlng array", function () {
|
||||
var originalLatLngs = [
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
];
|
||||
var sourceLatLngs = originalLatLngs.slice();
|
||||
|
||||
var polygon = new L.Polygon(sourceLatLngs);
|
||||
|
||||
expect(sourceLatLngs).toEqual(originalLatLngs);
|
||||
expect(polygon._latlngs).toNotEqual(sourceLatLngs);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setLatLngs", function () {
|
||||
it("doesn't overwrite the given latlng array", function () {
|
||||
var originalLatLngs = [
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
];
|
||||
var sourceLatLngs = originalLatLngs.slice();
|
||||
|
||||
var polygon = new L.Polygon(sourceLatLngs);
|
||||
|
||||
polygon.setLatLngs(sourceLatLngs);
|
||||
|
||||
expect(sourceLatLngs).toEqual(originalLatLngs);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#spliceLatLngs", function () {
|
||||
it("splices the internal latLngs", function () {
|
||||
var latLngs = [
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
[5, 6]
|
||||
];
|
||||
|
||||
var polygon = new L.Polygon(latLngs);
|
||||
|
||||
polygon.spliceLatLngs(1, 1, [7, 8]);
|
||||
|
||||
expect(polygon._latlngs).toEqual([L.latLng([1, 2]), L.latLng([7, 8]), L.latLng([5, 6])]);
|
||||
});
|
||||
});
|
||||
});
|
@ -7,7 +7,7 @@ describe('PolylineGeometry', function() {
|
||||
map.setView(new L.LatLng(55.8, 37.6), 6);
|
||||
|
||||
describe("#distanceTo", function() {
|
||||
it("should calculate correct distances to points", function() {
|
||||
it("calculates distances to points", function() {
|
||||
var p1 = map.latLngToLayerPoint(new L.LatLng(55.8, 37.6));
|
||||
var p2 = map.latLngToLayerPoint(new L.LatLng(57.123076977278, 44.861962891635));
|
||||
var latlngs = [[56.485503424111, 35.545556640339], [55.972522915346, 36.116845702918], [55.502459116923, 34.930322265253], [55.31534617509, 38.973291015816]]
|
||||
|
55
spec/suites/layer/vector/PolylineSpec.js
Normal file
55
spec/suites/layer/vector/PolylineSpec.js
Normal file
@ -0,0 +1,55 @@
|
||||
describe('Polyline', function() {
|
||||
|
||||
var c = document.createElement('div');
|
||||
c.style.width = '400px';
|
||||
c.style.height = '400px';
|
||||
var map = new L.Map(c);
|
||||
map.setView(new L.LatLng(55.8, 37.6), 6);
|
||||
|
||||
describe("#initialize", function() {
|
||||
it("doesn't overwrite the given latlng array", function () {
|
||||
var originalLatLngs = [
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
];
|
||||
var sourceLatLngs = originalLatLngs.slice();
|
||||
|
||||
var polyline = new L.Polyline(sourceLatLngs);
|
||||
|
||||
expect(sourceLatLngs).toEqual(originalLatLngs);
|
||||
expect(polyline._latlngs).toNotEqual(sourceLatLngs);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setLatLngs", function () {
|
||||
it("doesn't overwrite the given latlng array", function () {
|
||||
var originalLatLngs = [
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
];
|
||||
var sourceLatLngs = originalLatLngs.slice();
|
||||
|
||||
var polyline = new L.Polyline(sourceLatLngs);
|
||||
|
||||
polyline.setLatLngs(sourceLatLngs);
|
||||
|
||||
expect(sourceLatLngs).toEqual(originalLatLngs);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#spliceLatLngs", function () {
|
||||
it("splices the internal latLngs", function () {
|
||||
var latLngs = [
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
[5, 6]
|
||||
];
|
||||
|
||||
var polyline = new L.Polyline(latLngs);
|
||||
|
||||
polyline.spliceLatLngs(1, 1, [7, 8]);
|
||||
|
||||
expect(polyline._latlngs).toEqual([L.latLng([1, 2]), L.latLng([7, 8]), L.latLng([5, 6])]);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,10 +1,60 @@
|
||||
describe("Map", function () {
|
||||
var map,
|
||||
spy;
|
||||
beforeEach(function () {
|
||||
map = L.map(document.createElement('div'));
|
||||
spy = jasmine.createSpy();
|
||||
});
|
||||
|
||||
describe("#remove", function () {
|
||||
it("fires an unload event if loaded", function () {
|
||||
var container = document.createElement('div'),
|
||||
map = new L.Map(container).setView([0, 0], 0);
|
||||
map.on('unload', spy);
|
||||
map.remove();
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("fires no unload event if not loaded", function () {
|
||||
var container = document.createElement('div'),
|
||||
map = new L.Map(container);
|
||||
map.on('unload', spy);
|
||||
map.remove();
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("undefines container._leaflet", function () {
|
||||
var container = document.createElement('div'),
|
||||
map = new L.Map(container);
|
||||
map.remove();
|
||||
expect(container._leaflet).toBeUndefined();
|
||||
});
|
||||
|
||||
it("unbinds events", function () {
|
||||
var container = document.createElement('div'),
|
||||
map = new L.Map(container).setView([0, 0], 1);
|
||||
map.on('click dblclick mousedown mouseup mousemove', spy);
|
||||
map.remove();
|
||||
happen.click(container);
|
||||
happen.dblclick(container);
|
||||
happen.mousedown(container);
|
||||
happen.mouseup(container);
|
||||
happen.mousemove(container);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getCenter', function () {
|
||||
it ('throws if not set before', function () {
|
||||
expect(function () {
|
||||
map.getCenter();
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("#whenReady", function () {
|
||||
describe("when the map has not yet been loaded", function () {
|
||||
it("calls the callback when the map is loaded", function () {
|
||||
var map = L.map(document.createElement('div')),
|
||||
spy = jasmine.createSpy();
|
||||
|
||||
map.whenReady(spy);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
|
||||
@ -15,9 +65,6 @@ describe("Map", function () {
|
||||
|
||||
describe("when the map has already been loaded", function () {
|
||||
it("calls the callback immediately", function () {
|
||||
var map = L.map(document.createElement('div')),
|
||||
spy = jasmine.createSpy();
|
||||
|
||||
map.setView([0, 0], 1);
|
||||
map.whenReady(spy);
|
||||
|
||||
@ -26,12 +73,16 @@ describe("Map", function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#getBounds", function () {
|
||||
it("is safe to call from within a moveend callback during initial "
|
||||
+ "load (#1027)", function () {
|
||||
var c = document.createElement('div'),
|
||||
map = L.map(c);
|
||||
describe("#setView", function () {
|
||||
it("sets the view of the map", function () {
|
||||
expect(map.setView([51.505, -0.09], 13)).toBe(map);
|
||||
expect(map.getZoom()).toBe(13);
|
||||
expect(map.getCenter().distanceTo([51.505, -0.09])).toBeLessThan(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#getBounds", function () {
|
||||
it("is safe to call from within a moveend callback during initial load (#1027)", function () {
|
||||
map.on("moveend", function () {
|
||||
map.getBounds();
|
||||
});
|
||||
@ -41,8 +92,7 @@ describe("Map", function () {
|
||||
});
|
||||
|
||||
describe("#getMinZoom and #getMaxZoom", function () {
|
||||
it("The minZoom and maxZoom options overrides any"
|
||||
+ " minZoom and maxZoom set on layers", function () {
|
||||
it("minZoom and maxZoom options overrides any minZoom and maxZoom set on layers", function () {
|
||||
var c = document.createElement('div'),
|
||||
map = L.map(c, { minZoom: 5, maxZoom: 10 });
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
|
||||
@ -51,4 +101,108 @@ describe("Map", function () {
|
||||
expect(map.getMaxZoom()).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#addLayer", function () {
|
||||
describe("When the first layer is added to a map", function () {
|
||||
it("fires a zoomlevelschange event", function () {
|
||||
map.on("zoomlevelschange", spy);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a new layer with greater zoomlevel coverage than the current layer is added to a map", function () {
|
||||
it("fires a zoomlevelschange event", function () {
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
|
||||
map.on("zoomlevelschange", spy);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 15 }).addTo(map);
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a new layer with the same or lower zoomlevel coverage as the current layer is added to a map", function () {
|
||||
it("fires no zoomlevelschange event", function () {
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
|
||||
map.on("zoomlevelschange", spy);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 5 }).addTo(map);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#removeLayer", function () {
|
||||
describe("when the last tile layer on a map is removed", function () {
|
||||
it("fires a zoomlevelschange event", function () {
|
||||
map.whenReady(function(){
|
||||
var tl = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map);
|
||||
|
||||
map.on("zoomlevelschange", spy);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
map.removeLayer(tl);
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a tile layer is removed from a map and it had greater zoom level coverage than the remainding layer", function () {
|
||||
it("fires a zoomlevelschange event", function () {
|
||||
map.whenReady(function(){
|
||||
var tl = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map),
|
||||
t2 = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 15 }).addTo(map);
|
||||
|
||||
map.on("zoomlevelschange", spy);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
map.removeLayer(t2);
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when a tile layer is removed from a map it and it had lesser or the sa,e zoom level coverage as the remainding layer(s)", function () {
|
||||
it("fires no zoomlevelschange event", function () {
|
||||
map.whenReady(function(){
|
||||
var tl = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map),
|
||||
t2 = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 10 }).addTo(map),
|
||||
t3 = L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 5 }).addTo(map);
|
||||
|
||||
map.on("zoomlevelschange", spy);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
map.removeLayer(t2);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
map.removeLayer(t3);
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#eachLayer", function () {
|
||||
it("returns self", function () {
|
||||
expect(map.eachLayer(function () {})).toBe(map);
|
||||
});
|
||||
|
||||
it("calls the provided function for each layer", function () {
|
||||
var t1 = L.tileLayer("{z}{x}{y}").addTo(map),
|
||||
t2 = L.tileLayer("{z}{x}{y}").addTo(map);
|
||||
|
||||
map.eachLayer(spy);
|
||||
|
||||
expect(spy.calls.length).toEqual(2);
|
||||
expect(spy.calls[0].args).toEqual([t1]);
|
||||
expect(spy.calls[1].args).toEqual([t2]);
|
||||
});
|
||||
|
||||
it("calls the provided function with the provided context", function () {
|
||||
var t1 = L.tileLayer("{z}{x}{y}").addTo(map);
|
||||
|
||||
map.eachLayer(spy, map);
|
||||
|
||||
expect(spy.calls[0].object).toEqual(map);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -12,7 +12,8 @@ for (var i=0; i < libSources.length; i++) {
|
||||
files = [].concat([
|
||||
JASMINE,
|
||||
JASMINE_ADAPTER,
|
||||
"before.js"
|
||||
"before.js",
|
||||
"testacular.js"
|
||||
], libSources, [
|
||||
"after.js",
|
||||
"happen.js",
|
||||
|
7
spec/testacular.js
Normal file
7
spec/testacular.js
Normal file
@ -0,0 +1,7 @@
|
||||
// PhantomJS has `'ontouchstart' in document.documentElement`, but
|
||||
// doesn't actually support touch. So force touch not to be used.
|
||||
//
|
||||
// http://code.google.com/p/phantomjs/issues/detail?id=375
|
||||
// https://github.com/ariya/phantomjs/pull/408
|
||||
// https://github.com/Leaflet/Leaflet/pull/1434#issuecomment-13843151
|
||||
window.L_NO_TOUCH = true;
|
@ -5,7 +5,7 @@
|
||||
L.Control.Attribution = L.Control.extend({
|
||||
options: {
|
||||
position: 'bottomright',
|
||||
prefix: 'Powered by <a href="http://leafletjs.com">Leaflet</a>'
|
||||
prefix: '<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
@ -56,8 +56,10 @@ L.Control.Attribution = L.Control.extend({
|
||||
removeAttribution: function (text) {
|
||||
if (!text) { return; }
|
||||
|
||||
if (this._attributions[text]) {
|
||||
this._attributions[text]--;
|
||||
this._update();
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
@ -82,7 +84,7 @@ L.Control.Attribution = L.Control.extend({
|
||||
prefixAndAttribs.push(attribs.join(', '));
|
||||
}
|
||||
|
||||
this._container.innerHTML = prefixAndAttribs.join(' — ');
|
||||
this._container.innerHTML = prefixAndAttribs.join(' | ');
|
||||
},
|
||||
|
||||
_onLayerAdd: function (e) {
|
||||
|
@ -18,13 +18,13 @@ L.Control.Zoom = L.Control.extend({
|
||||
this._zoomOutButton = this._createButton(
|
||||
'-', 'Zoom out', zoomName + '-out', container, this._zoomOut, this);
|
||||
|
||||
map.on('zoomend', this._updateDisabled, this);
|
||||
map.on('zoomend zoomlevelschange', this._updateDisabled, this);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
map.off('zoomend', this._updateDisabled, this);
|
||||
map.off('zoomend zoomlevelschange', this._updateDisabled, this);
|
||||
},
|
||||
|
||||
_zoomIn: function (e) {
|
||||
|
@ -32,6 +32,10 @@ L.Control = L.Class.extend({
|
||||
return this;
|
||||
},
|
||||
|
||||
getContainer: function () {
|
||||
return this._container;
|
||||
},
|
||||
|
||||
addTo: function (map) {
|
||||
this._map = map;
|
||||
|
||||
|
@ -116,10 +116,10 @@ L.Mixin.Events = {
|
||||
return this;
|
||||
}
|
||||
|
||||
var event = L.Util.extend({
|
||||
var event = L.Util.extend({}, data, {
|
||||
type: type,
|
||||
target: this
|
||||
}, data);
|
||||
});
|
||||
|
||||
var listeners, i, len, eventsObj, contextId;
|
||||
|
||||
|
@ -67,7 +67,7 @@ L.DomEvent = {
|
||||
key = '_leaflet_' + type + id,
|
||||
handler = obj[key];
|
||||
|
||||
if (!handler) { return; }
|
||||
if (!handler) { return this; }
|
||||
|
||||
if (L.Browser.msTouch && type.indexOf('touch') === 0) {
|
||||
this.removeMsTouchListener(obj, type, id);
|
||||
|
@ -29,6 +29,7 @@ L.DomUtil = {
|
||||
left = 0,
|
||||
el = element,
|
||||
docBody = document.body,
|
||||
docEl = document.documentElement,
|
||||
pos,
|
||||
ie7 = L.Browser.ie7;
|
||||
|
||||
@ -45,8 +46,8 @@ L.DomUtil = {
|
||||
if (el.offsetParent === docBody && pos === 'absolute') { break; }
|
||||
|
||||
if (pos === 'fixed') {
|
||||
top += docBody.scrollTop || 0;
|
||||
left += docBody.scrollLeft || 0;
|
||||
top += docBody.scrollTop || docEl.scrollTop || 0;
|
||||
left += docBody.scrollLeft || docEl.scrollLeft || 0;
|
||||
break;
|
||||
}
|
||||
el = el.offsetParent;
|
||||
@ -151,7 +152,12 @@ L.DomUtil = {
|
||||
filterName = 'DXImageTransform.Microsoft.Alpha';
|
||||
|
||||
// filters collection throws an error if we try to retrieve a filter that doesn't exist
|
||||
try { filter = el.filters.item(filterName); } catch (e) {}
|
||||
try {
|
||||
filter = el.filters.item(filterName);
|
||||
} catch (e) {
|
||||
//Don't set opacity to 1 if we haven't already set an opacity, it isn't needed and breaks transparent pngs.
|
||||
if (value === 1) { return; }
|
||||
}
|
||||
|
||||
value = Math.round(value * 100);
|
||||
|
||||
|
@ -46,7 +46,7 @@ L.Draggable = L.Class.extend({
|
||||
},
|
||||
|
||||
_onDown: function (e) {
|
||||
if ((!L.Browser.touch && e.shiftKey) ||
|
||||
if (e.shiftKey ||
|
||||
((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }
|
||||
|
||||
L.DomEvent.preventDefault(e);
|
||||
|
@ -80,6 +80,9 @@ L.latLng = function (a, b) { // (LatLng) or ([Number, Number]) or (Number, Numbe
|
||||
if (a === undefined || a === null) {
|
||||
return a;
|
||||
}
|
||||
if (typeof a === 'object' && 'lat' in a) {
|
||||
return new L.LatLng(a.lat, 'lng' in a ? a.lng : a.lon);
|
||||
}
|
||||
return new L.LatLng(a, b);
|
||||
};
|
||||
|
||||
|
@ -89,6 +89,11 @@ L.Point.prototype = {
|
||||
point.y === this.y;
|
||||
},
|
||||
|
||||
contains: function (point) {
|
||||
return Math.abs(point.x) <= Math.abs(this.x) &&
|
||||
Math.abs(point.y) <= Math.abs(this.y);
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return 'Point(' +
|
||||
L.Util.formatNum(this.x) + ', ' +
|
||||
|
@ -90,6 +90,17 @@ L.LayerGroup = L.Class.extend({
|
||||
method.call(context, this._layers[i]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
getLayers: function () {
|
||||
var layers = [];
|
||||
for (var i in this._layers) {
|
||||
if (this._layers.hasOwnProperty(i)) {
|
||||
layers.push(this._layers[i]);
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
},
|
||||
|
||||
setZIndex: function (zIndex) {
|
||||
|
@ -19,6 +19,11 @@ L.Handler.MarkerDrag = L.Handler.extend({
|
||||
},
|
||||
|
||||
removeHooks: function () {
|
||||
this._draggable
|
||||
.off('dragstart', this._onDragStart)
|
||||
.off('drag', this._onDrag)
|
||||
.off('dragend', this._onDragEnd);
|
||||
|
||||
this._draggable.disable();
|
||||
},
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
L.Marker.include({
|
||||
openPopup: function () {
|
||||
if (this._popup && this._map) {
|
||||
if (this._popup && this._map && !this._map.hasLayer(this._popup)) {
|
||||
this._popup.setLatLng(this._latlng);
|
||||
this._map.openPopup(this._popup);
|
||||
}
|
||||
@ -37,12 +37,24 @@ L.Marker.include({
|
||||
.on('move', this._movePopup, this);
|
||||
}
|
||||
|
||||
if (content instanceof L.Popup) {
|
||||
L.setOptions(content, options);
|
||||
this._popup = content;
|
||||
} else {
|
||||
this._popup = new L.Popup(options, this)
|
||||
.setContent(content);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setPopupContent: function (content) {
|
||||
if (this._popup) {
|
||||
this._popup.setContent(content);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
unbindPopup: function () {
|
||||
if (this._popup) {
|
||||
this._popup = null;
|
||||
|
@ -41,6 +41,10 @@ L.Marker = L.Class.extend({
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
if (this.dragging) {
|
||||
this.dragging.disable();
|
||||
}
|
||||
|
||||
this._removeIcon();
|
||||
|
||||
this.fire('remove');
|
||||
|
117
src/layer/tile/TileLayer.Anim.js
Normal file
117
src/layer/tile/TileLayer.Anim.js
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Zoom animation logic for L.TileLayer.
|
||||
*/
|
||||
|
||||
L.TileLayer.include({
|
||||
_animateZoom: function (e) {
|
||||
var firstFrame = false;
|
||||
|
||||
if (!this._animating) {
|
||||
this._animating = true;
|
||||
firstFrame = true;
|
||||
}
|
||||
|
||||
if (firstFrame) {
|
||||
this._prepareBgBuffer();
|
||||
}
|
||||
|
||||
var transform = L.DomUtil.TRANSFORM,
|
||||
bg = this._bgBuffer;
|
||||
|
||||
if (firstFrame) {
|
||||
//prevent bg buffer from clearing right after zoom
|
||||
clearTimeout(this._clearBgBufferTimer);
|
||||
|
||||
// hack to make sure transform is updated before running animation
|
||||
L.Util.falseFn(bg.offsetWidth);
|
||||
}
|
||||
|
||||
var scaleStr = L.DomUtil.getScaleString(e.scale, e.origin),
|
||||
oldTransform = bg.style[transform];
|
||||
|
||||
bg.style[transform] = e.backwards ?
|
||||
(e.delta ? L.DomUtil.getTranslateString(e.delta) : oldTransform) + ' ' + scaleStr :
|
||||
scaleStr + ' ' + oldTransform;
|
||||
},
|
||||
|
||||
_endZoomAnim: function () {
|
||||
var front = this._tileContainer,
|
||||
bg = this._bgBuffer;
|
||||
|
||||
front.style.visibility = '';
|
||||
front.style.zIndex = 2;
|
||||
|
||||
bg.style.zIndex = 1;
|
||||
|
||||
// force reflow
|
||||
L.Util.falseFn(bg.offsetWidth);
|
||||
|
||||
this._animating = false;
|
||||
},
|
||||
|
||||
_clearBgBuffer: function () {
|
||||
var map = this._map;
|
||||
|
||||
if (!map._animatingZoom && !map.touchZoom._zooming) {
|
||||
this._bgBuffer.innerHTML = '';
|
||||
this._bgBuffer.style[L.DomUtil.TRANSFORM] = '';
|
||||
}
|
||||
},
|
||||
|
||||
_prepareBgBuffer: function () {
|
||||
|
||||
var front = this._tileContainer,
|
||||
bg = this._bgBuffer;
|
||||
|
||||
// if foreground layer doesn't have many tiles but bg layer does,
|
||||
// keep the existing bg layer and just zoom it some more
|
||||
|
||||
if (bg && this._getLoadedTilesPercentage(bg) > 0.5 &&
|
||||
this._getLoadedTilesPercentage(front) < 0.5) {
|
||||
|
||||
front.style.visibility = 'hidden';
|
||||
this._stopLoadingImages(front);
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare the buffer to become the front tile pane
|
||||
bg.style.visibility = 'hidden';
|
||||
bg.style[L.DomUtil.TRANSFORM] = '';
|
||||
|
||||
// switch out the current layer to be the new bg layer (and vice-versa)
|
||||
this._tileContainer = bg;
|
||||
bg = this._bgBuffer = front;
|
||||
|
||||
this._stopLoadingImages(bg);
|
||||
},
|
||||
|
||||
_getLoadedTilesPercentage: function (container) {
|
||||
var tiles = container.getElementsByTagName('img'),
|
||||
i, len, count = 0;
|
||||
|
||||
for (i = 0, len = tiles.length; i < len; i++) {
|
||||
if (tiles[i].complete) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count / len;
|
||||
},
|
||||
|
||||
// stops loading all tiles in the background layer
|
||||
_stopLoadingImages: function (container) {
|
||||
var tiles = Array.prototype.slice.call(container.getElementsByTagName('img')),
|
||||
i, len, tile;
|
||||
|
||||
for (i = 0, len = tiles.length; i < len; i++) {
|
||||
tile = tiles[i];
|
||||
|
||||
if (!tile.complete) {
|
||||
tile.onload = L.Util.falseFn;
|
||||
tile.onerror = L.Util.falseFn;
|
||||
tile.src = L.Util.emptyImageUrl;
|
||||
|
||||
tile.parentNode.removeChild(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
@ -18,12 +18,13 @@ L.TileLayer.WMS = L.TileLayer.extend({
|
||||
|
||||
this._url = url;
|
||||
|
||||
var wmsParams = L.extend({}, this.defaultWmsParams);
|
||||
var wmsParams = L.extend({}, this.defaultWmsParams),
|
||||
tileSize = options.tileSize || this.options.tileSize;
|
||||
|
||||
if (options.detectRetina && L.Browser.retina) {
|
||||
wmsParams.width = wmsParams.height = this.options.tileSize * 2;
|
||||
wmsParams.width = wmsParams.height = tileSize * 2;
|
||||
} else {
|
||||
wmsParams.width = wmsParams.height = this.options.tileSize;
|
||||
wmsParams.width = wmsParams.height = tileSize;
|
||||
}
|
||||
|
||||
for (var i in options) {
|
||||
@ -48,8 +49,6 @@ L.TileLayer.WMS = L.TileLayer.extend({
|
||||
|
||||
getTileUrl: function (tilePoint, zoom) { // (Point, Number) -> String
|
||||
|
||||
this._adjustTilePoint(tilePoint);
|
||||
|
||||
var map = this._map,
|
||||
crs = map.options.crs,
|
||||
tileSize = this.options.tileSize,
|
||||
|
@ -22,6 +22,7 @@ L.TileLayer = L.Class.extend({
|
||||
zoomReverse: false,
|
||||
detectRetina: false,
|
||||
reuseTiles: false,
|
||||
bounds: false,
|
||||
*/
|
||||
unloadInvisibleTiles: L.Browser.mobile,
|
||||
updateWhenIdle: L.Browser.mobile
|
||||
@ -42,6 +43,10 @@ L.TileLayer = L.Class.extend({
|
||||
this.options.maxZoom--;
|
||||
}
|
||||
|
||||
if (options.bounds) {
|
||||
options.bounds = L.latLngBounds(options.bounds);
|
||||
}
|
||||
|
||||
this._url = url;
|
||||
|
||||
var subdomains = this.options.subdomains;
|
||||
@ -53,6 +58,7 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
onAdd: function (map) {
|
||||
this._map = map;
|
||||
this._animated = map.options.zoomAnimation && L.Browser.any3d;
|
||||
|
||||
// create a container div for tiles
|
||||
this._initContainer();
|
||||
@ -62,10 +68,17 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
// set up events
|
||||
map.on({
|
||||
'viewreset': this._resetCallback,
|
||||
'viewreset': this._reset,
|
||||
'moveend': this._update
|
||||
}, this);
|
||||
|
||||
if (this._animated) {
|
||||
map.on({
|
||||
'zoomanim': this._animateZoom,
|
||||
'zoomend': this._endZoomAnim
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (!this.options.updateWhenIdle) {
|
||||
this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
|
||||
map.on('move', this._limitedUpdate, this);
|
||||
@ -84,10 +97,17 @@ L.TileLayer = L.Class.extend({
|
||||
this._container.parentNode.removeChild(this._container);
|
||||
|
||||
map.off({
|
||||
'viewreset': this._resetCallback,
|
||||
'viewreset': this._reset,
|
||||
'moveend': this._update
|
||||
}, this);
|
||||
|
||||
if (this._animated) {
|
||||
map.off({
|
||||
'zoomanim': this._animateZoom,
|
||||
'zoomend': this._endZoomAnim
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (!this.options.updateWhenIdle) {
|
||||
map.off('move', this._limitedUpdate, this);
|
||||
}
|
||||
@ -122,6 +142,10 @@ L.TileLayer = L.Class.extend({
|
||||
return this.options.attribution;
|
||||
},
|
||||
|
||||
getContainer: function () {
|
||||
return this._container;
|
||||
},
|
||||
|
||||
setOpacity: function (opacity) {
|
||||
this.options.opacity = opacity;
|
||||
|
||||
@ -151,8 +175,7 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
redraw: function () {
|
||||
if (this._map) {
|
||||
this._map._panes.tilePane.empty = false;
|
||||
this._reset(true);
|
||||
this._reset({hard: true});
|
||||
this._update();
|
||||
}
|
||||
return this;
|
||||
@ -212,11 +235,20 @@ L.TileLayer = L.Class.extend({
|
||||
_initContainer: function () {
|
||||
var tilePane = this._map._panes.tilePane;
|
||||
|
||||
if (!this._container || tilePane.empty) {
|
||||
if (!this._container) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-layer');
|
||||
|
||||
this._updateZIndex();
|
||||
|
||||
if (this._animated) {
|
||||
var className = 'leaflet-tile-container leaflet-zoom-animated';
|
||||
|
||||
this._bgBuffer = L.DomUtil.create('div', className, this._container);
|
||||
this._tileContainer = L.DomUtil.create('div', className, this._container);
|
||||
} else {
|
||||
this._tileContainer = this._container;
|
||||
}
|
||||
|
||||
tilePane.appendChild(this._container);
|
||||
|
||||
if (this.options.opacity < 1) {
|
||||
@ -225,11 +257,7 @@ L.TileLayer = L.Class.extend({
|
||||
}
|
||||
},
|
||||
|
||||
_resetCallback: function (e) {
|
||||
this._reset(e.hard);
|
||||
},
|
||||
|
||||
_reset: function (clearOldContainer) {
|
||||
_reset: function (e) {
|
||||
var tiles = this._tiles;
|
||||
|
||||
for (var key in tiles) {
|
||||
@ -245,8 +273,10 @@ L.TileLayer = L.Class.extend({
|
||||
this._unusedTiles = [];
|
||||
}
|
||||
|
||||
if (clearOldContainer && this._container) {
|
||||
this._container.innerHTML = "";
|
||||
this._tileContainer.innerHTML = "";
|
||||
|
||||
if (this._animated && e && e.hard) {
|
||||
this._clearBgBuffer();
|
||||
}
|
||||
|
||||
this._initContainer();
|
||||
@ -319,7 +349,7 @@ L.TileLayer = L.Class.extend({
|
||||
this._addTile(queue[i], fragment);
|
||||
}
|
||||
|
||||
this._container.appendChild(fragment);
|
||||
this._tileContainer.appendChild(fragment);
|
||||
},
|
||||
|
||||
_tileShouldBeLoaded: function (tilePoint) {
|
||||
@ -336,6 +366,19 @@ L.TileLayer = L.Class.extend({
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.bounds) {
|
||||
var tileSize = this.options.tileSize,
|
||||
nwPoint = tilePoint.multiplyBy(tileSize),
|
||||
sePoint = nwPoint.add(new L.Point(tileSize, tileSize)),
|
||||
nw = this._map.unproject(nwPoint),
|
||||
se = this._map.unproject(sePoint),
|
||||
bounds = new L.LatLngBounds([nw, se]);
|
||||
|
||||
if (!this.options.bounds.intersects(bounds)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -365,8 +408,8 @@ L.TileLayer = L.Class.extend({
|
||||
L.DomUtil.removeClass(tile, 'leaflet-tile-loaded');
|
||||
this._unusedTiles.push(tile);
|
||||
|
||||
} else if (tile.parentNode === this._container) {
|
||||
this._container.removeChild(tile);
|
||||
} else if (tile.parentNode === this._tileContainer) {
|
||||
this._tileContainer.removeChild(tile);
|
||||
}
|
||||
|
||||
// for https://github.com/CloudMade/Leaflet/issues/137
|
||||
@ -386,7 +429,6 @@ 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 3 browser not tested
|
||||
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
|
||||
@ -397,7 +439,7 @@ L.TileLayer = L.Class.extend({
|
||||
|
||||
this._loadTile(tile, tilePoint);
|
||||
|
||||
if (tile.parentNode !== this._container) {
|
||||
if (tile.parentNode !== this._tileContainer) {
|
||||
container.appendChild(tile);
|
||||
}
|
||||
},
|
||||
@ -424,11 +466,9 @@ L.TileLayer = L.Class.extend({
|
||||
// image-specific code (override to implement e.g. Canvas or SVG tile layer)
|
||||
|
||||
getTileUrl: function (tilePoint) {
|
||||
this._adjustTilePoint(tilePoint);
|
||||
|
||||
return L.Util.template(this._url, L.extend({
|
||||
s: this._getSubdomain(tilePoint),
|
||||
z: this._getZoomForUrl(),
|
||||
z: tilePoint.z,
|
||||
x: tilePoint.x,
|
||||
y: tilePoint.y
|
||||
}, this.options));
|
||||
@ -451,6 +491,8 @@ L.TileLayer = L.Class.extend({
|
||||
if (this.options.tms) {
|
||||
tilePoint.y = limit - tilePoint.y - 1;
|
||||
}
|
||||
|
||||
tilePoint.z = this._getZoomForUrl();
|
||||
},
|
||||
|
||||
_getSubdomain: function (tilePoint) {
|
||||
@ -491,6 +533,7 @@ L.TileLayer = L.Class.extend({
|
||||
tile.onload = this._tileOnLoad;
|
||||
tile.onerror = this._tileOnError;
|
||||
|
||||
this._adjustTilePoint(tilePoint);
|
||||
tile.src = this.getTileUrl(tilePoint);
|
||||
},
|
||||
|
||||
@ -498,6 +541,12 @@ L.TileLayer = L.Class.extend({
|
||||
this._tilesToLoad--;
|
||||
if (!this._tilesToLoad) {
|
||||
this.fire('load');
|
||||
|
||||
if (this._animated) {
|
||||
// clear scaled tiles after all new tiles are loaded (for performance)
|
||||
clearTimeout(this._clearBgBufferTimer);
|
||||
this._clearBgBufferTimer = setTimeout(L.bind(this._clearBgBuffer, this), 500);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -6,11 +6,14 @@ L.Path.include({
|
||||
|
||||
bindPopup: function (content, options) {
|
||||
|
||||
if (content instanceof L.Popup) {
|
||||
this._popup = content;
|
||||
} else {
|
||||
if (!this._popup || options) {
|
||||
this._popup = new L.Popup(options, this);
|
||||
}
|
||||
|
||||
this._popup.setContent(content);
|
||||
}
|
||||
|
||||
if (!this._popupHandlersAdded) {
|
||||
this
|
||||
|
@ -64,6 +64,9 @@ L.Path = L.Path.extend({
|
||||
if (this.options.pointerEvents) {
|
||||
this._path.setAttribute('pointer-events', this.options.pointerEvents);
|
||||
}
|
||||
if (!this.options.clickable && !this.options.pointerEvents) {
|
||||
this._path.setAttribute('pointer-events', 'none');
|
||||
}
|
||||
this._updateStyle();
|
||||
},
|
||||
|
||||
|
@ -8,11 +8,20 @@ L.Polygon = L.Polyline.extend({
|
||||
},
|
||||
|
||||
initialize: function (latlngs, options) {
|
||||
var i, len, hole;
|
||||
|
||||
L.Polyline.prototype.initialize.call(this, latlngs, options);
|
||||
|
||||
if (latlngs && L.Util.isArray(latlngs[0]) && (typeof latlngs[0][0] !== 'number')) {
|
||||
this._latlngs = this._convertLatLngs(latlngs[0]);
|
||||
this._holes = latlngs.slice(1);
|
||||
|
||||
for (i = 0, len = this._holes.length; i < len; i++) {
|
||||
hole = this._holes[i] = this._convertLatLngs(this._holes[i]);
|
||||
if (hole[0].equals(hole[hole.length - 1])) {
|
||||
hole.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// filter out last point if its equal to the first one
|
||||
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* L.Handler.PolyEdit is an editing handler for polylines and polygons.
|
||||
*/
|
||||
|
||||
L.Handler.PolyEdit = L.Handler.extend({
|
||||
options: {
|
||||
icon: new L.DivIcon({
|
||||
iconSize: new L.Point(8, 8),
|
||||
className: 'leaflet-div-icon leaflet-editing-icon'
|
||||
})
|
||||
},
|
||||
|
||||
initialize: function (poly, options) {
|
||||
this._poly = poly;
|
||||
L.setOptions(this, options);
|
||||
},
|
||||
|
||||
addHooks: function () {
|
||||
if (this._poly._map) {
|
||||
if (!this._markerGroup) {
|
||||
this._initMarkers();
|
||||
}
|
||||
this._poly._map.addLayer(this._markerGroup);
|
||||
}
|
||||
},
|
||||
|
||||
removeHooks: function () {
|
||||
if (this._poly._map) {
|
||||
this._poly._map.removeLayer(this._markerGroup);
|
||||
delete this._markerGroup;
|
||||
delete this._markers;
|
||||
}
|
||||
},
|
||||
|
||||
updateMarkers: function () {
|
||||
this._markerGroup.clearLayers();
|
||||
this._initMarkers();
|
||||
},
|
||||
|
||||
_initMarkers: function () {
|
||||
if (!this._markerGroup) {
|
||||
this._markerGroup = new L.LayerGroup();
|
||||
}
|
||||
this._markers = [];
|
||||
|
||||
var latlngs = this._poly._latlngs,
|
||||
i, j, len, marker;
|
||||
|
||||
// TODO refactor holes implementation in Polygon to support it here
|
||||
|
||||
for (i = 0, len = latlngs.length; i < len; i++) {
|
||||
|
||||
marker = this._createMarker(latlngs[i], i);
|
||||
marker.on('click', this._onMarkerClick, this);
|
||||
this._markers.push(marker);
|
||||
}
|
||||
|
||||
var markerLeft, markerRight;
|
||||
|
||||
for (i = 0, j = len - 1; i < len; j = i++) {
|
||||
if (i === 0 && !(L.Polygon && (this._poly instanceof L.Polygon))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
markerLeft = this._markers[j];
|
||||
markerRight = this._markers[i];
|
||||
|
||||
this._createMiddleMarker(markerLeft, markerRight);
|
||||
this._updatePrevNext(markerLeft, markerRight);
|
||||
}
|
||||
},
|
||||
|
||||
_createMarker: function (latlng, index) {
|
||||
var marker = new L.Marker(latlng, {
|
||||
draggable: true,
|
||||
icon: this.options.icon
|
||||
});
|
||||
|
||||
marker._origLatLng = latlng;
|
||||
marker._index = index;
|
||||
|
||||
marker.on('drag', this._onMarkerDrag, this);
|
||||
marker.on('dragend', this._fireEdit, this);
|
||||
|
||||
this._markerGroup.addLayer(marker);
|
||||
|
||||
return marker;
|
||||
},
|
||||
|
||||
_fireEdit: function () {
|
||||
this._poly.fire('edit');
|
||||
},
|
||||
|
||||
_onMarkerDrag: function (e) {
|
||||
var marker = e.target;
|
||||
|
||||
L.extend(marker._origLatLng, marker._latlng);
|
||||
|
||||
if (marker._middleLeft) {
|
||||
marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
|
||||
}
|
||||
if (marker._middleRight) {
|
||||
marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
|
||||
}
|
||||
|
||||
this._poly.redraw();
|
||||
},
|
||||
|
||||
_onMarkerClick: function (e) {
|
||||
// we want to remove the marker on click, but if latlng count < 3, polyline would be invalid
|
||||
if (this._poly._latlngs.length < 3) { return; }
|
||||
|
||||
var marker = e.target,
|
||||
i = marker._index;
|
||||
|
||||
// remove the marker
|
||||
this._markerGroup.removeLayer(marker);
|
||||
this._markers.splice(i, 1);
|
||||
this._poly.spliceLatLngs(i, 1);
|
||||
this._updateIndexes(i, -1);
|
||||
|
||||
// update prev/next links of adjacent markers
|
||||
this._updatePrevNext(marker._prev, marker._next);
|
||||
|
||||
// remove ghost markers near the removed marker
|
||||
if (marker._middleLeft) {
|
||||
this._markerGroup.removeLayer(marker._middleLeft);
|
||||
}
|
||||
if (marker._middleRight) {
|
||||
this._markerGroup.removeLayer(marker._middleRight);
|
||||
}
|
||||
|
||||
// create a ghost marker in place of the removed one
|
||||
if (marker._prev && marker._next) {
|
||||
this._createMiddleMarker(marker._prev, marker._next);
|
||||
|
||||
} else if (!marker._prev) {
|
||||
marker._next._middleLeft = null;
|
||||
|
||||
} else if (!marker._next) {
|
||||
marker._prev._middleRight = null;
|
||||
}
|
||||
|
||||
this._poly.fire('edit');
|
||||
},
|
||||
|
||||
_updateIndexes: function (index, delta) {
|
||||
this._markerGroup.eachLayer(function (marker) {
|
||||
if (marker._index > index) {
|
||||
marker._index += delta;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_createMiddleMarker: function (marker1, marker2) {
|
||||
var latlng = this._getMiddleLatLng(marker1, marker2),
|
||||
marker = this._createMarker(latlng),
|
||||
onClick,
|
||||
onDragStart,
|
||||
onDragEnd;
|
||||
|
||||
marker.setOpacity(0.6);
|
||||
|
||||
marker1._middleRight = marker2._middleLeft = marker;
|
||||
|
||||
onDragStart = function () {
|
||||
var i = marker2._index;
|
||||
|
||||
marker._index = i;
|
||||
|
||||
marker
|
||||
.off('click', onClick)
|
||||
.on('click', this._onMarkerClick, this);
|
||||
|
||||
latlng.lat = marker.getLatLng().lat;
|
||||
latlng.lng = marker.getLatLng().lng;
|
||||
this._poly.spliceLatLngs(i, 0, latlng);
|
||||
this._markers.splice(i, 0, marker);
|
||||
|
||||
marker.setOpacity(1);
|
||||
|
||||
this._updateIndexes(i, 1);
|
||||
marker2._index++;
|
||||
this._updatePrevNext(marker1, marker);
|
||||
this._updatePrevNext(marker, marker2);
|
||||
};
|
||||
|
||||
onDragEnd = function () {
|
||||
marker.off('dragstart', onDragStart, this);
|
||||
marker.off('dragend', onDragEnd, this);
|
||||
|
||||
this._createMiddleMarker(marker1, marker);
|
||||
this._createMiddleMarker(marker, marker2);
|
||||
};
|
||||
|
||||
onClick = function () {
|
||||
onDragStart.call(this);
|
||||
onDragEnd.call(this);
|
||||
this._poly.fire('edit');
|
||||
};
|
||||
|
||||
marker
|
||||
.on('click', onClick, this)
|
||||
.on('dragstart', onDragStart, this)
|
||||
.on('dragend', onDragEnd, this);
|
||||
|
||||
this._markerGroup.addLayer(marker);
|
||||
},
|
||||
|
||||
_updatePrevNext: function (marker1, marker2) {
|
||||
if (marker1) {
|
||||
marker1._next = marker2;
|
||||
}
|
||||
if (marker2) {
|
||||
marker2._prev = marker1;
|
||||
}
|
||||
},
|
||||
|
||||
_getMiddleLatLng: function (marker1, marker2) {
|
||||
var map = this._poly._map,
|
||||
p1 = map.latLngToLayerPoint(marker1.getLatLng()),
|
||||
p2 = map.latLngToLayerPoint(marker2.getLatLng());
|
||||
|
||||
return map.layerPointToLatLng(p1._add(p2)._divideBy(2));
|
||||
}
|
||||
});
|
||||
|
||||
L.Polyline.addInitHook(function () {
|
||||
|
||||
if (L.Handler.PolyEdit) {
|
||||
this.editing = new L.Handler.PolyEdit(this);
|
||||
|
||||
if (this.options.editable) {
|
||||
this.editing.enable();
|
||||
}
|
||||
}
|
||||
|
||||
this.on('add', function () {
|
||||
if (this.editing && this.editing.enabled()) {
|
||||
this.editing.addHooks();
|
||||
}
|
||||
});
|
||||
|
||||
this.on('remove', function () {
|
||||
if (this.editing && this.editing.enabled()) {
|
||||
this.editing.removeHooks();
|
||||
}
|
||||
});
|
||||
});
|
@ -47,7 +47,7 @@ L.Polyline = L.Path.extend({
|
||||
|
||||
spliceLatLngs: function () { // (Number index, Number howMany)
|
||||
var removed = [].splice.apply(this._latlngs, arguments);
|
||||
this._convertLatLngs(this._latlngs);
|
||||
this._convertLatLngs(this._latlngs, true);
|
||||
this.redraw();
|
||||
return removed;
|
||||
},
|
||||
@ -85,15 +85,16 @@ L.Polyline = L.Path.extend({
|
||||
return bounds;
|
||||
},
|
||||
|
||||
_convertLatLngs: function (latlngs) {
|
||||
var i, len;
|
||||
_convertLatLngs: function (latlngs, overwrite) {
|
||||
var i, len, target = overwrite ? latlngs : [];
|
||||
|
||||
for (i = 0, len = latlngs.length; i < len; i++) {
|
||||
if (L.Util.isArray(latlngs[i]) && typeof latlngs[i][0] !== 'number') {
|
||||
return;
|
||||
}
|
||||
latlngs[i] = L.latLng(latlngs[i]);
|
||||
target[i] = L.latLng(latlngs[i]);
|
||||
}
|
||||
return latlngs;
|
||||
return target;
|
||||
},
|
||||
|
||||
_initEvents: function () {
|
||||
|
@ -123,20 +123,31 @@ L.Path = (L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? L.Path :
|
||||
|
||||
_initEvents: function () {
|
||||
if (this.options.clickable) {
|
||||
// TODO hand cursor
|
||||
// TODO mouseover, mouseout, dblclick
|
||||
// TODO dblclick
|
||||
this._map.on('mousemove', this._onMouseMove, this);
|
||||
this._map.on('click', this._onClick, this);
|
||||
}
|
||||
},
|
||||
|
||||
_onClick: function (e) {
|
||||
if (this._containsPoint(e.layerPoint)) {
|
||||
this.fire('click', {
|
||||
latlng: e.latlng,
|
||||
layerPoint: e.layerPoint,
|
||||
containerPoint: e.containerPoint,
|
||||
originalEvent: e
|
||||
});
|
||||
this.fire('click', e);
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseMove: function (e) {
|
||||
if (this._map._animatingZoom) { return; }
|
||||
|
||||
// TODO don't do on each move
|
||||
if (this._containsPoint(e.layerPoint)) {
|
||||
this._ctx.canvas.style.cursor = 'pointer';
|
||||
this._mouseInside = true;
|
||||
this.fire('mouseover', e);
|
||||
|
||||
} else if (this._mouseInside) {
|
||||
this._ctx.canvas.style.cursor = '';
|
||||
this._mouseInside = false;
|
||||
this.fire('mouseout', e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -198,6 +198,15 @@ L.Map = L.Class.extend({
|
||||
return this._layers.hasOwnProperty(id);
|
||||
},
|
||||
|
||||
eachLayer: function (method, context) {
|
||||
for (var i in this._layers) {
|
||||
if (this._layers.hasOwnProperty(i)) {
|
||||
method.call(context, this._layers[i]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
invalidateSize: function (animate) {
|
||||
var oldSize = this.getSize();
|
||||
|
||||
@ -211,6 +220,7 @@ L.Map = L.Class.extend({
|
||||
|
||||
var offset = oldSize._subtract(this.getSize())._divideBy(2)._round();
|
||||
|
||||
if ((offset.x !== 0) || (offset.y !== 0)) {
|
||||
if (animate === true) {
|
||||
this.panBy(offset);
|
||||
} else {
|
||||
@ -221,6 +231,7 @@ L.Map = L.Class.extend({
|
||||
clearTimeout(this._sizeTimer);
|
||||
this._sizeTimer = setTimeout(L.bind(this.fire, this, 'moveend'), 200);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
@ -237,10 +248,24 @@ L.Map = L.Class.extend({
|
||||
return this;
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
if (this._loaded) {
|
||||
this.fire('unload');
|
||||
}
|
||||
this._initEvents('off');
|
||||
delete this._container._leaflet;
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
// public methods for getting map state
|
||||
|
||||
getCenter: function () { // (Boolean) -> LatLng
|
||||
this._checkIfLoaded();
|
||||
|
||||
if (!this._moved()) {
|
||||
return this._initialCenter;
|
||||
}
|
||||
return this.layerPointToLatLng(this._getCenterLayerPoint());
|
||||
},
|
||||
|
||||
@ -328,6 +353,7 @@ L.Map = L.Class.extend({
|
||||
},
|
||||
|
||||
getPixelOrigin: function () {
|
||||
this._checkIfLoaded();
|
||||
return this._initialTopLeftPoint;
|
||||
},
|
||||
|
||||
@ -365,13 +391,13 @@ L.Map = L.Class.extend({
|
||||
},
|
||||
|
||||
layerPointToLatLng: function (point) { // (Point)
|
||||
var projectedPoint = L.point(point).add(this._initialTopLeftPoint);
|
||||
var projectedPoint = L.point(point).add(this.getPixelOrigin());
|
||||
return this.unproject(projectedPoint);
|
||||
},
|
||||
|
||||
latLngToLayerPoint: function (latlng) { // (LatLng)
|
||||
var projectedPoint = this.project(L.latLng(latlng))._round();
|
||||
return projectedPoint._subtract(this._initialTopLeftPoint);
|
||||
return projectedPoint._subtract(this.getPixelOrigin());
|
||||
},
|
||||
|
||||
containerPointToLayerPoint: function (point) { // (Point)
|
||||
@ -497,6 +523,7 @@ L.Map = L.Class.extend({
|
||||
}
|
||||
|
||||
this._zoom = zoom;
|
||||
this._initialCenter = center;
|
||||
|
||||
this._initialTopLeftPoint = this._getNewTopLeftPoint(center);
|
||||
|
||||
@ -530,10 +557,15 @@ L.Map = L.Class.extend({
|
||||
L.DomUtil.setPosition(this._mapPane, this._getMapPanePos().subtract(offset));
|
||||
},
|
||||
|
||||
_getZoomSpan: function () {
|
||||
return this.getMaxZoom() - this.getMinZoom();
|
||||
},
|
||||
|
||||
_updateZoomLevels: function () {
|
||||
var i,
|
||||
minZoom = Infinity,
|
||||
maxZoom = -Infinity;
|
||||
maxZoom = -Infinity,
|
||||
oldZoomSpan = this._getZoomSpan();
|
||||
|
||||
for (i in this._zoomBoundLayers) {
|
||||
if (this._zoomBoundLayers.hasOwnProperty(i)) {
|
||||
@ -553,25 +585,37 @@ L.Map = L.Class.extend({
|
||||
this._layersMaxZoom = maxZoom;
|
||||
this._layersMinZoom = minZoom;
|
||||
}
|
||||
|
||||
if (oldZoomSpan !== this._getZoomSpan()) {
|
||||
this.fire("zoomlevelschange");
|
||||
}
|
||||
},
|
||||
|
||||
_checkIfLoaded: function () {
|
||||
if (!this._loaded) {
|
||||
throw new Error('Set map center and zoom first.');
|
||||
}
|
||||
},
|
||||
|
||||
// map events
|
||||
|
||||
_initEvents: function () {
|
||||
_initEvents: function (onOff) {
|
||||
if (!L.DomEvent) { return; }
|
||||
|
||||
L.DomEvent.on(this._container, 'click', this._onMouseClick, this);
|
||||
onOff = onOff || 'on';
|
||||
|
||||
L.DomEvent[onOff](this._container, 'click', this._onMouseClick, this);
|
||||
|
||||
var events = ['dblclick', 'mousedown', 'mouseup', 'mouseenter',
|
||||
'mouseleave', 'mousemove', 'contextmenu'],
|
||||
i, len;
|
||||
|
||||
for (i = 0, len = events.length; i < len; i++) {
|
||||
L.DomEvent.on(this._container, events[i], this._fireMouseEvent, this);
|
||||
L.DomEvent[onOff](this._container, events[i], this._fireMouseEvent, this);
|
||||
}
|
||||
|
||||
if (this.options.trackResize) {
|
||||
L.DomEvent.on(window, 'resize', this._onResize, this);
|
||||
L.DomEvent[onOff](window, 'resize', this._onResize, this);
|
||||
}
|
||||
},
|
||||
|
||||
@ -614,12 +658,9 @@ L.Map = L.Class.extend({
|
||||
},
|
||||
|
||||
_onTileLayerLoad: function () {
|
||||
// TODO super-ugly, refactor!!!
|
||||
// clear scaled tiles after all new tiles are loaded (for performance)
|
||||
this._tileLayersToLoad--;
|
||||
if (this._tileLayersNum && !this._tileLayersToLoad && this._tileBg) {
|
||||
clearTimeout(this._clearTileBgTimer);
|
||||
this._clearTileBgTimer = setTimeout(L.bind(this._clearTileBg, this), 500);
|
||||
if (this._tileLayersNum && !this._tileLayersToLoad) {
|
||||
this.fire('tilelayersload');
|
||||
}
|
||||
},
|
||||
|
||||
@ -639,12 +680,13 @@ L.Map = L.Class.extend({
|
||||
return L.DomUtil.getPosition(this._mapPane);
|
||||
},
|
||||
|
||||
_getTopLeftPoint: function () {
|
||||
if (!this._loaded) {
|
||||
throw new Error('Set map center and zoom first.');
|
||||
}
|
||||
_moved: function () {
|
||||
var pos = this._getMapPanePos();
|
||||
return pos && !pos.equals(new L.Point(0, 0));
|
||||
},
|
||||
|
||||
return this._initialTopLeftPoint.subtract(this._getMapPanePos());
|
||||
_getTopLeftPoint: function () {
|
||||
return this.getPixelOrigin().subtract(this._getMapPanePos());
|
||||
},
|
||||
|
||||
_getNewTopLeftPoint: function (center, zoom) {
|
||||
@ -658,12 +700,14 @@ L.Map = L.Class.extend({
|
||||
return this.project(latlng, newZoom)._subtract(topLeft);
|
||||
},
|
||||
|
||||
// layer point of the current center
|
||||
_getCenterLayerPoint: function () {
|
||||
return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
|
||||
},
|
||||
|
||||
_getCenterOffset: function (center) {
|
||||
return this.latLngToLayerPoint(center).subtract(this._getCenterLayerPoint());
|
||||
// offset of the specified place to the current center in pixels
|
||||
_getCenterOffset: function (latlng) {
|
||||
return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint());
|
||||
},
|
||||
|
||||
_limitZoom: function (zoom) {
|
||||
|
@ -5,37 +5,43 @@
|
||||
L.Map.include({
|
||||
|
||||
setView: function (center, zoom, forceReset) {
|
||||
|
||||
zoom = this._limitZoom(zoom);
|
||||
|
||||
var zoomChanged = (this._zoom !== zoom);
|
||||
|
||||
if (this._loaded && !forceReset && this._layers) {
|
||||
center = L.latLng(center);
|
||||
|
||||
if (this._panAnim) {
|
||||
this._panAnim.stop();
|
||||
}
|
||||
|
||||
var done = (zoomChanged ?
|
||||
this._zoomToIfClose && this._zoomToIfClose(center, zoom) :
|
||||
this._panByIfClose(center));
|
||||
var zoomChanged = (this._zoom !== zoom),
|
||||
canBeAnimated = this._loaded && !forceReset && !!this._layers;
|
||||
|
||||
// exit if animated pan or zoom started
|
||||
if (done) {
|
||||
if (canBeAnimated) {
|
||||
|
||||
// try animating pan or zoom
|
||||
var animated = zoomChanged && this.options.zoomAnimation ?
|
||||
this._animateZoomIfClose && this._animateZoomIfClose(center, zoom) :
|
||||
this._animatePanIfClose(center);
|
||||
|
||||
if (animated) {
|
||||
// prevent resize handler call, the view will refresh after animation anyway
|
||||
clearTimeout(this._sizeTimer);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// reset the map view
|
||||
// animation didn't start, just reset the map view
|
||||
this._resetView(center, zoom);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
panBy: function (offset, duration, easeLinearity) {
|
||||
offset = L.point(offset);
|
||||
panBy: function (offset, duration, easeLinearity, noMoveStart) {
|
||||
offset = L.point(offset).round();
|
||||
|
||||
if (!(offset.x || offset.y)) {
|
||||
// TODO add options instead of arguments to setView/panTo/panBy/etc.
|
||||
|
||||
if (!offset.x && !offset.y) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -48,11 +54,14 @@ L.Map.include({
|
||||
}, this);
|
||||
}
|
||||
|
||||
// don't fire movestart if animating inertia
|
||||
if (!noMoveStart) {
|
||||
this.fire('movestart');
|
||||
}
|
||||
|
||||
L.DomUtil.addClass(this._mapPane, 'leaflet-pan-anim');
|
||||
|
||||
var newPos = L.DomUtil.getPosition(this._mapPane).subtract(offset)._round();
|
||||
var newPos = this._getMapPanePos().subtract(offset);
|
||||
this._panAnim.run(this._mapPane, newPos, duration || 0.25, easeLinearity);
|
||||
|
||||
return this;
|
||||
@ -67,22 +76,13 @@ L.Map.include({
|
||||
this.fire('moveend');
|
||||
},
|
||||
|
||||
_panByIfClose: function (center) {
|
||||
_animatePanIfClose: function (center) {
|
||||
// difference between the new and current centers in pixels
|
||||
var offset = this._getCenterOffset(center)._floor();
|
||||
|
||||
if (this._offsetIsWithinView(offset)) {
|
||||
if (!this.getSize().contains(offset)) { return false; }
|
||||
|
||||
this.panBy(offset);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_offsetIsWithinView: function (offset, multiplyFactor) {
|
||||
var m = multiplyFactor || 1,
|
||||
size = this.getSize();
|
||||
|
||||
return (Math.abs(offset.x) <= size.x * m) &&
|
||||
(Math.abs(offset.y) <= size.y * m);
|
||||
}
|
||||
});
|
||||
|
@ -7,163 +7,80 @@ L.Map.mergeOptions({
|
||||
});
|
||||
|
||||
if (L.DomUtil.TRANSITION) {
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
// zoom transitions run with the same duration for all layers, so if one of transitionend events
|
||||
// happens after starting zoom animation (propagating to the map pane), we know that it ended globally
|
||||
|
||||
L.DomEvent.on(this._mapPane, L.DomUtil.TRANSITION_END, this._catchTransitionEnd, this);
|
||||
});
|
||||
}
|
||||
|
||||
L.Map.include(!L.DomUtil.TRANSITION ? {} : {
|
||||
|
||||
_zoomToIfClose: function (center, zoom) {
|
||||
|
||||
if (this._animatingZoom) { return true; }
|
||||
|
||||
if (!this.options.zoomAnimation) { return false; }
|
||||
|
||||
var scale = this.getZoomScale(zoom),
|
||||
offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale);
|
||||
|
||||
// if offset does not exceed half of the view
|
||||
if (!this._offsetIsWithinView(offset, 1)) { return false; }
|
||||
|
||||
L.DomUtil.addClass(this._mapPane, 'leaflet-zoom-anim');
|
||||
|
||||
this
|
||||
.fire('movestart')
|
||||
.fire('zoomstart');
|
||||
|
||||
this.fire('zoomanim', {
|
||||
center: center,
|
||||
zoom: zoom
|
||||
});
|
||||
|
||||
var origin = this._getCenterLayerPoint().add(offset);
|
||||
|
||||
this._prepareTileBg();
|
||||
this._runAnimation(center, zoom, scale, origin);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_catchTransitionEnd: function () {
|
||||
if (this._animatingZoom) {
|
||||
this._onZoomTransitionEnd();
|
||||
}
|
||||
},
|
||||
|
||||
_runAnimation: function (center, zoom, scale, origin, backwardsTransform) {
|
||||
this._animateToCenter = center;
|
||||
this._animateToZoom = zoom;
|
||||
_animateZoomIfClose: function (center, zoom) {
|
||||
|
||||
if (this._animatingZoom) { return true; }
|
||||
|
||||
// offset is the pixel coords of the zoom origin relative to the current center
|
||||
var scale = this.getZoomScale(zoom),
|
||||
offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale),
|
||||
origin = this._getCenterLayerPoint()._add(offset);
|
||||
|
||||
// only animate if the zoom origin is within one screen from the current center
|
||||
if (!this.getSize().contains(offset)) { return false; }
|
||||
|
||||
this
|
||||
.fire('movestart')
|
||||
.fire('zoomstart');
|
||||
|
||||
this._animateZoom(center, zoom, origin, scale);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
_animateZoom: function (center, zoom, origin, scale, delta, backwards) {
|
||||
|
||||
this._animatingZoom = true;
|
||||
|
||||
// put transform transition on all layers with leaflet-zoom-animated class
|
||||
L.DomUtil.addClass(this._mapPane, 'leaflet-zoom-anim');
|
||||
|
||||
// remember what center/zoom to set after animation
|
||||
this._animateToCenter = center;
|
||||
this._animateToZoom = zoom;
|
||||
|
||||
// disable any dragging during animation
|
||||
if (L.Draggable) {
|
||||
L.Draggable._disabled = true;
|
||||
}
|
||||
|
||||
var transform = L.DomUtil.TRANSFORM,
|
||||
tileBg = this._tileBg;
|
||||
|
||||
clearTimeout(this._clearTileBgTimer);
|
||||
|
||||
L.Util.falseFn(tileBg.offsetWidth); //hack to make sure transform is updated before running animation
|
||||
|
||||
var scaleStr = L.DomUtil.getScaleString(scale, origin),
|
||||
oldTransform = tileBg.style[transform];
|
||||
|
||||
tileBg.style[transform] = backwardsTransform ?
|
||||
oldTransform + ' ' + scaleStr :
|
||||
scaleStr + ' ' + oldTransform;
|
||||
},
|
||||
|
||||
_prepareTileBg: function () {
|
||||
var tilePane = this._tilePane,
|
||||
tileBg = this._tileBg;
|
||||
|
||||
// If foreground layer doesn't have many tiles but bg layer does, keep the existing bg layer and just zoom it some more
|
||||
if (tileBg && this._getLoadedTilesPercentage(tileBg) > 0.5 &&
|
||||
this._getLoadedTilesPercentage(tilePane) < 0.5) {
|
||||
|
||||
tilePane.style.visibility = 'hidden';
|
||||
tilePane.empty = true;
|
||||
this._stopLoadingImages(tilePane);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tileBg) {
|
||||
tileBg = this._tileBg = this._createPane('leaflet-tile-pane', this._mapPane);
|
||||
tileBg.style.zIndex = 1;
|
||||
}
|
||||
|
||||
// prepare the background pane to become the main tile pane
|
||||
tileBg.style[L.DomUtil.TRANSFORM] = '';
|
||||
tileBg.style.visibility = 'hidden';
|
||||
|
||||
// tells tile layers to reinitialize their containers
|
||||
tileBg.empty = true; //new FG
|
||||
tilePane.empty = false; //new BG
|
||||
|
||||
//Switch out the current layer to be the new bg layer (And vice-versa)
|
||||
this._tilePane = this._panes.tilePane = tileBg;
|
||||
var newTileBg = this._tileBg = tilePane;
|
||||
|
||||
L.DomUtil.addClass(newTileBg, 'leaflet-zoom-animated');
|
||||
|
||||
this._stopLoadingImages(newTileBg);
|
||||
},
|
||||
|
||||
_getLoadedTilesPercentage: function (container) {
|
||||
var tiles = container.getElementsByTagName('img'),
|
||||
i, len, count = 0;
|
||||
|
||||
for (i = 0, len = tiles.length; i < len; i++) {
|
||||
if (tiles[i].complete) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count / len;
|
||||
},
|
||||
|
||||
// stops loading all tiles in the background layer
|
||||
_stopLoadingImages: function (container) {
|
||||
var tiles = Array.prototype.slice.call(container.getElementsByTagName('img')),
|
||||
i, len, tile;
|
||||
|
||||
for (i = 0, len = tiles.length; i < len; i++) {
|
||||
tile = tiles[i];
|
||||
|
||||
if (!tile.complete) {
|
||||
tile.onload = L.Util.falseFn;
|
||||
tile.onerror = L.Util.falseFn;
|
||||
tile.src = L.Util.emptyImageUrl;
|
||||
|
||||
tile.parentNode.removeChild(tile);
|
||||
}
|
||||
}
|
||||
this.fire('zoomanim', {
|
||||
center: center,
|
||||
zoom: zoom,
|
||||
origin: origin,
|
||||
scale: scale,
|
||||
delta: delta,
|
||||
backwards: backwards
|
||||
});
|
||||
},
|
||||
|
||||
_onZoomTransitionEnd: function () {
|
||||
this._restoreTileFront();
|
||||
|
||||
this._animatingZoom = false;
|
||||
|
||||
L.DomUtil.removeClass(this._mapPane, 'leaflet-zoom-anim');
|
||||
L.Util.falseFn(this._tileBg.offsetWidth); // force reflow
|
||||
this._animatingZoom = false;
|
||||
|
||||
this._resetView(this._animateToCenter, this._animateToZoom, true, true);
|
||||
|
||||
if (L.Draggable) {
|
||||
L.Draggable._disabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
_restoreTileFront: function () {
|
||||
this._tilePane.innerHTML = '';
|
||||
this._tilePane.style.visibility = '';
|
||||
this._tilePane.style.zIndex = 2;
|
||||
this._tileBg.style.zIndex = 1;
|
||||
},
|
||||
|
||||
_clearTileBg: function () {
|
||||
if (!this._animatingZoom && !this.touchZoom._zooming) {
|
||||
this._tileBg.innerHTML = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -60,13 +60,13 @@ L.Map.include({
|
||||
},
|
||||
|
||||
_handleGeolocationResponse: function (pos) {
|
||||
var latAccuracy = 180 * pos.coords.accuracy / 4e7,
|
||||
lngAccuracy = latAccuracy * 2,
|
||||
|
||||
lat = pos.coords.latitude,
|
||||
var lat = pos.coords.latitude,
|
||||
lng = pos.coords.longitude,
|
||||
latlng = new L.LatLng(lat, lng),
|
||||
|
||||
latAccuracy = 180 * pos.coords.accuracy / 40075017,
|
||||
lngAccuracy = latAccuracy / Math.cos(L.LatLng.DEG_TO_RAD * lat),
|
||||
|
||||
sw = new L.LatLng(lat - latAccuracy, lng - lngAccuracy),
|
||||
ne = new L.LatLng(lat + latAccuracy, lng + lngAccuracy),
|
||||
bounds = new L.LatLngBounds(sw, ne),
|
||||
@ -78,10 +78,11 @@ L.Map.include({
|
||||
this.setView(latlng, zoom);
|
||||
}
|
||||
|
||||
this.fire('locationfound', {
|
||||
var event = L.extend({
|
||||
latlng: latlng,
|
||||
bounds: bounds,
|
||||
accuracy: pos.coords.accuracy
|
||||
});
|
||||
bounds: bounds
|
||||
}, pos.coords);
|
||||
|
||||
this.fire('locationfound', event);
|
||||
}
|
||||
});
|
||||
|
@ -38,6 +38,7 @@ L.Map.BoxZoom = L.Handler.extend({
|
||||
L.DomEvent
|
||||
.on(document, 'mousemove', this._onMouseMove, this)
|
||||
.on(document, 'mouseup', this._onMouseUp, this)
|
||||
.on(document, 'keydown', this._onKeyDown, this)
|
||||
.preventDefault(e);
|
||||
|
||||
this._map.fire("boxzoomstart");
|
||||
@ -61,7 +62,7 @@ L.Map.BoxZoom = L.Handler.extend({
|
||||
box.style.height = (Math.max(0, Math.abs(offset.y) - 4)) + 'px';
|
||||
},
|
||||
|
||||
_onMouseUp: function (e) {
|
||||
_finish: function () {
|
||||
this._pane.removeChild(this._box);
|
||||
this._container.style.cursor = '';
|
||||
|
||||
@ -69,7 +70,13 @@ L.Map.BoxZoom = L.Handler.extend({
|
||||
|
||||
L.DomEvent
|
||||
.off(document, 'mousemove', this._onMouseMove)
|
||||
.off(document, 'mouseup', this._onMouseUp);
|
||||
.off(document, 'mouseup', this._onMouseUp)
|
||||
.off(document, 'keydown', this._onKeyDown);
|
||||
},
|
||||
|
||||
_onMouseUp: function (e) {
|
||||
|
||||
this._finish();
|
||||
|
||||
var map = this._map,
|
||||
layerPoint = map.mouseEventToLayerPoint(e);
|
||||
@ -85,6 +92,12 @@ L.Map.BoxZoom = L.Handler.extend({
|
||||
map.fire("boxzoomend", {
|
||||
boxZoomBounds: bounds
|
||||
});
|
||||
},
|
||||
|
||||
_onKeyDown: function (e) {
|
||||
if (e.keyCode === 27) {
|
||||
this._finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -111,6 +111,8 @@ L.Map.Drag = L.Handler.extend({
|
||||
|
||||
noInertia = !options.inertia || delay > options.inertiaThreshold || !this._positions[0];
|
||||
|
||||
map.fire('dragend');
|
||||
|
||||
if (noInertia) {
|
||||
map.fire('moveend');
|
||||
|
||||
@ -130,12 +132,10 @@ L.Map.Drag = L.Handler.extend({
|
||||
offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
|
||||
|
||||
L.Util.requestAnimFrame(function () {
|
||||
map.panBy(offset, decelerationDuration, ease);
|
||||
map.panBy(offset, decelerationDuration, ease, true);
|
||||
});
|
||||
}
|
||||
|
||||
map.fire('dragend');
|
||||
|
||||
if (options.maxBounds) {
|
||||
// TODO predrag validation instead of animation
|
||||
L.Util.requestAnimFrame(this._panInsideMaxBounds, map, true, map._container);
|
||||
|
@ -57,12 +57,11 @@ L.Map.TouchZoom = L.Handler.extend({
|
||||
if (this._scale === 1) { return; }
|
||||
|
||||
if (!this._moved) {
|
||||
L.DomUtil.addClass(map._mapPane, 'leaflet-zoom-anim leaflet-touching');
|
||||
L.DomUtil.addClass(map._mapPane, 'leaflet-touching');
|
||||
|
||||
map
|
||||
.fire('movestart')
|
||||
.fire('zoomstart')
|
||||
._prepareTileBg();
|
||||
.fire('zoomstart');
|
||||
|
||||
this._moved = true;
|
||||
}
|
||||
@ -77,19 +76,10 @@ L.Map.TouchZoom = L.Handler.extend({
|
||||
_updateOnMove: function () {
|
||||
var map = this._map,
|
||||
origin = this._getScaleOrigin(),
|
||||
center = map.layerPointToLatLng(origin);
|
||||
center = map.layerPointToLatLng(origin),
|
||||
zoom = map.getScaleZoom(this._scale);
|
||||
|
||||
map.fire('zoomanim', {
|
||||
center: center,
|
||||
zoom: map.getScaleZoom(this._scale)
|
||||
});
|
||||
|
||||
// Used 2 translates instead of transform-origin because of a very strange bug -
|
||||
// it didn't count the origin on the first touch-zoom but worked correctly afterwards
|
||||
|
||||
map._tileBg.style[L.DomUtil.TRANSFORM] =
|
||||
L.DomUtil.getTranslateString(this._delta) + ' ' +
|
||||
L.DomUtil.getScaleString(this._scale, this._startCenter);
|
||||
map._animateZoom(center, zoom, this._startCenter, this._scale, this._delta, true);
|
||||
},
|
||||
|
||||
_onTouchEnd: function () {
|
||||
@ -112,14 +102,10 @@ L.Map.TouchZoom = L.Handler.extend({
|
||||
roundZoomDelta = (floatZoomDelta > 0 ?
|
||||
Math.ceil(floatZoomDelta) : Math.floor(floatZoomDelta)),
|
||||
|
||||
zoom = map._limitZoom(oldZoom + roundZoomDelta);
|
||||
zoom = map._limitZoom(oldZoom + roundZoomDelta),
|
||||
scale = map.getZoomScale(zoom) / this._scale;
|
||||
|
||||
map.fire('zoomanim', {
|
||||
center: center,
|
||||
zoom: zoom
|
||||
});
|
||||
|
||||
map._runAnimation(center, zoom, map.getZoomScale(zoom) / this._scale, origin, true);
|
||||
map._animateZoom(center, zoom, origin, scale, null, true);
|
||||
},
|
||||
|
||||
_getScaleOrigin: function () {
|
||||
|
Loading…
Reference in New Issue
Block a user