1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/src/elements/emby-scroller/emby-scroller.js

202 lines
6.5 KiB
JavaScript
Raw Normal View History

2020-08-14 08:46:34 +02:00
import scroller from '../../libraries/scroller';
import dom from '../../scripts/dom';
import layoutManager from '../../components/layoutManager';
import inputManager from '../../scripts/inputManager';
import focusManager from '../../components/focusManager';
import browser from '../../scripts/browser';
2020-09-08 02:43:56 -04:00
import 'webcomponents.js/webcomponents-lite';
2021-01-26 15:42:02 -05:00
import './emby-scroller.scss';
/* eslint-disable indent */
2020-07-17 10:33:31 +02:00
const ScrollerPrototype = Object.create(HTMLDivElement.prototype);
ScrollerPrototype.createdCallback = function () {
2020-09-08 15:43:19 -04:00
this.classList.add('emby-scroller');
};
2018-10-23 01:05:09 +03:00
function initCenterFocus(elem, scrollerInstance) {
dom.addEventListener(elem, 'focus', function (e) {
2020-07-11 11:23:28 +01:00
const focused = focusManager.focusableParent(e.target);
if (focused) {
scrollerInstance.toCenter(focused);
}
2018-10-23 01:05:09 +03:00
}, {
capture: true,
passive: true
});
2018-10-23 01:05:09 +03:00
}
ScrollerPrototype.scrollToBeginning = function () {
if (this.scroller) {
this.scroller.slideTo(0, true);
}
};
ScrollerPrototype.toStart = function (elem, immediate) {
if (this.scroller) {
this.scroller.toStart(elem, immediate);
}
};
ScrollerPrototype.toCenter = function (elem, immediate) {
if (this.scroller) {
this.scroller.toCenter(elem, immediate);
}
};
ScrollerPrototype.scrollToPosition = function (pos, immediate) {
if (this.scroller) {
this.scroller.slideTo(pos, immediate);
}
};
ScrollerPrototype.getScrollPosition = function () {
if (this.scroller) {
return this.scroller.getScrollPosition();
}
};
ScrollerPrototype.getScrollSize = function () {
if (this.scroller) {
return this.scroller.getScrollSize();
}
};
ScrollerPrototype.getScrollEventName = function () {
if (this.scroller) {
return this.scroller.getScrollEventName();
}
};
ScrollerPrototype.getScrollSlider = function () {
if (this.scroller) {
return this.scroller.getScrollSlider();
}
};
ScrollerPrototype.addScrollEventListener = function (fn, options) {
if (this.scroller) {
dom.addEventListener(this.scroller.getScrollFrame(), this.scroller.getScrollEventName(), fn, options);
}
};
ScrollerPrototype.removeScrollEventListener = function (fn, options) {
if (this.scroller) {
dom.removeEventListener(this.scroller.getScrollFrame(), this.scroller.getScrollEventName(), fn, options);
}
};
2018-10-23 01:05:09 +03:00
function onInputCommand(e) {
2020-07-11 11:23:28 +01:00
const cmd = e.detail.command;
if (cmd === 'end') {
focusManager.focusLast(this, '.' + this.getAttribute('data-navcommands'));
e.preventDefault();
e.stopPropagation();
} else if (cmd === 'pageup') {
focusManager.moveFocus(e.target, this, '.' + this.getAttribute('data-navcommands'), -12);
e.preventDefault();
e.stopPropagation();
} else if (cmd === 'pagedown') {
focusManager.moveFocus(e.target, this, '.' + this.getAttribute('data-navcommands'), 12);
e.preventDefault();
e.stopPropagation();
}
2018-10-23 01:05:09 +03:00
}
ScrollerPrototype.attachedCallback = function () {
if (this.getAttribute('data-navcommands')) {
inputManager.on(this, onInputCommand);
}
2020-07-11 11:23:28 +01:00
const horizontal = this.getAttribute('data-horizontal') !== 'false';
2020-07-11 11:23:28 +01:00
const slider = this.querySelector('.scrollSlider');
if (horizontal) {
slider.style['white-space'] = 'nowrap';
}
2020-07-11 11:23:28 +01:00
const scrollFrame = this;
const enableScrollButtons = layoutManager.desktop && horizontal && this.getAttribute('data-scrollbuttons') !== 'false';
2020-07-11 11:23:28 +01:00
const options = {
horizontal: horizontal,
mouseDragging: 1,
mouseWheel: this.getAttribute('data-mousewheel') !== 'false',
touchDragging: 1,
slidee: slider,
scrollBy: 200,
speed: horizontal ? 270 : 240,
elasticBounds: 1,
dragHandle: 1,
autoImmediate: true,
skipSlideToWhenVisible: this.getAttribute('data-skipfocuswhenvisible') === 'true',
2020-04-24 18:03:55 +02:00
dispatchScrollEvent: enableScrollButtons || this.getAttribute('data-scrollevent') === 'true',
hideScrollbar: enableScrollButtons || this.getAttribute('data-hidescrollbar') === 'true',
allowNativeSmoothScroll: this.getAttribute('data-allownativesmoothscroll') === 'true' && !enableScrollButtons,
allowNativeScroll: !enableScrollButtons,
forceHideScrollbars: enableScrollButtons,
// In edge, with the native scroll, the content jumps around when hovering over the buttons
requireAnimation: enableScrollButtons && browser.edge
};
// If just inserted it might not have any height yet - yes this is a hack
this.scroller = new scroller(scrollFrame, options);
this.scroller.init();
2019-05-23 00:04:48 -07:00
this.scroller.reload();
if (layoutManager.tv && this.getAttribute('data-centerfocus')) {
initCenterFocus(this, this.scroller);
}
if (enableScrollButtons) {
loadScrollButtons(this);
}
};
2022-10-16 16:04:37 +02:00
function loadScrollButtons(buttonsScroller) {
2020-08-14 08:46:34 +02:00
import('../emby-scrollbuttons/emby-scrollbuttons').then(() => {
2022-10-16 16:04:37 +02:00
buttonsScroller.insertAdjacentHTML('beforebegin', '<div is="emby-scrollbuttons" class="emby-scrollbuttons padded-right"></div>');
});
2018-10-23 01:05:09 +03:00
}
ScrollerPrototype.pause = function () {
2020-07-11 11:23:28 +01:00
const headroom = this.headroom;
if (headroom) {
headroom.pause();
}
};
ScrollerPrototype.resume = function () {
2020-07-11 11:23:28 +01:00
const headroom = this.headroom;
if (headroom) {
headroom.resume();
}
};
ScrollerPrototype.detachedCallback = function () {
if (this.getAttribute('data-navcommands')) {
inputManager.off(this, onInputCommand);
}
2020-07-11 11:23:28 +01:00
const headroom = this.headroom;
if (headroom) {
headroom.destroy();
this.headroom = null;
}
2020-07-11 11:23:28 +01:00
const scrollerInstance = this.scroller;
if (scrollerInstance) {
scrollerInstance.destroy();
this.scroller = null;
}
};
2020-09-08 15:43:19 -04:00
document.registerElement('emby-scroller', {
prototype: ScrollerPrototype,
extends: 'div'
});
/* eslint-enable indent */