mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-06-21 12:50:36 +03:00
improve code, add env, test nesting
This commit is contained in:
+146
-117
@@ -864,7 +864,7 @@ const createEnvironment = () => {
|
|||||||
const envDOM = createDOM(`<div class="${classNameEnvironment}"><div></div></div>`);
|
const envDOM = createDOM(`<div class="${classNameEnvironment}"><div></div></div>`);
|
||||||
const envElm = envDOM[0];
|
const envElm = envDOM[0];
|
||||||
const envChildElm = envElm.firstChild;
|
const envChildElm = envElm.firstChild;
|
||||||
const onChangedListener = new Set();
|
const [addEvent,, triggerEvent] = createEventListenerHub();
|
||||||
const [updateNativeScrollbarSizeCache, getNativeScrollbarSizeCache] = createCache({
|
const [updateNativeScrollbarSizeCache, getNativeScrollbarSizeCache] = createCache({
|
||||||
_initialValue: getNativeScrollbarSize(body, envElm, envChildElm),
|
_initialValue: getNativeScrollbarSize(body, envElm, envChildElm),
|
||||||
_equal: equalXY
|
_equal: equalXY
|
||||||
@@ -884,12 +884,7 @@ const createEnvironment = () => {
|
|||||||
_cssCustomProperties: style(envElm, 'zIndex') === '-1',
|
_cssCustomProperties: style(envElm, 'zIndex') === '-1',
|
||||||
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
||||||
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
||||||
|
_addListener: listener => addEvent('_', listener),
|
||||||
_addListener(listener) {
|
|
||||||
onChangedListener.add(listener);
|
|
||||||
return () => onChangedListener.delete(listener);
|
|
||||||
},
|
|
||||||
|
|
||||||
_getInitializationStrategy: assignDeep.bind(0, {}, initializationStrategy),
|
_getInitializationStrategy: assignDeep.bind(0, {}, initializationStrategy),
|
||||||
|
|
||||||
_setInitializationStrategy(newInitializationStrategy) {
|
_setInitializationStrategy(newInitializationStrategy) {
|
||||||
@@ -912,40 +907,38 @@ const createEnvironment = () => {
|
|||||||
let size = windowSize();
|
let size = windowSize();
|
||||||
let dpr = getWindowDPR();
|
let dpr = getWindowDPR();
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
if (onChangedListener.size) {
|
const sizeNew = windowSize();
|
||||||
const sizeNew = windowSize();
|
const deltaSize = {
|
||||||
const deltaSize = {
|
w: sizeNew.w - size.w,
|
||||||
w: sizeNew.w - size.w,
|
h: sizeNew.h - size.h
|
||||||
h: sizeNew.h - size.h
|
};
|
||||||
};
|
if (deltaSize.w === 0 && deltaSize.h === 0) return;
|
||||||
if (deltaSize.w === 0 && deltaSize.h === 0) return;
|
const deltaAbsSize = {
|
||||||
const deltaAbsSize = {
|
w: abs(deltaSize.w),
|
||||||
w: abs(deltaSize.w),
|
h: abs(deltaSize.h)
|
||||||
h: abs(deltaSize.h)
|
};
|
||||||
};
|
const deltaAbsRatio = {
|
||||||
const deltaAbsRatio = {
|
w: abs(round(sizeNew.w / (size.w / 100.0))),
|
||||||
w: abs(round(sizeNew.w / (size.w / 100.0))),
|
h: abs(round(sizeNew.h / (size.h / 100.0)))
|
||||||
h: abs(round(sizeNew.h / (size.h / 100.0)))
|
};
|
||||||
};
|
const dprNew = getWindowDPR();
|
||||||
const dprNew = getWindowDPR();
|
const deltaIsBigger = deltaAbsSize.w > 2 && deltaAbsSize.h > 2;
|
||||||
const deltaIsBigger = deltaAbsSize.w > 2 && deltaAbsSize.h > 2;
|
const difference = !diffBiggerThanOne(deltaAbsRatio.w, deltaAbsRatio.h);
|
||||||
const difference = !diffBiggerThanOne(deltaAbsRatio.w, deltaAbsRatio.h);
|
const dprChanged = dprNew !== dpr && dpr > 0;
|
||||||
const dprChanged = dprNew !== dpr && dpr > 0;
|
const isZoom = deltaIsBigger && difference && dprChanged;
|
||||||
const isZoom = deltaIsBigger && difference && dprChanged;
|
|
||||||
|
|
||||||
if (isZoom) {
|
if (isZoom) {
|
||||||
const [scrollbarSize, scrollbarSizeChanged] = updateNativeScrollbarSizeCache(getNativeScrollbarSize(body, envElm, envChildElm));
|
const [scrollbarSize, scrollbarSizeChanged] = updateNativeScrollbarSizeCache(getNativeScrollbarSize(body, envElm, envChildElm));
|
||||||
assignDeep(environmentInstance._nativeScrollbarSize, scrollbarSize);
|
assignDeep(environmentInstance._nativeScrollbarSize, scrollbarSize);
|
||||||
removeElements(envElm);
|
removeElements(envElm);
|
||||||
|
|
||||||
if (scrollbarSizeChanged) {
|
if (scrollbarSizeChanged) {
|
||||||
runEach(onChangedListener);
|
triggerEvent('_');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size = sizeNew;
|
|
||||||
dpr = dprNew;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = sizeNew;
|
||||||
|
dpr = dprNew;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,14 +1108,18 @@ const createTrinsicUpdate = (structureSetupElements, state) => {
|
|||||||
} = structureSetupElements;
|
} = structureSetupElements;
|
||||||
const [getState] = state;
|
const [getState] = state;
|
||||||
return updateHints => {
|
return updateHints => {
|
||||||
|
const {
|
||||||
|
_flexboxGlue
|
||||||
|
} = getEnvironment();
|
||||||
const {
|
const {
|
||||||
_heightIntrinsic
|
_heightIntrinsic
|
||||||
} = getState();
|
} = getState();
|
||||||
const {
|
const {
|
||||||
_heightIntrinsicChanged
|
_heightIntrinsicChanged
|
||||||
} = updateHints;
|
} = updateHints;
|
||||||
|
const heightIntrinsicChanged = (_content || !_flexboxGlue) && _heightIntrinsicChanged;
|
||||||
|
|
||||||
if (_heightIntrinsicChanged) {
|
if (heightIntrinsicChanged) {
|
||||||
style(_content, {
|
style(_content, {
|
||||||
height: _heightIntrinsic ? '' : '100%',
|
height: _heightIntrinsic ? '' : '100%',
|
||||||
display: _heightIntrinsic ? '' : 'inline'
|
display: _heightIntrinsic ? '' : 'inline'
|
||||||
@@ -1130,8 +1127,8 @@ const createTrinsicUpdate = (structureSetupElements, state) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_sizeChanged: _heightIntrinsicChanged,
|
_sizeChanged: heightIntrinsicChanged,
|
||||||
_contentMutation: _heightIntrinsicChanged
|
_contentMutation: heightIntrinsicChanged
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1208,6 +1205,7 @@ const {
|
|||||||
max
|
max
|
||||||
} = Math;
|
} = Math;
|
||||||
const strVisible = 'visible';
|
const strVisible = 'visible';
|
||||||
|
const strHidden = 'hidden';
|
||||||
const overlaidScrollbarsHideOffset = 42;
|
const overlaidScrollbarsHideOffset = 42;
|
||||||
const whCacheOptions = {
|
const whCacheOptions = {
|
||||||
_equal: equalWH,
|
_equal: equalWH,
|
||||||
@@ -1219,8 +1217,8 @@ const whCacheOptions = {
|
|||||||
const xyCacheOptions = {
|
const xyCacheOptions = {
|
||||||
_equal: equalXY,
|
_equal: equalXY,
|
||||||
_initialValue: {
|
_initialValue: {
|
||||||
x: false,
|
x: strHidden,
|
||||||
y: false
|
y: strHidden
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1258,7 +1256,7 @@ const createOverflowUpdate = (structureSetupElements, state) => {
|
|||||||
const [updateSizeFraction, getCurrentSizeFraction] = createCache(whCacheOptions, fractionalSize.bind(0, _host));
|
const [updateSizeFraction, getCurrentSizeFraction] = createCache(whCacheOptions, fractionalSize.bind(0, _host));
|
||||||
const [updateViewportScrollSizeCache, getCurrentViewportScrollSizeCache] = createCache(whCacheOptions, scrollSize.bind(0, _viewport));
|
const [updateViewportScrollSizeCache, getCurrentViewportScrollSizeCache] = createCache(whCacheOptions, scrollSize.bind(0, _viewport));
|
||||||
const [updateOverflowAmountCache, getCurrentOverflowAmountCache] = createCache(whCacheOptions);
|
const [updateOverflowAmountCache, getCurrentOverflowAmountCache] = createCache(whCacheOptions);
|
||||||
const [updateOverflowScrollCache] = createCache(xyCacheOptions);
|
const [updateOverflowStyleCache] = createCache(xyCacheOptions);
|
||||||
|
|
||||||
const fixFlexboxGlue = (viewportOverflowState, heightIntrinsic) => {
|
const fixFlexboxGlue = (viewportOverflowState, heightIntrinsic) => {
|
||||||
style(_viewport, {
|
style(_viewport, {
|
||||||
@@ -1286,39 +1284,45 @@ const createOverflowUpdate = (structureSetupElements, state) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getViewportOverflowState = (showNativeOverlaidScrollbars, viewportStyleObj) => {
|
const getViewportOverflowState = (showNativeOverlaidScrollbars, viewportStyleObj) => {
|
||||||
const {
|
|
||||||
x: overlaidX,
|
|
||||||
y: overlaidY
|
|
||||||
} = _nativeScrollbarIsOverlaid;
|
|
||||||
const determineOverflow = !viewportStyleObj;
|
|
||||||
const arrangeHideOffset = !_nativeScrollbarStyling && !showNativeOverlaidScrollbars ? overlaidScrollbarsHideOffset : 0;
|
const arrangeHideOffset = !_nativeScrollbarStyling && !showNativeOverlaidScrollbars ? overlaidScrollbarsHideOffset : 0;
|
||||||
const styleObj = determineOverflow ? style(_viewport, ['overflowX', 'overflowY']) : viewportStyleObj;
|
|
||||||
const scroll = {
|
const getStatePerAxis = (styleKey, isOverlaid, nativeScrollbarSize) => {
|
||||||
x: styleObj.overflowX === 'scroll',
|
const overflowStyle = style(_viewport, styleKey);
|
||||||
y: styleObj.overflowY === 'scroll'
|
const objectPrefferedOverflowStyle = viewportStyleObj ? viewportStyleObj[styleKey] : overflowStyle;
|
||||||
};
|
const overflowScroll = objectPrefferedOverflowStyle === 'scroll';
|
||||||
const nonScrollbarStylingHideOffset = {
|
const nonScrollbarStylingHideOffset = isOverlaid ? arrangeHideOffset : nativeScrollbarSize;
|
||||||
x: overlaidX ? arrangeHideOffset : _nativeScrollbarSize.x,
|
const scrollbarsHideOffset = overflowScroll && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset : 0;
|
||||||
y: overlaidY ? arrangeHideOffset : _nativeScrollbarSize.y
|
const scrollbarsHideOffsetArrange = isOverlaid && !!arrangeHideOffset;
|
||||||
};
|
return [overflowStyle, overflowScroll, scrollbarsHideOffset, scrollbarsHideOffsetArrange];
|
||||||
const scrollbarsHideOffset = {
|
|
||||||
x: scroll.x && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset.x : 0,
|
|
||||||
y: scroll.y && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset.y : 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [xOverflowStyle, xOverflowScroll, xScrollbarsHideOffset, xScrollbarsHideOffsetArrange] = getStatePerAxis('overflowX', _nativeScrollbarIsOverlaid.x, _nativeScrollbarSize.x);
|
||||||
|
const [yOverflowStyle, yOverflowScroll, yScrollbarsHideOffset, yScrollbarsHideOffsetArrange] = getStatePerAxis('overflowY', _nativeScrollbarIsOverlaid.y, _nativeScrollbarSize.y);
|
||||||
return {
|
return {
|
||||||
_overflowScroll: scroll,
|
_overflowStyle: {
|
||||||
_scrollbarsHideOffsetArrange: {
|
x: xOverflowStyle,
|
||||||
x: overlaidX && !!arrangeHideOffset,
|
y: yOverflowStyle
|
||||||
y: overlaidY && !!arrangeHideOffset
|
|
||||||
},
|
},
|
||||||
_scrollbarsHideOffset: scrollbarsHideOffset
|
_overflowScroll: {
|
||||||
|
x: xOverflowScroll,
|
||||||
|
y: yOverflowScroll
|
||||||
|
},
|
||||||
|
_scrollbarsHideOffset: {
|
||||||
|
x: xScrollbarsHideOffset,
|
||||||
|
y: yScrollbarsHideOffset
|
||||||
|
},
|
||||||
|
_scrollbarsHideOffsetArrange: {
|
||||||
|
x: xScrollbarsHideOffsetArrange,
|
||||||
|
y: yScrollbarsHideOffsetArrange
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const setViewportOverflowState = (showNativeOverlaidScrollbars, hasOverflow, overflowOption, viewportStyleObj) => {
|
const setViewportOverflowState = (showNativeOverlaidScrollbars, hasOverflow, overflowOption, viewportStyleObj) => {
|
||||||
const setAxisOverflowStyle = (behavior, hasOverflowAxis) => {
|
const setAxisOverflowStyle = (behavior, hasOverflowAxis) => {
|
||||||
const overflowVisible = overflowIsVisible(behavior);
|
const overflowVisible = overflowIsVisible(behavior);
|
||||||
return [hasOverflowAxis && !overflowVisible ? behavior : '', hasOverflowAxis && overflowVisible && behavior.replace(`${strVisible}-`, '') || ''];
|
const overflowVisibleBehavior = hasOverflowAxis && overflowVisible && behavior.replace(`${strVisible}-`, '') || '';
|
||||||
|
return [hasOverflowAxis && !overflowVisible ? behavior : '', overflowIsVisible(overflowVisibleBehavior) ? 'hidden' : overflowVisibleBehavior];
|
||||||
};
|
};
|
||||||
|
|
||||||
const [overflowX, visibleBehaviorX] = setAxisOverflowStyle(overflowOption.x, hasOverflow.x);
|
const [overflowX, visibleBehaviorX] = setAxisOverflowStyle(overflowOption.x, hasOverflow.x);
|
||||||
@@ -1486,7 +1490,6 @@ const createOverflowUpdate = (structureSetupElements, state) => {
|
|||||||
let sizeFractionCache = getCurrentSizeFraction(force);
|
let sizeFractionCache = getCurrentSizeFraction(force);
|
||||||
let viewportScrollSizeCache = getCurrentViewportScrollSizeCache(force);
|
let viewportScrollSizeCache = getCurrentViewportScrollSizeCache(force);
|
||||||
let overflowAmuntCache = getCurrentOverflowAmountCache(force);
|
let overflowAmuntCache = getCurrentOverflowAmountCache(force);
|
||||||
let updateHintsReturn;
|
|
||||||
let preMeasureViewportOverflowState;
|
let preMeasureViewportOverflowState;
|
||||||
|
|
||||||
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarStyling) {
|
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarStyling) {
|
||||||
@@ -1498,11 +1501,11 @@ const createOverflowUpdate = (structureSetupElements, state) => {
|
|||||||
fixFlexboxGlue(preMeasureViewportOverflowState, _heightIntrinsic);
|
fixFlexboxGlue(preMeasureViewportOverflowState, _heightIntrinsic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overflowVisible) {
|
|
||||||
removeClass(_viewport, classNameOverflowVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_sizeChanged || _paddingStyleChanged || _contentMutation || _directionChanged || showNativeOverlaidScrollbarsChanged) {
|
if (_sizeChanged || _paddingStyleChanged || _contentMutation || _directionChanged || showNativeOverlaidScrollbarsChanged) {
|
||||||
|
if (overflowVisible) {
|
||||||
|
removeClass(_viewport, classNameOverflowVisible);
|
||||||
|
}
|
||||||
|
|
||||||
const [redoViewportArrange, undoViewportArrangeOverflowState] = undoViewportArrange(showNativeOverlaidScrollbars, _directionIsRTL, preMeasureViewportOverflowState);
|
const [redoViewportArrange, undoViewportArrangeOverflowState] = undoViewportArrange(showNativeOverlaidScrollbars, _directionIsRTL, preMeasureViewportOverflowState);
|
||||||
const [_sizeFraction, _sizeFractionChanged] = sizeFractionCache = updateSizeFraction(force);
|
const [_sizeFraction, _sizeFractionChanged] = sizeFractionCache = updateSizeFraction(force);
|
||||||
const [_viewportScrollSize, _viewportScrollSizeChanged] = viewportScrollSizeCache = updateViewportScrollSizeCache(force);
|
const [_viewportScrollSize, _viewportScrollSizeChanged] = viewportScrollSizeCache = updateViewportScrollSizeCache(force);
|
||||||
@@ -1545,7 +1548,6 @@ const createOverflowUpdate = (structureSetupElements, state) => {
|
|||||||
};
|
};
|
||||||
const viewportOverflowState = setViewportOverflowState(showNativeOverlaidScrollbars, hasOverflow, overflow, viewportStyle);
|
const viewportOverflowState = setViewportOverflowState(showNativeOverlaidScrollbars, hasOverflow, overflow, viewportStyle);
|
||||||
const viewportArranged = arrangeViewport(viewportOverflowState, viewportScrollSize, sizeFraction, _directionIsRTL);
|
const viewportArranged = arrangeViewport(viewportOverflowState, viewportScrollSize, sizeFraction, _directionIsRTL);
|
||||||
const [overflowScroll, overflowScrollChanged] = updateOverflowScrollCache(viewportOverflowState._overflowScroll);
|
|
||||||
hideNativeScrollbars(viewportOverflowState, _directionIsRTL, viewportArranged, viewportStyle);
|
hideNativeScrollbars(viewportOverflowState, _directionIsRTL, viewportArranged, viewportStyle);
|
||||||
|
|
||||||
if (adjustFlexboxGlue) {
|
if (adjustFlexboxGlue) {
|
||||||
@@ -1553,21 +1555,24 @@ const createOverflowUpdate = (structureSetupElements, state) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
style(_viewport, viewportStyle);
|
style(_viewport, viewportStyle);
|
||||||
setState({
|
|
||||||
_overflowScroll: overflowScroll,
|
|
||||||
_overflowAmount: overflowAmount,
|
|
||||||
_hasOverflow: hasOverflow
|
|
||||||
});
|
|
||||||
updateHintsReturn = {
|
|
||||||
_overflowAmountChanged: overflowAmountChanged,
|
|
||||||
_overflowScrollChanged: overflowScrollChanged
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attr(_host, dataAttributeHost, removeClipping ? 'overflowVisible' : '');
|
attr(_host, dataAttributeHost, removeClipping ? 'overflowVisible' : '');
|
||||||
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
||||||
conditionalClass(_viewport, classNameOverflowVisible, overflowVisible);
|
conditionalClass(_viewport, classNameOverflowVisible, overflowVisible);
|
||||||
return updateHintsReturn;
|
const [overflowStyle, overflowStyleChanged] = updateOverflowStyleCache(getViewportOverflowState(showNativeOverlaidScrollbars)._overflowStyle);
|
||||||
|
setState({
|
||||||
|
_overflowStyle: overflowStyle,
|
||||||
|
_overflowAmount: {
|
||||||
|
x: overflowAmount.w,
|
||||||
|
y: overflowAmount.h
|
||||||
|
},
|
||||||
|
_hasOverflow: hasOverflow
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
_overflowStyleChanged: overflowStyleChanged,
|
||||||
|
_overflowAmountChanged: overflowAmountChanged
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1600,8 +1605,8 @@ const createStructureSetupUpdate = (structureSetupElements, state) => {
|
|||||||
_paddingStyleChanged: false,
|
_paddingStyleChanged: false,
|
||||||
_directionChanged: false,
|
_directionChanged: false,
|
||||||
_heightIntrinsicChanged: false,
|
_heightIntrinsicChanged: false,
|
||||||
_overflowScrollChanged: false,
|
|
||||||
_overflowAmountChanged: false,
|
_overflowAmountChanged: false,
|
||||||
|
_overflowStyleChanged: false,
|
||||||
_hostMutation: false,
|
_hostMutation: false,
|
||||||
_contentMutation: false
|
_contentMutation: false
|
||||||
}, updateHints), {}, force);
|
}, updateHints), {}, force);
|
||||||
@@ -2178,12 +2183,12 @@ const initialStructureSetupUpdateState = {
|
|||||||
paddingLeft: 0
|
paddingLeft: 0
|
||||||
},
|
},
|
||||||
_overflowAmount: {
|
_overflowAmount: {
|
||||||
w: 0,
|
x: 0,
|
||||||
h: 0
|
y: 0
|
||||||
},
|
},
|
||||||
_overflowScroll: {
|
_overflowStyle: {
|
||||||
x: false,
|
x: 'hidden',
|
||||||
y: false
|
y: 'hidden'
|
||||||
},
|
},
|
||||||
_hasOverflow: {
|
_hasOverflow: {
|
||||||
x: false,
|
x: false,
|
||||||
@@ -2384,15 +2389,6 @@ const getInstance = target => targetInstanceMap.get(target);
|
|||||||
|
|
||||||
const createOSEventListenerHub = initialEventListeners => createEventListenerHub(initialEventListeners);
|
const createOSEventListenerHub = initialEventListeners => createEventListenerHub(initialEventListeners);
|
||||||
|
|
||||||
const createOverflowChangedArgs = (overflowAmount, hasOverflow, overflowScroll) => ({
|
|
||||||
amount: {
|
|
||||||
x: overflowAmount.w,
|
|
||||||
y: overflowAmount.h
|
|
||||||
},
|
|
||||||
overflow: hasOverflow,
|
|
||||||
scrollableOverflow: assignDeep({}, overflowScroll)
|
|
||||||
});
|
|
||||||
|
|
||||||
const OverlayScrollbars = (target, options, eventListeners) => {
|
const OverlayScrollbars = (target, options, eventListeners) => {
|
||||||
const {
|
const {
|
||||||
_getDefaultOptions,
|
_getDefaultOptions,
|
||||||
@@ -2430,35 +2426,25 @@ const OverlayScrollbars = (target, options, eventListeners) => {
|
|||||||
updateScrollbars(changedOptions, force);
|
updateScrollbars(changedOptions, force);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
||||||
|
|
||||||
structureState._addOnUpdatedListener((updateHints, changedOptions, force) => {
|
structureState._addOnUpdatedListener((updateHints, changedOptions, force) => {
|
||||||
const {
|
const {
|
||||||
_sizeChanged,
|
_sizeChanged,
|
||||||
_directionChanged,
|
_directionChanged,
|
||||||
_heightIntrinsicChanged,
|
_heightIntrinsicChanged,
|
||||||
_overflowAmountChanged,
|
_overflowAmountChanged,
|
||||||
_overflowScrollChanged,
|
_overflowStyleChanged,
|
||||||
_contentMutation,
|
_contentMutation,
|
||||||
_hostMutation
|
_hostMutation
|
||||||
} = updateHints;
|
} = updateHints;
|
||||||
const {
|
|
||||||
_overflowAmount,
|
|
||||||
_overflowScroll,
|
|
||||||
_hasOverflow
|
|
||||||
} = structureState();
|
|
||||||
|
|
||||||
if (_overflowAmountChanged || _overflowScrollChanged) {
|
|
||||||
triggerEvent('overflowChanged', assignDeep({}, createOverflowChangedArgs(_overflowAmount, _hasOverflow, _overflowScroll), {
|
|
||||||
previous: createOverflowChangedArgs(_overflowAmount, _hasOverflow, _overflowScroll)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerEvent('updated', {
|
triggerEvent('updated', {
|
||||||
updateHints: {
|
updateHints: {
|
||||||
sizeChanged: _sizeChanged,
|
sizeChanged: _sizeChanged,
|
||||||
directionChanged: _directionChanged,
|
directionChanged: _directionChanged,
|
||||||
heightIntrinsicChanged: _heightIntrinsicChanged,
|
heightIntrinsicChanged: _heightIntrinsicChanged,
|
||||||
overflowAmountChanged: _overflowAmountChanged,
|
overflowAmountChanged: _overflowAmountChanged,
|
||||||
overflowScrollChanged: _overflowScrollChanged,
|
overflowStyleChanged: _overflowStyleChanged,
|
||||||
contentMutation: _contentMutation,
|
contentMutation: _contentMutation,
|
||||||
hostMutation: _hostMutation
|
hostMutation: _hostMutation
|
||||||
},
|
},
|
||||||
@@ -2467,7 +2453,6 @@ const OverlayScrollbars = (target, options, eventListeners) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
|
||||||
const instance = {
|
const instance = {
|
||||||
options(newOptions) {
|
options(newOptions) {
|
||||||
if (newOptions) {
|
if (newOptions) {
|
||||||
@@ -2479,14 +2464,27 @@ const OverlayScrollbars = (target, options, eventListeners) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentOptions;
|
return assignDeep({}, currentOptions);
|
||||||
},
|
},
|
||||||
|
|
||||||
on: addEvent,
|
on: addEvent,
|
||||||
off: removeEvent,
|
off: removeEvent,
|
||||||
state: () => ({
|
state: () => {
|
||||||
_overflowAmount: structureState()._overflowAmount
|
const {
|
||||||
}),
|
_overflowAmount,
|
||||||
|
_overflowStyle,
|
||||||
|
_hasOverflow,
|
||||||
|
_padding,
|
||||||
|
_paddingAbsolute
|
||||||
|
} = structureState();
|
||||||
|
return assignDeep({}, {
|
||||||
|
overflowAmount: _overflowAmount,
|
||||||
|
overflowStyle: _overflowStyle,
|
||||||
|
hasOverflow: _hasOverflow,
|
||||||
|
padding: _padding,
|
||||||
|
paddingAbsolute: _paddingAbsolute
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
update(force) {
|
update(force) {
|
||||||
update({}, force);
|
update({}, force);
|
||||||
@@ -2513,7 +2511,38 @@ const OverlayScrollbars = (target, options, eventListeners) => {
|
|||||||
triggerEvent('initialized');
|
triggerEvent('initialized');
|
||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
OverlayScrollbars.extend = addPlugin;
|
OverlayScrollbars.plugin = addPlugin;
|
||||||
|
|
||||||
|
OverlayScrollbars.env = () => {
|
||||||
|
const {
|
||||||
|
_nativeScrollbarSize,
|
||||||
|
_nativeScrollbarIsOverlaid,
|
||||||
|
_nativeScrollbarStyling,
|
||||||
|
_rtlScrollBehavior,
|
||||||
|
_flexboxGlue,
|
||||||
|
_cssCustomProperties,
|
||||||
|
_defaultInitializationStrategy,
|
||||||
|
_defaultDefaultOptions,
|
||||||
|
_getInitializationStrategy,
|
||||||
|
_setInitializationStrategy,
|
||||||
|
_getDefaultOptions,
|
||||||
|
_setDefaultOptions
|
||||||
|
} = getEnvironment();
|
||||||
|
return assignDeep({}, {
|
||||||
|
scrollbarSize: _nativeScrollbarSize,
|
||||||
|
scrollbarIsOverlaid: _nativeScrollbarIsOverlaid,
|
||||||
|
scrollbarStyling: _nativeScrollbarStyling,
|
||||||
|
rtlScrollBehavior: _rtlScrollBehavior,
|
||||||
|
flexboxGlue: _flexboxGlue,
|
||||||
|
cssCustomProperties: _cssCustomProperties,
|
||||||
|
defaultInitializationStrategy: _defaultInitializationStrategy,
|
||||||
|
defaultDefaultOptions: _defaultDefaultOptions,
|
||||||
|
getInitializationStrategy: _getInitializationStrategy,
|
||||||
|
setInitializationStrategy: _setInitializationStrategy,
|
||||||
|
getDefaultOptions: _getDefaultOptions,
|
||||||
|
setDefaultOptions: _setDefaultOptions
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export { OverlayScrollbars as default };
|
export { OverlayScrollbars as default };
|
||||||
//# sourceMappingURL=overlayscrollbars.esm.js.map
|
//# sourceMappingURL=overlayscrollbars.esm.js.map
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+163
-121
@@ -951,7 +951,10 @@
|
|||||||
var envDOM = createDOM("<div class=\"" + classNameEnvironment + "\"><div></div></div>");
|
var envDOM = createDOM("<div class=\"" + classNameEnvironment + "\"><div></div></div>");
|
||||||
var envElm = envDOM[0];
|
var envElm = envDOM[0];
|
||||||
var envChildElm = envElm.firstChild;
|
var envChildElm = envElm.firstChild;
|
||||||
var onChangedListener = new Set();
|
|
||||||
|
var _createEventListenerH = createEventListenerHub(),
|
||||||
|
addEvent = _createEventListenerH[0],
|
||||||
|
triggerEvent = _createEventListenerH[2];
|
||||||
|
|
||||||
var _createCache = createCache({
|
var _createCache = createCache({
|
||||||
_initialValue: getNativeScrollbarSize(body, envElm, envChildElm),
|
_initialValue: getNativeScrollbarSize(body, envElm, envChildElm),
|
||||||
@@ -978,10 +981,7 @@
|
|||||||
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
||||||
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
||||||
_addListener: function _addListener(listener) {
|
_addListener: function _addListener(listener) {
|
||||||
onChangedListener.add(listener);
|
return addEvent('_', listener);
|
||||||
return function () {
|
|
||||||
return onChangedListener.delete(listener);
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
_getInitializationStrategy: assignDeep.bind(0, {}, initializationStrategy),
|
_getInitializationStrategy: assignDeep.bind(0, {}, initializationStrategy),
|
||||||
_setInitializationStrategy: function _setInitializationStrategy(newInitializationStrategy) {
|
_setInitializationStrategy: function _setInitializationStrategy(newInitializationStrategy) {
|
||||||
@@ -1001,43 +1001,41 @@
|
|||||||
var size = windowSize();
|
var size = windowSize();
|
||||||
var dpr = getWindowDPR();
|
var dpr = getWindowDPR();
|
||||||
window.addEventListener('resize', function () {
|
window.addEventListener('resize', function () {
|
||||||
if (onChangedListener.size) {
|
var sizeNew = windowSize();
|
||||||
var sizeNew = windowSize();
|
var deltaSize = {
|
||||||
var deltaSize = {
|
w: sizeNew.w - size.w,
|
||||||
w: sizeNew.w - size.w,
|
h: sizeNew.h - size.h
|
||||||
h: sizeNew.h - size.h
|
};
|
||||||
};
|
if (deltaSize.w === 0 && deltaSize.h === 0) return;
|
||||||
if (deltaSize.w === 0 && deltaSize.h === 0) return;
|
var deltaAbsSize = {
|
||||||
var deltaAbsSize = {
|
w: abs(deltaSize.w),
|
||||||
w: abs(deltaSize.w),
|
h: abs(deltaSize.h)
|
||||||
h: abs(deltaSize.h)
|
};
|
||||||
};
|
var deltaAbsRatio = {
|
||||||
var deltaAbsRatio = {
|
w: abs(round(sizeNew.w / (size.w / 100.0))),
|
||||||
w: abs(round(sizeNew.w / (size.w / 100.0))),
|
h: abs(round(sizeNew.h / (size.h / 100.0)))
|
||||||
h: abs(round(sizeNew.h / (size.h / 100.0)))
|
};
|
||||||
};
|
var dprNew = getWindowDPR();
|
||||||
var dprNew = getWindowDPR();
|
var deltaIsBigger = deltaAbsSize.w > 2 && deltaAbsSize.h > 2;
|
||||||
var deltaIsBigger = deltaAbsSize.w > 2 && deltaAbsSize.h > 2;
|
var difference = !diffBiggerThanOne(deltaAbsRatio.w, deltaAbsRatio.h);
|
||||||
var difference = !diffBiggerThanOne(deltaAbsRatio.w, deltaAbsRatio.h);
|
var dprChanged = dprNew !== dpr && dpr > 0;
|
||||||
var dprChanged = dprNew !== dpr && dpr > 0;
|
var isZoom = deltaIsBigger && difference && dprChanged;
|
||||||
var isZoom = deltaIsBigger && difference && dprChanged;
|
|
||||||
|
|
||||||
if (isZoom) {
|
if (isZoom) {
|
||||||
var _updateNativeScrollba = updateNativeScrollbarSizeCache(getNativeScrollbarSize(body, envElm, envChildElm)),
|
var _updateNativeScrollba = updateNativeScrollbarSizeCache(getNativeScrollbarSize(body, envElm, envChildElm)),
|
||||||
scrollbarSize = _updateNativeScrollba[0],
|
scrollbarSize = _updateNativeScrollba[0],
|
||||||
scrollbarSizeChanged = _updateNativeScrollba[1];
|
scrollbarSizeChanged = _updateNativeScrollba[1];
|
||||||
|
|
||||||
assignDeep(environmentInstance._nativeScrollbarSize, scrollbarSize);
|
assignDeep(environmentInstance._nativeScrollbarSize, scrollbarSize);
|
||||||
removeElements(envElm);
|
removeElements(envElm);
|
||||||
|
|
||||||
if (scrollbarSizeChanged) {
|
if (scrollbarSizeChanged) {
|
||||||
runEach(onChangedListener);
|
triggerEvent('_');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size = sizeNew;
|
|
||||||
dpr = dprNew;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = sizeNew;
|
||||||
|
dpr = dprNew;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1205,12 +1203,16 @@
|
|||||||
var _content = structureSetupElements._content;
|
var _content = structureSetupElements._content;
|
||||||
var getState = state[0];
|
var getState = state[0];
|
||||||
return function (updateHints) {
|
return function (updateHints) {
|
||||||
|
var _getEnvironment = getEnvironment(),
|
||||||
|
_flexboxGlue = _getEnvironment._flexboxGlue;
|
||||||
|
|
||||||
var _getState = getState(),
|
var _getState = getState(),
|
||||||
_heightIntrinsic = _getState._heightIntrinsic;
|
_heightIntrinsic = _getState._heightIntrinsic;
|
||||||
|
|
||||||
var _heightIntrinsicChanged = updateHints._heightIntrinsicChanged;
|
var _heightIntrinsicChanged = updateHints._heightIntrinsicChanged;
|
||||||
|
var heightIntrinsicChanged = (_content || !_flexboxGlue) && _heightIntrinsicChanged;
|
||||||
|
|
||||||
if (_heightIntrinsicChanged) {
|
if (heightIntrinsicChanged) {
|
||||||
style(_content, {
|
style(_content, {
|
||||||
height: _heightIntrinsic ? '' : '100%',
|
height: _heightIntrinsic ? '' : '100%',
|
||||||
display: _heightIntrinsic ? '' : 'inline'
|
display: _heightIntrinsic ? '' : 'inline'
|
||||||
@@ -1218,8 +1220,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_sizeChanged: _heightIntrinsicChanged,
|
_sizeChanged: heightIntrinsicChanged,
|
||||||
_contentMutation: _heightIntrinsicChanged
|
_contentMutation: heightIntrinsicChanged
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1305,6 +1307,7 @@
|
|||||||
|
|
||||||
var max = Math.max;
|
var max = Math.max;
|
||||||
var strVisible = 'visible';
|
var strVisible = 'visible';
|
||||||
|
var strHidden = 'hidden';
|
||||||
var overlaidScrollbarsHideOffset = 42;
|
var overlaidScrollbarsHideOffset = 42;
|
||||||
var whCacheOptions = {
|
var whCacheOptions = {
|
||||||
_equal: equalWH,
|
_equal: equalWH,
|
||||||
@@ -1316,8 +1319,8 @@
|
|||||||
var xyCacheOptions = {
|
var xyCacheOptions = {
|
||||||
_equal: equalXY,
|
_equal: equalXY,
|
||||||
_initialValue: {
|
_initialValue: {
|
||||||
x: false,
|
x: strHidden,
|
||||||
y: false
|
y: strHidden
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1370,7 +1373,7 @@
|
|||||||
getCurrentOverflowAmountCache = _createCache3[1];
|
getCurrentOverflowAmountCache = _createCache3[1];
|
||||||
|
|
||||||
var _createCache4 = createCache(xyCacheOptions),
|
var _createCache4 = createCache(xyCacheOptions),
|
||||||
updateOverflowScrollCache = _createCache4[0];
|
updateOverflowStyleCache = _createCache4[0];
|
||||||
|
|
||||||
var fixFlexboxGlue = function fixFlexboxGlue(viewportOverflowState, heightIntrinsic) {
|
var fixFlexboxGlue = function fixFlexboxGlue(viewportOverflowState, heightIntrinsic) {
|
||||||
style(_viewport, {
|
style(_viewport, {
|
||||||
@@ -1396,37 +1399,55 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var getViewportOverflowState = function getViewportOverflowState(showNativeOverlaidScrollbars, viewportStyleObj) {
|
var getViewportOverflowState = function getViewportOverflowState(showNativeOverlaidScrollbars, viewportStyleObj) {
|
||||||
var overlaidX = _nativeScrollbarIsOverlaid.x,
|
|
||||||
overlaidY = _nativeScrollbarIsOverlaid.y;
|
|
||||||
var determineOverflow = !viewportStyleObj;
|
|
||||||
var arrangeHideOffset = !_nativeScrollbarStyling && !showNativeOverlaidScrollbars ? overlaidScrollbarsHideOffset : 0;
|
var arrangeHideOffset = !_nativeScrollbarStyling && !showNativeOverlaidScrollbars ? overlaidScrollbarsHideOffset : 0;
|
||||||
var styleObj = determineOverflow ? style(_viewport, ['overflowX', 'overflowY']) : viewportStyleObj;
|
|
||||||
var scroll = {
|
var getStatePerAxis = function getStatePerAxis(styleKey, isOverlaid, nativeScrollbarSize) {
|
||||||
x: styleObj.overflowX === 'scroll',
|
var overflowStyle = style(_viewport, styleKey);
|
||||||
y: styleObj.overflowY === 'scroll'
|
var objectPrefferedOverflowStyle = viewportStyleObj ? viewportStyleObj[styleKey] : overflowStyle;
|
||||||
};
|
var overflowScroll = objectPrefferedOverflowStyle === 'scroll';
|
||||||
var nonScrollbarStylingHideOffset = {
|
var nonScrollbarStylingHideOffset = isOverlaid ? arrangeHideOffset : nativeScrollbarSize;
|
||||||
x: overlaidX ? arrangeHideOffset : _nativeScrollbarSize.x,
|
var scrollbarsHideOffset = overflowScroll && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset : 0;
|
||||||
y: overlaidY ? arrangeHideOffset : _nativeScrollbarSize.y
|
var scrollbarsHideOffsetArrange = isOverlaid && !!arrangeHideOffset;
|
||||||
};
|
return [overflowStyle, overflowScroll, scrollbarsHideOffset, scrollbarsHideOffsetArrange];
|
||||||
var scrollbarsHideOffset = {
|
|
||||||
x: scroll.x && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset.x : 0,
|
|
||||||
y: scroll.y && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset.y : 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var _getStatePerAxis = getStatePerAxis('overflowX', _nativeScrollbarIsOverlaid.x, _nativeScrollbarSize.x),
|
||||||
|
xOverflowStyle = _getStatePerAxis[0],
|
||||||
|
xOverflowScroll = _getStatePerAxis[1],
|
||||||
|
xScrollbarsHideOffset = _getStatePerAxis[2],
|
||||||
|
xScrollbarsHideOffsetArrange = _getStatePerAxis[3];
|
||||||
|
|
||||||
|
var _getStatePerAxis2 = getStatePerAxis('overflowY', _nativeScrollbarIsOverlaid.y, _nativeScrollbarSize.y),
|
||||||
|
yOverflowStyle = _getStatePerAxis2[0],
|
||||||
|
yOverflowScroll = _getStatePerAxis2[1],
|
||||||
|
yScrollbarsHideOffset = _getStatePerAxis2[2],
|
||||||
|
yScrollbarsHideOffsetArrange = _getStatePerAxis2[3];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_overflowScroll: scroll,
|
_overflowStyle: {
|
||||||
_scrollbarsHideOffsetArrange: {
|
x: xOverflowStyle,
|
||||||
x: overlaidX && !!arrangeHideOffset,
|
y: yOverflowStyle
|
||||||
y: overlaidY && !!arrangeHideOffset
|
|
||||||
},
|
},
|
||||||
_scrollbarsHideOffset: scrollbarsHideOffset
|
_overflowScroll: {
|
||||||
|
x: xOverflowScroll,
|
||||||
|
y: yOverflowScroll
|
||||||
|
},
|
||||||
|
_scrollbarsHideOffset: {
|
||||||
|
x: xScrollbarsHideOffset,
|
||||||
|
y: yScrollbarsHideOffset
|
||||||
|
},
|
||||||
|
_scrollbarsHideOffsetArrange: {
|
||||||
|
x: xScrollbarsHideOffsetArrange,
|
||||||
|
y: yScrollbarsHideOffsetArrange
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var setViewportOverflowState = function setViewportOverflowState(showNativeOverlaidScrollbars, hasOverflow, overflowOption, viewportStyleObj) {
|
var setViewportOverflowState = function setViewportOverflowState(showNativeOverlaidScrollbars, hasOverflow, overflowOption, viewportStyleObj) {
|
||||||
var setAxisOverflowStyle = function setAxisOverflowStyle(behavior, hasOverflowAxis) {
|
var setAxisOverflowStyle = function setAxisOverflowStyle(behavior, hasOverflowAxis) {
|
||||||
var overflowVisible = overflowIsVisible(behavior);
|
var overflowVisible = overflowIsVisible(behavior);
|
||||||
return [hasOverflowAxis && !overflowVisible ? behavior : '', hasOverflowAxis && overflowVisible && behavior.replace(strVisible + "-", '') || ''];
|
var overflowVisibleBehavior = hasOverflowAxis && overflowVisible && behavior.replace(strVisible + "-", '') || '';
|
||||||
|
return [hasOverflowAxis && !overflowVisible ? behavior : '', overflowIsVisible(overflowVisibleBehavior) ? 'hidden' : overflowVisibleBehavior];
|
||||||
};
|
};
|
||||||
|
|
||||||
var _setAxisOverflowStyle = setAxisOverflowStyle(overflowOption.x, hasOverflow.x),
|
var _setAxisOverflowStyle = setAxisOverflowStyle(overflowOption.x, hasOverflow.x),
|
||||||
@@ -1589,7 +1610,6 @@
|
|||||||
var sizeFractionCache = getCurrentSizeFraction(force);
|
var sizeFractionCache = getCurrentSizeFraction(force);
|
||||||
var viewportScrollSizeCache = getCurrentViewportScrollSizeCache(force);
|
var viewportScrollSizeCache = getCurrentViewportScrollSizeCache(force);
|
||||||
var overflowAmuntCache = getCurrentOverflowAmountCache(force);
|
var overflowAmuntCache = getCurrentOverflowAmountCache(force);
|
||||||
var updateHintsReturn;
|
|
||||||
var preMeasureViewportOverflowState;
|
var preMeasureViewportOverflowState;
|
||||||
|
|
||||||
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarStyling) {
|
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarStyling) {
|
||||||
@@ -1601,11 +1621,11 @@
|
|||||||
fixFlexboxGlue(preMeasureViewportOverflowState, _heightIntrinsic);
|
fixFlexboxGlue(preMeasureViewportOverflowState, _heightIntrinsic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overflowVisible) {
|
|
||||||
removeClass(_viewport, classNameOverflowVisible);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_sizeChanged || _paddingStyleChanged || _contentMutation || _directionChanged || showNativeOverlaidScrollbarsChanged) {
|
if (_sizeChanged || _paddingStyleChanged || _contentMutation || _directionChanged || showNativeOverlaidScrollbarsChanged) {
|
||||||
|
if (overflowVisible) {
|
||||||
|
removeClass(_viewport, classNameOverflowVisible);
|
||||||
|
}
|
||||||
|
|
||||||
var _undoViewportArrange = undoViewportArrange(showNativeOverlaidScrollbars, _directionIsRTL, preMeasureViewportOverflowState),
|
var _undoViewportArrange = undoViewportArrange(showNativeOverlaidScrollbars, _directionIsRTL, preMeasureViewportOverflowState),
|
||||||
redoViewportArrange = _undoViewportArrange[0],
|
redoViewportArrange = _undoViewportArrange[0],
|
||||||
undoViewportArrangeOverflowState = _undoViewportArrange[1];
|
undoViewportArrangeOverflowState = _undoViewportArrange[1];
|
||||||
@@ -1663,11 +1683,6 @@
|
|||||||
};
|
};
|
||||||
var viewportOverflowState = setViewportOverflowState(showNativeOverlaidScrollbars, hasOverflow, overflow, viewportStyle);
|
var viewportOverflowState = setViewportOverflowState(showNativeOverlaidScrollbars, hasOverflow, overflow, viewportStyle);
|
||||||
var viewportArranged = arrangeViewport(viewportOverflowState, viewportScrollSize, sizeFraction, _directionIsRTL);
|
var viewportArranged = arrangeViewport(viewportOverflowState, viewportScrollSize, sizeFraction, _directionIsRTL);
|
||||||
|
|
||||||
var _updateOverflowScroll = updateOverflowScrollCache(viewportOverflowState._overflowScroll),
|
|
||||||
overflowScroll = _updateOverflowScroll[0],
|
|
||||||
overflowScrollChanged = _updateOverflowScroll[1];
|
|
||||||
|
|
||||||
hideNativeScrollbars(viewportOverflowState, _directionIsRTL, viewportArranged, viewportStyle);
|
hideNativeScrollbars(viewportOverflowState, _directionIsRTL, viewportArranged, viewportStyle);
|
||||||
|
|
||||||
if (adjustFlexboxGlue) {
|
if (adjustFlexboxGlue) {
|
||||||
@@ -1675,21 +1690,28 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
style(_viewport, viewportStyle);
|
style(_viewport, viewportStyle);
|
||||||
setState({
|
|
||||||
_overflowScroll: overflowScroll,
|
|
||||||
_overflowAmount: overflowAmount,
|
|
||||||
_hasOverflow: hasOverflow
|
|
||||||
});
|
|
||||||
updateHintsReturn = {
|
|
||||||
_overflowAmountChanged: overflowAmountChanged,
|
|
||||||
_overflowScrollChanged: overflowScrollChanged
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attr(_host, dataAttributeHost, removeClipping ? 'overflowVisible' : '');
|
attr(_host, dataAttributeHost, removeClipping ? 'overflowVisible' : '');
|
||||||
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
||||||
conditionalClass(_viewport, classNameOverflowVisible, overflowVisible);
|
conditionalClass(_viewport, classNameOverflowVisible, overflowVisible);
|
||||||
return updateHintsReturn;
|
|
||||||
|
var _updateOverflowStyleC = updateOverflowStyleCache(getViewportOverflowState(showNativeOverlaidScrollbars)._overflowStyle),
|
||||||
|
overflowStyle = _updateOverflowStyleC[0],
|
||||||
|
overflowStyleChanged = _updateOverflowStyleC[1];
|
||||||
|
|
||||||
|
setState({
|
||||||
|
_overflowStyle: overflowStyle,
|
||||||
|
_overflowAmount: {
|
||||||
|
x: overflowAmount.w,
|
||||||
|
y: overflowAmount.h
|
||||||
|
},
|
||||||
|
_hasOverflow: hasOverflow
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
_overflowStyleChanged: overflowStyleChanged,
|
||||||
|
_overflowAmountChanged: overflowAmountChanged
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1721,8 +1743,8 @@
|
|||||||
_paddingStyleChanged: false,
|
_paddingStyleChanged: false,
|
||||||
_directionChanged: false,
|
_directionChanged: false,
|
||||||
_heightIntrinsicChanged: false,
|
_heightIntrinsicChanged: false,
|
||||||
_overflowScrollChanged: false,
|
|
||||||
_overflowAmountChanged: false,
|
_overflowAmountChanged: false,
|
||||||
|
_overflowStyleChanged: false,
|
||||||
_hostMutation: false,
|
_hostMutation: false,
|
||||||
_contentMutation: false
|
_contentMutation: false
|
||||||
}, updateHints), {}, force);
|
}, updateHints), {}, force);
|
||||||
@@ -2340,12 +2362,12 @@
|
|||||||
paddingLeft: 0
|
paddingLeft: 0
|
||||||
},
|
},
|
||||||
_overflowAmount: {
|
_overflowAmount: {
|
||||||
w: 0,
|
x: 0,
|
||||||
h: 0
|
y: 0
|
||||||
},
|
},
|
||||||
_overflowScroll: {
|
_overflowStyle: {
|
||||||
x: false,
|
x: 'hidden',
|
||||||
y: false
|
y: 'hidden'
|
||||||
},
|
},
|
||||||
_hasOverflow: {
|
_hasOverflow: {
|
||||||
x: false,
|
x: false,
|
||||||
@@ -2557,17 +2579,6 @@
|
|||||||
return createEventListenerHub(initialEventListeners);
|
return createEventListenerHub(initialEventListeners);
|
||||||
};
|
};
|
||||||
|
|
||||||
var createOverflowChangedArgs = function createOverflowChangedArgs(overflowAmount, hasOverflow, overflowScroll) {
|
|
||||||
return {
|
|
||||||
amount: {
|
|
||||||
x: overflowAmount.w,
|
|
||||||
y: overflowAmount.h
|
|
||||||
},
|
|
||||||
overflow: hasOverflow,
|
|
||||||
scrollableOverflow: assignDeep({}, overflowScroll)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var OverlayScrollbars = function OverlayScrollbars(target, options, eventListeners) {
|
var OverlayScrollbars = function OverlayScrollbars(target, options, eventListeners) {
|
||||||
var _getEnvironment = getEnvironment(),
|
var _getEnvironment = getEnvironment(),
|
||||||
_getDefaultOptions = _getEnvironment._getDefaultOptions,
|
_getDefaultOptions = _getEnvironment._getDefaultOptions,
|
||||||
@@ -2615,33 +2626,23 @@
|
|||||||
updateScrollbars(changedOptions, force);
|
updateScrollbars(changedOptions, force);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var removeEnvListener = addEnvListener(_update.bind(0, {}, true));
|
||||||
|
|
||||||
structureState._addOnUpdatedListener(function (updateHints, changedOptions, force) {
|
structureState._addOnUpdatedListener(function (updateHints, changedOptions, force) {
|
||||||
var _sizeChanged = updateHints._sizeChanged,
|
var _sizeChanged = updateHints._sizeChanged,
|
||||||
_directionChanged = updateHints._directionChanged,
|
_directionChanged = updateHints._directionChanged,
|
||||||
_heightIntrinsicChanged = updateHints._heightIntrinsicChanged,
|
_heightIntrinsicChanged = updateHints._heightIntrinsicChanged,
|
||||||
_overflowAmountChanged = updateHints._overflowAmountChanged,
|
_overflowAmountChanged = updateHints._overflowAmountChanged,
|
||||||
_overflowScrollChanged = updateHints._overflowScrollChanged,
|
_overflowStyleChanged = updateHints._overflowStyleChanged,
|
||||||
_contentMutation = updateHints._contentMutation,
|
_contentMutation = updateHints._contentMutation,
|
||||||
_hostMutation = updateHints._hostMutation;
|
_hostMutation = updateHints._hostMutation;
|
||||||
|
|
||||||
var _structureState = structureState(),
|
|
||||||
_overflowAmount = _structureState._overflowAmount,
|
|
||||||
_overflowScroll = _structureState._overflowScroll,
|
|
||||||
_hasOverflow = _structureState._hasOverflow;
|
|
||||||
|
|
||||||
if (_overflowAmountChanged || _overflowScrollChanged) {
|
|
||||||
triggerEvent('overflowChanged', assignDeep({}, createOverflowChangedArgs(_overflowAmount, _hasOverflow, _overflowScroll), {
|
|
||||||
previous: createOverflowChangedArgs(_overflowAmount, _hasOverflow, _overflowScroll)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerEvent('updated', {
|
triggerEvent('updated', {
|
||||||
updateHints: {
|
updateHints: {
|
||||||
sizeChanged: _sizeChanged,
|
sizeChanged: _sizeChanged,
|
||||||
directionChanged: _directionChanged,
|
directionChanged: _directionChanged,
|
||||||
heightIntrinsicChanged: _heightIntrinsicChanged,
|
heightIntrinsicChanged: _heightIntrinsicChanged,
|
||||||
overflowAmountChanged: _overflowAmountChanged,
|
overflowAmountChanged: _overflowAmountChanged,
|
||||||
overflowScrollChanged: _overflowScrollChanged,
|
overflowStyleChanged: _overflowStyleChanged,
|
||||||
contentMutation: _contentMutation,
|
contentMutation: _contentMutation,
|
||||||
hostMutation: _hostMutation
|
hostMutation: _hostMutation
|
||||||
},
|
},
|
||||||
@@ -2650,7 +2651,6 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var removeEnvListener = addEnvListener(_update.bind(0, {}, true));
|
|
||||||
var instance = {
|
var instance = {
|
||||||
options: function options(newOptions) {
|
options: function options(newOptions) {
|
||||||
if (newOptions) {
|
if (newOptions) {
|
||||||
@@ -2663,14 +2663,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentOptions;
|
return assignDeep({}, currentOptions);
|
||||||
},
|
},
|
||||||
on: addEvent,
|
on: addEvent,
|
||||||
off: removeEvent,
|
off: removeEvent,
|
||||||
state: function state() {
|
state: function state() {
|
||||||
return {
|
var _structureState = structureState(),
|
||||||
_overflowAmount: structureState()._overflowAmount
|
_overflowAmount = _structureState._overflowAmount,
|
||||||
};
|
_overflowStyle = _structureState._overflowStyle,
|
||||||
|
_hasOverflow = _structureState._hasOverflow,
|
||||||
|
_padding = _structureState._padding,
|
||||||
|
_paddingAbsolute = _structureState._paddingAbsolute;
|
||||||
|
|
||||||
|
return assignDeep({}, {
|
||||||
|
overflowAmount: _overflowAmount,
|
||||||
|
overflowStyle: _overflowStyle,
|
||||||
|
hasOverflow: _hasOverflow,
|
||||||
|
padding: _padding,
|
||||||
|
paddingAbsolute: _paddingAbsolute
|
||||||
|
});
|
||||||
},
|
},
|
||||||
update: function update(force) {
|
update: function update(force) {
|
||||||
_update({}, force);
|
_update({}, force);
|
||||||
@@ -2696,7 +2707,38 @@
|
|||||||
triggerEvent('initialized');
|
triggerEvent('initialized');
|
||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
OverlayScrollbars.extend = addPlugin;
|
OverlayScrollbars.plugin = addPlugin;
|
||||||
|
|
||||||
|
OverlayScrollbars.env = function () {
|
||||||
|
var _getEnvironment2 = getEnvironment(),
|
||||||
|
_nativeScrollbarSize = _getEnvironment2._nativeScrollbarSize,
|
||||||
|
_nativeScrollbarIsOverlaid = _getEnvironment2._nativeScrollbarIsOverlaid,
|
||||||
|
_nativeScrollbarStyling = _getEnvironment2._nativeScrollbarStyling,
|
||||||
|
_rtlScrollBehavior = _getEnvironment2._rtlScrollBehavior,
|
||||||
|
_flexboxGlue = _getEnvironment2._flexboxGlue,
|
||||||
|
_cssCustomProperties = _getEnvironment2._cssCustomProperties,
|
||||||
|
_defaultInitializationStrategy = _getEnvironment2._defaultInitializationStrategy,
|
||||||
|
_defaultDefaultOptions = _getEnvironment2._defaultDefaultOptions,
|
||||||
|
_getInitializationStrategy = _getEnvironment2._getInitializationStrategy,
|
||||||
|
_setInitializationStrategy = _getEnvironment2._setInitializationStrategy,
|
||||||
|
_getDefaultOptions = _getEnvironment2._getDefaultOptions,
|
||||||
|
_setDefaultOptions = _getEnvironment2._setDefaultOptions;
|
||||||
|
|
||||||
|
return assignDeep({}, {
|
||||||
|
scrollbarSize: _nativeScrollbarSize,
|
||||||
|
scrollbarIsOverlaid: _nativeScrollbarIsOverlaid,
|
||||||
|
scrollbarStyling: _nativeScrollbarStyling,
|
||||||
|
rtlScrollBehavior: _rtlScrollBehavior,
|
||||||
|
flexboxGlue: _flexboxGlue,
|
||||||
|
cssCustomProperties: _cssCustomProperties,
|
||||||
|
defaultInitializationStrategy: _defaultInitializationStrategy,
|
||||||
|
defaultDefaultOptions: _defaultDefaultOptions,
|
||||||
|
getInitializationStrategy: _getInitializationStrategy,
|
||||||
|
setInitializationStrategy: _setInitializationStrategy,
|
||||||
|
getDefaultOptions: _getDefaultOptions,
|
||||||
|
setDefaultOptions: _setDefaultOptions
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return OverlayScrollbars;
|
return OverlayScrollbars;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,13 +12,14 @@ import {
|
|||||||
removeAttr,
|
removeAttr,
|
||||||
removeElements,
|
removeElements,
|
||||||
windowSize,
|
windowSize,
|
||||||
runEach,
|
|
||||||
equalBCRWH,
|
equalBCRWH,
|
||||||
getBoundingClientRect,
|
getBoundingClientRect,
|
||||||
assignDeep,
|
assignDeep,
|
||||||
cssProperty,
|
cssProperty,
|
||||||
createCache,
|
createCache,
|
||||||
equalXY,
|
equalXY,
|
||||||
|
createEventListenerHub,
|
||||||
|
EventListener,
|
||||||
} from 'support';
|
} from 'support';
|
||||||
import {
|
import {
|
||||||
classNameEnvironment,
|
classNameEnvironment,
|
||||||
@@ -80,7 +81,10 @@ export type DefaultInitializationStrategy = {
|
|||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnEnvironmentChanged = (env: Environment) => void;
|
export interface EnvironmentListenersNameArgsMap {
|
||||||
|
_: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Environment {
|
export interface Environment {
|
||||||
readonly _nativeScrollbarSize: XY;
|
readonly _nativeScrollbarSize: XY;
|
||||||
readonly _nativeScrollbarIsOverlaid: XY<boolean>;
|
readonly _nativeScrollbarIsOverlaid: XY<boolean>;
|
||||||
@@ -90,7 +94,7 @@ export interface Environment {
|
|||||||
readonly _cssCustomProperties: boolean;
|
readonly _cssCustomProperties: boolean;
|
||||||
readonly _defaultInitializationStrategy: DefaultInitializationStrategy;
|
readonly _defaultInitializationStrategy: DefaultInitializationStrategy;
|
||||||
readonly _defaultDefaultOptions: OSOptions;
|
readonly _defaultDefaultOptions: OSOptions;
|
||||||
_addListener(listener: OnEnvironmentChanged): () => void;
|
_addListener(listener: EventListener<EnvironmentListenersNameArgsMap, '_'>): () => void;
|
||||||
_getInitializationStrategy(): InitializationStrategy;
|
_getInitializationStrategy(): InitializationStrategy;
|
||||||
_setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
_setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
||||||
_getDefaultOptions(): OSOptions;
|
_getDefaultOptions(): OSOptions;
|
||||||
@@ -208,7 +212,7 @@ const createEnvironment = (): Environment => {
|
|||||||
const envDOM = createDOM(`<div class="${classNameEnvironment}"><div></div></div>`);
|
const envDOM = createDOM(`<div class="${classNameEnvironment}"><div></div></div>`);
|
||||||
const envElm = envDOM[0] as HTMLElement;
|
const envElm = envDOM[0] as HTMLElement;
|
||||||
const envChildElm = envElm.firstChild as HTMLElement;
|
const envChildElm = envElm.firstChild as HTMLElement;
|
||||||
const onChangedListener: Set<OnEnvironmentChanged> = new Set();
|
const [addEvent, , triggerEvent] = createEventListenerHub<EnvironmentListenersNameArgsMap>();
|
||||||
const [updateNativeScrollbarSizeCache, getNativeScrollbarSizeCache] = createCache({
|
const [updateNativeScrollbarSizeCache, getNativeScrollbarSizeCache] = createCache({
|
||||||
_initialValue: getNativeScrollbarSize(body, envElm, envChildElm),
|
_initialValue: getNativeScrollbarSize(body, envElm, envChildElm),
|
||||||
_equal: equalXY,
|
_equal: equalXY,
|
||||||
@@ -229,10 +233,7 @@ const createEnvironment = (): Environment => {
|
|||||||
_cssCustomProperties: style(envElm, 'zIndex') === '-1',
|
_cssCustomProperties: style(envElm, 'zIndex') === '-1',
|
||||||
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
_rtlScrollBehavior: getRtlScrollBehavior(envElm, envChildElm),
|
||||||
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
_flexboxGlue: getFlexboxGlue(envElm, envChildElm),
|
||||||
_addListener(listener) {
|
_addListener: (listener) => addEvent('_', listener),
|
||||||
onChangedListener.add(listener);
|
|
||||||
return () => onChangedListener.delete(listener);
|
|
||||||
},
|
|
||||||
_getInitializationStrategy: assignDeep<InitializationStrategy, InitializationStrategy>.bind(
|
_getInitializationStrategy: assignDeep<InitializationStrategy, InitializationStrategy>.bind(
|
||||||
0,
|
0,
|
||||||
{} as InitializationStrategy,
|
{} as InitializationStrategy,
|
||||||
@@ -261,45 +262,43 @@ const createEnvironment = (): Environment => {
|
|||||||
let dpr = getWindowDPR();
|
let dpr = getWindowDPR();
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
if (onChangedListener.size) {
|
const sizeNew = windowSize();
|
||||||
const sizeNew = windowSize();
|
const deltaSize = {
|
||||||
const deltaSize = {
|
w: sizeNew.w - size.w,
|
||||||
w: sizeNew.w - size.w,
|
h: sizeNew.h - size.h,
|
||||||
h: sizeNew.h - size.h,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
if (deltaSize.w === 0 && deltaSize.h === 0) return;
|
if (deltaSize.w === 0 && deltaSize.h === 0) return;
|
||||||
|
|
||||||
const deltaAbsSize = {
|
const deltaAbsSize = {
|
||||||
w: abs(deltaSize.w),
|
w: abs(deltaSize.w),
|
||||||
h: abs(deltaSize.h),
|
h: abs(deltaSize.h),
|
||||||
};
|
};
|
||||||
const deltaAbsRatio = {
|
const deltaAbsRatio = {
|
||||||
w: abs(round(sizeNew.w / (size.w / 100.0))),
|
w: abs(round(sizeNew.w / (size.w / 100.0))),
|
||||||
h: abs(round(sizeNew.h / (size.h / 100.0))),
|
h: abs(round(sizeNew.h / (size.h / 100.0))),
|
||||||
};
|
};
|
||||||
const dprNew = getWindowDPR();
|
const dprNew = getWindowDPR();
|
||||||
const deltaIsBigger = deltaAbsSize.w > 2 && deltaAbsSize.h > 2;
|
const deltaIsBigger = deltaAbsSize.w > 2 && deltaAbsSize.h > 2;
|
||||||
const difference = !diffBiggerThanOne(deltaAbsRatio.w, deltaAbsRatio.h);
|
const difference = !diffBiggerThanOne(deltaAbsRatio.w, deltaAbsRatio.h);
|
||||||
const dprChanged = dprNew !== dpr && dpr > 0;
|
const dprChanged = dprNew !== dpr && dpr > 0;
|
||||||
const isZoom = deltaIsBigger && difference && dprChanged;
|
const isZoom = deltaIsBigger && difference && dprChanged;
|
||||||
|
|
||||||
if (isZoom) {
|
if (isZoom) {
|
||||||
const [scrollbarSize, scrollbarSizeChanged] = updateNativeScrollbarSizeCache(
|
const [scrollbarSize, scrollbarSizeChanged] = updateNativeScrollbarSizeCache(
|
||||||
getNativeScrollbarSize(body, envElm, envChildElm)
|
getNativeScrollbarSize(body, envElm, envChildElm)
|
||||||
);
|
);
|
||||||
|
|
||||||
assignDeep(environmentInstance._nativeScrollbarSize, scrollbarSize); // keep the object same!
|
assignDeep(environmentInstance._nativeScrollbarSize, scrollbarSize); // keep the object same!
|
||||||
removeElements(envElm);
|
removeElements(envElm);
|
||||||
|
|
||||||
if (scrollbarSizeChanged) {
|
if (scrollbarSizeChanged) {
|
||||||
runEach(onChangedListener);
|
triggerEvent('_');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size = sizeNew;
|
|
||||||
dpr = dprNew;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = sizeNew;
|
||||||
|
dpr = dprNew;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { OSOptions } from 'options';
|
import { OSOptions } from 'options';
|
||||||
import { createEventListenerHub, XY } from 'support';
|
import { createEventListenerHub } from 'support';
|
||||||
import { PartialOptions } from 'typings';
|
import { PartialOptions } from 'typings';
|
||||||
import type {
|
import type {
|
||||||
InitialEventListeners,
|
InitialEventListeners,
|
||||||
@@ -25,7 +25,7 @@ export interface OnUpdatedEventListenerArgs {
|
|||||||
directionChanged: boolean;
|
directionChanged: boolean;
|
||||||
heightIntrinsicChanged: boolean;
|
heightIntrinsicChanged: boolean;
|
||||||
overflowAmountChanged: boolean;
|
overflowAmountChanged: boolean;
|
||||||
overflowScrollChanged: boolean;
|
overflowStyleChanged: boolean;
|
||||||
hostMutation: boolean;
|
hostMutation: boolean;
|
||||||
contentMutation: boolean;
|
contentMutation: boolean;
|
||||||
};
|
};
|
||||||
@@ -33,21 +33,9 @@ export interface OnUpdatedEventListenerArgs {
|
|||||||
force: boolean;
|
force: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnOverflowChangedEventListenerArgs {
|
|
||||||
overflow: XY<boolean>; // whether there is an overflow
|
|
||||||
scrollableOverflow: XY<boolean>; // whether there is an scrollable overflow
|
|
||||||
amount: XY<number>; // the overflow amount in pixel
|
|
||||||
previous: {
|
|
||||||
overflow: XY<boolean>;
|
|
||||||
scrollableOverflow: XY<boolean>;
|
|
||||||
amount: XY<number>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OSEventListenersNameArgsMap {
|
export interface OSEventListenersNameArgsMap {
|
||||||
initialized: undefined;
|
initialized: undefined;
|
||||||
initializationWithdrawn: undefined;
|
initializationWithdrawn: undefined;
|
||||||
overflowChanged: OnOverflowChangedEventListenerArgs;
|
|
||||||
updated: OnUpdatedEventListenerArgs;
|
updated: OnUpdatedEventListenerArgs;
|
||||||
destroyed: undefined;
|
destroyed: undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ export type SizeChangedCallback = (this: any, args?: SizeChangedArgs) => void;
|
|||||||
export type UpdatedCallback = (this: any, args?: UpdatedArgs) => void;
|
export type UpdatedCallback = (this: any, args?: UpdatedArgs) => void;
|
||||||
|
|
||||||
export interface OSOptions {
|
export interface OSOptions {
|
||||||
resize: ResizeBehavior;
|
|
||||||
paddingAbsolute: boolean;
|
paddingAbsolute: boolean;
|
||||||
updating: {
|
updating: {
|
||||||
elementEvents: Array<[string, string]> | null;
|
elementEvents: Array<[string, string]> | null;
|
||||||
@@ -58,34 +57,10 @@ export interface OSOptions {
|
|||||||
clickScroll: boolean;
|
clickScroll: boolean;
|
||||||
touch: boolean;
|
touch: boolean;
|
||||||
};
|
};
|
||||||
textarea: {
|
|
||||||
dynWidth: boolean;
|
|
||||||
dynHeight: boolean;
|
|
||||||
inheritedAttrs: string | Array<string> | null;
|
|
||||||
};
|
|
||||||
nativeScrollbarsOverlaid: {
|
nativeScrollbarsOverlaid: {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
initialize: boolean;
|
initialize: boolean;
|
||||||
};
|
};
|
||||||
callbacks: {
|
|
||||||
onUpdated: (() => any) | null;
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
callbacks?: {
|
|
||||||
onInitialized?: BasicEventCallback | null;
|
|
||||||
onInitializationWithdrawn?: BasicEventCallback | null;
|
|
||||||
onDestroyed?: BasicEventCallback | null;
|
|
||||||
onScrollStart?: ScrollEventCallback | null;
|
|
||||||
onScroll?: ScrollEventCallback | null;
|
|
||||||
onScrollStop?: ScrollEventCallback | null;
|
|
||||||
onOverflowChanged?: OverflowChangedCallback | null;
|
|
||||||
onOverflowAmountChanged?: OverflowAmountChangedCallback | null;
|
|
||||||
onDirectionChanged?: DirectionChangedCallback | null;
|
|
||||||
onContentSizeChanged?: SizeChangedCallback | null;
|
|
||||||
onHostSizeChanged?: SizeChangedCallback | null;
|
|
||||||
onUpdated?: UpdatedCallback | null;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ReadonlyOSOptions = ReadonlyOptions<OSOptions>;
|
export type ReadonlyOSOptions = ReadonlyOptions<OSOptions>;
|
||||||
@@ -118,7 +93,7 @@ export interface UpdatedArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const defaultOptions: OSOptions = {
|
export const defaultOptions: OSOptions = {
|
||||||
resize: 'none', // none || both || horizontal || vertical || n || b || h || v
|
// resize: 'none', // none || both || horizontal || vertical || n || b || h || v
|
||||||
paddingAbsolute: false, // true || false
|
paddingAbsolute: false, // true || false
|
||||||
updating: {
|
updating: {
|
||||||
elementEvents: [['img', 'load']], // array of tuples || null
|
elementEvents: [['img', 'load']], // array of tuples || null
|
||||||
@@ -129,6 +104,10 @@ export const defaultOptions: OSOptions = {
|
|||||||
x: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
x: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
||||||
y: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
y: 'scroll', // visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s
|
||||||
},
|
},
|
||||||
|
nativeScrollbarsOverlaid: {
|
||||||
|
show: false, // true || false
|
||||||
|
initialize: false, // true || false
|
||||||
|
},
|
||||||
scrollbars: {
|
scrollbars: {
|
||||||
visibility: 'auto', // visible || hidden || auto || v || h || a
|
visibility: 'auto', // visible || hidden || auto || v || h || a
|
||||||
autoHide: 'never', // never || scroll || leave || move || n || s || l || m
|
autoHide: 'never', // never || scroll || leave || move || n || s || l || m
|
||||||
@@ -137,18 +116,13 @@ export const defaultOptions: OSOptions = {
|
|||||||
clickScroll: false, // true || false
|
clickScroll: false, // true || false
|
||||||
touch: true, // true || false
|
touch: true, // true || false
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
textarea: {
|
textarea: {
|
||||||
dynWidth: false, // true || false
|
dynWidth: false, // true || false
|
||||||
dynHeight: false, // true || false
|
dynHeight: false, // true || false
|
||||||
inheritedAttrs: ['style', 'class'], // string || array || null
|
inheritedAttrs: ['style', 'class'], // string || array || null
|
||||||
},
|
},
|
||||||
nativeScrollbarsOverlaid: {
|
*/
|
||||||
show: false, // true || false
|
|
||||||
initialize: false, // true || false
|
|
||||||
},
|
|
||||||
callbacks: {
|
|
||||||
onUpdated: null,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOptionsDiff = <T>(
|
export const getOptionsDiff = <T>(
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
import { OSTarget, OSInitializationObject, PartialOptions } from 'typings';
|
import { OSTarget, OSInitializationObject, PartialOptions, OverflowStyle } from 'typings';
|
||||||
import { assignDeep, isEmptyObject, each, isFunction, keys, isHTMLElement, WH, XY } from 'support';
|
import {
|
||||||
|
assignDeep,
|
||||||
|
isEmptyObject,
|
||||||
|
each,
|
||||||
|
isFunction,
|
||||||
|
keys,
|
||||||
|
isHTMLElement,
|
||||||
|
XY,
|
||||||
|
TRBL,
|
||||||
|
} from 'support';
|
||||||
import { createStructureSetup, createScrollbarsSetup } from 'setups';
|
import { createStructureSetup, createScrollbarsSetup } from 'setups';
|
||||||
import { getOptionsDiff, OSOptions, ReadonlyOSOptions } from 'options';
|
import { getOptionsDiff, OSOptions, ReadonlyOSOptions } from 'options';
|
||||||
import { getEnvironment } from 'environment';
|
import { DefaultInitializationStrategy, getEnvironment, InitializationStrategy } from 'environment';
|
||||||
import {
|
import {
|
||||||
getPlugins,
|
getPlugins,
|
||||||
addPlugin,
|
addPlugin,
|
||||||
@@ -25,7 +34,32 @@ export interface OverlayScrollbarsStatic {
|
|||||||
eventListeners?: InitialOSEventListeners
|
eventListeners?: InitialOSEventListeners
|
||||||
): OverlayScrollbars;
|
): OverlayScrollbars;
|
||||||
|
|
||||||
extend(osPlugin: OSPlugin | OSPlugin[]): void;
|
plugin(osPlugin: OSPlugin | OSPlugin[]): void;
|
||||||
|
env(): OverlayScrollbarsEnv;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OverlayScrollbarsEnv {
|
||||||
|
scrollbarSize: XY<number>;
|
||||||
|
scrollbarIsOverlaid: XY<boolean>;
|
||||||
|
scrollbarStyling: boolean;
|
||||||
|
rtlScrollBehavior: { n: boolean; i: boolean };
|
||||||
|
flexboxGlue: boolean;
|
||||||
|
cssCustomProperties: boolean;
|
||||||
|
defaultInitializationStrategy: DefaultInitializationStrategy;
|
||||||
|
defaultDefaultOptions: OSOptions;
|
||||||
|
|
||||||
|
getInitializationStrategy(): InitializationStrategy;
|
||||||
|
setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
||||||
|
getDefaultOptions(): OSOptions;
|
||||||
|
setDefaultOptions(newDefaultOptions: PartialOptions<OSOptions>): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OverlayScrollbarsState {
|
||||||
|
padding: TRBL;
|
||||||
|
paddingAbsolute: boolean;
|
||||||
|
overflowAmount: XY<number>;
|
||||||
|
overflowStyle: XY<OverflowStyle>;
|
||||||
|
hasOverflow: XY<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OverlayScrollbars {
|
export interface OverlayScrollbars {
|
||||||
@@ -35,24 +69,16 @@ export interface OverlayScrollbars {
|
|||||||
update(force?: boolean): void;
|
update(force?: boolean): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
|
|
||||||
state(): any;
|
state(): OverlayScrollbarsState;
|
||||||
|
|
||||||
on: AddOSEventListener;
|
on: AddOSEventListener;
|
||||||
off: RemoveOSEventListener;
|
off: RemoveOSEventListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createOverflowChangedArgs = (
|
/**
|
||||||
overflowAmount: WH<number>,
|
* Notes:
|
||||||
hasOverflow: XY<boolean>,
|
* Height intrinsic detection use "content: true" init strategy - or open ticket for custom height intrinsic observer
|
||||||
overflowScroll: XY<boolean>
|
*/
|
||||||
) => ({
|
|
||||||
amount: {
|
|
||||||
x: overflowAmount.w,
|
|
||||||
y: overflowAmount.h,
|
|
||||||
},
|
|
||||||
overflow: hasOverflow,
|
|
||||||
scrollableOverflow: assignDeep({}, overflowScroll),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
||||||
target,
|
target,
|
||||||
@@ -109,26 +135,18 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
updateScrollbars(changedOptions, force);
|
updateScrollbars(changedOptions, force);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
||||||
|
|
||||||
structureState._addOnUpdatedListener((updateHints, changedOptions, force) => {
|
structureState._addOnUpdatedListener((updateHints, changedOptions, force) => {
|
||||||
const {
|
const {
|
||||||
_sizeChanged,
|
_sizeChanged,
|
||||||
_directionChanged,
|
_directionChanged,
|
||||||
_heightIntrinsicChanged,
|
_heightIntrinsicChanged,
|
||||||
_overflowAmountChanged,
|
_overflowAmountChanged,
|
||||||
_overflowScrollChanged,
|
_overflowStyleChanged,
|
||||||
_contentMutation,
|
_contentMutation,
|
||||||
_hostMutation,
|
_hostMutation,
|
||||||
} = updateHints;
|
} = updateHints;
|
||||||
const { _overflowAmount, _overflowScroll, _hasOverflow } = structureState();
|
|
||||||
|
|
||||||
if (_overflowAmountChanged || _overflowScrollChanged) {
|
|
||||||
triggerEvent(
|
|
||||||
'overflowChanged',
|
|
||||||
assignDeep({}, createOverflowChangedArgs(_overflowAmount, _hasOverflow, _overflowScroll), {
|
|
||||||
previous: createOverflowChangedArgs(_overflowAmount!, _hasOverflow, _overflowScroll!),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerEvent('updated', {
|
triggerEvent('updated', {
|
||||||
updateHints: {
|
updateHints: {
|
||||||
@@ -136,7 +154,7 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
directionChanged: _directionChanged,
|
directionChanged: _directionChanged,
|
||||||
heightIntrinsicChanged: _heightIntrinsicChanged,
|
heightIntrinsicChanged: _heightIntrinsicChanged,
|
||||||
overflowAmountChanged: _overflowAmountChanged,
|
overflowAmountChanged: _overflowAmountChanged,
|
||||||
overflowScrollChanged: _overflowScrollChanged,
|
overflowStyleChanged: _overflowStyleChanged,
|
||||||
contentMutation: _contentMutation,
|
contentMutation: _contentMutation,
|
||||||
hostMutation: _hostMutation,
|
hostMutation: _hostMutation,
|
||||||
},
|
},
|
||||||
@@ -145,8 +163,6 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const removeEnvListener = addEnvListener(update.bind(0, {}, true));
|
|
||||||
|
|
||||||
const instance: OverlayScrollbars = {
|
const instance: OverlayScrollbars = {
|
||||||
options(newOptions?: PartialOptions<OSOptions>) {
|
options(newOptions?: PartialOptions<OSOptions>) {
|
||||||
if (newOptions) {
|
if (newOptions) {
|
||||||
@@ -157,13 +173,24 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
update(changedOptions);
|
update(changedOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return currentOptions;
|
return assignDeep({}, currentOptions);
|
||||||
},
|
},
|
||||||
on: addEvent,
|
on: addEvent,
|
||||||
off: removeEvent,
|
off: removeEvent,
|
||||||
state: () => ({
|
state: () => {
|
||||||
_overflowAmount: structureState()._overflowAmount,
|
const { _overflowAmount, _overflowStyle, _hasOverflow, _padding, _paddingAbsolute } =
|
||||||
}),
|
structureState();
|
||||||
|
return assignDeep(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
overflowAmount: _overflowAmount,
|
||||||
|
overflowStyle: _overflowStyle,
|
||||||
|
hasOverflow: _hasOverflow,
|
||||||
|
padding: _padding,
|
||||||
|
paddingAbsolute: _paddingAbsolute,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
update(force?: boolean) {
|
update(force?: boolean) {
|
||||||
update({}, force);
|
update({}, force);
|
||||||
},
|
},
|
||||||
@@ -195,4 +222,38 @@ export const OverlayScrollbars: OverlayScrollbarsStatic = (
|
|||||||
return instance;
|
return instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
OverlayScrollbars.extend = addPlugin;
|
OverlayScrollbars.plugin = addPlugin;
|
||||||
|
OverlayScrollbars.env = () => {
|
||||||
|
const {
|
||||||
|
_nativeScrollbarSize,
|
||||||
|
_nativeScrollbarIsOverlaid,
|
||||||
|
_nativeScrollbarStyling,
|
||||||
|
_rtlScrollBehavior,
|
||||||
|
_flexboxGlue,
|
||||||
|
_cssCustomProperties,
|
||||||
|
_defaultInitializationStrategy,
|
||||||
|
_defaultDefaultOptions,
|
||||||
|
_getInitializationStrategy,
|
||||||
|
_setInitializationStrategy,
|
||||||
|
_getDefaultOptions,
|
||||||
|
_setDefaultOptions,
|
||||||
|
} = getEnvironment();
|
||||||
|
return assignDeep(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
scrollbarSize: _nativeScrollbarSize,
|
||||||
|
scrollbarIsOverlaid: _nativeScrollbarIsOverlaid,
|
||||||
|
scrollbarStyling: _nativeScrollbarStyling,
|
||||||
|
rtlScrollBehavior: _rtlScrollBehavior,
|
||||||
|
flexboxGlue: _flexboxGlue,
|
||||||
|
cssCustomProperties: _cssCustomProperties,
|
||||||
|
defaultInitializationStrategy: _defaultInitializationStrategy,
|
||||||
|
defaultDefaultOptions: _defaultDefaultOptions,
|
||||||
|
|
||||||
|
getInitializationStrategy: _getInitializationStrategy,
|
||||||
|
setInitializationStrategy: _setInitializationStrategy,
|
||||||
|
getDefaultOptions: _getDefaultOptions,
|
||||||
|
setDefaultOptions: _setDefaultOptions,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
import { OSPlugin } from 'plugins';
|
import { OSPlugin } from 'plugins';
|
||||||
import {
|
import { OSOptions, OverflowBehavior, VisibilityBehavior, AutoHideBehavior } from 'options';
|
||||||
OSOptions,
|
|
||||||
ResizeBehavior,
|
|
||||||
OverflowBehavior,
|
|
||||||
VisibilityBehavior,
|
|
||||||
AutoHideBehavior,
|
|
||||||
} from 'options';
|
|
||||||
import {
|
import {
|
||||||
validateOptions,
|
validateOptions,
|
||||||
OptionsTemplate,
|
OptionsTemplate,
|
||||||
@@ -17,12 +11,6 @@ import { PartialOptions } from 'typings';
|
|||||||
const numberAllowedValues: OptionsTemplateValue<number> = oTypes.number;
|
const numberAllowedValues: OptionsTemplateValue<number> = oTypes.number;
|
||||||
const booleanAllowedValues: OptionsTemplateValue<boolean> = oTypes.boolean;
|
const booleanAllowedValues: OptionsTemplateValue<boolean> = oTypes.boolean;
|
||||||
const arrayNullValues: OptionsTemplateValue<Array<unknown> | null> = [oTypes.array, oTypes.null];
|
const arrayNullValues: OptionsTemplateValue<Array<unknown> | null> = [oTypes.array, oTypes.null];
|
||||||
const stringArrayNullAllowedValues: OptionsTemplateValue<string | ReadonlyArray<string> | null> = [
|
|
||||||
oTypes.string,
|
|
||||||
oTypes.array,
|
|
||||||
oTypes.null,
|
|
||||||
];
|
|
||||||
const resizeAllowedValues: OptionsTemplateValue<ResizeBehavior> = 'none both horizontal vertical';
|
|
||||||
const overflowAllowedValues: OptionsTemplateValue<OverflowBehavior> =
|
const overflowAllowedValues: OptionsTemplateValue<OverflowBehavior> =
|
||||||
'hidden scroll visible visible-hidden';
|
'hidden scroll visible visible-hidden';
|
||||||
const scrollbarsVisibilityAllowedValues: OptionsTemplateValue<VisibilityBehavior> =
|
const scrollbarsVisibilityAllowedValues: OptionsTemplateValue<VisibilityBehavior> =
|
||||||
@@ -31,7 +19,7 @@ const scrollbarsAutoHideAllowedValues: OptionsTemplateValue<AutoHideBehavior> =
|
|||||||
'never scroll leavemove';
|
'never scroll leavemove';
|
||||||
|
|
||||||
const optionsTemplate: OptionsTemplate<OSOptions> = {
|
const optionsTemplate: OptionsTemplate<OSOptions> = {
|
||||||
resize: resizeAllowedValues, // none || both || horizontal || vertical || n || b ||
|
// resize: resizeAllowedValues, // none || both || horizontal || vertical || n || b ||
|
||||||
paddingAbsolute: booleanAllowedValues, // true || false
|
paddingAbsolute: booleanAllowedValues, // true || false
|
||||||
updating: {
|
updating: {
|
||||||
elementEvents: arrayNullValues, // array of tuples || null
|
elementEvents: arrayNullValues, // array of tuples || null
|
||||||
@@ -50,18 +38,17 @@ const optionsTemplate: OptionsTemplate<OSOptions> = {
|
|||||||
clickScroll: booleanAllowedValues, // true || false
|
clickScroll: booleanAllowedValues, // true || false
|
||||||
touch: booleanAllowedValues, // true || false
|
touch: booleanAllowedValues, // true || false
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
textarea: {
|
textarea: {
|
||||||
dynWidth: booleanAllowedValues, // true || false
|
dynWidth: booleanAllowedValues, // true || false
|
||||||
dynHeight: booleanAllowedValues, // true || false
|
dynHeight: booleanAllowedValues, // true || false
|
||||||
inheritedAttrs: stringArrayNullAllowedValues, // string || array || nul
|
inheritedAttrs: stringArrayNullAllowedValues, // string || array || nul
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
nativeScrollbarsOverlaid: {
|
nativeScrollbarsOverlaid: {
|
||||||
show: booleanAllowedValues, // true || false
|
show: booleanAllowedValues, // true || false
|
||||||
initialize: booleanAllowedValues, // true || false
|
initialize: booleanAllowedValues, // true || false
|
||||||
},
|
},
|
||||||
callbacks: {
|
|
||||||
onUpdated: [oTypes.function, oTypes.null],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OptionsValidationPluginInstance = {
|
export type OptionsValidationPluginInstance = {
|
||||||
|
|||||||
@@ -10,8 +10,23 @@ import {
|
|||||||
removeAttr,
|
removeAttr,
|
||||||
CacheValues,
|
CacheValues,
|
||||||
keys,
|
keys,
|
||||||
|
liesBetween,
|
||||||
|
scrollSize,
|
||||||
|
equalWH,
|
||||||
|
createCache,
|
||||||
|
WH,
|
||||||
|
fractionalSize,
|
||||||
|
removeClass,
|
||||||
|
addClass,
|
||||||
|
hasClass,
|
||||||
} from 'support';
|
} from 'support';
|
||||||
import { getEnvironment } from 'environment';
|
import { getEnvironment } from 'environment';
|
||||||
|
import {
|
||||||
|
dataAttributeHost,
|
||||||
|
classNameViewport,
|
||||||
|
classNameContent,
|
||||||
|
classNameOverflowVisible,
|
||||||
|
} from 'classnames';
|
||||||
import { createSizeObserver, SizeObserverCallbackParams } from 'observers/sizeObserver';
|
import { createSizeObserver, SizeObserverCallbackParams } from 'observers/sizeObserver';
|
||||||
import { createTrinsicObserver } from 'observers/trinsicObserver';
|
import { createTrinsicObserver } from 'observers/trinsicObserver';
|
||||||
import { createDOMObserver, DOMObserver } from 'observers/domObserver';
|
import { createDOMObserver, DOMObserver } from 'observers/domObserver';
|
||||||
@@ -36,14 +51,14 @@ type ExcludeFromTuple<T extends readonly any[], E> = T extends [infer F, ...infe
|
|||||||
: [F, ...ExcludeFromTuple<R, E>]
|
: [F, ...ExcludeFromTuple<R, E>]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
// const hostSelector = `.${classNameHost}`;
|
const hostSelector = `[${dataAttributeHost}]`;
|
||||||
|
|
||||||
// TODO: observer textarea attrs if textarea
|
// TODO: observer textarea attrs if textarea
|
||||||
// TODO: test _ignoreContentChange & _ignoreNestedTargetChange for content dom observer
|
// TODO: test _ignoreContentChange & _ignoreNestedTargetChange for content dom observer
|
||||||
// TODO: test _ignoreTargetChange for target dom observer
|
// TODO: test _ignoreTargetChange for target dom observer
|
||||||
|
|
||||||
// const viewportSelector = `.${classNameViewport}`;
|
const viewportSelector = `.${classNameViewport}`;
|
||||||
// const contentSelector = `.${classNameContent}`;
|
const contentSelector = `.${classNameContent}`;
|
||||||
const ignorePrefix = 'os-';
|
const ignorePrefix = 'os-';
|
||||||
const viewportAttrsFromTarget = ['tabindex'];
|
const viewportAttrsFromTarget = ['tabindex'];
|
||||||
const baseStyleChangingAttrsTextarea = ['wrap', 'cols', 'rows'];
|
const baseStyleChangingAttrsTextarea = ['wrap', 'cols', 'rows'];
|
||||||
@@ -75,6 +90,25 @@ export const createStructureSetupObservers = (
|
|||||||
const [, setState] = state;
|
const [, setState] = state;
|
||||||
const { _host, _viewport, _content, _isTextarea } = structureSetupElements;
|
const { _host, _viewport, _content, _isTextarea } = structureSetupElements;
|
||||||
const { _nativeScrollbarStyling, _flexboxGlue } = getEnvironment();
|
const { _nativeScrollbarStyling, _flexboxGlue } = getEnvironment();
|
||||||
|
const [updateContentSizeCache] = createCache<WH<number>>(
|
||||||
|
{
|
||||||
|
_equal: equalWH,
|
||||||
|
_initialValue: { w: 0, h: 0 },
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
const has = hasClass(_viewport, classNameOverflowVisible);
|
||||||
|
has && removeClass(_viewport, classNameOverflowVisible);
|
||||||
|
|
||||||
|
const scroll = scrollSize(_viewport);
|
||||||
|
const fractional = fractionalSize(_viewport);
|
||||||
|
|
||||||
|
has && addClass(_viewport, classNameOverflowVisible);
|
||||||
|
return {
|
||||||
|
w: scroll.w + fractional.w,
|
||||||
|
h: scroll.h + fractional.h,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
const contentMutationObserverAttr = _isTextarea
|
const contentMutationObserverAttr = _isTextarea
|
||||||
? baseStyleChangingAttrsTextarea
|
? baseStyleChangingAttrsTextarea
|
||||||
: baseStyleChangingAttrs.concat(baseStyleChangingAttrsTextarea);
|
: baseStyleChangingAttrs.concat(baseStyleChangingAttrsTextarea);
|
||||||
@@ -132,13 +166,17 @@ export const createStructureSetupObservers = (
|
|||||||
updateFn({ _sizeChanged, _directionChanged: directionChanged });
|
updateFn({ _sizeChanged, _directionChanged: directionChanged });
|
||||||
};
|
};
|
||||||
const onContentMutation = (contentChangedTroughEvent: boolean) => {
|
const onContentMutation = (contentChangedTroughEvent: boolean) => {
|
||||||
|
const [, contentSizeChanged] = updateContentSizeCache();
|
||||||
// if contentChangedTroughEvent is true its already debounced
|
// if contentChangedTroughEvent is true its already debounced
|
||||||
const updateFn = contentChangedTroughEvent
|
const updateFn = contentChangedTroughEvent
|
||||||
? structureSetupUpdate
|
? structureSetupUpdate
|
||||||
: structureSetupUpdateWithDebouncedAdaptiveUpdateHints;
|
: structureSetupUpdateWithDebouncedAdaptiveUpdateHints;
|
||||||
updateFn({
|
|
||||||
_contentMutation: true,
|
if (contentSizeChanged) {
|
||||||
});
|
updateFn({
|
||||||
|
_contentMutation: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const onHostMutation = (targetChangedAttrs: string[], targetStyleChanged: boolean) => {
|
const onHostMutation = (targetChangedAttrs: string[], targetStyleChanged: boolean) => {
|
||||||
if (targetStyleChanged) {
|
if (targetStyleChanged) {
|
||||||
@@ -189,17 +227,17 @@ export const createStructureSetupObservers = (
|
|||||||
_attributes: contentMutationObserverAttr.concat(attributes || []),
|
_attributes: contentMutationObserverAttr.concat(attributes || []),
|
||||||
_eventContentChange: elementEvents,
|
_eventContentChange: elementEvents,
|
||||||
_ignoreNestedTargetChange: ignoreTargetChange,
|
_ignoreNestedTargetChange: ignoreTargetChange,
|
||||||
// _nestedTargetSelector: hostSelector,
|
_nestedTargetSelector: hostSelector,
|
||||||
/*
|
_ignoreContentChange: (mutation, isNestedTarget) => {
|
||||||
_ignoreContentChange: (mutation, isNestedTarget) => {
|
const { target, attributeName } = mutation;
|
||||||
const { target, attributeName } = mutation;
|
return !isNestedTarget && attributeName
|
||||||
return isNestedTarget
|
? liesBetween(
|
||||||
? false
|
target as Element,
|
||||||
: attributeName
|
hostSelector,
|
||||||
? liesBetween(target as Element, hostSelector, viewportSelector) || liesBetween(target as Element, hostSelector, contentSelector)
|
_content ? contentSelector : viewportSelector
|
||||||
: false;
|
)
|
||||||
},
|
: false;
|
||||||
*/
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ import { createStructureSetupUpdate } from 'setups/structureSetup/structureSetup
|
|||||||
import { createStructureSetupObservers } from 'setups/structureSetup/structureSetup.observers';
|
import { createStructureSetupObservers } from 'setups/structureSetup/structureSetup.observers';
|
||||||
import type { StructureSetupUpdateHints } from 'setups/structureSetup/structureSetup.update';
|
import type { StructureSetupUpdateHints } from 'setups/structureSetup/structureSetup.update';
|
||||||
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
import type { StructureSetupElementsObj } from 'setups/structureSetup/structureSetup.elements';
|
||||||
import type { TRBL, XY, WH } from 'support';
|
import type { TRBL, XY } from 'support';
|
||||||
import type { OSOptions, ReadonlyOSOptions } from 'options';
|
import type { OSOptions, ReadonlyOSOptions } from 'options';
|
||||||
import type { Setup } from 'setups';
|
import type { Setup } from 'setups';
|
||||||
import type { OSTarget, PartialOptions, StyleObject } from 'typings';
|
import type { OSTarget, PartialOptions, StyleObject, OverflowStyle } from 'typings';
|
||||||
|
|
||||||
export interface StructureSetupState {
|
export interface StructureSetupState {
|
||||||
_padding: TRBL;
|
_padding: TRBL;
|
||||||
_paddingAbsolute: boolean;
|
_paddingAbsolute: boolean;
|
||||||
_viewportPaddingStyle: StyleObject;
|
_viewportPaddingStyle: StyleObject;
|
||||||
_overflowScroll: XY<boolean>;
|
_overflowAmount: XY<number>;
|
||||||
_overflowAmount: WH<number>;
|
_overflowStyle: XY<OverflowStyle>;
|
||||||
_hasOverflow: XY<boolean>;
|
_hasOverflow: XY<boolean>;
|
||||||
_heightIntrinsic: boolean;
|
_heightIntrinsic: boolean;
|
||||||
_directionIsRTL: boolean;
|
_directionIsRTL: boolean;
|
||||||
@@ -50,12 +50,12 @@ const initialStructureSetupUpdateState: StructureSetupState = {
|
|||||||
paddingLeft: 0,
|
paddingLeft: 0,
|
||||||
},
|
},
|
||||||
_overflowAmount: {
|
_overflowAmount: {
|
||||||
w: 0,
|
x: 0,
|
||||||
h: 0,
|
y: 0,
|
||||||
},
|
},
|
||||||
_overflowScroll: {
|
_overflowStyle: {
|
||||||
x: false,
|
x: 'hidden',
|
||||||
y: false,
|
y: 'hidden',
|
||||||
},
|
},
|
||||||
_hasOverflow: {
|
_hasOverflow: {
|
||||||
x: false,
|
x: false,
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ export interface StructureSetupUpdateHints {
|
|||||||
_sizeChanged: boolean;
|
_sizeChanged: boolean;
|
||||||
_directionChanged: boolean;
|
_directionChanged: boolean;
|
||||||
_heightIntrinsicChanged: boolean;
|
_heightIntrinsicChanged: boolean;
|
||||||
_overflowScrollChanged: boolean;
|
|
||||||
_overflowAmountChanged: boolean;
|
_overflowAmountChanged: boolean;
|
||||||
|
_overflowStyleChanged: boolean;
|
||||||
_paddingStyleChanged: boolean;
|
_paddingStyleChanged: boolean;
|
||||||
_hostMutation: boolean;
|
_hostMutation: boolean;
|
||||||
_contentMutation: boolean;
|
_contentMutation: boolean;
|
||||||
@@ -78,8 +78,8 @@ export const createStructureSetupUpdate = (
|
|||||||
_paddingStyleChanged: false,
|
_paddingStyleChanged: false,
|
||||||
_directionChanged: false,
|
_directionChanged: false,
|
||||||
_heightIntrinsicChanged: false,
|
_heightIntrinsicChanged: false,
|
||||||
_overflowScrollChanged: false,
|
|
||||||
_overflowAmountChanged: false,
|
_overflowAmountChanged: false,
|
||||||
|
_overflowStyleChanged: false,
|
||||||
_hostMutation: false,
|
_hostMutation: false,
|
||||||
_contentMutation: false,
|
_contentMutation: false,
|
||||||
},
|
},
|
||||||
|
|||||||
+64
-39
@@ -22,7 +22,7 @@ import {
|
|||||||
classNameOverflowVisible,
|
classNameOverflowVisible,
|
||||||
dataAttributeHost,
|
dataAttributeHost,
|
||||||
} from 'classnames';
|
} from 'classnames';
|
||||||
import type { StyleObject } from 'typings';
|
import type { StyleObject, OverflowStyle } from 'typings';
|
||||||
import type { OverflowBehavior } from 'options';
|
import type { OverflowBehavior } from 'options';
|
||||||
import type { CreateStructureUpdateSegment } from 'setups/structureSetup/structureSetup.update';
|
import type { CreateStructureUpdateSegment } from 'setups/structureSetup/structureSetup.update';
|
||||||
|
|
||||||
@@ -30,6 +30,7 @@ interface ViewportOverflowState {
|
|||||||
_scrollbarsHideOffset: XY<number>;
|
_scrollbarsHideOffset: XY<number>;
|
||||||
_scrollbarsHideOffsetArrange: XY<boolean>;
|
_scrollbarsHideOffsetArrange: XY<boolean>;
|
||||||
_overflowScroll: XY<boolean>;
|
_overflowScroll: XY<boolean>;
|
||||||
|
_overflowStyle: XY<OverflowStyle>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type UndoViewportArrangeResult = [
|
type UndoViewportArrangeResult = [
|
||||||
@@ -39,6 +40,7 @@ type UndoViewportArrangeResult = [
|
|||||||
|
|
||||||
const { max } = Math;
|
const { max } = Math;
|
||||||
const strVisible = 'visible';
|
const strVisible = 'visible';
|
||||||
|
const strHidden = 'hidden';
|
||||||
const overlaidScrollbarsHideOffset = 42;
|
const overlaidScrollbarsHideOffset = 42;
|
||||||
const whCacheOptions = {
|
const whCacheOptions = {
|
||||||
_equal: equalWH,
|
_equal: equalWH,
|
||||||
@@ -46,7 +48,7 @@ const whCacheOptions = {
|
|||||||
};
|
};
|
||||||
const xyCacheOptions = {
|
const xyCacheOptions = {
|
||||||
_equal: equalXY,
|
_equal: equalXY,
|
||||||
_initialValue: { x: false, y: false },
|
_initialValue: { x: strHidden, y: strHidden } as XY<OverflowStyle>,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOverflowAmount = (
|
const getOverflowAmount = (
|
||||||
@@ -106,7 +108,7 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
|||||||
const [updateOverflowAmountCache, getCurrentOverflowAmountCache] =
|
const [updateOverflowAmountCache, getCurrentOverflowAmountCache] =
|
||||||
createCache<WH<number>>(whCacheOptions);
|
createCache<WH<number>>(whCacheOptions);
|
||||||
|
|
||||||
const [updateOverflowScrollCache] = createCache<XY<boolean>>(xyCacheOptions);
|
const [updateOverflowStyleCache] = createCache<XY<OverflowStyle>>(xyCacheOptions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies a fixed height to the viewport so it can't overflow or underflow the host element.
|
* Applies a fixed height to the viewport so it can't overflow or underflow the host element.
|
||||||
@@ -152,33 +154,54 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
|||||||
showNativeOverlaidScrollbars: boolean,
|
showNativeOverlaidScrollbars: boolean,
|
||||||
viewportStyleObj?: StyleObject
|
viewportStyleObj?: StyleObject
|
||||||
): ViewportOverflowState => {
|
): ViewportOverflowState => {
|
||||||
const { x: overlaidX, y: overlaidY } = _nativeScrollbarIsOverlaid;
|
|
||||||
const determineOverflow = !viewportStyleObj;
|
|
||||||
const arrangeHideOffset =
|
const arrangeHideOffset =
|
||||||
!_nativeScrollbarStyling && !showNativeOverlaidScrollbars ? overlaidScrollbarsHideOffset : 0;
|
!_nativeScrollbarStyling && !showNativeOverlaidScrollbars ? overlaidScrollbarsHideOffset : 0;
|
||||||
const styleObj = determineOverflow
|
const getStatePerAxis = (
|
||||||
? style(_viewport, ['overflowX', 'overflowY'])
|
styleKey: string,
|
||||||
: viewportStyleObj;
|
isOverlaid: boolean,
|
||||||
const scroll = {
|
nativeScrollbarSize: number
|
||||||
x: styleObj.overflowX === 'scroll',
|
) => {
|
||||||
y: styleObj.overflowY === 'scroll',
|
const overflowStyle = style(_viewport, styleKey);
|
||||||
};
|
// can't do something like "viewportStyleObj && viewportStyleObj[styleKey] || overflowStyle" here!
|
||||||
const nonScrollbarStylingHideOffset = {
|
const objectPrefferedOverflowStyle = viewportStyleObj
|
||||||
x: overlaidX ? arrangeHideOffset : _nativeScrollbarSize.x,
|
? viewportStyleObj[styleKey]
|
||||||
y: overlaidY ? arrangeHideOffset : _nativeScrollbarSize.y,
|
: overflowStyle;
|
||||||
};
|
const overflowScroll = objectPrefferedOverflowStyle === 'scroll';
|
||||||
const scrollbarsHideOffset = {
|
const nonScrollbarStylingHideOffset = isOverlaid ? arrangeHideOffset : nativeScrollbarSize;
|
||||||
x: scroll.x && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset.x : 0,
|
const scrollbarsHideOffset =
|
||||||
y: scroll.y && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset.y : 0,
|
overflowScroll && !_nativeScrollbarStyling ? nonScrollbarStylingHideOffset : 0;
|
||||||
|
const scrollbarsHideOffsetArrange = isOverlaid && !!arrangeHideOffset;
|
||||||
|
|
||||||
|
return [overflowStyle, overflowScroll, scrollbarsHideOffset, scrollbarsHideOffsetArrange] as [
|
||||||
|
overflowStyle: OverflowStyle,
|
||||||
|
overflowScroll: boolean,
|
||||||
|
scrollbarsHideOffset: number,
|
||||||
|
scrollbarsHideOffsetArrange: boolean
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [xOverflowStyle, xOverflowScroll, xScrollbarsHideOffset, xScrollbarsHideOffsetArrange] =
|
||||||
|
getStatePerAxis('overflowX', _nativeScrollbarIsOverlaid.x, _nativeScrollbarSize.x);
|
||||||
|
const [yOverflowStyle, yOverflowScroll, yScrollbarsHideOffset, yScrollbarsHideOffsetArrange] =
|
||||||
|
getStatePerAxis('overflowY', _nativeScrollbarIsOverlaid.y, _nativeScrollbarSize.y);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_overflowScroll: scroll,
|
_overflowStyle: {
|
||||||
|
x: xOverflowStyle,
|
||||||
|
y: yOverflowStyle,
|
||||||
|
},
|
||||||
|
_overflowScroll: {
|
||||||
|
x: xOverflowScroll,
|
||||||
|
y: yOverflowScroll,
|
||||||
|
},
|
||||||
|
_scrollbarsHideOffset: {
|
||||||
|
x: xScrollbarsHideOffset,
|
||||||
|
y: yScrollbarsHideOffset,
|
||||||
|
},
|
||||||
_scrollbarsHideOffsetArrange: {
|
_scrollbarsHideOffsetArrange: {
|
||||||
x: overlaidX && !!arrangeHideOffset,
|
x: xScrollbarsHideOffsetArrange,
|
||||||
y: overlaidY && !!arrangeHideOffset,
|
y: yScrollbarsHideOffsetArrange,
|
||||||
},
|
},
|
||||||
_scrollbarsHideOffset: scrollbarsHideOffset,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -416,7 +439,7 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
|||||||
let sizeFractionCache = getCurrentSizeFraction(force);
|
let sizeFractionCache = getCurrentSizeFraction(force);
|
||||||
let viewportScrollSizeCache = getCurrentViewportScrollSizeCache(force);
|
let viewportScrollSizeCache = getCurrentViewportScrollSizeCache(force);
|
||||||
let overflowAmuntCache = getCurrentOverflowAmountCache(force);
|
let overflowAmuntCache = getCurrentOverflowAmountCache(force);
|
||||||
let updateHintsReturn;
|
|
||||||
let preMeasureViewportOverflowState: ViewportOverflowState | undefined;
|
let preMeasureViewportOverflowState: ViewportOverflowState | undefined;
|
||||||
|
|
||||||
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarStyling) {
|
if (showNativeOverlaidScrollbarsChanged && _nativeScrollbarStyling) {
|
||||||
@@ -527,9 +550,6 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
|||||||
sizeFraction,
|
sizeFraction,
|
||||||
_directionIsRTL
|
_directionIsRTL
|
||||||
);
|
);
|
||||||
const [overflowScroll, overflowScrollChanged] = updateOverflowScrollCache(
|
|
||||||
viewportOverflowState._overflowScroll
|
|
||||||
);
|
|
||||||
hideNativeScrollbars(viewportOverflowState, _directionIsRTL, viewportArranged, viewportStyle);
|
hideNativeScrollbars(viewportOverflowState, _directionIsRTL, viewportArranged, viewportStyle);
|
||||||
|
|
||||||
if (adjustFlexboxGlue) {
|
if (adjustFlexboxGlue) {
|
||||||
@@ -537,23 +557,28 @@ export const createOverflowUpdate: CreateStructureUpdateSegment = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
style(_viewport, viewportStyle);
|
style(_viewport, viewportStyle);
|
||||||
|
|
||||||
setState({
|
|
||||||
_overflowScroll: overflowScroll,
|
|
||||||
_overflowAmount: overflowAmount,
|
|
||||||
_hasOverflow: hasOverflow,
|
|
||||||
});
|
|
||||||
|
|
||||||
updateHintsReturn = {
|
|
||||||
_overflowAmountChanged: overflowAmountChanged,
|
|
||||||
_overflowScrollChanged: overflowScrollChanged,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attr(_host, dataAttributeHost, removeClipping ? 'overflowVisible' : '');
|
attr(_host, dataAttributeHost, removeClipping ? 'overflowVisible' : '');
|
||||||
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
conditionalClass(_padding, classNameOverflowVisible, removeClipping);
|
||||||
conditionalClass(_viewport, classNameOverflowVisible, overflowVisible);
|
conditionalClass(_viewport, classNameOverflowVisible, overflowVisible);
|
||||||
|
|
||||||
return updateHintsReturn;
|
const [overflowStyle, overflowStyleChanged] = updateOverflowStyleCache(
|
||||||
|
getViewportOverflowState(showNativeOverlaidScrollbars)._overflowStyle
|
||||||
|
);
|
||||||
|
|
||||||
|
setState({
|
||||||
|
_overflowStyle: overflowStyle,
|
||||||
|
_overflowAmount: {
|
||||||
|
x: overflowAmount.w,
|
||||||
|
y: overflowAmount.h,
|
||||||
|
},
|
||||||
|
_hasOverflow: hasOverflow,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
_overflowStyleChanged: overflowStyleChanged,
|
||||||
|
_overflowAmountChanged: overflowAmountChanged,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
+6
-3
@@ -1,4 +1,5 @@
|
|||||||
import { style } from 'support';
|
import { style } from 'support';
|
||||||
|
import { getEnvironment } from 'environment';
|
||||||
import type { CreateStructureUpdateSegment } from 'setups/structureSetup/structureSetup.update';
|
import type { CreateStructureUpdateSegment } from 'setups/structureSetup/structureSetup.update';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,10 +15,12 @@ export const createTrinsicUpdate: CreateStructureUpdateSegment = (
|
|||||||
const [getState] = state;
|
const [getState] = state;
|
||||||
|
|
||||||
return (updateHints) => {
|
return (updateHints) => {
|
||||||
|
const { _flexboxGlue } = getEnvironment();
|
||||||
const { _heightIntrinsic } = getState();
|
const { _heightIntrinsic } = getState();
|
||||||
const { _heightIntrinsicChanged } = updateHints;
|
const { _heightIntrinsicChanged } = updateHints;
|
||||||
|
const heightIntrinsicChanged = (_content || !_flexboxGlue) && _heightIntrinsicChanged;
|
||||||
|
|
||||||
if (_heightIntrinsicChanged) {
|
if (heightIntrinsicChanged) {
|
||||||
style(_content, {
|
style(_content, {
|
||||||
height: _heightIntrinsic ? '' : '100%',
|
height: _heightIntrinsic ? '' : '100%',
|
||||||
display: _heightIntrinsic ? '' : 'inline',
|
display: _heightIntrinsic ? '' : 'inline',
|
||||||
@@ -25,8 +28,8 @@ export const createTrinsicUpdate: CreateStructureUpdateSegment = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_sizeChanged: _heightIntrinsicChanged,
|
_sizeChanged: heightIntrinsicChanged,
|
||||||
_contentMutation: _heightIntrinsicChanged,
|
_contentMutation: heightIntrinsicChanged,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ export interface OSInitializationObject extends StructureInitialization, Scrollb
|
|||||||
|
|
||||||
export type OSTarget = OSTargetElement | OSInitializationObject;
|
export type OSTarget = OSTargetElement | OSInitializationObject;
|
||||||
|
|
||||||
|
export type OverflowStyle = 'scroll' | 'hidden' | 'visible';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
export namespace OverlayScrollbars {
|
export namespace OverlayScrollbars {
|
||||||
export type ResizeBehavior = 'none' | 'both' | 'horizontal' | 'vertical';
|
export type ResizeBehavior = 'none' | 'both' | 'horizontal' | 'vertical';
|
||||||
|
|||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
import 'styles/overlayscrollbars.scss';
|
||||||
|
import './index.scss';
|
||||||
|
import should from 'should';
|
||||||
|
import { OverlayScrollbars } from 'overlayscrollbars';
|
||||||
|
|
||||||
|
import { resize } from '@/testing-browser/Resize';
|
||||||
|
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
|
||||||
|
import { addClass } from 'support';
|
||||||
|
|
||||||
|
OverlayScrollbars.env().setDefaultOptions({
|
||||||
|
nativeScrollbarsOverlaid: { initialize: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
const startBtn: HTMLButtonElement | null = document.querySelector('#start');
|
||||||
|
const targetRoot: HTMLElement | null = document.querySelector('#targetRoot');
|
||||||
|
const targetA: HTMLElement | null = document.querySelector('#targetA');
|
||||||
|
const targetB: HTMLElement | null = document.querySelector('#targetB');
|
||||||
|
const updatesRootSlot: HTMLElement | null = document.querySelector('#updatesRoot');
|
||||||
|
const updatesASlot: HTMLElement | null = document.querySelector('#updatesA');
|
||||||
|
const updatesBSlot: HTMLElement | null = document.querySelector('#updatesB');
|
||||||
|
const resizeRoot: HTMLElement | null = document.querySelector('#resizeRoot');
|
||||||
|
const resizeA: HTMLElement | null = document.querySelector('#resizeA');
|
||||||
|
const resizeB: HTMLElement | null = document.querySelector('#resizeB');
|
||||||
|
const resizeBetweenRoot: HTMLElement | null = document.createElement('div');
|
||||||
|
const resizeBetweenA: HTMLElement | null = document.createElement('div');
|
||||||
|
const resizeBetweenB: HTMLElement | null = document.createElement('div');
|
||||||
|
|
||||||
|
let rootUpdateCount = 0;
|
||||||
|
let aUpdateCount = 0;
|
||||||
|
let bUpdateCount = 0;
|
||||||
|
const osInstanceRoot = OverlayScrollbars(
|
||||||
|
targetRoot!,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
initialized() {
|
||||||
|
addClass(resizeBetweenRoot, 'resize resizeBetween');
|
||||||
|
targetRoot!.append(resizeBetweenRoot);
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
rootUpdateCount++;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (updatesRootSlot) {
|
||||||
|
updatesRootSlot.textContent = `${rootUpdateCount}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const osInstanceA = OverlayScrollbars(
|
||||||
|
targetA!,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
initialized() {
|
||||||
|
addClass(resizeBetweenA, 'resize resizeBetween');
|
||||||
|
targetA!.append(resizeBetweenA);
|
||||||
|
},
|
||||||
|
updated(args) {
|
||||||
|
console.log(args);
|
||||||
|
aUpdateCount++;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (updatesASlot) {
|
||||||
|
updatesASlot.textContent = `${aUpdateCount}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const osInstanceB = OverlayScrollbars(
|
||||||
|
targetB!,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
initialized() {
|
||||||
|
addClass(resizeBetweenB, 'resize resizeBetween');
|
||||||
|
targetB!.append(resizeBetweenB);
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
bUpdateCount++;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (updatesBSlot) {
|
||||||
|
updatesBSlot.textContent = `${bUpdateCount}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
resize(resizeRoot!);
|
||||||
|
resize(resizeA!);
|
||||||
|
resize(resizeB!);
|
||||||
|
resize(resizeBetweenRoot!);
|
||||||
|
resize(resizeBetweenA!);
|
||||||
|
resize(resizeBetweenB!);
|
||||||
|
|
||||||
|
const start = async () => {
|
||||||
|
setTestResult(null);
|
||||||
|
|
||||||
|
// target?.removeAttribute('style');
|
||||||
|
|
||||||
|
setTestResult(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
startBtn?.addEventListener('click', start);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<div id="controls">
|
||||||
|
<button id="start">start</button>
|
||||||
|
<div>UpdatesRoot: <span id="updatesRoot"></span></div>
|
||||||
|
<div>UpdatesA: <span id="updatesA"></span></div>
|
||||||
|
<div>UpdatesB:</div>
|
||||||
|
</div>
|
||||||
|
<div id="stage">
|
||||||
|
<div>
|
||||||
|
<div id="targetRoot" class="container">
|
||||||
|
<div id="targetA" class="container">
|
||||||
|
<div id="targetB" class="container">
|
||||||
|
<div id="resizeB" class="resize">B <span id="updatesB"></span></div>
|
||||||
|
</div>
|
||||||
|
<div id="resizeA" class="resize">A</div>
|
||||||
|
</div>
|
||||||
|
<div id="resizeRoot" class="resize">Root</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
#controls {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
#stage {
|
||||||
|
flex: auto;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
background: lightgoldenrodyellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
border: 1px solid red;
|
||||||
|
width: 60%;
|
||||||
|
height: 60%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize {
|
||||||
|
overflow: hidden;
|
||||||
|
background: lime;
|
||||||
|
border: 1px solid green;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizer {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizeBetween {
|
||||||
|
background: tomato;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizeBtn {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
background: blue;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#targetRoot {
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
+1
-1
@@ -4,7 +4,7 @@ import { test, Page } from '@playwright/test';
|
|||||||
|
|
||||||
playwrightRollup();
|
playwrightRollup();
|
||||||
|
|
||||||
test.describe('StructureLifecycle', () => {
|
test.describe('StructureSetup.update', () => {
|
||||||
[false, true].forEach(async (nativeScrollbarStyling) => {
|
[false, true].forEach(async (nativeScrollbarStyling) => {
|
||||||
const withText = nativeScrollbarStyling ? 'with' : 'without';
|
const withText = nativeScrollbarStyling ? 'with' : 'without';
|
||||||
const nss = async (page: Page) => {
|
const nss = async (page: Page) => {
|
||||||
+32
-16
@@ -155,14 +155,14 @@ const getMetrics = (elm: HTMLElement): Metrics => {
|
|||||||
},
|
},
|
||||||
scroll: elmIsTarget
|
scroll: elmIsTarget
|
||||||
? {
|
? {
|
||||||
width: Math.round(osInstance.state()._overflowAmount.w),
|
width: Math.round(osInstance.state().overflowAmount.x),
|
||||||
height: Math.round(osInstance.state()._overflowAmount.h),
|
height: Math.round(osInstance.state().overflowAmount.y),
|
||||||
}
|
}
|
||||||
: scrollMeasure(),
|
: scrollMeasure(),
|
||||||
hasOverflow: elmIsTarget
|
hasOverflow: elmIsTarget
|
||||||
? {
|
? {
|
||||||
x: osInstance.state()._overflowAmount.w > 0,
|
x: osInstance.state().hasOverflow.x,
|
||||||
y: osInstance.state()._overflowAmount.h > 0,
|
y: osInstance.state().hasOverflow.y,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
x: scrollMeasure().width > 0,
|
x: scrollMeasure().width > 0,
|
||||||
@@ -274,12 +274,12 @@ const checkMetrics = async (checkComparison: CheckComparisonObj) => {
|
|||||||
should.equal(
|
should.equal(
|
||||||
targetMetrics.scroll.width,
|
targetMetrics.scroll.width,
|
||||||
comparisonMetrics.scroll.width,
|
comparisonMetrics.scroll.width,
|
||||||
`Scroll width equality. (${osInstance.state()._overflowAmount.w})`
|
`Scroll width equality. (${osInstance.state().overflowAmount.x})`
|
||||||
);
|
);
|
||||||
should.equal(
|
should.equal(
|
||||||
targetMetrics.scroll.height,
|
targetMetrics.scroll.height,
|
||||||
comparisonMetrics.scroll.height,
|
comparisonMetrics.scroll.height,
|
||||||
`Scroll height equality. (${osInstance.state()._overflowAmount.h})`
|
`Scroll height equality. (${osInstance.state().overflowAmount.y})`
|
||||||
);
|
);
|
||||||
|
|
||||||
should.equal(
|
should.equal(
|
||||||
@@ -295,24 +295,24 @@ const checkMetrics = async (checkComparison: CheckComparisonObj) => {
|
|||||||
|
|
||||||
if (targetMetrics.hasOverflow.x) {
|
if (targetMetrics.hasOverflow.x) {
|
||||||
should.ok(
|
should.ok(
|
||||||
osInstance.state()._overflowAmount.w > 0,
|
osInstance.state().overflowAmount.x > 0,
|
||||||
'Overflow amount width should be > 0 with overflow.'
|
'Overflow amount width should be > 0 with overflow.'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
should.equal(
|
should.equal(
|
||||||
osInstance.state()._overflowAmount.w,
|
osInstance.state().overflowAmount.x,
|
||||||
0,
|
0,
|
||||||
'Overflow amount width should be 0 without overflow.'
|
'Overflow amount width should be 0 without overflow.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (targetMetrics.hasOverflow.y) {
|
if (targetMetrics.hasOverflow.y) {
|
||||||
should.ok(
|
should.ok(
|
||||||
osInstance.state()._overflowAmount.h > 0,
|
osInstance.state().overflowAmount.y > 0,
|
||||||
'Overflow amount height should be > 0 with overflow.'
|
'Overflow amount height should be > 0 with overflow.'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
should.equal(
|
should.equal(
|
||||||
osInstance.state()._overflowAmount.h,
|
osInstance.state().overflowAmount.y,
|
||||||
0,
|
0,
|
||||||
'Overflow amount height should be 0 without overflow.'
|
'Overflow amount height should be 0 without overflow.'
|
||||||
);
|
);
|
||||||
@@ -414,6 +414,17 @@ const checkMetrics = async (checkComparison: CheckComparisonObj) => {
|
|||||||
should.notEqual(viewportOverflowYStyle, 'scroll', 'No Overflow-Y shouldnt result in scroll.');
|
should.notEqual(viewportOverflowYStyle, 'scroll', 'No Overflow-Y shouldnt result in scroll.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
should.equal(
|
||||||
|
osInstance.state().overflowStyle.x,
|
||||||
|
viewportOverflowXStyle,
|
||||||
|
'Overflow-X Style: State and style should match.'
|
||||||
|
);
|
||||||
|
should.equal(
|
||||||
|
osInstance.state().overflowStyle.y,
|
||||||
|
viewportOverflowYStyle,
|
||||||
|
'Overflow-Y Style: State and style should match.'
|
||||||
|
);
|
||||||
|
|
||||||
// ==== check host & padding overflow style:
|
// ==== check host & padding overflow style:
|
||||||
|
|
||||||
if (!targetMetrics.hasOverflow.x && !targetMetrics.hasOverflow.y) {
|
if (!targetMetrics.hasOverflow.x && !targetMetrics.hasOverflow.y) {
|
||||||
@@ -712,18 +723,23 @@ const start = async () => {
|
|||||||
setTestResult(null);
|
setTestResult(null);
|
||||||
|
|
||||||
target?.removeAttribute('style');
|
target?.removeAttribute('style');
|
||||||
await overflowTest();
|
|
||||||
|
|
||||||
await overflowTest({ overflow: { x: 'hidden', y: 'scroll' } });
|
const start = performance.now();
|
||||||
await overflowTest({ overflow: { x: 'scroll', y: 'hidden' } });
|
console.log(start);
|
||||||
await overflowTest({ overflow: { x: 'visible', y: 'scroll' } });
|
await overflowTest();
|
||||||
await overflowTest({ overflow: { x: 'scroll', y: 'visible' } });
|
|
||||||
await overflowTest({ overflow: { x: 'visible', y: 'visible' } });
|
await overflowTest({ overflow: { x: 'visible', y: 'visible' } });
|
||||||
await overflowTest({ overflow: { x: 'visible-scroll', y: 'visible-hidden' } });
|
await overflowTest({ overflow: { x: 'visible-scroll', y: 'visible-hidden' } });
|
||||||
await overflowTest({ overflow: { x: 'visible-hidden', y: 'hidden' } });
|
await overflowTest({ overflow: { x: 'visible-hidden', y: 'hidden' } });
|
||||||
await overflowTest({ overflow: { x: 'visible', y: 'visible-scroll' } });
|
await overflowTest({ overflow: { x: 'visible', y: 'visible-scroll' } });
|
||||||
await overflowTest({ overflow: { x: 'scroll', y: 'visible-scroll' } });
|
await overflowTest({ overflow: { x: 'scroll', y: 'visible-scroll' } });
|
||||||
|
await overflowTest({ overflow: { x: 'hidden', y: 'scroll' } });
|
||||||
|
await overflowTest({ overflow: { x: 'scroll', y: 'hidden' } });
|
||||||
|
await overflowTest({ overflow: { x: 'visible', y: 'scroll' } });
|
||||||
|
await overflowTest({ overflow: { x: 'scroll', y: 'visible' } });
|
||||||
|
await overflowTest({ overflow: { x: 'visible', y: 'hidden' } });
|
||||||
|
await overflowTest({ overflow: { x: 'hidden', y: 'visible' } });
|
||||||
|
const end = performance.now();
|
||||||
|
console.log(start - end);
|
||||||
setTestResult(true);
|
setTestResult(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
import { playwrightRollup, expectSuccess } from '@/playwright/rollup';
|
||||||
|
import { test, Page } from '@playwright/test';
|
||||||
|
|
||||||
|
playwrightRollup();
|
||||||
|
|
||||||
|
test.describe('StructureSetup.update', () => {
|
||||||
|
[false, true].forEach(async (nativeScrollbarStyling) => {
|
||||||
|
const withText = nativeScrollbarStyling ? 'with' : 'without';
|
||||||
|
const nss = async (page: Page) => {
|
||||||
|
if (!nativeScrollbarStyling) {
|
||||||
|
await page.click('#nss');
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test.describe(`${withText} native scrollbar styling`, () => {
|
||||||
|
test.describe.configure({ mode: 'parallel' });
|
||||||
|
|
||||||
|
test('default', async ({ page }) => {
|
||||||
|
await nss(page);
|
||||||
|
await page.click('#start');
|
||||||
|
await expectSuccess(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('without flexbox glue & css custom props', async ({ page }) => {
|
||||||
|
await nss(page);
|
||||||
|
await page.click('#fbg');
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
await page.click('#ccp');
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
await page.click('#start');
|
||||||
|
await expectSuccess(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('with partially overlaid scrollbars', async ({ page, browserName }) => {
|
||||||
|
test.skip(
|
||||||
|
browserName === 'firefox' || browserName === 'webkit',
|
||||||
|
"firefox can't simulate partially overlaid scrollbars, boost speed by omitting webkit"
|
||||||
|
);
|
||||||
|
|
||||||
|
await nss(page);
|
||||||
|
await page.click('#po');
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
await page.click('#start');
|
||||||
|
await expectSuccess(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('with fully overlaid scrollbars', async ({ page }) => {
|
||||||
|
await nss(page);
|
||||||
|
await page.click('#fo');
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
await page.click('#start');
|
||||||
|
await expectSuccess(page);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
+85
-28
@@ -41,6 +41,27 @@ interface ScrollbarsInitialization {
|
|||||||
interface OSInitializationObject extends StructureInitialization, ScrollbarsInitialization {
|
interface OSInitializationObject extends StructureInitialization, ScrollbarsInitialization {
|
||||||
}
|
}
|
||||||
type OSTarget = OSTargetElement | OSInitializationObject;
|
type OSTarget = OSTargetElement | OSInitializationObject;
|
||||||
|
type OverflowStyle = "scroll" | "hidden" | "visible";
|
||||||
|
interface TRBL {
|
||||||
|
t: number;
|
||||||
|
r: number;
|
||||||
|
b: number;
|
||||||
|
l: number;
|
||||||
|
}
|
||||||
|
interface XY<T> {
|
||||||
|
x: T;
|
||||||
|
y: T;
|
||||||
|
}
|
||||||
|
type EventListener<NameArgsMap extends Record<string, any>, Name extends Extract<keyof NameArgsMap, string>> = (...args: NameArgsMap[Name] extends undefined ? [
|
||||||
|
] : [
|
||||||
|
args: NameArgsMap[Name]
|
||||||
|
]) => void;
|
||||||
|
type EventListenerGroup<NameArgsMap extends Record<string, any>, Name extends Extract<keyof NameArgsMap, string>> = EventListener<NameArgsMap, Name> | EventListener<NameArgsMap, Name>[];
|
||||||
|
type AddEventListener<NameArgsMap extends Record<string, any>> = <Name extends Extract<keyof NameArgsMap, string>>(name: Name, listener: EventListenerGroup<NameArgsMap, Name>) => () => void;
|
||||||
|
type RemoveEventListener<NameArgsMap extends Record<string, any>> = <Name extends Extract<keyof NameArgsMap, string>>(name?: Name, listener?: EventListenerGroup<NameArgsMap, Name>) => void;
|
||||||
|
type InitialEventListeners<NameArgsMap extends Record<string, any>> = {
|
||||||
|
[K in Extract<keyof NameArgsMap, string>]?: EventListenerGroup<NameArgsMap, K>;
|
||||||
|
};
|
||||||
type ResizeBehavior = "none" | "both" | "horizontal" | "vertical";
|
type ResizeBehavior = "none" | "both" | "horizontal" | "vertical";
|
||||||
type OverflowBehavior = "hidden" | "scroll" | "visible" | "visible-hidden" | "visible-scroll";
|
type OverflowBehavior = "hidden" | "scroll" | "visible" | "visible-hidden" | "visible-scroll";
|
||||||
type VisibilityBehavior = "visible" | "hidden" | "auto";
|
type VisibilityBehavior = "visible" | "hidden" | "auto";
|
||||||
@@ -84,25 +105,43 @@ interface OSOptions {
|
|||||||
onUpdated: (() => any) | null;
|
onUpdated: (() => any) | null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
type StructureInitializationStrategyElementFn<T> = ((target: OSTargetElement) => HTMLElement | T) | T;
|
||||||
|
type ScrollbarsInitializationStrategyElementFn<T> = ((target: OSTargetElement, host: HTMLElement, viewport: HTMLElement) => HTMLElement | T) | T;
|
||||||
|
/**
|
||||||
|
* A Static element is an element which MUST be generated.
|
||||||
|
* If null or undefined (or the returned result is null or undefined), the initialization function is generatig the element, otherwise
|
||||||
|
* the element returned by the function acts as the generated element.
|
||||||
|
*/
|
||||||
|
type StructureInitializationStrategyStaticElement = StructureInitializationStrategyElementFn<null | undefined>;
|
||||||
|
/**
|
||||||
|
* A Dynamic element is an element which CAN be generated.
|
||||||
|
* If boolean (or the returned result is boolean), the generation of the element is forced (or not).
|
||||||
|
* If the function returns and element, the element returned by the function acts as the generated element.
|
||||||
|
*/
|
||||||
|
type StructureInitializationStrategyDynamicElement = StructureInitializationStrategyElementFn<boolean>;
|
||||||
|
interface StructureInitializationStrategy {
|
||||||
|
_host: StructureInitializationStrategyStaticElement;
|
||||||
|
_viewport: StructureInitializationStrategyStaticElement;
|
||||||
|
_padding: StructureInitializationStrategyDynamicElement;
|
||||||
|
_content: StructureInitializationStrategyDynamicElement;
|
||||||
|
}
|
||||||
|
interface ScrollbarsInitializationStrategy {
|
||||||
|
/**
|
||||||
|
* The scrollbars slot. If null or undefined (or the returned result is null or undefined), the initialization function is deciding the element, otherwise
|
||||||
|
* the element returned by the function acts as the scrollbars slot.
|
||||||
|
*/
|
||||||
|
_scrollbarsSlot: ScrollbarsInitializationStrategyElementFn<null | undefined>;
|
||||||
|
}
|
||||||
|
interface InitializationStrategy extends StructureInitializationStrategy, ScrollbarsInitializationStrategy {
|
||||||
|
}
|
||||||
|
type DefaultInitializationStrategy = {
|
||||||
|
[K in keyof InitializationStrategy]: Extract<InitializationStrategy[K], boolean | null | undefined>;
|
||||||
|
};
|
||||||
type OSPluginInstance = Record<string, unknown> | ((staticObj: OverlayScrollbarsStatic, instanceObj: OverlayScrollbars) => void);
|
type OSPluginInstance = Record<string, unknown> | ((staticObj: OverlayScrollbarsStatic, instanceObj: OverlayScrollbars) => void);
|
||||||
type OSPlugin<T extends OSPluginInstance> = [
|
type OSPlugin<T extends OSPluginInstance> = [
|
||||||
string,
|
string,
|
||||||
T
|
T
|
||||||
];
|
];
|
||||||
interface XY<T> {
|
|
||||||
x: T;
|
|
||||||
y: T;
|
|
||||||
}
|
|
||||||
type EventListener<NameArgsMap extends Record<string, any>, Name extends Extract<keyof NameArgsMap, string>> = (...args: NameArgsMap[Name] extends undefined ? [
|
|
||||||
] : [
|
|
||||||
args: NameArgsMap[Name]
|
|
||||||
]) => void;
|
|
||||||
type EventListenerGroup<NameArgsMap extends Record<string, any>, Name extends Extract<keyof NameArgsMap, string>> = EventListener<NameArgsMap, Name> | EventListener<NameArgsMap, Name>[];
|
|
||||||
type AddEventListener<NameArgsMap extends Record<string, any>> = <Name extends Extract<keyof NameArgsMap, string>>(name: Name, listener: EventListenerGroup<NameArgsMap, Name>) => () => void;
|
|
||||||
type RemoveEventListener<NameArgsMap extends Record<string, any>> = <Name extends Extract<keyof NameArgsMap, string>>(name?: Name, listener?: EventListenerGroup<NameArgsMap, Name>) => void;
|
|
||||||
type InitialEventListeners<NameArgsMap extends Record<string, any>> = {
|
|
||||||
[K in Extract<keyof NameArgsMap, string>]?: EventListenerGroup<NameArgsMap, K>;
|
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
onScrollStart : null,
|
onScrollStart : null,
|
||||||
onScroll : null,
|
onScroll : null,
|
||||||
@@ -119,27 +158,16 @@ interface OnUpdatedEventListenerArgs {
|
|||||||
directionChanged: boolean;
|
directionChanged: boolean;
|
||||||
heightIntrinsicChanged: boolean;
|
heightIntrinsicChanged: boolean;
|
||||||
overflowAmountChanged: boolean;
|
overflowAmountChanged: boolean;
|
||||||
overflowScrollChanged: boolean;
|
overflowStyleChanged: boolean;
|
||||||
hostMutation: boolean;
|
hostMutation: boolean;
|
||||||
contentMutation: boolean;
|
contentMutation: boolean;
|
||||||
};
|
};
|
||||||
changedOptions: PartialOptions<OSOptions>;
|
changedOptions: PartialOptions<OSOptions>;
|
||||||
force: boolean;
|
force: boolean;
|
||||||
}
|
}
|
||||||
interface OnOverflowChangedEventListenerArgs {
|
|
||||||
overflow: XY<boolean>; // whether there is an overflow
|
|
||||||
scrollableOverflow: XY<boolean>; // whether there is an scrollable overflow
|
|
||||||
amount: XY<number>; // the overflow amount in pixel
|
|
||||||
previous: {
|
|
||||||
overflow: XY<boolean>;
|
|
||||||
scrollableOverflow: XY<boolean>;
|
|
||||||
amount: XY<number>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
interface OSEventListenersNameArgsMap {
|
interface OSEventListenersNameArgsMap {
|
||||||
initialized: undefined;
|
initialized: undefined;
|
||||||
initializationWithdrawn: undefined;
|
initializationWithdrawn: undefined;
|
||||||
overflowChanged: OnOverflowChangedEventListenerArgs;
|
|
||||||
updated: OnUpdatedEventListenerArgs;
|
updated: OnUpdatedEventListenerArgs;
|
||||||
destroyed: undefined;
|
destroyed: undefined;
|
||||||
}
|
}
|
||||||
@@ -148,16 +176,45 @@ type RemoveOSEventListener = RemoveEventListener<OSEventListenersNameArgsMap>;
|
|||||||
type InitialOSEventListeners = InitialEventListeners<OSEventListenersNameArgsMap>;
|
type InitialOSEventListeners = InitialEventListeners<OSEventListenersNameArgsMap>;
|
||||||
interface OverlayScrollbarsStatic {
|
interface OverlayScrollbarsStatic {
|
||||||
(target: OSTarget | OSInitializationObject, options?: PartialOptions<OSOptions>, eventListeners?: InitialOSEventListeners): OverlayScrollbars;
|
(target: OSTarget | OSInitializationObject, options?: PartialOptions<OSOptions>, eventListeners?: InitialOSEventListeners): OverlayScrollbars;
|
||||||
extend(osPlugin: OSPlugin | OSPlugin[]): void;
|
plugin(osPlugin: OSPlugin | OSPlugin[]): void;
|
||||||
|
env(): OverlayScrollbarsEnv;
|
||||||
|
}
|
||||||
|
interface OverlayScrollbarsEnv {
|
||||||
|
scrollbarSize: XY<number>;
|
||||||
|
scrollbarIsOverlaid: XY<boolean>;
|
||||||
|
scrollbarStyling: boolean;
|
||||||
|
rtlScrollBehavior: {
|
||||||
|
n: boolean;
|
||||||
|
i: boolean;
|
||||||
|
};
|
||||||
|
flexboxGlue: boolean;
|
||||||
|
cssCustomProperties: boolean;
|
||||||
|
defaultInitializationStrategy: DefaultInitializationStrategy;
|
||||||
|
defaultDefaultOptions: OSOptions;
|
||||||
|
getInitializationStrategy(): InitializationStrategy;
|
||||||
|
setInitializationStrategy(newInitializationStrategy: Partial<InitializationStrategy>): void;
|
||||||
|
getDefaultOptions(): OSOptions;
|
||||||
|
setDefaultOptions(newDefaultOptions: PartialOptions<OSOptions>): void;
|
||||||
|
}
|
||||||
|
interface OverlayScrollbarsState {
|
||||||
|
padding: TRBL;
|
||||||
|
paddingAbsolute: boolean;
|
||||||
|
overflowAmount: XY<number>;
|
||||||
|
overflowStyle: XY<OverflowStyle>;
|
||||||
|
hasOverflow: XY<boolean>;
|
||||||
}
|
}
|
||||||
interface OverlayScrollbars {
|
interface OverlayScrollbars {
|
||||||
options(): OSOptions;
|
options(): OSOptions;
|
||||||
options(newOptions?: PartialOptions<OSOptions>): OSOptions;
|
options(newOptions?: PartialOptions<OSOptions>): OSOptions;
|
||||||
update(force?: boolean): void;
|
update(force?: boolean): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
state(): any;
|
state(): OverlayScrollbarsState;
|
||||||
on: AddOSEventListener;
|
on: AddOSEventListener;
|
||||||
off: RemoveOSEventListener;
|
off: RemoveOSEventListener;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Notes:
|
||||||
|
* Height intrinsic detection use "content: true" init strategy - or open ticket for custom height intrinsic observer
|
||||||
|
*/
|
||||||
declare const OverlayScrollbars: OverlayScrollbarsStatic;
|
declare const OverlayScrollbars: OverlayScrollbarsStatic;
|
||||||
export { OverlayScrollbars as default };
|
export { OverlayScrollbars as default };
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const { devices } = require('@playwright/test');
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
testMatch: /.*\/tests\/playwright\/.*\.test\.[jt]sx?/,
|
testMatch: /.*\/tests\/playwright\/.*\.test\.[jt]sx?/,
|
||||||
timeout: 5 * 60 * 1000,
|
timeout: 8 * 60 * 1000,
|
||||||
actionTimeout: 300,
|
actionTimeout: 300,
|
||||||
navigationTimeout: 1000,
|
navigationTimeout: 1000,
|
||||||
retries: 0,
|
retries: 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user