mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-17 08:30:36 +03:00
improve code
This commit is contained in:
@@ -1,5 +1,22 @@
|
|||||||
import { XY, WH, TRBL, CacheValues, PartialOptions, each, push, keys, hasOwnProperty, isNumber, scrollLeft, scrollTop } from 'support';
|
import {
|
||||||
|
XY,
|
||||||
|
WH,
|
||||||
|
TRBL,
|
||||||
|
CacheValues,
|
||||||
|
PartialOptions,
|
||||||
|
each,
|
||||||
|
push,
|
||||||
|
keys,
|
||||||
|
hasOwnProperty,
|
||||||
|
isNumber,
|
||||||
|
scrollLeft,
|
||||||
|
scrollTop,
|
||||||
|
assignDeep,
|
||||||
|
liesBetween,
|
||||||
|
diffClass,
|
||||||
|
} from 'support';
|
||||||
import { OSOptions } from 'options';
|
import { OSOptions } from 'options';
|
||||||
|
import { classNameHost, classNameViewport, classNameContent } from 'classnames';
|
||||||
import { getEnvironment } from 'environment';
|
import { getEnvironment } from 'environment';
|
||||||
import { StructureSetup } from 'setups/structureSetup';
|
import { StructureSetup } from 'setups/structureSetup';
|
||||||
import { createTrinsicLifecycle } from 'lifecycles/trinsicLifecycle';
|
import { createTrinsicLifecycle } from 'lifecycles/trinsicLifecycle';
|
||||||
@@ -12,16 +29,21 @@ import { StyleObject } from 'typings';
|
|||||||
|
|
||||||
export type LifecycleCheckOption = <T>(path: string) => LifecycleOptionInfo<T>;
|
export type LifecycleCheckOption = <T>(path: string) => LifecycleOptionInfo<T>;
|
||||||
|
|
||||||
export interface PaddingInfo {
|
|
||||||
_absolute: boolean;
|
|
||||||
_padding: TRBL;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LifecycleOptionInfo<T> {
|
export interface LifecycleOptionInfo<T> {
|
||||||
readonly _value: T;
|
readonly _value: T;
|
||||||
_changed: boolean;
|
_changed: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LifecycleCommunication {
|
||||||
|
_paddingInfo: {
|
||||||
|
_absolute: boolean;
|
||||||
|
_padding: TRBL;
|
||||||
|
};
|
||||||
|
_viewportPaddingStyle: StyleObject;
|
||||||
|
_viewportOverflowScroll: XY<boolean>;
|
||||||
|
_viewportOverflowAmount: WH<number>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface LifecycleAdaptiveUpdateHints {
|
export interface LifecycleAdaptiveUpdateHints {
|
||||||
_sizeChanged: boolean;
|
_sizeChanged: boolean;
|
||||||
_hostMutation: boolean;
|
_hostMutation: boolean;
|
||||||
@@ -40,9 +62,13 @@ export type Lifecycle = (
|
|||||||
force: boolean
|
force: boolean
|
||||||
) => Partial<LifecycleAdaptiveUpdateHints> | void;
|
) => Partial<LifecycleAdaptiveUpdateHints> | void;
|
||||||
|
|
||||||
|
export interface LifecycleHubState {
|
||||||
|
_overflowAmount: WH<number>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface LifecycleHubInstance {
|
export interface LifecycleHubInstance {
|
||||||
_update(changedOptions?: PartialOptions<OSOptions> | null, force?: boolean): void;
|
_update(changedOptions?: PartialOptions<OSOptions> | null, force?: boolean): void;
|
||||||
_state(): any;
|
_state(): LifecycleHubState;
|
||||||
_destroy(): void;
|
_destroy(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,19 +77,12 @@ export interface LifecycleHub {
|
|||||||
_structureSetup: StructureSetup;
|
_structureSetup: StructureSetup;
|
||||||
// whether the "viewport arrange" strategy must be used (true if no native scrollbar hiding and scrollbars are overlaid)
|
// whether the "viewport arrange" strategy must be used (true if no native scrollbar hiding and scrollbars are overlaid)
|
||||||
_doViewportArrange: boolean;
|
_doViewportArrange: boolean;
|
||||||
_getPaddingInfo(): PaddingInfo;
|
_getLifecycleCommunication(): LifecycleCommunication;
|
||||||
_setPaddingInfo(newPadding?: PaddingInfo | null): void;
|
_setLifecycleCommunication(newLifecycleCommunication?: Partial<LifecycleCommunication>): void;
|
||||||
// padding related styles applied to the viewport element
|
|
||||||
_getViewportPaddingStyle(): StyleObject;
|
|
||||||
_setViewportPaddingStyle(newPaddingStlye?: StyleObject | null): void;
|
|
||||||
_getViewportOverflowScroll(): XY<boolean>;
|
|
||||||
_setViewportOverflowScroll(newViewportOverflowScroll?: XY<boolean>): void;
|
|
||||||
_getViewportOverflowAmount(): WH<number>;
|
|
||||||
_setViewportOverflowAmount(newViewportOverflowAmount?: WH<number>): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPropByPath = <T>(obj: any, path: string): T =>
|
const getPropByPath = <T>(obj: any, path: string): T =>
|
||||||
obj && path.split('.').reduce((o, prop) => (o && hasOwnProperty(o, prop) ? o[prop] : undefined), obj);
|
obj ? path.split('.').reduce((o, prop) => (o && hasOwnProperty(o, prop) ? o[prop] : undefined), obj) : undefined;
|
||||||
|
|
||||||
const emptyStylePropsToZero = (stlyeObj: StyleObject, baseStyle?: StyleObject) =>
|
const emptyStylePropsToZero = (stlyeObj: StyleObject, baseStyle?: StyleObject) =>
|
||||||
keys(stlyeObj).reduce(
|
keys(stlyeObj).reduce(
|
||||||
@@ -77,33 +96,19 @@ const emptyStylePropsToZero = (stlyeObj: StyleObject, baseStyle?: StyleObject) =
|
|||||||
|
|
||||||
// TODO: observer textarea attrs if textarea
|
// TODO: observer textarea attrs if textarea
|
||||||
// TODO: tabindex, open etc.
|
// TODO: tabindex, open etc.
|
||||||
|
// TODO: test _ignoreContentChange & _ignoreNestedTargetChange for content dom observer
|
||||||
|
// TODO: test _ignoreTargetChange for target dom observer
|
||||||
|
const ignorePrefix = 'os-';
|
||||||
|
const hostSelector = `.${classNameHost}`;
|
||||||
|
const viewportSelector = `.${classNameViewport}`;
|
||||||
|
const contentSelector = `.${classNameContent}`;
|
||||||
const attrs = ['id', 'class', 'style', 'open'];
|
const attrs = ['id', 'class', 'style', 'open'];
|
||||||
const paddingInfoFallback: PaddingInfo = {
|
const ignoreTargetChange = (target: Node, attrName: string, oldValue: string | null, newValue: string | null) => {
|
||||||
_absolute: false,
|
if (attrName === 'class' && oldValue && newValue) {
|
||||||
_padding: {
|
const diff = diffClass(oldValue, newValue);
|
||||||
t: 0,
|
return !!diff.find((addedOrRemovedClass) => addedOrRemovedClass.indexOf(ignorePrefix) !== 0);
|
||||||
r: 0,
|
}
|
||||||
b: 0,
|
return false;
|
||||||
l: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const viewportPaddingStyleFallback: StyleObject = {
|
|
||||||
marginTop: 0,
|
|
||||||
marginRight: 0,
|
|
||||||
marginBottom: 0,
|
|
||||||
marginLeft: 0,
|
|
||||||
paddingTop: 0,
|
|
||||||
paddingRight: 0,
|
|
||||||
paddingBottom: 0,
|
|
||||||
paddingLeft: 0,
|
|
||||||
};
|
|
||||||
const viewportOverflowScrollFallback: XY<boolean> = {
|
|
||||||
x: false,
|
|
||||||
y: false,
|
|
||||||
};
|
|
||||||
const viewportOverflowAmountFallback: WH<number> = {
|
|
||||||
w: 0,
|
|
||||||
h: 0,
|
|
||||||
};
|
};
|
||||||
const directionIsRTLCacheValuesFallback: CacheValues<boolean> = {
|
const directionIsRTLCacheValuesFallback: CacheValues<boolean> = {
|
||||||
_value: false,
|
_value: false,
|
||||||
@@ -115,12 +120,38 @@ const heightIntrinsicCacheValuesFallback: CacheValues<boolean> = {
|
|||||||
_previous: false,
|
_previous: false,
|
||||||
_changed: false,
|
_changed: false,
|
||||||
};
|
};
|
||||||
|
const lifecycleCommunicationFallback: LifecycleCommunication = {
|
||||||
|
_paddingInfo: {
|
||||||
|
_absolute: false,
|
||||||
|
_padding: {
|
||||||
|
t: 0,
|
||||||
|
r: 0,
|
||||||
|
b: 0,
|
||||||
|
l: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_viewportOverflowScroll: {
|
||||||
|
x: false,
|
||||||
|
y: false,
|
||||||
|
},
|
||||||
|
_viewportOverflowAmount: {
|
||||||
|
w: 0,
|
||||||
|
h: 0,
|
||||||
|
},
|
||||||
|
_viewportPaddingStyle: {
|
||||||
|
marginTop: 0,
|
||||||
|
marginRight: 0,
|
||||||
|
marginBottom: 0,
|
||||||
|
marginLeft: 0,
|
||||||
|
paddingTop: 0,
|
||||||
|
paddingRight: 0,
|
||||||
|
paddingBottom: 0,
|
||||||
|
paddingLeft: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const createLifecycleHub = (options: OSOptions, structureSetup: StructureSetup): LifecycleHubInstance => {
|
export const createLifecycleHub = (options: OSOptions, structureSetup: StructureSetup): LifecycleHubInstance => {
|
||||||
let paddingInfo = paddingInfoFallback;
|
let lifecycleCommunication = lifecycleCommunicationFallback;
|
||||||
let viewportPaddingStyle = viewportPaddingStyleFallback;
|
|
||||||
let viewportOverflowScroll = viewportOverflowScrollFallback;
|
|
||||||
let viewportOverflowAmount = viewportOverflowAmountFallback;
|
|
||||||
const { _host, _viewport, _content } = structureSetup._targetObj;
|
const { _host, _viewport, _content } = structureSetup._targetObj;
|
||||||
const {
|
const {
|
||||||
_nativeScrollbarStyling,
|
_nativeScrollbarStyling,
|
||||||
@@ -135,21 +166,16 @@ export const createLifecycleHub = (options: OSOptions, structureSetup: Structure
|
|||||||
_options: options,
|
_options: options,
|
||||||
_structureSetup: structureSetup,
|
_structureSetup: structureSetup,
|
||||||
_doViewportArrange: doViewportArrange,
|
_doViewportArrange: doViewportArrange,
|
||||||
_getPaddingInfo: () => paddingInfo,
|
_getLifecycleCommunication: () => lifecycleCommunication,
|
||||||
_setPaddingInfo(newPaddingInfo) {
|
_setLifecycleCommunication(newLifecycleCommunication) {
|
||||||
paddingInfo = newPaddingInfo || paddingInfoFallback;
|
if (newLifecycleCommunication && newLifecycleCommunication._viewportPaddingStyle) {
|
||||||
},
|
newLifecycleCommunication._viewportPaddingStyle = emptyStylePropsToZero(
|
||||||
_getViewportPaddingStyle: () => viewportPaddingStyle,
|
newLifecycleCommunication._viewportPaddingStyle,
|
||||||
_setViewportPaddingStyle(newPaddingStlye) {
|
lifecycleCommunicationFallback._viewportPaddingStyle
|
||||||
viewportPaddingStyle = newPaddingStlye ? emptyStylePropsToZero(newPaddingStlye, viewportPaddingStyleFallback) : viewportPaddingStyleFallback;
|
);
|
||||||
},
|
}
|
||||||
_getViewportOverflowScroll: () => viewportOverflowScroll,
|
|
||||||
_setViewportOverflowScroll(newViewportOverflowScroll) {
|
lifecycleCommunication = assignDeep({}, lifecycleCommunication, newLifecycleCommunication);
|
||||||
viewportOverflowScroll = newViewportOverflowScroll || viewportOverflowScrollFallback;
|
|
||||||
},
|
|
||||||
_getViewportOverflowAmount: () => viewportOverflowAmount,
|
|
||||||
_setViewportOverflowAmount(newViewportOverflowAmount) {
|
|
||||||
viewportOverflowAmount = newViewportOverflowAmount || viewportOverflowAmountFallback;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -172,7 +198,7 @@ export const createLifecycleHub = (options: OSOptions, structureSetup: Structure
|
|||||||
_heightIntrinsic || (trinsicObserver ? trinsicObserver._getCurrentCacheValues(force)._heightIntrinsic : heightIntrinsicCacheValuesFallback);
|
_heightIntrinsic || (trinsicObserver ? trinsicObserver._getCurrentCacheValues(force)._heightIntrinsic : heightIntrinsicCacheValuesFallback);
|
||||||
const checkOption: LifecycleCheckOption = (path) => ({
|
const checkOption: LifecycleCheckOption = (path) => ({
|
||||||
_value: getPropByPath(options, path),
|
_value: getPropByPath(options, path),
|
||||||
_changed: force || (!!changedOptions && getPropByPath(changedOptions, path) !== undefined),
|
_changed: force || getPropByPath(changedOptions, path) !== undefined,
|
||||||
});
|
});
|
||||||
const adjustScrollOffset = doViewportArrange || !_flexboxGlue;
|
const adjustScrollOffset = doViewportArrange || !_flexboxGlue;
|
||||||
const scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
|
const scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
|
||||||
@@ -246,26 +272,22 @@ export const createLifecycleHub = (options: OSOptions, structureSetup: Structure
|
|||||||
const hostMutationObserver = createDOMObserver(_host, false, onHostMutation, {
|
const hostMutationObserver = createDOMObserver(_host, false, onHostMutation, {
|
||||||
_styleChangingAttributes: attrs,
|
_styleChangingAttributes: attrs,
|
||||||
_attributes: attrs,
|
_attributes: attrs,
|
||||||
|
_ignoreTargetChange: ignoreTargetChange,
|
||||||
});
|
});
|
||||||
const contentMutationObserver = createDOMObserver(_content || _viewport, true, onContentMutation, {
|
const contentMutationObserver = createDOMObserver(_content || _viewport, true, onContentMutation, {
|
||||||
_styleChangingAttributes: attrs,
|
_styleChangingAttributes: attrs,
|
||||||
_attributes: attrs,
|
_attributes: attrs,
|
||||||
_eventContentChange: options!.updating!.elementEvents as [string, string][],
|
_eventContentChange: options!.updating!.elementEvents,
|
||||||
/*
|
_nestedTargetSelector: hostSelector,
|
||||||
_nestedTargetSelector: hostSelector,
|
_ignoreContentChange: (mutation, isNestedTarget) => {
|
||||||
_ignoreContentChange: (mutation, isNestedTarget) => {
|
const { target, attributeName } = mutation;
|
||||||
const { target, attributeName } = mutation;
|
return isNestedTarget
|
||||||
return isNestedTarget ? false : attributeName ? liesBetween(target as Element, hostSelector, '.content') : false;
|
? false
|
||||||
},
|
: attributeName
|
||||||
_ignoreTargetAttrChange: (target, attrName, oldValue, newValue) => {
|
? liesBetween(target as Element, hostSelector, viewportSelector) || liesBetween(target as Element, hostSelector, contentSelector)
|
||||||
if (attrName === 'class' && oldValue && newValue) {
|
: false;
|
||||||
const diff = diffClass(oldValue, newValue);
|
},
|
||||||
const ignore = diff.length === 1 && diff[0].startsWith(ignorePrefix);
|
_ignoreNestedTargetChange: ignoreTargetChange,
|
||||||
return ignore;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const update = (changedOptions?: Partial<OSOptions> | null, force?: boolean) => {
|
const update = (changedOptions?: Partial<OSOptions> | null, force?: boolean) => {
|
||||||
@@ -279,7 +301,7 @@ export const createLifecycleHub = (options: OSOptions, structureSetup: Structure
|
|||||||
return {
|
return {
|
||||||
_update: update,
|
_update: update,
|
||||||
_state: () => ({
|
_state: () => ({
|
||||||
_overflowAmount: viewportOverflowAmount,
|
_overflowAmount: lifecycleCommunication._viewportOverflowAmount,
|
||||||
}),
|
}),
|
||||||
_destroy() {
|
_destroy() {
|
||||||
removeEnvironmentListener(envUpdateListener);
|
removeEnvironmentListener(envUpdateListener);
|
||||||
|
|||||||
@@ -57,14 +57,7 @@ const overlaidScrollbarsHideOffset = 42;
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle => {
|
export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle => {
|
||||||
const {
|
const { _structureSetup, _doViewportArrange, _getLifecycleCommunication, _setLifecycleCommunication } = lifecycleHub;
|
||||||
_structureSetup,
|
|
||||||
_doViewportArrange,
|
|
||||||
_getViewportPaddingStyle,
|
|
||||||
_getPaddingInfo,
|
|
||||||
_setViewportOverflowScroll,
|
|
||||||
_setViewportOverflowAmount,
|
|
||||||
} = lifecycleHub;
|
|
||||||
const { _host, _viewport, _viewportArrange } = _structureSetup._targetObj;
|
const { _host, _viewport, _viewportArrange } = _structureSetup._targetObj;
|
||||||
const { _update: updateContentScrollSizeCache, _current: getCurrentContentScrollSizeCache } = createCache<
|
const { _update: updateContentScrollSizeCache, _current: getCurrentContentScrollSizeCache } = createCache<
|
||||||
WH<number>,
|
WH<number>,
|
||||||
@@ -101,7 +94,7 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (heightIntrinsic) {
|
if (heightIntrinsic) {
|
||||||
const { _absolute: paddingAbsolute, _padding: padding } = _getPaddingInfo();
|
const { _absolute: paddingAbsolute, _padding: padding } = _getLifecycleCommunication()._paddingInfo;
|
||||||
const { _overflowScroll, _scrollbarsHideOffset } = viewportOverflowState;
|
const { _overflowScroll, _scrollbarsHideOffset } = viewportOverflowState;
|
||||||
const hostBCR = getBoundingClientRect(_host);
|
const hostBCR = getBoundingClientRect(_host);
|
||||||
const hostOffsetSize = offsetSize(_host);
|
const hostOffsetSize = offsetSize(_host);
|
||||||
@@ -204,7 +197,7 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
|
|||||||
const { _scrollbarsHideOffset, _scrollbarsHideOffsetArrange } = viewportOverflowState;
|
const { _scrollbarsHideOffset, _scrollbarsHideOffsetArrange } = viewportOverflowState;
|
||||||
const { x: arrangeX, y: arrangeY } = _scrollbarsHideOffsetArrange;
|
const { x: arrangeX, y: arrangeY } = _scrollbarsHideOffsetArrange;
|
||||||
const { x: hideOffsetX, y: hideOffsetY } = _scrollbarsHideOffset;
|
const { x: hideOffsetX, y: hideOffsetY } = _scrollbarsHideOffset;
|
||||||
const viewportPaddingStyle = _getViewportPaddingStyle();
|
const { _viewportPaddingStyle: viewportPaddingStyle } = _getLifecycleCommunication();
|
||||||
const viewportArrangeHorizontalPaddingKey: keyof StyleObject = directionIsRTL ? 'paddingRight' : 'paddingLeft';
|
const viewportArrangeHorizontalPaddingKey: keyof StyleObject = directionIsRTL ? 'paddingRight' : 'paddingLeft';
|
||||||
const viewportArrangeHorizontalPaddingValue = viewportPaddingStyle[viewportArrangeHorizontalPaddingKey] as number;
|
const viewportArrangeHorizontalPaddingValue = viewportPaddingStyle[viewportArrangeHorizontalPaddingKey] as number;
|
||||||
const viewportArrangeVerticalPaddingValue = viewportPaddingStyle.paddingTop as number;
|
const viewportArrangeVerticalPaddingValue = viewportPaddingStyle.paddingTop as number;
|
||||||
@@ -257,13 +250,13 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
|
|||||||
const { _scrollbarsHideOffset, _scrollbarsHideOffsetArrange } = viewportOverflowState;
|
const { _scrollbarsHideOffset, _scrollbarsHideOffsetArrange } = viewportOverflowState;
|
||||||
const { x: arrangeX, y: arrangeY } = _scrollbarsHideOffsetArrange;
|
const { x: arrangeX, y: arrangeY } = _scrollbarsHideOffsetArrange;
|
||||||
const { x: hideOffsetX, y: hideOffsetY } = _scrollbarsHideOffset;
|
const { x: hideOffsetX, y: hideOffsetY } = _scrollbarsHideOffset;
|
||||||
const paddingStyle = _getViewportPaddingStyle();
|
const { _viewportPaddingStyle: viewportPaddingStyle } = _getLifecycleCommunication();
|
||||||
const horizontalMarginKey: keyof StyleObject = directionIsRTL ? 'marginLeft' : 'marginRight';
|
const horizontalMarginKey: keyof StyleObject = directionIsRTL ? 'marginLeft' : 'marginRight';
|
||||||
const viewportHorizontalPaddingKey: keyof StyleObject = directionIsRTL ? 'paddingLeft' : 'paddingRight';
|
const viewportHorizontalPaddingKey: keyof StyleObject = directionIsRTL ? 'paddingLeft' : 'paddingRight';
|
||||||
const horizontalMarginValue = paddingStyle[horizontalMarginKey] as number;
|
const horizontalMarginValue = viewportPaddingStyle[horizontalMarginKey] as number;
|
||||||
const verticalMarginValue = paddingStyle.marginBottom as number;
|
const verticalMarginValue = viewportPaddingStyle.marginBottom as number;
|
||||||
const horizontalPaddingValue = paddingStyle[viewportHorizontalPaddingKey] as number;
|
const horizontalPaddingValue = viewportPaddingStyle[viewportHorizontalPaddingKey] as number;
|
||||||
const verticalPaddingValue = paddingStyle.paddingBottom as number;
|
const verticalPaddingValue = viewportPaddingStyle.paddingBottom as number;
|
||||||
|
|
||||||
// horizontal
|
// horizontal
|
||||||
viewportStyleObj.maxWidth = `calc(100% + ${hideOffsetY + horizontalMarginValue * -1}px)`;
|
viewportStyleObj.maxWidth = `calc(100% + ${hideOffsetY + horizontalMarginValue * -1}px)`;
|
||||||
@@ -293,14 +286,14 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
|
|||||||
): UndoViewportArrangeResult => {
|
): UndoViewportArrangeResult => {
|
||||||
if (_doViewportArrange) {
|
if (_doViewportArrange) {
|
||||||
const finalViewportOverflowState = viewportOverflowState || getViewportOverflowState(showNativeOverlaidScrollbars);
|
const finalViewportOverflowState = viewportOverflowState || getViewportOverflowState(showNativeOverlaidScrollbars);
|
||||||
const paddingStyle = _getViewportPaddingStyle();
|
const { _viewportPaddingStyle: viewportPaddingStyle } = _getLifecycleCommunication();
|
||||||
const { _flexboxGlue } = getEnvironment();
|
const { _flexboxGlue } = getEnvironment();
|
||||||
const { _scrollbarsHideOffsetArrange } = finalViewportOverflowState;
|
const { _scrollbarsHideOffsetArrange } = finalViewportOverflowState;
|
||||||
const { x: arrangeX, y: arrangeY } = _scrollbarsHideOffsetArrange;
|
const { x: arrangeX, y: arrangeY } = _scrollbarsHideOffsetArrange;
|
||||||
const finalPaddingStyle: StyleObject = {};
|
const finalPaddingStyle: StyleObject = {};
|
||||||
const assignProps = (props: string) =>
|
const assignProps = (props: string) =>
|
||||||
each(props.split(' '), (prop) => {
|
each(props.split(' '), (prop) => {
|
||||||
finalPaddingStyle[prop] = paddingStyle[prop];
|
finalPaddingStyle[prop] = viewportPaddingStyle[prop];
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!_flexboxGlue) {
|
if (!_flexboxGlue) {
|
||||||
@@ -443,8 +436,10 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
|
|||||||
|
|
||||||
style(_viewport, viewportStyle);
|
style(_viewport, viewportStyle);
|
||||||
|
|
||||||
_setViewportOverflowScroll(viewportOverflowState._overflowScroll);
|
_setLifecycleCommunication({
|
||||||
_setViewportOverflowAmount(overflowAmount);
|
_viewportOverflowScroll: viewportOverflowState._overflowScroll,
|
||||||
|
_viewportOverflowAmount: overflowAmount,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { getEnvironment } from 'environment';
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createPaddingLifecycle = (lifecycleHub: LifecycleHub): Lifecycle => {
|
export const createPaddingLifecycle = (lifecycleHub: LifecycleHub): Lifecycle => {
|
||||||
const { _setPaddingInfo, _setViewportPaddingStyle, _structureSetup } = lifecycleHub;
|
const { _structureSetup, _setLifecycleCommunication } = lifecycleHub;
|
||||||
const { _host, _padding, _viewport } = _structureSetup._targetObj;
|
const { _host, _padding, _viewport } = _structureSetup._targetObj;
|
||||||
const { _update: updatePaddingCache, _current: currentPaddingCache } = createCache(() => topRightBottomLeft(_host, 'padding'), {
|
const { _update: updatePaddingCache, _current: currentPaddingCache } = createCache(() => topRightBottomLeft(_host, 'padding'), {
|
||||||
_equal: equalTRBL,
|
_equal: equalTRBL,
|
||||||
@@ -66,18 +66,18 @@ export const createPaddingLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =>
|
|||||||
style(_padding || _viewport, paddingStyle);
|
style(_padding || _viewport, paddingStyle);
|
||||||
style(_viewport, viewportStyle);
|
style(_viewport, viewportStyle);
|
||||||
|
|
||||||
_setPaddingInfo({
|
_setLifecycleCommunication({
|
||||||
_absolute: !paddingRelative,
|
_paddingInfo: {
|
||||||
_padding: padding!,
|
_absolute: !paddingRelative,
|
||||||
});
|
_padding: padding!,
|
||||||
_setViewportPaddingStyle(
|
},
|
||||||
_padding
|
_viewportPaddingStyle: _padding
|
||||||
? viewportStyle
|
? viewportStyle
|
||||||
: {
|
: {
|
||||||
...paddingStyle,
|
...paddingStyle,
|
||||||
...viewportStyle,
|
...viewportStyle,
|
||||||
}
|
},
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -49,11 +49,9 @@ interface DOMContentObserver extends DOMObserverBase {
|
|||||||
|
|
||||||
interface DOMTargetObserver extends DOMObserverBase {}
|
interface DOMTargetObserver extends DOMObserverBase {}
|
||||||
|
|
||||||
export type DOMObserverEventContentChange =
|
type ContentChangeArrayItem = [StringNullUndefined, ((elms: Node[]) => StringNullUndefined) | StringNullUndefined] | null | undefined;
|
||||||
| Array<[StringNullUndefined, ((elms: Node[]) => StringNullUndefined) | StringNullUndefined] | null | undefined>
|
|
||||||
| false
|
export type DOMObserverEventContentChange = Array<ContentChangeArrayItem> | false | null | undefined;
|
||||||
| null
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
export type DOMObserverIgnoreContentChange = (
|
export type DOMObserverIgnoreContentChange = (
|
||||||
mutation: MutationRecord,
|
mutation: MutationRecord,
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export interface OSOptions {
|
|||||||
resize: ResizeBehavior;
|
resize: ResizeBehavior;
|
||||||
paddingAbsolute: boolean;
|
paddingAbsolute: boolean;
|
||||||
updating: {
|
updating: {
|
||||||
elementEvents: ReadonlyArray<[string, string]> | null;
|
elementEvents: Array<[string, string]> | null;
|
||||||
contentMutationDebounce: number;
|
contentMutationDebounce: number;
|
||||||
hostMutationDebounce: number;
|
hostMutationDebounce: number;
|
||||||
resizeDebounce: number;
|
resizeDebounce: number;
|
||||||
@@ -54,7 +54,7 @@ export interface OSOptions {
|
|||||||
textarea: {
|
textarea: {
|
||||||
dynWidth: boolean;
|
dynWidth: boolean;
|
||||||
dynHeight: boolean;
|
dynHeight: boolean;
|
||||||
inheritedAttrs: string | ReadonlyArray<string> | null;
|
inheritedAttrs: string | Array<string> | null;
|
||||||
};
|
};
|
||||||
nativeScrollbarsOverlaid: {
|
nativeScrollbarsOverlaid: {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
|
|||||||
+43
-45
@@ -12,6 +12,9 @@ import { clientSize, from, getBoundingClientRect, style, parent, addClass, WH, r
|
|||||||
const msie11 = !!window.MSInputMethodContext && !!document.documentMode;
|
const msie11 = !!window.MSInputMethodContext && !!document.documentMode;
|
||||||
const firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
const firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
||||||
|
|
||||||
|
msie11 && addClass(document.body, 'msie11');
|
||||||
|
firefox && addClass(document.body, 'firefox');
|
||||||
|
|
||||||
const useContentElement = false;
|
const useContentElement = false;
|
||||||
const fixedDigits = msie11 ? 1 : 10;
|
const fixedDigits = msie11 ? 1 : 10;
|
||||||
const fixedDigitsOffset = firefox ? 3 : fixedDigits; // ff does roundign errors here only
|
const fixedDigitsOffset = firefox ? 3 : fixedDigits; // ff does roundign errors here only
|
||||||
@@ -220,27 +223,6 @@ const iterateMinMax = async (afterEach?: () => any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const containerTest = async () => {
|
const containerTest = async () => {
|
||||||
await iterateMinMax(async () => {
|
|
||||||
await iterateBoxSizing(async () => {
|
|
||||||
await iterateHeight(async () => {
|
|
||||||
await iterateWidth(async () => {
|
|
||||||
await iterateBorder(async () => {
|
|
||||||
// assume this part isn't critical for IE11, to boost test speed
|
|
||||||
if (!msie11) {
|
|
||||||
await iterateFloat(async () => {
|
|
||||||
await iterateMargin();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await iteratePadding();
|
|
||||||
await iterateDirection();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const overflowTest = async () => {
|
|
||||||
const contentBox = (elm: HTMLElement | null): WH<number> => {
|
const contentBox = (elm: HTMLElement | null): WH<number> => {
|
||||||
if (elm) {
|
if (elm) {
|
||||||
const computedStyle = window.getComputedStyle(elm);
|
const computedStyle = window.getComputedStyle(elm);
|
||||||
@@ -323,50 +305,66 @@ const overflowTest = async () => {
|
|||||||
|
|
||||||
await checkMetrics();
|
await checkMetrics();
|
||||||
};
|
};
|
||||||
|
const overflowTest = async () => {
|
||||||
|
style(targetResize, { boxSizing: 'border-box' });
|
||||||
|
style(comparisonResize, { boxSizing: 'border-box' });
|
||||||
|
style(targetPercent, { display: 'none' });
|
||||||
|
style(comparisonPercent, { display: 'none' });
|
||||||
|
style(targetEnd, { display: 'none' });
|
||||||
|
style(comparisonEnd, { display: 'none' });
|
||||||
|
|
||||||
style(targetResize, { boxSizing: 'border-box', background: 'rgba(0, 0, 0, 0.1)' });
|
await setNoOverflow();
|
||||||
style(comparisonResize, { boxSizing: 'border-box', background: 'rgba(0, 0, 0, 0.1)' });
|
await setSmallestOverflow(true, false);
|
||||||
style(targetPercent, { display: 'none' });
|
await setSmallestOverflow(false, true);
|
||||||
style(comparisonPercent, { display: 'none' });
|
await setSmallestOverflow(true, true);
|
||||||
style(targetEnd, { display: 'none' });
|
|
||||||
style(comparisonEnd, { display: 'none' });
|
await setNoOverflow();
|
||||||
|
await setLargeOverflow(true, false);
|
||||||
|
await setLargeOverflow(false, true);
|
||||||
|
await setLargeOverflow(true, true);
|
||||||
|
|
||||||
|
removeAttr(targetResize, 'style');
|
||||||
|
removeAttr(comparisonResize, 'style');
|
||||||
|
removeAttr(targetPercent, 'style');
|
||||||
|
removeAttr(comparisonPercent, 'style');
|
||||||
|
removeAttr(targetEnd, 'style');
|
||||||
|
removeAttr(comparisonEnd, 'style');
|
||||||
|
|
||||||
|
if (msie11) {
|
||||||
|
await timeout(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
await checkMetrics();
|
||||||
|
};
|
||||||
|
|
||||||
await iterateMinMax(async () => {
|
await iterateMinMax(async () => {
|
||||||
await iterateBoxSizing(async () => {
|
await iterateBoxSizing(async () => {
|
||||||
await iterateHeight(async () => {
|
await iterateHeight(async () => {
|
||||||
await iterateWidth(async () => {
|
await iterateWidth(async () => {
|
||||||
await iterateBorder(async () => {
|
await iterateBorder(async () => {
|
||||||
await iteratePadding(async () => {
|
// assume this part isn't critical for IE11, to boost test speed
|
||||||
await setNoOverflow();
|
if (!msie11) {
|
||||||
await setSmallestOverflow(true, false);
|
await iterateFloat(async () => {
|
||||||
await setSmallestOverflow(false, true);
|
await iterateMargin();
|
||||||
await setSmallestOverflow(true, true);
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await setNoOverflow();
|
await iteratePadding(async () => {
|
||||||
await setLargeOverflow(true, false);
|
await overflowTest();
|
||||||
await setLargeOverflow(false, true);
|
|
||||||
await setLargeOverflow(true, true);
|
|
||||||
});
|
});
|
||||||
|
await iterateDirection();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
removeAttr(targetResize, 'style');
|
|
||||||
removeAttr(comparisonResize, 'style');
|
|
||||||
removeAttr(targetPercent, 'style');
|
|
||||||
removeAttr(comparisonPercent, 'style');
|
|
||||||
removeAttr(targetEnd, 'style');
|
|
||||||
removeAttr(comparisonEnd, 'style');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const start = async () => {
|
const start = async () => {
|
||||||
setTestResult(null);
|
setTestResult(null);
|
||||||
|
|
||||||
target?.removeAttribute('style');
|
target?.removeAttribute('style');
|
||||||
//await containerTest();
|
await containerTest();
|
||||||
await overflowTest();
|
|
||||||
|
|
||||||
setTestResult(true);
|
setTestResult(true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -246,6 +246,16 @@ body {
|
|||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ie11 doesn't respect percentage max-width in display: inline-block elements, they can always expand to infinity
|
||||||
|
.msie11 {
|
||||||
|
.column {
|
||||||
|
min-width: 900px;
|
||||||
|
}
|
||||||
|
.minMaxNone.widthAuto > .container {
|
||||||
|
max-width: 700px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.intrinsic-hack {
|
.intrinsic-hack {
|
||||||
&.heightAuto,
|
&.heightAuto,
|
||||||
&.envHeightAuto {
|
&.envHeightAuto {
|
||||||
|
|||||||
Reference in New Issue
Block a user