Canvas events fixes (fix #3915)
- fix fireEvent called for each layer containing event point - fix layer not removed from this._layer at remove - fix L.DomEvent.stop(e) not honoured for canvas because events are both listenned on canvas container and map container
This commit is contained in:
parent
c82aaa4158
commit
0b0989f9f1
@ -77,6 +77,7 @@
|
|||||||
<script type="text/javascript" src="suites/layer/vector/PolygonSpec.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/PolylineSpec.js"></script>
|
||||||
<script type="text/javascript" src="suites/layer/vector/PolylineGeometrySpec.js"></script>
|
<script type="text/javascript" src="suites/layer/vector/PolylineGeometrySpec.js"></script>
|
||||||
|
<script type="text/javascript" src="suites/layer/vector/CanvasSpec.js"></script>
|
||||||
|
|
||||||
<!-- /map -->
|
<!-- /map -->
|
||||||
<script type="text/javascript" src="suites/map/MapSpec.js"></script>
|
<script type="text/javascript" src="suites/map/MapSpec.js"></script>
|
||||||
|
78
spec/suites/layer/vector/CanvasSpec.js
Normal file
78
spec/suites/layer/vector/CanvasSpec.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
describe('Canvas', function () {
|
||||||
|
|
||||||
|
var c, map, p2ll, latLngs;
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
c = document.createElement('div');
|
||||||
|
c.style.width = '400px';
|
||||||
|
c.style.height = '400px';
|
||||||
|
c.style.position = 'absolute';
|
||||||
|
c.style.top = '0';
|
||||||
|
c.style.left = '0';
|
||||||
|
document.body.appendChild(c);
|
||||||
|
map = new L.Map(c, {preferCanvas: true, zoomControl: false});
|
||||||
|
map.setView([0, 0], 6);
|
||||||
|
p2ll = function (x, y) {
|
||||||
|
return map.layerPointToLatLng([x, y]);
|
||||||
|
};
|
||||||
|
latLngs = [p2ll(0, 0), p2ll(0, 100), p2ll(100, 100), p2ll(100, 0)];
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function () {
|
||||||
|
document.body.removeChild(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#events", function () {
|
||||||
|
var layer;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
layer = L.polygon(latLngs).addTo(map);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
layer.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fire event when layer contains mouse", function () {
|
||||||
|
var spy = sinon.spy();
|
||||||
|
layer.on('click', spy);
|
||||||
|
happen.at('click', 50, 50); // Click on the layer.
|
||||||
|
expect(spy.callCount).to.eql(1);
|
||||||
|
happen.at('click', 150, 150); // Click outside layer.
|
||||||
|
expect(spy.callCount).to.eql(1);
|
||||||
|
layer.off("click", spy);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("DOM events propagate from canvas polygon to map", function () {
|
||||||
|
var spy = sinon.spy();
|
||||||
|
map.on("click", spy);
|
||||||
|
happen.at('click', 50, 50);
|
||||||
|
expect(spy.callCount).to.eql(1);
|
||||||
|
map.off("click", spy);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("DOM events fired on canvas polygon can be cancelled before being caught by the map", function () {
|
||||||
|
var mapSpy = sinon.spy();
|
||||||
|
var layerSpy = sinon.spy();
|
||||||
|
map.on("click", mapSpy);
|
||||||
|
layer.on("click", L.DomEvent.stopPropagation).on("click", layerSpy);
|
||||||
|
happen.at('click', 50, 50);
|
||||||
|
expect(layerSpy.callCount).to.eql(1);
|
||||||
|
expect(mapSpy.callCount).to.eql(0);
|
||||||
|
map.off("click", mapSpy);
|
||||||
|
layer.off("click", L.DomEvent.stopPropagation).off("click", layerSpy);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("DOM events fired on canvas polygon are propagated only once to the map even when two layers contains the event", function () {
|
||||||
|
var spy = sinon.spy();
|
||||||
|
var layer2 = L.polygon(latLngs).addTo(map);
|
||||||
|
map.on("click", spy);
|
||||||
|
happen.at('click', 50, 50);
|
||||||
|
expect(spy.callCount).to.eql(1);
|
||||||
|
layer2.remove();
|
||||||
|
map.off("click", spy);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -644,14 +644,6 @@ describe("Map", function () {
|
|||||||
expect(spy.calledOnce).to.be.ok();
|
expect(spy.calledOnce).to.be.ok();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("DOM events propagate from canvas polygon to map", function () {
|
|
||||||
var spy = sinon.spy();
|
|
||||||
map.on("mousemove", spy);
|
|
||||||
var layer = new L.Polygon([[1, 2], [3, 4], [5, 6]], {rendered: L.canvas()}).addTo(map);
|
|
||||||
happen.mousemove(layer._path);
|
|
||||||
expect(spy.calledOnce).to.be.ok();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("DOM events propagate from marker to map", function () {
|
it("DOM events propagate from marker to map", function () {
|
||||||
var spy = sinon.spy();
|
var spy = sinon.spy();
|
||||||
map.on("mousemove", spy);
|
map.on("mousemove", spy);
|
||||||
@ -682,17 +674,6 @@ describe("Map", function () {
|
|||||||
expect(mapSpy.called).not.to.be.ok();
|
expect(mapSpy.called).not.to.be.ok();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("DOM events fired on canvas polygon can be cancelled before being caught by the map", function () {
|
|
||||||
var mapSpy = sinon.spy();
|
|
||||||
var layerSpy = sinon.spy();
|
|
||||||
map.on("mousemove", mapSpy);
|
|
||||||
var layer = new L.Polygon([[1, 2], [3, 4], [5, 6]], {rendered: L.canvas()}).addTo(map);
|
|
||||||
layer.on("mousemove", L.DomEvent.stopPropagation).on("mousemove", layerSpy);
|
|
||||||
happen.mousemove(layer._path);
|
|
||||||
expect(layerSpy.calledOnce).to.be.ok();
|
|
||||||
expect(mapSpy.called).not.to.be.ok();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("mouseout is forwarded if fired on the original target", function () {
|
it("mouseout is forwarded if fired on the original target", function () {
|
||||||
var mapSpy = sinon.spy(),
|
var mapSpy = sinon.spy(),
|
||||||
layerSpy = sinon.spy(),
|
layerSpy = sinon.spy(),
|
||||||
|
@ -61,6 +61,7 @@ L.Canvas = L.Renderer.extend({
|
|||||||
|
|
||||||
_removePath: function (layer) {
|
_removePath: function (layer) {
|
||||||
layer._removed = true;
|
layer._removed = true;
|
||||||
|
delete this._layers[L.stamp(layer)];
|
||||||
this._requestRedraw(layer);
|
this._requestRedraw(layer);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -201,14 +202,17 @@ L.Canvas = L.Renderer.extend({
|
|||||||
// so we emulate that by calculating what's under the mouse on mousemove/click manually
|
// so we emulate that by calculating what's under the mouse on mousemove/click manually
|
||||||
|
|
||||||
_onClick: function (e) {
|
_onClick: function (e) {
|
||||||
var point = this._map.mouseEventToLayerPoint(e);
|
var point = this._map.mouseEventToLayerPoint(e), layers = [];
|
||||||
|
|
||||||
for (var id in this._layers) {
|
for (var id in this._layers) {
|
||||||
if (this._layers[id]._containsPoint(point)) {
|
if (this._layers[id]._containsPoint(point)) {
|
||||||
L.DomEvent._fakeStop(e);
|
L.DomEvent._fakeStop(e);
|
||||||
this._fireEvent(this._layers[id], e);
|
layers.push(this._layers[id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (layers.length) {
|
||||||
|
this._fireEvent(layers, e);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMouseMove: function (e) {
|
_onMouseMove: function (e) {
|
||||||
@ -225,7 +229,7 @@ L.Canvas = L.Renderer.extend({
|
|||||||
if (layer && (e.type === 'mouseout' || !layer._containsPoint(point))) {
|
if (layer && (e.type === 'mouseout' || !layer._containsPoint(point))) {
|
||||||
// if we're leaving the layer, fire mouseout
|
// if we're leaving the layer, fire mouseout
|
||||||
L.DomUtil.removeClass(this._container, 'leaflet-interactive');
|
L.DomUtil.removeClass(this._container, 'leaflet-interactive');
|
||||||
this._fireEvent(layer, e, 'mouseout');
|
this._fireEvent([layer], e, 'mouseout');
|
||||||
this._hoveredLayer = null;
|
this._hoveredLayer = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -237,19 +241,19 @@ L.Canvas = L.Renderer.extend({
|
|||||||
layer = this._drawnLayers[id];
|
layer = this._drawnLayers[id];
|
||||||
if (layer.options.interactive && layer._containsPoint(point)) {
|
if (layer.options.interactive && layer._containsPoint(point)) {
|
||||||
L.DomUtil.addClass(this._container, 'leaflet-interactive'); // change cursor
|
L.DomUtil.addClass(this._container, 'leaflet-interactive'); // change cursor
|
||||||
this._fireEvent(layer, e, 'mouseover');
|
this._fireEvent([layer], e, 'mouseover');
|
||||||
this._hoveredLayer = layer;
|
this._hoveredLayer = layer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this._hoveredLayer) {
|
if (this._hoveredLayer) {
|
||||||
this._fireEvent(this._hoveredLayer, e);
|
this._fireEvent([this._hoveredLayer], e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_fireEvent: function (layer, e, type) {
|
_fireEvent: function (layers, e, type) {
|
||||||
this._map._fireDOMEvent(e, type || e.type, [layer]);
|
this._map._fireDOMEvent(e, type || e.type, layers);
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO _bringToFront & _bringToBack, pretty tricky
|
// TODO _bringToFront & _bringToBack, pretty tricky
|
||||||
|
@ -688,6 +688,8 @@ L.Map = L.Evented.extend({
|
|||||||
|
|
||||||
_fireDOMEvent: function (e, type, targets) {
|
_fireDOMEvent: function (e, type, targets) {
|
||||||
|
|
||||||
|
if (e._stopped) { return; }
|
||||||
|
|
||||||
targets = (targets || []).concat(this._findEventTargets(e, type));
|
targets = (targets || []).concat(this._findEventTargets(e, type));
|
||||||
|
|
||||||
if (!targets.length) { return; }
|
if (!targets.length) { return; }
|
||||||
|
Loading…
Reference in New Issue
Block a user