+
+
+
+
diff --git a/spec/suites/layer/PopupSpec.js b/spec/suites/layer/PopupSpec.js
index 9679c2558..df51157dd 100644
--- a/spec/suites/layer/PopupSpec.js
+++ b/spec/suites/layer/PopupSpec.js
@@ -423,6 +423,28 @@ describe('Popup', function () {
.down().moveBy(10, 10, 20).up();
});
+ it('moves the map over a short distance to the popup if it is not in the view (keepInView)', function (done) {
+ container.style.position = 'absolute';
+ container.style.left = 0;
+ container.style.top = 0;
+ container.style.zIndex = 10000;
+
+ // to prevent waiting until the animation is finished
+ map.options.inertia = false;
+
+ var spy = sinon.spy();
+ map.on('autopanstart', spy);
+
+ // Short hop to the edge of the map (at time of writing, will trigger an animated pan)
+ var p = L.popup({keepInView: true}).setContent('Popup').setLatLng(map.getBounds()._northEast);
+ map.once('moveend', function () {
+ expect(spy.callCount).to.be(1);
+ expect(map.getBounds().contains(p.getLatLng())).to.be(true);
+ done();
+ });
+ map.openPopup(p);
+ });
+
it('moves the map over a long distance to the popup if it is not in the view (keepInView)', function (done) {
container.style.position = 'absolute';
container.style.left = 0;
@@ -434,14 +456,30 @@ describe('Popup', function () {
var spy = sinon.spy();
map.on('autopanstart', spy);
- var p = L.popup({keepInView: true}).setContent('Popup').setLatLng([center[0], center[1] + 50]);
- map.openPopup(p);
- setTimeout(function () {
- expect(spy.called).to.be(true);
+ // Long hop (at time of writing, will trigger a view reset)
+ var p = L.popup({keepInView: true}).setContent('Popup').setLatLng([center[0], center[1] + 50]);
+ map.once('moveend', function () {
+ expect(spy.callCount).to.be(1);
expect(map.getBounds().contains(p.getLatLng())).to.be(true);
done();
- }, 800);
+ });
+ map.openPopup(p);
+ });
+
+ it('moves on setLatLng after initial autopan', function (done) {
+ var p = L.popup().setContent('Popup').setLatLng(map.getBounds().getNorthEast());
+
+ map.once('moveend', function () {
+ map.once('moveend', function () {
+ expect(map.getBounds().contains(p.getLatLng())).to.be(true);
+ done();
+ });
+
+ p.setLatLng(map.getBounds().getNorthEast());
+ });
+
+ map.openPopup(p);
});
it("shows the popup at the correct location when multiple markers are registered", function () {
diff --git a/src/layer/Popup.js b/src/layer/Popup.js
index 46de30692..5da70dc71 100644
--- a/src/layer/Popup.js
+++ b/src/layer/Popup.js
@@ -254,10 +254,17 @@ export var Popup = DivOverlay.extend({
DomUtil.setPosition(this._container, pos.add(anchor));
},
- _adjustPan: function (e) {
+ _adjustPan: function () {
if (!this.options.autoPan) { return; }
if (this._map._panAnim) { this._map._panAnim.stop(); }
+ // We can endlessly recurse if keepInView is set and the view resets.
+ // Let's guard against that by exiting early if we're responding to our own autopan.
+ if (this._autopanning) {
+ this._autopanning = false;
+ return;
+ }
+
var map = this._map,
marginBottom = parseInt(DomUtil.getStyle(this._container, 'marginBottom'), 10) || 0,
containerHeight = this._container.offsetHeight + marginBottom,
@@ -292,9 +299,14 @@ export var Popup = DivOverlay.extend({
// @event autopanstart: Event
// Fired when the map starts autopanning when opening a popup.
if (dx || dy) {
+ // Track that we're autopanning, as this function will be re-ran on moveend
+ if (this.options.keepInView) {
+ this._autopanning = true;
+ }
+
map
.fire('autopanstart')
- .panBy([dx, dy], {animate: e && e.type === 'moveend'});
+ .panBy([dx, dy]);
}
},