Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ElementEvents): ElementEvents.defaultListenerOptions allows to set default options when subscribing to events #658

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/element-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ interface EventHandler {
* @param element
*/
export class ElementEvents {
static defaultListenerOptions: boolean | AddEventListenerOptions = { capture: true };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. But this is unfortunately a breaking change as well, as it doesn't work for IE users. I think it should be
defaultListenerOptions = true


constructor(element: EventTarget) {
this.element = element;
this.subscriptions = {};
Expand Down Expand Up @@ -51,8 +53,11 @@ export class ElementEvents {
* Adds and Event Listener on the context element.
* @return Returns the eventHandler containing a dispose method
*/
subscribe(eventName: string, handler: Function, captureOrOptions?: boolean = true): EventHandler {
subscribe(eventName: string, handler: Function, captureOrOptions?: boolean | AddEventListenerOptions): EventHandler {
if (typeof handler === 'function') {
if (typeof captureOrOptions === 'undefined') {
captureOrOptions = ElementEvents.defaultListenerOptions;
}
const eventHandler = new EventHandlerImpl(this, eventName, handler, captureOrOptions, false);
return eventHandler;
}
Expand All @@ -64,8 +69,11 @@ export class ElementEvents {
* Adds an Event Listener on the context element, that will be disposed on the first trigger.
* @return Returns the eventHandler containing a dispose method
*/
subscribeOnce(eventName: string, handler: Function, captureOrOptions?: boolean = true): EventHandler {
subscribeOnce(eventName: string, handler: Function, captureOrOptions?: boolean | AddEventListenerOptions): EventHandler {
if (typeof handler === 'function') {
if (typeof captureOrOptions === 'undefined') {
captureOrOptions = ElementEvents.defaultListenerOptions;
}
const eventHandler = new EventHandlerImpl(this, eventName, handler, captureOrOptions, true);
return eventHandler;
}
Expand Down
42 changes: 42 additions & 0 deletions test/element-events.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,48 @@ describe('ElementEvents', () => {
expect(callCount).toBe(1);
});

it("should subscribe and take ElementEvent default listener options into account", () => {
let isCapture;

// we need to track event on a parent of the input, let's take body
const bodyElementEvents = new ElementEvents(document.body);
ElementEvents.defaultListenerOptions = { capture: false };
let eventHandler = bodyElementEvents.subscribe('input', event => {
isCapture = event.eventPhase === Event.CAPTURING_PHASE;
});

// input has to be attached for the event to bubble up
document.body.appendChild(input);
input.dispatchEvent(new CustomEvent('input', {bubbles: true}));
expect(isCapture).toBe(false);
eventHandler.dispose();


// set capture back to true and check if it's being used
ElementEvents.defaultListenerOptions = { capture: true };
eventHandler = bodyElementEvents.subscribe('input', event => {
isCapture = event.eventPhase === Event.CAPTURING_PHASE;
});

input.dispatchEvent(new CustomEvent('input', {bubbles: true}));
expect(isCapture).toBe(true);
eventHandler.dispose();
});

it("should subscribe and ignore ElementEvent default listener options when argument captureOrOptions is passed", () => {
let isCapture;

const bodyElementEvents = new ElementEvents(document.body);
ElementEvents.defaultListenerOptions = { capture: false };
bodyElementEvents.subscribe('input', event => {
isCapture = event.eventPhase === Event.CAPTURING_PHASE;
}, true);

document.body.appendChild(input);
input.dispatchEvent(new CustomEvent('input', {bubbles: true}));
expect(isCapture).toBe(true);
});

it('should dispose single event', () => {
let value;
let callCount = 0;
Expand Down