(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.listen = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
var DOCUMENT_NODE_TYPE = 9;
|
|
/**
|
* A polyfill for Element.matches()
|
*/
|
if (typeof Element !== 'undefined' && !Element.prototype.matches) {
|
var proto = Element.prototype;
|
|
proto.matches = proto.matchesSelector ||
|
proto.mozMatchesSelector ||
|
proto.msMatchesSelector ||
|
proto.oMatchesSelector ||
|
proto.webkitMatchesSelector;
|
}
|
|
/**
|
* Finds the closest parent that matches a selector.
|
*
|
* @param {Element} element
|
* @param {String} selector
|
* @return {Function}
|
*/
|
function closest (element, selector) {
|
while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
|
if (element.matches(selector)) return element;
|
element = element.parentNode;
|
}
|
}
|
|
module.exports = closest;
|
|
},{}],2:[function(require,module,exports){
|
var closest = require('./closest');
|
|
/**
|
* Delegates event to a selector.
|
*
|
* @param {Element} element
|
* @param {String} selector
|
* @param {String} type
|
* @param {Function} callback
|
* @param {Boolean} useCapture
|
* @return {Object}
|
*/
|
function delegate(element, selector, type, callback, useCapture) {
|
var listenerFn = listener.apply(this, arguments);
|
|
element.addEventListener(type, listenerFn, useCapture);
|
|
return {
|
destroy: function() {
|
element.removeEventListener(type, listenerFn, useCapture);
|
}
|
}
|
}
|
|
/**
|
* Finds closest match and invokes callback.
|
*
|
* @param {Element} element
|
* @param {String} selector
|
* @param {String} type
|
* @param {Function} callback
|
* @return {Function}
|
*/
|
function listener(element, selector, type, callback) {
|
return function(e) {
|
e.delegateTarget = closest(e.target, selector);
|
|
if (e.delegateTarget) {
|
callback.call(element, e);
|
}
|
}
|
}
|
|
module.exports = delegate;
|
|
},{"./closest":1}],3:[function(require,module,exports){
|
/**
|
* Check if argument is a HTML element.
|
*
|
* @param {Object} value
|
* @return {Boolean}
|
*/
|
exports.node = function(value) {
|
return value !== undefined
|
&& value instanceof HTMLElement
|
&& value.nodeType === 1;
|
};
|
|
/**
|
* Check if argument is a list of HTML elements.
|
*
|
* @param {Object} value
|
* @return {Boolean}
|
*/
|
exports.nodeList = function(value) {
|
var type = Object.prototype.toString.call(value);
|
|
return value !== undefined
|
&& (type === '[object NodeList]' || type === '[object HTMLCollection]')
|
&& ('length' in value)
|
&& (value.length === 0 || exports.node(value[0]));
|
};
|
|
/**
|
* Check if argument is a string.
|
*
|
* @param {Object} value
|
* @return {Boolean}
|
*/
|
exports.string = function(value) {
|
return typeof value === 'string'
|
|| value instanceof String;
|
};
|
|
/**
|
* Check if argument is a function.
|
*
|
* @param {Object} value
|
* @return {Boolean}
|
*/
|
exports.fn = function(value) {
|
var type = Object.prototype.toString.call(value);
|
|
return type === '[object Function]';
|
};
|
|
},{}],4:[function(require,module,exports){
|
var is = require('./is');
|
var delegate = require('delegate');
|
|
/**
|
* Validates all params and calls the right
|
* listener function based on its target type.
|
*
|
* @param {String|HTMLElement|HTMLCollection|NodeList} target
|
* @param {String} type
|
* @param {Function} callback
|
* @return {Object}
|
*/
|
function listen(target, type, callback) {
|
if (!target && !type && !callback) {
|
throw new Error('Missing required arguments');
|
}
|
|
if (!is.string(type)) {
|
throw new TypeError('Second argument must be a String');
|
}
|
|
if (!is.fn(callback)) {
|
throw new TypeError('Third argument must be a Function');
|
}
|
|
if (is.node(target)) {
|
return listenNode(target, type, callback);
|
}
|
else if (is.nodeList(target)) {
|
return listenNodeList(target, type, callback);
|
}
|
else if (is.string(target)) {
|
return listenSelector(target, type, callback);
|
}
|
else {
|
throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');
|
}
|
}
|
|
/**
|
* Adds an event listener to a HTML element
|
* and returns a remove listener function.
|
*
|
* @param {HTMLElement} node
|
* @param {String} type
|
* @param {Function} callback
|
* @return {Object}
|
*/
|
function listenNode(node, type, callback) {
|
node.addEventListener(type, callback);
|
|
return {
|
destroy: function() {
|
node.removeEventListener(type, callback);
|
}
|
}
|
}
|
|
/**
|
* Add an event listener to a list of HTML elements
|
* and returns a remove listener function.
|
*
|
* @param {NodeList|HTMLCollection} nodeList
|
* @param {String} type
|
* @param {Function} callback
|
* @return {Object}
|
*/
|
function listenNodeList(nodeList, type, callback) {
|
Array.prototype.forEach.call(nodeList, function(node) {
|
node.addEventListener(type, callback);
|
});
|
|
return {
|
destroy: function() {
|
Array.prototype.forEach.call(nodeList, function(node) {
|
node.removeEventListener(type, callback);
|
});
|
}
|
}
|
}
|
|
/**
|
* Add an event listener to a selector
|
* and returns a remove listener function.
|
*
|
* @param {String} selector
|
* @param {String} type
|
* @param {Function} callback
|
* @return {Object}
|
*/
|
function listenSelector(selector, type, callback) {
|
return delegate(document.body, selector, type, callback);
|
}
|
|
module.exports = listen;
|
|
},{"./is":3,"delegate":2}]},{},[4])(4)
|
});
|