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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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);
}