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

consolidated-events

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

consolidated-events - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

__tests__/canUsePassiveEventListeners-test.js

25

__tests__/index-test.js

@@ -1,2 +0,1 @@

/* eslint-disable import/first */
import { addEventListener, removeEventListener, EVENT_HANDLERS_KEY } from '../src';

@@ -28,8 +27,7 @@ import TargetEventHandlers from '../src/TargetEventHandlers';

it('returns a handle', () => {
it('returns an unsubscribe function', () => {
const target = new MockTarget();
const handle = addEventListener(target, 'scroll', () => {}, { capture: true });
const remove = addEventListener(target, 'scroll', () => {}, { capture: true });
expect(handle).not.toBe(null);
expect(handle).not.toBe(undefined);
expect(typeof remove).toBe('function');
});

@@ -39,11 +37,6 @@ });

describe('removeEventListener()', () => {
it('does not throw when target is undefined', () => {
const handle = { target: undefined };
expect(() => removeEventListener(handle)).not.toThrow();
});
it('removes event listeners that were previously registered', () => {
const target = new MockTarget();
const handle = addEventListener(target, 'scroll', () => {});
removeEventListener(handle);
const unsubscribe = addEventListener(target, 'scroll', () => {});
removeEventListener(unsubscribe);

@@ -57,4 +50,4 @@ expect(target.removeEventListener)

addEventListener(target, 'scroll', () => {});
removeEventListener({ target, eventName: 'scroll', index: 'foo' });
removeEventListener({ target, eventName: 'resize', index: 'foo' });
removeEventListener(() => {});
removeEventListener(() => {});

@@ -66,4 +59,4 @@ expect(target.removeEventListener).toHaveBeenCalledTimes(0);

const target = new MockTarget();
const handle = addEventListener(target, 'scroll', () => {}, { capture: true });
removeEventListener(handle);
const unsubscribe = addEventListener(target, 'scroll', () => {}, { capture: true });
removeEventListener(unsubscribe);

@@ -70,0 +63,0 @@ expect(target.removeEventListener)

@@ -11,11 +11,2 @@ import TargetEventHandlers from '../src/TargetEventHandlers';

describe('#add()', () => {
it('returns a handle', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const handle = eventHandlers.add('scroll', () => {});
expect(handle).not.toBe(null);
expect(handle).not.toBe(undefined);
});
it('adds a single event listener to the target the first time', () => {

@@ -74,11 +65,17 @@ const target = new MockTarget();

});
});
describe('#delete()', () => {
it('deletes the event listener when the only handler is removed', () => {
it('returns an unsubscribe function', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const handle = eventHandlers.add('scroll', () => {});
eventHandlers.delete(handle);
const remove = eventHandlers.add('scroll', () => {});
expect(typeof remove).toBe('function');
});
it('unsubscribe deletes the event listener when the only handler is removed', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const remove = eventHandlers.add('scroll', () => {});
remove();
expect(target.removeEventListener).toHaveBeenCalledTimes(1);

@@ -89,7 +86,17 @@ expect(target.removeEventListener)

it('does not delete the listener when removing an unknown handler', () => {
it('unsubscribe does not throw when called twice', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const remove = eventHandlers.add('scroll', () => {});
remove();
expect(remove).not.toThrow();
});
it('unsubscribe does not delete the event listener when there are more handlers left', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const remove = eventHandlers.add('scroll', () => {});
eventHandlers.add('scroll', () => {});
eventHandlers.delete({ target: 'foo' });
remove();

@@ -99,8 +106,9 @@ expect(target.removeEventListener).toHaveBeenCalledTimes(0);

it('does not delete the event listener when there are more handlers left', () => {
it('unsubscribe called multiple times does not delete the event listener when there are more handlers left', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const handle = eventHandlers.add('scroll', () => {});
const remove = eventHandlers.add('scroll', () => {});
eventHandlers.add('scroll', () => {});
eventHandlers.delete(handle);
remove();
remove();

@@ -110,9 +118,9 @@ expect(target.removeEventListener).toHaveBeenCalledTimes(0);

it('deletes the event listener when all handlers is removed', () => {
it('unsubscribe deletes the event listener when all handlers are removed', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const handle = eventHandlers.add('scroll', () => {});
const handle2 = eventHandlers.add('scroll', () => {});
eventHandlers.delete(handle);
eventHandlers.delete(handle2);
const remove = eventHandlers.add('scroll', () => {});
const remove2 = eventHandlers.add('scroll', () => {});
remove();
remove2();

@@ -124,9 +132,9 @@ expect(target.removeEventListener).toHaveBeenCalledTimes(1);

it('handles different options separately', () => {
it('unsubscribe handles different options separately', () => {
const target = new MockTarget();
const eventHandlers = new TargetEventHandlers(target);
const handle = eventHandlers.add('scroll', () => {});
const handle2 = eventHandlers.add('scroll', () => {}, { passive: true });
eventHandlers.delete(handle);
eventHandlers.delete(handle2);
const remove = eventHandlers.add('scroll', () => {});
const remove2 = eventHandlers.add('scroll', () => {}, { passive: true });
remove();
remove2();

@@ -133,0 +141,0 @@ expect(target.removeEventListener).toHaveBeenCalledTimes(2);

@@ -0,1 +1,6 @@

## v1.1.0
- Return an unsubscribe function from `addEventListener` and deprecate
`removeEventListener`.
## v1.0.1

@@ -2,0 +7,0 @@

@@ -19,2 +19,6 @@ Object.defineProperty(exports, "__esModule", {

if (!window.addEventListener || !window.removeEventListener || !Object.defineProperty) {
return false;
}
var supportsPassiveOption = false;

@@ -21,0 +25,0 @@ try {

@@ -30,14 +30,5 @@ Object.defineProperty(exports, "__esModule", {

function removeEventListener(eventHandle) {
var target = eventHandle.target;
// There can be a race condition where the target may no longer exist when
// this function is called, e.g. when a React component is unmounting.
// Guarding against this prevents the following error:
//
// Cannot read property 'removeEventListener' of undefined
if (target) {
target[EVENT_HANDLERS_KEY]['delete'](eventHandle);
}
// Deprecated
function removeEventListener(unsubscribeFn) {
unsubscribeFn();
}

@@ -31,8 +31,7 @@ Object.defineProperty(exports, "__esModule", {

this.events[key] = {
size: 0,
index: 0,
handlers: {},
handlers: [],
handleEvent: undefined
};
}
return this.events[key];

@@ -50,4 +49,3 @@ }

Object.keys(handlers).forEach(function (index) {
var handler = handlers[index];
handlers.forEach(function (handler) {
if (handler) {

@@ -69,6 +67,8 @@ // We need to check for presence here because a handler function may

function add(eventName, listener, options) {
var _this = this;
// options has already been normalized at this point.
var eventHandlers = this.getEventHandlers(eventName, options);
if (eventHandlers.size === 0) {
if (eventHandlers.handlers.length === 0) {
eventHandlers.handleEvent = this.handleEvent.bind(this, eventName, options);

@@ -79,45 +79,39 @@

eventHandlers.size += 1;
eventHandlers.index += 1;
eventHandlers.handlers[eventHandlers.index] = listener;
eventHandlers.handlers.push(listener);
return {
target: this.target,
eventName: eventName,
options: options,
index: eventHandlers.index
};
}
var isSubscribed = true;
var unsubscribe = function () {
function unsubscribe() {
if (!isSubscribed) {
return;
}
return add;
}()
}, {
key: 'delete',
value: function () {
function _delete(_ref) {
var eventName = _ref.eventName,
index = _ref.index,
options = _ref.options;
isSubscribed = false;
// options has already been normalized at this point.
var eventHandlers = this.getEventHandlers(eventName, options);
var index = eventHandlers.handlers.indexOf(listener);
eventHandlers.handlers.splice(index, 1);
if (eventHandlers.size === 0) {
// There are no matching event handlers, so no work to be done here.
return;
}
if (eventHandlers.handlers.length === 0) {
// All event handlers have been removed, so we want to remove the event
// listener from the target node.
if (eventHandlers.handlers[index]) {
delete eventHandlers.handlers[index];
eventHandlers.size -= 1;
}
if (_this.target) {
// There can be a race condition where the target may no longer exist
// when this function is called, e.g. when a React component is
// unmounting. Guarding against this prevents the following error:
//
// Cannot read property 'removeEventListener' of undefined
_this.target.removeEventListener(eventName, eventHandlers.handleEvent, options);
}
if (eventHandlers.size === 0) {
this.target.removeEventListener(eventName, eventHandlers.handleEvent, options);
eventHandlers.handleEvent = undefined;
}
}
eventHandlers.handleEvent = undefined;
}
return unsubscribe;
}();
return unsubscribe;
}
return _delete;
return add;
}()

@@ -124,0 +118,0 @@ }]);

{
"name": "consolidated-events",
"version": "1.0.1",
"version": "1.1.0",
"description": "Manage multiple event handlers using few event listeners",

@@ -39,14 +39,15 @@ "main": "lib/index.js",

"devDependencies": {
"babel-cli": "^6.18.0",
"babel-core": "^6.18.2",
"babel-jest": "^17.0.0",
"babel-preset-airbnb": "^2.1.1",
"eslint": "^3.9.1",
"eslint-config-airbnb-base": "^10.0.1",
"eslint-plugin-import": "^2.2.0",
"babel-cli": "^6.22.2",
"babel-core": "^6.22.1",
"babel-jest": "^20.0.0",
"babel-preset-airbnb": "^2.2.3",
"eslint": "^3.15.0",
"eslint-config-airbnb-base": "^11.1.0",
"eslint-plugin-import": "^2.3.0",
"in-publish": "^2.0.0",
"jest": "^17.0.0",
"rimraf": "^2.5.4",
"jest": "^20.0.0",
"jest-wrap": "^1.0.0",
"rimraf": "^2.6.1",
"safe-publish-latest": "^1.1.1"
}
}

@@ -17,5 +17,5 @@ # consolidated-events <sup>[![Version Badge][npm-version-svg]][package-url]</sup>

```js
import { addEventListener, removeEventListener } from 'consolidated-events';
import { addEventListener } from 'consolidated-events';
const handle = addEventListener(
const removeEventListener = addEventListener(
window,

@@ -22,0 +22,0 @@ 'scroll',

@@ -10,2 +10,6 @@ import canUseDOM from './canUseDOM';

if (!window.addEventListener || !window.removeEventListener || !Object.defineProperty) {
return false;
}
let supportsPassiveOption = false;

@@ -12,0 +16,0 @@ try {

@@ -16,13 +16,5 @@ import normalizeEventOptions from './normalizeEventOptions';

export function removeEventListener(eventHandle) {
const { target } = eventHandle;
// There can be a race condition where the target may no longer exist when
// this function is called, e.g. when a React component is unmounting.
// Guarding against this prevents the following error:
//
// Cannot read property 'removeEventListener' of undefined
if (target) {
target[EVENT_HANDLERS_KEY].delete(eventHandle);
}
// Deprecated
export function removeEventListener(unsubscribeFn) {
unsubscribeFn();
}

@@ -14,8 +14,7 @@ import eventOptionsKey from './eventOptionsKey';

this.events[key] = {
size: 0,
index: 0,
handlers: {},
handlers: [],
handleEvent: undefined,
};
}
return this.events[key];

@@ -26,4 +25,3 @@ }

const { handlers } = this.getEventHandlers(eventName, options);
Object.keys(handlers).forEach((index) => {
const handler = handlers[index];
handlers.forEach((handler) => {
if (handler) {

@@ -43,3 +41,3 @@ // We need to check for presence here because a handler function may

if (eventHandlers.size === 0) {
if (eventHandlers.handlers.length === 0) {
eventHandlers.handleEvent = this.handleEvent.bind(this, eventName, options);

@@ -54,38 +52,37 @@

eventHandlers.size += 1;
eventHandlers.index += 1;
eventHandlers.handlers[eventHandlers.index] = listener;
eventHandlers.handlers.push(listener);
return {
target: this.target,
eventName,
options,
index: eventHandlers.index,
};
}
let isSubscribed = true;
const unsubscribe = () => {
if (!isSubscribed) {
return;
}
delete({ eventName, index, options }) {
// options has already been normalized at this point.
const eventHandlers = this.getEventHandlers(eventName, options);
isSubscribed = false;
if (eventHandlers.size === 0) {
// There are no matching event handlers, so no work to be done here.
return;
}
const index = eventHandlers.handlers.indexOf(listener);
eventHandlers.handlers.splice(index, 1);
if (eventHandlers.handlers[index]) {
delete eventHandlers.handlers[index];
eventHandlers.size -= 1;
}
if (eventHandlers.handlers.length === 0) {
// All event handlers have been removed, so we want to remove the event
// listener from the target node.
if (eventHandlers.size === 0) {
this.target.removeEventListener(
eventName,
eventHandlers.handleEvent,
options,
);
if (this.target) {
// There can be a race condition where the target may no longer exist
// when this function is called, e.g. when a React component is
// unmounting. Guarding against this prevents the following error:
//
// Cannot read property 'removeEventListener' of undefined
this.target.removeEventListener(
eventName,
eventHandlers.handleEvent,
options,
);
}
eventHandlers.handleEvent = undefined;
}
eventHandlers.handleEvent = undefined;
}
};
return unsubscribe;
}
}
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