183 lines
7.2 KiB
JavaScript
183 lines
7.2 KiB
JavaScript
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports.default = void 0;
|
|
|
|
function isElement(el) {
|
|
return el != null && typeof el === 'object' && el.nodeType === 1;
|
|
}
|
|
|
|
function canOverflow(overflow, skipOverflowHiddenElements) {
|
|
if (skipOverflowHiddenElements && overflow === 'hidden') {
|
|
return false;
|
|
}
|
|
|
|
return overflow !== 'visible' && overflow !== 'clip';
|
|
}
|
|
|
|
function isScrollable(el, skipOverflowHiddenElements) {
|
|
if (el.clientHeight < el.scrollHeight || el.clientWidth < el.scrollWidth) {
|
|
var style = getComputedStyle(el, null);
|
|
return canOverflow(style.overflowY, skipOverflowHiddenElements) || canOverflow(style.overflowX, skipOverflowHiddenElements);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function alignNearest(scrollingEdgeStart, scrollingEdgeEnd, scrollingSize, scrollingBorderStart, scrollingBorderEnd, elementEdgeStart, elementEdgeEnd, elementSize) {
|
|
if (elementEdgeStart < scrollingEdgeStart && elementEdgeEnd > scrollingEdgeEnd || elementEdgeStart > scrollingEdgeStart && elementEdgeEnd < scrollingEdgeEnd) {
|
|
return 0;
|
|
}
|
|
|
|
if (elementEdgeStart <= scrollingEdgeStart && elementSize <= scrollingSize || elementEdgeEnd >= scrollingEdgeEnd && elementSize >= scrollingSize) {
|
|
return elementEdgeStart - scrollingEdgeStart - scrollingBorderStart;
|
|
}
|
|
|
|
if (elementEdgeEnd > scrollingEdgeEnd && elementSize < scrollingSize || elementEdgeStart < scrollingEdgeStart && elementSize > scrollingSize) {
|
|
return elementEdgeEnd - scrollingEdgeEnd + scrollingBorderEnd;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
var _default = function _default(target, options) {
|
|
var scrollMode = options.scrollMode,
|
|
block = options.block,
|
|
inline = options.inline,
|
|
boundary = options.boundary,
|
|
skipOverflowHiddenElements = options.skipOverflowHiddenElements;
|
|
var checkBoundary = typeof boundary === 'function' ? boundary : function (node) {
|
|
return node !== boundary;
|
|
};
|
|
|
|
if (!isElement(target)) {
|
|
throw new TypeError('Invalid target');
|
|
}
|
|
|
|
var scrollingElement = document.scrollingElement || document.documentElement;
|
|
var frames = [];
|
|
var cursor = target;
|
|
|
|
while (isElement(cursor) && checkBoundary(cursor)) {
|
|
cursor = cursor.parentNode;
|
|
|
|
if (cursor === scrollingElement) {
|
|
frames.push(cursor);
|
|
break;
|
|
}
|
|
|
|
if (cursor === document.body && isScrollable(cursor) && !isScrollable(document.documentElement)) {
|
|
continue;
|
|
}
|
|
|
|
if (isScrollable(cursor, skipOverflowHiddenElements)) {
|
|
frames.push(cursor);
|
|
}
|
|
}
|
|
|
|
var viewportWidth = window.visualViewport ? visualViewport.width : innerWidth;
|
|
var viewportHeight = window.visualViewport ? visualViewport.height : innerHeight;
|
|
var viewportX = window.scrollX || pageXOffset;
|
|
var viewportY = window.scrollY || pageYOffset;
|
|
|
|
var _target$getBoundingCl = target.getBoundingClientRect(),
|
|
targetHeight = _target$getBoundingCl.height,
|
|
targetWidth = _target$getBoundingCl.width,
|
|
targetTop = _target$getBoundingCl.top,
|
|
targetRight = _target$getBoundingCl.right,
|
|
targetBottom = _target$getBoundingCl.bottom,
|
|
targetLeft = _target$getBoundingCl.left;
|
|
|
|
var targetBlock = block === 'start' || block === 'nearest' ? targetTop : block === 'end' ? targetBottom : targetTop + targetHeight / 2;
|
|
var targetInline = inline === 'center' ? targetLeft + targetWidth / 2 : inline === 'end' ? targetRight : targetLeft;
|
|
var computations = [];
|
|
|
|
for (var index = 0; index < frames.length; index++) {
|
|
var frame = frames[index];
|
|
|
|
var _frame$getBoundingCli = frame.getBoundingClientRect(),
|
|
_height = _frame$getBoundingCli.height,
|
|
_width = _frame$getBoundingCli.width,
|
|
_top = _frame$getBoundingCli.top,
|
|
right = _frame$getBoundingCli.right,
|
|
bottom = _frame$getBoundingCli.bottom,
|
|
_left = _frame$getBoundingCli.left;
|
|
|
|
if (scrollMode === 'if-needed' && targetTop >= 0 && targetLeft >= 0 && targetBottom <= viewportHeight && targetRight <= viewportWidth && targetTop >= _top && targetBottom <= bottom && targetLeft >= _left && targetRight <= right) {
|
|
return computations;
|
|
}
|
|
|
|
var frameStyle = getComputedStyle(frame);
|
|
var borderLeft = parseInt(frameStyle.borderLeftWidth, 10);
|
|
var borderTop = parseInt(frameStyle.borderTopWidth, 10);
|
|
var borderRight = parseInt(frameStyle.borderRightWidth, 10);
|
|
var borderBottom = parseInt(frameStyle.borderBottomWidth, 10);
|
|
var blockScroll = 0;
|
|
var inlineScroll = 0;
|
|
var scrollbarWidth = 'offsetWidth' in frame ? frame.offsetWidth - frame.clientWidth - borderLeft - borderRight : 0;
|
|
var scrollbarHeight = 'offsetHeight' in frame ? frame.offsetHeight - frame.clientHeight - borderTop - borderBottom : 0;
|
|
|
|
if (scrollingElement === frame) {
|
|
if (block === 'start') {
|
|
blockScroll = targetBlock;
|
|
} else if (block === 'end') {
|
|
blockScroll = targetBlock - viewportHeight;
|
|
} else if (block === 'nearest') {
|
|
blockScroll = alignNearest(viewportY, viewportY + viewportHeight, viewportHeight, borderTop, borderBottom, viewportY + targetBlock, viewportY + targetBlock + targetHeight, targetHeight);
|
|
} else {
|
|
blockScroll = targetBlock - viewportHeight / 2;
|
|
}
|
|
|
|
if (inline === 'start') {
|
|
inlineScroll = targetInline;
|
|
} else if (inline === 'center') {
|
|
inlineScroll = targetInline - viewportWidth / 2;
|
|
} else if (inline === 'end') {
|
|
inlineScroll = targetInline - viewportWidth;
|
|
} else {
|
|
inlineScroll = alignNearest(viewportX, viewportX + viewportWidth, viewportWidth, borderLeft, borderRight, viewportX + targetInline, viewportX + targetInline + targetWidth, targetWidth);
|
|
}
|
|
|
|
blockScroll = Math.max(0, blockScroll + viewportY);
|
|
inlineScroll = Math.max(0, inlineScroll + viewportX);
|
|
} else {
|
|
if (block === 'start') {
|
|
blockScroll = targetBlock - _top - borderTop;
|
|
} else if (block === 'end') {
|
|
blockScroll = targetBlock - bottom + borderBottom + scrollbarHeight;
|
|
} else if (block === 'nearest') {
|
|
blockScroll = alignNearest(_top, bottom, _height, borderTop, borderBottom + scrollbarHeight, targetBlock, targetBlock + targetHeight, targetHeight);
|
|
} else {
|
|
blockScroll = targetBlock - (_top + _height / 2) + scrollbarHeight / 2;
|
|
}
|
|
|
|
if (inline === 'start') {
|
|
inlineScroll = targetInline - _left - borderLeft;
|
|
} else if (inline === 'center') {
|
|
inlineScroll = targetInline - (_left + _width / 2) + scrollbarWidth / 2;
|
|
} else if (inline === 'end') {
|
|
inlineScroll = targetInline - right + borderRight + scrollbarWidth;
|
|
} else {
|
|
inlineScroll = alignNearest(_left, right, _width, borderLeft, borderRight + scrollbarWidth, targetInline, targetInline + targetWidth, targetWidth);
|
|
}
|
|
|
|
var scrollLeft = frame.scrollLeft,
|
|
scrollTop = frame.scrollTop;
|
|
blockScroll = Math.max(0, Math.min(scrollTop + blockScroll, frame.scrollHeight - _height + scrollbarHeight));
|
|
inlineScroll = Math.max(0, Math.min(scrollLeft + inlineScroll, frame.scrollWidth - _width + scrollbarWidth));
|
|
targetBlock += scrollTop - blockScroll;
|
|
targetInline += scrollLeft - inlineScroll;
|
|
}
|
|
|
|
computations.push({
|
|
el: frame,
|
|
top: blockScroll,
|
|
left: inlineScroll
|
|
});
|
|
}
|
|
|
|
return computations;
|
|
};
|
|
|
|
exports.default = _default;
|
|
module.exports = exports.default; |