From ec81f4400a6bc1d48e75705a6a8089f6cf6207c8 Mon Sep 17 00:00:00 2001 From: Scott Busche Date: Sat, 9 Oct 2021 16:43:33 -0500 Subject: [PATCH 1/4] Add TSDoc for `options` parameter (#27) --- index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.ts b/index.ts index 05e9cd6..14cca15 100644 --- a/index.ts +++ b/index.ts @@ -82,6 +82,7 @@ function safeClosest(event: Event, selector: string): Element | void { /** * Delegates event to a selector. + * @param options A boolean value setting options.capture or an options object of type AddEventListenerOptions */ function delegate< Selector extends string, From 00817425c73fef3c024176c2c69728e103d7fde9 Mon Sep 17 00:00:00 2001 From: Florent Date: Fri, 13 May 2022 15:41:08 +0200 Subject: [PATCH 2/4] Ignore unsupported `once` option (#29) --- index.ts | 15 +++++++++++---- readme.md | 17 +++++++++++++++++ test.js | 9 +++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/index.ts b/index.ts index 14cca15..0bd1de6 100644 --- a/index.ts +++ b/index.ts @@ -1,5 +1,7 @@ import type {ParseSelector} from 'typed-query-selector/parser'; +// eslint-disable-next-line @typescript-eslint/ban-types -- It's a single property, no mistakes possible +export type DelegateOptions = boolean | Omit; export type EventType = keyof GlobalEventHandlersEventMap; type GlobalEvent = Event; @@ -82,7 +84,7 @@ function safeClosest(event: Event, selector: string): Element | void { /** * Delegates event to a selector. - * @param options A boolean value setting options.capture or an options object of type AddEventListenerOptions + * @param options A boolean value setting options.capture or an options object of type AddEventListenerOptions without the `once` option */ function delegate< Selector extends string, @@ -93,7 +95,7 @@ function delegate< selector: Selector, type: TEventType, callback: delegate.EventHandler, - options?: boolean | AddEventListenerOptions + options?: DelegateOptions ): delegate.Subscription; function delegate< @@ -104,7 +106,7 @@ function delegate< selector: string, type: TEventType, callback: delegate.EventHandler, - options?: boolean | AddEventListenerOptions + options?: DelegateOptions ): delegate.Subscription; // This type isn't exported as a declaration, so it needs to be duplicated above @@ -116,7 +118,7 @@ function delegate< selector: string, type: TEventType, callback: delegate.EventHandler, - options?: boolean | AddEventListenerOptions + options?: DelegateOptions ): delegate.Subscription { // Handle Selector-based usage if (typeof base === 'string') { @@ -160,6 +162,11 @@ function delegate< } }; + // Drop unsupported `once` option https://github.com/fregante/delegate-it/pull/28#discussion_r863467939 + if (typeof options === 'object') { + delete (options as AddEventListenerOptions).once; + } + const setup = JSON.stringify({selector, type, capture}); const isAlreadyListening = editLedger(true, baseElement, callback, setup); const delegateSubscription = { diff --git a/readme.md b/readme.md index 7ea625a..4b292ea 100644 --- a/readme.md +++ b/readme.md @@ -52,6 +52,23 @@ delegate(document.querySelectorAll('.container'), '.btn', 'click', event => { }); ``` +#### With listener options + +```js +delegate(document.body, '.btn', 'click', event => { + console.log(event.delegateTarget); +}, true); + +// Or equivalent: +delegate(document.body, '.btn', 'click', event => { + console.log(event.delegateTarget); +}, { + capture: true +}); +``` + +**Note:** the `once` option is currently not supported. + ### Remove event delegation ```js diff --git a/test.js b/test.js index cee71e8..a5c6321 100644 --- a/test.js +++ b/test.js @@ -123,3 +123,12 @@ test.serial('should not fire when the selector matches an ancestor of the base e anchor.click(); t.true(spy.notCalled); }); + +test.serial('should not consider the `once` option', t => { + const spy = sinon.spy(); + delegate(container, 'a', 'click', spy, {once: true}); + + anchor.click(); + anchor.click(); + t.true(spy.calledTwice); +}); From 9bbdb156f58b67ae369aa9594a1299e177dd9fbb Mon Sep 17 00:00:00 2001 From: Federico Brigante Date: Fri, 13 May 2022 22:49:22 +0800 Subject: [PATCH 3/4] Update dev dependencies + lint --- index.ts | 43 ++++++++++++++++++++----------------------- package.json | 19 +++++++++---------- test.js | 13 +++---------- 3 files changed, 32 insertions(+), 43 deletions(-) diff --git a/index.ts b/index.ts index 0bd1de6..2c4a553 100644 --- a/index.ts +++ b/index.ts @@ -1,6 +1,5 @@ import type {ParseSelector} from 'typed-query-selector/parser'; -// eslint-disable-next-line @typescript-eslint/ban-types -- It's a single property, no mistakes possible export type DelegateOptions = boolean | Omit; export type EventType = keyof GlobalEventHandlersEventMap; type GlobalEvent = Event; @@ -12,12 +11,12 @@ namespace delegate { export type EventHandler< TEvent extends GlobalEvent = GlobalEvent, - TElement extends Element = Element + TElement extends Element = Element, > = (event: Event) => void; export type Event< TEvent extends GlobalEvent = GlobalEvent, - TElement extends Element = Element + TElement extends Element = Element, > = TEvent & { delegateTarget: TElement; }; @@ -33,15 +32,15 @@ function editLedger( wanted: boolean, baseElement: EventTarget | Document, callback: delegate.EventHandler, - setup: string + setup: string, ): boolean { if (!wanted && !ledger.has(baseElement)) { return false; } - const elementMap = - ledger.get(baseElement) ?? - new WeakMap>(); + const elementMap + = ledger.get(baseElement) + ?? new WeakMap>(); ledger.set(baseElement, elementMap); if (!wanted && !ledger.has(baseElement)) { @@ -62,7 +61,7 @@ function editLedger( } function isEventTarget( - elements: EventTarget | Document | ArrayLike | string + elements: EventTarget | Document | ArrayLike | string, ): elements is EventTarget { return typeof (elements as EventTarget).addEventListener === 'function'; } @@ -89,7 +88,7 @@ function safeClosest(event: Event, selector: string): Element | void { function delegate< Selector extends string, TElement extends Element = ParseSelector, - TEventType extends EventType = EventType + TEventType extends EventType = EventType, >( base: EventTarget | Document | ArrayLike | string, selector: Selector, @@ -100,7 +99,7 @@ function delegate< function delegate< TElement extends Element = HTMLElement, - TEventType extends EventType = EventType + TEventType extends EventType = EventType, >( base: EventTarget | Document | ArrayLike | string, selector: string, @@ -112,13 +111,13 @@ function delegate< // This type isn't exported as a declaration, so it needs to be duplicated above function delegate< TElement extends Element, - TEventType extends EventType = EventType + TEventType extends EventType = EventType, >( base: EventTarget | Document | ArrayLike | string, selector: string, type: TEventType, callback: delegate.EventHandler, - options?: DelegateOptions + options?: DelegateOptions, ): delegate.Subscription { // Handle Selector-based usage if (typeof base === 'string') { @@ -129,15 +128,13 @@ function delegate< if (!isEventTarget(base)) { const subscriptions = Array.prototype.map.call( base, - (element: EventTarget) => { - return delegate( - element, - selector, - type, - callback, - options - ); - } + (element: EventTarget) => delegate( + element, + selector, + type, + callback, + options, + ), ) as delegate.Subscription[]; return { @@ -145,7 +142,7 @@ function delegate< for (const subscription of subscriptions) { subscription.destroy(); } - } + }, }; } @@ -173,7 +170,7 @@ function delegate< destroy() { baseElement.removeEventListener(type, listenerFn, options); editLedger(false, baseElement, callback, setup); - } + }, }; if (!isAlreadyListening) { diff --git a/package.json b/package.json index f224ad6..d398eb4 100644 --- a/package.json +++ b/package.json @@ -38,22 +38,21 @@ "browser" ], "rules": { - "import/extensions": "off", - "import/no-useless-path-segments": "off", "max-params": "off", - "unicorn/import-index": "off" + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/naming-convention": "off" } }, "dependencies": { - "typed-query-selector": "^2.4.1" + "typed-query-selector": "^2.6.1" }, "devDependencies": { - "@sindresorhus/tsconfig": "^1.0.1", - "ava": "^3.15.0", - "jsdom": "^16.5.2", + "@sindresorhus/tsconfig": "^2.0.0", + "ava": "^4.2.0", + "jsdom": "^19.0.0", "npm-run-all": "^4.1.5", - "sinon": "^10.0.0", - "typescript": "^4.2.4", - "xo": "^0.38.2" + "sinon": "^14.0.0", + "typescript": "^4.6.4", + "xo": "^0.48.0" } } diff --git a/test.js b/test.js index a5c6321..6431658 100644 --- a/test.js +++ b/test.js @@ -1,11 +1,8 @@ import test from 'ava'; import sinon from 'sinon'; -import {createRequire} from 'module'; +import {JSDOM} from 'jsdom'; import delegate from './index.js'; -const require = createRequire(import.meta.url); -export const {JSDOM} = require('jsdom'); - const {window} = new JSDOM(`
  • Item 1
  • @@ -75,9 +72,7 @@ test.serial('should add event listeners to all the elements in a base selector', test.serial('should remove the event listeners from all the elements in a base selector', t => { const items = document.querySelectorAll('li'); - const spies = Array.prototype.map.call(items, li => { - return sinon.spy(li, 'removeEventListener'); - }); + const spies = Array.prototype.map.call(items, li => sinon.spy(li, 'removeEventListener')); const delegation = delegate('li', 'a', 'click', () => {}); delegation.destroy(); @@ -102,9 +97,7 @@ test.serial('should add event listeners to all the elements in a base array', t test.serial('should remove the event listeners from all the elements in a base array', t => { const items = document.querySelectorAll('li'); - const spies = Array.prototype.map.call(items, li => { - return sinon.spy(li, 'removeEventListener'); - }); + const spies = Array.prototype.map.call(items, li => sinon.spy(li, 'removeEventListener')); const delegation = delegate(items, 'a', 'click', () => {}); delegation.destroy(); From a0a60d8ea83e3b9de9b1a7af529a7289c889895c Mon Sep 17 00:00:00 2001 From: Federico Brigante Date: Fri, 13 May 2022 22:50:01 +0800 Subject: [PATCH 4/4] 3.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d398eb4..714e5cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "delegate-it", - "version": "3.0.0", + "version": "3.0.1", "description": "Lightweight and modern event delegation in the browser", "keywords": [ "delegate",