Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

delegate-it

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

delegate-it - npm Package Compare versions

Comparing version 3.0.1 to 4.0.0

18

index.d.ts
import type { ParseSelector } from 'typed-query-selector/parser';
export declare type DelegateOptions = boolean | Omit<AddEventListenerOptions, 'once'>;
export declare type EventType = keyof GlobalEventHandlersEventMap;
declare type GlobalEvent = Event;
declare namespace delegate {
type Subscription = {
destroy: VoidFunction;
};
type EventHandler<TEvent extends GlobalEvent = GlobalEvent, TElement extends Element = Element> = (event: Event<TEvent, TElement>) => void;
type Event<TEvent extends GlobalEvent = GlobalEvent, TElement extends Element = Element> = TEvent & {
delegateTarget: TElement;
};
}
export declare type DelegateEventHandler<TEvent extends Event = Event, TElement extends Element = Element> = (event: DelegateEvent<TEvent, TElement>) => void;
export declare type DelegateEvent<TEvent extends Event = Event, TElement extends Element = Element> = TEvent & {
delegateTarget: TElement;
};
/**

@@ -18,4 +12,4 @@ * Delegates event to a selector.

*/
declare function delegate<Selector extends string, TElement extends Element = ParseSelector<Selector, HTMLElement>, TEventType extends EventType = EventType>(base: EventTarget | Document | ArrayLike<Element> | string, selector: Selector, type: TEventType, callback: delegate.EventHandler<GlobalEventHandlersEventMap[TEventType], TElement>, options?: DelegateOptions): delegate.Subscription;
declare function delegate<TElement extends Element = HTMLElement, TEventType extends EventType = EventType>(base: EventTarget | Document | ArrayLike<Element> | string, selector: string, type: TEventType, callback: delegate.EventHandler<GlobalEventHandlersEventMap[TEventType], TElement>, options?: DelegateOptions): delegate.Subscription;
declare function delegate<Selector extends string, TElement extends Element = ParseSelector<Selector, HTMLElement>, TEventType extends EventType = EventType>(base: EventTarget | Document | Iterable<Element> | string, selector: Selector, type: TEventType, callback: DelegateEventHandler<GlobalEventHandlersEventMap[TEventType], TElement>, options?: DelegateOptions): AbortController;
declare function delegate<TElement extends Element = HTMLElement, TEventType extends EventType = EventType>(base: EventTarget | Document | Iterable<Element> | string, selector: string, type: TEventType, callback: DelegateEventHandler<GlobalEventHandlersEventMap[TEventType], TElement>, options?: DelegateOptions): AbortController;
export default delegate;
/** Keeps track of raw listeners added to the base elements to avoid duplication */
const ledger = new WeakMap();
function editLedger(wanted, baseElement, callback, setup) {
var _a, _b;
if (!wanted && !ledger.has(baseElement)) {
return false;
}
const elementMap = (_a = ledger.get(baseElement)) !== null && _a !== void 0 ? _a : new WeakMap();
const elementMap = ledger.get(baseElement)
?? new WeakMap();
ledger.set(baseElement, elementMap);

@@ -13,3 +13,3 @@ if (!wanted && !ledger.has(baseElement)) {

}
const setups = (_b = elementMap.get(callback)) !== null && _b !== void 0 ? _b : new Set();
const setups = elementMap.get(callback) ?? new Set();
elementMap.set(callback, setups);

@@ -43,2 +43,18 @@ const existed = setups.has(setup);

function delegate(base, selector, type, callback, options) {
const internalController = new AbortController();
const listenerOptions = typeof options === 'object' ? options : { capture: options };
// Drop unsupported `once` option https://github.com/fregante/delegate-it/pull/28#discussion_r863467939
delete listenerOptions.once;
if (listenerOptions.signal) {
if (listenerOptions.signal.aborted) {
internalController.abort();
return internalController;
}
listenerOptions.signal.addEventListener('abort', () => {
internalController.abort();
});
}
else {
listenerOptions.signal = internalController.signal;
}
// Handle Selector-based usage

@@ -50,10 +66,6 @@ if (typeof base === 'string') {

if (!isEventTarget(base)) {
const subscriptions = Array.prototype.map.call(base, (element) => delegate(element, selector, type, callback, options));
return {
destroy() {
for (const subscription of subscriptions) {
subscription.destroy();
}
},
};
for (const element of base) {
delegate(element, selector, type, callback, listenerOptions);
}
return internalController;
}

@@ -67,23 +79,16 @@ // `document` should never be the base, it's just an easy way to define "global event listeners"

if (delegateTarget) {
event.delegateTarget = delegateTarget;
callback.call(baseElement, event);
const delegateEvent = Object.assign(event, { delegateTarget });
callback.call(baseElement, delegateEvent);
}
};
// Drop unsupported `once` option https://github.com/fregante/delegate-it/pull/28#discussion_r863467939
if (typeof options === 'object') {
delete options.once;
}
const setup = JSON.stringify({ selector, type, capture });
const isAlreadyListening = editLedger(true, baseElement, callback, setup);
const delegateSubscription = {
destroy() {
baseElement.removeEventListener(type, listenerFn, options);
editLedger(false, baseElement, callback, setup);
},
};
if (!isAlreadyListening) {
baseElement.addEventListener(type, listenerFn, options);
baseElement.addEventListener(type, listenerFn, listenerOptions);
}
return delegateSubscription;
internalController.signal.addEventListener('abort', () => {
editLedger(false, baseElement, callback, setup);
});
return internalController;
}
export default delegate;
{
"name": "delegate-it",
"version": "3.0.1",
"version": "4.0.0",
"description": "Lightweight and modern event delegation in the browser",

@@ -42,3 +42,2 @@ "keywords": [

"max-params": "off",
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/naming-convention": "off"

@@ -52,9 +51,9 @@ }

"@sindresorhus/tsconfig": "^2.0.0",
"ava": "^4.2.0",
"jsdom": "^19.0.0",
"ava": "^4.3.0",
"jsdom": "^20.0.0",
"npm-run-all": "^4.1.5",
"sinon": "^14.0.0",
"typescript": "^4.6.4",
"xo": "^0.48.0"
"typescript": "^4.7.4",
"xo": "^0.50.0"
}
}

@@ -10,5 +10,6 @@ # delegate-it [![][badge-gzip]][link-bundlephobia]

- modern: ES6, TypeScript, Edge 15+ (it uses `WeakMap` and `Element.closest()`)
- modern: ES2021, TypeScript, Edge 16+ (it uses `WeakMap` and `Element.closest()`)
- idempotent: identical listeners aren't added multiple times, just like the native `addEventListener`
- debugged ([2d54c11](https://github.com/fregante/delegate-it/commit/2d54c1182aefd3ec9d8250fda76290971f5d7166), [c6bb88c](https://github.com/fregante/delegate-it/commit/c6bb88c2aa8097b25f22993a237cf09c96bcbfb8))
- supports [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)

@@ -76,9 +77,20 @@ If you need IE support, you can keep using [`delegate`](https://github.com/zenorocha/delegate)

```js
const delegation = delegate(document.body, '.btn', 'click', event => {
const controller = delegate(document.body, '.btn', 'click', event => {
console.log(event.delegateTarget);
});
delegation.destroy();
controller.abort();
```
```js
const controller = new AbortController();
delegate(document.body, '.btn', 'click', event => {
console.log(event.delegateTarget);
}, {
signal: controller.signal,
});
controller.abort();
```
### Custom event types in Typescript

@@ -85,0 +97,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc