overflow calc

This commit is contained in:
Rene
2022-07-13 10:47:54 +02:00
parent aa5eadf384
commit 86e6c2457d
10 changed files with 285 additions and 95 deletions
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,
@@ -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
+2 -2
View File
@@ -9,9 +9,9 @@ module.exports = {
workers: 4,
projects: [
{
name: 'Safari',
name: 'Chromium',
use: {
...devices['Desktop Safari'],
...devices['Desktop Chromium'],
headless: false,
},
},