Skip to content

Commit

Permalink
feat: introduce EventUtils with a set of event related utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
ala-n committed Jan 30, 2021
1 parent 68f1bb6 commit 04c5368
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ExportNs} from '../../../esl-utils/environment/export-ns';
import ESLCarouselPlugin from './esl-carousel-plugin';
import {DeviceDetector} from '../../../esl-utils/environment/device-detector';
import {normalizeTouchPoint, Point} from '../../../esl-utils/dom/events';
import {EventUtils, Point} from '../../../esl-utils/dom/events';

/**
* Slide Carousel Touch plugin
Expand Down Expand Up @@ -37,12 +37,12 @@ export class ESLCarouselTouchPlugin extends ESLCarouselPlugin {
return;
}
this.isTouchStarted = true;
this.startPoint = normalizeTouchPoint(event);
this.startPoint = EventUtils.normalizeTouchPoint(event);
};

onTouchMove = (event: TouchEvent | PointerEvent) => {
if (!this.isTouchStarted) return;
// const point = normalizeTouchPoint(event);
// const point = EventUtils.normalizeTouchPoint(event);
// const offset = {
// x: point.x - this.startPoint.x,
// y: point.y - this.startPoint.y
Expand All @@ -51,7 +51,7 @@ export class ESLCarouselTouchPlugin extends ESLCarouselPlugin {

onTouchEnd = (event: TouchEvent | PointerEvent) => {
if (!this.isTouchStarted) return;
const point = normalizeTouchPoint(event);
const point = EventUtils.normalizeTouchPoint(event);
const offset = {
x: point.x - this.startPoint.x,
y: point.y - this.startPoint.y
Expand Down
21 changes: 3 additions & 18 deletions src/modules/esl-base-element/core/esl-base-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Base class for ESL custom elements.
* Allows to define custom element with the optional custom tag name.
*/
import {EventUtils} from '../../esl-utils/dom/events';

export abstract class ESLBaseElement extends HTMLElement {
/** Custom element tag name */
public static is = '';
Expand All @@ -28,26 +30,9 @@ export abstract class ESLBaseElement extends HTMLElement {
* Uses 'esl:' prefix for event name, overridable to customize event namespaces.
* @param eventName - event name
* @param [eventInit] - custom event init. See {@link CustomEventInit}
* @see ESLBaseElement.$$fire
*/
public $$fire(eventName: string, eventInit?: CustomEventInit): boolean {
return ESLBaseElement.$$fire(this, 'esl:' + eventName, eventInit);
}

/**
* Dispatch custom event.
* Event bubbles and is cancelable by default, use {@param eventInit} to override that.
* @param el - element target
* @param eventName - event name
* @param [eventInit] - custom event init. See {@link CustomEventInit}
*/
public static $$fire(el: ESLBaseElement, eventName: string, eventInit?: CustomEventInit) {
const init = Object.assign({
bubbles: true,
composed: true,
cancelable: true
}, eventInit || {});
return el.dispatchEvent(new CustomEvent(eventName, init));
return EventUtils.dispatch(this, 'esl:' + eventName, eventInit);
}

/**
Expand Down
18 changes: 5 additions & 13 deletions src/modules/esl-base-element/test/base-element.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,28 +43,20 @@ describe('ESLBaseElement test', () => {
});
});

test('FireEvent - simple', (done) => {
el.addEventListener('testevent', (e) => {
test('FireEvent - default', (done) => {
el.addEventListener('esl:testevent', (e) => {
expect(e).toBeInstanceOf(CustomEvent);
done();
});
ESLBaseElement.$$fire(el, 'testevent');
}, { once: true });
el.$$fire('testevent');
}, 10);

test('FireEvent - bubbling', (done) => {
document.addEventListener('testevent', (e) => {
document.addEventListener('esl:testevent', (e) => {
expect(e).toBeInstanceOf(CustomEvent);
done();
}, { once: true });

ESLBaseElement.$$fire(el, 'testevent');
}, 10);

test('FireEvent - default', (done) => {
el.addEventListener('esl:testevent', (e) => {
expect(e).toBeInstanceOf(CustomEvent);
done();
}, { once: true });
el.$$fire('testevent');
}, 10);
});
3 changes: 2 additions & 1 deletion src/modules/esl-image/core/esl-image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {ExportNs} from '../../esl-utils/environment/export-ns';
import {bind} from '../../esl-utils/decorators/bind';
import {CSSUtil} from '../../esl-utils/dom/styles';
import {ESLBaseElement, attr, boolAttr} from '../../esl-base-element/core';
import {EventUtils} from '../../esl-utils/dom/events';
import {ESLMediaRuleList} from '../../esl-media-query/core';
import {TraversingQuery} from '../../esl-traversing-query/core/esl-traversing-query';

Expand Down Expand Up @@ -300,7 +301,7 @@ export class ESLImage extends ESLBaseElement {
}

public $$fire(eventName: string, eventInit: CustomEventInit = {bubbles: false}): boolean {
return ESLBaseElement.$$fire(this, eventName, eventInit);
return EventUtils.dispatch(this, eventName, eventInit);
}

public static isEmptyImage(src: string) {
Expand Down
12 changes: 7 additions & 5 deletions src/modules/esl-media/core/esl-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@

import {ExportNs} from '../../esl-utils/environment/export-ns';
import {ESLBaseElement, attr, boolAttr} from '../../esl-base-element/core';
import {debounce} from '../../esl-utils/async/debounce';
import {CSSUtil} from '../../esl-utils/dom/styles';
import {rafDecorator} from '../../esl-utils/async/raf';
import {ESLMediaQuery} from '../../esl-media-query/core';
import {debounce} from '../../esl-utils/async/debounce';
import {EventUtils} from '../../esl-utils/dom/events';
import {parseAspectRatio} from '../../esl-utils/misc/format';

import {ESLMediaQuery} from '../../esl-media-query/core';
import {TraversingQuery} from '../../esl-traversing-query/core';

import {getIObserver} from './esl-media-iobserver';
import {BaseProvider, PlayerStates} from './esl-media-provider';
import ESLMediaRegistry from './esl-media-registry';
import MediaGroupRestrictionManager from './esl-media-manager';
import {CSSUtil} from '../../esl-utils/dom/styles';
import {TraversingQuery} from '../../esl-traversing-query/core';

@ExportNs('Media')
export class ESLMedia extends ESLBaseElement {
Expand Down Expand Up @@ -344,7 +346,7 @@ export class ESLMedia extends ESLBaseElement {

public $$fire(eventName: string, eventInit?: CustomEventInit): boolean {
const ns = (this.constructor as typeof ESLMedia).eventNs;
return ESLBaseElement.$$fire(this, ns + eventName, eventInit);
return EventUtils.dispatch(this, ns + eventName, eventInit);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/modules/esl-scrollbar/core/esl-scrollbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {ESLBaseElement, attr, boolAttr} from '../../esl-base-element/core';
import {bind} from '../../esl-utils/decorators/bind';
import {ready} from '../../esl-utils/decorators/ready';
import {rafDecorator} from '../../esl-utils/async/raf';
import {normalizeCoordinates} from '../../esl-utils/dom/events';
import {EventUtils} from '../../esl-utils/dom/events';
import {TraversingUtils} from '../../esl-utils/dom/traversing';
import {TraversingQuery} from '../../esl-traversing-query/core';

Expand Down Expand Up @@ -287,7 +287,7 @@ export class ESLScrollbar extends ESLBaseElement {
@bind
protected _onClick(event: MouseEvent) {
if (event.target !== this.$scrollbarTrack && event.target !== this) return;
const clickCoordinates = normalizeCoordinates(event, this.$scrollbarTrack);
const clickCoordinates = EventUtils.normalizeCoordinates(event, this.$scrollbarTrack);
const clickPosition = this.horizontal ? clickCoordinates.x : clickCoordinates.y;

const freeTrackArea = this.trackOffset - this.thumbOffset; // px
Expand Down
62 changes: 41 additions & 21 deletions src/modules/esl-utils/dom/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,46 @@ export interface Point {
y: number;
}

/**
* Normalize TouchEvent or PointerEvent
*/
export function normalizeTouchPoint(event: TouchEvent | PointerEvent): Point {
const source = (event instanceof TouchEvent) ? event.changedTouches[0] : event;
return {
x: source.pageX,
y: source.pageY
};
}
export abstract class EventUtils {
/**
* Dispatch custom event.
* Event bubbles and is cancelable by default, use {@param eventInit} to override that.
* @param el - element target
* @param eventName - event name
* @param [eventInit] - custom event init. See {@link CustomEventInit}
*/
public static dispatch(el: HTMLElement, eventName: string, eventInit?: CustomEventInit) {
const init = Object.assign({
bubbles: true,
composed: true,
cancelable: true
}, eventInit || {});
return el.dispatchEvent(new CustomEvent(eventName, init));
}

/** Get original CustomEvent source */
public static source(e: CustomEvent) {
const path = (e.composedPath && e.composedPath());
return path ? path[0] : e.target;
}

/** Normalize TouchEvent or PointerEvent */
public static normalizeTouchPoint(event: TouchEvent | PointerEvent): Point {
const source = (event instanceof TouchEvent) ? event.changedTouches[0] : event;
return {
x: source.pageX,
y: source.pageY
};
}

/**
* Normalize MouseEvent
*/
export function normalizeCoordinates(event: MouseEvent, elem: HTMLElement): Point {
const props = elem.getBoundingClientRect();
const top = props.top + window.pageYOffset;
const left = props.left + window.pageXOffset;
return {
x: event.pageX - left,
y: event.pageY - top
};
/** Normalize MouseEvent */
public static normalizeCoordinates(event: MouseEvent, elem: HTMLElement): Point {
const props = elem.getBoundingClientRect();
const top = props.top + window.pageYOffset;
const left = props.left + window.pageXOffset;
return {
x: event.pageX - left,
y: event.pageY - top
};
}
}

0 comments on commit 04c5368

Please sign in to comment.