Skip to content

Commit

Permalink
remove direction change observer and rtlScrollBehavior
Browse files Browse the repository at this point in the history
  • Loading branch information
KingSora committed May 7, 2024
1 parent 955b72c commit 0204fcd
Show file tree
Hide file tree
Showing 11 changed files with 27 additions and 268 deletions.
41 changes: 0 additions & 41 deletions packages/overlayscrollbars/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
appendChildren,
getFractionalSize,
getClientSize,
absoluteCoordinates,
getOffsetSize,
removeAttrs,
removeElements,
Expand All @@ -15,12 +14,7 @@ import {
scrollT,
bind,
wnd,
scrollElementTo,
strHidden,
strOverflowX,
strOverflowY,
getStyles,
setStyles,
isBodyElement,
isFunction,
addEventListener,
Expand All @@ -40,7 +34,6 @@ export interface Env {
readonly _nativeScrollbarsSize: XY;
readonly _nativeScrollbarsOverlaid: XY<boolean>;
readonly _nativeScrollbarsHiding: boolean;
readonly _rtlScrollBehavior: { n: boolean; i: boolean };
readonly _scrollTimeline: boolean;
readonly _staticDefaultInitialization: Initialization;
readonly _staticDefaultOptions: Options;
Expand Down Expand Up @@ -87,39 +80,6 @@ const createEnvironment = (): Env => {
return result;
};

const getRtlScrollBehavior = (
parentElm: HTMLElement,
childElm: HTMLElement
): { i: boolean; n: boolean } => {
setStyles(parentElm, {
[strOverflowX]: strHidden,
[strOverflowY]: strHidden,
direction: 'rtl',
});
scrollElementTo(parentElm, { x: 0 });

const parentOffset = absoluteCoordinates(parentElm);
const childOffset = absoluteCoordinates(childElm);
scrollElementTo(parentElm, { x: -999 }); // https://github.com/KingSora/OverlayScrollbars/issues/187
const childOffsetAfterScroll = absoluteCoordinates(childElm);
return {
/**
* origin direction = determines if the zero scroll position is on the left or right side
* 'i' means 'invert' (i === true means that the axis must be inverted to be correct)
* true = on the left side
* false = on the right side
*/
i: parentOffset.x === childOffset.x,
/**
* negative = determines if the maximum scroll is positive or negative
* 'n' means 'negate' (n === true means that the axis must be negated to be correct)
* true = negative
* false = positive
*/
n: childOffset.x !== childOffsetAfterScroll.x,
};
};

// changes to this styles need to be reflected in the "hide native scrollbars" section of the structure styles
const envStyle = `.${classNameEnvironment}{scroll-behavior:auto!important;position:fixed;opacity:0;visibility:hidden;overflow:scroll;height:200px;width:200px;z-index:-1}.${classNameEnvironment} div{width:200%;height:200%;margin:10px 0}.${classNameEnvironmentScrollbarHidden}{scrollbar-width:none!important}.${classNameEnvironmentScrollbarHidden}::-webkit-scrollbar,.${classNameEnvironmentScrollbarHidden}::-webkit-scrollbar-corner{appearance:none!important;display:none!important;width:0!important;height:0!important}`;
const envDOM = createDOM(
Expand Down Expand Up @@ -173,7 +133,6 @@ const createEnvironment = (): Env => {
_nativeScrollbarsOverlaid: nativeScrollbarsOverlaid,
_nativeScrollbarsHiding: nativeScrollbarsHiding,
_scrollTimeline: !!scrollT,
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
_addResizeListener: bind(addEvent, 'r'),
_getDefaultInitialization: getDefaultInitialization,
_setDefaultInitialization: (newInitializationStrategy) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/overlayscrollbars/src/observers/domObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ interface DOMTargetObserverOptions extends DOMObserverOptionsBase {
* Marks certain attributes as style changing, should be a subset of the _attributes prop.
* Used to set the "targetStyleChanged" param in the DOMTargetObserverCallback.
*/
_styleChangingAttributes?: string[];
_styleChangingAttributes?: string[] | readonly string[];
}

type ContentChangeArrayItem = [selector?: string, eventNames?: string] | null | undefined;
Expand Down
69 changes: 3 additions & 66 deletions packages/overlayscrollbars/src/observers/sizeObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,28 @@ import {
addClass,
push,
ResizeObserverConstructor,
removeClass,
stopPropagation,
appendChildren,
getDirectionIsRTL,
domRectHasDimensions,
bind,
noop,
isArray,
convertScrollPosition,
scrollElementTo,
domRectAppeared,
concat,
} from '~/support';
import { getEnvironment } from '~/environment';
import {
classNameSizeObserver,
classNameSizeObserverAppear,
classNameSizeObserverListener,
} from '~/classnames';
import { getStaticPluginModuleInstance, sizeObserverPluginName } from '~/plugins';
import type { CacheValues } from '~/support';
import type { SizeObserverPlugin } from '~/plugins';

export interface SizeObserverOptions {
/** Whether direction changes should be observed. */
_direction?: boolean;
/** Whether appearing should be observed. */
_appear?: boolean;
}

export interface SizeObserverCallbackParams {
_sizeChanged: boolean;
_directionIsRTLCache?: CacheValues<boolean>;
_appear?: boolean;
}

Expand All @@ -56,12 +45,9 @@ export const createSizeObserver = (
onSizeChangedCallback: (params: SizeObserverCallbackParams) => any,
options?: SizeObserverOptions
): SizeObserver => {
const scrollAmount = 3333333;
const { _direction: observeDirectionChange, _appear: observeAppearChange } = options || {};
const { _appear: observeAppearChange } = options || {};
const sizeObserverPlugin =
getStaticPluginModuleInstance<typeof SizeObserverPlugin>(sizeObserverPluginName);
const { _rtlScrollBehavior: rtlScrollBehavior } = getEnvironment();
const getIsDirectionRTL = bind(getDirectionIsRTL, target);
const [updateResizeObserverContentRectCache] = createCache<DOMRectReadOnly | false>({
_initialValue: false,
_alwaysUpdateValues: true,
Expand All @@ -74,15 +60,11 @@ export const createSizeObserver = (
);
const sizeObserver = baseElements[0] as HTMLElement;
const listenerElement = sizeObserver.firstChild as HTMLElement;
const onSizeChangedCallbackProxy = (
sizeChangedContext?: CacheValues<boolean> | ResizeObserverEntry | boolean
) => {
const onSizeChangedCallbackProxy = (sizeChangedContext?: ResizeObserverEntry | boolean) => {
const isResizeObserverCall = sizeChangedContext instanceof ResizeObserverEntry;
const hasDirectionCache = !isResizeObserverCall && isArray(sizeChangedContext);

let skip = false;
let appear = false;
let doDirectionScroll = true; // always true if sizeChangedContext is Event (appear callback or RO. Polyfill)

// if triggered from RO.
if (isResizeObserverCall) {
Expand All @@ -94,30 +76,15 @@ export const createSizeObserver = (
const firstCall = !prevContentRect;
appear = firstCall || appeared;
skip = !appear && !hasDimensions; // skip if display is none or when window resize

doDirectionScroll = !skip; // direction scroll when not skipping
}
// else if its triggered with DirectionCache
else if (hasDirectionCache) {
[, doDirectionScroll] = sizeChangedContext; // direction scroll when DirectionCache changed, false otherwise
}
// else if it triggered with appear from polyfill
else {
appear = sizeChangedContext === true;
}

if (observeDirectionChange && doDirectionScroll) {
const rtl = hasDirectionCache ? sizeChangedContext[0] : getDirectionIsRTL(sizeObserver);
scrollElementTo(sizeObserver, {
x: convertScrollPosition(scrollAmount, scrollAmount, rtl && rtlScrollBehavior),
y: scrollAmount,
});
}

if (!skip) {
onSizeChangedCallback({
_directionIsRTLCache: hasDirectionCache ? sizeChangedContext : undefined,
_sizeChanged: !hasDirectionCache,
_sizeChanged: true,
_appear: appear,
});
}
Expand Down Expand Up @@ -151,36 +118,6 @@ export const createSizeObserver = (
return noop;
}

if (observeDirectionChange) {
const [updateDirectionIsRTLCache] = createCache(
{
_initialValue: undefined,
},
getIsDirectionRTL
);

push(
destroyFns,
addEventListener(sizeObserver, 'scroll', (event) => {
const directionIsRTLCacheValues = updateDirectionIsRTLCache();
const [directionIsRTLCache, directionIsRTLCacheChanged, directionIsRTLCachePrevious] =
directionIsRTLCacheValues;
if (directionIsRTLCacheChanged) {
removeClass(listenerElement, 'ltr rtl');
addClass(listenerElement, directionIsRTLCache ? 'rtl' : 'ltr');

onSizeChangedCallbackProxy([
!!directionIsRTLCache,
directionIsRTLCacheChanged,
directionIsRTLCachePrevious,
]);
}

stopPropagation(event);
})
);
}

return bind(runEachAndClear, push(destroyFns, appendChildren(target, sizeObserver)));
};
};
4 changes: 0 additions & 4 deletions packages/overlayscrollbars/src/overlayscrollbars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ export interface Environment {
scrollbarsOverlaid: XY<boolean>;
/** Whether the browser supports native scrollbars hiding. */
scrollbarsHiding: boolean;
/** The rtl scroll behavior of the browser. */
rtlScrollBehavior: { n: boolean; i: boolean };
/** Whether the browser supports the ScrollTimeline API. */
scrollTimeline: boolean;
/** The default Initialization to use if nothing else is specified. */
Expand Down Expand Up @@ -557,7 +555,6 @@ OverlayScrollbars.env = () => {
_nativeScrollbarsSize,
_nativeScrollbarsOverlaid,
_nativeScrollbarsHiding,
_rtlScrollBehavior,
_scrollTimeline,
_staticDefaultInitialization,
_staticDefaultOptions,
Expand All @@ -572,7 +569,6 @@ OverlayScrollbars.env = () => {
scrollbarsSize: _nativeScrollbarsSize,
scrollbarsOverlaid: _nativeScrollbarsOverlaid,
scrollbarsHiding: _nativeScrollbarsHiding,
rtlScrollBehavior: _rtlScrollBehavior,
scrollTimeline: _scrollTimeline,
staticDefaultInitialization: _staticDefaultInitialization,
staticDefaultOptions: _staticDefaultOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ export const createObserversSetup = (
// TODO: observer textarea attrs if textarea

const viewportSelector = `[${dataAttributeViewport}]`;
const viewportAttrsFromTarget = ['tabindex'];
const baseStyleChangingAttrsTextarea = ['wrap', 'cols', 'rows'];
const baseStyleChangingAttrs = ['id', 'class', 'style', 'open'];
const viewportAttrsFromTarget = ['tabindex'] as const;
const baseStyleChangingAttrsTextarea = ['wrap', 'cols', 'rows'] as const;
const baseStyleChangingAttrs = ['id', 'class', 'style', 'open'] as const;
const {
_target,
_host,
Expand Down Expand Up @@ -168,13 +168,11 @@ export const createObserversSetup = (
},
});

const setDirectionWhenViewportIsTarget = (updateHints: ObserversSetupUpdateHints) => {
if (_viewportIsTarget) {
const newDirectionIsRTL = getDirectionIsRTL(_target);
assignDeep(updateHints, { _directionChanged: prevDirectionIsRTL !== newDirectionIsRTL });
assignDeep(state, { _directionIsRTL: newDirectionIsRTL });
prevDirectionIsRTL = newDirectionIsRTL;
}
const setDirection = (updateHints: ObserversSetupUpdateHints) => {
const newDirectionIsRTL = getDirectionIsRTL(_target);
assignDeep(updateHints, { _directionChanged: prevDirectionIsRTL !== newDirectionIsRTL });
assignDeep(state, { _directionIsRTL: newDirectionIsRTL });
prevDirectionIsRTL = newDirectionIsRTL;
};

const updateViewportAttrsFromHost = (attributes?: string[]) => {
Expand Down Expand Up @@ -205,12 +203,8 @@ export const createObserversSetup = (
return updateHints;
};

const onSizeChanged = ({
_sizeChanged,
_directionIsRTLCache,
_appear,
}: SizeObserverCallbackParams) => {
const exclusiveSizeChange = _sizeChanged && !_appear && !_directionIsRTLCache;
const onSizeChanged = ({ _sizeChanged, _appear }: SizeObserverCallbackParams) => {
const exclusiveSizeChange = _sizeChanged && !_appear;
const updateFn =
// use debounceed update:
// if native scrollbars hiding is supported
Expand All @@ -219,16 +213,12 @@ export const createObserversSetup = (
? onObserversUpdatedDebounced
: onObserversUpdated;

const [directionIsRTL, directionIsRTLChanged] = _directionIsRTLCache || [];
const updateHints: ObserversSetupUpdateHints = {
_sizeChanged: _sizeChanged || _appear,
_appear,
_directionChanged: directionIsRTLChanged,
};

setDirectionWhenViewportIsTarget(updateHints);

_directionIsRTLCache && assignDeep(state, { _directionIsRTL: directionIsRTL });
setDirection(updateHints);

updateFn(updateHints);
};
Expand All @@ -242,7 +232,7 @@ export const createObserversSetup = (
_contentMutation,
};

setDirectionWhenViewportIsTarget(updateHints);
setDirection(updateHints);

// if contentChangedThroughEvent is true its already debounced
const updateFn = contentChangedThroughEvent ? onObserversUpdated : onObserversUpdatedDebounced;
Expand All @@ -261,7 +251,7 @@ export const createObserversSetup = (
_hostMutation: targetStyleChanged,
};

setDirectionWhenViewportIsTarget(updateHints);
setDirection(updateHints);

if (targetStyleChanged && !fromRecords) {
onObserversUpdatedDebounced(updateHints);
Expand All @@ -281,7 +271,6 @@ export const createObserversSetup = (
!_viewportIsTarget &&
createSizeObserver(_host, onSizeChanged, {
_appear: true,
_direction: true,
});

const [constructHostMutationObserver, updateHostMutationObserver] = createDOMObserver(
Expand Down Expand Up @@ -406,7 +395,7 @@ export const createObserversSetup = (
assignDeep(updateHints, onContentMutation(contentUpdateResult[0], takeRecords));
}

setDirectionWhenViewportIsTarget(updateHints);
setDirection(updateHints);

return updateHints;
},
Expand Down
25 changes: 0 additions & 25 deletions packages/overlayscrollbars/src/support/dom/scroll.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
import type { Env } from '~/environment';
import type { XY } from './offset';
import type { WH } from './dimensions';
import { capNumber, isNumber, mathAbs, mathSign } from '../utils';

export type RTLScrollBehavior = Env['_rtlScrollBehavior'] | false | null | undefined;

export interface ScrollCoordinates {
/** The start (origin) scroll coordinates for each axis. */
_start: XY<number>;
/** The end scroll coordinates for each axis. */
_end: XY<number>;
}

/**
* Transforms a normalized scroll position to a RTL compatilbe scroll position value or vice versa (depending on the input format).
* @param scrollPosition The scroll position value.
* @param overflowAmount The (normalized) overflow amount value.
* @param rtlScrollBehavior The RTL scroll behavior or `falsy` if the rtl scroll behavior doesn't apply.
* @returns The input scroll position, just converted.
* If the input `scrollPosition` is normalized the raw (RTL Compatible) format is returned.
* If the input `scrollPosition` is raw (RTL Compatible) the normalized format is returned.
*/
export const convertScrollPosition = (
scrollPosition: number,
overflowAmount: number,
rtlScrollBehavior?: RTLScrollBehavior
) =>
rtlScrollBehavior
? rtlScrollBehavior.n
? -scrollPosition + 0 // +0 avoids negative zero (-0) as a result
: rtlScrollBehavior.i
? overflowAmount - scrollPosition
: scrollPosition
: scrollPosition;

/**
* Scroll the passed element to the passed position.
* @param elm The element to be scrolled.
Expand Down

0 comments on commit 0204fcd

Please sign in to comment.