Code coverage report for src/core/Events.js

Statements: 100% (63 / 63)      Branches: 88.24% (60 / 68)      Functions: 100% (4 / 4)      Lines: 100% (63 / 63)     

All files » src/core/ » Events.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157        1   1   1       664           664 66 179 179       66       598   598 663         663       571       571 11   560 560       92 92       598       219           17         17 3 6 6     3     14   14 14   12   12 7   5     12 14 12       12 4 4 4         14       205 138     67         67   67 11   11 14           67   67 58 63 63 63 63 64             67       1 1 1  
/*
 * L.Mixin.Events is used to add custom events functionality to Leaflet classes.
 */
 
var key = '_leaflet_events';
 
L.Mixin = {};
 
L.Mixin.Events = {
 
	addEventListener: function (types, fn, context) { // (String, Function[, Object]) or (Object[, Object])
 
		var events = this[key] = this[key] || {},
		    contextId = context && L.stamp(context),
		    type, i, len, evt,
		    objKey, objLenKey, eventsObj;
 
		// types can be a map of types/handlers
		if (typeof types === 'object') {
			for (type in types) {
				Eif (types.hasOwnProperty(type)) {
					this.addEventListener(type, types[type], fn);
				}
			}
 
			return this;
		}
 
		// types can be a string of space-separated words
		types = L.Util.splitWords(types);
 
		for (i = 0, len = types.length; i < len; i++) {
			evt = {
				action: fn,
				context: context || this
			};
 
			if (contextId) {
				// store listeners of a particular context in a separate hash (if it has an id)
				// gives a major performance boost when removing thousands of map layers
 
				objKey = types[i] + '_idx',
				objLenKey = objKey + '_len',
				eventsObj = events[objKey] = events[objKey] || {};
 
				if (eventsObj[contextId]) {
					eventsObj[contextId].push(evt);
				} else {
					eventsObj[contextId] = [evt];
					events[objLenKey] = (events[objLenKey] || 0) + 1;
				}
 
			} else {
				events[types[i]] = events[types[i]] || [];
				events[types[i]].push(evt);
			}
		}
 
		return this;
	},
 
	hasEventListeners: function (type) { // (String) -> Boolean
		return (key in this) &&
		       (((type in this[key]) && this[key][type].length > 0) ||
		        (this[key][type + '_idx_len'] > 0));
	},
 
	removeEventListener: function (types, fn, context) { // (String[, Function, Object]) or (Object[, Object])
		var events = this[key],
		    contextId = context && L.stamp(context),
		    type, i, len, listeners, j,
		    objKey, objLenKey;
 
		if (typeof types === 'object') {
			for (type in types) {
				Eif (types.hasOwnProperty(type)) {
					this.removeEventListener(type, types[type], fn);
				}
			}
			return this;
		}
 
		types = L.Util.splitWords(types);
 
		for (i = 0, len = types.length; i < len; i++) {
			if (this.hasEventListeners(types[i])) {
 
				objKey = types[i] + '_idx';
 
				if (contextId && events[objKey]) {
					listeners =  events[objKey][contextId] || [];
				} else {
					listeners = events[types[i]] || [];
				}
 
				for (j = listeners.length - 1; j >= 0; j--) {
					if ((!fn || listeners[j].action === fn) && (!context || (listeners[j].context === context))) {
						listeners.splice(j, 1);
					}
				}
 
				if (contextId && listeners.length === 0 && events[objKey] && events[objKey][contextId]) {
					objLenKey = objKey + '_len';
					delete events[objKey][contextId];
					events[objLenKey] = (events[objLenKey] || 1) - 1;
				}
			}
		}
 
		return this;
	},
 
	fireEvent: function (type, data) { // (String[, Object])
		if (!this.hasEventListeners(type)) {
			return this;
		}
 
		var event = L.Util.extend({}, data, {
			type: type,
			target: this
		});
 
		var listeners, i, len, eventsObj, contextId;
 
		if (this[key][type]) {
			listeners = this[key][type].slice();
 
			for (i = 0, len = listeners.length; i < len; i++) {
				listeners[i].action.call(listeners[i].context || this, event);
			}
		}
 
		// fire event for the context-indexed listeners as well
 
		eventsObj = this[key][type + '_idx'];
 
		if (eventsObj) {
			for (contextId in eventsObj) {
				Eif (eventsObj.hasOwnProperty(contextId)) {
					listeners = eventsObj[contextId];
					Eif (listeners) {
						for (i = 0, len = listeners.length; i < len; i++) {
							listeners[i].action.call(listeners[i].context || this, event);
						}
					}
				}
			}
		}
 
		return this;
	}
};
 
L.Mixin.Events.on = L.Mixin.Events.addEventListener;
L.Mixin.Events.off = L.Mixin.Events.removeEventListener;
L.Mixin.Events.fire = L.Mixin.Events.fireEvent;