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

feat: ES5/IE11 cleanup (part 1) #1633

Merged
merged 8 commits into from
May 4, 2023
Merged
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
2 changes: 0 additions & 2 deletions pages/src/landing/marquee/marquee.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {ESLBaseElement} from '../../../../src/modules/esl-base-element/core';
import {bind, ready, memoize, attr} from '../../../../src/modules/esl-utils/decorators';
import {range} from '../../../../src/modules/esl-utils/misc/array';
import {isIE} from '../../../../src/modules/esl-utils/environment/device-detector';

export class ESLDemoMarquee extends ESLBaseElement {
static override is = 'esl-d-marquee';
Expand All @@ -16,7 +15,6 @@ export class ESLDemoMarquee extends ESLBaseElement {
@ready
protected override connectedCallback(): void {
super.connectedCallback();
if (isIE) return;
this.startAnimation();
}
protected override disconnectedCallback(): void {
Expand Down
2 changes: 0 additions & 2 deletions src/modules/esl-alert/core/esl-alert.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@import "../../esl-utils/fixes/ie-fixes";

esl-alert {
display: flex;
justify-content: center;
Expand Down
3 changes: 0 additions & 3 deletions src/modules/esl-alert/core/esl-alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import {ExportNs} from '../../esl-utils/environment/export-ns';
import {attr, jsonAttr, prop, listen} from '../../esl-utils/decorators';
import {isMatches} from '../../esl-utils/dom/traversing';
import {ESLToggleable} from '../../esl-toggleable/core';
import {DeviceDetector} from '../../esl-utils/environment/device-detector';
import {CSSClassUtils} from '../../esl-utils/dom/class';
import {createZIndexIframe} from '../../esl-utils/fixes/ie-fixes';
import {ESLTraversingQuery} from '../../esl-traversing-query/core';

import type {ESLToggleableActionParams, ESLToggleableRequestDetails} from '../../esl-toggleable/core';
Expand Down Expand Up @@ -87,7 +85,6 @@ export class ESLAlert extends ESLToggleable {
this.$content.className = 'esl-alert-content';
this.innerHTML = '';
this.appendChild(this.$content);
if (DeviceDetector.isIE) this.appendChild(createZIndexIframe());
if (this.target) {
this.$target = ESLTraversingQuery.first(this.target, this) as EventTarget;
}
Expand Down
26 changes: 8 additions & 18 deletions src/modules/esl-utils/dom/events/target.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {flat, uniq} from '../../misc/array';
import {uniq} from '../../misc/array';
import {overrideEvent} from './misc';

/** Key to store listeners on the {@link SyntheticEventTarget} instance*/
Expand All @@ -10,27 +10,21 @@ const LISTENERS = Symbol('_listeners');
* Doesn't give explicit access to callback storage
*/
export class SyntheticEventTarget implements EventTarget {
// Event type to use in the shortcutted calls
// Event type to use in the shortcut calls
public static DEFAULT_EVENT = 'change';

private readonly [LISTENERS]: Record<string, EventListenerOrEventListenerObject[]> = {};

protected getEventListeners(): EventListenerOrEventListenerObject[];
protected getEventListeners(type: string): EventListenerOrEventListenerObject[];
protected getEventListeners(type?: string): EventListenerOrEventListenerObject[] {
if (typeof type !== 'string') return uniq(flat(Object.values(this[LISTENERS])));
if (typeof type !== 'string') return uniq(Object.values(this[LISTENERS]).flat(1));
return this[LISTENERS][type] || [];
}

public hasEventListener(): boolean;
public hasEventListener(type: string): boolean;
/** @deprecated alias for `addEventListener` */
public hasEventListener(type: string | number): boolean;
/** @deprecated alias for `addEventListener` */
public hasEventListener(type: string, minCount: number): boolean;
public hasEventListener(type: string | number = 'change', minCount: number = 0): boolean {
if (typeof type !== 'string') return this.hasEventListener('change', type || 0); // TODO: remove in 5.0.0
return this.getEventListeners(type).length > minCount;
public hasEventListener(type?: string): boolean {
if (typeof type === 'string') return this.getEventListeners(type).length > 0;
return this.hasEventListener((this.constructor as typeof SyntheticEventTarget).DEFAULT_EVENT);
}

public addEventListener(callback: EventListenerOrEventListenerObject): void;
Expand All @@ -56,14 +50,10 @@ export class SyntheticEventTarget implements EventTarget {
this[LISTENERS][type] = listeners.filter((cb) => cb !== callback);
}

public dispatchEvent(e: Event): boolean;
/** @deprecated use `overrideEvent` to declare `target` */
public dispatchEvent(e: Event, target?: EventTarget): boolean;
public dispatchEvent(e: Event, target?: EventTarget): boolean {
public dispatchEvent(e: Event): boolean {
overrideEvent(e, 'currentTarget', this);
if (target) overrideEvent(e, 'target', target); // TODO: remove in 5.0.0
if (!e.target) overrideEvent(e, 'target', this);
if (!e.srcElement) overrideEvent(e, 'srcElement', e.target); // TODO: remove in 5.0.0
if (!e.srcElement) overrideEvent(e, 'srcElement', e.target);
this.getEventListeners(e.type).forEach((listener) => {
if (typeof listener === 'function') listener.call(this, e);
else listener.handleEvent.call(listener, e);
Expand Down
31 changes: 0 additions & 31 deletions src/modules/esl-utils/dom/events/test/target.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,6 @@ describe('dom/events: SyntheticEventTarget', () => {
expect(listener).toHaveBeenLastCalledWith(event2);
});

test('listener should be stored', () => {
expect(et.hasEventListener('change', 0)).toBe(true);
});

test('target shouldn`t have more listeners than it actually has', () => {
expect(et.hasEventListener('change', 1)).toBe(false);
});

test('listener shouldn`t be stored for wrong event type', () => {
expect(et.hasEventListener('change2', 0)).toBe(false);
});

test('listener shouldn`t be called third time', () => {
et.removeEventListener('change', listener);
et.dispatchEvent(event3);
Expand Down Expand Up @@ -81,10 +69,6 @@ describe('dom/events: SyntheticEventTarget', () => {
expect(et.hasEventListener('change2')).toBe(false);
});

test('target shouldn`t have more listeners than it actually has', () => {
expect(et.hasEventListener(1)).toBe(false);
});

test('listener shouldn`t be called second time', () => {
et.removeEventListener(listener);
et.dispatchEvent(event2);
Expand Down Expand Up @@ -186,19 +170,4 @@ describe('dom/events: SyntheticEventTarget', () => {
});
});
});

describe('Listener duplicate subscription', () => {
const et = new SyntheticEventTarget();
const listener = jest.fn(() => {});

test('event should be subscribed', () => {
et.addEventListener('change', listener);
expect(et.hasEventListener(1)).toBe(false);
});

test('event shouldn`t be subscribed again', () => {
et.addEventListener('change', listener);
expect(et.hasEventListener(1)).toBe(false);
});
});
});
1 change: 0 additions & 1 deletion src/modules/esl-utils/fixes.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './fixes/ie-fixes';
export * from './fixes/viewport';
10 changes: 0 additions & 10 deletions src/modules/esl-utils/fixes/ie-fixes.less

This file was deleted.

7 changes: 0 additions & 7 deletions src/modules/esl-utils/fixes/ie-fixes.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/modules/esl-utils/fixes/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ export class ESLVSizeCSSProxy {

/** Inits custom CSS variables for viewport sizes and it's observation */
public static observe(): void {
// IE doesn’t support CSS Variables (hopefully same as 100vh issue :D)
if (DeviceDetector.isIE) return;

this.update();
window.addEventListener('resize', this.updateDebounced);
}
Expand Down
22 changes: 10 additions & 12 deletions src/modules/esl-utils/misc/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ export const tuple = <T>(arr: T[]): Tuple<T>[] => arr.reduce((acc: Tuple<T>[], e
return acc;
}, []);

/** Flat array - unwraps one level of nested arrays */
export const flat = <T>(arr: (null | T | T[])[]): T[] =>
arr.reduce((acc: T[], el) => el ? acc.concat(el) : acc, []) as T[];
/**
* Flat array - unwraps one level of nested arrays
* @deprecated use `Array.prototype.flat` instead
*/
export const flat = <T>(arr: (null | T | T[])[]): T[] => arr.flat(1) as T[];

/** Wraps passed object or primitive to array */
export const wrap = <T>(arr: undefined | null | T | T[]): T[] => {
Expand All @@ -23,22 +25,18 @@ export const wrap = <T>(arr: undefined | null | T | T[]): T[] => {

/** Unwraps and returns the first element if passed object is array-like, returns original object otherwise */
export function unwrap(value: []): undefined;
export function unwrap<T>(value: (ArrayLike<T> & {0: T}) | T): T;
export function unwrap<T>(value: (ArrayLike<T> & {0: T})): T;
export function unwrap<T>(value: ArrayLike<T>): T | undefined;
export function unwrap<T extends Node>(value: NodeListOf<T>): T | undefined;
export function unwrap<T>(value: T): T;
export function unwrap(value: any): any;
export function unwrap(value: any): any {
return isArrayLike(value) ? value[0] : value;
}

/** Makes array values unique */
export const uniq = <T> (arr: T[]): T[] => {
if (arr.length < 2) return arr.slice(0);
const result: T[] = [];
const set = new Set<T>();
arr.forEach((item) => set.add(item));
set.forEach((item) => result.push(item));
return result;
};
export const uniq = <T> (arr: T[]): T[] =>
arr.length > 1 ? [...new Set<T>(arr)] : arr.slice(0);

/** Create an array filled with the range [0,..,N-1] */
export function range(n: number): number[];
Expand Down
6 changes: 2 additions & 4 deletions src/modules/esl-utils/misc/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ export function intersection<T>(a: T[], b: T[], ...rest: T[][]): T[] {

/** Create an array with unique values from each of the passed arrays */
export function union<T>(...rest: T[][]): T[] {
const set = new Set();
const set = new Set<T>();
rest.forEach((item) => item.forEach((i) => set.add(i)));
const result: any[] = [];
set.forEach((value) => result.push(value));
return result;
return [...set];
}

/** Creates an array of unique values from the first array that are not present in the other arrays */
Expand Down
4 changes: 3 additions & 1 deletion src/modules/esl-utils/misc/test/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ describe('misc/array helper tests', () => {

test('flat', () => {
expect(flat([])).toEqual([]);
expect(flat([0])).toEqual([0]);
expect(flat([1])).toEqual([1]);
expect(flat([1, 2])).toEqual([1, 2]);
expect(flat([1, [2, 3]])).toEqual([1, 2, 3]);
expect(flat([[1, 2], [3, 4]])).toEqual([1, 2, 3, 4]);
expect(flat([[1], [2, 3, 4], [], [5]])).toEqual([1, 2, 3, 4, 5]);
expect(flat([null, 1, 2, 3, [4, 5], null, [6]])).toEqual([1, 2, 3, 4, 5, 6]);
expect(flat([null, 1, 2, 3, [4, 5], null, [6]])).toEqual([null, 1, 2, 3, 4, 5, null, 6]);
});

test('wrap', () => {
Expand All @@ -43,6 +44,7 @@ describe('misc/array helper tests', () => {

test('range', () => {
expect(range(3)).toEqual([0, 1, 2]);
// @ts-ignore
expect(range(9, (x) => x / 8)).toEqual([...Array(9).keys()].map((x) => x / 8));
});

Expand Down