merge conflicts

This commit is contained in:
Rene Haas
2022-07-18 21:46:00 +02:00
12 changed files with 181 additions and 42 deletions
@@ -4,6 +4,7 @@ import {
createDiv,
each,
isEmptyArray,
noop,
on,
push,
removeClass,
@@ -11,6 +12,7 @@ import {
runEachAndClear,
setT,
stopPropagation,
style,
} from 'support';
import {
classNameScrollbar,
@@ -30,6 +32,7 @@ import type {
ScrollbarsInitializationStrategy,
ScrollbarsDynamicInitializationElement,
} from 'setups/scrollbarsSetup/scrollbarsSetup.initialization';
import { StyleObject } from 'typings';
export interface ScrollbarStructure {
_scrollbar: HTMLElement;
@@ -40,7 +43,16 @@ export interface ScrollbarStructure {
export interface ScrollbarsSetupElement {
_scrollbarStructures: ScrollbarStructure[];
_clone: () => ScrollbarStructure;
_addRemoveClass: (classNames: string | false | null | undefined, add?: boolean) => void;
_addRemoveClass: (
classNames: string,
add?: boolean,
elm?: (scrollbarStructure: ScrollbarStructure) => HTMLElement | false | null | undefined
) => void;
_handleStyle: (
elmStyle: (
scrollbarStructure: ScrollbarStructure
) => [HTMLElement | false | null | undefined, StyleObject]
) => void;
// _removeClass: (classNames: string) => void;
/*
_addEventListener: () => void;
@@ -89,12 +101,24 @@ export const createScrollbarsSetupElements = (
);
const scrollbarsAddRemoveClass = (
scrollbarStructures: ScrollbarStructure[],
classNames: string | false | null | undefined,
add?: boolean
classNames: string,
add?: boolean,
elm?: (scrollbarStructure: ScrollbarStructure) => HTMLElement | false | null | undefined
) => {
const action = add ? addClass : removeClass;
each(scrollbarStructures, (scrollbarStructure) => {
action(scrollbarStructure._scrollbar, classNames);
action((elm || noop)(scrollbarStructure) || scrollbarStructure._scrollbar, classNames);
});
};
const scrollbarsHandleStyle = (
scrollbarStructures: ScrollbarStructure[],
elmStyle: (
scrollbarStructure: ScrollbarStructure
) => [HTMLElement | false | null | undefined, StyleObject]
) => {
each(scrollbarStructures, (scrollbarStructure) => {
const [elm, styles] = elmStyle(scrollbarStructure);
style(elm, styles);
});
};
const destroyFns: (() => void)[] = [];
@@ -160,11 +184,13 @@ export const createScrollbarsSetupElements = (
_scrollbarStructures: horizontalScrollbars,
_clone: generateHorizontalScrollbarStructure,
_addRemoveClass: addRemoveClassHorizontal,
_handleStyle: scrollbarsHandleStyle.bind(0, horizontalScrollbars),
},
_vertical: {
_scrollbarStructures: verticalScrollbars,
_clone: generateVerticalScrollbarStructure,
_addRemoveClass: addRemoveClassVertical,
_handleStyle: scrollbarsHandleStyle.bind(0, verticalScrollbars),
},
},
appendElements,
@@ -2,6 +2,7 @@ import { rAF, cAF, isFunction, on, runEachAndClear, setT, clearT } from 'support
import { createState, createOptionCheck } from 'setups/setups';
import {
createScrollbarsSetupElements,
ScrollbarsSetupElement,
ScrollbarsSetupElementsObj,
} from 'setups/scrollbarsSetup/scrollbarsSetup.elements';
import {
@@ -17,7 +18,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 {}
@@ -27,6 +28,7 @@ export interface ScrollbarsSetupStaticState {
_appendElements: () => void;
}
const { min } = Math;
const createSelfCancelTimeout = (timeout?: number | (() => number)) => {
let id: number;
const setTFn = timeout ? setT : rAF!;
@@ -41,6 +43,105 @@ const createSelfCancelTimeout = (timeout?: number | (() => number)) => {
] as [timeout: (callback: () => any) => void, clear: () => void];
};
const refreshScrollbarHandleLength = (
setStyleFn: ScrollbarsSetupElement['_handleStyle'],
structureSetupState: StructureSetupState,
isHorizontal?: boolean
) => {
const { _overflowAmount, _overflowEdge } = structureSetupState;
const axis = isHorizontal ? 'x' : 'y';
const viewportSize = _overflowEdge[axis];
const overflowAmount = _overflowAmount[axis];
const handleRatio = min(1, viewportSize / (viewportSize + overflowAmount));
setStyleFn((structure) => [
structure._handle,
{
[isHorizontal ? 'width' : 'height']: `${(handleRatio * 100).toFixed(3)}%`,
},
]);
};
const refreshScrollbarHandlePosition = (
setStyleFn: (styles: StyleObject) => void,
structureSetupState: StructureSetupState,
isHorizontal?: boolean
) => {
/*
//measure the handle length to respect min & max length
var handleLength = scrollbarVarsInfo._handleLength;
var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height];
var handleTrackDiff = trackLength - handleLength;
var handleCSS = {};
var transformOffset;
var translateValue;
//DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]'
// because its a bit behind during the small delay when content size updates
//(delay = mutationObserverContentLag, if its 0 then this var could be used)
var maxScroll =
(_viewportElementNative[_strScroll + scrollbarVars._Width_Height] -
_viewportElementNative['client' + scrollbarVars._Width_Height]) *
(_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative
var getScrollRatio = function (base) {
return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll));
};
var getHandleOffset = function (scrollRatio) {
var offset = handleTrackDiff * scrollRatio;
offset = isNaN(offset) ? 0 : offset;
offset =
isRTLisHorizontal && !_rtlScrollBehavior.i ? trackLength - handleLength - offset : offset;
offset = MATH.max(0, offset);
return offset;
};
var scrollRatio = getScrollRatio(nativeScroll);
var unsnappedScrollRatio = getScrollRatio(currentScroll);
var handleOffset = getHandleOffset(unsnappedScrollRatio);
var snappedHandleOffset = getHandleOffset(scrollRatio);
scrollbarVarsInfo._maxScroll = maxScroll;
scrollbarVarsInfo._currentScroll = nativeScroll;
scrollbarVarsInfo._currentScrollRatio = scrollRatio;
if (_supportTransform) {
transformOffset = isRTLisHorizontal
? -(trackLength - handleLength - handleOffset)
: handleOffset; //in px
//transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in %
translateValue = isHorizontal
? strTranslateBrace + transformOffset + 'px, 0)'
: strTranslateBrace + '0, ' + transformOffset + 'px)';
handleCSS[strTransform] = translateValue;
//apply or clear up transition
if (_supportTransition)
handleCSS[strTransition] =
transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1
? getCSSTransitionString(scrollbarVars._handle) +
', ' +
(strTransform + _strSpace + transitionDuration + 'ms')
: _strEmpty;
} else handleCSS[scrollbarVars._left_top] = handleOffset;
//only apply css if offset has changed and overflow exists.
if (!nativeOverlayScrollbarsAreActive()) {
scrollbarVars._handle.css(handleCSS);
//clear up transition
if (_supportTransform && _supportTransition && transition) {
scrollbarVars._handle.one(_strTransitionEndEvent, function () {
if (!_destroyed) scrollbarVars._handle.css(strTransition, _strEmpty);
});
}
}
scrollbarVarsInfo._handleOffset = handleOffset;
scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset;
scrollbarVarsInfo._trackLength = trackLength;
*/
};
export const createScrollbarsSetup = (
target: InitializationTarget,
options: ReadonlyOSOptions,
@@ -66,8 +167,8 @@ export const createScrollbarsSetup = (
);
const { _host, _viewport } = structureSetupState._elements;
const { _horizontal, _vertical } = elements;
const { _addRemoveClass: addRemoveClassHorizontal } = _horizontal;
const { _addRemoveClass: addRemoveClassVertical } = _vertical;
const { _addRemoveClass: addRemoveClassHorizontal, _handleStyle: styleHorizontal } = _horizontal;
const { _addRemoveClass: addRemoveClassVertical, _handleStyle: styleVertical } = _vertical;
const manageScrollbarsAutoHide = (removeAutoHide: boolean, delayless?: boolean) => {
clearAutoTimeout();
if (removeAutoHide) {
@@ -133,6 +234,7 @@ export const createScrollbarsSetup = (
const { _overflowEdgeChanged, _overflowAmountChanged, _overflowStyleChanged } =
structureUpdateHints;
const checkOption = createOptionCheck(options, changedOptions, force);
const currStructureSetupState = structureSetupState();
const [theme, themeChanged] = checkOption<string | null>('scrollbars.theme');
const [visibility, visibilityChanged] =
@@ -145,7 +247,7 @@ export const createScrollbarsSetup = (
);
const [touchSupport, touchSupportChanged] = checkOption<boolean>('scrollbars.touchSupport');
const updateHandleSize = _overflowEdgeChanged || _overflowAmountChanged;
const updateHandle = _overflowEdgeChanged || _overflowAmountChanged;
const updateVisibility = _overflowStyleChanged || visibilityChanged;
const setScrollbarVisibility = (
@@ -161,7 +263,7 @@ export const createScrollbarsSetup = (
globalAutoHideDelay = autoHideDelay;
if (updateVisibility) {
const { _overflowStyle } = structureSetupState();
const { _overflowStyle } = currStructureSetupState;
const xVisible = setScrollbarVisibility(_overflowStyle.x, addRemoveClassHorizontal);
const yVisible = setScrollbarVisibility(_overflowStyle.y, addRemoveClassVertical);
@@ -184,6 +286,10 @@ export const createScrollbarsSetup = (
autoHideNotNever = autoHide !== 'never';
manageScrollbarsAutoHide(!autoHideNotNever, true);
}
if (updateHandle) {
refreshScrollbarHandleLength(styleHorizontal, currStructureSetupState, true);
refreshScrollbarHandleLength(styleVertical, currStructureSetupState);
}
},
scrollbarsSetupState,
runEachAndClear.bind(0, destroyFns),
@@ -20,6 +20,8 @@ import {
closest,
assignDeep,
push,
scrollLeft,
scrollTop,
} from 'support';
import { getEnvironment } from 'environment';
import {
@@ -28,6 +30,7 @@ import {
classNameViewport,
classNameOverflowVisible,
classNameScrollbar,
classNameViewportArrange,
} from 'classnames';
import { createSizeObserver, SizeObserverCallbackParams } from 'observers/sizeObserver';
import { createTrinsicObserver } from 'observers/trinsicObserver';
@@ -91,14 +94,21 @@ export const createStructureSetupObservers = (
_initialValue: { w: 0, h: 0 },
},
() => {
const has = _viewportHasClass(classNameOverflowVisible, dataValueHostOverflowVisible);
has && _viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible);
const hasOver = _viewportHasClass(classNameOverflowVisible, dataValueHostOverflowVisible);
const hasVpStyle = _viewportHasClass(classNameViewportArrange, '');
const scrollOffsetX = hasVpStyle && scrollLeft(_viewport);
const scrollOffsetY = hasVpStyle && scrollTop(_viewport);
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible);
_viewportAddRemoveClass(classNameViewportArrange, '');
const contentScroll = scrollSize(_content);
const viewportScroll = scrollSize(_viewport);
const fractional = fractionalSize(_viewport);
has && _viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible, true);
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible, hasOver);
_viewportAddRemoveClass(classNameViewportArrange, '', hasVpStyle);
scrollLeft(_viewport, scrollOffsetX);
scrollTop(_viewport, scrollOffsetY);
return {
w: viewportScroll.w + contentScroll.w + fractional.w,
h: viewportScroll.h + contentScroll.h + fractional.h,
@@ -1,4 +1,4 @@
import { each, isNumber, scrollLeft, scrollTop, assignDeep, keys } from 'support';
import { each, scrollLeft, scrollTop, assignDeep, keys } from 'support';
import { getEnvironment } from 'environment';
import {
createTrinsicUpdateSegment,
@@ -107,12 +107,8 @@ export const createStructureSetupUpdate = (
);
});
if (isNumber(scrollOffsetX)) {
scrollLeft(_viewport, scrollOffsetX);
}
if (isNumber(scrollOffsetY)) {
scrollTop(_viewport, scrollOffsetY);
}
scrollLeft(_viewport, scrollOffsetX);
scrollTop(_viewport, scrollOffsetY);
return adaptivedUpdateHints;
};
@@ -13,7 +13,7 @@ body > .os-scrollbar {
transition: none;
}
.os-scrollbar-track {
pointer-events: auto;
pointer-events: none;
position: relative;
height: 100%;
width: 100%;
@@ -21,14 +21,14 @@ body > .os-scrollbar {
border: none !important;
}
.os-scrollbar-handle {
pointer-events: auto;
pointer-events: none;
position: absolute;
width: 100%;
height: 100%;
}
.os-scrollbar-handle-off,
.os-scrollbar-track-off {
pointer-events: none;
.os-scrollbar-handle-interactive,
.os-scrollbar-track-interactive {
pointer-events: auto;
}
.os-scrollbar-unusable,
.os-scrollbar-unusable * {
@@ -1,5 +1,5 @@
import { from } from 'support/utils/array';
import { isUndefined } from 'support/utils/types';
import { isNull, isUndefined } from 'support/utils/types';
type GetSetPropName = 'scrollLeft' | 'scrollTop' | 'value';
@@ -14,20 +14,20 @@ type Attr = {
type GetSetProp<T> = {
(elm: HTMLElement | false | null | undefined): T;
(elm: HTMLElement | false | null | undefined, value: T): void;
(elm: HTMLElement | false | null | undefined, value?: T): number | void;
(elm: HTMLElement | false | null | undefined, value: T | false | null): void;
(elm: HTMLElement | false | null | undefined, value?: T | false | null): T | void;
};
const getSetProp = (
topLeft: GetSetPropName,
fallback: number | string,
elm: HTMLElement | HTMLInputElement | false | null | undefined,
value?: number | string
value?: number | string | false | null
): number | string | void => {
if (isUndefined(value)) {
return elm ? elm[topLeft] : fallback;
}
elm && (elm[topLeft] = value);
elm && !isNull(value) && value !== false && (elm[topLeft] = value);
};
/**
@@ -61,11 +61,13 @@ export const attrClass = (
value: string,
add?: boolean
) => {
const currValues = attr(elm, attrName) || '';
const currValuesSet = new Set(currValues.split(' '));
currValuesSet[add ? 'add' : 'delete'](value);
if (value) {
const currValues = attr(elm, attrName) || '';
const currValuesSet = new Set(currValues.split(' '));
currValuesSet[add ? 'add' : 'delete'](value);
attr(elm, attrName, from(currValuesSet).join(' ').trim());
attr(elm, attrName, from(currValuesSet).join(' ').trim());
}
};
/**
@@ -101,7 +103,7 @@ export const removeAttr = (elm: Element | false | null | undefined, attrName: st
*/
export const scrollLeft = ((
elm: HTMLElement | false | null | undefined,
value?: number
value?: number | false | null
): number | void => getSetProp('scrollLeft', 0, elm, value) as number) as GetSetProp<number>;
/**
@@ -111,7 +113,7 @@ export const scrollLeft = ((
*/
export const scrollTop = ((
elm: HTMLElement | false | null | undefined,
value?: number
value?: number | false | null
): number | void => getSetProp('scrollTop', 0, elm, value) as number) as GetSetProp<number>;
/**
@@ -74,7 +74,7 @@ const contents = (elm: InputElementType): ReadonlyArray<ChildNode> =>
*/
const parent = (elm: InputElementType): OutputElementType => (elm ? elm.parentElement : null);
export const closest = (elm: InputElementType, selector: string): OutputElementType => {
const closest = (elm: InputElementType, selector: string): OutputElementType => {
if (isElement(elm)) {
const closestFn = elmPrototype.closest;
if (closestFn) {
@@ -113,4 +113,4 @@ const liesBetween = (
: false;
};
export { find, findFirst, is, children, contents, parent, liesBetween };
export { find, findFirst, is, children, contents, parent, liesBetween, closest };
@@ -30,7 +30,6 @@ if (!window.ResizeObserver) {
addPlugin(sizeObserverPlugin);
}
if (!OverlayScrollbars.env().scrollbarsHiding) {
console.log('added');
addPlugin(scrollbarsHidingPlugin);
}