UNPKG

delegate-event-listener

Version:
146 lines (115 loc) 3.5 kB
/** * Determine if a DOM element matches a CSS selector * * @param {Element} elem * @param {String} selector * @return {Boolean} * @api public */ function matches(elem, selector) { // Vendor-specific implementations of `Element.prototype.matches()`. var proto = window.Element.prototype; var nativeMatches = proto.matches || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector; if (!elem || elem.nodeType !== 1) { return false; } var parentElem = elem.parentNode; // use native 'matches' if (nativeMatches) { return nativeMatches.call(elem, selector); } // native support for `matches` is missing and a fallback is required var nodes = parentElem.querySelectorAll(selector); var len = nodes.length; for (var i = 0; i < len; i++) { if (nodes[i] === elem) { return true; } } return false; } /** * Expose `matches` */ var domMatches = matches; /** * Module dependencies */ /** * @param element {Element} * @param selector {String} * @param context {Element} * @return {Element} */ var domClosest = function (element, selector, context) { context = context || document; // guard against orphans element = { parentNode: element }; while ((element = element.parentNode) && element !== context) { if (domMatches(element, selector)) { return element; } } }; var disabledElementsSelector = ['input', 'textarea', 'button', 'select', 'form'].map(function (element) { return "".concat(element, "[disabled]"); }).join(','); var eventNameMap = { focus: 'focusin', blur: 'focusout', mouseenter: 'mouseover', mouseleave: 'mouseout', pointerenter: 'pointerover', pointerleave: 'pointerout' }; var index = (function () { for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0; _key < _len; _key++) { arguments_[_key] = arguments[_key]; } var handleEventName = arguments_.length === 3; if (!handleEventName) { arguments_.unshift(null); } var eventName = arguments_[0], selector = arguments_[1], listener = arguments_[2]; var wrappedListener = function wrappedListener(e) { if (selector === '') { e.delegateTarget = e.target; if (handleEventName) { e.originalEventType = eventName; } listener(e); return; } var disabledAncestor = domClosest(e.target, disabledElementsSelector); var closestNode = domClosest(e.target, selector); var isDelegated = !e.currentTarget.contains(disabledAncestor) && e.currentTarget.contains(closestNode) && e.currentTarget !== e.target; if (isDelegated) { e.delegateTarget = closestNode; if (handleEventName) { e.originalEventType = eventName; } if (handleEventName && typeof eventNameMap[eventName] !== 'undefined' && eventName !== 'focus' && eventName !== 'blur') { var delegateTarget = e.delegateTarget; var relatedTarget = e.relatedTarget; if (!relatedTarget || !delegateTarget.contains(relatedTarget)) { listener(e); } } else { listener(e); } } }; if (handleEventName) { var _eventNameMap$eventNa; return [(_eventNameMap$eventNa = eventNameMap[eventName]) !== null && _eventNameMap$eventNa !== void 0 ? _eventNameMap$eventNa : eventName, wrappedListener]; } return wrappedListener; }); export default index; //# sourceMappingURL=index.js.map