overflowChanged event listener

This commit is contained in:
Rene Haas
2022-06-24 16:48:40 +02:00
parent 0413be4b4a
commit 06bbfe18f9
13 changed files with 384 additions and 246 deletions
+118 -100
View File
@@ -471,6 +471,7 @@ const equal = (a, b, props, propMutation) => {
return false;
};
const equalWH = (a, b) => equal(a, b, ['w', 'h']);
const equalXY = (a, b) => equal(a, b, ['x', 'y']);
const equalTRBL = (a, b) => equal(a, b, ['t', 'r', 'b', 'l']);
const equalBCRWH = (a, b, round) => equal(a, b, ['width', 'height'], round && (value => Math.round(value)));
@@ -1288,18 +1289,9 @@ const createSizeObserver = (target, onSizeChangedCallback, options) => {
}
prependChildren(target, sizeObserver);
return {
_destroy() {
runEach(offListeners);
removeElements(sizeObserver);
},
_getCurrentCacheValues(force) {
return {
_directionIsRTL: directionIsRTLCache ? directionIsRTLCache[1](force) : [false, false, false]
};
}
return () => {
runEach(offListeners);
removeElements(sizeObserver);
};
};
@@ -1308,7 +1300,7 @@ const isHeightIntrinsic = ioEntryOrSize => ioEntryOrSize.h === 0 || ioEntryOrSiz
const createTrinsicObserver = (target, onTrinsicChangedCallback) => {
const trinsicObserver = createDiv(classNameTrinsicObserver);
const offListeners = [];
const [updateHeightIntrinsicCache, getCurrentHeightIntrinsicCache] = createCache({
const [updateHeightIntrinsicCache] = createCache({
_initialValue: false
});
@@ -1341,23 +1333,14 @@ const createTrinsicObserver = (target, onTrinsicChangedCallback) => {
triggerOnTrinsicChangedCallback(newSize);
};
push(offListeners, createSizeObserver(trinsicObserver, onSizeChanged)._destroy);
push(offListeners, createSizeObserver(trinsicObserver, onSizeChanged));
onSizeChanged();
}
prependChildren(target, trinsicObserver);
return {
_destroy() {
runEach(offListeners);
removeElements(trinsicObserver);
},
_getCurrentCacheValues(force) {
return {
_heightIntrinsic: getCurrentHeightIntrinsicCache(force)
};
}
return () => {
runEach(offListeners);
removeElements(trinsicObserver);
};
};
@@ -1640,8 +1623,8 @@ const lifecycleHubOservers = (instance, updateLifecycles) => {
}
};
const trinsicObserver = (_content || !_flexboxGlue) && createTrinsicObserver(_host, onTrinsicChanged);
const sizeObserver = createSizeObserver(_host, onSizeChanged, {
const destroyTrinsicObserver = (_content || !_flexboxGlue) && createTrinsicObserver(_host, onTrinsicChanged);
const destroySizeObserver = createSizeObserver(_host, onSizeChanged, {
_appear: true,
_direction: !_nativeScrollbarStyling
});
@@ -1691,21 +1674,13 @@ const lifecycleHubOservers = (instance, updateLifecycles) => {
};
updateViewportAttrsFromHost();
return {
_trinsicObserver: trinsicObserver,
_sizeObserver: sizeObserver,
_updateObserverOptions: updateOptions,
return [updateOptions, () => {
contentMutationObserver && contentMutationObserver._destroy();
destroyTrinsicObserver && destroyTrinsicObserver();
destroySizeObserver();
_destroy() {
contentMutationObserver && contentMutationObserver._destroy();
trinsicObserver && trinsicObserver._destroy();
sizeObserver._destroy();
hostMutationObserver._destroy();
}
};
hostMutationObserver._destroy();
}];
};
const createTrinsicLifecycle = lifecycleHub => {
@@ -1820,6 +1795,13 @@ const whCacheOptions = {
h: 0
}
};
const xyCacheOptions = {
_equal: equalXY,
_initialValue: {
x: false,
y: false
}
};
const sizeFraction = elm => {
const viewportOffsetSize = offsetSize(elm);
@@ -1873,6 +1855,7 @@ const createOverflowLifecycle = lifecycleHub => {
const [updateViewportSizeFraction, getCurrentViewportSizeFraction] = createCache(whCacheOptions, sizeFraction.bind(0, _viewport));
const [updateViewportScrollSizeCache, getCurrentViewportScrollSizeCache] = createCache(whCacheOptions, scrollSize.bind(0, _viewport));
const [updateOverflowAmountCache, getCurrentOverflowAmountCache] = createCache(whCacheOptions);
const [updateOverflowScrollCache] = createCache(xyCacheOptions);
const fixFlexboxGlue = (viewportOverflowState, heightIntrinsic) => {
style(_viewport, {
@@ -2189,8 +2172,8 @@ const createOverflowLifecycle = lifecycleHub => {
style(_viewport, viewportStyle);
_setLifecycleCommunication({
_viewportOverflowScroll: viewportOverflowState._overflowScroll,
_viewportOverflowAmount: overflowAmount
_viewportOverflowScrollCache: updateOverflowScrollCache(viewportOverflowState._overflowScroll),
_viewportOverflowAmountCache: overflowAmuntCache
});
}
};
@@ -2198,6 +2181,8 @@ const createOverflowLifecycle = lifecycleHub => {
const getPropByPath = (obj, path) => obj ? path.split('.').reduce((o, prop) => o && hasOwnProperty(o, prop) ? o[prop] : undefined, obj) : undefined;
const applyForceToCache = (cacheValues, force) => [cacheValues[0], force || cacheValues[1], cacheValues[2]];
const booleanCacheValuesFallback = [false, false, false];
const lifecycleCommunicationFallback = {
_paddingInfo: {
@@ -2209,14 +2194,14 @@ const lifecycleCommunicationFallback = {
l: 0
}
},
_viewportOverflowScroll: {
_viewportOverflowScrollCache: [{
x: false,
y: false
},
_viewportOverflowAmount: {
}, false],
_viewportOverflowAmountCache: [{
w: 0,
h: 0
},
}, false],
_viewportPaddingStyle: {
marginRight: 0,
marginBottom: 0,
@@ -2227,8 +2212,35 @@ const lifecycleCommunicationFallback = {
paddingLeft: 0
}
};
const createLifecycleHub = (options, triggerEvent, structureSetup, scrollbarsSetup) => {
const prepareUpdateHints = (leading, adaptive, force) => {
const result = {};
const finalAdaptive = adaptive || {};
const objKeys = keys(leading).concat(keys(finalAdaptive));
each(objKeys, key => {
const leadingValue = leading[key];
const adaptiveValue = finalAdaptive[key];
result[key] = isBoolean(leadingValue) ? !!force || !!leadingValue || !!adaptiveValue : applyForceToCache(leadingValue || booleanCacheValuesFallback, force);
});
return result;
};
const createOverflowChangedArgs = (overflowAmount, overflowScroll) => ({
amount: {
x: overflowAmount.w,
y: overflowAmount.h
},
overflow: {
x: overflowAmount.w > 0,
y: overflowAmount.h > 0
},
scrollableOverflow: assignDeep({}, overflowScroll)
});
const createLifecycleHub = (options, triggerListener, structureSetup, scrollbarsSetup) => {
let lifecycleCommunication = lifecycleCommunicationFallback;
let updateObserverOptions;
let destroyObservers;
const {
_viewport
} = structureSetup._targetObj;
@@ -2254,16 +2266,14 @@ const createLifecycleHub = (options, triggerEvent, structureSetup, scrollbarsSet
const lifecycles = [createTrinsicLifecycle(instance), createPaddingLifecycle(instance), createOverflowLifecycle(instance)];
const updateLifecycles = (updateHints, changedOptions, force) => {
let {
_directionIsRTL,
_heightIntrinsic,
_sizeChanged = force || false,
_hostMutation = force || false,
_contentMutation = force || false,
_paddingStyleChanged = force || false
} = updateHints || {};
const finalDirectionIsRTL = _directionIsRTL || (_sizeObserver ? _sizeObserver._getCurrentCacheValues(force)._directionIsRTL : booleanCacheValuesFallback);
const finalHeightIntrinsic = _heightIntrinsic || (_trinsicObserver ? _trinsicObserver._getCurrentCacheValues(force)._heightIntrinsic : booleanCacheValuesFallback);
const initialUpdateHints = prepareUpdateHints(assignDeep({
_sizeChanged: false,
_hostMutation: false,
_contentMutation: false,
_paddingStyleChanged: false,
_directionIsRTL: booleanCacheValuesFallback,
_heightIntrinsic: booleanCacheValuesFallback
}, updateHints), {}, force);
const checkOption = path => [getPropByPath(options, path), force || getPropByPath(changedOptions, path) !== undefined];
@@ -2271,28 +2281,13 @@ const createLifecycleHub = (options, triggerEvent, structureSetup, scrollbarsSet
const scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
const scrollOffsetY = adjustScrollOffset && scrollTop(_viewport);
if (_updateObserverOptions) {
_updateObserverOptions(checkOption);
if (updateObserverOptions) {
updateObserverOptions(checkOption);
}
let adaptivedUpdateHints = initialUpdateHints;
each(lifecycles, lifecycle => {
const {
_sizeChanged: adaptiveSizeChanged,
_hostMutation: adaptiveHostMutation,
_contentMutation: adaptiveContentMutation,
_paddingStyleChanged: adaptivePaddingStyleChanged
} = lifecycle({
_directionIsRTL: finalDirectionIsRTL,
_heightIntrinsic: finalHeightIntrinsic,
_sizeChanged,
_hostMutation,
_contentMutation,
_paddingStyleChanged
}, checkOption, !!force) || {};
_sizeChanged = adaptiveSizeChanged || _sizeChanged;
_hostMutation = adaptiveHostMutation || _hostMutation;
_contentMutation = adaptiveContentMutation || _contentMutation;
_paddingStyleChanged = adaptivePaddingStyleChanged || _paddingStyleChanged;
adaptivedUpdateHints = prepareUpdateHints(adaptivedUpdateHints, lifecycle(adaptivedUpdateHints, checkOption, !!force) || {}, force);
});
if (isNumber(scrollOffsetX)) {
@@ -2303,35 +2298,42 @@ const createLifecycleHub = (options, triggerEvent, structureSetup, scrollbarsSet
scrollTop(_viewport, scrollOffsetY);
}
triggerEvent('updated', {
const {
_viewportOverflowAmountCache: overflowAmountCache,
_viewportOverflowScrollCache: overflowScrollCache
} = lifecycleCommunication;
const [overflowAmount, overflowAmountChanged, prevOverflowAmount] = overflowAmountCache;
const [overflowScroll, overflowScrollChanged, prevOverflowScroll] = overflowScrollCache;
if (overflowAmountChanged || overflowScrollChanged) {
triggerListener('overflowChanged', assignDeep({}, createOverflowChangedArgs(overflowAmount, overflowScroll), {
previous: createOverflowChangedArgs(prevOverflowAmount, prevOverflowScroll)
}));
}
triggerListener('updated', {
updateHints: {
sizeChanged: _sizeChanged,
contentMutation: _contentMutation,
hostMutation: _hostMutation,
directionChanged: finalDirectionIsRTL[1],
heightIntrinsicChanged: finalHeightIntrinsic[1]
sizeChanged: adaptivedUpdateHints._sizeChanged,
contentMutation: adaptivedUpdateHints._contentMutation,
hostMutation: adaptivedUpdateHints._hostMutation,
directionChanged: adaptivedUpdateHints._directionIsRTL[1],
heightIntrinsicChanged: adaptivedUpdateHints._heightIntrinsic[1]
},
changedOptions: changedOptions || {},
force: !!force
});
};
const {
_sizeObserver,
_trinsicObserver,
_updateObserverOptions,
_destroy: destroyObservers
} = lifecycleHubOservers(instance, updateLifecycles);
[updateObserverOptions, destroyObservers] = lifecycleHubOservers(instance, updateLifecycles);
const update = (changedOptions, force) => updateLifecycles({}, changedOptions, force);
const envUpdateListener = update.bind(0, {}, true);
addEnvironmentListener(envUpdateListener);
console.log(getEnvironment());
return {
_update: update,
_state: () => ({
_overflowAmount: lifecycleCommunication._viewportOverflowAmount
_overflowAmount: lifecycleCommunication._viewportOverflowAmountCache[0]
}),
_destroy() {
@@ -2417,7 +2419,7 @@ const manageListener = (callback, listener) => {
each(isArray(listener) ? listener : [listener], callback);
};
const createEventHub = () => {
const createEventListenerHub = initialEventListeners => {
const events = new Map();
const removeEvent = (name, listener) => {
@@ -2448,14 +2450,27 @@ const createEventHub = () => {
const triggerEvent = (name, args) => {
const eventSet = events.get(name);
each(from(eventSet), event => {
event(args);
if (args) {
event(args);
} else {
event();
}
});
};
const initialListenerKeys = keys(initialEventListeners);
each(initialListenerKeys, key => {
addEvent(key, initialEventListeners[key]);
});
return [addEvent, removeEvent, triggerEvent];
};
const OverlayScrollbars = (target, options) => {
const OverlayScrollbars = (target, options, eventListeners) => {
const {
_getDefaultOptions,
_nativeScrollbarIsOverlaid
} = getEnvironment();
const plugins = getPlugins();
const instanceTarget = isHTMLElement(target) ? target : target.target;
const potentialInstance = getInstance(instanceTarget);
@@ -2463,10 +2478,6 @@ const OverlayScrollbars = (target, options) => {
return potentialInstance;
}
const {
_getDefaultOptions
} = getEnvironment();
const plugins = getPlugins();
const optionsValidationPlugin = plugins[optionsValidationPluginName];
const validateOptions = newOptions => {
@@ -2475,8 +2486,13 @@ const OverlayScrollbars = (target, options) => {
return validate ? validate(opts, true) : opts;
};
const [addEvent, removeEvent, triggerEvent] = createEventHub();
const currentOptions = assignDeep({}, _getDefaultOptions(), validateOptions(options));
const [addEvent, removeEvent, triggerEvent] = createEventListenerHub(eventListeners);
if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !currentOptions.nativeScrollbarsOverlaid.initialize) {
triggerEvent('initializationWithdrawn', false);
}
const structureSetup = createStructureSetup(target);
const scrollbarsSetup = createScrollbarsSetup(target, structureSetup);
const lifecycleHub = createLifecycleHub(currentOptions, triggerEvent, structureSetup, scrollbarsSetup);
@@ -2508,6 +2524,7 @@ const OverlayScrollbars = (target, options) => {
removeInstance(instanceTarget);
removeEvent();
triggerEvent('destroyed', false);
}
};
each(keys(plugins), pluginName => {
@@ -2519,6 +2536,7 @@ const OverlayScrollbars = (target, options) => {
});
instance.update(true);
addInstance(instanceTarget, instance);
triggerEvent('initialized', false);
return instance;
};
OverlayScrollbars.extend = addPlugin;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+136 -102
View File
@@ -532,6 +532,9 @@
var equalWH = function equalWH(a, b) {
return equal(a, b, ['w', 'h']);
};
var equalXY = function equalXY(a, b) {
return equal(a, b, ['x', 'y']);
};
var equalTRBL = function equalTRBL(a, b) {
return equal(a, b, ['t', 'r', 'b', 'l']);
};
@@ -1363,16 +1366,9 @@
}
prependChildren(target, sizeObserver);
return {
_destroy: function _destroy() {
runEach(offListeners);
removeElements(sizeObserver);
},
_getCurrentCacheValues: function _getCurrentCacheValues(force) {
return {
_directionIsRTL: directionIsRTLCache ? directionIsRTLCache[1](force) : [false, false, false]
};
}
return function () {
runEach(offListeners);
removeElements(sizeObserver);
};
};
@@ -1387,8 +1383,7 @@
var _createCache = createCache({
_initialValue: false
}),
updateHeightIntrinsicCache = _createCache[0],
getCurrentHeightIntrinsicCache = _createCache[1];
updateHeightIntrinsicCache = _createCache[0];
var triggerOnTrinsicChangedCallback = function triggerOnTrinsicChangedCallback(updateValue) {
if (updateValue) {
@@ -1419,21 +1414,14 @@
triggerOnTrinsicChangedCallback(newSize);
};
push(offListeners, createSizeObserver(trinsicObserver, onSizeChanged)._destroy);
push(offListeners, createSizeObserver(trinsicObserver, onSizeChanged));
onSizeChanged();
}
prependChildren(target, trinsicObserver);
return {
_destroy: function _destroy() {
runEach(offListeners);
removeElements(trinsicObserver);
},
_getCurrentCacheValues: function _getCurrentCacheValues(force) {
return {
_heightIntrinsic: getCurrentHeightIntrinsicCache(force)
};
}
return function () {
runEach(offListeners);
removeElements(trinsicObserver);
};
};
@@ -1713,8 +1701,8 @@
}
};
var trinsicObserver = (_content || !_flexboxGlue) && createTrinsicObserver(_host, onTrinsicChanged);
var sizeObserver = createSizeObserver(_host, onSizeChanged, {
var destroyTrinsicObserver = (_content || !_flexboxGlue) && createTrinsicObserver(_host, onTrinsicChanged);
var destroySizeObserver = createSizeObserver(_host, onSizeChanged, {
_appear: true,
_direction: !_nativeScrollbarStyling
});
@@ -1773,19 +1761,13 @@
};
updateViewportAttrsFromHost();
return {
_trinsicObserver: trinsicObserver,
_sizeObserver: sizeObserver,
_updateObserverOptions: updateOptions,
_destroy: function _destroy() {
contentMutationObserver && contentMutationObserver._destroy();
trinsicObserver && trinsicObserver._destroy();
return [updateOptions, function () {
contentMutationObserver && contentMutationObserver._destroy();
destroyTrinsicObserver && destroyTrinsicObserver();
destroySizeObserver();
sizeObserver._destroy();
hostMutationObserver._destroy();
}
};
hostMutationObserver._destroy();
}];
};
var createTrinsicLifecycle = function createTrinsicLifecycle(lifecycleHub) {
@@ -1903,6 +1885,13 @@
h: 0
}
};
var xyCacheOptions = {
_equal: equalXY,
_initialValue: {
x: false,
y: false
}
};
var sizeFraction = function sizeFraction(elm) {
var viewportOffsetSize = offsetSize(elm);
@@ -1967,6 +1956,9 @@
updateOverflowAmountCache = _createCache3[0],
getCurrentOverflowAmountCache = _createCache3[1];
var _createCache4 = createCache(xyCacheOptions),
updateOverflowScrollCache = _createCache4[0];
var fixFlexboxGlue = function fixFlexboxGlue(viewportOverflowState, heightIntrinsic) {
style(_viewport, {
height: ''
@@ -2277,8 +2269,8 @@
style(_viewport, viewportStyle);
_setLifecycleCommunication({
_viewportOverflowScroll: viewportOverflowState._overflowScroll,
_viewportOverflowAmount: overflowAmount
_viewportOverflowScrollCache: updateOverflowScrollCache(viewportOverflowState._overflowScroll),
_viewportOverflowAmountCache: overflowAmuntCache
});
}
};
@@ -2290,6 +2282,10 @@
}, obj) : undefined;
};
var applyForceToCache = function applyForceToCache(cacheValues, force) {
return [cacheValues[0], force || cacheValues[1], cacheValues[2]];
};
var booleanCacheValuesFallback = [false, false, false];
var lifecycleCommunicationFallback = {
_paddingInfo: {
@@ -2301,14 +2297,14 @@
l: 0
}
},
_viewportOverflowScroll: {
_viewportOverflowScrollCache: [{
x: false,
y: false
},
_viewportOverflowAmount: {
}, false],
_viewportOverflowAmountCache: [{
w: 0,
h: 0
},
}, false],
_viewportPaddingStyle: {
marginRight: 0,
marginBottom: 0,
@@ -2319,8 +2315,37 @@
paddingLeft: 0
}
};
var createLifecycleHub = function createLifecycleHub(options, triggerEvent, structureSetup, scrollbarsSetup) {
var prepareUpdateHints = function prepareUpdateHints(leading, adaptive, force) {
var result = {};
var finalAdaptive = adaptive || {};
var objKeys = keys(leading).concat(keys(finalAdaptive));
each(objKeys, function (key) {
var leadingValue = leading[key];
var adaptiveValue = finalAdaptive[key];
result[key] = isBoolean(leadingValue) ? !!force || !!leadingValue || !!adaptiveValue : applyForceToCache(leadingValue || booleanCacheValuesFallback, force);
});
return result;
};
var createOverflowChangedArgs = function createOverflowChangedArgs(overflowAmount, overflowScroll) {
return {
amount: {
x: overflowAmount.w,
y: overflowAmount.h
},
overflow: {
x: overflowAmount.w > 0,
y: overflowAmount.h > 0
},
scrollableOverflow: assignDeep({}, overflowScroll)
};
};
var createLifecycleHub = function createLifecycleHub(options, triggerListener, structureSetup, scrollbarsSetup) {
var lifecycleCommunication = lifecycleCommunicationFallback;
var updateObserverOptions;
var destroyObservers;
var _viewport = structureSetup._targetObj._viewport;
var _getEnvironment = getEnvironment(),
@@ -2345,20 +2370,14 @@
var lifecycles = [createTrinsicLifecycle(instance), createPaddingLifecycle(instance), createOverflowLifecycle(instance)];
var updateLifecycles = function updateLifecycles(updateHints, changedOptions, force) {
var _ref = updateHints || {},
_directionIsRTL = _ref._directionIsRTL,
_heightIntrinsic = _ref._heightIntrinsic,
_ref$_sizeChanged = _ref._sizeChanged,
_sizeChanged = _ref$_sizeChanged === void 0 ? force || false : _ref$_sizeChanged,
_ref$_hostMutation = _ref._hostMutation,
_hostMutation = _ref$_hostMutation === void 0 ? force || false : _ref$_hostMutation,
_ref$_contentMutation = _ref._contentMutation,
_contentMutation = _ref$_contentMutation === void 0 ? force || false : _ref$_contentMutation,
_ref$_paddingStyleCha = _ref._paddingStyleChanged,
_paddingStyleChanged = _ref$_paddingStyleCha === void 0 ? force || false : _ref$_paddingStyleCha;
var finalDirectionIsRTL = _directionIsRTL || (_sizeObserver ? _sizeObserver._getCurrentCacheValues(force)._directionIsRTL : booleanCacheValuesFallback);
var finalHeightIntrinsic = _heightIntrinsic || (_trinsicObserver ? _trinsicObserver._getCurrentCacheValues(force)._heightIntrinsic : booleanCacheValuesFallback);
var initialUpdateHints = prepareUpdateHints(assignDeep({
_sizeChanged: false,
_hostMutation: false,
_contentMutation: false,
_paddingStyleChanged: false,
_directionIsRTL: booleanCacheValuesFallback,
_heightIntrinsic: booleanCacheValuesFallback
}, updateHints), {}, force);
var checkOption = function checkOption(path) {
return [getPropByPath(options, path), force || getPropByPath(changedOptions, path) !== undefined];
@@ -2368,28 +2387,13 @@
var scrollOffsetX = adjustScrollOffset && scrollLeft(_viewport);
var scrollOffsetY = adjustScrollOffset && scrollTop(_viewport);
if (_updateObserverOptions) {
_updateObserverOptions(checkOption);
if (updateObserverOptions) {
updateObserverOptions(checkOption);
}
var adaptivedUpdateHints = initialUpdateHints;
each(lifecycles, function (lifecycle) {
var _ref2 = lifecycle({
_directionIsRTL: finalDirectionIsRTL,
_heightIntrinsic: finalHeightIntrinsic,
_sizeChanged: _sizeChanged,
_hostMutation: _hostMutation,
_contentMutation: _contentMutation,
_paddingStyleChanged: _paddingStyleChanged
}, checkOption, !!force) || {},
adaptiveSizeChanged = _ref2._sizeChanged,
adaptiveHostMutation = _ref2._hostMutation,
adaptiveContentMutation = _ref2._contentMutation,
adaptivePaddingStyleChanged = _ref2._paddingStyleChanged;
_sizeChanged = adaptiveSizeChanged || _sizeChanged;
_hostMutation = adaptiveHostMutation || _hostMutation;
_contentMutation = adaptiveContentMutation || _contentMutation;
_paddingStyleChanged = adaptivePaddingStyleChanged || _paddingStyleChanged;
adaptivedUpdateHints = prepareUpdateHints(adaptivedUpdateHints, lifecycle(adaptivedUpdateHints, checkOption, !!force) || {}, force);
});
if (isNumber(scrollOffsetX)) {
@@ -2400,24 +2404,39 @@
scrollTop(_viewport, scrollOffsetY);
}
triggerEvent('updated', {
var _lifecycleCommunicati = lifecycleCommunication,
overflowAmountCache = _lifecycleCommunicati._viewportOverflowAmountCache,
overflowScrollCache = _lifecycleCommunicati._viewportOverflowScrollCache;
var overflowAmount = overflowAmountCache[0],
overflowAmountChanged = overflowAmountCache[1],
prevOverflowAmount = overflowAmountCache[2];
var overflowScroll = overflowScrollCache[0],
overflowScrollChanged = overflowScrollCache[1],
prevOverflowScroll = overflowScrollCache[2];
if (overflowAmountChanged || overflowScrollChanged) {
triggerListener('overflowChanged', assignDeep({}, createOverflowChangedArgs(overflowAmount, overflowScroll), {
previous: createOverflowChangedArgs(prevOverflowAmount, prevOverflowScroll)
}));
}
triggerListener('updated', {
updateHints: {
sizeChanged: _sizeChanged,
contentMutation: _contentMutation,
hostMutation: _hostMutation,
directionChanged: finalDirectionIsRTL[1],
heightIntrinsicChanged: finalHeightIntrinsic[1]
sizeChanged: adaptivedUpdateHints._sizeChanged,
contentMutation: adaptivedUpdateHints._contentMutation,
hostMutation: adaptivedUpdateHints._hostMutation,
directionChanged: adaptivedUpdateHints._directionIsRTL[1],
heightIntrinsicChanged: adaptivedUpdateHints._heightIntrinsic[1]
},
changedOptions: changedOptions || {},
force: !!force
});
};
var _lifecycleHubOservers = lifecycleHubOservers(instance, updateLifecycles),
_sizeObserver = _lifecycleHubOservers._sizeObserver,
_trinsicObserver = _lifecycleHubOservers._trinsicObserver,
_updateObserverOptions = _lifecycleHubOservers._updateObserverOptions,
destroyObservers = _lifecycleHubOservers._destroy;
var _lifecycleHubOservers = lifecycleHubOservers(instance, updateLifecycles);
updateObserverOptions = _lifecycleHubOservers[0];
destroyObservers = _lifecycleHubOservers[1];
var update = function update(changedOptions, force) {
return updateLifecycles({}, changedOptions, force);
@@ -2425,12 +2444,11 @@
var envUpdateListener = update.bind(0, {}, true);
addEnvironmentListener(envUpdateListener);
console.log(getEnvironment());
return {
_update: update,
_state: function _state() {
return {
_overflowAmount: lifecycleCommunication._viewportOverflowAmount
_overflowAmount: lifecycleCommunication._viewportOverflowAmountCache[0]
};
},
_destroy: function _destroy() {
@@ -2521,7 +2539,7 @@
each(isArray(listener) ? listener : [listener], callback);
};
var createEventHub = function createEventHub() {
var createEventListenerHub = function createEventListenerHub(initialEventListeners) {
var events = new Map();
var removeEvent = function removeEvent(name, listener) {
@@ -2552,14 +2570,27 @@
var triggerEvent = function triggerEvent(name, args) {
var eventSet = events.get(name);
each(from(eventSet), function (event) {
event(args);
if (args) {
event(args);
} else {
event();
}
});
};
var initialListenerKeys = keys(initialEventListeners);
each(initialListenerKeys, function (key) {
addEvent(key, initialEventListeners[key]);
});
return [addEvent, removeEvent, triggerEvent];
};
var OverlayScrollbars = function OverlayScrollbars(target, options) {
var OverlayScrollbars = function OverlayScrollbars(target, options, eventListeners) {
var _getEnvironment = getEnvironment(),
_getDefaultOptions = _getEnvironment._getDefaultOptions,
_nativeScrollbarIsOverlaid = _getEnvironment._nativeScrollbarIsOverlaid;
var plugins = getPlugins();
var instanceTarget = isHTMLElement(target) ? target : target.target;
var potentialInstance = getInstance(instanceTarget);
@@ -2567,10 +2598,6 @@
return potentialInstance;
}
var _getEnvironment = getEnvironment(),
_getDefaultOptions = _getEnvironment._getDefaultOptions;
var plugins = getPlugins();
var optionsValidationPlugin = plugins[optionsValidationPluginName];
var validateOptions = function validateOptions(newOptions) {
@@ -2579,12 +2606,17 @@
return validate ? validate(opts, true) : opts;
};
var _createEventHub = createEventHub(),
addEvent = _createEventHub[0],
removeEvent = _createEventHub[1],
triggerEvent = _createEventHub[2];
var currentOptions = assignDeep({}, _getDefaultOptions(), validateOptions(options));
var _createEventListenerH = createEventListenerHub(eventListeners),
addEvent = _createEventListenerH[0],
removeEvent = _createEventListenerH[1],
triggerEvent = _createEventListenerH[2];
if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !currentOptions.nativeScrollbarsOverlaid.initialize) {
triggerEvent('initializationWithdrawn', false);
}
var structureSetup = createStructureSetup(target);
var scrollbarsSetup = createScrollbarsSetup(target, structureSetup);
var lifecycleHub = createLifecycleHub(currentOptions, triggerEvent, structureSetup, scrollbarsSetup);
@@ -2615,6 +2647,7 @@
removeInstance(instanceTarget);
removeEvent();
triggerEvent('destroyed', false);
}
};
each(keys(plugins), function (pluginName) {
@@ -2626,6 +2659,7 @@
});
instance.update(true);
addInstance(instanceTarget, instance);
triggerEvent('initialized', false);
return instance;
};
OverlayScrollbars.extend = addPlugin;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,15 +1,15 @@
import { OSOptions } from 'options';
import { each, from, isArray, keys } from 'support';
import { each, from, isArray, keys, XY } from 'support';
import { PartialOptions } from 'typings';
/*
onScrollStart : null,
onScroll : null,
onScrollStop : null,
onOverflowChanged : null,
onOverflowAmountChanged : null,
onDirectionChanged : null,
onContentSizeChanged : null,
onHostSizeChanged : null,
onOverflowAmountChanged : null, // fusion with onOverflowChanged
onDirectionChanged : null, // gone
onContentSizeChanged : null, // gone
onHostSizeChanged : null, // gone
*/
export interface OnUpdatedEventListenerArgs {
@@ -24,11 +24,23 @@ export interface OnUpdatedEventListenerArgs {
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 EventListenerArgsMap {
initialized: false;
initializationWithdrawn: false;
destroyed: false;
overflowChanged: OnOverflowChangedEventListenerArgs;
updated: OnUpdatedEventListenerArgs;
destroyed: false;
}
export type OSEventListener<N extends keyof EventListenerArgsMap> = (
@@ -93,11 +105,15 @@ export const createEventListenerHub = (
return removeEvent.bind(0, name, listener as any);
};
const triggerEvent: TriggerEventListener = (name, args) => {
const triggerEvent: TriggerEventListener = (name, args?) => {
const eventSet = events.get(name);
each(from(eventSet), (event) => {
args ? event(args) : (event as () => void)();
if (args) {
event(args);
} else {
(event as () => void)();
}
});
};
@@ -39,8 +39,8 @@ export interface LifecycleCommunication {
_padding: TRBL;
};
_viewportPaddingStyle: StyleObject;
_viewportOverflowScroll: XY<boolean>;
_viewportOverflowAmount: WH<number>;
_viewportOverflowScrollCache: CacheValues<XY<boolean>>;
_viewportOverflowAmountCache: CacheValues<WH<number>>;
}
export interface LifecycleUpdateHints {
@@ -92,14 +92,20 @@ const lifecycleCommunicationFallback: LifecycleCommunication = {
l: 0,
},
},
_viewportOverflowScroll: {
x: false,
y: false,
},
_viewportOverflowAmount: {
w: 0,
h: 0,
},
_viewportOverflowScrollCache: [
{
x: false,
y: false,
},
false,
],
_viewportOverflowAmountCache: [
{
w: 0,
h: 0,
},
false,
],
_viewportPaddingStyle: {
marginRight: 0,
marginBottom: 0,
@@ -131,6 +137,18 @@ const prepareUpdateHints = <T extends LifecycleUpdateHints>(
return result as Required<T>;
};
const createOverflowChangedArgs = (overflowAmount: WH<number>, overflowScroll: XY<boolean>) => ({
amount: {
x: overflowAmount.w,
y: overflowAmount.h,
},
overflow: {
x: overflowAmount.w > 0,
y: overflowAmount.h > 0,
},
scrollableOverflow: assignDeep({}, overflowScroll),
});
export const createLifecycleHub = (
options: OSOptions,
triggerListener: TriggerEventListener,
@@ -214,6 +232,22 @@ export const createLifecycleHub = (
scrollTop(_viewport, scrollOffsetY);
}
const {
_viewportOverflowAmountCache: overflowAmountCache,
_viewportOverflowScrollCache: overflowScrollCache,
} = lifecycleCommunication;
const [overflowAmount, overflowAmountChanged, prevOverflowAmount] = overflowAmountCache;
const [overflowScroll, overflowScrollChanged, prevOverflowScroll] = overflowScrollCache;
if (overflowAmountChanged || overflowScrollChanged) {
triggerListener(
'overflowChanged',
assignDeep({}, createOverflowChangedArgs(overflowAmount, overflowScroll), {
previous: createOverflowChangedArgs(prevOverflowAmount!, prevOverflowScroll!),
})
);
}
triggerListener('updated', {
updateHints: {
sizeChanged: adaptivedUpdateHints._sizeChanged,
@@ -237,7 +271,7 @@ export const createLifecycleHub = (
return {
_update: update,
_state: () => ({
_overflowAmount: lifecycleCommunication._viewportOverflowAmount,
_overflowAmount: lifecycleCommunication._viewportOverflowAmountCache[0],
}),
_destroy() {
destroyObservers();
@@ -15,6 +15,7 @@ import {
getBoundingClientRect,
noop,
each,
equalXY,
} from 'support';
import { LifecycleHub, Lifecycle } from 'lifecycles/lifecycleHub';
import { getEnvironment } from 'environment';
@@ -28,11 +29,6 @@ interface ViewportOverflowState {
_overflowScroll: XY<boolean>;
}
interface OverflowOption {
x: OverflowBehavior;
y: OverflowBehavior;
}
type UndoViewportArrangeResult = [
() => void, // redoViewportArrange
ViewportOverflowState?
@@ -44,6 +40,10 @@ const whCacheOptions = {
_equal: equalWH,
_initialValue: { w: 0, h: 0 },
};
const xyCacheOptions = {
_equal: equalXY,
_initialValue: { x: false, y: false },
};
const sizeFraction = (elm: HTMLElement): WH<number> => {
const viewportOffsetSize = offsetSize(elm);
const viewportRect = getBoundingClientRect(elm);
@@ -126,6 +126,8 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
const [updateOverflowAmountCache, getCurrentOverflowAmountCache] =
createCache<WH<number>>(whCacheOptions);
const [updateOverflowScrollCache] = createCache<XY<boolean>>(xyCacheOptions);
/**
* Applies a fixed height to the viewport so it can't overflow or underflow the host element.
* @param viewportOverflowState The current overflow state.
@@ -215,7 +217,7 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
const setViewportOverflowState = (
showNativeOverlaidScrollbars: boolean,
overflowAmount: WH<number>,
overflow: OverflowOption,
overflow: XY<OverflowBehavior>,
viewportStyleObj: StyleObject
): ViewportOverflowState => {
const { _visible: xVisible, _behavior: xVisibleBehavior } = setAxisOverflowStyle(
@@ -514,7 +516,7 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
const [viewportSizeFraction, viewportSizeFractionChanged] = viewportSizeFractionCache;
const [viewportScrollSize, viewportScrollSizeChanged] = viewportScrollSizeCache;
const [overflowAmount, overflowAmountChanged] = overflowAmuntCache;
const [overflow, overflowChanged] = checkOption<OverflowOption>('overflow');
const [overflow, overflowChanged] = checkOption<XY<OverflowBehavior>>('overflow');
if (
_paddingStyleChanged ||
@@ -561,8 +563,10 @@ export const createOverflowLifecycle = (lifecycleHub: LifecycleHub): Lifecycle =
style(_viewport, viewportStyle);
_setLifecycleCommunication({
_viewportOverflowScroll: viewportOverflowState._overflowScroll,
_viewportOverflowAmount: overflowAmount,
_viewportOverflowScrollCache: updateOverflowScrollCache(
viewportOverflowState._overflowScroll
),
_viewportOverflowAmountCache: overflowAmuntCache,
});
}
};
+1 -1
View File
@@ -10,7 +10,7 @@ export interface CacheOptions<Value> {
export type CacheValues<T> = [
T, // value
boolean, // changed
T | undefined // previous
T? // previous
];
export type EqualCachePropFunction<Value> = (currentVal: Value, newVal: Value) => boolean;
@@ -34,7 +34,7 @@ export const equal = <T extends PlainObject>(
* @param a Object a.
* @param b Object b.
*/
export const equalWH = (a?: WH, b?: WH) => equal<WH>(a, b, ['w', 'h']);
export const equalWH = <T>(a?: WH<T>, b?: WH<T>) => equal<WH<T>>(a, b, ['w', 'h']);
/**
* Compares object a with object b and returns true if both have the same property values, false otherwise.
@@ -42,7 +42,7 @@ export const equalWH = (a?: WH, b?: WH) => equal<WH>(a, b, ['w', 'h']);
* @param a Object a.
* @param b Object b.
*/
export const equalXY = (a?: XY, b?: XY) => equal<XY>(a, b, ['x', 'y']);
export const equalXY = <T>(a?: XY<T>, b?: XY<T>) => equal<XY<T>>(a, b, ['x', 'y']);
/**
* Compares object a with object b and returns true if both have the same property values, false otherwise.
@@ -91,6 +91,7 @@ export const debounce = <FunctionToDebounce extends (...args: any) => any>(
// }
clearTimeouts(timeoutId);
// @ts-ignore
timeoutId = setTimeoutFn(boundInvoke, finalTimeout as number) as number;
if (hasMaxWait && !maxTimeoutId) {
+40 -9
View File
@@ -89,7 +89,21 @@ type OSPlugin<T extends OSPluginInstance> = [
string,
T
];
interface onUpdatedEventArgs {
interface XY<T> {
x: T;
y: T;
}
/*
onScrollStart : null,
onScroll : null,
onScrollStop : null,
onOverflowChanged : null,
onOverflowAmountChanged : null, // fusion with onOverflowChanged
onDirectionChanged : null, // gone
onContentSizeChanged : null, // gone
onHostSizeChanged : null, // gone
*/
interface OnUpdatedEventListenerArgs {
updateHints: {
sizeChanged: boolean;
hostMutation: boolean;
@@ -100,14 +114,31 @@ interface onUpdatedEventArgs {
changedOptions: PartialOptions<OSOptions>;
force: boolean;
}
interface EventArgsMap {
updated: onUpdatedEventArgs;
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>;
};
}
type OSEventListener<N extends keyof EventArgsMap> = (args: EventArgsMap[N]) => void;
type AddEvent = <N extends keyof EventArgsMap>(name: N, listener: OSEventListener<N> | OSEventListener<N>[]) => () => void;
type RemoveEvent = <N extends keyof EventArgsMap>(name?: N, listener?: OSEventListener<N> | OSEventListener<N>[]) => void;
interface EventListenerArgsMap {
initialized: false;
initializationWithdrawn: false;
overflowChanged: OnOverflowChangedEventListenerArgs;
updated: OnUpdatedEventListenerArgs;
destroyed: false;
}
type OSEventListener<N extends keyof EventListenerArgsMap> = (args: EventListenerArgsMap[N]) => void;
type AddEventListener = <N extends keyof EventListenerArgsMap>(name: N, listener: OSEventListener<N> | OSEventListener<N>[]) => () => void;
type RemoveEventListener = <N extends keyof EventListenerArgsMap>(name?: N, listener?: OSEventListener<N> | OSEventListener<N>[]) => void;
type EventListenersMap = {
[K in keyof EventListenerArgsMap]?: OSEventListener<K> | OSEventListener<K>[];
};
interface OverlayScrollbarsStatic {
(target: OSTarget | OSInitializationObject, options?: PartialOptions<OSOptions>, extensions?: any): OverlayScrollbars;
(target: OSTarget | OSInitializationObject, options?: PartialOptions<OSOptions>, eventListeners?: EventListenersMap): OverlayScrollbars;
extend(osPlugin: OSPlugin | OSPlugin[]): void;
}
interface OverlayScrollbars {
@@ -116,8 +147,8 @@ interface OverlayScrollbars {
update(force?: boolean): void;
destroy(): void;
state(): any;
on: AddEvent;
off: RemoveEvent;
on: AddEventListener;
off: RemoveEventListener;
}
declare const OverlayScrollbars: OverlayScrollbarsStatic;
export { OverlayScrollbars as default };