improve bundle size and build process for tests

This commit is contained in:
Rene
2022-07-12 22:25:12 +02:00
parent 06f0bc4c7c
commit bd7c06c9dd
22 changed files with 2768 additions and 2810 deletions
-26
View File
@@ -59,32 +59,6 @@ module.exports = (esm, options, { declarationFiles = false, outputStyle = false
format: esm ? 'esm' : 'umd', format: esm ? 'esm' : 'umd',
generatedCode: esm ? 'es2015' : 'es5', generatedCode: esm ? 'es2015' : 'es5',
file: path.resolve(distPath, `${file}${esm ? '.esm' : ''}.js`), file: path.resolve(distPath, `${file}${esm ? '.esm' : ''}.js`),
plugins: [
rollupTerser({
ecma: esm ? 2015 : 5,
safari10: true,
mangle: {
safari10: true,
keep_fnames: true, // eslint-disable-line camelcase
/*
properties: {
regex: /^_/,
},
*/
},
compress: {
defaults: false,
hoist_funs: true, // eslint-disable-line camelcase
},
format: {
beautify: true,
max_line_len: 80, // eslint-disable-line camelcase
braces: true,
indent_level: 2, // eslint-disable-line camelcase
},
}),
],
}, },
esm, esm,
buildMinifiedVersion buildMinifiedVersion
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,3 +1,4 @@
const { terser: rollupTerser } = require('rollup-plugin-terser');
const createRollupConfig = require('../../rollup.config.base'); const createRollupConfig = require('../../rollup.config.base');
const { devDependencies, peerDependencies } = require('./package.json'); const { devDependencies, peerDependencies } = require('./package.json');
@@ -8,6 +9,28 @@ module.exports = createRollupConfig({
external: Object.keys(devDependencies || {}).concat(Object.keys(peerDependencies || {})), external: Object.keys(devDependencies || {}).concat(Object.keys(peerDependencies || {})),
output: { output: {
exports: 'auto', exports: 'auto',
plugins: [
rollupTerser({
safari10: true,
mangle: {
safari10: true,
keep_fnames: true, // eslint-disable-line camelcase
properties: {
regex: /^_/,
},
},
compress: {
defaults: false,
hoist_funs: true, // eslint-disable-line camelcase
},
format: {
beautify: true,
max_line_len: 80, // eslint-disable-line camelcase
braces: true,
indent_level: 2, // eslint-disable-line camelcase
},
}),
],
}, },
}, },
}); });
+1 -1
View File
@@ -1,4 +1,4 @@
import 'index.scss'; import 'index.scss';
export { OverlayScrollbars as default, OverlayScrollbars } from 'overlayscrollbars'; export { OverlayScrollbars } from 'overlayscrollbars';
export { optionsValidationPlugin, scrollbarsHidingPlugin, sizeObserverPlugin } from 'plugins'; export { optionsValidationPlugin, scrollbarsHidingPlugin, sizeObserverPlugin } from 'plugins';
@@ -23,15 +23,18 @@ export type Cache<Value> = [UpdateCache<Value>, GetCurrentCache<Value>];
export type CacheContextual<Value> = [UpdateCacheContextual<Value>, GetCurrentCache<Value>]; export type CacheContextual<Value> = [UpdateCacheContextual<Value>, GetCurrentCache<Value>];
export function createCache<Value>(options: CacheOptions<Value>): CacheContextual<Value>; type CreateCache = {
export function createCache<Value>( <Value>(options: CacheOptions<Value>): CacheContextual<Value>;
options: CacheOptions<Value>, <Value>(options: CacheOptions<Value>, update: CacheUpdater<Value>): Cache<Value>;
update: CacheUpdater<Value> <Value>(options: CacheOptions<Value>, update?: CacheUpdater<Value>):
): Cache<Value>; | CacheContextual<Value>
export function createCache<Value>( | Cache<Value>;
};
export const createCache: CreateCache = <Value>(
options: CacheOptions<Value>, options: CacheOptions<Value>,
update?: CacheUpdater<Value> update?: CacheUpdater<Value>
): CacheContextual<Value> | Cache<Value> { ): CacheContextual<Value> | Cache<Value> => {
const { _initialValue, _equal, _alwaysUpdateValues } = options; const { _initialValue, _equal, _alwaysUpdateValues } = options;
let _value: Value = _initialValue; let _value: Value = _initialValue;
let _previous: Value | undefined; let _previous: Value | undefined;
@@ -61,4 +64,4 @@ export function createCache<Value>(
return [update ? cacheUpdateIsolated : cacheUpdateContextual, getCurrentCache] as return [update ? cacheUpdateIsolated : cacheUpdateContextual, getCurrentCache] as
| CacheContextual<Value> | CacheContextual<Value>
| Cache<Value>; | Cache<Value>;
} };
@@ -3,17 +3,32 @@ import { isUndefined } from 'support/utils/types';
type GetSetPropName = 'scrollLeft' | 'scrollTop' | 'value'; type GetSetPropName = 'scrollLeft' | 'scrollTop' | 'value';
function getSetProp( type Attr = {
(elm: HTMLElement | false | null | undefined, attrName: string): string | null;
(elm: HTMLElement | false | null | undefined, attrName: string, value: string): void;
(elm: HTMLElement | false | null | undefined, attrName: string, value?: string):
| string
| null
| void;
};
type GetSetProp = {
(elm: HTMLElement | false | null | undefined): number;
(elm: HTMLElement | false | null | undefined, value: number): void;
(elm: HTMLElement | false | null | undefined, value?: number): number | void;
};
const getSetProp = (
topLeft: GetSetPropName, topLeft: GetSetPropName,
fallback: number | string, fallback: number | string,
elm: HTMLElement | HTMLInputElement | false | null | undefined, elm: HTMLElement | HTMLInputElement | false | null | undefined,
value?: number | string value?: number | string
): number | string | void { ): number | string | void => {
if (isUndefined(value)) { if (isUndefined(value)) {
return elm ? elm[topLeft] : fallback; return elm ? elm[topLeft] : fallback;
} }
elm && (elm[topLeft] = value); elm && (elm[topLeft] = value);
} };
/** /**
* Gets or sets a attribute with the given attribute of the given element depending whether the value attribute is given. * Gets or sets a attribute with the given attribute of the given element depending whether the value attribute is given.
@@ -22,22 +37,16 @@ function getSetProp(
* @param attrName The attribute name which shall be get or set. * @param attrName The attribute name which shall be get or set.
* @param value The value of the attribute which shall be set. * @param value The value of the attribute which shall be set.
*/ */
export function attr(elm: HTMLElement | false | null | undefined, attrName: string): string | null; export const attr = ((
export function attr(
elm: HTMLElement | false | null | undefined,
attrName: string,
value: string
): void;
export function attr(
elm: HTMLElement | false | null | undefined, elm: HTMLElement | false | null | undefined,
attrName: string, attrName: string,
value?: string value?: string
): string | null | void { ): string | null | void => {
if (isUndefined(value)) { if (isUndefined(value)) {
return elm ? elm.getAttribute(attrName) : null; return elm ? elm.getAttribute(attrName) : null;
} }
elm && elm.setAttribute(attrName, value); elm && elm.setAttribute(attrName, value);
} }) as Attr;
/** /**
* Treats the given attribute like the "class" attribute and adds or removes the given value from it. * Treats the given attribute like the "class" attribute and adds or removes the given value from it.
@@ -90,39 +99,27 @@ export const removeAttr = (elm: Element | false | null | undefined, attrName: st
* @param elm The element of which the scrollLeft value shall be get or set. * @param elm The element of which the scrollLeft value shall be get or set.
* @param value The scrollLeft value which shall be set. * @param value The scrollLeft value which shall be set.
*/ */
export function scrollLeft(elm: HTMLElement | false | null | undefined): number; export const scrollLeft = ((
export function scrollLeft(elm: HTMLElement | false | null | undefined, value: number): void;
export function scrollLeft(
elm: HTMLElement | false | null | undefined, elm: HTMLElement | false | null | undefined,
value?: number value?: number
): number | void { ): number | void => getSetProp('scrollLeft', 0, elm, value) as number) as GetSetProp;
return getSetProp('scrollLeft', 0, elm, value) as number;
}
/** /**
* Gets or sets the scrollTop value of the given element depending whether the value attribute is given. * Gets or sets the scrollTop value of the given element depending whether the value attribute is given.
* @param elm The element of which the scrollTop value shall be get or set. * @param elm The element of which the scrollTop value shall be get or set.
* @param value The scrollTop value which shall be set. * @param value The scrollTop value which shall be set.
*/ */
export function scrollTop(elm: HTMLElement | false | null | undefined): number; export const scrollTop = ((
export function scrollTop(elm: HTMLElement | false | null | undefined, value: number): void;
export function scrollTop(
elm: HTMLElement | false | null | undefined, elm: HTMLElement | false | null | undefined,
value?: number value?: number
): number | void { ): number | void => getSetProp('scrollTop', 0, elm, value) as number) as GetSetProp;
return getSetProp('scrollTop', 0, elm, value) as number;
}
/** /**
* Gets or sets the value of the given input element depending whether the value attribute is given. * Gets or sets the value of the given input element depending whether the value attribute is given.
* @param elm The input element of which the value shall be get or set. * @param elm The input element of which the value shall be get or set.
* @param value The value which shall be set. * @param value The value which shall be set.
*/ */
export function val(elm: HTMLInputElement | false | null | undefined): string; export const val = ((
export function val(elm: HTMLInputElement | false | null | undefined, value: string): void;
export function val(
elm: HTMLInputElement | false | null | undefined, elm: HTMLInputElement | false | null | undefined,
value?: string value?: string
): string | void { ): string | void => getSetProp('value', '', elm, value) as string) as GetSetProp;
return getSetProp('value', '', elm, value) as string;
}
@@ -12,7 +12,7 @@ const supportPassiveEvents = (): boolean => {
'test', 'test',
null, null,
Object.defineProperty({}, 'passive', { Object.defineProperty({}, 'passive', {
get: function () { get() {
passiveEventsSupport = true; passiveEventsSupport = true;
}, },
}) })
@@ -28,16 +28,20 @@ const cssNumber = {
const parseToZeroOrNumber = (value: string, toFloat?: boolean): number => { const parseToZeroOrNumber = (value: string, toFloat?: boolean): number => {
/* istanbul ignore next */ /* istanbul ignore next */
const num = toFloat ? parseFloat(value) : parseInt(value, 10); const num = toFloat ? parseFloat(value) : parseInt(value, 10);
// num === num means num is not NaN
/* istanbul ignore next */ /* istanbul ignore next */
return Number.isNaN(num) ? 0 : num; return num === num ? num : 0; // eslint-disable-line no-self-compare
}; };
const adaptCSSVal = (prop: string, val: string | number): string | number => const adaptCSSVal = (prop: string, val: string | number): string | number =>
!cssNumber[prop.toLowerCase()] && isNumber(val) ? `${val}px` : val; !cssNumber[prop.toLowerCase()] && isNumber(val) ? `${val}px` : val;
const getCSSVal = (elm: HTMLElement, computedStyle: CSSStyleDeclaration, prop: string): string => const getCSSVal = (elm: HTMLElement, computedStyle: CSSStyleDeclaration, prop: string): string =>
/* istanbul ignore next */ /* istanbul ignore next */
computedStyle != null computedStyle != null
? computedStyle[prop] || computedStyle.getPropertyValue(prop) ? computedStyle[prop] || computedStyle.getPropertyValue(prop)
: elm.style[prop]; : elm.style[prop];
const setCSSVal = ( const setCSSVal = (
elm: HTMLElement | false | null | undefined, elm: HTMLElement | false | null | undefined,
prop: string, prop: string,
@@ -24,21 +24,32 @@ export const createEventListenerHub = <EventMap extends Record<string, any[]>>(
type EventListener<Name extends keyof EventMap = keyof EventMap> = ( type EventListener<Name extends keyof EventMap = keyof EventMap> = (
...args: EventMap[Name] ...args: EventMap[Name]
) => void; ) => void;
type RemoveEvent = {
<Name extends keyof EventMap>(name?: Name, listener?: EventListener<Name>): void;
<Name extends keyof EventMap>(name?: Name, listener?: EventListener<Name>[]): void;
<Name extends keyof EventMap>(
name?: Name,
listener?: EventListener<Name> | EventListener<Name>[]
): void;
};
type AddEvent = {
<Name extends keyof EventMap>(name: Name, listener: EventListener<Name>): () => void;
<Name extends keyof EventMap>(name: Name, listener: EventListener<Name>[]): () => void;
<Name extends keyof EventMap>(
name: Name,
listener: EventListener<Name> | EventListener<Name>[]
): () => void;
};
type TriggerEvent = {
<Name extends keyof EventMap>(name: Name, args?: EventMap[Name]): void;
};
const events = new Map<keyof EventMap, Set<EventListener>>(); const events = new Map<keyof EventMap, Set<EventListener>>();
function removeEvent<Name extends keyof EventMap>( const removeEvent: RemoveEvent = <Name extends keyof EventMap>(
name?: Name,
listener?: EventListener<Name>
): void;
function removeEvent<Name extends keyof EventMap>(
name?: Name,
listener?: EventListener<Name>[]
): void;
function removeEvent<Name extends keyof EventMap>(
name?: Name, name?: Name,
listener?: EventListener<Name> | EventListener<Name>[] listener?: EventListener<Name> | EventListener<Name>[]
): void { ): void => {
if (name) { if (name) {
const eventSet = events.get(name); const eventSet = events.get(name);
manageListener((currListener) => { manageListener((currListener) => {
@@ -52,20 +63,12 @@ export const createEventListenerHub = <EventMap extends Record<string, any[]>>(
}); });
events.clear(); events.clear();
} }
} };
function addEvent<Name extends keyof EventMap>( const addEvent: AddEvent = <Name extends keyof EventMap>(
name: Name,
listener: EventListener<Name>
): () => void;
function addEvent<Name extends keyof EventMap>(
name: Name,
listener: EventListener<Name>[]
): () => void;
function addEvent<Name extends keyof EventMap>(
name: Name, name: Name,
listener: EventListener<Name> | EventListener<Name>[] listener: EventListener<Name> | EventListener<Name>[]
): () => void { ): (() => void) => {
const eventSet = events.get(name) || new Set(); const eventSet = events.get(name) || new Set();
events.set(name, eventSet); events.set(name, eventSet);
@@ -74,9 +77,12 @@ export const createEventListenerHub = <EventMap extends Record<string, any[]>>(
}, listener as any); }, listener as any);
return removeEvent.bind(0, name as any, listener as any); return removeEvent.bind(0, name as any, listener as any);
} };
function triggerEvent<Name extends keyof EventMap>(name: Name, args?: EventMap[Name]): void { const triggerEvent: TriggerEvent = <Name extends keyof EventMap>(
name: Name,
args?: EventMap[Name]
): void => {
const eventSet = events.get(name); const eventSet = events.get(name);
each(from(eventSet), (event) => { each(from(eventSet), (event) => {
@@ -86,16 +92,12 @@ export const createEventListenerHub = <EventMap extends Record<string, any[]>>(
(event as () => void)(); (event as () => void)();
} }
}); });
} };
const initialListenerKeys = keys(initialEventListeners) as Extract<keyof EventMap, string>[]; const initialListenerKeys = keys(initialEventListeners) as Extract<keyof EventMap, string>[];
each(initialListenerKeys, (key) => { each(initialListenerKeys, (key) => {
addEvent(key, initialEventListeners![key] as any); addEvent(key, initialEventListeners![key] as any);
}); });
return [addEvent, removeEvent, triggerEvent] as [ return [addEvent, removeEvent, triggerEvent] as [AddEvent, RemoveEvent, TriggerEvent];
typeof addEvent,
typeof removeEvent,
typeof triggerEvent
];
}; };
@@ -35,9 +35,9 @@ export function each(
callback: (value: any, indexOrKey: string, source: PlainObject) => boolean | unknown callback: (value: any, indexOrKey: string, source: PlainObject) => boolean | unknown
): PlainObject | null | undefined; ): PlainObject | null | undefined;
export function each<T>( export function each<T>(
source: ArrayLike<T> | PlainObject | null | undefined, source: Array<T> | ArrayLike<T> | ReadonlyArray<T> | PlainObject | null | undefined,
callback: (value: T, indexOrKey: any, source: any) => boolean | unknown callback: (value: T, indexOrKey: any, source: any) => boolean | unknown
): Array<T> | ReadonlyArray<T> | ArrayLike<T> | PlainObject | null | undefined { ): Array<T> | ArrayLike<T> | ReadonlyArray<T> | PlainObject | null | undefined {
if (isArrayLike(source)) { if (isArrayLike(source)) {
for (let i = 0; i < source.length; i++) { for (let i = 0; i < source.length; i++) {
if (callback(source[i], i, source) === false) { if (callback(source[i], i, source) === false) {
@@ -76,11 +76,13 @@ export const push = <T>(array: T[], items: T | ArrayLike<T>, arrayIsSingleItem?:
* @param arr The object from which the array instance shall be created. * @param arr The object from which the array instance shall be created.
*/ */
export const from = <T = any>(arr?: ArrayLike<T> | Set<T>) => { export const from = <T = any>(arr?: ArrayLike<T> | Set<T>) => {
if (Array.from && arr) { const original = Array.from;
return Array.from(arr);
}
const result: T[] = []; const result: T[] = [];
if (original && arr) {
return original(arr);
}
if (arr instanceof Set) { if (arr instanceof Set) {
arr.forEach((value) => { arr.forEach((value) => {
push(result, value); push(result, value);
@@ -107,18 +109,9 @@ export const isEmptyArray = (array: any[] | null | undefined): boolean =>
* @param args The args with which each function is called. * @param args The args with which each function is called.
* @param keep True when the Set / array should not be cleared afterwards, false otherwise. * @param keep True when the Set / array should not be cleared afterwards, false otherwise.
*/ */
export const runEachAndClear = ( export const runEachAndClear = (arr: RunEachItem[], args?: any[], keep?: boolean): void => {
arr: ArrayLike<RunEachItem> | Set<RunEachItem>,
args?: any[],
keep?: boolean
): void => {
// eslint-disable-next-line prefer-spread // eslint-disable-next-line prefer-spread
const runFn = (fn: RunEachItem) => fn && fn.apply(undefined, args || []); const runFn = (fn: RunEachItem) => fn && fn.apply(undefined, args || []);
if (arr instanceof Set) { each(arr, runFn);
arr.forEach(runFn); !keep && ((arr as any[]).length = 0);
!keep && arr.clear();
} else {
each(arr, runFn);
!keep && (arr as any[]).splice && (arr as any[]).splice(0, arr.length);
}
}; };
@@ -15,31 +15,30 @@ export const hasOwnProperty = (obj: any, prop: string | number | symbol): boolea
*/ */
export const keys = (obj: any): Array<string> => (obj ? Object.keys(obj) : []); export const keys = (obj: any): Array<string> => (obj ? Object.keys(obj) : []);
type AssignDeep = {
<T, U>(target: T, object1: U): T & U;
<T, U, V>(target: T, object1: U, object2: V): T & U & V;
<T, U, V, W>(target: T, object1: U, object2: V, object3: W): T & U & V & W;
<T, U, V, W, X>(target: T, object1: U, object2: V, object3: W, object4: X): T & U & V & W & X;
<T, U, V, W, X, Y>(target: T, object1: U, object2: V, object3: W, object4: X, object5: Y): T &
U &
V &
W &
X &
Y;
<T, U, V, W, X, Y, Z>(
target: T,
object1?: U,
object2?: V,
object3?: W,
object4?: X,
object5?: Y,
object6?: Z
): T & U & V & W & X & Y & Z;
};
// https://github.com/jquery/jquery/blob/master/src/core.js#L116 // https://github.com/jquery/jquery/blob/master/src/core.js#L116
export function assignDeep<T, U>(target: T, object1: U): T & U; export const assignDeep: AssignDeep = <T, U, V, W, X, Y, Z>(
export function assignDeep<T, U, V>(target: T, object1: U, object2: V): T & U & V;
export function assignDeep<T, U, V, W>(
target: T,
object1: U,
object2: V,
object3: W
): T & U & V & W;
export function assignDeep<T, U, V, W, X>(
target: T,
object1: U,
object2: V,
object3: W,
object4: X
): T & U & V & W & X;
export function assignDeep<T, U, V, W, X, Y>(
target: T,
object1: U,
object2: V,
object3: W,
object4: X,
object5: Y
): T & U & V & W & X & Y;
export function assignDeep<T, U, V, W, X, Y, Z>(
target: T, target: T,
object1?: U, object1?: U,
object2?: V, object2?: V,
@@ -47,7 +46,7 @@ export function assignDeep<T, U, V, W, X, Y, Z>(
object4?: X, object4?: X,
object5?: Y, object5?: Y,
object6?: Z object6?: Z
): T & U & V & W & X & Y & Z { ): T & U & V & W & X & Y & Z => {
const sources: Array<any> = [object1, object2, object3, object4, object5, object6]; const sources: Array<any> = [object1, object2, object3, object4, object5, object6];
// Handle case when target is a string or something (possible in deep copy) // Handle case when target is a string or something (possible in deep copy)
@@ -90,15 +89,15 @@ export function assignDeep<T, U, V, W, X, Y, Z>(
// Return the modified object // Return the modified object
return target as any; return target as any;
} };
/** /**
* Returns true if the given object is empty, false otherwise. * Returns true if the given object is empty, false otherwise.
* @param obj The Object. * @param obj The Object.
*/ */
export function isEmptyObject(obj: any): boolean { export const isEmptyObject = (obj: any): boolean => {
/* eslint-disable no-restricted-syntax, guard-for-in */ /* eslint-disable no-restricted-syntax, guard-for-in */
for (const name in obj) return false; for (const name in obj) return false;
return true; return true;
/* eslint-enable */ /* eslint-enable */
} };
@@ -3,15 +3,11 @@ import { PlainObject } from 'typings';
const ElementNodeType = Node.ELEMENT_NODE; const ElementNodeType = Node.ELEMENT_NODE;
const { toString, hasOwnProperty } = Object.prototype; const { toString, hasOwnProperty } = Object.prototype;
export function isUndefined(obj: any): obj is undefined { export const isUndefined = (obj: any): obj is undefined => obj === undefined;
return obj === undefined;
}
export function isNull(obj: any): obj is null { export const isNull = (obj: any): obj is null => obj === null;
return obj === null;
}
export const type: (obj: any) => string = (obj) => export const type = (obj: any): string =>
isUndefined(obj) || isNull(obj) isUndefined(obj) || isNull(obj)
? `${obj}` ? `${obj}`
: toString : toString
@@ -19,35 +15,24 @@ export const type: (obj: any) => string = (obj) =>
.replace(/^\[object (.+)\]$/, '$1') .replace(/^\[object (.+)\]$/, '$1')
.toLowerCase(); .toLowerCase();
export function isNumber(obj: any): obj is number { export const isNumber = (obj: any): obj is number => typeof obj === 'number';
return typeof obj === 'number';
}
export function isString(obj: any): obj is string { export const isString = (obj: any): obj is string => typeof obj === 'string';
return typeof obj === 'string';
}
export function isBoolean(obj: any): obj is boolean { export const isBoolean = (obj: any): obj is boolean => typeof obj === 'boolean';
return typeof obj === 'boolean';
}
export function isFunction(obj: any): obj is (...args: any[]) => any { export const isFunction = (obj: any): obj is (...args: any[]) => any => typeof obj === 'function';
return typeof obj === 'function';
}
export function isArray(obj: any): obj is Array<any> { export const isArray = <T = any>(obj: any): obj is Array<T> => Array.isArray(obj);
return Array.isArray(obj);
}
export function isObject(obj: any): boolean { export const isObject = (obj: any): boolean =>
return typeof obj === 'object' && !isArray(obj) && !isNull(obj); typeof obj === 'object' && !isArray(obj) && !isNull(obj);
}
/** /**
* Returns true if the given object is array like, false otherwise. * Returns true if the given object is array like, false otherwise.
* @param obj The Object * @param obj The Object
*/ */
export function isArrayLike<T extends PlainObject = any>(obj: any): obj is ArrayLike<T> { export const isArrayLike = <T extends PlainObject = any>(obj: any): obj is ArrayLike<T> => {
const length = !!obj && obj.length; const length = !!obj && obj.length;
const lengthCorrectFormat = isNumber(length) && length > -1 && length % 1 == 0; // eslint-disable-line eqeqeq const lengthCorrectFormat = isNumber(length) && length > -1 && length % 1 == 0; // eslint-disable-line eqeqeq
@@ -56,13 +41,13 @@ export function isArrayLike<T extends PlainObject = any>(obj: any): obj is Array
? length - 1 in obj ? length - 1 in obj
: true : true
: false; : false;
} };
/** /**
* Returns true if the given object is a "plain" (e.g. { key: value }) object, false otherwise. * Returns true if the given object is a "plain" (e.g. { key: value }) object, false otherwise.
* @param obj The Object. * @param obj The Object.
*/ */
export function isPlainObject<T = any>(obj: any): obj is PlainObject<T> { export const isPlainObject = <T = any>(obj: any): obj is PlainObject<T> => {
if (!obj || !isObject(obj) || type(obj) !== 'object') return false; if (!obj || !isObject(obj) || type(obj) !== 'object') return false;
let key; let key;
@@ -83,30 +68,30 @@ export function isPlainObject<T = any>(obj: any): obj is PlainObject<T> {
/* eslint-enable */ /* eslint-enable */
return isUndefined(key) || hasOwnProperty.call(obj, key); return isUndefined(key) || hasOwnProperty.call(obj, key);
} };
/** /**
* Checks whether the given object is a HTMLElement. * Checks whether the given object is a HTMLElement.
* @param obj The object which shall be checked. * @param obj The object which shall be checked.
*/ */
export function isHTMLElement(obj: any): obj is HTMLElement { export const isHTMLElement = (obj: any): obj is HTMLElement => {
const instanceofObj = window.HTMLElement; const instanceofObj = window.HTMLElement;
return obj return obj
? instanceofObj ? instanceofObj
? obj instanceof instanceofObj ? obj instanceof instanceofObj
: obj.nodeType === ElementNodeType : obj.nodeType === ElementNodeType
: false; : false;
} };
/** /**
* Checks whether the given object is a Element. * Checks whether the given object is a Element.
* @param obj The object which shall be checked. * @param obj The object which shall be checked.
*/ */
export function isElement(obj: any): obj is Element { export const isElement = (obj: any): obj is Element => {
const instanceofObj = window.Element; const instanceofObj = window.Element;
return obj return obj
? instanceofObj ? instanceofObj
? obj instanceof instanceofObj ? obj instanceof instanceofObj
: obj.nodeType === ElementNodeType : obj.nodeType === ElementNodeType
: false; : false;
} };
@@ -2,12 +2,10 @@ import { createCache } from 'support/cache';
const createUpdater = <T>(updaterReturn: (i: number) => T) => { const createUpdater = <T>(updaterReturn: (i: number) => T) => {
let index = 0; let index = 0;
const updater = jest.fn( const updater = jest.fn((): T => {
(): T => { index += 1;
index += 1; return updaterReturn(index);
return updaterReturn(index); });
}
);
return updater; return updater;
}; };
@@ -16,7 +14,7 @@ describe('cache', () => {
test('creates and updates cache', () => { test('creates and updates cache', () => {
const updater = createUpdater((i) => `${i}`); const updater = createUpdater((i) => `${i}`);
const _initialValue = ''; const _initialValue = '';
const [updateCache, getCurrentCache] = createCache<string>( const [updateCache, getCurrentCache] = createCache(
{ {
_initialValue, _initialValue,
}, },
@@ -1,7 +1,17 @@
import { off, preventDefault, stopPropagation, stopAndPrevent, OnOptions } from 'support/dom/events'; import {
off,
preventDefault,
stopPropagation,
stopAndPrevent,
OnOptions,
} from 'support/dom/events';
const testElm = document.body; const testElm = document.body;
const mockEventListener = (passive?: boolean, add?: (...args: any) => any, remove?: (...args: any) => any) => { const mockEventListener = (
passive?: boolean,
add?: (...args: any) => any,
remove?: (...args: any) => any
) => {
const originalAdd = testElm.addEventListener; const originalAdd = testElm.addEventListener;
const originalRemove = testElm.removeEventListener; const originalRemove = testElm.removeEventListener;
const originalWindow = window.addEventListener; const originalWindow = window.addEventListener;
@@ -59,23 +69,31 @@ describe('dom events', () => {
const removeFn = eventsModule.on(testElm, eventNames, eventListener, options); const removeFn = eventsModule.on(testElm, eventNames, eventListener, options);
eventNames.split(' ').forEach((eventName, index) => { eventNames.split(' ').forEach((eventName, index) => {
expect(mockFnAdd).toHaveBeenCalledWith(eventName, once ? onceListeners[index] : eventListener, expectObjAdd); expect(mockFnAdd).toHaveBeenCalledWith(
eventName,
once ? onceListeners[index] : eventListener,
expectObjAdd
);
}); });
removeFn(); removeFn();
eventNames.split(' ').forEach((eventName, index) => { eventNames.split(' ').forEach((eventName, index) => {
expect(mockFnRemove).toHaveBeenCalledWith(eventName, once ? onceListeners[index] : eventListener, expectObjRemove); expect(mockFnRemove).toHaveBeenCalledWith(
eventName,
once ? onceListeners[index] : eventListener,
expectObjRemove
);
}); });
revert(); revert();
}; };
beforeEach(() => { beforeEach(() =>
return import('support/dom/events').then((module) => { import('support/dom/events').then((module) => {
eventsModule = module; eventsModule = module;
jest.resetModules(); jest.resetModules();
}); })
}); );
[true, false].forEach((passiveSupport) => { [true, false].forEach((passiveSupport) => {
describe(`passive event listeners support: ${passiveSupport}`, () => { describe(`passive event listeners support: ${passiveSupport}`, () => {
@@ -301,18 +301,6 @@ describe('array utilities', () => {
runEachAndClear(arr, ['a', 'b', 'c', 'd']); runEachAndClear(arr, ['a', 'b', 'c', 'd']);
expect(arr.length).toBe(0); expect(arr.length).toBe(0);
}); });
test('set', () => {
const set = new Set([jest.fn(), null, jest.fn(), undefined, jest.fn()]);
runEachAndClear(set, [1, 2, 3, 4], true);
set.forEach((fn) => {
if (fn) {
expect(fn).toHaveBeenCalledWith(1, 2, 3, 4);
}
});
runEachAndClear(set, [1, 2, 3, 4]);
expect(set.size).toBe(0);
});
}); });
test('indexOf', () => { test('indexOf', () => {
@@ -73,7 +73,9 @@ describe('types', () => {
expect(type(new Number(3))).toBe('number'); expect(type(new Number(3))).toBe('number');
expect(type('test')).toBe('string'); expect(type('test')).toBe('string');
expect(type(new String('test'))).toBe('string'); expect(type(new String('test'))).toBe('string');
// eslint-disable-next-line prefer-arrow-callback
expect(type(function () {})).toBe('function'); expect(type(function () {})).toBe('function');
expect(type(() => {})).toBe('function');
expect(type([])).toBe('array'); expect(type([])).toBe('array');
expect(type([])).toBe('array'); expect(type([])).toBe('array');
expect(type(new Date())).toBe('date'); expect(type(new Date())).toBe('date');
+1 -1
View File
@@ -173,7 +173,7 @@ type GeneralInitialEventListeners = InitialEventListeners;
type GeneralEventListener = EventListener; type GeneralEventListener = EventListener;
interface OverlayScrollbarsStatic { interface OverlayScrollbarsStatic {
(target: InitializationTarget | InitializationTargetObject, options?: PartialOptions<Options>, eventListeners?: GeneralInitialEventListeners<EventListenerMap>): OverlayScrollbars; (target: InitializationTarget | InitializationTargetObject, options?: PartialOptions<Options>, eventListeners?: GeneralInitialEventListeners<EventListenerMap>): OverlayScrollbars;
plugin(osPlugin: Plugin | Plugin[]): void; plugin(plugin: Plugin | Plugin[]): void;
env(): Environment; env(): Environment;
} }
interface Environment { interface Environment {