From 5780867cf6bca127c28748857001e6615c99e7fb Mon Sep 17 00:00:00 2001 From: Jake Whiteley Date: Mon, 23 Oct 2023 17:43:08 +0100 Subject: [PATCH 1/3] start refactor to sets --- dist/e.umd.js | 889 +++++++++++++++++++++++++++++++++++++++++++- examples/index.html | 1 - examples/test.js | 121 +++--- src/e.js | 11 +- src/utils.js | 8 +- 5 files changed, 964 insertions(+), 66 deletions(-) diff --git a/dist/e.umd.js b/dist/e.umd.js index 97646dc..cf5dfef 100644 --- a/dist/e.umd.js +++ b/dist/e.umd.js @@ -1 +1,888 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("E",[],t):"object"==typeof exports?exports.E=t():e.E=t()}(self,(function(){return(()=>{"use strict";var e={d:(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};function n(){if(!(this instanceof n))return new n;this.size=0,this.uid=0,this.selectors=[],this.selectorObjects={},this.indexes=Object.create(this.indexes),this.activeIndexes=[]}e.r(t),e.d(t,{default:()=>k});var r=window.document.documentElement,o=r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.oMatchesSelector||r.msMatchesSelector;n.prototype.matchesSelector=function(e,t){return o.call(e,t)},n.prototype.querySelectorAll=function(e,t){return t.querySelectorAll(e)},n.prototype.indexes=[];var i=/^#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g;n.prototype.indexes.push({name:"ID",selector:function(e){var t;if(t=e.match(i))return t[0].slice(1)},element:function(e){if(e.id)return[e.id]}});var a=/^\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g;n.prototype.indexes.push({name:"CLASS",selector:function(e){var t;if(t=e.match(a))return t[0].slice(1)},element:function(e){var t=e.className;if(t){if("string"==typeof t)return t.split(/\s/);if("object"==typeof t&&"baseVal"in t)return t.baseVal.split(/\s/)}}});var s,u=/^((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g;n.prototype.indexes.push({name:"TAG",selector:function(e){var t;if(t=e.match(u))return t[0].toUpperCase()},element:function(e){return[e.nodeName.toUpperCase()]}}),n.prototype.indexes.default={name:"UNIVERSAL",selector:function(){return!0},element:function(){return[!0]}},s="function"==typeof window.Map?window.Map:function(){function e(){this.map={}}return e.prototype.get=function(e){return this.map[e+" "]},e.prototype.set=function(e,t){this.map[e+" "]=t},e}();var l=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g;function f(e,t){var n,r,o,i,a,s,u=(e=e.slice(0).concat(e.default)).length,f=t,c=[];do{if(l.exec(""),(o=l.exec(f))&&(f=o[3],o[2]||!f))for(n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n1?t-1:0),r=1;r { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./src/utils.js": +/*!**********************!*\ + !*** ./src/utils.js ***! + \**********************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ clone: () => (/* binding */ clone), +/* harmony export */ eventTypes: () => (/* binding */ eventTypes), +/* harmony export */ handleDelegation: () => (/* binding */ handleDelegation), +/* harmony export */ listeners: () => (/* binding */ listeners), +/* harmony export */ makeBusStack: () => (/* binding */ makeBusStack), +/* harmony export */ maybeRunQuerySelector: () => (/* binding */ maybeRunQuerySelector), +/* harmony export */ nonBubblers: () => (/* binding */ nonBubblers), +/* harmony export */ triggerBus: () => (/* binding */ triggerBus) +/* harmony export */ }); +function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } +function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } +function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } +/** + * Holds the SelectorSets for each event type + * @type {{}} + */ +var eventTypes = {}; + +/** + * Holds Bus event stacks + * @type {{}} + */ +var listeners = {}; + +/** + * Events that don't bubble + * @type {string[]} + */ +var nonBubblers = ['mouseenter', 'mouseleave', 'pointerenter', 'pointerleave', 'blur', 'focus']; + +/** + * Make a bus stack if not already created. + * + * @param {string} event + */ +function makeBusStack(event) { + if (listeners[event] === undefined) { + listeners[event] = new Set(); + } +} + +/** + * Trigger a bus stack. + * + * @param {string} event + * @param args + */ +function triggerBus(event, args) { + if (listeners[event]) { + listeners[event].forEach(function (cb) { + cb.apply(void 0, _toConsumableArray(args)); + }); + } +} + +/** + * Maybe run querySelectorAll if input is a string. + * + * @param {HTMLElement|Element|string} el + * @returns {NodeListOf} + */ +function maybeRunQuerySelector(el) { + return typeof el === 'string' ? document.querySelectorAll(el) : el; +} + +/** + * Handle delegated events + * + * @param {Event} e + */ +function handleDelegation(e) { + var matches = traverse(eventTypes[e.type], e.target); + if (matches.length) { + for (var i = 0; i < matches.length; i++) { + for (var i2 = 0; i2 < matches[i].stack.length; i2++) { + if (nonBubblers.indexOf(e.type) !== -1) { + addDelegateTarget(e, matches[i].delegatedTarget); + if (e.target === matches[i].delegatedTarget) { + matches[i].stack[i2].data(e); + } + } else { + addDelegateTarget(e, matches[i].delegatedTarget); + matches[i].stack[i2].data(e); + } + } + } + } +} + +/** + * Find a matching selector for delegation + * + * @param {SelectorSet} listeners + * @param {HTMLElement|Element|EventTarget} target + * @returns {[]} + */ +function traverse(listeners, target) { + var queue = []; + var node = target; + do { + if (node.nodeType !== 1) { + break; + } + var matches = listeners.matches(node); + if (matches.length) { + queue.push({ + delegatedTarget: node, + stack: matches + }); + } + } while (node = node.parentElement); + return queue; +} + +/** + * Add delegatedTarget attribute to dispatched delegated events + * + * @param {Event} event + * @param {HTMLElement|Element} delegatedTarget + */ +function addDelegateTarget(event, delegatedTarget) { + Object.defineProperty(event, 'currentTarget', { + configurable: true, + enumerable: true, + get: function get() { + return delegatedTarget; + } + }); +} + +/** + * Creates a deep clone of an object. + * + * @param object + * @returns {Object.} + */ +function clone(object) { + var copy = {}; + for (var key in object) { + copy[key] = _toConsumableArray(object[key]); + } + return copy; +} + + +/***/ }), + +/***/ "./node_modules/selector-set/selector-set.next.js": +/*!********************************************************!*\ + !*** ./node_modules/selector-set/selector-set.next.js ***! + \********************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (/* binding */ SelectorSet) +/* harmony export */ }); +// Public: Create a new SelectorSet. +function SelectorSet() { + // Construct new SelectorSet if called as a function. + if (!(this instanceof SelectorSet)) { + return new SelectorSet(); + } + + // Public: Number of selectors added to the set + this.size = 0; + + // Internal: Incrementing ID counter + this.uid = 0; + + // Internal: Array of String selectors in the set + this.selectors = []; + + // Internal: Map of selector ids to objects + this.selectorObjects = {}; + + // Internal: All Object index String names mapping to Index objects. + this.indexes = Object.create(this.indexes); + + // Internal: Used Object index String names mapping to Index objects. + this.activeIndexes = []; +} + +// Detect prefixed Element#matches function. +var docElem = window.document.documentElement; +var matches = + docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + +// Public: Check if element matches selector. +// +// Maybe overridden with custom Element.matches function. +// +// el - An Element +// selector - String CSS selector +// +// Returns true or false. +SelectorSet.prototype.matchesSelector = function(el, selector) { + return matches.call(el, selector); +}; + +// Public: Find all elements in the context that match the selector. +// +// Maybe overridden with custom querySelectorAll function. +// +// selectors - String CSS selectors. +// context - Element context +// +// Returns non-live list of Elements. +SelectorSet.prototype.querySelectorAll = function(selectors, context) { + return context.querySelectorAll(selectors); +}; + +// Public: Array of indexes. +// +// name - Unique String name +// selector - Function that takes a String selector and returns a String key +// or undefined if it can't be used by the index. +// element - Function that takes an Element and returns an Array of String +// keys that point to indexed values. +// +SelectorSet.prototype.indexes = []; + +// Index by element id +var idRe = /^#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; +SelectorSet.prototype.indexes.push({ + name: 'ID', + selector: function matchIdSelector(sel) { + var m; + if ((m = sel.match(idRe))) { + return m[0].slice(1); + } + }, + element: function getElementId(el) { + if (el.id) { + return [el.id]; + } + } +}); + +// Index by all of its class names +var classRe = /^\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; +SelectorSet.prototype.indexes.push({ + name: 'CLASS', + selector: function matchClassSelector(sel) { + var m; + if ((m = sel.match(classRe))) { + return m[0].slice(1); + } + }, + element: function getElementClassNames(el) { + var className = el.className; + if (className) { + if (typeof className === 'string') { + return className.split(/\s/); + } else if (typeof className === 'object' && 'baseVal' in className) { + // className is a SVGAnimatedString + // global SVGAnimatedString is not an exposed global in Opera 12 + return className.baseVal.split(/\s/); + } + } + } +}); + +// Index by tag/node name: `DIV`, `FORM`, `A` +var tagRe = /^((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; +SelectorSet.prototype.indexes.push({ + name: 'TAG', + selector: function matchTagSelector(sel) { + var m; + if ((m = sel.match(tagRe))) { + return m[0].toUpperCase(); + } + }, + element: function getElementTagName(el) { + return [el.nodeName.toUpperCase()]; + } +}); + +// Default index just contains a single array of elements. +SelectorSet.prototype.indexes['default'] = { + name: 'UNIVERSAL', + selector: function() { + return true; + }, + element: function() { + return [true]; + } +}; + +// Use ES Maps when supported +var Map; +if (typeof window.Map === 'function') { + Map = window.Map; +} else { + Map = (function() { + function Map() { + this.map = {}; + } + Map.prototype.get = function(key) { + return this.map[key + ' ']; + }; + Map.prototype.set = function(key, value) { + this.map[key + ' '] = value; + }; + return Map; + })(); +} + +// Regexps adopted from Sizzle +// https://github.com/jquery/sizzle/blob/1.7/sizzle.js +// +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; + +// Internal: Get indexes for selector. +// +// selector - String CSS selector +// +// Returns Array of {index, key}. +function parseSelectorIndexes(allIndexes, selector) { + allIndexes = allIndexes.slice(0).concat(allIndexes['default']); + + var allIndexesLen = allIndexes.length, + i, + j, + m, + dup, + rest = selector, + key, + index, + indexes = []; + + do { + chunker.exec(''); + if ((m = chunker.exec(rest))) { + rest = m[3]; + if (m[2] || !rest) { + for (i = 0; i < allIndexesLen; i++) { + index = allIndexes[i]; + if ((key = index.selector(m[1]))) { + j = indexes.length; + dup = false; + while (j--) { + if (indexes[j].index === index && indexes[j].key === key) { + dup = true; + break; + } + } + if (!dup) { + indexes.push({ index: index, key: key }); + } + break; + } + } + } + } + } while (m); + + return indexes; +} + +// Internal: Find first item in Array that is a prototype of `proto`. +// +// ary - Array of objects +// proto - Prototype of expected item in `ary` +// +// Returns object from `ary` if found. Otherwise returns undefined. +function findByPrototype(ary, proto) { + var i, len, item; + for (i = 0, len = ary.length; i < len; i++) { + item = ary[i]; + if (proto.isPrototypeOf(item)) { + return item; + } + } +} + +// Public: Log when added selector falls under the default index. +// +// This API should not be considered stable. May change between +// minor versions. +// +// obj - {selector, data} Object +// +// SelectorSet.prototype.logDefaultIndexUsed = function(obj) { +// console.warn(obj.selector, "could not be indexed"); +// }; +// +// Returns nothing. +SelectorSet.prototype.logDefaultIndexUsed = function() {}; + +// Public: Add selector to set. +// +// selector - String CSS selector +// data - Optional data Object (default: undefined) +// +// Returns nothing. +SelectorSet.prototype.add = function(selector, data) { + var obj, + i, + indexProto, + key, + index, + objs, + selectorIndexes, + selectorIndex, + indexes = this.activeIndexes, + selectors = this.selectors, + selectorObjects = this.selectorObjects; + + if (typeof selector !== 'string') { + return; + } + + obj = { + id: this.uid++, + selector: selector, + data: data + }; + selectorObjects[obj.id] = obj; + + selectorIndexes = parseSelectorIndexes(this.indexes, selector); + for (i = 0; i < selectorIndexes.length; i++) { + selectorIndex = selectorIndexes[i]; + key = selectorIndex.key; + indexProto = selectorIndex.index; + + index = findByPrototype(indexes, indexProto); + if (!index) { + index = Object.create(indexProto); + index.map = new Map(); + indexes.push(index); + } + + if (indexProto === this.indexes['default']) { + this.logDefaultIndexUsed(obj); + } + objs = index.map.get(key); + if (!objs) { + objs = []; + index.map.set(key, objs); + } + objs.push(obj); + } + + this.size++; + selectors.push(selector); +}; + +// Public: Remove selector from set. +// +// selector - String CSS selector +// data - Optional data Object (default: undefined) +// +// Returns nothing. +SelectorSet.prototype.remove = function(selector, data) { + if (typeof selector !== 'string') { + return; + } + + var selectorIndexes, + selectorIndex, + i, + j, + k, + selIndex, + objs, + obj, + indexes = this.activeIndexes, + selectors = (this.selectors = []), + selectorObjects = this.selectorObjects, + removedIds = {}, + removeAll = arguments.length === 1; + + selectorIndexes = parseSelectorIndexes(this.indexes, selector); + for (i = 0; i < selectorIndexes.length; i++) { + selectorIndex = selectorIndexes[i]; + + j = indexes.length; + while (j--) { + selIndex = indexes[j]; + if (selectorIndex.index.isPrototypeOf(selIndex)) { + objs = selIndex.map.get(selectorIndex.key); + if (objs) { + k = objs.length; + while (k--) { + obj = objs[k]; + if (obj.selector === selector && (removeAll || obj.data === data)) { + objs.splice(k, 1); + removedIds[obj.id] = true; + } + } + } + break; + } + } + } + + for (i in removedIds) { + delete selectorObjects[i]; + this.size--; + } + + for (i in selectorObjects) { + selectors.push(selectorObjects[i].selector); + } +}; + +// Sort by id property handler. +// +// a - Selector obj. +// b - Selector obj. +// +// Returns Number. +function sortById(a, b) { + return a.id - b.id; +} + +// Public: Find all matching decendants of the context element. +// +// context - An Element +// +// Returns Array of {selector, data, elements} matches. +SelectorSet.prototype.queryAll = function(context) { + if (!this.selectors.length) { + return []; + } + + var matches = {}, + results = []; + var els = this.querySelectorAll(this.selectors.join(', '), context); + + var i, j, len, len2, el, m, match, obj; + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + m = this.matches(el); + for (j = 0, len2 = m.length; j < len2; j++) { + obj = m[j]; + if (!matches[obj.id]) { + match = { + id: obj.id, + selector: obj.selector, + data: obj.data, + elements: [] + }; + matches[obj.id] = match; + results.push(match); + } else { + match = matches[obj.id]; + } + match.elements.push(el); + } + } + + return results.sort(sortById); +}; + +// Public: Match element against all selectors in set. +// +// el - An Element +// +// Returns Array of {selector, data} matches. +SelectorSet.prototype.matches = function(el) { + if (!el) { + return []; + } + + var i, j, k, len, len2, len3, index, keys, objs, obj, id; + var indexes = this.activeIndexes, + matchedIds = {}, + matches = []; + + for (i = 0, len = indexes.length; i < len; i++) { + index = indexes[i]; + keys = index.element(el); + if (keys) { + for (j = 0, len2 = keys.length; j < len2; j++) { + if ((objs = index.map.get(keys[j]))) { + for (k = 0, len3 = objs.length; k < len3; k++) { + obj = objs[k]; + id = obj.id; + if (!matchedIds[id] && this.matchesSelector(el, obj.selector)) { + matchedIds[id] = true; + matches.push(obj); + } + } + } + } + } + } + + return matches.sort(sortById); +}; + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!******************!*\ + !*** ./src/e.js ***! + \******************/ +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var selector_set__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! selector-set */ "./node_modules/selector-set/selector-set.next.js"); +/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/utils.js"); +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } +function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } +function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } + + + +/** + * Public API + */ +var E = /*#__PURE__*/function () { + function E() { + _classCallCheck(this, E); + } + _createClass(E, [{ + key: "bindAll", + value: + /** + * Binds all provided methods to a provided context. + * + * @param {object} context + * @param {string[]} [methods] Optional. + */ + function bindAll(context, methods) { + if (!methods) { + methods = Object.getOwnPropertyNames(Object.getPrototypeOf(context)); + } + for (var i = 0; i < methods.length; i++) { + context[methods[i]] = context[methods[i]].bind(context); + } + } + + /** + * Bind event to a string, NodeList, or element. + * + * @param {string} event + * @param {string|NodeList|HTMLElement|HTMLElement[]|Window|Document|function} el + * @param {*} [callback] + * @param {{}|boolean} [options] + */ + }, { + key: "on", + value: function on(event, el, callback, options) { + var events = event.split(' '); + for (var i = 0; i < events.length; i++) { + if (typeof el === 'function' && callback === undefined) { + (0,_utils__WEBPACK_IMPORTED_MODULE_1__.makeBusStack)(events[i]); + _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]].add(el); + continue; + } + if (el.nodeType && el.nodeType === 1 || el === window || el === document) { + el.addEventListener(events[i], callback, options); + continue; + } + el = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.maybeRunQuerySelector)(el); + for (var n = 0; n < el.length; n++) { + el[n].addEventListener(events[i], callback, options); + } + } + } + + /** + * Add a delegated event. + * + * @param {string} event + * @param {string|NodeList|HTMLElement|Element} delegate + * @param {*} [callback] + */ + }, { + key: "delegate", + value: function delegate(event, _delegate, callback) { + var events = event.split(' '); + for (var i = 0; i < events.length; i++) { + var map = _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; + if (map === undefined) { + map = new selector_set__WEBPACK_IMPORTED_MODULE_0__["default"](); + _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]] = map; + if (_utils__WEBPACK_IMPORTED_MODULE_1__.nonBubblers.indexOf(events[i]) !== -1) { + document.addEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation, true); + } else { + document.addEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation); + } + } + map.add(_delegate, callback); + } + } + + /** + * Remove a callback from a DOM element, or one or all Bus events. + * + * @param {string} event + * @param {string|NodeList|HTMLElement|Element|Window|undefined} [el] + * @param {*} [callback] + * @param {{}|boolean} [options] + */ + }, { + key: "off", + value: function off(event, el, callback, options) { + var events = event.split(' '); + for (var i = 0; i < events.length; i++) { + if (el === undefined) { + var _listeners$events$i; + (_listeners$events$i = _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]]) === null || _listeners$events$i === void 0 || _listeners$events$i.clear(); + continue; + } + if (typeof el === 'function') { + (0,_utils__WEBPACK_IMPORTED_MODULE_1__.makeBusStack)(events[i]); + _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]]["delete"](el); + continue; + } + var map = _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; + if (map !== undefined) { + map.remove(el, callback); + if (map.size === 0) { + delete _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; + if (_utils__WEBPACK_IMPORTED_MODULE_1__.nonBubblers.indexOf(events[i]) !== -1) { + document.removeEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation, true); + } else { + document.removeEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation); + } + continue; + } + } + if (el.removeEventListener !== undefined) { + el.removeEventListener(events[i], callback, options); + continue; + } + el = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.maybeRunQuerySelector)(el); + for (var n = 0; n < el.length; n++) { + el[n].removeEventListener(events[i], callback, options); + } + } + } + + /** + * Emit a Bus event. + * + * @param {string} event + * @param {...*} args + */ + }, { + key: "emit", + value: function emit(event) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + (0,_utils__WEBPACK_IMPORTED_MODULE_1__.triggerBus)(event, args); + } + + /** + * Return a clone of the delegated event stack for debugging. + * + * @returns {Object.} + */ + }, { + key: "debugDelegated", + value: function debugDelegated() { + return JSON.parse(JSON.stringify(_utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes)); + } + + /** + * Return a clone of the bus event stack for debugging. + * + * @returns {Object.} + */ + }, { + key: "debugBus", + value: function debugBus() { + return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.clone)(_utils__WEBPACK_IMPORTED_MODULE_1__.listeners); + } + + /** + * Checks if a given bus event has listeners. + * + * @param {string} event + * @returns {boolean} + */ + }, { + key: "hasBus", + value: function hasBus(event) { + return this.debugBus().hasOwnProperty(event); + } + }]); + return E; +}(); +var instance = new E(); +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (instance); +})(); + +/******/ return __webpack_exports__; +/******/ })() +; +}); \ No newline at end of file diff --git a/examples/index.html b/examples/index.html index 19132f8..6614312 100644 --- a/examples/index.html +++ b/examples/index.html @@ -28,7 +28,6 @@

Event Bus

- click
diff --git a/examples/test.js b/examples/test.js index c5020c6..ddb2de2 100644 --- a/examples/test.js +++ b/examples/test.js @@ -5,38 +5,41 @@ const btn2 = document.getElementById('btn2') class Foo { - init() { - E.bindAll(this) - - E.on('resize', window, e => console.log('window resized!')) - E.on('click', btn, this.eventHandler, {capture: true}) - E.off('click', btn, this.eventHandler, {capture: true}) - E.on('click', btn2, this.offHandler) - E.on('click', '#btnone', this.one, {once: true}) - E.delegate('click','#btn3', this.onceHandler) - E.delegate('click','.deep', this.delegateHandler) - - E.on('mouseenter', document.querySelectorAll('.nodelist'), () => console.log('nodelist')) - E.on('mouseenter', [...document.querySelectorAll('.nodelist')], () => console.log('nodelist array')) - - E.delegate('mouseenter', '#mouseover', this.delegatedMouseEnter) - E.delegate('mouseleave', '#mouseover', this.delegatedMouseLeave) + init() { + E.bindAll(this) + + E.on('resize', window, e => console.log('window resized!')) + E.on('click', btn, this.eventHandler, { capture: true }) + E.off('click', btn, this.eventHandler, { capture: true }) + E.on('click', btn2, this.offHandler) + E.on('click', '#btnone', this.one, { once: true }) + E.delegate('click', '#btn3', this.onceHandler) + E.delegate('click', '.deep', this.delegateHandler) + + E.on('mouseenter', document.querySelectorAll('.nodelist'), () => console.log('nodelist')) + E.on('mouseenter', [...document.querySelectorAll('.nodelist')], () => console.log('nodelist array')) + + E.delegate('mouseenter', '#mouseover', this.delegatedMouseEnter) + E.delegate('mouseleave', '#mouseover', this.delegatedMouseLeave) //E.off('mouseenter', '#mouseover', this.delegatedMouseEnter) - //E.off('mouseleave', '#mouseover', this.delegatedMouseLeave) + //E.off('mouseleave', '#mouseover', this.delegatedMouseLeave) - E.delegate('blur focus', '.delegatedblurfocus', (e) => console.log(`delegated ${e.type}`)) + E.delegate('blur focus', '.delegatedblurfocus', (e) => console.log(`delegated ${e.type}`)) - E.delegate('click','button, h2', () => console.log('qs example')) + E.delegate('click', 'button, h2', () => console.log('qs example')) - // Event bus example - E.on('event.bus.event event.bus.event2', this.listener) - E.on('click', '#bus-test', this.triggerBus) - E.on('click', '#bus-off', this.removeBus) + // Event bus example + E.on('event.bus.event event.bus.event2', this.listener) + E.on('event.bus.removal', this.removalTest1) + E.on('event.bus.removal', this.removalTest2) + E.on('event.bus.removal', this.removalTest3) + E.on('click', '#bus-test', this.triggerBus) + E.on('click', '#bus-off', this.removeBus) - console.log(E.hasBus('doesnt exist'), E.debugDelegated()) - } + console.log(E.hasBus('doesnt exist'), E.debugDelegated()) + } - delegatedMouseEnter() { + delegatedMouseEnter() { console.log('delegated mouse enter') } @@ -44,42 +47,56 @@ class Foo { console.log('delegated mouse leave') } - one() { + one() { console.log('one!') } - onceHandler(e) { - console.log('delegated event target test', e) - } + onceHandler(e) { + console.log('delegated event target test', e) + } + + eventHandler(e) { + console.log('Dom event test', e) + } + + delegateHandler(e) { + console.log('delegated nested event target test', e) + } + + removalTest1() { + console.log('removal test 1') + E.off('event.bus.removal', this.removalTest1) + } - eventHandler(e) { - console.log('Dom event test', e) - } + removalTest2() { + console.log('removal test 2') + } - delegateHandler(e) { - console.log('delegated nested event target test', e) - } + removalTest3() { + console.log('removal test 3') + } - triggerBus() { - console.log('triggering event.bus.event event') - E.emit('event.bus.event', 'one', 2) - E.emit('event.bus.event2', 'two', 2) - } + triggerBus() { + console.log('triggering event.bus.event event') + E.emit('event.bus.event', 'one', 2) + E.emit('event.bus.event2', 'two', 2) + E.emit('event.bus.removal') + } - removeBus() { - console.log('bus off') - E.off('event.bus.event', this.listener) - } + removeBus() { + console.log('bus off') + E.off('event.bus.event', this.listener) + } - listener(arg1, arg2) { - console.log('Triggered via the event bus!', arg1, arg2) - } + listener(arg1, arg2) { + console.log('Triggered via the event bus!', arg1, arg2) + } - offHandler = () => { - E.off('click', btn, this.onceHandler) - E.off('click', '#btn3', this.onceHandler) + offHandler = () => { + E.off('click', btn, this.onceHandler) + E.off('click', '#btn3', this.onceHandler) E.off('click', '#btnone', this.one) - } + } } let bar = new Foo() diff --git a/src/e.js b/src/e.js index 1642c12..8096608 100644 --- a/src/e.js +++ b/src/e.js @@ -44,7 +44,7 @@ class E { for (let i = 0; i < events.length; i++) { if (typeof el === 'function' && callback === undefined) { makeBusStack(events[i]) - listeners[events[i]].push(el) + listeners[events[i]].add(el) continue } @@ -102,18 +102,13 @@ class E { for (let i = 0; i < events.length; i++) { if (el === undefined) { - listeners[events[i]] = [] + listeners[events[i]]?.clear() continue } if (typeof el === 'function') { makeBusStack(events[i]) - - for (let n = 0; n < listeners[events[i]].length; n++) { - if (listeners[events[i]][n] === el) { - listeners[events[i]].splice(n, 1) - } - } + listeners[events[i]].delete(el) continue } diff --git a/src/utils.js b/src/utils.js index 2d3a885..3ea0f76 100644 --- a/src/utils.js +++ b/src/utils.js @@ -23,7 +23,7 @@ const nonBubblers = ['mouseenter', 'mouseleave', 'pointerenter', 'pointerleave', */ function makeBusStack(event) { if (listeners[event] === undefined) { - listeners[event] = [] + listeners[event] = new Set() } } @@ -35,9 +35,9 @@ function makeBusStack(event) { */ function triggerBus(event, args) { if (listeners[event]) { - for (let i = 0; i < listeners[event].length; i++) { - listeners[event][i](...args) - } + listeners[event].forEach(cb => { + cb(...args) + }) } } From 8f51f622f48bb06502b2df44c11788db0f01971d Mon Sep 17 00:00:00 2001 From: Jake Whiteley Date: Mon, 23 Oct 2023 18:43:14 +0100 Subject: [PATCH 2/3] build release --- dist/e.umd.js | 109 +++++++++++++++++++++++++++++++++-------------- examples/test.js | 2 + package.json | 2 +- src/e.d.ts | 4 +- src/e.js | 2 +- 5 files changed, 83 insertions(+), 36 deletions(-) diff --git a/dist/e.umd.js b/dist/e.umd.js index cf5dfef..f3f494f 100644 --- a/dist/e.umd.js +++ b/dist/e.umd.js @@ -7,7 +7,7 @@ exports["E"] = factory(); else root["E"] = factory(); -})(self, () => { +})(self, function() { return /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ @@ -20,56 +20,63 @@ return /******/ (() => { // webpackBootstrap __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ clone: () => (/* binding */ clone), -/* harmony export */ eventTypes: () => (/* binding */ eventTypes), -/* harmony export */ handleDelegation: () => (/* binding */ handleDelegation), -/* harmony export */ listeners: () => (/* binding */ listeners), -/* harmony export */ makeBusStack: () => (/* binding */ makeBusStack), -/* harmony export */ maybeRunQuerySelector: () => (/* binding */ maybeRunQuerySelector), -/* harmony export */ nonBubblers: () => (/* binding */ nonBubblers), -/* harmony export */ triggerBus: () => (/* binding */ triggerBus) +/* harmony export */ "eventTypes": () => (/* binding */ eventTypes), +/* harmony export */ "listeners": () => (/* binding */ listeners), +/* harmony export */ "nonBubblers": () => (/* binding */ nonBubblers), +/* harmony export */ "makeBusStack": () => (/* binding */ makeBusStack), +/* harmony export */ "triggerBus": () => (/* binding */ triggerBus), +/* harmony export */ "maybeRunQuerySelector": () => (/* binding */ maybeRunQuerySelector), +/* harmony export */ "handleDelegation": () => (/* binding */ handleDelegation), +/* harmony export */ "clone": () => (/* binding */ clone) /* harmony export */ }); function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } + function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } + function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } + function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + /** * Holds the SelectorSets for each event type * @type {{}} */ var eventTypes = {}; - /** * Holds Bus event stacks * @type {{}} */ -var listeners = {}; +var listeners = {}; /** * Events that don't bubble * @type {string[]} */ -var nonBubblers = ['mouseenter', 'mouseleave', 'pointerenter', 'pointerleave', 'blur', 'focus']; +var nonBubblers = ['mouseenter', 'mouseleave', 'pointerenter', 'pointerleave', 'blur', 'focus']; /** * Make a bus stack if not already created. * * @param {string} event */ + function makeBusStack(event) { if (listeners[event] === undefined) { listeners[event] = new Set(); } } - /** * Trigger a bus stack. * * @param {string} event * @param args */ + + function triggerBus(event, args) { if (listeners[event]) { listeners[event].forEach(function (cb) { @@ -77,29 +84,33 @@ function triggerBus(event, args) { }); } } - /** * Maybe run querySelectorAll if input is a string. * * @param {HTMLElement|Element|string} el * @returns {NodeListOf} */ + + function maybeRunQuerySelector(el) { return typeof el === 'string' ? document.querySelectorAll(el) : el; } - /** * Handle delegated events * * @param {Event} e */ + + function handleDelegation(e) { var matches = traverse(eventTypes[e.type], e.target); + if (matches.length) { for (var i = 0; i < matches.length; i++) { for (var i2 = 0; i2 < matches[i].stack.length; i2++) { if (nonBubblers.indexOf(e.type) !== -1) { addDelegateTarget(e, matches[i].delegatedTarget); + if (e.target === matches[i].delegatedTarget) { matches[i].stack[i2].data(e); } @@ -111,7 +122,6 @@ function handleDelegation(e) { } } } - /** * Find a matching selector for delegation * @@ -119,14 +129,19 @@ function handleDelegation(e) { * @param {HTMLElement|Element|EventTarget} target * @returns {[]} */ + + function traverse(listeners, target) { var queue = []; var node = target; + do { if (node.nodeType !== 1) { break; } + var matches = listeners.matches(node); + if (matches.length) { queue.push({ delegatedTarget: node, @@ -134,15 +149,17 @@ function traverse(listeners, target) { }); } } while (node = node.parentElement); + return queue; } - /** * Add delegatedTarget attribute to dispatched delegated events * * @param {Event} event * @param {HTMLElement|Element} delegatedTarget */ + + function addDelegateTarget(event, delegatedTarget) { Object.defineProperty(event, 'currentTarget', { configurable: true, @@ -152,22 +169,26 @@ function addDelegateTarget(event, delegatedTarget) { } }); } - /** * Creates a deep clone of an object. * * @param object * @returns {Object.} */ + + function clone(object) { var copy = {}; + for (var key in object) { copy[key] = _toConsumableArray(object[key]); } + return copy; } + /***/ }), /***/ "./node_modules/selector-set/selector-set.next.js": @@ -691,22 +712,23 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ }); /* harmony import */ var selector_set__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! selector-set */ "./node_modules/selector-set/selector-set.next.js"); /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/utils.js"); -function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } -function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } -function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /** * Public API */ + var E = /*#__PURE__*/function () { function E() { _classCallCheck(this, E); } + _createClass(E, [{ key: "bindAll", value: @@ -720,40 +742,44 @@ var E = /*#__PURE__*/function () { if (!methods) { methods = Object.getOwnPropertyNames(Object.getPrototypeOf(context)); } + for (var i = 0; i < methods.length; i++) { context[methods[i]] = context[methods[i]].bind(context); } } - /** * Bind event to a string, NodeList, or element. * * @param {string} event - * @param {string|NodeList|HTMLElement|HTMLElement[]|Window|Document|function} el + * @param {string|NodeList|NodeListOf|HTMLElement|HTMLElement[]|Window|Document|function} el * @param {*} [callback] * @param {{}|boolean} [options] */ + }, { key: "on", value: function on(event, el, callback, options) { var events = event.split(' '); + for (var i = 0; i < events.length; i++) { if (typeof el === 'function' && callback === undefined) { (0,_utils__WEBPACK_IMPORTED_MODULE_1__.makeBusStack)(events[i]); _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]].add(el); continue; } + if (el.nodeType && el.nodeType === 1 || el === window || el === document) { el.addEventListener(events[i], callback, options); continue; } + el = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.maybeRunQuerySelector)(el); + for (var n = 0; n < el.length; n++) { el[n].addEventListener(events[i], callback, options); } } } - /** * Add a delegated event. * @@ -761,25 +787,29 @@ var E = /*#__PURE__*/function () { * @param {string|NodeList|HTMLElement|Element} delegate * @param {*} [callback] */ + }, { key: "delegate", value: function delegate(event, _delegate, callback) { var events = event.split(' '); + for (var i = 0; i < events.length; i++) { var map = _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; + if (map === undefined) { map = new selector_set__WEBPACK_IMPORTED_MODULE_0__["default"](); _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]] = map; + if (_utils__WEBPACK_IMPORTED_MODULE_1__.nonBubblers.indexOf(events[i]) !== -1) { document.addEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation, true); } else { document.addEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation); } } + map.add(_delegate, callback); } } - /** * Remove a callback from a DOM element, or one or all Bus events. * @@ -788,96 +818,111 @@ var E = /*#__PURE__*/function () { * @param {*} [callback] * @param {{}|boolean} [options] */ + }, { key: "off", value: function off(event, el, callback, options) { var events = event.split(' '); + for (var i = 0; i < events.length; i++) { if (el === undefined) { var _listeners$events$i; - (_listeners$events$i = _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]]) === null || _listeners$events$i === void 0 || _listeners$events$i.clear(); + + (_listeners$events$i = _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]]) === null || _listeners$events$i === void 0 ? void 0 : _listeners$events$i.clear(); continue; } + if (typeof el === 'function') { (0,_utils__WEBPACK_IMPORTED_MODULE_1__.makeBusStack)(events[i]); _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]]["delete"](el); continue; } + var map = _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; + if (map !== undefined) { map.remove(el, callback); + if (map.size === 0) { delete _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; + if (_utils__WEBPACK_IMPORTED_MODULE_1__.nonBubblers.indexOf(events[i]) !== -1) { document.removeEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation, true); } else { document.removeEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation); } + continue; } } + if (el.removeEventListener !== undefined) { el.removeEventListener(events[i], callback, options); continue; } + el = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.maybeRunQuerySelector)(el); + for (var n = 0; n < el.length; n++) { el[n].removeEventListener(events[i], callback, options); } } } - /** * Emit a Bus event. * * @param {string} event * @param {...*} args */ + }, { key: "emit", value: function emit(event) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } + (0,_utils__WEBPACK_IMPORTED_MODULE_1__.triggerBus)(event, args); } - /** * Return a clone of the delegated event stack for debugging. * * @returns {Object.} */ + }, { key: "debugDelegated", value: function debugDelegated() { return JSON.parse(JSON.stringify(_utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes)); } - /** * Return a clone of the bus event stack for debugging. * * @returns {Object.} */ + }, { key: "debugBus", value: function debugBus() { return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.clone)(_utils__WEBPACK_IMPORTED_MODULE_1__.listeners); } - /** * Checks if a given bus event has listeners. * * @param {string} event * @returns {boolean} */ + }, { key: "hasBus", value: function hasBus(event) { return this.debugBus().hasOwnProperty(event); } }]); + return E; }(); + var instance = new E(); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (instance); })(); diff --git a/examples/test.js b/examples/test.js index ddb2de2..19b1b3d 100644 --- a/examples/test.js +++ b/examples/test.js @@ -37,6 +37,7 @@ class Foo { E.on('click', '#bus-off', this.removeBus) console.log(E.hasBus('doesnt exist'), E.debugDelegated()) + console.log(E.debugBus()) } delegatedMouseEnter() { @@ -86,6 +87,7 @@ class Foo { removeBus() { console.log('bus off') E.off('event.bus.event', this.listener) + E.off('event.bus.imaginary') } listener(arg1, arg2) { diff --git a/package.json b/package.json index 0dfc11b..7d03a6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@unseenco/e", - "version": "2.3.0", + "version": "2.4.0", "description": "The complete (but tiny) js events solution - An event bus/emitter, simple DOM event API, and incredibly efficient delegated events.", "keywords": [ "eventbus", diff --git a/src/e.d.ts b/src/e.d.ts index 24d25c9..1b08c1f 100644 --- a/src/e.d.ts +++ b/src/e.d.ts @@ -15,11 +15,11 @@ declare class E { * Bind event to a string, NodeList, or element. * * @param {string} event - * @param {string|NodeList|HTMLElement|HTMLElement[]|Window|Document|function} el + * @param {string|NodeList|NodeListOf|HTMLElement|HTMLElement[]|Window|Document|function} el * @param {*} [callback] * @param {{}|boolean} [options] */ - on(event: string, el: string | NodeList | HTMLElement | HTMLElement[] | Window | Document | Function, callback?: any, options?: {} | boolean): void; + on(event: string, el: string | NodeList | NodeListOf | HTMLElement | HTMLElement[] | Window | Document | Function, callback?: any, options?: {} | boolean): void; /** * Add a delegated event. * diff --git a/src/e.js b/src/e.js index 8096608..2649c9d 100644 --- a/src/e.js +++ b/src/e.js @@ -34,7 +34,7 @@ class E { * Bind event to a string, NodeList, or element. * * @param {string} event - * @param {string|NodeList|HTMLElement|HTMLElement[]|Window|Document|function} el + * @param {string|NodeList|NodeListOf|HTMLElement|HTMLElement[]|Window|Document|function} el * @param {*} [callback] * @param {{}|boolean} [options] */ From 893db33e9935f50136e618570cb1c6bb2f0f4f50 Mon Sep 17 00:00:00 2001 From: Jake Whiteley Date: Mon, 23 Oct 2023 18:44:16 +0100 Subject: [PATCH 3/3] minify dist/e.umd.js --- dist/e.umd.js | 934 +------------------------------------------------- 1 file changed, 1 insertion(+), 933 deletions(-) diff --git a/dist/e.umd.js b/dist/e.umd.js index f3f494f..5790c16 100644 --- a/dist/e.umd.js +++ b/dist/e.umd.js @@ -1,933 +1 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define("E", [], factory); - else if(typeof exports === 'object') - exports["E"] = factory(); - else - root["E"] = factory(); -})(self, function() { -return /******/ (() => { // webpackBootstrap -/******/ "use strict"; -/******/ var __webpack_modules__ = ({ - -/***/ "./src/utils.js": -/*!**********************!*\ - !*** ./src/utils.js ***! - \**********************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "eventTypes": () => (/* binding */ eventTypes), -/* harmony export */ "listeners": () => (/* binding */ listeners), -/* harmony export */ "nonBubblers": () => (/* binding */ nonBubblers), -/* harmony export */ "makeBusStack": () => (/* binding */ makeBusStack), -/* harmony export */ "triggerBus": () => (/* binding */ triggerBus), -/* harmony export */ "maybeRunQuerySelector": () => (/* binding */ maybeRunQuerySelector), -/* harmony export */ "handleDelegation": () => (/* binding */ handleDelegation), -/* harmony export */ "clone": () => (/* binding */ clone) -/* harmony export */ }); -function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } - -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } - -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - -/** - * Holds the SelectorSets for each event type - * @type {{}} - */ -var eventTypes = {}; -/** - * Holds Bus event stacks - * @type {{}} - */ - -var listeners = {}; -/** - * Events that don't bubble - * @type {string[]} - */ - -var nonBubblers = ['mouseenter', 'mouseleave', 'pointerenter', 'pointerleave', 'blur', 'focus']; -/** - * Make a bus stack if not already created. - * - * @param {string} event - */ - -function makeBusStack(event) { - if (listeners[event] === undefined) { - listeners[event] = new Set(); - } -} -/** - * Trigger a bus stack. - * - * @param {string} event - * @param args - */ - - -function triggerBus(event, args) { - if (listeners[event]) { - listeners[event].forEach(function (cb) { - cb.apply(void 0, _toConsumableArray(args)); - }); - } -} -/** - * Maybe run querySelectorAll if input is a string. - * - * @param {HTMLElement|Element|string} el - * @returns {NodeListOf} - */ - - -function maybeRunQuerySelector(el) { - return typeof el === 'string' ? document.querySelectorAll(el) : el; -} -/** - * Handle delegated events - * - * @param {Event} e - */ - - -function handleDelegation(e) { - var matches = traverse(eventTypes[e.type], e.target); - - if (matches.length) { - for (var i = 0; i < matches.length; i++) { - for (var i2 = 0; i2 < matches[i].stack.length; i2++) { - if (nonBubblers.indexOf(e.type) !== -1) { - addDelegateTarget(e, matches[i].delegatedTarget); - - if (e.target === matches[i].delegatedTarget) { - matches[i].stack[i2].data(e); - } - } else { - addDelegateTarget(e, matches[i].delegatedTarget); - matches[i].stack[i2].data(e); - } - } - } - } -} -/** - * Find a matching selector for delegation - * - * @param {SelectorSet} listeners - * @param {HTMLElement|Element|EventTarget} target - * @returns {[]} - */ - - -function traverse(listeners, target) { - var queue = []; - var node = target; - - do { - if (node.nodeType !== 1) { - break; - } - - var matches = listeners.matches(node); - - if (matches.length) { - queue.push({ - delegatedTarget: node, - stack: matches - }); - } - } while (node = node.parentElement); - - return queue; -} -/** - * Add delegatedTarget attribute to dispatched delegated events - * - * @param {Event} event - * @param {HTMLElement|Element} delegatedTarget - */ - - -function addDelegateTarget(event, delegatedTarget) { - Object.defineProperty(event, 'currentTarget', { - configurable: true, - enumerable: true, - get: function get() { - return delegatedTarget; - } - }); -} -/** - * Creates a deep clone of an object. - * - * @param object - * @returns {Object.} - */ - - -function clone(object) { - var copy = {}; - - for (var key in object) { - copy[key] = _toConsumableArray(object[key]); - } - - return copy; -} - - - -/***/ }), - -/***/ "./node_modules/selector-set/selector-set.next.js": -/*!********************************************************!*\ - !*** ./node_modules/selector-set/selector-set.next.js ***! - \********************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ SelectorSet) -/* harmony export */ }); -// Public: Create a new SelectorSet. -function SelectorSet() { - // Construct new SelectorSet if called as a function. - if (!(this instanceof SelectorSet)) { - return new SelectorSet(); - } - - // Public: Number of selectors added to the set - this.size = 0; - - // Internal: Incrementing ID counter - this.uid = 0; - - // Internal: Array of String selectors in the set - this.selectors = []; - - // Internal: Map of selector ids to objects - this.selectorObjects = {}; - - // Internal: All Object index String names mapping to Index objects. - this.indexes = Object.create(this.indexes); - - // Internal: Used Object index String names mapping to Index objects. - this.activeIndexes = []; -} - -// Detect prefixed Element#matches function. -var docElem = window.document.documentElement; -var matches = - docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector; - -// Public: Check if element matches selector. -// -// Maybe overridden with custom Element.matches function. -// -// el - An Element -// selector - String CSS selector -// -// Returns true or false. -SelectorSet.prototype.matchesSelector = function(el, selector) { - return matches.call(el, selector); -}; - -// Public: Find all elements in the context that match the selector. -// -// Maybe overridden with custom querySelectorAll function. -// -// selectors - String CSS selectors. -// context - Element context -// -// Returns non-live list of Elements. -SelectorSet.prototype.querySelectorAll = function(selectors, context) { - return context.querySelectorAll(selectors); -}; - -// Public: Array of indexes. -// -// name - Unique String name -// selector - Function that takes a String selector and returns a String key -// or undefined if it can't be used by the index. -// element - Function that takes an Element and returns an Array of String -// keys that point to indexed values. -// -SelectorSet.prototype.indexes = []; - -// Index by element id -var idRe = /^#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; -SelectorSet.prototype.indexes.push({ - name: 'ID', - selector: function matchIdSelector(sel) { - var m; - if ((m = sel.match(idRe))) { - return m[0].slice(1); - } - }, - element: function getElementId(el) { - if (el.id) { - return [el.id]; - } - } -}); - -// Index by all of its class names -var classRe = /^\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; -SelectorSet.prototype.indexes.push({ - name: 'CLASS', - selector: function matchClassSelector(sel) { - var m; - if ((m = sel.match(classRe))) { - return m[0].slice(1); - } - }, - element: function getElementClassNames(el) { - var className = el.className; - if (className) { - if (typeof className === 'string') { - return className.split(/\s/); - } else if (typeof className === 'object' && 'baseVal' in className) { - // className is a SVGAnimatedString - // global SVGAnimatedString is not an exposed global in Opera 12 - return className.baseVal.split(/\s/); - } - } - } -}); - -// Index by tag/node name: `DIV`, `FORM`, `A` -var tagRe = /^((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; -SelectorSet.prototype.indexes.push({ - name: 'TAG', - selector: function matchTagSelector(sel) { - var m; - if ((m = sel.match(tagRe))) { - return m[0].toUpperCase(); - } - }, - element: function getElementTagName(el) { - return [el.nodeName.toUpperCase()]; - } -}); - -// Default index just contains a single array of elements. -SelectorSet.prototype.indexes['default'] = { - name: 'UNIVERSAL', - selector: function() { - return true; - }, - element: function() { - return [true]; - } -}; - -// Use ES Maps when supported -var Map; -if (typeof window.Map === 'function') { - Map = window.Map; -} else { - Map = (function() { - function Map() { - this.map = {}; - } - Map.prototype.get = function(key) { - return this.map[key + ' ']; - }; - Map.prototype.set = function(key, value) { - this.map[key + ' '] = value; - }; - return Map; - })(); -} - -// Regexps adopted from Sizzle -// https://github.com/jquery/sizzle/blob/1.7/sizzle.js -// -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; - -// Internal: Get indexes for selector. -// -// selector - String CSS selector -// -// Returns Array of {index, key}. -function parseSelectorIndexes(allIndexes, selector) { - allIndexes = allIndexes.slice(0).concat(allIndexes['default']); - - var allIndexesLen = allIndexes.length, - i, - j, - m, - dup, - rest = selector, - key, - index, - indexes = []; - - do { - chunker.exec(''); - if ((m = chunker.exec(rest))) { - rest = m[3]; - if (m[2] || !rest) { - for (i = 0; i < allIndexesLen; i++) { - index = allIndexes[i]; - if ((key = index.selector(m[1]))) { - j = indexes.length; - dup = false; - while (j--) { - if (indexes[j].index === index && indexes[j].key === key) { - dup = true; - break; - } - } - if (!dup) { - indexes.push({ index: index, key: key }); - } - break; - } - } - } - } - } while (m); - - return indexes; -} - -// Internal: Find first item in Array that is a prototype of `proto`. -// -// ary - Array of objects -// proto - Prototype of expected item in `ary` -// -// Returns object from `ary` if found. Otherwise returns undefined. -function findByPrototype(ary, proto) { - var i, len, item; - for (i = 0, len = ary.length; i < len; i++) { - item = ary[i]; - if (proto.isPrototypeOf(item)) { - return item; - } - } -} - -// Public: Log when added selector falls under the default index. -// -// This API should not be considered stable. May change between -// minor versions. -// -// obj - {selector, data} Object -// -// SelectorSet.prototype.logDefaultIndexUsed = function(obj) { -// console.warn(obj.selector, "could not be indexed"); -// }; -// -// Returns nothing. -SelectorSet.prototype.logDefaultIndexUsed = function() {}; - -// Public: Add selector to set. -// -// selector - String CSS selector -// data - Optional data Object (default: undefined) -// -// Returns nothing. -SelectorSet.prototype.add = function(selector, data) { - var obj, - i, - indexProto, - key, - index, - objs, - selectorIndexes, - selectorIndex, - indexes = this.activeIndexes, - selectors = this.selectors, - selectorObjects = this.selectorObjects; - - if (typeof selector !== 'string') { - return; - } - - obj = { - id: this.uid++, - selector: selector, - data: data - }; - selectorObjects[obj.id] = obj; - - selectorIndexes = parseSelectorIndexes(this.indexes, selector); - for (i = 0; i < selectorIndexes.length; i++) { - selectorIndex = selectorIndexes[i]; - key = selectorIndex.key; - indexProto = selectorIndex.index; - - index = findByPrototype(indexes, indexProto); - if (!index) { - index = Object.create(indexProto); - index.map = new Map(); - indexes.push(index); - } - - if (indexProto === this.indexes['default']) { - this.logDefaultIndexUsed(obj); - } - objs = index.map.get(key); - if (!objs) { - objs = []; - index.map.set(key, objs); - } - objs.push(obj); - } - - this.size++; - selectors.push(selector); -}; - -// Public: Remove selector from set. -// -// selector - String CSS selector -// data - Optional data Object (default: undefined) -// -// Returns nothing. -SelectorSet.prototype.remove = function(selector, data) { - if (typeof selector !== 'string') { - return; - } - - var selectorIndexes, - selectorIndex, - i, - j, - k, - selIndex, - objs, - obj, - indexes = this.activeIndexes, - selectors = (this.selectors = []), - selectorObjects = this.selectorObjects, - removedIds = {}, - removeAll = arguments.length === 1; - - selectorIndexes = parseSelectorIndexes(this.indexes, selector); - for (i = 0; i < selectorIndexes.length; i++) { - selectorIndex = selectorIndexes[i]; - - j = indexes.length; - while (j--) { - selIndex = indexes[j]; - if (selectorIndex.index.isPrototypeOf(selIndex)) { - objs = selIndex.map.get(selectorIndex.key); - if (objs) { - k = objs.length; - while (k--) { - obj = objs[k]; - if (obj.selector === selector && (removeAll || obj.data === data)) { - objs.splice(k, 1); - removedIds[obj.id] = true; - } - } - } - break; - } - } - } - - for (i in removedIds) { - delete selectorObjects[i]; - this.size--; - } - - for (i in selectorObjects) { - selectors.push(selectorObjects[i].selector); - } -}; - -// Sort by id property handler. -// -// a - Selector obj. -// b - Selector obj. -// -// Returns Number. -function sortById(a, b) { - return a.id - b.id; -} - -// Public: Find all matching decendants of the context element. -// -// context - An Element -// -// Returns Array of {selector, data, elements} matches. -SelectorSet.prototype.queryAll = function(context) { - if (!this.selectors.length) { - return []; - } - - var matches = {}, - results = []; - var els = this.querySelectorAll(this.selectors.join(', '), context); - - var i, j, len, len2, el, m, match, obj; - for (i = 0, len = els.length; i < len; i++) { - el = els[i]; - m = this.matches(el); - for (j = 0, len2 = m.length; j < len2; j++) { - obj = m[j]; - if (!matches[obj.id]) { - match = { - id: obj.id, - selector: obj.selector, - data: obj.data, - elements: [] - }; - matches[obj.id] = match; - results.push(match); - } else { - match = matches[obj.id]; - } - match.elements.push(el); - } - } - - return results.sort(sortById); -}; - -// Public: Match element against all selectors in set. -// -// el - An Element -// -// Returns Array of {selector, data} matches. -SelectorSet.prototype.matches = function(el) { - if (!el) { - return []; - } - - var i, j, k, len, len2, len3, index, keys, objs, obj, id; - var indexes = this.activeIndexes, - matchedIds = {}, - matches = []; - - for (i = 0, len = indexes.length; i < len; i++) { - index = indexes[i]; - keys = index.element(el); - if (keys) { - for (j = 0, len2 = keys.length; j < len2; j++) { - if ((objs = index.map.get(keys[j]))) { - for (k = 0, len3 = objs.length; k < len3; k++) { - obj = objs[k]; - id = obj.id; - if (!matchedIds[id] && this.matchesSelector(el, obj.selector)) { - matchedIds[id] = true; - matches.push(obj); - } - } - } - } - } - } - - return matches.sort(sortById); -}; - - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. -(() => { -/*!******************!*\ - !*** ./src/e.js ***! - \******************/ -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); -/* harmony import */ var selector_set__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! selector-set */ "./node_modules/selector-set/selector-set.next.js"); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/utils.js"); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } - - - -/** - * Public API - */ - -var E = /*#__PURE__*/function () { - function E() { - _classCallCheck(this, E); - } - - _createClass(E, [{ - key: "bindAll", - value: - /** - * Binds all provided methods to a provided context. - * - * @param {object} context - * @param {string[]} [methods] Optional. - */ - function bindAll(context, methods) { - if (!methods) { - methods = Object.getOwnPropertyNames(Object.getPrototypeOf(context)); - } - - for (var i = 0; i < methods.length; i++) { - context[methods[i]] = context[methods[i]].bind(context); - } - } - /** - * Bind event to a string, NodeList, or element. - * - * @param {string} event - * @param {string|NodeList|NodeListOf|HTMLElement|HTMLElement[]|Window|Document|function} el - * @param {*} [callback] - * @param {{}|boolean} [options] - */ - - }, { - key: "on", - value: function on(event, el, callback, options) { - var events = event.split(' '); - - for (var i = 0; i < events.length; i++) { - if (typeof el === 'function' && callback === undefined) { - (0,_utils__WEBPACK_IMPORTED_MODULE_1__.makeBusStack)(events[i]); - _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]].add(el); - continue; - } - - if (el.nodeType && el.nodeType === 1 || el === window || el === document) { - el.addEventListener(events[i], callback, options); - continue; - } - - el = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.maybeRunQuerySelector)(el); - - for (var n = 0; n < el.length; n++) { - el[n].addEventListener(events[i], callback, options); - } - } - } - /** - * Add a delegated event. - * - * @param {string} event - * @param {string|NodeList|HTMLElement|Element} delegate - * @param {*} [callback] - */ - - }, { - key: "delegate", - value: function delegate(event, _delegate, callback) { - var events = event.split(' '); - - for (var i = 0; i < events.length; i++) { - var map = _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; - - if (map === undefined) { - map = new selector_set__WEBPACK_IMPORTED_MODULE_0__["default"](); - _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]] = map; - - if (_utils__WEBPACK_IMPORTED_MODULE_1__.nonBubblers.indexOf(events[i]) !== -1) { - document.addEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation, true); - } else { - document.addEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation); - } - } - - map.add(_delegate, callback); - } - } - /** - * Remove a callback from a DOM element, or one or all Bus events. - * - * @param {string} event - * @param {string|NodeList|HTMLElement|Element|Window|undefined} [el] - * @param {*} [callback] - * @param {{}|boolean} [options] - */ - - }, { - key: "off", - value: function off(event, el, callback, options) { - var events = event.split(' '); - - for (var i = 0; i < events.length; i++) { - if (el === undefined) { - var _listeners$events$i; - - (_listeners$events$i = _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]]) === null || _listeners$events$i === void 0 ? void 0 : _listeners$events$i.clear(); - continue; - } - - if (typeof el === 'function') { - (0,_utils__WEBPACK_IMPORTED_MODULE_1__.makeBusStack)(events[i]); - _utils__WEBPACK_IMPORTED_MODULE_1__.listeners[events[i]]["delete"](el); - continue; - } - - var map = _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; - - if (map !== undefined) { - map.remove(el, callback); - - if (map.size === 0) { - delete _utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes[events[i]]; - - if (_utils__WEBPACK_IMPORTED_MODULE_1__.nonBubblers.indexOf(events[i]) !== -1) { - document.removeEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation, true); - } else { - document.removeEventListener(events[i], _utils__WEBPACK_IMPORTED_MODULE_1__.handleDelegation); - } - - continue; - } - } - - if (el.removeEventListener !== undefined) { - el.removeEventListener(events[i], callback, options); - continue; - } - - el = (0,_utils__WEBPACK_IMPORTED_MODULE_1__.maybeRunQuerySelector)(el); - - for (var n = 0; n < el.length; n++) { - el[n].removeEventListener(events[i], callback, options); - } - } - } - /** - * Emit a Bus event. - * - * @param {string} event - * @param {...*} args - */ - - }, { - key: "emit", - value: function emit(event) { - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - (0,_utils__WEBPACK_IMPORTED_MODULE_1__.triggerBus)(event, args); - } - /** - * Return a clone of the delegated event stack for debugging. - * - * @returns {Object.} - */ - - }, { - key: "debugDelegated", - value: function debugDelegated() { - return JSON.parse(JSON.stringify(_utils__WEBPACK_IMPORTED_MODULE_1__.eventTypes)); - } - /** - * Return a clone of the bus event stack for debugging. - * - * @returns {Object.} - */ - - }, { - key: "debugBus", - value: function debugBus() { - return (0,_utils__WEBPACK_IMPORTED_MODULE_1__.clone)(_utils__WEBPACK_IMPORTED_MODULE_1__.listeners); - } - /** - * Checks if a given bus event has listeners. - * - * @param {string} event - * @returns {boolean} - */ - - }, { - key: "hasBus", - value: function hasBus(event) { - return this.debugBus().hasOwnProperty(event); - } - }]); - - return E; -}(); - -var instance = new E(); -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (instance); -})(); - -/******/ return __webpack_exports__; -/******/ })() -; -}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("E",[],t):"object"==typeof exports?exports.E=t():e.E=t()}(self,(function(){return(()=>{"use strict";var e={d:(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};function n(){if(!(this instanceof n))return new n;this.size=0,this.uid=0,this.selectors=[],this.selectorObjects={},this.indexes=Object.create(this.indexes),this.activeIndexes=[]}e.r(t),e.d(t,{default:()=>k});var r=window.document.documentElement,o=r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.oMatchesSelector||r.msMatchesSelector;n.prototype.matchesSelector=function(e,t){return o.call(e,t)},n.prototype.querySelectorAll=function(e,t){return t.querySelectorAll(e)},n.prototype.indexes=[];var i=/^#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g;n.prototype.indexes.push({name:"ID",selector:function(e){var t;if(t=e.match(i))return t[0].slice(1)},element:function(e){if(e.id)return[e.id]}});var a=/^\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g;n.prototype.indexes.push({name:"CLASS",selector:function(e){var t;if(t=e.match(a))return t[0].slice(1)},element:function(e){var t=e.className;if(t){if("string"==typeof t)return t.split(/\s/);if("object"==typeof t&&"baseVal"in t)return t.baseVal.split(/\s/)}}});var s,u=/^((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g;n.prototype.indexes.push({name:"TAG",selector:function(e){var t;if(t=e.match(u))return t[0].toUpperCase()},element:function(e){return[e.nodeName.toUpperCase()]}}),n.prototype.indexes.default={name:"UNIVERSAL",selector:function(){return!0},element:function(){return[!0]}},s="function"==typeof window.Map?window.Map:function(){function e(){this.map={}}return e.prototype.get=function(e){return this.map[e+" "]},e.prototype.set=function(e,t){this.map[e+" "]=t},e}();var l=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g;function c(e,t){var n,r,o,i,a,s,u=(e=e.slice(0).concat(e.default)).length,c=t,f=[];do{if(l.exec(""),(o=l.exec(c))&&(c=o[3],o[2]||!c))for(n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n1?t-1:0),r=1;r