mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Fix indentation issues
This commit is contained in:
parent
52c8cffc82
commit
f2726653ae
120 changed files with 30271 additions and 30631 deletions
|
@ -1,5 +1,3 @@
|
|||
/* eslint-disable indent */
|
||||
|
||||
/**
|
||||
* Module for controlling scroll behavior.
|
||||
* @module components/scrollManager
|
||||
|
@ -9,50 +7,50 @@ import dom from '../scripts/dom';
|
|||
import browser from '../scripts/browser';
|
||||
import layoutManager from './layoutManager';
|
||||
|
||||
/**
|
||||
/**
|
||||
* Scroll time in ms.
|
||||
*/
|
||||
const ScrollTime = 270;
|
||||
const ScrollTime = 270;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Epsilon for comparing values.
|
||||
*/
|
||||
const Epsilon = 1e-6;
|
||||
const Epsilon = 1e-6;
|
||||
|
||||
// FIXME: Need to scroll to top of page to fully show the top menu. This can be solved by some marker of top most elements or their containers
|
||||
/**
|
||||
// FIXME: Need to scroll to top of page to fully show the top menu. This can be solved by some marker of top most elements or their containers
|
||||
/**
|
||||
* Returns minimum vertical scroll.
|
||||
* Scroll less than that value will be zeroed.
|
||||
*
|
||||
* @return {number} Minimum vertical scroll.
|
||||
*/
|
||||
function minimumScrollY() {
|
||||
const topMenu = document.querySelector('.headerTop');
|
||||
if (topMenu) {
|
||||
return topMenu.clientHeight;
|
||||
function minimumScrollY() {
|
||||
const topMenu = document.querySelector('.headerTop');
|
||||
if (topMenu) {
|
||||
return topMenu.clientHeight;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const supportsSmoothScroll = 'scrollBehavior' in document.documentElement.style;
|
||||
|
||||
let supportsScrollToOptions = false;
|
||||
try {
|
||||
const elem = document.createElement('div');
|
||||
|
||||
const opts = Object.defineProperty({}, 'behavior', {
|
||||
// eslint-disable-next-line getter-return
|
||||
get: function () {
|
||||
supportsScrollToOptions = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
const supportsSmoothScroll = 'scrollBehavior' in document.documentElement.style;
|
||||
elem.scrollTo(opts);
|
||||
} catch (e) {
|
||||
console.error('error checking ScrollToOptions support');
|
||||
}
|
||||
|
||||
let supportsScrollToOptions = false;
|
||||
try {
|
||||
const elem = document.createElement('div');
|
||||
|
||||
const opts = Object.defineProperty({}, 'behavior', {
|
||||
// eslint-disable-next-line getter-return
|
||||
get: function () {
|
||||
supportsScrollToOptions = true;
|
||||
}
|
||||
});
|
||||
|
||||
elem.scrollTo(opts);
|
||||
} catch (e) {
|
||||
console.error('error checking ScrollToOptions support');
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns value clamped by range [min, max].
|
||||
*
|
||||
* @param {number} value - Clamped value.
|
||||
|
@ -60,16 +58,16 @@ import layoutManager from './layoutManager';
|
|||
* @param {number} max - Ending of range.
|
||||
* @return {number} Clamped value.
|
||||
*/
|
||||
function clamp(value, min, max) {
|
||||
if (value <= min) {
|
||||
return min;
|
||||
} else if (value >= max) {
|
||||
return max;
|
||||
}
|
||||
return value;
|
||||
function clamp(value, min, max) {
|
||||
if (value <= min) {
|
||||
return min;
|
||||
} else if (value >= max) {
|
||||
return max;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns the required delta to fit range 1 into range 2.
|
||||
* In case of range 1 is bigger than range 2 returns delta to fit most out of range part.
|
||||
*
|
||||
|
@ -79,28 +77,28 @@ import layoutManager from './layoutManager';
|
|||
* @param {number} end2 - Ending of range 2.
|
||||
* @return {number} Delta: <0 move range1 to the left, >0 - to the right.
|
||||
*/
|
||||
function fitRange(begin1, end1, begin2, end2) {
|
||||
const delta1 = begin1 - begin2;
|
||||
const delta2 = end2 - end1;
|
||||
if (delta1 < 0 && delta1 < delta2) {
|
||||
return -delta1;
|
||||
} else if (delta2 < 0) {
|
||||
return delta2;
|
||||
}
|
||||
return 0;
|
||||
function fitRange(begin1, end1, begin2, end2) {
|
||||
const delta1 = begin1 - begin2;
|
||||
const delta2 = end2 - end1;
|
||||
if (delta1 < 0 && delta1 < delta2) {
|
||||
return -delta1;
|
||||
} else if (delta2 < 0) {
|
||||
return delta2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Ease value.
|
||||
*
|
||||
* @param {number} t - Value in range [0, 1].
|
||||
* @return {number} Eased value in range [0, 1].
|
||||
*/
|
||||
function ease(t) {
|
||||
return t * (2 - t); // easeOutQuad === ease-out
|
||||
}
|
||||
function ease(t) {
|
||||
return t * (2 - t); // easeOutQuad === ease-out
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @typedef {Object} Rect
|
||||
* @property {number} left - X coordinate of top-left corner.
|
||||
* @property {number} top - Y coordinate of top-left corner.
|
||||
|
@ -108,7 +106,7 @@ import layoutManager from './layoutManager';
|
|||
* @property {number} height - Height.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Document scroll wrapper helps to unify scrolling and fix issues of some browsers.
|
||||
*
|
||||
* webOS 2 Browser: scrolls documentElement (and window), but body has a scroll size
|
||||
|
@ -121,157 +119,157 @@ import layoutManager from './layoutManager';
|
|||
*
|
||||
* Tizen 5 Browser/Native: scrolls documentElement (and window); has a document.scrollingElement
|
||||
*/
|
||||
class DocumentScroller {
|
||||
/**
|
||||
class DocumentScroller {
|
||||
/**
|
||||
* Horizontal scroll position.
|
||||
* @type {number}
|
||||
*/
|
||||
get scrollLeft() {
|
||||
return window.pageXOffset;
|
||||
}
|
||||
get scrollLeft() {
|
||||
return window.pageXOffset;
|
||||
}
|
||||
|
||||
set scrollLeft(val) {
|
||||
window.scroll(val, window.pageYOffset);
|
||||
}
|
||||
set scrollLeft(val) {
|
||||
window.scroll(val, window.pageYOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Vertical scroll position.
|
||||
* @type {number}
|
||||
*/
|
||||
get scrollTop() {
|
||||
return window.pageYOffset;
|
||||
}
|
||||
get scrollTop() {
|
||||
return window.pageYOffset;
|
||||
}
|
||||
|
||||
set scrollTop(val) {
|
||||
window.scroll(window.pageXOffset, val);
|
||||
}
|
||||
set scrollTop(val) {
|
||||
window.scroll(window.pageXOffset, val);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Horizontal scroll size (scroll width).
|
||||
* @type {number}
|
||||
*/
|
||||
get scrollWidth() {
|
||||
return Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
|
||||
}
|
||||
get scrollWidth() {
|
||||
return Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Vertical scroll size (scroll height).
|
||||
* @type {number}
|
||||
*/
|
||||
get scrollHeight() {
|
||||
return Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
|
||||
}
|
||||
get scrollHeight() {
|
||||
return Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Horizontal client size (client width).
|
||||
* @type {number}
|
||||
*/
|
||||
get clientWidth() {
|
||||
return Math.min(document.documentElement.clientWidth, document.body.clientWidth);
|
||||
}
|
||||
get clientWidth() {
|
||||
return Math.min(document.documentElement.clientWidth, document.body.clientWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Vertical client size (client height).
|
||||
* @type {number}
|
||||
*/
|
||||
get clientHeight() {
|
||||
return Math.min(document.documentElement.clientHeight, document.body.clientHeight);
|
||||
}
|
||||
get clientHeight() {
|
||||
return Math.min(document.documentElement.clientHeight, document.body.clientHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns attribute value.
|
||||
* @param {string} attributeName - Attibute name.
|
||||
* @return {string} Attibute value.
|
||||
*/
|
||||
getAttribute(attributeName) {
|
||||
return document.body.getAttribute(attributeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns bounding client rect.
|
||||
* @return {Rect} Bounding client rect.
|
||||
*/
|
||||
getBoundingClientRect() {
|
||||
// Make valid viewport coordinates: documentElement.getBoundingClientRect returns rect of entire document relative to viewport
|
||||
return {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: this.clientWidth,
|
||||
height: this.clientHeight
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls window.
|
||||
* @param {...mixed} args See window.scrollTo.
|
||||
*/
|
||||
scrollTo() {
|
||||
window.scrollTo.apply(window, arguments);
|
||||
}
|
||||
getAttribute(attributeName) {
|
||||
return document.body.getAttribute(attributeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default (document) scroller.
|
||||
*/
|
||||
const documentScroller = new DocumentScroller();
|
||||
|
||||
const scrollerHints = {
|
||||
x: {
|
||||
nameScroll: 'scrollWidth',
|
||||
nameClient: 'clientWidth',
|
||||
nameStyle: 'overflowX',
|
||||
nameScrollMode: 'data-scroll-mode-x'
|
||||
},
|
||||
y: {
|
||||
nameScroll: 'scrollHeight',
|
||||
nameClient: 'clientHeight',
|
||||
nameStyle: 'overflowY',
|
||||
nameScrollMode: 'data-scroll-mode-y'
|
||||
}
|
||||
};
|
||||
* Returns bounding client rect.
|
||||
* @return {Rect} Bounding client rect.
|
||||
*/
|
||||
getBoundingClientRect() {
|
||||
// Make valid viewport coordinates: documentElement.getBoundingClientRect returns rect of entire document relative to viewport
|
||||
return {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: this.clientWidth,
|
||||
height: this.clientHeight
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls window.
|
||||
* @param {...mixed} args See window.scrollTo.
|
||||
*/
|
||||
scrollTo() {
|
||||
window.scrollTo.apply(window, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default (document) scroller.
|
||||
*/
|
||||
const documentScroller = new DocumentScroller();
|
||||
|
||||
const scrollerHints = {
|
||||
x: {
|
||||
nameScroll: 'scrollWidth',
|
||||
nameClient: 'clientWidth',
|
||||
nameStyle: 'overflowX',
|
||||
nameScrollMode: 'data-scroll-mode-x'
|
||||
},
|
||||
y: {
|
||||
nameScroll: 'scrollHeight',
|
||||
nameClient: 'clientHeight',
|
||||
nameStyle: 'overflowY',
|
||||
nameScrollMode: 'data-scroll-mode-y'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns parent element that can be scrolled. If no such, returns document scroller.
|
||||
*
|
||||
* @param {HTMLElement} element - Element for which parent is being searched.
|
||||
* @param {boolean} vertical - Search for vertical scrollable parent.
|
||||
* @param {HTMLElement|DocumentScroller} Parent element that can be scrolled or document scroller.
|
||||
*/
|
||||
function getScrollableParent(element, vertical) {
|
||||
if (element) {
|
||||
const scrollerHint = vertical ? scrollerHints.y : scrollerHints.x;
|
||||
function getScrollableParent(element, vertical) {
|
||||
if (element) {
|
||||
const scrollerHint = vertical ? scrollerHints.y : scrollerHints.x;
|
||||
|
||||
let parent = element.parentElement;
|
||||
let parent = element.parentElement;
|
||||
|
||||
while (parent && parent !== document.body) {
|
||||
const scrollMode = parent.getAttribute(scrollerHint.nameScrollMode);
|
||||
while (parent && parent !== document.body) {
|
||||
const scrollMode = parent.getAttribute(scrollerHint.nameScrollMode);
|
||||
|
||||
// Stop on self-scrolled containers
|
||||
if (scrollMode === 'custom') {
|
||||
return parent;
|
||||
}
|
||||
|
||||
const styles = window.getComputedStyle(parent);
|
||||
|
||||
// Stop on fixed parent
|
||||
if (styles.position === 'fixed') {
|
||||
return parent;
|
||||
}
|
||||
|
||||
const overflow = styles[scrollerHint.nameStyle];
|
||||
|
||||
if (overflow === 'scroll' || overflow === 'auto' && parent[scrollerHint.nameScroll] > parent[scrollerHint.nameClient]) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
parent = parent.parentElement;
|
||||
// Stop on self-scrolled containers
|
||||
if (scrollMode === 'custom') {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
return documentScroller;
|
||||
const styles = window.getComputedStyle(parent);
|
||||
|
||||
// Stop on fixed parent
|
||||
if (styles.position === 'fixed') {
|
||||
return parent;
|
||||
}
|
||||
|
||||
const overflow = styles[scrollerHint.nameStyle];
|
||||
|
||||
if (overflow === 'scroll' || overflow === 'auto' && parent[scrollerHint.nameScroll] > parent[scrollerHint.nameClient]) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
return documentScroller;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} ScrollerData
|
||||
* @property {number} scrollPos - Current scroll position.
|
||||
* @property {number} scrollSize - Scroll size.
|
||||
|
@ -280,34 +278,34 @@ import layoutManager from './layoutManager';
|
|||
* @property {boolean} custom - Custom scrolling mode.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns scroller data for specified orientation.
|
||||
*
|
||||
* @param {HTMLElement} scroller - Scroller.
|
||||
* @param {boolean} vertical - Vertical scroller data.
|
||||
* @return {ScrollerData} Scroller data.
|
||||
*/
|
||||
function getScrollerData(scroller, vertical) {
|
||||
const data = {};
|
||||
function getScrollerData(scroller, vertical) {
|
||||
const data = {};
|
||||
|
||||
if (!vertical) {
|
||||
data.scrollPos = scroller.scrollLeft;
|
||||
data.scrollSize = scroller.scrollWidth;
|
||||
data.clientSize = scroller.clientWidth;
|
||||
data.mode = scroller.getAttribute(scrollerHints.x.nameScrollMode);
|
||||
} else {
|
||||
data.scrollPos = scroller.scrollTop;
|
||||
data.scrollSize = scroller.scrollHeight;
|
||||
data.clientSize = scroller.clientHeight;
|
||||
data.mode = scroller.getAttribute(scrollerHints.y.nameScrollMode);
|
||||
}
|
||||
|
||||
data.custom = data.mode === 'custom';
|
||||
|
||||
return data;
|
||||
if (!vertical) {
|
||||
data.scrollPos = scroller.scrollLeft;
|
||||
data.scrollSize = scroller.scrollWidth;
|
||||
data.clientSize = scroller.clientWidth;
|
||||
data.mode = scroller.getAttribute(scrollerHints.x.nameScrollMode);
|
||||
} else {
|
||||
data.scrollPos = scroller.scrollTop;
|
||||
data.scrollSize = scroller.scrollHeight;
|
||||
data.clientSize = scroller.clientHeight;
|
||||
data.mode = scroller.getAttribute(scrollerHints.y.nameScrollMode);
|
||||
}
|
||||
|
||||
/**
|
||||
data.custom = data.mode === 'custom';
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns position of child of scroller for specified orientation.
|
||||
*
|
||||
* @param {HTMLElement} scroller - Scroller.
|
||||
|
@ -315,18 +313,18 @@ import layoutManager from './layoutManager';
|
|||
* @param {boolean} vertical - Vertical scroll.
|
||||
* @return {number} Child position.
|
||||
*/
|
||||
function getScrollerChildPos(scroller, element, vertical) {
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
const scrollerRect = scroller.getBoundingClientRect();
|
||||
function getScrollerChildPos(scroller, element, vertical) {
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
const scrollerRect = scroller.getBoundingClientRect();
|
||||
|
||||
if (!vertical) {
|
||||
return scroller.scrollLeft + elementRect.left - scrollerRect.left;
|
||||
} else {
|
||||
return scroller.scrollTop + elementRect.top - scrollerRect.top;
|
||||
}
|
||||
if (!vertical) {
|
||||
return scroller.scrollLeft + elementRect.left - scrollerRect.left;
|
||||
} else {
|
||||
return scroller.scrollTop + elementRect.top - scrollerRect.top;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns scroll position for element.
|
||||
*
|
||||
* @param {ScrollerData} scrollerData - Scroller data.
|
||||
|
@ -335,47 +333,47 @@ import layoutManager from './layoutManager';
|
|||
* @param {boolean} centered - Scroll to center.
|
||||
* @return {number} Scroll position.
|
||||
*/
|
||||
function calcScroll(scrollerData, elementPos, elementSize, centered) {
|
||||
const maxScroll = scrollerData.scrollSize - scrollerData.clientSize;
|
||||
function calcScroll(scrollerData, elementPos, elementSize, centered) {
|
||||
const maxScroll = scrollerData.scrollSize - scrollerData.clientSize;
|
||||
|
||||
let scroll;
|
||||
let scroll;
|
||||
|
||||
if (centered) {
|
||||
scroll = elementPos + (elementSize - scrollerData.clientSize) / 2;
|
||||
} else {
|
||||
const delta = fitRange(elementPos, elementPos + elementSize - 1, scrollerData.scrollPos, scrollerData.scrollPos + scrollerData.clientSize - 1);
|
||||
scroll = scrollerData.scrollPos - delta;
|
||||
}
|
||||
|
||||
return clamp(Math.round(scroll), 0, maxScroll);
|
||||
if (centered) {
|
||||
scroll = elementPos + (elementSize - scrollerData.clientSize) / 2;
|
||||
} else {
|
||||
const delta = fitRange(elementPos, elementPos + elementSize - 1, scrollerData.scrollPos, scrollerData.scrollPos + scrollerData.clientSize - 1);
|
||||
scroll = scrollerData.scrollPos - delta;
|
||||
}
|
||||
|
||||
/**
|
||||
return clamp(Math.round(scroll), 0, maxScroll);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls scrollTo function in proper way.
|
||||
*
|
||||
* @param {HTMLElement} scroller - Scroller.
|
||||
* @param {ScrollToOptions} options - Scroll options.
|
||||
*/
|
||||
function scrollToHelper(scroller, options) {
|
||||
if ('scrollTo' in scroller) {
|
||||
if (!supportsScrollToOptions) {
|
||||
const scrollX = (options.left !== undefined ? options.left : scroller.scrollLeft);
|
||||
const scrollY = (options.top !== undefined ? options.top : scroller.scrollTop);
|
||||
scroller.scrollTo(scrollX, scrollY);
|
||||
} else {
|
||||
scroller.scrollTo(options);
|
||||
}
|
||||
} else if ('scrollLeft' in scroller) {
|
||||
if (options.left !== undefined) {
|
||||
scroller.scrollLeft = options.left;
|
||||
}
|
||||
if (options.top !== undefined) {
|
||||
scroller.scrollTop = options.top;
|
||||
}
|
||||
function scrollToHelper(scroller, options) {
|
||||
if ('scrollTo' in scroller) {
|
||||
if (!supportsScrollToOptions) {
|
||||
const scrollX = (options.left !== undefined ? options.left : scroller.scrollLeft);
|
||||
const scrollY = (options.top !== undefined ? options.top : scroller.scrollTop);
|
||||
scroller.scrollTo(scrollX, scrollY);
|
||||
} else {
|
||||
scroller.scrollTo(options);
|
||||
}
|
||||
} else if ('scrollLeft' in scroller) {
|
||||
if (options.left !== undefined) {
|
||||
scroller.scrollLeft = options.left;
|
||||
}
|
||||
if (options.top !== undefined) {
|
||||
scroller.scrollTop = options.top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Performs built-in scroll.
|
||||
*
|
||||
* @param {HTMLElement} xScroller - Horizontal scroller.
|
||||
|
@ -384,35 +382,35 @@ import layoutManager from './layoutManager';
|
|||
* @param {number} scrollY - Vertical coordinate.
|
||||
* @param {boolean} smooth - Smooth scrolling.
|
||||
*/
|
||||
function builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
|
||||
const scrollBehavior = smooth ? 'smooth' : 'instant';
|
||||
function builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
|
||||
const scrollBehavior = smooth ? 'smooth' : 'instant';
|
||||
|
||||
if (xScroller !== yScroller) {
|
||||
if (xScroller) {
|
||||
scrollToHelper(xScroller, { left: scrollX, behavior: scrollBehavior });
|
||||
}
|
||||
if (yScroller) {
|
||||
scrollToHelper(yScroller, { top: scrollY, behavior: scrollBehavior });
|
||||
}
|
||||
} else if (xScroller) {
|
||||
scrollToHelper(xScroller, { left: scrollX, top: scrollY, behavior: scrollBehavior });
|
||||
if (xScroller !== yScroller) {
|
||||
if (xScroller) {
|
||||
scrollToHelper(xScroller, { left: scrollX, behavior: scrollBehavior });
|
||||
}
|
||||
if (yScroller) {
|
||||
scrollToHelper(yScroller, { top: scrollY, behavior: scrollBehavior });
|
||||
}
|
||||
} else if (xScroller) {
|
||||
scrollToHelper(xScroller, { left: scrollX, top: scrollY, behavior: scrollBehavior });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Requested frame for animated scroll.
|
||||
*/
|
||||
let scrollTimer;
|
||||
let scrollTimer;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Resets scroll timer to stop scrolling.
|
||||
*/
|
||||
function resetScrollTimer() {
|
||||
cancelAnimationFrame(scrollTimer);
|
||||
scrollTimer = undefined;
|
||||
}
|
||||
function resetScrollTimer() {
|
||||
cancelAnimationFrame(scrollTimer);
|
||||
scrollTimer = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Performs animated scroll.
|
||||
*
|
||||
* @param {HTMLElement} xScroller - Horizontal scroller.
|
||||
|
@ -420,43 +418,43 @@ import layoutManager from './layoutManager';
|
|||
* @param {HTMLElement} yScroller - Vertical scroller.
|
||||
* @param {number} scrollY - Vertical coordinate.
|
||||
*/
|
||||
function animateScroll(xScroller, scrollX, yScroller, scrollY) {
|
||||
const ox = xScroller ? xScroller.scrollLeft : scrollX;
|
||||
const oy = yScroller ? yScroller.scrollTop : scrollY;
|
||||
const dx = scrollX - ox;
|
||||
const dy = scrollY - oy;
|
||||
function animateScroll(xScroller, scrollX, yScroller, scrollY) {
|
||||
const ox = xScroller ? xScroller.scrollLeft : scrollX;
|
||||
const oy = yScroller ? yScroller.scrollTop : scrollY;
|
||||
const dx = scrollX - ox;
|
||||
const dy = scrollY - oy;
|
||||
|
||||
if (Math.abs(dx) < Epsilon && Math.abs(dy) < Epsilon) {
|
||||
if (Math.abs(dx) < Epsilon && Math.abs(dy) < Epsilon) {
|
||||
return;
|
||||
}
|
||||
|
||||
let start;
|
||||
|
||||
function scrollAnim(currentTimestamp) {
|
||||
start = start || currentTimestamp;
|
||||
|
||||
let k = Math.min(1, (currentTimestamp - start) / ScrollTime);
|
||||
|
||||
if (k === 1) {
|
||||
resetScrollTimer();
|
||||
builtinScroll(xScroller, scrollX, yScroller, scrollY, false);
|
||||
return;
|
||||
}
|
||||
|
||||
let start;
|
||||
k = ease(k);
|
||||
|
||||
function scrollAnim(currentTimestamp) {
|
||||
start = start || currentTimestamp;
|
||||
const x = ox + dx * k;
|
||||
const y = oy + dy * k;
|
||||
|
||||
let k = Math.min(1, (currentTimestamp - start) / ScrollTime);
|
||||
|
||||
if (k === 1) {
|
||||
resetScrollTimer();
|
||||
builtinScroll(xScroller, scrollX, yScroller, scrollY, false);
|
||||
return;
|
||||
}
|
||||
|
||||
k = ease(k);
|
||||
|
||||
const x = ox + dx * k;
|
||||
const y = oy + dy * k;
|
||||
|
||||
builtinScroll(xScroller, x, yScroller, y, false);
|
||||
|
||||
scrollTimer = requestAnimationFrame(scrollAnim);
|
||||
}
|
||||
builtinScroll(xScroller, x, yScroller, y, false);
|
||||
|
||||
scrollTimer = requestAnimationFrame(scrollAnim);
|
||||
}
|
||||
|
||||
/**
|
||||
scrollTimer = requestAnimationFrame(scrollAnim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs scroll.
|
||||
*
|
||||
* @param {HTMLElement} xScroller - Horizontal scroller.
|
||||
|
@ -465,142 +463,140 @@ import layoutManager from './layoutManager';
|
|||
* @param {number} scrollY - Vertical coordinate.
|
||||
* @param {boolean} smooth - Smooth scrolling.
|
||||
*/
|
||||
function doScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
|
||||
resetScrollTimer();
|
||||
function doScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
|
||||
resetScrollTimer();
|
||||
|
||||
if (smooth && useAnimatedScroll()) {
|
||||
animateScroll(xScroller, scrollX, yScroller, scrollY);
|
||||
} else {
|
||||
builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth);
|
||||
}
|
||||
if (smooth && useAnimatedScroll()) {
|
||||
animateScroll(xScroller, scrollX, yScroller, scrollY);
|
||||
} else {
|
||||
builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns true if smooth scroll must be used.
|
||||
*/
|
||||
function useSmoothScroll() {
|
||||
return !!browser.tizen;
|
||||
}
|
||||
function useSmoothScroll() {
|
||||
return !!browser.tizen;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns true if animated implementation of smooth scroll must be used.
|
||||
*/
|
||||
function useAnimatedScroll() {
|
||||
// Add block to force using (or not) of animated implementation
|
||||
function useAnimatedScroll() {
|
||||
// Add block to force using (or not) of animated implementation
|
||||
|
||||
return !supportsSmoothScroll;
|
||||
}
|
||||
return !supportsSmoothScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns true if scroll manager is enabled.
|
||||
*/
|
||||
export function isEnabled() {
|
||||
return layoutManager.tv;
|
||||
}
|
||||
export function isEnabled() {
|
||||
return layoutManager.tv;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Scrolls the document to a given position.
|
||||
*
|
||||
* @param {number} scrollX - Horizontal coordinate.
|
||||
* @param {number} scrollY - Vertical coordinate.
|
||||
* @param {boolean} [smooth=false] - Smooth scrolling.
|
||||
*/
|
||||
export function scrollTo(scrollX, scrollY, smooth) {
|
||||
smooth = !!smooth;
|
||||
export function scrollTo(scrollX, scrollY, smooth) {
|
||||
smooth = !!smooth;
|
||||
|
||||
// Scroller is document itself by default
|
||||
const scroller = getScrollableParent(null, false);
|
||||
// Scroller is document itself by default
|
||||
const scroller = getScrollableParent(null, false);
|
||||
|
||||
const xScrollerData = getScrollerData(scroller, false);
|
||||
const yScrollerData = getScrollerData(scroller, true);
|
||||
const xScrollerData = getScrollerData(scroller, false);
|
||||
const yScrollerData = getScrollerData(scroller, true);
|
||||
|
||||
scrollX = clamp(Math.round(scrollX), 0, xScrollerData.scrollSize - xScrollerData.clientSize);
|
||||
scrollY = clamp(Math.round(scrollY), 0, yScrollerData.scrollSize - yScrollerData.clientSize);
|
||||
scrollX = clamp(Math.round(scrollX), 0, xScrollerData.scrollSize - xScrollerData.clientSize);
|
||||
scrollY = clamp(Math.round(scrollY), 0, yScrollerData.scrollSize - yScrollerData.clientSize);
|
||||
|
||||
doScroll(scroller, scrollX, scroller, scrollY, smooth);
|
||||
}
|
||||
doScroll(scroller, scrollX, scroller, scrollY, smooth);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Scrolls the document to a given element.
|
||||
*
|
||||
* @param {HTMLElement} element - Target element of scroll task.
|
||||
* @param {boolean} [smooth=false] - Smooth scrolling.
|
||||
*/
|
||||
export function scrollToElement(element, smooth) {
|
||||
smooth = !!smooth;
|
||||
export function scrollToElement(element, smooth) {
|
||||
smooth = !!smooth;
|
||||
|
||||
let scrollCenterX = true;
|
||||
let scrollCenterY = true;
|
||||
let scrollCenterX = true;
|
||||
let scrollCenterY = true;
|
||||
|
||||
const offsetParent = element.offsetParent;
|
||||
const offsetParent = element.offsetParent;
|
||||
|
||||
// In Firefox offsetParent.offsetParent is BODY
|
||||
const isFixed = offsetParent && (!offsetParent.offsetParent || window.getComputedStyle(offsetParent).position === 'fixed');
|
||||
// In Firefox offsetParent.offsetParent is BODY
|
||||
const isFixed = offsetParent && (!offsetParent.offsetParent || window.getComputedStyle(offsetParent).position === 'fixed');
|
||||
|
||||
// Scroll fixed elements to nearest edge (or do not scroll at all)
|
||||
if (isFixed) {
|
||||
scrollCenterX = scrollCenterY = false;
|
||||
}
|
||||
|
||||
let xScroller = getScrollableParent(element, false);
|
||||
let yScroller = getScrollableParent(element, true);
|
||||
|
||||
const xScrollerData = getScrollerData(xScroller, false);
|
||||
const yScrollerData = getScrollerData(yScroller, true);
|
||||
|
||||
// Exit, since we have no control over scrolling in this container
|
||||
if (xScroller === yScroller && (xScrollerData.custom || yScrollerData.custom)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit, since we have no control over scrolling in these containers
|
||||
if (xScrollerData.custom && yScrollerData.custom) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
|
||||
let scrollX = 0;
|
||||
let scrollY = 0;
|
||||
|
||||
if (!xScrollerData.custom) {
|
||||
const xPos = getScrollerChildPos(xScroller, element, false);
|
||||
scrollX = calcScroll(xScrollerData, xPos, elementRect.width, scrollCenterX);
|
||||
} else {
|
||||
xScroller = null;
|
||||
}
|
||||
|
||||
if (!yScrollerData.custom) {
|
||||
const yPos = getScrollerChildPos(yScroller, element, true);
|
||||
scrollY = calcScroll(yScrollerData, yPos, elementRect.height, scrollCenterY);
|
||||
|
||||
// HACK: Scroll to top for top menu because it is hidden
|
||||
// FIXME: Need a marker to scroll top/bottom
|
||||
if (isFixed && elementRect.bottom < 0) {
|
||||
scrollY = 0;
|
||||
}
|
||||
|
||||
// HACK: Ensure we are at the top
|
||||
// FIXME: Need a marker to scroll top/bottom
|
||||
if (scrollY < minimumScrollY() && yScroller === documentScroller) {
|
||||
scrollY = 0;
|
||||
}
|
||||
} else {
|
||||
yScroller = null;
|
||||
}
|
||||
|
||||
doScroll(xScroller, scrollX, yScroller, scrollY, smooth);
|
||||
// Scroll fixed elements to nearest edge (or do not scroll at all)
|
||||
if (isFixed) {
|
||||
scrollCenterX = scrollCenterY = false;
|
||||
}
|
||||
|
||||
if (isEnabled()) {
|
||||
dom.addEventListener(window, 'focusin', function(e) {
|
||||
setTimeout(function() {
|
||||
scrollToElement(e.target, useSmoothScroll());
|
||||
}, 0);
|
||||
}, { capture: true });
|
||||
let xScroller = getScrollableParent(element, false);
|
||||
let yScroller = getScrollableParent(element, true);
|
||||
|
||||
const xScrollerData = getScrollerData(xScroller, false);
|
||||
const yScrollerData = getScrollerData(yScroller, true);
|
||||
|
||||
// Exit, since we have no control over scrolling in this container
|
||||
if (xScroller === yScroller && (xScrollerData.custom || yScrollerData.custom)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* eslint-enable indent */
|
||||
// Exit, since we have no control over scrolling in these containers
|
||||
if (xScrollerData.custom && yScrollerData.custom) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
|
||||
let scrollX = 0;
|
||||
let scrollY = 0;
|
||||
|
||||
if (!xScrollerData.custom) {
|
||||
const xPos = getScrollerChildPos(xScroller, element, false);
|
||||
scrollX = calcScroll(xScrollerData, xPos, elementRect.width, scrollCenterX);
|
||||
} else {
|
||||
xScroller = null;
|
||||
}
|
||||
|
||||
if (!yScrollerData.custom) {
|
||||
const yPos = getScrollerChildPos(yScroller, element, true);
|
||||
scrollY = calcScroll(yScrollerData, yPos, elementRect.height, scrollCenterY);
|
||||
|
||||
// HACK: Scroll to top for top menu because it is hidden
|
||||
// FIXME: Need a marker to scroll top/bottom
|
||||
if (isFixed && elementRect.bottom < 0) {
|
||||
scrollY = 0;
|
||||
}
|
||||
|
||||
// HACK: Ensure we are at the top
|
||||
// FIXME: Need a marker to scroll top/bottom
|
||||
if (scrollY < minimumScrollY() && yScroller === documentScroller) {
|
||||
scrollY = 0;
|
||||
}
|
||||
} else {
|
||||
yScroller = null;
|
||||
}
|
||||
|
||||
doScroll(xScroller, scrollX, yScroller, scrollY, smooth);
|
||||
}
|
||||
|
||||
if (isEnabled()) {
|
||||
dom.addEventListener(window, 'focusin', function(e) {
|
||||
setTimeout(function() {
|
||||
scrollToElement(e.target, useSmoothScroll());
|
||||
}, 0);
|
||||
}, { capture: true });
|
||||
}
|
||||
|
||||
export default {
|
||||
isEnabled: isEnabled,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue