diff --git a/src/elements/emby-button/emby-button.js b/src/elements/emby-button/emby-button.js index b986fcba1..3d911c6e3 100644 --- a/src/elements/emby-button/emby-button.js +++ b/src/elements/emby-button/emby-button.js @@ -1,3 +1,4 @@ +import 'webcomponents.js/webcomponents-lite'; import { removeEventListener, addEventListener } from '../../scripts/dom'; import layoutManager from '../../components/layoutManager'; import shell from '../../scripts/shell'; @@ -5,61 +6,8 @@ import { appRouter } from '../../components/appRouter'; import { appHost } from '../../components/apphost'; import './emby-button.css'; -class EmbyButton extends HTMLButtonElement { - createdCallback() { - if (this.classList.contains('emby-button')) { - return; - } - - this.classList.add('emby-button'); - // TODO replace all instances of element-showfocus with this method - if (layoutManager.tv) { - // handles all special css for tv layout - // this method utilizes class chaining - this.classList.add('show-focus'); - } - } - - attachedCallback() { - if (this.tagName === 'A') { - removeEventListener(this, 'click', onAnchorClick, {}); - addEventListener(this, 'click', onAnchorClick, {}); - - if (this.getAttribute('data-autohide') === 'true') { - if (appHost.supports('externallinks')) { - this.classList.remove('hide'); - } else { - this.classList.add('hide'); - } - } - } - } - - detachedCallback() { - removeEventListener(this, 'click', onAnchorClick, {}); - } -} - -class EmbyLinkButton extends HTMLAnchorElement { - attachedCallback() { - if (this.tagName === 'A') { - removeEventListener(this, 'click', onAnchorClick, {}); - addEventListener(this, 'click', onAnchorClick, {}); - - if (this.getAttribute('data-autohide') === 'true') { - if (appHost.supports('externallinks')) { - this.classList.remove('hide'); - } else { - this.classList.add('hide'); - } - } - } - } - - detachedCallback() { - removeEventListener(this, 'click', onAnchorClick, {}); - } -} +const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); +const EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype); function onAnchorClick(e) { const href = this.getAttribute('href') || ''; @@ -77,8 +25,50 @@ function onAnchorClick(e) { } } -customElements.define('emby-button', EmbyButton, { extends: 'button' }); +EmbyButtonPrototype.createdCallback = function () { + if (this.classList.contains('emby-button')) { + return; + } -customElements.define('emby-linkbutton', EmbyLinkButton, { extends: 'a' }); + this.classList.add('emby-button'); + // TODO replace all instances of element-showfocus with this method + if (layoutManager.tv) { + // handles all special css for tv layout + // this method utilizes class chaining + this.classList.add('show-focus'); + } +}; -export default EmbyButton; +EmbyButtonPrototype.attachedCallback = function () { + if (this.tagName === 'A') { + removeEventListener(this, 'click', onAnchorClick, {}); + addEventListener(this, 'click', onAnchorClick, {}); + + if (this.getAttribute('data-autohide') === 'true') { + if (appHost.supports('externallinks')) { + this.classList.remove('hide'); + } else { + this.classList.add('hide'); + } + } + } +}; + +EmbyButtonPrototype.detachedCallback = function () { + removeEventListener(this, 'click', onAnchorClick, {}); +}; + +EmbyLinkButtonPrototype.createdCallback = EmbyButtonPrototype.createdCallback; +EmbyLinkButtonPrototype.attachedCallback = EmbyButtonPrototype.attachedCallback; + +document.registerElement('emby-button', { + prototype: EmbyButtonPrototype, + extends: 'button' +}); + +document.registerElement('emby-linkbutton', { + prototype: EmbyLinkButtonPrototype, + extends: 'a' +}); + +export default EmbyButtonPrototype; diff --git a/src/elements/emby-tabs/emby-tabs.js b/src/elements/emby-tabs/emby-tabs.js index 9b7dd794d..ebe46f916 100644 --- a/src/elements/emby-tabs/emby-tabs.js +++ b/src/elements/emby-tabs/emby-tabs.js @@ -1,12 +1,13 @@ +import 'webcomponents.js/webcomponents-lite'; import dom from '../../scripts/dom'; import scroller from '../../libraries/scroller'; import browser from '../../scripts/browser'; import focusManager from '../../components/focusManager'; -import 'webcomponents.js/webcomponents-lite'; import './emby-tabs.css'; import '../../assets/css/scrollstyles.css'; /* eslint-disable indent */ + const EmbyTabs = Object.create(HTMLDivElement.prototype); const buttonClass = 'emby-tab-button'; const activeButtonClass = buttonClass + '-active'; @@ -143,181 +144,182 @@ import '../../assets/css/scrollstyles.css'; } } - class EmbyTabs extends HTMLDivElement { - createdCallback() { - if (this.classList.contains('emby-tabs')) { - return; - } - this.classList.add('emby-tabs'); - this.classList.add('focusable'); - - dom.addEventListener(this, 'click', onClick, { - passive: true - }); - - dom.addEventListener(this, 'focusout', onFocusOut); + EmbyTabs.createdCallback = function () { + if (this.classList.contains('emby-tabs')) { + return; } + this.classList.add('emby-tabs'); + this.classList.add('focusable'); - focus() { - const selected = this.querySelector('.' + activeButtonClass); + dom.addEventListener(this, 'click', onClick, { + passive: true + }); - if (this.lastFocused) { - focusManager.focus(this.lastFocused); - } else if (this.selectedTab) { - focusManager.focus(this.selectedTab); - } else { - focusManager.autoFocus(this); + dom.addEventListener(this, 'focusout', onFocusOut); + }; + + EmbyTabs.focus = function onFocusIn() { + const selectedTab = this.querySelector('.' + activeButtonClass); + const lastFocused = this.querySelector('.lastFocused'); + + if (lastFocused) { + focusManager.focus(lastFocused); + } else if (selectedTab) { + focusManager.focus(selectedTab); + } else { + focusManager.autoFocus(this); + } + }; + + EmbyTabs.refresh = function () { + if (this.scroller) { + this.scroller.reload(); + } + }; + + EmbyTabs.attachedCallback = function () { + initScroller(this); + + const current = this.querySelector('.' + activeButtonClass); + const currentIndex = current ? parseInt(current.getAttribute('data-index')) : parseInt(this.getAttribute('data-index') || '0'); + + if (currentIndex !== -1) { + this.selectedTabIndex = currentIndex; + + const tabButtons = this.querySelectorAll('.' + buttonClass); + + const newTabButton = tabButtons[currentIndex]; + + if (newTabButton) { + setActiveTabButton(newTabButton); } } - refresh() { - if (this.scroller) { - this.scroller.reload(); - } + if (!this.readyFired) { + this.readyFired = true; + this.dispatchEvent(new CustomEvent('ready', {})); + } + }; + + EmbyTabs.detachedCallback = function () { + if (this.scroller) { + this.scroller.destroy(); + this.scroller = null; } - attachedCallback() { - console.warn(this); - initScroller(this); + dom.removeEventListener(this, 'click', onClick, { + passive: true + }); + }; - const current = this.querySelector('.' + activeButtonClass); - const currentIndex = current ? parseInt(current.getAttribute('data-index')) : parseInt(this.getAttribute('data-index') || '0'); + function getSelectedTabButton(elem) { + return elem.querySelector('.' + activeButtonClass); + } - if (currentIndex !== -1) { - this.selectedTabIndex = currentIndex; + EmbyTabs.selectedIndex = function (selected, triggerEvent) { + const tabs = this; - const tabButtons = this.querySelectorAll('.' + buttonClass); - - const newTabButton = tabButtons[currentIndex]; - - if (newTabButton) { - setActiveTabButton(newTabButton); - } - } - - if (!this.readyFired) { - this.readyFired = true; - this.dispatchEvent(new CustomEvent('ready', {})); - } + if (selected == null) { + return tabs.selectedTabIndex || 0; } - detachedCallback() { - if (this.scroller) { - this.scroller.destroy(); - this.scroller = null; - } + const current = tabs.selectedIndex(); - dom.removeEventListener(this, 'click', onClick, { - passive: true - }); - } + tabs.selectedTabIndex = selected; - getSelectedTabButton(elem) { - return elem.querySelector('.' + activeButtonClass); - } + const tabButtons = tabs.querySelectorAll('.' + buttonClass); - selectedIndex(selected, triggerEvent) { - const tabs = this; - - if (selected == null) { - return tabs.selectedTabIndex || 0; - } - - const current = tabs.selectedIndex(); - - tabs.selectedTabIndex = selected; - - const tabButtons = tabs.querySelectorAll('.' + buttonClass); - - if (current === selected || triggerEvent === false) { - triggerBeforeTabChange(tabs, selected, current); - - tabs.dispatchEvent(new CustomEvent('tabchange', { - detail: { - selectedTabIndex: selected - } - })); - - const currentTabButton = tabButtons[current]; - setActiveTabButton(tabButtons[selected]); - - if (current !== selected && currentTabButton) { - currentTabButton.classList.remove(activeButtonClass); - } - } else { - onClick.call(tabs, { - target: tabButtons[selected] - }); - } - } - - getSibling(elem, method) { - let sibling = elem[method]; - - while (sibling) { - if (sibling.classList.contains(buttonClass)) { - if (!sibling.classList.contains('hide')) { - return sibling; - } - } - - sibling = sibling[method]; - } - - return null; - } - - selectNext() { - const current = this.getSelectedTabButton(this); - - const sibling = this.getSibling(current, 'nextSibling'); - - if (sibling) { - onClick.call(this, { - target: sibling - }); - } - } - - selectPrevious() { - const current = this.getSelectedTabButton(this); - - const sibling = this.getSibling(current, 'previousSibling'); - - if (sibling) { - onClick.call(this, { - target: sibling - }); - } - } - - triggerBeforeTabChange(selected) { - const tabs = this; - - triggerBeforeTabChange(tabs, tabs.selectedIndex()); - } - - triggerTabChange(selected) { - const tabs = this; + if (current === selected || triggerEvent === false) { + triggerBeforeTabChange(tabs, selected, current); tabs.dispatchEvent(new CustomEvent('tabchange', { detail: { - selectedTabIndex: tabs.selectedIndex() + selectedTabIndex: selected } })); - } - setTabEnabled(index, enabled) { - const btn = this.querySelector('.emby-tab-button[data-index="' + index + '"]'); + const currentTabButton = tabButtons[current]; + setActiveTabButton(tabButtons[selected]); - if (enabled) { - btn.classList.remove('hide'); - } else { - btn.classList.remove('add'); + if (current !== selected && currentTabButton) { + currentTabButton.classList.remove(activeButtonClass); } + } else { + onClick.call(tabs, { + target: tabButtons[selected] + }); } + }; + + function getSibling(elem, method) { + let sibling = elem[method]; + + while (sibling) { + if (sibling.classList.contains(buttonClass)) { + if (!sibling.classList.contains('hide')) { + return sibling; + } + } + + sibling = sibling[method]; + } + + return null; } - customElements.define('emby-tabs', EmbyTabs, { extends: 'div' }); + EmbyTabs.selectNext = function () { + const current = getSelectedTabButton(this); + + const sibling = getSibling(current, 'nextSibling'); + + if (sibling) { + onClick.call(this, { + target: sibling + }); + } + }; + + EmbyTabs.selectPrevious = function () { + const current = getSelectedTabButton(this); + + const sibling = getSibling(current, 'previousSibling'); + + if (sibling) { + onClick.call(this, { + target: sibling + }); + } + }; + + EmbyTabs.triggerBeforeTabChange = function (selected) { + const tabs = this; + + triggerBeforeTabChange(tabs, tabs.selectedIndex()); + }; + + EmbyTabs.triggerTabChange = function (selected) { + const tabs = this; + + tabs.dispatchEvent(new CustomEvent('tabchange', { + detail: { + selectedTabIndex: tabs.selectedIndex() + } + })); + }; + + EmbyTabs.setTabEnabled = function (index, enabled) { + const btn = this.querySelector('.emby-tab-button[data-index="' + index + '"]'); + + if (enabled) { + btn.classList.remove('hide'); + } else { + btn.classList.remove('add'); + } + }; + + document.registerElement('emby-tabs', { + prototype: EmbyTabs, + extends: 'div' + }); /* eslint-enable indent */