improve initialization

This commit is contained in:
Rene Haas
2022-07-24 21:50:34 +02:00
parent 027ae348ef
commit 772e6782fe
16 changed files with 1866 additions and 184 deletions
@@ -7,6 +7,7 @@ export const dataAttributeHostOverflowX = `${dataAttributeHost}-overflow-x`;
export const dataAttributeHostOverflowY = `${dataAttributeHost}-overflow-y`;
export const dataValueHostOverflowVisible = 'overflowVisible';
export const dataValueHostScrollbarHidden = 'scrollbarHidden';
export const dataValueHostUpdating = 'updating';
export const classNamePadding = 'os-padding';
export const classNameViewport = 'os-viewport';
export const classNameViewportArrange = `${classNameViewport}-arrange`;
+17 -14
View File
@@ -28,7 +28,7 @@ import {
} from 'classnames';
import { Options, defaultOptions } from 'options';
import { DeepPartial } from 'typings';
import { DefaultInitialization } from 'initialization';
import { Initialization } from 'initialization';
import { getPlugins, ScrollbarsHidingPluginInstance, scrollbarsHidingPluginName } from 'plugins';
type EnvironmentEventMap = {
@@ -42,11 +42,11 @@ export interface InternalEnvironment {
readonly _rtlScrollBehavior: { n: boolean; i: boolean };
readonly _flexboxGlue: boolean;
readonly _cssCustomProperties: boolean;
readonly _staticDefaultInitialization: DefaultInitialization;
readonly _staticDefaultInitialization: Initialization;
readonly _staticDefaultOptions: Options;
_addListener(listener: EventListener<EnvironmentEventMap, '_'>): () => void;
_getDefaultInitialization(): DefaultInitialization;
_setDefaultInitialization(newInitialization: DeepPartial<DefaultInitialization>): void;
_getDefaultInitialization(): Initialization;
_setDefaultInitialization(newInitialization: DeepPartial<Initialization>): void;
_getDefaultOptions(): Options;
_setDefaultOptions(newDefaultOptions: DeepPartial<Options>): void;
}
@@ -152,15 +152,18 @@ const createEnvironment = (): InternalEnvironment => {
x: nativeScrollbarsSize.x === 0,
y: nativeScrollbarsSize.y === 0,
};
const defaultInitialization = {
const staticDefaultInitialization: Initialization = {
host: null,
padding: !nativeScrollbarsHiding,
viewport: (target) => nativeScrollbarsHiding && target === target.ownerDocument.body && target,
content: false,
scrollbarsSlot: true,
cancel: {
nativeScrollbarsOverlaid: true,
body: null,
},
};
const defaultDefaultOptions = assignDeep({}, defaultOptions);
const staticDefaultOptions = assignDeep({}, defaultOptions);
const env: InternalEnvironment = {
_nativeScrollbarsSize: nativeScrollbarsSize,
@@ -170,20 +173,20 @@ const createEnvironment = (): InternalEnvironment => {
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
_addListener: (listener) => addEvent('_', listener),
_getDefaultInitialization: assignDeep<DefaultInitialization, DefaultInitialization>.bind(
_getDefaultInitialization: assignDeep<Initialization, Initialization>.bind(
0,
{} as DefaultInitialization,
defaultInitialization
{} as Initialization,
staticDefaultInitialization
),
_setDefaultInitialization(newInitializationStrategy) {
assignDeep(defaultInitialization, newInitializationStrategy);
assignDeep(staticDefaultInitialization, newInitializationStrategy);
},
_getDefaultOptions: assignDeep<Options, Options>.bind(0, {} as Options, defaultDefaultOptions),
_getDefaultOptions: assignDeep<Options, Options>.bind(0, {} as Options, staticDefaultOptions),
_setDefaultOptions(newDefaultOptions) {
assignDeep(defaultDefaultOptions, newDefaultOptions);
assignDeep(staticDefaultOptions, newDefaultOptions);
},
_staticDefaultInitialization: assignDeep({}, defaultInitialization),
_staticDefaultOptions: assignDeep({}, defaultDefaultOptions),
_staticDefaultInitialization: assignDeep({}, staticDefaultInitialization),
_staticDefaultOptions: assignDeep({}, staticDefaultOptions),
};
removeAttr(envElm, 'style');
@@ -1,41 +1,31 @@
import { isBoolean, isFunction, isNull, isUndefined } from 'support';
import type {
StructureInitialization,
DefaultStructureInitialization,
} from 'setups/structureSetup';
import type {
ScrollbarsInitialization,
DefaultScrollbarsInitialization,
} from 'setups/scrollbarsSetup';
import { isFunction, isHTMLElement, isNull, isUndefined } from 'support';
import type { StructureInitialization } from 'setups/structureSetup';
import type { ScrollbarsInitialization } from 'setups/scrollbarsSetup';
import { getEnvironment } from 'environment';
import { DeepPartial } from 'typings';
import { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
type StaticInitialization = HTMLElement | null | undefined;
type DynamicInitialization = HTMLElement | boolean | null | undefined;
export type CancelInitialization = {
cancel: {
nativeScrollbarsOverlaid: boolean | undefined;
body: boolean | null | undefined;
};
};
type StaticInitialization = HTMLElement | false | null;
type DynamicInitialization = HTMLElement | boolean | null;
export type InitializationTargetElement = HTMLElement | HTMLTextAreaElement;
export type InitializationTargetObject = StructureInitialization &
ScrollbarsInitialization &
DeepPartial<CancelInitialization>;
export type Initialization = Omit<StructureInitialization, 'target'> &
ScrollbarsInitialization & {
cancel: {
nativeScrollbarsOverlaid: boolean;
body: boolean | null;
};
};
export type InitializationTargetObject = DeepPartial<Initialization> &
Pick<StructureInitialization, 'target'>;
export type InitializationTarget = InitializationTargetElement | InitializationTargetObject;
export type DefaultInitialization = DefaultStructureInitialization &
DefaultScrollbarsInitialization &
CancelInitialization;
/**
* Static elements MUST be present.
* Null or undefined behave like if this element wasn't specified during initialization.
* With false, null or undefined the element will be generated, otherwise the specified element is taken.
*/
export type StaticInitializationElement<Args extends any[]> =
| ((...args: Args) => StaticInitialization)
@@ -43,17 +33,14 @@ export type StaticInitializationElement<Args extends any[]> =
/**
* Dynamic element CAN be present.
* If its a element the element will be handled as the repsective element.
* True means that the respective dynamic element is forced to be generated.
* False means that the respective dynamic element is forced NOT to be generated.
* Null or undefined behave like if this element wasn't specified during initialization.
* If its a element the element will be taken as the repsective element.
* With true the element will be generated.
* With false, null or undefined the element won't be generated.
*/
export type DynamicInitializationElement<Args extends any[]> =
| ((...args: Args) => DynamicInitialization)
| DynamicInitialization;
export type DefaultInitializtationElement<InitElm> = Exclude<InitElm, HTMLElement>;
export type FallbackInitializtationElement<
InitElm extends StaticInitializationElement<any> | DynamicInitializationElement<any>
> = Extract<InitElm, (...args: any[]) => any> extends (...args: infer P) => any
@@ -66,40 +53,42 @@ const resolveInitialization = <T>(value: any, args: any): T =>
const staticInitializationElement = <T extends StaticInitializationElement<any>>(
args: Parameters<Extract<T, (...args: any[]) => any>>,
fallbackStaticInitializationElement: FallbackInitializtationElement<T>,
defaultStaticInitializationElementStrategy?: DefaultInitializtationElement<T>,
staticInitializationElementValue?: T | false
): HTMLElement =>
resolveInitialization<StaticInitialization>(
staticInitializationElementValue ||
resolveInitialization<StaticInitialization>(defaultStaticInitializationElementStrategy, args),
defaultStaticInitializationElementStrategy: T,
staticInitializationElementValue?: T
): HTMLElement => {
const staticInitialization = isUndefined(staticInitializationElementValue)
? defaultStaticInitializationElementStrategy
: staticInitializationElementValue;
const resolvedInitialization = resolveInitialization<StaticInitialization>(
staticInitialization,
args
) || fallbackStaticInitializationElement.apply(0, args);
);
return resolvedInitialization || fallbackStaticInitializationElement();
};
const dynamicInitializationElement = <T extends DynamicInitializationElement<any>>(
args: Parameters<Extract<T, (...args: any[]) => any>>,
fallbackDynamicInitializationElement: FallbackInitializtationElement<T>,
defaultDynamicInitializationElementStrategy?: DefaultInitializtationElement<T>,
dynamicInitializationElementValue?: T | false
defaultDynamicInitializationElementStrategy: T,
dynamicInitializationElementValue?: T
): HTMLElement | false => {
let result = resolveInitialization<DynamicInitialization>(
dynamicInitializationElementValue,
const dynamicInitialization = isUndefined(dynamicInitializationElementValue)
? defaultDynamicInitializationElementStrategy
: dynamicInitializationElementValue;
const resolvedInitialization = resolveInitialization<DynamicInitialization>(
dynamicInitialization,
args
);
if (isNull(result) || isUndefined(result)) {
result = resolveInitialization<DynamicInitialization>(
defaultDynamicInitializationElementStrategy,
args
);
}
return result === true || isNull(result) || isUndefined(result)
? fallbackDynamicInitializationElement.apply(0, args)
: result;
return (
!!resolvedInitialization &&
(isHTMLElement(resolvedInitialization)
? resolvedInitialization
: fallbackDynamicInitializationElement())
);
};
const cancelInitialization = (
cancelInitializationValue: DeepPartial<CancelInitialization['cancel']> | false | null | undefined,
cancelInitializationValue: DeepPartial<Initialization['cancel']> | false | null | undefined,
structureSetupElements: StructureSetupElementsObj
): boolean => {
const { nativeScrollbarsOverlaid, body } = cancelInitializationValue || {};
@@ -110,7 +99,7 @@ const cancelInitialization = (
const resolvedNativeScrollbarsOverlaid =
nativeScrollbarsOverlaid ?? defaultNativeScrollbarsOverlaid;
const resolvedDocumentScrollingElement = isBoolean(body) || isNull(body) ? body : defaultbody;
const resolvedDocumentScrollingElement = isUndefined(body) ? defaultbody : body;
const finalNativeScrollbarsOverlaid =
(_nativeScrollbarsOverlaid.x || _nativeScrollbarsOverlaid.y) &&
@@ -21,12 +21,7 @@ import {
} from 'plugins';
import { addInstance, getInstance, removeInstance } from 'instances';
import type { DeepPartial, OverflowStyle } from 'typings';
import {
InitializationTarget,
InitializationTargetObject,
DefaultInitialization,
cancelInitialization,
} from 'initialization';
import { InitializationTarget, Initialization, cancelInitialization } from 'initialization';
import type {
InitialEventListeners as GeneralInitialEventListeners,
EventListener as GeneralEventListener,
@@ -34,7 +29,7 @@ import type {
export interface OverlayScrollbarsStatic {
(
target: InitializationTarget | InitializationTargetObject,
target: InitializationTarget,
options?: DeepPartial<Options>,
eventListeners?: GeneralInitialEventListeners<EventListenerMap>
): OverlayScrollbars;
@@ -50,11 +45,11 @@ export interface Environment {
rtlScrollBehavior: { n: boolean; i: boolean };
flexboxGlue: boolean;
cssCustomProperties: boolean;
staticDefaultInitialization: DefaultInitialization;
staticDefaultInitialization: Initialization;
staticDefaultOptions: Options;
getDefaultInitialization(): DefaultInitialization;
setDefaultInitialization(newDefaultInitialization: DeepPartial<DefaultInitialization>): void;
getDefaultInitialization(): Initialization;
setDefaultInitialization(newDefaultInitialization: DeepPartial<Initialization>): void;
getDefaultOptions(): Options;
setDefaultOptions(newDefaultOptions: DeepPartial<Options>): void;
}
@@ -29,7 +29,6 @@ import type { InitializationTarget } from 'initialization';
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
import type {
ScrollbarsInitialization,
DefaultScrollbarsInitialization,
ScrollbarsDynamicInitializationElement,
} from 'setups/scrollbarsSetup/scrollbarsSetup.initialization';
import { StyleObject } from 'typings';
@@ -86,8 +85,7 @@ export const createScrollbarsSetupElements = (
structureSetupElements: StructureSetupElementsObj
): ScrollbarsSetupElements => {
const { _getDefaultInitialization } = getEnvironment();
const { scrollbarsSlot: defaultScrollbarSlot } =
_getDefaultInitialization() as DefaultScrollbarsInitialization;
const { scrollbarsSlot: defaultScrollbarSlot } = _getDefaultInitialization();
const { _documentElm, _target, _host, _viewport, _targetIsElm } = structureSetupElements;
const scrollbarSlot = _targetIsElm ? null : (target as ScrollbarsInitialization).scrollbarsSlot;
const evaluatedScrollbarSlot =
@@ -1,8 +1,4 @@
import type {
InitializationTargetElement,
DefaultInitializtationElement,
DynamicInitializationElement,
} from 'initialization';
import type { InitializationTargetElement, DynamicInitializationElement } from 'initialization';
export type ScrollbarsDynamicInitializationElement = DynamicInitializationElement<
[target: InitializationTargetElement, host: HTMLElement, viewport: HTMLElement]
@@ -17,9 +13,5 @@ export type ScrollbarsDynamicInitializationElement = DynamicInitializationElemen
* Null or Undefined means that the environment initialization strategy is used.
*/
export interface ScrollbarsInitialization {
scrollbarsSlot?: ScrollbarsDynamicInitializationElement;
scrollbarsSlot: ScrollbarsDynamicInitializationElement;
}
export type DefaultScrollbarsInitialization = {
[K in keyof ScrollbarsInitialization]: DefaultInitializtationElement<ScrollbarsInitialization[K]>;
};
@@ -1,9 +1,21 @@
import { rAF, cAF, isFunction, on, runEachAndClear, setT, clearT } from 'support';
import {
rAF,
cAF,
isFunction,
on,
runEachAndClear,
setT,
clearT,
parent,
scrollLeft,
scrollTop,
} from 'support';
import { createState, createOptionCheck } from 'setups/setups';
import {
createScrollbarsSetupElements,
ScrollbarsSetupElement,
ScrollbarsSetupElementsObj,
ScrollbarStructure,
} from 'setups/scrollbarsSetup/scrollbarsSetup.elements';
import {
classNamesScrollbarVisible,
@@ -18,7 +30,7 @@ import type {
} from 'options';
import type { Setup, StructureSetupState, StructureSetupStaticState } from 'setups';
import type { InitializationTarget } from 'initialization';
import type { OverflowStyle } from 'typings';
import type { OverflowStyle, StyleObject } from 'typings';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ScrollbarsSetupState {}
@@ -121,10 +133,20 @@ export const createScrollbarsSetup = (
target,
structureSetupState._elements
);
const { _host, _viewport } = structureSetupState._elements;
const { _host, _viewport, _viewportIsTarget, _isBody } = structureSetupState._elements;
const { _horizontal, _vertical } = elements;
const { _addRemoveClass: addRemoveClassHorizontal, _handleStyle: styleHorizontal } = _horizontal;
const { _addRemoveClass: addRemoveClassVertical, _handleStyle: styleVertical } = _vertical;
const styleScrollbarPosition = (structure: ScrollbarStructure) => {
const { _scrollbar } = structure;
const elm = _viewportIsTarget && _isBody && parent(_scrollbar) === _viewport && _scrollbar;
return [
elm,
{
transform: elm ? `translate(${scrollLeft(_viewport)}px, ${scrollTop(_viewport)}px)` : '',
},
] as [HTMLElement | false, StyleObject];
};
const manageScrollbarsAutoHide = (removeAutoHide: boolean, delayless?: boolean) => {
clearAutoTimeout();
if (removeAutoHide) {
@@ -146,6 +168,7 @@ export const createScrollbarsSetup = (
mouseInHost = autoHideIsLeave;
mouseInHost && manageScrollbarsAutoHide(true);
};
const destroyFns: (() => void)[] = [
clearScrollTimeout,
clearAutoTimeout,
@@ -181,6 +204,9 @@ export const createScrollbarsSetup = (
autoHideNotNever && !mouseInHost && manageScrollbarsAutoHide(false);
});
});
_viewportIsTarget && styleHorizontal(styleScrollbarPosition);
_viewportIsTarget && styleVertical(styleScrollbarPosition);
}),
];
const scrollbarsSetupState = getState.bind(0) as (() => ScrollbarsSetupState) &
@@ -19,8 +19,6 @@ import {
removeAttr,
attrClass,
hasAttrClass,
ResizeObserverConstructor,
hasOwnProperty,
noop,
} from 'support';
import {
@@ -38,9 +36,12 @@ import type { ScrollbarsHidingPluginInstance } from 'plugins/scrollbarsHidingPlu
import {
staticInitializationElement as generalStaticInitializationElement,
dynamicInitializationElement as generalDynamicInitializationElement,
} from 'initialization';
import type {
InitializationTarget,
InitializationTargetElement,
InitializationTargetObject,
} from 'initialization';
import type { InitializationTarget, InitializationTargetElement } from 'initialization';
import type {
StructureDynamicInitializationElement,
StructureStaticInitializationElement,
@@ -93,18 +94,18 @@ export const createStructureSetupElements = (
const createUniqueViewportArrangeElement =
scrollbarsHidingPlugin && scrollbarsHidingPlugin._createUniqueViewportArrangeElement;
const {
host: defaultHostInitializationStrategy,
viewport: defaultViewportInitializationStrategy,
padding: defaultPaddingInitializationStrategy,
content: defaultContentInitializationStrategy,
host: defaultHostInitialization,
viewport: defaultViewportInitialization,
padding: defaultPaddingInitialization,
content: defaultContentInitialization,
} = _getDefaultInitialization();
const targetIsElm = isHTMLElement(target);
const targetStructureInitialization = (targetIsElm ? {} : target) as InitializationTargetObject;
const {
host: hostInitializationStrategy,
padding: paddingInitializationStrategy,
viewport: viewportInitializationStrategy,
content: contentInitializationStrategy,
host: hostInitialization,
padding: paddingInitialization,
viewport: viewportInitialization,
content: contentInitialization,
} = targetStructureInitialization;
const targetElement = targetIsElm ? target : targetStructureInitialization.target;
@@ -112,9 +113,6 @@ export const createStructureSetupElements = (
const ownerDocument = targetElement.ownerDocument;
const isBody = targetElement === ownerDocument.body;
const wnd = ownerDocument.defaultView as Window;
const singleElmSupport = isBody
? _nativeScrollbarsHiding
: !!ResizeObserverConstructor && !isTextarea && _nativeScrollbarsHiding;
const staticInitializationElement =
generalStaticInitializationElement<StructureStaticInitializationElement>.bind(0, [
targetElement,
@@ -123,43 +121,31 @@ export const createStructureSetupElements = (
generalDynamicInitializationElement<StructureDynamicInitializationElement>.bind(0, [
targetElement,
]);
const viewportElement = [
staticInitializationElement(
createNewDiv,
defaultViewportInitializationStrategy,
isBody && !hasOwnProperty(targetStructureInitialization, 'viewport')
? targetElement
: viewportInitializationStrategy
),
staticInitializationElement(createNewDiv, defaultViewportInitializationStrategy),
staticInitializationElement(createNewDiv),
].filter((potentialViewport) =>
singleElmSupport ? true : potentialViewport !== targetElement
)[0];
const viewportElement = staticInitializationElement(
createNewDiv,
defaultViewportInitialization,
viewportInitialization
);
const viewportIsTarget = viewportElement === targetElement;
const evaluatedTargetObj: StructureSetupElementsObj = {
_target: targetElement,
_host: isTextarea
? staticInitializationElement(
createNewDiv,
defaultHostInitializationStrategy,
hostInitializationStrategy
)
? staticInitializationElement(createNewDiv, defaultHostInitialization, hostInitialization)
: (targetElement as HTMLElement),
_viewport: viewportElement,
_padding:
!viewportIsTarget &&
dynamicInitializationElement(
createNewDiv,
defaultPaddingInitializationStrategy,
paddingInitializationStrategy
defaultPaddingInitialization,
paddingInitialization
),
_content:
!viewportIsTarget &&
dynamicInitializationElement(
createNewDiv,
defaultContentInitializationStrategy,
contentInitializationStrategy
defaultContentInitialization,
contentInitialization
),
_viewportArrange:
!viewportIsTarget &&
@@ -2,7 +2,6 @@ import type {
InitializationTargetElement,
StaticInitializationElement,
DynamicInitializationElement,
DefaultInitializtationElement,
} from 'initialization';
export type StructureStaticInitializationElement = StaticInitializationElement<
@@ -25,14 +24,8 @@ export type StructureDynamicInitializationElement = DynamicInitializationElement
*/
export interface StructureInitialization {
target: InitializationTargetElement;
host?: StructureStaticInitializationElement; // only relevant for textarea
viewport?: StructureStaticInitializationElement;
padding?: StructureDynamicInitializationElement;
content?: StructureDynamicInitializationElement;
host: StructureStaticInitializationElement; // only relevant for textarea
viewport: StructureStaticInitializationElement;
padding: StructureDynamicInitializationElement;
content: StructureDynamicInitializationElement;
}
export type DefaultStructureInitialization = {
[K in keyof Omit<StructureInitialization, 'target'>]: DefaultInitializtationElement<
StructureInitialization[K]
>;
};
@@ -27,6 +27,7 @@ import { getEnvironment } from 'environment';
import {
dataAttributeHost,
dataValueHostOverflowVisible,
dataValueHostUpdating,
classNameViewport,
classNameOverflowVisible,
classNameScrollbar,
@@ -100,6 +101,7 @@ export const createStructureSetupObservers = (
const scrollOffsetY = hasVpStyle && scrollTop(_viewport);
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible);
_viewportAddRemoveClass(classNameViewportArrange, '');
_viewportAddRemoveClass('', dataValueHostUpdating, true);
const contentScroll = scrollSize(_content);
const viewportScroll = scrollSize(_viewport);
@@ -107,6 +109,7 @@ export const createStructureSetupObservers = (
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible, hasOver);
_viewportAddRemoveClass(classNameViewportArrange, '', hasVpStyle);
_viewportAddRemoveClass('', dataValueHostUpdating, false);
scrollLeft(_viewport, scrollOffsetX);
scrollTop(_viewport, scrollOffsetY);
return {
@@ -224,7 +227,8 @@ export const createStructureSetupObservers = (
const viewportIsTargetResizeObserver =
_viewportIsTarget &&
new ResizeObserverConstructor!(onSizeChanged.bind(0, { _sizeChanged: true }));
ResizeObserverConstructor &&
new ResizeObserverConstructor(onSizeChanged.bind(0, { _sizeChanged: true }));
viewportIsTargetResizeObserver && viewportIsTargetResizeObserver.observe(_host);
updateViewportAttrsFromHost();
@@ -1,5 +1,6 @@
import { each, scrollLeft, scrollTop, assignDeep, keys } from 'support';
import { getEnvironment } from 'environment';
import { dataValueHostUpdating } from 'classnames';
import {
createTrinsicUpdateSegment,
createPaddingUpdateSegment,
@@ -56,7 +57,7 @@ export const createStructureSetupUpdate = (
structureSetupElements: StructureSetupElementsObj,
state: SetupState<StructureSetupState>
): StructureSetupUpdate => {
const { _viewport } = structureSetupElements;
const { _viewport, _viewportAddRemoveClass } = structureSetupElements;
const { _nativeScrollbarsHiding, _nativeScrollbarsOverlaid, _flexboxGlue } = getEnvironment();
const doViewportArrange =
!_nativeScrollbarsHiding && (_nativeScrollbarsOverlaid.x || _nativeScrollbarsOverlaid.y);
@@ -93,6 +94,7 @@ export const createStructureSetupUpdate = (
const adjustScrollOffset = doViewportArrange || !_flexboxGlue;
const scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
const scrollOffsetY = adjustScrollOffset && scrollTop(_viewport);
_viewportAddRemoveClass('', dataValueHostUpdating, true);
let adaptivedUpdateHints: Required<StructureSetupUpdateHints> = initialUpdateHints;
each(updateSegments, (updateSegment) => {
@@ -105,6 +107,7 @@ export const createStructureSetupUpdate = (
scrollLeft(_viewport, scrollOffsetX);
scrollTop(_viewport, scrollOffsetY);
_viewportAddRemoveClass('', dataValueHostUpdating);
return adaptivedUpdateHints;
};
@@ -1,3 +1,6 @@
[data-overlayscrollbars~='updating'] > .os-scrollbar {
display: none !important;
}
.os-scrollbar {
contain: strict;
transition: opacity 0.3s, visibility 0.3s, top 0.3s, right 0.3s, bottom 0.3s, left 0.3s;
@@ -42,19 +42,13 @@ const getCSSVal = (elm: HTMLElement, computedStyle: CSSStyleDeclaration, prop: s
? computedStyle[prop] || computedStyle.getPropertyValue(prop)
: elm.style[prop];
const setCSSVal = (
elm: HTMLElement | false | null | undefined,
prop: string,
val: string | number
): void => {
const setCSSVal = (elm: HTMLElement, prop: string, val: string | number): void => {
try {
if (elm) {
const { style: elmStyle } = elm;
if (!isUndefined(elmStyle[prop])) {
elmStyle[prop] = adaptCSSVal(prop, val);
} else {
elmStyle.setProperty(prop, val as string);
}
const { style: elmStyle } = elm;
if (!isUndefined(elmStyle[prop])) {
elmStyle[prop] = adaptCSSVal(prop, val);
} else {
elmStyle.setProperty(prop, val as string);
}
} catch (e) {}
};
@@ -96,7 +90,7 @@ export function style<CustomCssProps>(
}
return getStylesResult;
}
each(keys(styles), (key) => setCSSVal(elm, key, styles[key]));
elm && each(keys(styles), (key) => setCSSVal(elm, key, styles[key]));
}
/**
@@ -5,7 +5,8 @@ import {
createStructureSetupElements,
StructureSetupElementsObj,
} from 'setups/structureSetup/structureSetup.elements';
import type { InitializationTarget, DefaultInitializtationElement } from 'initialization';
import { addPlugin, scrollbarsHidingPlugin } from 'plugins';
import type { InitializationTarget } from 'initialization';
import type {
StructureInitialization,
StructureStaticInitializationElement,
@@ -25,6 +26,8 @@ jest.mock('support/compatibility/apis', () => {
};
});
addPlugin(scrollbarsHidingPlugin);
interface StructureSetupElementsProxy {
input: InitializationTarget;
elements: StructureSetupElementsObj;
@@ -178,38 +181,33 @@ const assertCorrectSetupElements = (
expect(_content).toBeFalsy();
}
const { _isTextarea, _isBody, _bodyElm, _htmlElm, _documentElm, _windowElm } = elements;
const { _isTextarea, _isBody, _documentElm, _windowElm } = elements;
expect(_isTextarea).toBe(isTextarea);
expect(_isBody).toBe(isBody);
expect(_windowElm).toBe(document.defaultView);
expect(_documentElm).toBe(document);
expect(_htmlElm).toBe(document.body.parentElement);
expect(_bodyElm).toBe(document.body);
expect(typeof destroy).toBe('function');
const { _nativeScrollbarsHiding, _cssCustomProperties, _getDefaultInitialization } = environment;
const {
_nativeScrollbarsHiding: _nativeScrollbarStyling,
_cssCustomProperties,
_getInitializationStrategy,
} = environment;
const {
_host: hostInitStrategy,
_viewport: viewportInitStrategy,
_padding: paddingInitStrategy,
_content: contentInitStrategy,
} = _getInitializationStrategy();
host: hostInitStrategy,
viewport: viewportInitStrategy,
padding: paddingInitStrategy,
content: contentInitStrategy,
} = _getDefaultInitialization();
const inputIsElement = isHTMLElement(input);
const inputAsObj = input as StructureInitialization;
const styleElm = document.querySelector('style');
const checkStrategyDependendElements = (
elm: Element | null,
inputStrategy: StructureStaticInitializationElement | StructureDynamicInitializationElement,
inputStrategy:
| StructureStaticInitializationElement
| StructureDynamicInitializationElement
| undefined,
isStaticStrategy: boolean,
strategy:
| DefaultInitializtationElement<StructureStaticInitializationElement>
| DefaultInitializtationElement<StructureDynamicInitializationElement>,
strategy: StructureStaticInitializationElement | StructureDynamicInitializationElement,
kind: 'padding' | 'viewport' | 'content' | 'host'
) => {
const input = isFunction(inputStrategy) ? inputStrategy(target) : inputStrategy;
@@ -223,8 +221,7 @@ const assertCorrectSetupElements = (
}
if (input === undefined) {
if (isStaticStrategy) {
strategy =
strategy as DefaultInitializtationElement<StructureStaticInitializationElement>;
strategy = strategy as StructureStaticInitializationElement;
if (typeof strategy === 'function') {
const result = strategy(target);
if (_viewportIsTarget) {
@@ -242,8 +239,7 @@ const assertCorrectSetupElements = (
expect(elm).toBeTruthy();
}
} else {
strategy =
strategy as DefaultInitializtationElement<StructureDynamicInitializationElement>;
strategy = strategy as StructureDynamicInitializationElement;
if (typeof strategy === 'function') {
const result = strategy(target);
@@ -278,7 +274,7 @@ const assertCorrectSetupElements = (
}
};
if (_nativeScrollbarStyling || _cssCustomProperties) {
if (_nativeScrollbarsHiding || _cssCustomProperties) {
expect(styleElm).toBeFalsy();
} else {
expect(styleElm).toBeTruthy();
@@ -298,11 +298,11 @@ body {
// disable native scrollbar styling detection
.nss {
.os-viewport-scrollbar-styled.os-environment {
.os-viewport-scrollbar-hidden.os-environment {
scrollbar-width: auto !important;
}
.os-viewport-scrollbar-styled.os-environment::-webkit-scrollbar,
.os-viewport-scrollbar-styled.os-environment::-webkit-scrollbar-corner {
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar,
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar-corner {
display: block !important;
}
}