Scrubbing of detached DOM elements, prevents memory leaks (#5265)
* Scrubbing of detached DOM elements, prevents memory leaks and fixes #5263 * Make linter happy
This commit is contained in:
parent
5603a87c70
commit
14c5f1602c
@ -161,6 +161,11 @@ Map.include({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_clearControlPos: function () {
|
_clearControlPos: function () {
|
||||||
|
for (var i in this._controlCorners) {
|
||||||
|
DomUtil.remove(this._controlCorners[i]);
|
||||||
|
}
|
||||||
DomUtil.remove(this._controlContainer);
|
DomUtil.remove(this._controlContainer);
|
||||||
|
delete this._controlCorners;
|
||||||
|
delete this._controlContainer;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,6 @@ export var _pointersCount = 0;
|
|||||||
// ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890
|
// ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890
|
||||||
|
|
||||||
export function addPointerListener(obj, type, handler, id) {
|
export function addPointerListener(obj, type, handler, id) {
|
||||||
|
|
||||||
if (type === 'touchstart') {
|
if (type === 'touchstart') {
|
||||||
_addPointerStart(obj, handler, id);
|
_addPointerStart(obj, handler, id);
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ export function on(obj, types, fn, context) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var eventsKey = '_leaflet_events';
|
||||||
|
|
||||||
// @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this
|
// @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this
|
||||||
// Removes a previously added listener function. If no function is specified,
|
// Removes a previously added listener function. If no function is specified,
|
||||||
// it will remove all the listeners of that particular DOM event from the element.
|
// it will remove all the listeners of that particular DOM event from the element.
|
||||||
@ -46,25 +48,30 @@ export function on(obj, types, fn, context) {
|
|||||||
// @alternative
|
// @alternative
|
||||||
// @function off(el: HTMLElement, eventMap: Object, context?: Object): this
|
// @function off(el: HTMLElement, eventMap: Object, context?: Object): this
|
||||||
// Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
|
// Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
|
||||||
|
|
||||||
|
// @alternative
|
||||||
|
// @function off(el: HTMLElement): this
|
||||||
|
// Removes all known event listeners
|
||||||
export function off(obj, types, fn, context) {
|
export function off(obj, types, fn, context) {
|
||||||
|
|
||||||
if (typeof types === 'object') {
|
if (typeof types === 'object') {
|
||||||
for (var type in types) {
|
for (var type in types) {
|
||||||
removeOne(obj, type, types[type], fn);
|
removeOne(obj, type, types[type], fn);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (types) {
|
||||||
types = Util.splitWords(types);
|
types = Util.splitWords(types);
|
||||||
|
|
||||||
for (var i = 0, len = types.length; i < len; i++) {
|
for (var i = 0, len = types.length; i < len; i++) {
|
||||||
removeOne(obj, types[i], fn, context);
|
removeOne(obj, types[i], fn, context);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (var j in obj[eventsKey]) {
|
||||||
|
removeOne(obj, j, obj[eventsKey][j]);
|
||||||
|
}
|
||||||
|
delete obj[eventsKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var eventsKey = '_leaflet_events';
|
|
||||||
|
|
||||||
function addOne(obj, type, fn, context) {
|
function addOne(obj, type, fn, context) {
|
||||||
var id = type + Util.stamp(fn) + (context ? '_' + Util.stamp(context) : '');
|
var id = type + Util.stamp(fn) + (context ? '_' + Util.stamp(context) : '');
|
||||||
|
|
||||||
|
@ -67,6 +67,13 @@ export var Canvas = Renderer.extend({
|
|||||||
this._ctx = container.getContext('2d');
|
this._ctx = container.getContext('2d');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_destroyContainer: function () {
|
||||||
|
delete this._ctx;
|
||||||
|
L.DomUtil.remove(this._container);
|
||||||
|
L.DomEvent.off(this._container);
|
||||||
|
delete this._container;
|
||||||
|
},
|
||||||
|
|
||||||
_updatePaths: function () {
|
_updatePaths: function () {
|
||||||
if (this._postponeUpdatePaths) { return; }
|
if (this._postponeUpdatePaths) { return; }
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ export var Renderer = Layer.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onRemove: function () {
|
onRemove: function () {
|
||||||
DomUtil.remove(this._container);
|
|
||||||
this.off('update', this._updatePaths, this);
|
this.off('update', this._updatePaths, this);
|
||||||
|
this._destroyContainer();
|
||||||
},
|
},
|
||||||
|
|
||||||
getEvents: function () {
|
getEvents: function () {
|
||||||
|
@ -61,6 +61,13 @@ export var SVG = Renderer.extend({
|
|||||||
this._container.appendChild(this._rootGroup);
|
this._container.appendChild(this._rootGroup);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_destroyContainer: function () {
|
||||||
|
L.DomUtil.remove(this._container);
|
||||||
|
L.DomEvent.off(this._container);
|
||||||
|
delete this._container;
|
||||||
|
delete this._rootGroup;
|
||||||
|
},
|
||||||
|
|
||||||
_onZoomStart: function () {
|
_onZoomStart: function () {
|
||||||
// Drag-then-pinch interactions might mess up the center and zoom.
|
// Drag-then-pinch interactions might mess up the center and zoom.
|
||||||
// In this case, the easiest way to prevent this is re-do the renderer
|
// In this case, the easiest way to prevent this is re-do the renderer
|
||||||
|
@ -716,9 +716,18 @@ export var Map = Evented.extend({
|
|||||||
this.fire('unload');
|
this.fire('unload');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i in this._layers) {
|
var i;
|
||||||
|
for (i in this._layers) {
|
||||||
this._layers[i].remove();
|
this._layers[i].remove();
|
||||||
}
|
}
|
||||||
|
for (i in this._panes) {
|
||||||
|
L.DomUtil.remove(this._panes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._layers = [];
|
||||||
|
this._panes = [];
|
||||||
|
delete this._mapPane;
|
||||||
|
delete this._renderer;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -1507,12 +1516,12 @@ export var Map = Evented.extend({
|
|||||||
|
|
||||||
this.on('zoomanim', function (e) {
|
this.on('zoomanim', function (e) {
|
||||||
var prop = DomUtil.TRANSFORM,
|
var prop = DomUtil.TRANSFORM,
|
||||||
transform = proxy.style[prop];
|
transform = this._proxy.style[prop];
|
||||||
|
|
||||||
DomUtil.setTransform(proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));
|
DomUtil.setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));
|
||||||
|
|
||||||
// workaround for case when transform is the same and so transitionend event is not fired
|
// workaround for case when transform is the same and so transitionend event is not fired
|
||||||
if (transform === proxy.style[prop] && this._animatingZoom) {
|
if (transform === this._proxy.style[prop] && this._animatingZoom) {
|
||||||
this._onZoomTransitionEnd();
|
this._onZoomTransitionEnd();
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
@ -1520,8 +1529,15 @@ export var Map = Evented.extend({
|
|||||||
this.on('load moveend', function () {
|
this.on('load moveend', function () {
|
||||||
var c = this.getCenter(),
|
var c = this.getCenter(),
|
||||||
z = this.getZoom();
|
z = this.getZoom();
|
||||||
DomUtil.setTransform(proxy, this.project(c, z), this.getZoomScale(z, 1));
|
DomUtil.setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1));
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this._on('unload', this._destroyAnimProxy, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
_destroyAnimProxy: function () {
|
||||||
|
L.DomUtil.remove(this._proxy);
|
||||||
|
delete this._proxy;
|
||||||
},
|
},
|
||||||
|
|
||||||
_catchTransitionEnd: function (e) {
|
_catchTransitionEnd: function (e) {
|
||||||
|
@ -25,6 +25,7 @@ export var BoxZoom = Handler.extend({
|
|||||||
this._map = map;
|
this._map = map;
|
||||||
this._container = map._container;
|
this._container = map._container;
|
||||||
this._pane = map._panes.overlayPane;
|
this._pane = map._panes.overlayPane;
|
||||||
|
map.on('unload', this._destroy, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
addHooks: function () {
|
addHooks: function () {
|
||||||
@ -39,6 +40,11 @@ export var BoxZoom = Handler.extend({
|
|||||||
return this._moved;
|
return this._moved;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_destroy: function () {
|
||||||
|
L.DomUtil.remove(this._pane);
|
||||||
|
delete this._pane;
|
||||||
|
},
|
||||||
|
|
||||||
_resetState: function () {
|
_resetState: function () {
|
||||||
this._moved = false;
|
this._moved = false;
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user