mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-22 08:00:37 +03:00
move viewports elements classnames to data attribute to prevent overwriting by 3rd party libs
This commit is contained in:
@@ -3,6 +3,7 @@ export const classNameEnvironmentFlexboxGlue = `${classNameEnvironment}-flexbox-
|
|||||||
export const classNameEnvironmentFlexboxGlueMax = `${classNameEnvironmentFlexboxGlue}-max`;
|
export const classNameEnvironmentFlexboxGlueMax = `${classNameEnvironmentFlexboxGlue}-max`;
|
||||||
|
|
||||||
export const dataAttributeHost = 'data-overlayscrollbars';
|
export const dataAttributeHost = 'data-overlayscrollbars';
|
||||||
|
export const dataAttributeViewport = 'data-overlayscrollbars-viewport';
|
||||||
export const dataAttributeInitialize = 'data-overlayscrollbars-initialize';
|
export const dataAttributeInitialize = 'data-overlayscrollbars-initialize';
|
||||||
export const dataAttributeHostOverflowX = `${dataAttributeHost}-overflow-x`;
|
export const dataAttributeHostOverflowX = `${dataAttributeHost}-overflow-x`;
|
||||||
export const dataAttributeHostOverflowY = `${dataAttributeHost}-overflow-y`;
|
export const dataAttributeHostOverflowY = `${dataAttributeHost}-overflow-y`;
|
||||||
@@ -11,11 +12,12 @@ export const dataValueHostScrollbarHidden = 'scrollbarHidden';
|
|||||||
export const dataValueHostScrollbarPressed = 'scrollbarPressed';
|
export const dataValueHostScrollbarPressed = 'scrollbarPressed';
|
||||||
export const dataValueHostUpdating = 'updating';
|
export const dataValueHostUpdating = 'updating';
|
||||||
export const classNamePadding = 'os-padding';
|
export const classNamePadding = 'os-padding';
|
||||||
export const classNameViewport = 'os-viewport';
|
export const dataValueViewportArrange = 'arrange';
|
||||||
export const classNameViewportArrange = `${classNameViewport}-arrange`;
|
export const dataValueViewportScrollbarHidden = 'scrollbarHidden';
|
||||||
|
export const dataValueViewportOverflowVisible = 'overflowVisible';
|
||||||
export const classNameContent = 'os-content';
|
export const classNameContent = 'os-content';
|
||||||
export const classNameViewportScrollbarHidden = `${classNameViewport}-scrollbar-hidden`;
|
|
||||||
export const classNameOverflowVisible = `os-overflow-visible`;
|
export const classNameOverflowVisible = `os-overflow-visible`;
|
||||||
|
export const classNameScrollbarHidden = `os-scrollbar-hidden`;
|
||||||
|
|
||||||
export const classNameSizeObserver = 'os-size-observer';
|
export const classNameSizeObserver = 'os-size-observer';
|
||||||
export const classNameSizeObserverAppear = `${classNameSizeObserver}-appear`;
|
export const classNameSizeObserverAppear = `${classNameSizeObserver}-appear`;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
classNameEnvironment,
|
classNameEnvironment,
|
||||||
classNameEnvironmentFlexboxGlue,
|
classNameEnvironmentFlexboxGlue,
|
||||||
classNameEnvironmentFlexboxGlueMax,
|
classNameEnvironmentFlexboxGlueMax,
|
||||||
classNameViewportScrollbarHidden,
|
classNameScrollbarHidden,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import { defaultOptions } from '~/options';
|
import { defaultOptions } from '~/options';
|
||||||
import { getPlugins, scrollbarsHidingPluginName } from '~/plugins';
|
import { getPlugins, scrollbarsHidingPluginName } from '~/plugins';
|
||||||
@@ -120,7 +120,7 @@ const getNativeScrollbarSize = (
|
|||||||
|
|
||||||
const getNativeScrollbarsHiding = (testElm: HTMLElement): boolean => {
|
const getNativeScrollbarsHiding = (testElm: HTMLElement): boolean => {
|
||||||
let result = false;
|
let result = false;
|
||||||
const revertClass = addClass(testElm, classNameViewportScrollbarHidden);
|
const revertClass = addClass(testElm, classNameScrollbarHidden);
|
||||||
try {
|
try {
|
||||||
result =
|
result =
|
||||||
style(testElm, cssProperty('scrollbar-width')) === 'none' ||
|
style(testElm, cssProperty('scrollbar-width')) === 'none' ||
|
||||||
|
|||||||
+15
-16
@@ -1,15 +1,5 @@
|
|||||||
import {
|
import { keys, attr, style, noop, each, assignDeep, windowSize, attrClass } from '~/support';
|
||||||
keys,
|
import { dataValueViewportArrange, dataAttributeViewport } from '~/classnames';
|
||||||
attr,
|
|
||||||
style,
|
|
||||||
addClass,
|
|
||||||
removeClass,
|
|
||||||
noop,
|
|
||||||
each,
|
|
||||||
assignDeep,
|
|
||||||
windowSize,
|
|
||||||
} from '~/support';
|
|
||||||
import { classNameViewportArrange } from '~/classnames';
|
|
||||||
import type { WH, UpdateCache, XY } from '~/support';
|
import type { WH, UpdateCache, XY } from '~/support';
|
||||||
import type { StyleObject } from '~/typings';
|
import type { StyleObject } from '~/typings';
|
||||||
import type { StructureSetupState } from '~/setups/structureSetup';
|
import type { StructureSetupState } from '~/setups/structureSetup';
|
||||||
@@ -89,7 +79,11 @@ export const ScrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance> =
|
|||||||
const result = create ? document.createElement('style') : false;
|
const result = create ? document.createElement('style') : false;
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
attr(result, 'id', `${classNameViewportArrange}-${contentArrangeCounter}`);
|
attr(
|
||||||
|
result,
|
||||||
|
'id',
|
||||||
|
`${dataAttributeViewport}-${dataValueViewportArrange}-${contentArrangeCounter}`
|
||||||
|
);
|
||||||
contentArrangeCounter++;
|
contentArrangeCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +148,10 @@ export const ScrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance> =
|
|||||||
if (cssRules) {
|
if (cssRules) {
|
||||||
if (!cssRules.length) {
|
if (!cssRules.length) {
|
||||||
sheet.insertRule(
|
sheet.insertRule(
|
||||||
`#${attr(viewportArrange, 'id')} + .${classNameViewportArrange}::before {}`,
|
`#${attr(
|
||||||
|
viewportArrange,
|
||||||
|
'id'
|
||||||
|
)} + [${dataAttributeViewport}~='${dataValueViewportArrange}']::before {}`,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -211,7 +208,8 @@ export const ScrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance> =
|
|||||||
|
|
||||||
const prevStyle = style(viewport, keys(finalPaddingStyle));
|
const prevStyle = style(viewport, keys(finalPaddingStyle));
|
||||||
|
|
||||||
removeClass(viewport, classNameViewportArrange);
|
// add class
|
||||||
|
attrClass(viewport, dataAttributeViewport, dataValueViewportArrange);
|
||||||
|
|
||||||
if (!flexboxGlue) {
|
if (!flexboxGlue) {
|
||||||
finalPaddingStyle.height = '';
|
finalPaddingStyle.height = '';
|
||||||
@@ -228,7 +226,8 @@ export const ScrollbarsHidingPlugin: Plugin<ScrollbarsHidingPluginInstance> =
|
|||||||
prevStyle
|
prevStyle
|
||||||
);
|
);
|
||||||
style(viewport, prevStyle);
|
style(viewport, prevStyle);
|
||||||
addClass(viewport, classNameViewportArrange);
|
// remove class
|
||||||
|
attrClass(viewport, dataAttributeViewport, dataValueViewportArrange, true);
|
||||||
},
|
},
|
||||||
finalViewportOverflowState,
|
finalViewportOverflowState,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import {
|
|||||||
parent,
|
parent,
|
||||||
indexOf,
|
indexOf,
|
||||||
removeElements,
|
removeElements,
|
||||||
removeClass,
|
|
||||||
hasClass,
|
|
||||||
push,
|
push,
|
||||||
runEachAndClear,
|
runEachAndClear,
|
||||||
insertBefore,
|
insertBefore,
|
||||||
@@ -28,9 +26,10 @@ import {
|
|||||||
dataAttributeHostOverflowX,
|
dataAttributeHostOverflowX,
|
||||||
dataAttributeHostOverflowY,
|
dataAttributeHostOverflowY,
|
||||||
classNamePadding,
|
classNamePadding,
|
||||||
classNameViewport,
|
|
||||||
classNameContent,
|
classNameContent,
|
||||||
classNameViewportScrollbarHidden,
|
classNameScrollbarHidden,
|
||||||
|
dataAttributeViewport,
|
||||||
|
dataValueViewportScrollbarHidden,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import { getEnvironment } from '~/environment';
|
import { getEnvironment } from '~/environment';
|
||||||
import { getPlugins, scrollbarsHidingPluginName } from '~/plugins';
|
import { getPlugins, scrollbarsHidingPluginName } from '~/plugins';
|
||||||
@@ -69,8 +68,15 @@ export interface StructureSetupElementsObj {
|
|||||||
_targetIsElm: boolean;
|
_targetIsElm: boolean;
|
||||||
_viewportIsTarget: boolean;
|
_viewportIsTarget: boolean;
|
||||||
_viewportIsContent: boolean;
|
_viewportIsContent: boolean;
|
||||||
_viewportHasClass: (className: string, attributeClassName: string) => boolean;
|
_viewportHasClass: (
|
||||||
_viewportAddRemoveClass: (className: string, attributeClassName: string, add?: boolean) => void;
|
viewportAttributeClassName: string,
|
||||||
|
hostAttributeClassName: string
|
||||||
|
) => boolean;
|
||||||
|
_viewportAddRemoveClass: (
|
||||||
|
viewportAttributeClassName: string,
|
||||||
|
hostAttributeClassName: string,
|
||||||
|
add?: boolean
|
||||||
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabIndexStr = 'tabindex';
|
const tabIndexStr = 'tabindex';
|
||||||
@@ -184,14 +190,23 @@ export const createStructureSetupElements = (
|
|||||||
_targetIsElm: targetIsElm,
|
_targetIsElm: targetIsElm,
|
||||||
_viewportIsTarget: viewportIsTarget,
|
_viewportIsTarget: viewportIsTarget,
|
||||||
_viewportIsContent: viewportIsContent,
|
_viewportIsContent: viewportIsContent,
|
||||||
_viewportHasClass: (className: string, attributeClassName: string) =>
|
_viewportHasClass: (viewportAttributeClassName: string, hostAttributeClassName: string) =>
|
||||||
viewportIsTarget
|
hasAttrClass(
|
||||||
? hasAttrClass(viewportElement, dataAttributeHost, attributeClassName)
|
viewportElement,
|
||||||
: hasClass(viewportElement, className),
|
viewportIsTarget ? dataAttributeHost : dataAttributeViewport,
|
||||||
_viewportAddRemoveClass: (className: string, attributeClassName: string, add?: boolean) =>
|
viewportIsTarget ? hostAttributeClassName : viewportAttributeClassName
|
||||||
viewportIsTarget
|
),
|
||||||
? attrClass(viewportElement, dataAttributeHost, attributeClassName, add)
|
_viewportAddRemoveClass: (
|
||||||
: (add ? addClass : removeClass)(viewportElement, className),
|
viewportAttributeClassName: string,
|
||||||
|
hostAttributeClassName: string,
|
||||||
|
add?: boolean
|
||||||
|
) =>
|
||||||
|
attrClass(
|
||||||
|
viewportElement,
|
||||||
|
viewportIsTarget ? dataAttributeHost : dataAttributeViewport,
|
||||||
|
viewportIsTarget ? hostAttributeClassName : viewportAttributeClassName,
|
||||||
|
add
|
||||||
|
),
|
||||||
};
|
};
|
||||||
const generatedElements = keys(evaluatedTargetObj).reduce((arr, key: string) => {
|
const generatedElements = keys(evaluatedTargetObj).reduce((arr, key: string) => {
|
||||||
const value = evaluatedTargetObj[key];
|
const value = evaluatedTargetObj[key];
|
||||||
@@ -224,12 +239,15 @@ export const createStructureSetupElements = (
|
|||||||
const appendElements = () => {
|
const appendElements = () => {
|
||||||
attr(_host, dataAttributeHost, viewportIsTarget ? 'viewport' : 'host');
|
attr(_host, dataAttributeHost, viewportIsTarget ? 'viewport' : 'host');
|
||||||
|
|
||||||
|
if (!viewportIsTarget) {
|
||||||
|
attr(_viewport, dataAttributeViewport, '');
|
||||||
|
}
|
||||||
|
|
||||||
const removePaddingClass = addClass(_padding, classNamePadding);
|
const removePaddingClass = addClass(_padding, classNamePadding);
|
||||||
const removeViewportClass = addClass(_viewport, !viewportIsTarget && classNameViewport);
|
|
||||||
const removeContentClass = addClass(_content, classNameContent);
|
const removeContentClass = addClass(_content, classNameContent);
|
||||||
const removeHtmlClass =
|
const removeHtmlClass =
|
||||||
isBody && !viewportIsTarget
|
isBody && !viewportIsTarget
|
||||||
? addClass(parent(targetElement), classNameViewportScrollbarHidden)
|
? addClass(parent(targetElement), classNameScrollbarHidden)
|
||||||
: noop;
|
: noop;
|
||||||
|
|
||||||
// only insert host for textarea after target if it was generated
|
// only insert host for textarea after target if it was generated
|
||||||
@@ -251,6 +269,7 @@ export const createStructureSetupElements = (
|
|||||||
removeHtmlClass();
|
removeHtmlClass();
|
||||||
removeAttr(_viewport, dataAttributeHostOverflowX);
|
removeAttr(_viewport, dataAttributeHostOverflowX);
|
||||||
removeAttr(_viewport, dataAttributeHostOverflowY);
|
removeAttr(_viewport, dataAttributeHostOverflowY);
|
||||||
|
removeAttr(_viewport, dataAttributeViewport);
|
||||||
|
|
||||||
if (elementIsGenerated(_content)) {
|
if (elementIsGenerated(_content)) {
|
||||||
unwrap(_content);
|
unwrap(_content);
|
||||||
@@ -261,13 +280,14 @@ export const createStructureSetupElements = (
|
|||||||
if (elementIsGenerated(_padding)) {
|
if (elementIsGenerated(_padding)) {
|
||||||
unwrap(_padding);
|
unwrap(_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
removePaddingClass();
|
removePaddingClass();
|
||||||
removeViewportClass();
|
|
||||||
removeContentClass();
|
removeContentClass();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_nativeScrollbarsHiding && !viewportIsTarget) {
|
if (_nativeScrollbarsHiding && !viewportIsTarget) {
|
||||||
push(destroyFns, removeClass.bind(0, _viewport, classNameViewportScrollbarHidden));
|
attrClass(_viewport, dataAttributeViewport, dataValueViewportScrollbarHidden, true);
|
||||||
|
push(destroyFns, removeAttr.bind(0, _viewport, dataAttributeViewport));
|
||||||
}
|
}
|
||||||
if (_viewportArrange) {
|
if (_viewportArrange) {
|
||||||
insertBefore(_viewport, _viewportArrange);
|
insertBefore(_viewport, _viewportArrange);
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ import {
|
|||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
dataValueHostOverflowVisible,
|
dataValueHostOverflowVisible,
|
||||||
dataValueHostUpdating,
|
dataValueHostUpdating,
|
||||||
classNameViewport,
|
|
||||||
classNameOverflowVisible,
|
|
||||||
classNameScrollbar,
|
classNameScrollbar,
|
||||||
classNameViewportArrange,
|
dataValueViewportArrange,
|
||||||
|
dataAttributeViewport,
|
||||||
|
dataValueViewportOverflowVisible,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import { createSizeObserver, createTrinsicObserver, createDOMObserver } from '~/observers';
|
import { createSizeObserver, createTrinsicObserver, createDOMObserver } from '~/observers';
|
||||||
import type { DOMObserver, SizeObserverCallbackParams } from '~/observers';
|
import type { DOMObserver, SizeObserverCallbackParams } from '~/observers';
|
||||||
@@ -62,7 +62,7 @@ const hostSelector = `[${dataAttributeHost}]`;
|
|||||||
|
|
||||||
// TODO: observer textarea attrs if textarea
|
// TODO: observer textarea attrs if textarea
|
||||||
|
|
||||||
const viewportSelector = `.${classNameViewport}`;
|
const viewportSelector = `[${dataAttributeViewport}]`;
|
||||||
const viewportAttrsFromTarget = ['tabindex'];
|
const viewportAttrsFromTarget = ['tabindex'];
|
||||||
const baseStyleChangingAttrsTextarea = ['wrap', 'cols', 'rows'];
|
const baseStyleChangingAttrsTextarea = ['wrap', 'cols', 'rows'];
|
||||||
const baseStyleChangingAttrs = ['id', 'class', 'style', 'open'];
|
const baseStyleChangingAttrs = ['id', 'class', 'style', 'open'];
|
||||||
@@ -94,20 +94,27 @@ export const createStructureSetupObservers = (
|
|||||||
_initialValue: { w: 0, h: 0 },
|
_initialValue: { w: 0, h: 0 },
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
const hasOver = _viewportHasClass(classNameOverflowVisible, dataValueHostOverflowVisible);
|
const hasOver = _viewportHasClass(
|
||||||
const hasVpStyle = _viewportHasClass(classNameViewportArrange, '');
|
dataValueViewportOverflowVisible,
|
||||||
|
dataValueHostOverflowVisible
|
||||||
|
);
|
||||||
|
const hasVpStyle = _viewportHasClass(dataValueViewportArrange, '');
|
||||||
const scrollOffsetX = hasVpStyle && scrollLeft(_viewport);
|
const scrollOffsetX = hasVpStyle && scrollLeft(_viewport);
|
||||||
const scrollOffsetY = hasVpStyle && scrollTop(_viewport);
|
const scrollOffsetY = hasVpStyle && scrollTop(_viewport);
|
||||||
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible);
|
_viewportAddRemoveClass(dataValueViewportOverflowVisible, dataValueHostOverflowVisible);
|
||||||
_viewportAddRemoveClass(classNameViewportArrange, '');
|
_viewportAddRemoveClass(dataValueViewportArrange, '');
|
||||||
_viewportAddRemoveClass('', dataValueHostUpdating, true);
|
_viewportAddRemoveClass('', dataValueHostUpdating, true);
|
||||||
|
|
||||||
const contentScroll = scrollSize(_content);
|
const contentScroll = scrollSize(_content);
|
||||||
const viewportScroll = scrollSize(_viewport);
|
const viewportScroll = scrollSize(_viewport);
|
||||||
const fractional = fractionalSize(_viewport);
|
const fractional = fractionalSize(_viewport);
|
||||||
|
|
||||||
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible, hasOver);
|
_viewportAddRemoveClass(
|
||||||
_viewportAddRemoveClass(classNameViewportArrange, '', hasVpStyle);
|
dataValueViewportOverflowVisible,
|
||||||
|
dataValueHostOverflowVisible,
|
||||||
|
hasOver
|
||||||
|
);
|
||||||
|
_viewportAddRemoveClass(dataValueViewportArrange, '', hasVpStyle);
|
||||||
_viewportAddRemoveClass('', dataValueHostUpdating);
|
_viewportAddRemoveClass('', dataValueHostUpdating);
|
||||||
scrollLeft(_viewport, scrollOffsetX);
|
scrollLeft(_viewport, scrollOffsetX);
|
||||||
scrollTop(_viewport, scrollOffsetY);
|
scrollTop(_viewport, scrollOffsetY);
|
||||||
|
|||||||
+11
-4
@@ -14,13 +14,14 @@ import {
|
|||||||
} from '~/support';
|
} from '~/support';
|
||||||
import { getEnvironment } from '~/environment';
|
import { getEnvironment } from '~/environment';
|
||||||
import {
|
import {
|
||||||
classNameViewportScrollbarHidden,
|
|
||||||
classNameOverflowVisible,
|
classNameOverflowVisible,
|
||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
dataAttributeHostOverflowX,
|
dataAttributeHostOverflowX,
|
||||||
dataAttributeHostOverflowY,
|
dataAttributeHostOverflowY,
|
||||||
dataValueHostScrollbarHidden,
|
dataValueHostScrollbarHidden,
|
||||||
dataValueHostOverflowVisible,
|
dataValueHostOverflowVisible,
|
||||||
|
dataValueViewportScrollbarHidden,
|
||||||
|
dataValueViewportOverflowVisible,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import { getPlugins, scrollbarsHidingPluginName } from '~/plugins';
|
import { getPlugins, scrollbarsHidingPluginName } from '~/plugins';
|
||||||
import type { WH, XY } from '~/support';
|
import type { WH, XY } from '~/support';
|
||||||
@@ -358,7 +359,7 @@ export const createOverflowUpdateSegment: CreateStructureUpdateSegment = (
|
|||||||
|
|
||||||
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarsHiding) {
|
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarsHiding) {
|
||||||
_viewportAddRemoveClass(
|
_viewportAddRemoveClass(
|
||||||
classNameViewportScrollbarHidden,
|
dataValueViewportScrollbarHidden,
|
||||||
dataValueHostScrollbarHidden,
|
dataValueHostScrollbarHidden,
|
||||||
!showNativeOverlaidScrollbars
|
!showNativeOverlaidScrollbars
|
||||||
);
|
);
|
||||||
@@ -377,7 +378,11 @@ export const createOverflowUpdateSegment: CreateStructureUpdateSegment = (
|
|||||||
showNativeOverlaidScrollbarsChanged
|
showNativeOverlaidScrollbarsChanged
|
||||||
) {
|
) {
|
||||||
if (overflowVisible) {
|
if (overflowVisible) {
|
||||||
_viewportAddRemoveClass(classNameOverflowVisible, dataValueHostOverflowVisible, false);
|
_viewportAddRemoveClass(
|
||||||
|
dataValueViewportOverflowVisible,
|
||||||
|
dataValueHostOverflowVisible,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [redoViewportArrange, undoViewportArrangeOverflowState] = undoViewportArrange(
|
const [redoViewportArrange, undoViewportArrangeOverflowState] = undoViewportArrange(
|
||||||
@@ -504,7 +509,9 @@ export const createOverflowUpdateSegment: CreateStructureUpdateSegment = (
|
|||||||
|
|
||||||
attrClass(_host, dataAttributeHost, dataValueHostOverflowVisible, removeClipping);
|
attrClass(_host, dataAttributeHost, dataValueHostOverflowVisible, removeClipping);
|
||||||
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
||||||
!_viewportIsTarget && conditionalClass(_viewport, classNameOverflowVisible, overflowVisible);
|
if (!_viewportIsTarget) {
|
||||||
|
_viewportAddRemoveClass(dataValueViewportOverflowVisible, '', overflowVisible);
|
||||||
|
}
|
||||||
|
|
||||||
const [overflowStyle, overflowStyleChanged] = updateOverflowStyleCache(
|
const [overflowStyle, overflowStyleChanged] = updateOverflowStyleCache(
|
||||||
getViewportOverflowState(showNativeOverlaidScrollbars)._overflowStyle
|
getViewportOverflowState(showNativeOverlaidScrollbars)._overflowStyle
|
||||||
|
|||||||
@@ -58,23 +58,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.os-environment,
|
.os-environment,
|
||||||
.os-viewport {
|
[data-overlayscrollbars-viewport] {
|
||||||
-ms-overflow-style: scrollbar !important;
|
-ms-overflow-style: scrollbar !important;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-initialize],
|
[data-overlayscrollbars-initialize],
|
||||||
[data-overlayscrollbars~='scrollbarHidden'],
|
[data-overlayscrollbars~='scrollbarHidden'],
|
||||||
.os-viewport-scrollbar-hidden.os-environment,
|
[data-overlayscrollbars-viewport~='scrollbarHidden'],
|
||||||
.os-viewport-scrollbar-hidden.os-viewport {
|
.os-scrollbar-hidden.os-environment {
|
||||||
scrollbar-width: none !important;
|
scrollbar-width: none !important;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-initialize]::-webkit-scrollbar,
|
[data-overlayscrollbars-initialize]::-webkit-scrollbar,
|
||||||
[data-overlayscrollbars-initialize]::-webkit-scrollbar-corner,
|
[data-overlayscrollbars-initialize]::-webkit-scrollbar-corner,
|
||||||
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar,
|
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar,
|
||||||
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar-corner,
|
[data-overlayscrollbars~='scrollbarHidden']::-webkit-scrollbar-corner,
|
||||||
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar,
|
[data-overlayscrollbars-viewport~='scrollbarHidden']::-webkit-scrollbar,
|
||||||
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar-corner,
|
[data-overlayscrollbars-viewport~='scrollbarHidden']::-webkit-scrollbar-corner,
|
||||||
.os-viewport-scrollbar-hidden.os-viewport::-webkit-scrollbar,
|
.os-scrollbar-hidden.os-environment::-webkit-scrollbar,
|
||||||
.os-viewport-scrollbar-hidden.os-viewport::-webkit-scrollbar-corner {
|
.os-scrollbar-hidden.os-environment::-webkit-scrollbar-corner {
|
||||||
appearance: none !important;
|
appearance: none !important;
|
||||||
display: none !important;
|
display: none !important;
|
||||||
width: 0 !important;
|
width: 0 !important;
|
||||||
@@ -94,8 +94,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
html[data-overlayscrollbars],
|
html[data-overlayscrollbars],
|
||||||
html.os-viewport-scrollbar-hidden,
|
html.os-scrollbar-hidden,
|
||||||
html.os-viewport-scrollbar-hidden > body {
|
html.os-scrollbar-hidden > body {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -120,7 +120,7 @@ html[data-overlayscrollbars] > body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.os-padding,
|
.os-padding,
|
||||||
.os-viewport {
|
[data-overlayscrollbars-viewport] {
|
||||||
box-sizing: inherit;
|
box-sizing: inherit;
|
||||||
position: relative; // needed for correct padding styles
|
position: relative; // needed for correct padding styles
|
||||||
flex: auto !important;
|
flex: auto !important;
|
||||||
@@ -132,11 +132,11 @@ html[data-overlayscrollbars] > body {
|
|||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.os-viewport {
|
[data-overlayscrollbars-viewport] {
|
||||||
--os-vaw: 0;
|
--os-vaw: 0;
|
||||||
--os-vah: 0;
|
--os-vah: 0;
|
||||||
|
|
||||||
&.os-viewport-arrange::before {
|
&[data-overlayscrollbars-viewport~='arrange']::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@@ -148,11 +148,17 @@ html[data-overlayscrollbars] > body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.os-padding,
|
||||||
|
[data-overlayscrollbars-viewport] {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
[data-overlayscrollbars~='host'],
|
[data-overlayscrollbars~='host'],
|
||||||
[data-overlayscrollbars~='viewport'] {
|
[data-overlayscrollbars~='viewport'] {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars~='overflowVisible'] {
|
[data-overlayscrollbars~='overflowVisible'],
|
||||||
|
[data-overlayscrollbars-viewport~='overflowVisible'] {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-overflow-x='hidden'] {
|
[data-overlayscrollbars-overflow-x='hidden'] {
|
||||||
@@ -169,15 +175,10 @@ html[data-overlayscrollbars] > body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[data-overlayscrollbars~='scrollbarPressed'],
|
[data-overlayscrollbars~='scrollbarPressed'],
|
||||||
[data-overlayscrollbars~='scrollbarPressed'] .os-viewport {
|
[data-overlayscrollbars~='scrollbarPressed'] [data-overlayscrollbars-viewport] {
|
||||||
scroll-behavior: auto !important;
|
scroll-behavior: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.os-padding,
|
|
||||||
.os-viewport {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.os-overflow-visible {
|
.os-overflow-visible {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
@@ -196,8 +197,8 @@ html[data-overlayscrollbars] > body {
|
|||||||
grid-template: 1fr / 1fr;
|
grid-template: 1fr / 1fr;
|
||||||
}
|
}
|
||||||
[data-overlayscrollbars-grid] > .os-padding,
|
[data-overlayscrollbars-grid] > .os-padding,
|
||||||
[data-overlayscrollbars-grid] > .os-viewport,
|
[data-overlayscrollbars-grid] > [data-overlayscrollbars-viewport],
|
||||||
[data-overlayscrollbars-grid] > .os-padding > .os-viewport {
|
[data-overlayscrollbars-grid] > .os-padding > [data-overlayscrollbars-viewport] {
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,15 @@ export const attr = ((
|
|||||||
elm && elm.setAttribute(attrName, value);
|
elm && elm.setAttribute(attrName, value);
|
||||||
}) as Attr;
|
}) as Attr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given attribute from the given element.
|
||||||
|
* @param elm The element of which the attribute shall be removed.
|
||||||
|
* @param attrName The attribute name.
|
||||||
|
*/
|
||||||
|
export const removeAttr = (elm: Element | false | null | undefined, attrName: string): void => {
|
||||||
|
elm && elm.removeAttribute(attrName);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Treats the given attribute like the "class" attribute and adds or removes the given value from it.
|
* Treats the given attribute like the "class" attribute and adds or removes the given value from it.
|
||||||
* @param elm The element.
|
* @param elm The element.
|
||||||
@@ -65,8 +74,8 @@ export const attrClass = (
|
|||||||
const currValues = attr(elm, attrName) || '';
|
const currValues = attr(elm, attrName) || '';
|
||||||
const currValuesSet = new Set(currValues.split(' '));
|
const currValuesSet = new Set(currValues.split(' '));
|
||||||
currValuesSet[add ? 'add' : 'delete'](value);
|
currValuesSet[add ? 'add' : 'delete'](value);
|
||||||
|
const newTokens = from(currValuesSet).join(' ').trim();
|
||||||
attr(elm, attrName, from(currValuesSet).join(' ').trim());
|
attr(elm, attrName, newTokens);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,15 +96,6 @@ export const hasAttrClass = (
|
|||||||
return currValuesSet.has(value);
|
return currValuesSet.has(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the given attribute from the given element.
|
|
||||||
* @param elm The element of which the attribute shall be removed.
|
|
||||||
* @param attrName The attribute name.
|
|
||||||
*/
|
|
||||||
export const removeAttr = (elm: Element | false | null | undefined, attrName: string): void => {
|
|
||||||
elm && elm.removeAttribute(attrName);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets or sets the scrollLeft value of the given element depending whether the value attribute is given.
|
* Gets or sets the scrollLeft value of the given element depending whether the value attribute is given.
|
||||||
* @param elm The element of which the scrollLeft value shall be get or set.
|
* @param elm The element of which the scrollLeft value shall be get or set.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { rAF, cAF } from '~/support/compatibility';
|
import { rAF, cAF } from '~/support/compatibility';
|
||||||
import { isFunction } from '~/support/utils';
|
import { isFunction } from './types';
|
||||||
|
|
||||||
const { max } = Math;
|
const { max } = Math;
|
||||||
const animationCurrentTime = () => performance.now();
|
const animationCurrentTime = () => performance.now();
|
||||||
|
|||||||
+6
-8
@@ -1,11 +1,11 @@
|
|||||||
import { hasClass, is, isHTMLElement } from '~/support';
|
import { is, isHTMLElement } from '~/support';
|
||||||
import { resolveInitialization } from '~/initialization';
|
import { resolveInitialization } from '~/initialization';
|
||||||
import {
|
import {
|
||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
dataAttributeInitialize,
|
dataAttributeInitialize,
|
||||||
classNamePadding,
|
classNamePadding,
|
||||||
classNameViewport,
|
|
||||||
classNameContent,
|
classNameContent,
|
||||||
|
dataAttributeViewport,
|
||||||
} from '~/classnames';
|
} from '~/classnames';
|
||||||
import { getEnvironment } from '~/environment';
|
import { getEnvironment } from '~/environment';
|
||||||
import { createStructureSetupElements } from '~/setups/structureSetup/structureSetup.elements';
|
import { createStructureSetupElements } from '~/setups/structureSetup/structureSetup.elements';
|
||||||
@@ -89,7 +89,7 @@ const getElements = (targetType: TargetType) => {
|
|||||||
const target = getTarget(targetType);
|
const target = getTarget(targetType);
|
||||||
const host = document.querySelector(`[${dataAttributeHost}]`)!;
|
const host = document.querySelector(`[${dataAttributeHost}]`)!;
|
||||||
const padding = document.querySelector(`.${classNamePadding}`)!;
|
const padding = document.querySelector(`.${classNamePadding}`)!;
|
||||||
const viewport = document.querySelector(`.${classNameViewport}`)!;
|
const viewport = document.querySelector(`[${dataAttributeViewport}]`)!;
|
||||||
const content = document.querySelector(`.${classNameContent}`)!;
|
const content = document.querySelector(`.${classNameContent}`)!;
|
||||||
const children =
|
const children =
|
||||||
targetType === 'textarea'
|
targetType === 'textarea'
|
||||||
@@ -426,16 +426,14 @@ const assertCorrectSetupElements = (
|
|||||||
expect(_viewportHasClass('', attrName)).toBe(true);
|
expect(_viewportHasClass('', attrName)).toBe(true);
|
||||||
expect(_host.getAttribute(dataAttributeHost)!.indexOf(attrName) >= 0).toBe(true);
|
expect(_host.getAttribute(dataAttributeHost)!.indexOf(attrName) >= 0).toBe(true);
|
||||||
} else {
|
} else {
|
||||||
expect(hasClass(_viewport, className)).toBe(true);
|
expect(_viewportHasClass(className, attrName)).toBe(true);
|
||||||
expect(_viewportHasClass(className, '')).toBe(true);
|
|
||||||
}
|
}
|
||||||
_viewportAddRemoveClass(className, attrName);
|
_viewportAddRemoveClass(className, attrName);
|
||||||
if (_viewportIsTarget) {
|
if (_viewportIsTarget) {
|
||||||
expect(_host.getAttribute(dataAttributeHost)!.indexOf(attrName) >= 0).toBe(false);
|
expect(_host.getAttribute(dataAttributeHost)!.indexOf(attrName) >= 0).toBe(false);
|
||||||
expect(_viewportHasClass('', attrName)).toBe(false);
|
expect(_viewportHasClass('', attrName)).toBe(false);
|
||||||
} else {
|
} else {
|
||||||
expect(hasClass(_viewport, className)).toBe(false);
|
expect(_viewportHasClass(className, attrName)).toBe(false);
|
||||||
expect(_viewportHasClass(className, '')).toBe(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [elements, destroy];
|
return [elements, destroy];
|
||||||
@@ -453,7 +451,7 @@ const assertCorrectDestroy = (snapshot: string, destroy: () => void) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(snapshot).toBe(getSnapshot());
|
expect(getSnapshot()).toBe(snapshot);
|
||||||
};
|
};
|
||||||
|
|
||||||
const env: InternalEnvironment = jest.requireActual('~/environment').getEnvironment();
|
const env: InternalEnvironment = jest.requireActual('~/environment').getEnvironment();
|
||||||
|
|||||||
+5
-3
@@ -2,7 +2,7 @@ import '~/index.scss';
|
|||||||
import './index.scss';
|
import './index.scss';
|
||||||
import './handleEnvironment';
|
import './handleEnvironment';
|
||||||
import { OverlayScrollbars } from '~/overlayscrollbars';
|
import { OverlayScrollbars } from '~/overlayscrollbars';
|
||||||
import { classNameViewport } from '~/classnames';
|
import { dataAttributeViewport } from '~/classnames';
|
||||||
import should from 'should';
|
import should from 'should';
|
||||||
import {
|
import {
|
||||||
generateClassChangeSelectCallback,
|
generateClassChangeSelectCallback,
|
||||||
@@ -132,7 +132,7 @@ const targetUpdatesSlot: HTMLElement | null = document.querySelector('#updates')
|
|||||||
const comparisonContentElm: HTMLElement = document.createElement('div');
|
const comparisonContentElm: HTMLElement = document.createElement('div');
|
||||||
const envElms = document.querySelectorAll<HTMLElement>('.env');
|
const envElms = document.querySelectorAll<HTMLElement>('.env');
|
||||||
const getComparisonViewport = () =>
|
const getComparisonViewport = () =>
|
||||||
(comparison?.querySelector(`.${classNameViewport}`) || comparison) as HTMLElement;
|
(comparison?.querySelector(`[${dataAttributeViewport}]`) || comparison) as HTMLElement;
|
||||||
|
|
||||||
const initObj = hasClass(document.body, 'vpt')
|
const initObj = hasClass(document.body, 'vpt')
|
||||||
? {
|
? {
|
||||||
@@ -214,7 +214,9 @@ const osInstance =
|
|||||||
if (paddingAbsolute) {
|
if (paddingAbsolute) {
|
||||||
if (comparisonViewport === comparison) {
|
if (comparisonViewport === comparison) {
|
||||||
addClass(document.body, 'pa');
|
addClass(document.body, 'pa');
|
||||||
const absoluteWrapper = createDiv(classNameViewport);
|
const absoluteWrapper = createDiv();
|
||||||
|
absoluteWrapper.setAttribute(dataAttributeViewport, '');
|
||||||
|
|
||||||
appendChildren(absoluteWrapper, contents(comparison));
|
appendChildren(absoluteWrapper, contents(comparison));
|
||||||
|
|
||||||
appendChildren(comparison, absoluteWrapper);
|
appendChildren(comparison, absoluteWrapper);
|
||||||
|
|||||||
+11
-11
@@ -72,7 +72,7 @@ body {
|
|||||||
position: relative;
|
position: relative;
|
||||||
background: rgba(0, 0, 0, 0.1);
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
.os-viewport::after,
|
[data-overlayscrollbars-viewport]::after,
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
@@ -241,7 +241,7 @@ body {
|
|||||||
.boxSizingBorderBox > .container {
|
.boxSizingBorderBox > .container {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.os-viewport * {
|
[data-overlayscrollbars-viewport] * {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ body {
|
|||||||
.boxSizingContentBox > .container {
|
.boxSizingContentBox > .container {
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
|
|
||||||
.os-viewport * {
|
[data-overlayscrollbars-viewport] * {
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,11 +307,11 @@ body {
|
|||||||
|
|
||||||
// disable native scrollbar styling detection
|
// disable native scrollbar styling detection
|
||||||
body.nsh {
|
body.nsh {
|
||||||
.os-viewport-scrollbar-hidden.os-environment {
|
[data-overlayscrollbars-viewport~='scrollbarHidden'].os-environment {
|
||||||
scrollbar-width: auto !important;
|
scrollbar-width: auto !important;
|
||||||
}
|
}
|
||||||
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar,
|
.os-scrollbar-hidden.os-environment::-webkit-scrollbar,
|
||||||
.os-viewport-scrollbar-hidden.os-environment::-webkit-scrollbar-corner {
|
.os-scrollbar-hidden.os-environment::-webkit-scrollbar-corner {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,9 +333,9 @@ body.ccp {
|
|||||||
// fully overlaid
|
// fully overlaid
|
||||||
body.fo {
|
body.fo {
|
||||||
.os-environment::-webkit-scrollbar,
|
.os-environment::-webkit-scrollbar,
|
||||||
.os-viewport::-webkit-scrollbar,
|
[data-overlayscrollbars-viewport]::-webkit-scrollbar,
|
||||||
.os-environment::-webkit-scrollbar-corner,
|
.os-environment::-webkit-scrollbar-corner,
|
||||||
.os-viewport::-webkit-scrollbar-corner {
|
[data-overlayscrollbars-viewport]::-webkit-scrollbar-corner {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
width: 0px !important;
|
width: 0px !important;
|
||||||
height: 0px !important;
|
height: 0px !important;
|
||||||
@@ -344,7 +344,7 @@ body.fo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.os-environment,
|
.os-environment,
|
||||||
.os-viewport {
|
[data-overlayscrollbars-viewport] {
|
||||||
scrollbar-width: none !important;
|
scrollbar-width: none !important;
|
||||||
-ms-overflow-style: none !important;
|
-ms-overflow-style: none !important;
|
||||||
}
|
}
|
||||||
@@ -353,9 +353,9 @@ body.fo {
|
|||||||
// partially overlaid (chrome only)
|
// partially overlaid (chrome only)
|
||||||
body.po {
|
body.po {
|
||||||
.os-environment::-webkit-scrollbar,
|
.os-environment::-webkit-scrollbar,
|
||||||
.os-viewport::-webkit-scrollbar,
|
[data-overlayscrollbars-viewport]::-webkit-scrollbar,
|
||||||
.os-environment::-webkit-scrollbar-corner,
|
.os-environment::-webkit-scrollbar-corner,
|
||||||
.os-viewport::-webkit-scrollbar-corner {
|
[data-overlayscrollbars-viewport]::-webkit-scrollbar-corner {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
width: 10px !important;
|
width: 10px !important;
|
||||||
height: 0 !important;
|
height: 0 !important;
|
||||||
|
|||||||
Reference in New Issue
Block a user