From f631513accec04c6b38d00b7e5b7dcce69e0a6a0 Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Tue, 17 Dec 2013 17:08:21 -0500 Subject: [PATCH] fast event propagation (10x FeatureGroup layer add speedup) --- src/core/Events.js | 70 +++++++++++++++++++++++++++------------ src/layer/FeatureGroup.js | 16 ++------- 2 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/core/Events.js b/src/core/Events.js index c2d4a39a..9b34c7ae 100644 --- a/src/core/Events.js +++ b/src/core/Events.js @@ -113,42 +113,51 @@ L.Evented = L.Class.extend({ return this; } - var event = L.Util.extend({}, data, { type: type, target: this }); - - var events = this[eventsKey], + var event = L.Util.extend({}, data, {type: type, target: this}), + events = this[eventsKey], listeners, i, len, typeIndex, contextId; - if (events[type]) { - // make sure adding/removing listeners inside other listeners won't cause infinite loop - listeners = events[type].slice(); + if (events) { + if (events[type]) { + // make sure adding/removing listeners inside other listeners won't cause infinite loop + listeners = events[type].slice(); - for (i = 0, len = listeners.length; i < len; i++) { - listeners[i].action.call(listeners[i].context, event); - } - } - - // fire event for the context-indexed listeners as well - typeIndex = events[type + '_idx']; - - if (!typeIndex) { return this; } - - for (contextId in typeIndex) { - listeners = typeIndex[contextId].slice(); - - if (listeners) { for (i = 0, len = listeners.length; i < len; i++) { listeners[i].action.call(listeners[i].context, event); } } + + // fire event for the context-indexed listeners as well + typeIndex = events[type + '_idx']; + + if (typeIndex) { + for (contextId in typeIndex) { + listeners = typeIndex[contextId].slice(); + + if (listeners) { + for (i = 0, len = listeners.length; i < len; i++) { + listeners[i].action.call(listeners[i].context, event); + } + } + } + } } + this._propagateEvent(event); + return this; }, hasEventListeners: function (type) { var events = this[eventsKey]; - return !!events && ((type in events && events[type].length > 0) || - (type + '_idx' in events && events[type + '_idx_len'] > 0)); + if (events && ((type in events && events[type].length > 0) || + (type + '_idx' in events && events[type + '_idx_len'] > 0))) { + return true; + } + for (var id in this._eventParents) { + if (this._eventParents[id].hasEventListeners(type)) { return true; } + } + return false; }, clearAllEventListeners: function () { @@ -169,6 +178,23 @@ L.Evented = L.Class.extend({ return this .on(types, fn, context) .on(types, handler, context); + }, + + addEventParent: function (obj) { + this._eventParents = this._eventParents || {}; + this._eventParents[L.stamp(obj)] = obj; + }, + + removeEventParent: function (obj) { + if (this._eventParents) { + delete this._eventParents[L.stamp(obj)]; + } + }, + + _propagateEvent: function (e) { + for (var id in this._eventParents) { + this._eventParents[id].fire(e.type, L.extend({layer: e.target}, e)); + } } }); diff --git a/src/layer/FeatureGroup.js b/src/layer/FeatureGroup.js index a917db1d..2fe9e2c9 100644 --- a/src/layer/FeatureGroup.js +++ b/src/layer/FeatureGroup.js @@ -5,16 +5,12 @@ L.FeatureGroup = L.LayerGroup.extend({ - statics: { - EVENTS: 'click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose' - }, - addLayer: function (layer) { if (this.hasLayer(layer)) { return this; } - layer.on(L.FeatureGroup.EVENTS, this._propagateEvent, this); + layer.addEventParent(this); L.LayerGroup.prototype.addLayer.call(this, layer); @@ -33,7 +29,7 @@ L.FeatureGroup = L.LayerGroup.extend({ layer = this._layers[layer]; } - layer.off(L.FeatureGroup.EVENTS, this._propagateEvent, this); + layer.removeEventParent(this); L.LayerGroup.prototype.removeLayer.call(this, layer); @@ -79,14 +75,6 @@ L.FeatureGroup = L.LayerGroup.extend({ }); return bounds; - }, - - _propagateEvent: function (e) { - e = L.extend({ - layer: e.target, - target: this - }, e); - this.fire(e.type, e); } });