add flexboxglue content box fix

This commit is contained in:
Rene Haas
2021-03-31 13:06:08 +02:00
parent 40da2be1da
commit ea6794eca8
2 changed files with 41 additions and 26 deletions
@@ -1,8 +1,7 @@
import { TRBL, CacheValues, each, push, OptionsValidated, hasOwnProperty } from 'support'; import { XY, TRBL, CacheValues, each, push, OptionsValidated, hasOwnProperty, isNumber, scrollLeft, scrollTop } from 'support';
import { Options } from 'options'; import { Options } from 'options';
import { getEnvironment } from 'environment'; import { getEnvironment } from 'environment';
import { StructureSetup } from 'setups/structureSetup'; import { StructureSetup } from 'setups/structureSetup';
import { createStructureLifecycle } from 'lifecycles/structureLifecycle';
import { createPaddingLifecycle } from 'lifecycles/paddingLifecycle'; import { createPaddingLifecycle } from 'lifecycles/paddingLifecycle';
import { createOverflowLifecycle } from 'lifecycles/overflowLifecycle'; import { createOverflowLifecycle } from 'lifecycles/overflowLifecycle';
import { createSizeObserver } from 'observers/sizeObserver'; import { createSizeObserver } from 'observers/sizeObserver';
@@ -47,6 +46,8 @@ export interface LifecycleHub {
_setPadding(newPadding?: TRBL | null): void; _setPadding(newPadding?: TRBL | null): void;
_getPaddingStyle(): StyleObject; _getPaddingStyle(): StyleObject;
_setPaddingStyle(newPaddingStlye?: StyleObject | null): void; _setPaddingStyle(newPaddingStlye?: StyleObject | null): void;
_getViewportOverflowScroll(): XY<boolean>;
_setViewportOverflowScroll(newViewportOverflowScroll: XY<boolean>): void;
} }
const getPropByPath = <T>(obj: any, path: string): T => const getPropByPath = <T>(obj: any, path: string): T =>
@@ -60,6 +61,10 @@ const viewportPaddingStyleFallback: StyleObject = {
marginBottom: 0, marginBottom: 0,
marginLeft: 0, marginLeft: 0,
}; };
const viewportOverflowScrollFallback: XY<boolean> = {
x: false,
y: false,
};
const directionIsRTLCacheValuesFallback: CacheValues<boolean> = { const directionIsRTLCacheValuesFallback: CacheValues<boolean> = {
_value: false, _value: false,
_previous: false, _previous: false,
@@ -74,7 +79,8 @@ const heightIntrinsicCacheValuesFallback: CacheValues<boolean> = {
export const createLifecycleHub = (options: Options, structureSetup: StructureSetup): LifecycleHubInstance => { export const createLifecycleHub = (options: Options, structureSetup: StructureSetup): LifecycleHubInstance => {
let padding = paddingFallback; let padding = paddingFallback;
let viewportPaddingStyle = viewportPaddingStyleFallback; let viewportPaddingStyle = viewportPaddingStyleFallback;
const { _host, _viewport, _content } = structureSetup._targetObj; let viewportOverflowScroll = viewportOverflowScrollFallback;
const { _host, _viewport, _content, _contentArrange } = structureSetup._targetObj;
const { const {
_nativeScrollbarStyling, _nativeScrollbarStyling,
_flexboxGlue, _flexboxGlue,
@@ -90,16 +96,24 @@ export const createLifecycleHub = (options: Options, structureSetup: StructureSe
padding = newPadding || paddingFallback; padding = newPadding || paddingFallback;
}, },
_getPaddingStyle: () => viewportPaddingStyle, _getPaddingStyle: () => viewportPaddingStyle,
_setPaddingStyle(newPaddingStlye: StyleObject) { _setPaddingStyle(newPaddingStlye) {
viewportPaddingStyle = newPaddingStlye || viewportPaddingStyleFallback; viewportPaddingStyle = newPaddingStlye || viewportPaddingStyleFallback;
}, },
_getViewportOverflowScroll: () => viewportOverflowScroll,
_setViewportOverflowScroll(newViewportOverflowScroll) {
viewportOverflowScroll = newViewportOverflowScroll || viewportOverflowScrollFallback;
},
}; };
// push(lifecycles, createStructureLifecycle(instance)); // push(lifecycles, createStructureLifecycle(instance));
push(lifecycles, createPaddingLifecycle(instance)); push(lifecycles, createPaddingLifecycle(instance));
push(lifecycles, createOverflowLifecycle(instance)); push(lifecycles, createOverflowLifecycle(instance));
const runLifecycles = (updateHints?: Partial<LifecycleUpdateHints> | null, changedOptions?: OptionsValidated<Options> | null, force?: boolean) => { const updateLifecycles = (
updateHints?: Partial<LifecycleUpdateHints> | null,
changedOptions?: OptionsValidated<Options> | null,
force?: boolean
) => {
let { let {
_directionIsRTL, _directionIsRTL,
_heightIntrinsic, _heightIntrinsic,
@@ -116,6 +130,9 @@ export const createLifecycleHub = (options: Options, structureSetup: StructureSe
_value: getPropByPath(options, path), _value: getPropByPath(options, path),
_changed: force || getPropByPath(changedOptions, path) !== undefined, _changed: force || getPropByPath(changedOptions, path) !== undefined,
}); });
const adjustScrollOffset = _contentArrange || !_flexboxGlue;
const scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
const scrollOffsetY = adjustScrollOffset && scrollTop(_viewport);
each(lifecycles, (lifecycle) => { each(lifecycles, (lifecycle) => {
const { const {
@@ -142,24 +159,31 @@ export const createLifecycleHub = (options: Options, structureSetup: StructureSe
_contentMutation = adaptiveContentMutation || _contentMutation; _contentMutation = adaptiveContentMutation || _contentMutation;
_paddingStyleChanged = adaptivePaddingStyleChanged || _paddingStyleChanged; _paddingStyleChanged = adaptivePaddingStyleChanged || _paddingStyleChanged;
}); });
if (isNumber(scrollOffsetX)) {
scrollLeft(_viewport, scrollOffsetX);
}
if (isNumber(scrollOffsetY)) {
scrollTop(_viewport, scrollOffsetY);
}
}; };
const onSizeChanged = (directionIsRTL?: CacheValues<boolean>) => { const onSizeChanged = (directionIsRTL?: CacheValues<boolean>) => {
const sizeChanged = !directionIsRTL; const sizeChanged = !directionIsRTL;
runLifecycles({ updateLifecycles({
_directionIsRTL: directionIsRTL, _directionIsRTL: directionIsRTL,
_sizeChanged: sizeChanged, _sizeChanged: sizeChanged,
}); });
}; };
const onTrinsicChanged = (heightIntrinsic: CacheValues<boolean>) => { const onTrinsicChanged = (heightIntrinsic: CacheValues<boolean>) => {
runLifecycles({ updateLifecycles({
_heightIntrinsic: heightIntrinsic, _heightIntrinsic: heightIntrinsic,
}); });
}; };
const onHostMutation = () => { const onHostMutation = () => {
// TODO: rAF only here because IE // TODO: rAF only here because IE
requestAnimationFrame(() => { requestAnimationFrame(() => {
runLifecycles({ updateLifecycles({
_hostMutation: true, _hostMutation: true,
}); });
}); });
@@ -167,7 +191,7 @@ export const createLifecycleHub = (options: Options, structureSetup: StructureSe
const onContentMutation = () => { const onContentMutation = () => {
// TODO: rAF only here because IE // TODO: rAF only here because IE
requestAnimationFrame(() => { requestAnimationFrame(() => {
runLifecycles({ updateLifecycles({
_contentMutation: true, _contentMutation: true,
}); });
}); });
@@ -201,16 +225,16 @@ export const createLifecycleHub = (options: Options, structureSetup: StructureSe
*/ */
}); });
const updateAll = (changedOptions?: OptionsValidated<Options> | null, force?: boolean) => { const update = (changedOptions?: OptionsValidated<Options> | null, force?: boolean) => {
runLifecycles(null, changedOptions, force); updateLifecycles(null, changedOptions, force);
}; };
const envUpdateListener = updateAll.bind(null, null, true); const envUpdateListener = update.bind(null, null, true);
addEnvironmentListener(envUpdateListener); addEnvironmentListener(envUpdateListener);
console.log('flexboxGlue', _flexboxGlue); console.log('flexboxGlue', _flexboxGlue);
return { return {
_update: updateAll, _update: update,
_destroy() { _destroy() {
removeEnvironmentListener(envUpdateListener); removeEnvironmentListener(envUpdateListener);
}, },
@@ -7,14 +7,11 @@ import {
scrollSize, scrollSize,
CacheValues, CacheValues,
equalWH, equalWH,
scrollLeft,
scrollTop,
addClass, addClass,
removeClass, removeClass,
clientSize, clientSize,
offsetSize, offsetSize,
getBoundingClientRect, getBoundingClientRect,
topRightBottomLeft,
} from 'support'; } from 'support';
import { LifecycleHub, Lifecycle } from 'lifecycles/lifecycleHub'; import { LifecycleHub, Lifecycle } from 'lifecycles/lifecycleHub';
import { getEnvironment } from 'environment'; import { getEnvironment } from 'environment';
@@ -74,9 +71,6 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
}); });
const fixFlexboxGlue = (viewportOverflowState: ViewportOverflowState, heightIntrinsic: boolean) => { const fixFlexboxGlue = (viewportOverflowState: ViewportOverflowState, heightIntrinsic: boolean) => {
const offsetLeft = scrollLeft(_viewport);
const offsetTop = scrollTop(_viewport);
style(_viewport, { style(_viewport, {
maxHeight: '', maxHeight: '',
}); });
@@ -84,17 +78,14 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
if (heightIntrinsic) { if (heightIntrinsic) {
const { _overflowScroll, _scrollbarsHideOffset } = viewportOverflowState; const { _overflowScroll, _scrollbarsHideOffset } = viewportOverflowState;
const hostBCR = getBoundingClientRect(_host); const hostBCR = getBoundingClientRect(_host);
const hostOffsetSize = offsetSize(_host);
// TODO: change to offset size - client size calculation. const hostClientSize = clientSize(_host);
const border = topRightBottomLeft(_host, 'border', 'width'); const clientSizeWithoutRounding = hostClientSize.h + (hostBCR.height - hostOffsetSize.h);
style(_viewport, { style(_viewport, {
maxHeight: hostBCR.height - (border.t + border.b) + (_overflowScroll.x ? _scrollbarsHideOffset.x : 0), maxHeight: clientSizeWithoutRounding + (_overflowScroll.x ? _scrollbarsHideOffset.x : 0),
}); });
} }
scrollLeft(_viewport, offsetLeft);
scrollTop(_viewport, offsetTop);
}; };
const getViewportOverflowState = (showNativeOverlaidScrollbars: boolean, viewportStyleObj?: StyleObject): ViewportOverflowState => { const getViewportOverflowState = (showNativeOverlaidScrollbars: boolean, viewportStyleObj?: StyleObject): ViewportOverflowState => {