mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-05 21:52:26 +03:00
overflow calc
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -61,6 +61,7 @@ export interface Environment {
|
||||
export interface State {
|
||||
padding: TRBL;
|
||||
paddingAbsolute: boolean;
|
||||
overflowEdge: XY<number>;
|
||||
overflowAmount: XY<number>;
|
||||
overflowStyle: XY<OverflowStyle>;
|
||||
hasOverflow: XY<boolean>;
|
||||
@@ -80,6 +81,7 @@ export interface OnUpdatedEventListenerArgs {
|
||||
sizeChanged: boolean;
|
||||
directionChanged: boolean;
|
||||
heightIntrinsicChanged: boolean;
|
||||
overflowEdgeChanged: boolean;
|
||||
overflowAmountChanged: boolean;
|
||||
overflowStyleChanged: boolean;
|
||||
hostMutation: boolean;
|
||||
@@ -212,11 +214,18 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
||||
name && listener && removeEvent(name, listener as any);
|
||||
},
|
||||
state() {
|
||||
const { _overflowAmount, _overflowStyle, _hasOverflow, _padding, _paddingAbsolute } =
|
||||
structureState();
|
||||
const {
|
||||
_overflowEdge,
|
||||
_overflowAmount,
|
||||
_overflowStyle,
|
||||
_hasOverflow,
|
||||
_padding,
|
||||
_paddingAbsolute,
|
||||
} = structureState();
|
||||
return assignDeep(
|
||||
{},
|
||||
{
|
||||
overflowEdge: _overflowEdge,
|
||||
overflowAmount: _overflowAmount,
|
||||
overflowStyle: _overflowStyle,
|
||||
hasOverflow: _hasOverflow,
|
||||
@@ -273,6 +282,7 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
||||
_sizeChanged,
|
||||
_directionChanged,
|
||||
_heightIntrinsicChanged,
|
||||
_overflowEdgeChanged,
|
||||
_overflowAmountChanged,
|
||||
_overflowStyleChanged,
|
||||
_contentMutation,
|
||||
@@ -286,6 +296,7 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
||||
sizeChanged: _sizeChanged,
|
||||
directionChanged: _directionChanged,
|
||||
heightIntrinsicChanged: _heightIntrinsicChanged,
|
||||
overflowEdgeChanged: _overflowEdgeChanged,
|
||||
overflowAmountChanged: _overflowAmountChanged,
|
||||
overflowStyleChanged: _overflowStyleChanged,
|
||||
contentMutation: _contentMutation,
|
||||
|
||||
@@ -34,7 +34,7 @@ export type ScrollbarsSetupElements = [
|
||||
];
|
||||
|
||||
const generateScrollbarDOM = (scrollbarClassName: string): ScrollbarStructure => {
|
||||
const scrollbar = createDiv(`${classNameScrollbar} ${scrollbarClassName}`);
|
||||
const scrollbar = createDiv(`${classNameScrollbar} ${scrollbarClassName} os-theme-dark`);
|
||||
const track = createDiv(classNameScrollbarTrack);
|
||||
const handle = createDiv(classNameScrollbarHandle);
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import { each, isNumber, scrollLeft, scrollTop, assignDeep, keys } from 'support';
|
||||
import { getEnvironment } from 'environment';
|
||||
import {
|
||||
createTrinsicUpdate,
|
||||
createPaddingUpdate,
|
||||
createOverflowUpdate,
|
||||
} from 'setups/structureSetup/updateSegments';
|
||||
import type { SetupState, SetupUpdateSegment, SetupUpdateCheckOption } from 'setups';
|
||||
import type { StructureSetupState } from 'setups/structureSetup';
|
||||
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
||||
|
||||
export type CreateStructureUpdateSegment = (
|
||||
structureSetupElements: StructureSetupElementsObj,
|
||||
state: SetupState<StructureSetupState>
|
||||
) => StructureSetupUpdateSegment;
|
||||
|
||||
export type StructureSetupUpdateSegment = SetupUpdateSegment<StructureSetupUpdateHints>;
|
||||
|
||||
export type StructureSetupUpdate = (
|
||||
checkOption: SetupUpdateCheckOption,
|
||||
updateHints: Partial<StructureSetupUpdateHints>,
|
||||
force?: boolean
|
||||
) => StructureSetupUpdateHints;
|
||||
|
||||
export interface StructureSetupUpdateHints {
|
||||
_sizeChanged: boolean;
|
||||
_directionChanged: boolean;
|
||||
_heightIntrinsicChanged: boolean;
|
||||
_overflowAmountChanged: boolean;
|
||||
_overflowStyleChanged: boolean;
|
||||
_paddingStyleChanged: boolean;
|
||||
_hostMutation: boolean;
|
||||
_contentMutation: boolean;
|
||||
}
|
||||
|
||||
const prepareUpdateHints = <T extends StructureSetupUpdateHints>(
|
||||
leading: Required<T>,
|
||||
adaptive?: Partial<T>,
|
||||
force?: boolean
|
||||
): Required<T> => {
|
||||
const result = {};
|
||||
const finalAdaptive = adaptive || {};
|
||||
const objKeys = keys(leading).concat(keys(finalAdaptive));
|
||||
|
||||
each(objKeys, (key) => {
|
||||
const leadingValue = leading[key];
|
||||
const adaptiveValue = finalAdaptive[key];
|
||||
result[key] = !!(force || leadingValue || adaptiveValue);
|
||||
});
|
||||
|
||||
return result as Required<T>;
|
||||
};
|
||||
|
||||
export const createStructureSetupUpdate = (
|
||||
structureSetupElements: StructureSetupElementsObj,
|
||||
state: SetupState<StructureSetupState>
|
||||
): StructureSetupUpdate => {
|
||||
const { _viewport } = structureSetupElements;
|
||||
const {
|
||||
_nativeScrollbarsHiding: _nativeScrollbarStyling,
|
||||
_nativeScrollbarsOverlaid: _nativeScrollbarIsOverlaid,
|
||||
_flexboxGlue,
|
||||
} = getEnvironment();
|
||||
const doViewportArrange =
|
||||
!_nativeScrollbarStyling && (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y);
|
||||
|
||||
const updateSegments: StructureSetupUpdateSegment[] = [
|
||||
createTrinsicUpdate(structureSetupElements, state),
|
||||
createPaddingUpdate(structureSetupElements, state),
|
||||
createOverflowUpdate(structureSetupElements, state),
|
||||
];
|
||||
|
||||
return (
|
||||
checkOption: SetupUpdateCheckOption,
|
||||
updateHints: Partial<StructureSetupUpdateHints>,
|
||||
force?: boolean
|
||||
) => {
|
||||
const initialUpdateHints = prepareUpdateHints(
|
||||
assignDeep(
|
||||
{
|
||||
_sizeChanged: false,
|
||||
_paddingStyleChanged: false,
|
||||
_directionChanged: false,
|
||||
_heightIntrinsicChanged: false,
|
||||
_overflowAmountChanged: false,
|
||||
_overflowStyleChanged: false,
|
||||
_hostMutation: false,
|
||||
_contentMutation: false,
|
||||
},
|
||||
updateHints
|
||||
),
|
||||
{},
|
||||
force
|
||||
);
|
||||
const adjustScrollOffset = doViewportArrange || !_flexboxGlue;
|
||||
const scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
|
||||
const scrollOffsetY = adjustScrollOffset && scrollTop(_viewport);
|
||||
|
||||
let adaptivedUpdateHints: Required<StructureSetupUpdateHints> = initialUpdateHints;
|
||||
each(updateSegments, (updateSegment) => {
|
||||
adaptivedUpdateHints = prepareUpdateHints<StructureSetupUpdateHints>(
|
||||
adaptivedUpdateHints,
|
||||
updateSegment(adaptivedUpdateHints, checkOption, !!force) || {},
|
||||
force
|
||||
);
|
||||
});
|
||||
|
||||
if (isNumber(scrollOffsetX)) {
|
||||
scrollLeft(_viewport, scrollOffsetX);
|
||||
}
|
||||
if (isNumber(scrollOffsetY)) {
|
||||
scrollTop(_viewport, scrollOffsetY);
|
||||
}
|
||||
|
||||
return adaptivedUpdateHints;
|
||||
};
|
||||
};
|
||||
@@ -15,6 +15,7 @@ export interface StructureSetupState {
|
||||
_padding: TRBL;
|
||||
_paddingAbsolute: boolean;
|
||||
_viewportPaddingStyle: StyleObject;
|
||||
_overflowEdge: XY<number>;
|
||||
_overflowAmount: XY<number>;
|
||||
_overflowStyle: XY<OverflowStyle>;
|
||||
_hasOverflow: XY<boolean>;
|
||||
@@ -36,6 +37,7 @@ type StructureSetupEventMap = {
|
||||
];
|
||||
};
|
||||
|
||||
const initialXYNumber = { x: 0, y: 0 };
|
||||
const initialStructureSetupUpdateState: StructureSetupState = {
|
||||
_padding: {
|
||||
t: 0,
|
||||
@@ -53,10 +55,8 @@ const initialStructureSetupUpdateState: StructureSetupState = {
|
||||
paddingBottom: 0,
|
||||
paddingLeft: 0,
|
||||
},
|
||||
_overflowAmount: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
_overflowEdge: initialXYNumber,
|
||||
_overflowAmount: initialXYNumber,
|
||||
_overflowStyle: {
|
||||
x: 'hidden',
|
||||
y: 'hidden',
|
||||
|
||||
@@ -26,6 +26,7 @@ export interface StructureSetupUpdateHints {
|
||||
_sizeChanged: boolean;
|
||||
_directionChanged: boolean;
|
||||
_heightIntrinsicChanged: boolean;
|
||||
_overflowEdgeChanged: boolean;
|
||||
_overflowAmountChanged: boolean;
|
||||
_overflowStyleChanged: boolean;
|
||||
_paddingStyleChanged: boolean;
|
||||
@@ -82,6 +83,7 @@ export const createStructureSetupUpdate = (
|
||||
_paddingStyleChanged: false,
|
||||
_directionChanged: false,
|
||||
_heightIntrinsicChanged: false,
|
||||
_overflowEdgeChanged: false,
|
||||
_overflowAmountChanged: false,
|
||||
_overflowStyleChanged: false,
|
||||
_hostMutation: false,
|
||||
|
||||
+30
-18
@@ -66,15 +66,11 @@ const xyCacheOptions = {
|
||||
_initialValue: { x: strHidden, y: strHidden } as XY<OverflowStyle>,
|
||||
};
|
||||
|
||||
const getOverflowAmount = (
|
||||
viewportScrollSize: WH<number>,
|
||||
viewportClientSize: WH<number>,
|
||||
sizeFraction: WH<number>
|
||||
) => {
|
||||
const getOverflowAmount = (viewportScrollSize: WH<number>, viewportClientSize: WH<number>) => {
|
||||
const tollerance = window.devicePixelRatio % 1 !== 0 ? 1 : 0;
|
||||
const amount = {
|
||||
w: max(0, viewportScrollSize.w - viewportClientSize.w - max(0, sizeFraction.w)),
|
||||
h: max(0, viewportScrollSize.h - viewportClientSize.h - max(0, sizeFraction.h)),
|
||||
w: max(0, viewportScrollSize.w - viewportClientSize.w),
|
||||
h: max(0, viewportScrollSize.h - viewportClientSize.h),
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -135,6 +131,8 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
||||
const [updateOverflowAmountCache, getCurrentOverflowAmountCache] =
|
||||
createCache<WH<number>>(whCacheOptions);
|
||||
|
||||
const [updateOverflowEdge, getCurrentOverflowEdgeCache] = createCache<WH<number>>(whCacheOptions);
|
||||
|
||||
const [updateOverflowStyleCache] = createCache<XY<OverflowStyle>>(xyCacheOptions);
|
||||
|
||||
/**
|
||||
@@ -350,6 +348,7 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
||||
let sizeFractionCache = getCurrentSizeFraction(force);
|
||||
let viewportScrollSizeCache = getCurrentViewportScrollSizeCache(force);
|
||||
let overflowAmuntCache = getCurrentOverflowAmountCache(force);
|
||||
let overflowEdgeCache = getCurrentOverflowEdgeCache(force);
|
||||
|
||||
let preMeasureViewportOverflowState: ViewportOverflowState | undefined;
|
||||
|
||||
@@ -407,22 +406,29 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
||||
arrangedViewportScrollSize = scrollSize(_viewport);
|
||||
}
|
||||
|
||||
const overflowAmountScrollSize = {
|
||||
w: max(viewportScrollSize.w, arrangedViewportScrollSize.w) + sizeFraction.w,
|
||||
h: max(viewportScrollSize.h, arrangedViewportScrollSize.h) + sizeFraction.h,
|
||||
};
|
||||
const overflowAmountClientSize = {
|
||||
w:
|
||||
arrangedViewportClientSize.w +
|
||||
max(0, viewportclientSize.w - viewportScrollSize.w) +
|
||||
sizeFraction.w,
|
||||
h:
|
||||
arrangedViewportClientSize.h +
|
||||
max(0, viewportclientSize.h - viewportScrollSize.h) +
|
||||
sizeFraction.h,
|
||||
};
|
||||
|
||||
overflowEdgeCache = updateOverflowEdge(overflowAmountClientSize);
|
||||
overflowAmuntCache = updateOverflowAmountCache(
|
||||
getOverflowAmount(
|
||||
{
|
||||
w: max(viewportScrollSize.w, arrangedViewportScrollSize.w),
|
||||
h: max(viewportScrollSize.h, arrangedViewportScrollSize.h),
|
||||
}, // scroll size
|
||||
{
|
||||
w: arrangedViewportClientSize.w + max(0, viewportclientSize.w - viewportScrollSize.w),
|
||||
h: arrangedViewportClientSize.h + max(0, viewportclientSize.h - viewportScrollSize.h),
|
||||
}, // client size
|
||||
sizeFraction
|
||||
),
|
||||
getOverflowAmount(overflowAmountScrollSize, overflowAmountClientSize),
|
||||
force
|
||||
);
|
||||
}
|
||||
|
||||
const [overflowEdge, overflowEdgeChanged] = overflowEdgeCache;
|
||||
const [overflowAmount, overflowAmountChanged] = overflowAmuntCache;
|
||||
const [viewportScrollSize, viewportScrollSizeChanged] = viewportScrollSizeCache;
|
||||
const [sizeFraction, sizeFractionChanged] = sizeFractionCache;
|
||||
@@ -440,6 +446,7 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
||||
_directionChanged ||
|
||||
sizeFractionChanged ||
|
||||
viewportScrollSizeChanged ||
|
||||
overflowEdgeChanged ||
|
||||
overflowAmountChanged ||
|
||||
overflowChanged ||
|
||||
showNativeOverlaidScrollbarsChanged ||
|
||||
@@ -497,6 +504,10 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
||||
|
||||
setState({
|
||||
_overflowStyle: overflowStyle,
|
||||
_overflowEdge: {
|
||||
x: overflowEdge.w,
|
||||
y: overflowEdge.h,
|
||||
},
|
||||
_overflowAmount: {
|
||||
x: overflowAmount.w,
|
||||
y: overflowAmount.h,
|
||||
@@ -506,6 +517,7 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
||||
|
||||
return {
|
||||
_overflowStyleChanged: overflowStyleChanged,
|
||||
_overflowEdgeChanged: overflowEdgeChanged,
|
||||
_overflowAmountChanged: overflowAmountChanged,
|
||||
};
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -9,9 +9,9 @@ module.exports = {
|
||||
workers: 4,
|
||||
projects: [
|
||||
{
|
||||
name: 'Safari',
|
||||
name: 'Chromium',
|
||||
use: {
|
||||
...devices['Desktop Safari'],
|
||||
...devices['Desktop Chromium'],
|
||||
headless: false,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user