mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-19 13:20:36 +03:00
add clickScrollPlguin for click scrolling support
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { animateNumber, noop } from 'support';
|
||||
import type { Plugin } from 'plugins';
|
||||
|
||||
export type ClickScrollPluginInstance = {
|
||||
_: (
|
||||
moveHandleRelative: (deltaMovement: number) => void,
|
||||
getHandleOffset: (handleRect?: DOMRect, trackRect?: DOMRect) => number,
|
||||
startOffset: number,
|
||||
handleLength: number,
|
||||
relativeTrackPointerOffset: number
|
||||
) => () => void;
|
||||
};
|
||||
|
||||
export const clickScrollPluginName = '__osClickScrollPlugin';
|
||||
|
||||
export const clickScrollPlugin: Plugin<ClickScrollPluginInstance> = /* @__PURE__ */ (() => ({
|
||||
[clickScrollPluginName]: {
|
||||
_: (
|
||||
moveHandleRelative,
|
||||
getHandleOffset,
|
||||
startOffset,
|
||||
handleLength,
|
||||
relativeTrackPointerOffset
|
||||
) => {
|
||||
// click scroll animation
|
||||
let iteration = 0;
|
||||
let clear = noop;
|
||||
const animateClickScroll = (clickScrollProgress: number) => {
|
||||
clear = animateNumber(
|
||||
clickScrollProgress,
|
||||
clickScrollProgress + handleLength * Math.sign(startOffset),
|
||||
133,
|
||||
(animationProgress, _, animationCompleted) => {
|
||||
moveHandleRelative(animationProgress);
|
||||
const handleStartBound = getHandleOffset();
|
||||
const handleEndBound = handleStartBound + handleLength;
|
||||
const mouseBetweenHandleBounds =
|
||||
relativeTrackPointerOffset >= handleStartBound &&
|
||||
relativeTrackPointerOffset <= handleEndBound;
|
||||
|
||||
if (animationCompleted && !mouseBetweenHandleBounds) {
|
||||
if (iteration) {
|
||||
animateClickScroll(animationProgress);
|
||||
} else {
|
||||
const firstIterationPauseTimeout = setTimeout(() => {
|
||||
animateClickScroll(animationProgress);
|
||||
}, 222);
|
||||
clear = () => {
|
||||
clearTimeout(firstIterationPauseTimeout);
|
||||
};
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
animateClickScroll(0);
|
||||
|
||||
return () => clear();
|
||||
},
|
||||
},
|
||||
}))();
|
||||
@@ -0,0 +1 @@
|
||||
export * from 'plugins/clickScrollPlugin/clickScrollPlugin';
|
||||
@@ -2,3 +2,4 @@ export * from './plugins';
|
||||
export * from './optionsValidationPlugin';
|
||||
export * from './sizeObserverPlugin';
|
||||
export * from './scrollbarsHidingPlugin';
|
||||
export * from './clickScrollPlugin';
|
||||
|
||||
@@ -10,17 +10,16 @@ import {
|
||||
selfClearTimeout,
|
||||
parent,
|
||||
closest,
|
||||
rAF,
|
||||
cAF,
|
||||
push,
|
||||
noop,
|
||||
} from 'support';
|
||||
import { getPlugins, clickScrollPluginName } from 'plugins';
|
||||
import { getEnvironment } from 'environment';
|
||||
import {
|
||||
classNameScrollbarHandle,
|
||||
classNamesScrollbarInteraction,
|
||||
classNamesScrollbarWheel,
|
||||
} from 'classnames';
|
||||
import type { ClickScrollPluginInstance } from 'plugins';
|
||||
import type { ReadonlyOptions } from 'options';
|
||||
import type { StructureSetupState } from 'setups';
|
||||
import type {
|
||||
@@ -37,31 +36,7 @@ export type ScrollbarsSetupEvents = (
|
||||
isHorizontal?: boolean
|
||||
) => () => void;
|
||||
|
||||
const { round, max, sign } = Math;
|
||||
const animationCurrentTime = () => performance.now();
|
||||
const animateNumber = (
|
||||
from: number,
|
||||
to: number,
|
||||
duration: number,
|
||||
onFrame: (progress: number, completed: boolean) => any
|
||||
) => {
|
||||
let animationFrameId = 0;
|
||||
const timeStart = animationCurrentTime();
|
||||
const frame = () => {
|
||||
const timeNow = animationCurrentTime();
|
||||
const timeElapsed = timeNow - timeStart;
|
||||
const stopAnimation = timeElapsed >= duration;
|
||||
const percent = 1 - (max(0, timeStart + duration - timeNow) / duration || 0);
|
||||
const progress = (to - from) * percent + from;
|
||||
const animationCompleted = stopAnimation || percent === 1;
|
||||
|
||||
onFrame(progress, animationCompleted);
|
||||
|
||||
animationFrameId = animationCompleted ? 0 : rAF!(frame);
|
||||
};
|
||||
frame();
|
||||
return () => cAF!(animationFrameId);
|
||||
};
|
||||
const { round } = Math;
|
||||
const getScale = (element: HTMLElement): XY<number> => {
|
||||
const { width, height } = getBoundingClientRect(element);
|
||||
const { w, h } = offsetSize(element);
|
||||
@@ -108,8 +83,7 @@ const createInteractiveScrollEvents = (
|
||||
const leftTopKey = isHorizontal ? 'left' : 'top'; // for BCR (can't use xy because of IE11)
|
||||
const whKey = isHorizontal ? 'w' : 'h';
|
||||
const xyKey = isHorizontal ? 'x' : 'y';
|
||||
const getHandleOffset = (handleRect: DOMRect, trackRect: DOMRect) =>
|
||||
handleRect[leftTopKey] - trackRect[leftTopKey];
|
||||
|
||||
const createRelativeHandleMove =
|
||||
(mouseDownScroll: number, invertedScale: number) => (deltaMovement: number) => {
|
||||
const { _overflowAmount } = structureSetupState();
|
||||
@@ -129,13 +103,17 @@ const createInteractiveScrollEvents = (
|
||||
|
||||
if (continuePointerDown(pointerDownEvent, options, isDragScroll)) {
|
||||
const instantClickScroll = !isDragScroll && pointerDownEvent.shiftKey;
|
||||
const getHandleRect = () => getBoundingClientRect(_handle);
|
||||
const getTrackRect = () => getBoundingClientRect(_track);
|
||||
const getHandleOffset = (handleRect?: DOMRect, trackRect?: DOMRect) =>
|
||||
(handleRect || getHandleRect())[leftTopKey] - (trackRect || getTrackRect())[leftTopKey];
|
||||
const moveHandleRelative = createRelativeHandleMove(
|
||||
scrollOffsetElement[scrollLeftTopKey] || 0,
|
||||
1 / getScale(scrollOffsetElement)[xyKey]
|
||||
);
|
||||
const pointerDownOffset = pointerDownEvent[clientXYKey];
|
||||
const handleRect = getBoundingClientRect(_handle);
|
||||
const trackRect = getBoundingClientRect(_track);
|
||||
const handleRect = getHandleRect();
|
||||
const trackRect = getTrackRect();
|
||||
const handleLength = handleRect[widthHeightKey];
|
||||
const handleCenter = getHandleOffset(handleRect, trackRect) + handleLength / 2;
|
||||
const relativeTrackPointerOffset = pointerDownOffset - trackRect[leftTopKey];
|
||||
@@ -157,42 +135,22 @@ const createInteractiveScrollEvents = (
|
||||
if (instantClickScroll) {
|
||||
moveHandleRelative(startOffset);
|
||||
} else if (!isDragScroll) {
|
||||
// click scroll animation
|
||||
let iteration = 0;
|
||||
let clear = noop;
|
||||
const animateClickScroll = (clickScrollProgress: number) => {
|
||||
clear = animateNumber(
|
||||
clickScrollProgress,
|
||||
clickScrollProgress + handleLength * sign(startOffset),
|
||||
133,
|
||||
(animationProgress, animationCompleted) => {
|
||||
moveHandleRelative(animationProgress);
|
||||
const handleStartBound = getHandleOffset(getBoundingClientRect(_handle), trackRect);
|
||||
const handleEndBound = handleStartBound + handleLength;
|
||||
const mouseBetweenHandleBounds =
|
||||
relativeTrackPointerOffset >= handleStartBound &&
|
||||
relativeTrackPointerOffset <= handleEndBound;
|
||||
const sizeObserverPlugin = getPlugins()[clickScrollPluginName] as
|
||||
| ClickScrollPluginInstance
|
||||
| undefined;
|
||||
|
||||
if (animationCompleted && !mouseBetweenHandleBounds) {
|
||||
if (iteration) {
|
||||
animateClickScroll(animationProgress);
|
||||
} else {
|
||||
const firstIterationPauseTimeout = setTimeout(() => {
|
||||
animateClickScroll(animationProgress);
|
||||
}, 222);
|
||||
clear = () => {
|
||||
clearTimeout(firstIterationPauseTimeout);
|
||||
};
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
if (sizeObserverPlugin) {
|
||||
push(
|
||||
offFns,
|
||||
sizeObserverPlugin._(
|
||||
moveHandleRelative,
|
||||
getHandleOffset,
|
||||
startOffset,
|
||||
handleLength,
|
||||
relativeTrackPointerOffset
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
animateClickScroll(0);
|
||||
|
||||
push(offFns, () => clear());
|
||||
}
|
||||
}
|
||||
|
||||
on(
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { rAF, cAF } from 'support/compatibility';
|
||||
import { isFunction } from 'support/utils';
|
||||
|
||||
const { max } = Math;
|
||||
const animationCurrentTime = () => performance.now();
|
||||
|
||||
/**
|
||||
* percent: current percent (0 - 1),
|
||||
* time: current time (duration * percent),
|
||||
* min: start value
|
||||
* max: end value
|
||||
* duration: duration in ms
|
||||
*/
|
||||
export type EasingFn = (
|
||||
percent: number,
|
||||
time: number,
|
||||
min: number,
|
||||
max: number,
|
||||
duration: number
|
||||
) => number;
|
||||
|
||||
export const animateNumber = (
|
||||
from: number,
|
||||
to: number,
|
||||
duration: number,
|
||||
onFrame: (progress: number, percent: number, completed: boolean) => any,
|
||||
easing?: EasingFn | false
|
||||
): ((complete?: boolean) => void) => {
|
||||
let animationFrameId = 0;
|
||||
const timeStart = animationCurrentTime();
|
||||
const finalDuration = Math.max(0, duration);
|
||||
const frame = (complete?: boolean) => {
|
||||
const timeNow = animationCurrentTime();
|
||||
const timeElapsed = timeNow - timeStart;
|
||||
const stopAnimation = timeElapsed >= finalDuration;
|
||||
const percent = complete
|
||||
? 1
|
||||
: 1 - (max(0, timeStart + finalDuration - timeNow) / finalDuration || 0);
|
||||
const progress =
|
||||
(to - from) *
|
||||
(isFunction(easing)
|
||||
? easing(percent, percent * finalDuration, 0, 1, finalDuration)
|
||||
: percent) +
|
||||
from;
|
||||
const animationCompleted = stopAnimation || percent === 1;
|
||||
|
||||
onFrame && onFrame(progress, percent, animationCompleted);
|
||||
|
||||
animationFrameId = animationCompleted ? 0 : rAF!(() => frame());
|
||||
};
|
||||
frame();
|
||||
return (complete) => {
|
||||
cAF!(animationFrameId);
|
||||
complete && frame(complete);
|
||||
};
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from 'support/dom/animation';
|
||||
export * from 'support/dom/attribute';
|
||||
export * from 'support/dom/class';
|
||||
export * from 'support/dom/create';
|
||||
|
||||
@@ -9,9 +9,11 @@ jest.mock('support/compatibility/apis', () => {
|
||||
...originalModule,
|
||||
// @ts-ignore
|
||||
rAF: jest.fn().mockImplementation((...args) => mockRAF(...args)),
|
||||
// @ts-ignore
|
||||
cAF: jest.fn().mockImplementation((...args) => clearTimeout(...args)),
|
||||
// @ts-ignore
|
||||
setT: jest.fn().mockImplementation((...args) => setTimeout(...args)),
|
||||
// @ts-ignore
|
||||
clearT: jest.fn().mockImplementation((...args) => clearTimeout(...args)),
|
||||
};
|
||||
});
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ jest.mock('support/compatibility/apis', () => {
|
||||
...originalModule,
|
||||
// @ts-ignore
|
||||
setT: jest.fn().mockImplementation((...args) => setTimeout(...args)),
|
||||
// @ts-ignore
|
||||
clearT: jest.fn().mockImplementation((...args) => clearTimeout(...args)),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
import { animateNumber } from 'support/dom/animation';
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
jest.mock('support/compatibility/apis', () => {
|
||||
const originalModule = jest.requireActual('support/compatibility/apis');
|
||||
const mockRAF = (arg: any) => setTimeout(arg, 0);
|
||||
return {
|
||||
...originalModule,
|
||||
// @ts-ignore
|
||||
rAF: jest.fn().mockImplementation((...args) => mockRAF(...args)),
|
||||
// @ts-ignore
|
||||
cAF: jest.fn().mockImplementation((...args) => clearTimeout(...args)),
|
||||
// @ts-ignore
|
||||
setT: jest.fn().mockImplementation((...args) => setTimeout(...args)),
|
||||
// @ts-ignore
|
||||
clearT: jest.fn().mockImplementation((...args) => clearTimeout(...args)),
|
||||
};
|
||||
});
|
||||
|
||||
describe('dom animation', () => {
|
||||
describe('animateNumber', () => {
|
||||
test('animate 0 to 1', () => {
|
||||
const onFrame = jest.fn();
|
||||
expect(onFrame).not.toHaveBeenCalled();
|
||||
|
||||
animateNumber(0, 1, 500, onFrame);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(0, 0, false);
|
||||
|
||||
jest.advanceTimersByTime(250);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(252);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(0.5, 0.5, false);
|
||||
|
||||
jest.advanceTimersByTime(250);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(502);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(1, 1, true);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(502);
|
||||
});
|
||||
|
||||
test('animate 1 to 0', () => {
|
||||
const onFrame = jest.fn();
|
||||
expect(onFrame).not.toHaveBeenCalled();
|
||||
|
||||
animateNumber(1, 0, 1000, onFrame);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(1, 0, false);
|
||||
|
||||
jest.advanceTimersByTime(500);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(502);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(0.5, 0.5, false);
|
||||
|
||||
jest.advanceTimersByTime(500);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1002);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(0, 1, true);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1002);
|
||||
});
|
||||
|
||||
test('animate duration 0', () => {
|
||||
const onFrame = jest.fn();
|
||||
expect(onFrame).not.toHaveBeenCalled();
|
||||
|
||||
animateNumber(0, 100, 0, onFrame);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(100, 1, true);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('animate negative duration', () => {
|
||||
const onFrame = jest.fn();
|
||||
expect(onFrame).not.toHaveBeenCalled();
|
||||
|
||||
animateNumber(0, 100, -100, onFrame);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(100, 1, true);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('animate with easing and fractions', () => {
|
||||
const onFrame = jest.fn();
|
||||
const onFrameB = jest.fn();
|
||||
expect(onFrame).not.toHaveBeenCalled();
|
||||
expect(onFrameB).not.toHaveBeenCalled();
|
||||
|
||||
animateNumber(25.2, 55.5, 1000, onFrame, (percent) => percent);
|
||||
animateNumber(25.2, 55.5, 1000, onFrameB);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
expect(onFrameB).toHaveBeenCalledTimes(1);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(25.2, 0, false);
|
||||
expect(onFrameB).toHaveBeenLastCalledWith(25.2, 0, false);
|
||||
|
||||
jest.advanceTimersByTime(250);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(252);
|
||||
expect(onFrameB).toHaveBeenCalledTimes(252);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(32.775, 0.25, false);
|
||||
expect(onFrameB).toHaveBeenLastCalledWith(32.775, 0.25, false);
|
||||
|
||||
jest.advanceTimersByTime(250);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(502);
|
||||
expect(onFrameB).toHaveBeenCalledTimes(502);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(40.35, 0.5, false);
|
||||
expect(onFrameB).toHaveBeenLastCalledWith(40.35, 0.5, false);
|
||||
|
||||
jest.advanceTimersByTime(100);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(602);
|
||||
expect(onFrameB).toHaveBeenCalledTimes(602);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(43.379999999999995, 0.6, false);
|
||||
expect(onFrameB).toHaveBeenLastCalledWith(43.379999999999995, 0.6, false);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1002);
|
||||
expect(onFrameB).toHaveBeenCalledTimes(1002);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(55.5, 1, true);
|
||||
expect(onFrameB).toHaveBeenLastCalledWith(55.5, 1, true);
|
||||
});
|
||||
|
||||
test('animate and stop animation', () => {
|
||||
const onFrame = jest.fn();
|
||||
expect(onFrame).not.toHaveBeenCalled();
|
||||
|
||||
const stop = animateNumber(1, 0, 1000, onFrame);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(1, 0, false);
|
||||
|
||||
stop();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
|
||||
jest.advanceTimersByTime(500);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('animate and stop animation with complete', () => {
|
||||
const onFrame = jest.fn();
|
||||
expect(onFrame).not.toHaveBeenCalled();
|
||||
|
||||
const stop = animateNumber(0, 5555, 1000, onFrame);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(1);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(0, 0, false);
|
||||
|
||||
stop(true);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(2);
|
||||
expect(onFrame).toHaveBeenLastCalledWith(5555, 1, true);
|
||||
|
||||
jest.advanceTimersByTime(500);
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(2);
|
||||
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(onFrame).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,9 +10,11 @@ jest.mock('support/compatibility/apis', () => {
|
||||
...originalModule,
|
||||
// @ts-ignore
|
||||
rAF: jest.fn().mockImplementation((...args) => mockRAF(...args)),
|
||||
// @ts-ignore
|
||||
cAF: jest.fn().mockImplementation((...args) => clearTimeout(...args)),
|
||||
// @ts-ignore
|
||||
setT: jest.fn().mockImplementation((...args) => setTimeout(...args)),
|
||||
// @ts-ignore
|
||||
clearT: jest.fn().mockImplementation((...args) => clearTimeout(...args)),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -17,8 +17,8 @@ const normalizePath = (pathName) =>
|
||||
|
||||
const fixturesDir = path.join(__dirname, '.fixtures');
|
||||
const libraryFixturePath = normalizePath(path.join(fixturesDir, 'lib.js'));
|
||||
const unshakedFixturePath = normalizePath(path.join(fixturesDir, 'unshaked.js'));
|
||||
const shakedFixturePath = normalizePath(path.join(fixturesDir, 'shaked.js'));
|
||||
const normalFixturePath = normalizePath(path.join(fixturesDir, 'nromal.js'));
|
||||
const treeshakedFixturePath = normalizePath(path.join(fixturesDir, 'treeshaked.js'));
|
||||
|
||||
const unshakedFixtureContent = `
|
||||
export * as os from '${libraryFixturePath}';
|
||||
@@ -89,18 +89,24 @@ const bundleFunctions = {
|
||||
const testBundler = (bundlerName) => async () => {
|
||||
const bundleFunction = bundleFunctions[bundlerName];
|
||||
const outputDir = path.join(__dirname, `.${bundlerName}`);
|
||||
const unshaked = await bundleFunction(unshakedFixturePath, path.join(outputDir, 'unshaked.js'));
|
||||
const shaked = await bundleFunction(shakedFixturePath, path.join(outputDir, 'shaked.js'));
|
||||
const normal = await bundleFunction(
|
||||
normalFixturePath,
|
||||
path.join(outputDir, path.basename(normalFixturePath))
|
||||
);
|
||||
const treeshaked = await bundleFunction(
|
||||
treeshakedFixturePath,
|
||||
path.join(outputDir, path.basename(treeshakedFixturePath))
|
||||
);
|
||||
|
||||
cleanBundle && fs.rmSync(outputDir, { recursive: true });
|
||||
|
||||
console.info(`${bundlerName} size`, {
|
||||
unshaked,
|
||||
shaked,
|
||||
diff: unshaked - shaked,
|
||||
normal,
|
||||
treeshaked,
|
||||
diff: normal - treeshaked,
|
||||
});
|
||||
|
||||
expect(unshaked - shaked).toBeGreaterThan(expectedBundleDiff);
|
||||
expect(normal - treeshaked).toBeGreaterThan(expectedBundleDiff);
|
||||
};
|
||||
|
||||
describe('tree shaking', () => {
|
||||
@@ -131,8 +137,8 @@ describe('tree shaking', () => {
|
||||
fs.mkdirSync(fixturesDir);
|
||||
}
|
||||
|
||||
fs.writeFileSync(unshakedFixturePath, unshakedFixtureContent);
|
||||
fs.writeFileSync(shakedFixturePath, shakedFixtureContent);
|
||||
fs.writeFileSync(normalFixturePath, unshakedFixtureContent);
|
||||
fs.writeFileSync(treeshakedFixturePath, shakedFixtureContent);
|
||||
}, 60000 * 2);
|
||||
|
||||
// clean the fixture
|
||||
|
||||
+3
-1
@@ -32,7 +32,9 @@ import {
|
||||
} from 'support';
|
||||
import { Options } from 'options';
|
||||
import { DeepPartial } from 'typings';
|
||||
import { addPlugin, scrollbarsHidingPlugin, sizeObserverPlugin } from 'plugins';
|
||||
import { addPlugin, scrollbarsHidingPlugin, sizeObserverPlugin, clickScrollPlugin } from 'plugins';
|
||||
|
||||
addPlugin(clickScrollPlugin);
|
||||
|
||||
if (!window.ResizeObserver) {
|
||||
addPlugin(sizeObserverPlugin);
|
||||
|
||||
Reference in New Issue
Block a user