docs: function on (node, eventName, filter, handler) {
  		// normalize parameters
  		if (typeof node === 'string') {
  			node = getNodeById(node);
  		}
  
  		// prepare a callback
  		var callback = makeCallback(node, filter, handler);
  
  		// functional event
  		if (typeof eventName === 'function') {
  			return eventName(node, callback);
  		}
  
  		// special case: keydown/keyup with a list of expected keys
  		// TODO: consider replacing with an explicit event function:
  		// var h = on(node, onKeyEvent('keyup', /Enter,Esc/), callback);
  		var keyEvent = /^(keyup|keydown):(.+)$/.exec(eventName);
  		if (keyEvent) {
  			return onKeyEvent(keyEvent[1], new RegExp(keyEvent[2].split(',').join('|')))(node, callback);
  		}
  
  		// handle multiple event types, like: on(node, 'mouseup, mousedown', callback);
  		if (/,/.test(eventName)) {
  			return on.makeMultiHandle(eventName.split(',').map(function (name) {
  				return name.trim();
  			}).filter(function (name) {
  				return name;
  			}).map(function (name) {
  				return on(node, name, callback);
  			}));
  		}
  
  		// handle registered functional events
  		if (Object.prototype.hasOwnProperty.call(on.events, eventName)) {
  			return on.events[eventName](node, callback);
  		}
  
  		// special case: loading an image
  		if (eventName === 'load' && node.tagName.toLowerCase() === 'img') {
  			return onImageLoad(node, callback);
  		}
  
  		// special case: mousewheel
  		if (eventName === 'wheel') {
  			// pass through, but first curry callback to wheel events
  			callback = normalizeWheelEvent(callback);
  			if (!hasWheel) {
  				// old Firefox, old IE, Chrome
  				return on.makeMultiHandle([
  					on(node, 'DOMMouseScroll', callback),
  					on(node, 'mousewheel', callback)
  				]);
  			}
  		}
  
  		// special case: keyboard
  		if (/^key/.test(eventName)) {
  			callback = normalizeKeyEvent(callback);
  		}
  
  		// default case
  		return on.onDomEvent(node, eventName, callback);
  	}