diff --git a/.eslintrc.yml b/.eslintrc.yml index 57df44775a..64ee42cc0f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -97,6 +97,75 @@ settings: - document.registerElement # resize-observer-polyfill - ResizeObserver + # fast-text-encoding + - TextEncoder + # intersection-observer + - IntersectionObserver # Core-js - - Array.from - Object.assign + - Object.is + - Object.setPrototypeOf + - Object.toString + - Object.freeze + - Object.seal + - Object.preventExtensions + - Object.isFrozen + - Object.isSealed + - Object.isExtensible + - Object.getOwnPropertyDescriptor + - Object.getPrototypeOf + - Object.keys + - Object.getOwnPropertyNames + - Function.name + - Function.hasInstance + - Array.from + - Array.arrayOf + - Array.copyWithin + - Array.fill + - Array.find + - Array.findIndex + - Array.iterator + - String.fromCodePoint + - String.raw + - String.iterator + - String.codePointAt + - String.endsWith + - String.includes + - String.repeat + - String.startsWith + - String.trim + - String.anchor + - String.big + - String.blink + - String.bold + - String.fixed + - String.fontcolor + - String.fontsize + - String.italics + - String.link + - String.small + - String.strike + - String.sub + - String.sup + - RegExp + - Number + - Math + - Date + - async + - Symbol + - Map + - Set + - WeakMap + - WeakSet + - ArrayBuffer + - DataView + - Int8Array + - Uint8Array + - Uint8ClampedArray + - Int16Array + - Uint16Array + - Int32Array + - Uint32Array + - Float32Array + - Float64Array + - Reflect diff --git a/package.json b/package.json index 86d1fffcc8..5360c1b98f 100644 --- a/package.json +++ b/package.json @@ -58,9 +58,11 @@ "core-js": "^3.6.4", "date-fns": "^2.11.1", "document-register-element": "^1.14.3", + "fast-text-encoding": "^1.0.1", "flv.js": "^1.5.0", "hls.js": "^0.13.1", "howler": "^2.1.3", + "intersection-observer": "^0.7.0", "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jquery": "^3.4.1", "jstree": "^3.3.7", diff --git a/src/bundle.js b/src/bundle.js index 316f42c94a..ed6518447f 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -123,3 +123,13 @@ var date_fns_locale = require("date-fns/locale"); _define("date-fns/locale", function () { return date_fns_locale; }); + +var fast_text_encoding = require("fast-text-encoding"); +_define("fast-text-encoding", function () { + return fast_text_encoding; +}); + +var intersection_observer = require("intersection-observer"); +_define("intersection-observer", function () { + return intersection_observer; +}); diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 62bfb3cf40..c4ecede60f 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -268,6 +268,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM } function getMaxBandwidth() { + /* eslint-disable compat/compat */ if (navigator.connection) { var max = navigator.connection.downlinkMax; if (max && max > 0 && max < Number.POSITIVE_INFINITY) { @@ -279,6 +280,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM return max; } } + /* eslint-enable compat/compat */ return null; } diff --git a/src/components/apphost.js b/src/components/apphost.js index 868416b369..294ecb09f0 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -453,6 +453,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f if (doc) { doc.addEventListener(visibilityChange, function () { + /* eslint-disable-next-line compat/compat */ if (document[visibilityState]) { onAppHidden(); } else { diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 338b8e6fef..5270ba4b9e 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -31,7 +31,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } function enableHlsShakaPlayer(item, mediaSource, mediaType) { - + /* eslint-disable-next-line compat/compat */ if (!!window.MediaSource && !!MediaSource.isTypeSupported) { if (canPlayNativeHls()) { diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 764be06fd1..28b6923c33 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -1,10 +1,6 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', 'userSettings', 'require', 'css!./style'], function (lazyLoader, imageFetcher, layoutManager, browser, appSettings, userSettings, require) { 'use strict'; - var requestIdleCallback = window.requestIdleCallback || function (fn) { - fn(); - }; - var self = {}; function fillImage(elem, source, enableEffects) { diff --git a/src/components/input/gamepadtokey.js b/src/components/input/gamepadtokey.js index 5356bcbb45..71cbe87cd6 100644 --- a/src/components/input/gamepadtokey.js +++ b/src/components/input/gamepadtokey.js @@ -184,7 +184,7 @@ require(['apphost'], function (appHost) { function allowInput() { // This would be nice but always seems to return true with electron - if (!isElectron && document.hidden) { + if (!isElectron && document.hidden) { /* eslint-disable-line compat/compat */ return false; } @@ -254,7 +254,7 @@ require(['apphost'], function (appHost) { var inputLoopTimer; function runInputLoop() { // Get the latest gamepad state. - var gamepads = navigator.getGamepads(); + var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */ for (var i = 0, len = gamepads.length; i < len; i++) { var gamepad = gamepads[i]; if (!gamepad) { @@ -362,7 +362,7 @@ require(['apphost'], function (appHost) { } function isGamepadConnected() { - var gamepads = navigator.getGamepads(); + var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */ for (var i = 0, len = gamepads.length; i < len; i++) { var gamepad = gamepads[i]; if (gamepad && gamepad.connected) { @@ -373,6 +373,7 @@ require(['apphost'], function (appHost) { } function onFocusOrGamepadAttach(e) { + /* eslint-disable-next-line compat/compat */ if (isGamepadConnected() && document.hasFocus()) { console.log("Gamepad connected! Starting input loop"); startInputLoop(); @@ -380,6 +381,7 @@ require(['apphost'], function (appHost) { } function onFocusOrGamepadDetach(e) { + /* eslint-disable-next-line compat/compat */ if (!isGamepadConnected() || !document.hasFocus()) { console.log("Gamepad disconnected! No other gamepads are connected, stopping input loop"); stopInputLoop(); @@ -401,7 +403,7 @@ require(['apphost'], function (appHost) { if (window.navigator && typeof window.navigator.gamepadInputEmulation === "string") { // We want the gamepad to provide gamepad VK keyboard events rather than moving a // mouse like cursor. Set to "keyboard", the gamepad will provide such keyboard events - // and provide input to the DOM navigator.getGamepads API. + // and provide input to tonFocusOrGamepadDetachhe DOM navigator.getGamepads API. window.navigator.gamepadInputEmulation = "gamepad"; } diff --git a/src/components/input/keyboardnavigation.js b/src/components/input/keyboardnavigation.js index d356854a3e..3c80063f4f 100644 --- a/src/components/input/keyboardnavigation.js +++ b/src/components/input/keyboardnavigation.js @@ -159,7 +159,9 @@ function attachGamepadScript(e) { } // No need to check for gamepads manually at load time, the eventhandler will be fired for that -window.addEventListener("gamepadconnected", attachGamepadScript); +if (navigator.getGamepads) { /* eslint-disable-line compat/compat */ + window.addEventListener("gamepadconnected", attachGamepadScript); +} export default { enable: enable, diff --git a/src/components/itemcontextmenu.js b/src/components/itemcontextmenu.js index bdbcfc782b..9d683aa27c 100644 --- a/src/components/itemcontextmenu.js +++ b/src/components/itemcontextmenu.js @@ -352,6 +352,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", document.body.appendChild(textArea); textArea.focus(); textArea.select(); + if (document.execCommand("copy")) { require(["toast"], function (toast) { toast(globalize.translate("CopyStreamURLSuccess")); @@ -361,14 +362,19 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", } document.body.removeChild(textArea); }; + + /* eslint-disable-next-line compat/compat */ if (navigator.clipboard === undefined) { textAreaCopy(); } else { + /* eslint-disable-next-line compat/compat */ navigator.clipboard.writeText(downloadHref).then(function () { require(["toast"], function (toast) { toast(globalize.translate("CopyStreamURLSuccess")); }); - }, textAreaCopy); + }).catch(function () { + textAreaCopy(); + }); } getResolveFunction(resolve, id)(); break; diff --git a/src/components/lazyloader/lazyloader-scroll.js b/src/components/lazyloader/lazyloader-scroll.js index d5120146ce..4930f6376c 100644 --- a/src/components/lazyloader/lazyloader-scroll.js +++ b/src/components/lazyloader/lazyloader-scroll.js @@ -4,10 +4,6 @@ define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom var thresholdX; var thresholdY; - var requestIdleCallback = window.requestIdleCallback || function (fn) { - fn(); - }; - function resetThresholds() { var threshold = 0.3; diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index c8a79a3627..8ba870613b 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -6,6 +6,7 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir document.removeEventListener('keydown', onOneDocumentClick); if (window.Notification) { + /* eslint-disable-next-line compat/compat */ Notification.requestPermission(); } } @@ -26,6 +27,7 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'requir } function resetRegistration() { + /* eslint-disable-next-line compat/compat */ var serviceWorker = navigator.serviceWorker; if (serviceWorker) { serviceWorker.ready.then(function (registration) { diff --git a/src/components/playback/playbackorientation.js b/src/components/playback/playbackorientation.js index 5b178dbf08..5836298ead 100644 --- a/src/components/playback/playbackorientation.js +++ b/src/components/playback/playbackorientation.js @@ -17,6 +17,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player); if (isLocalVideo && layoutManager.mobile) { + /* eslint-disable-next-line compat/compat */ var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock); if (lockOrientation) { @@ -40,6 +41,7 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager if (orientationLocked && !playbackStopInfo.nextMediaType) { + /* eslint-disable-next-line compat/compat */ var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock); if (unlockOrientation) { diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index c61fd14a7a..f71eb0e095 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -1152,7 +1152,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med case "GamepadDPadLeft": case "GamepadLeftThumbstickLeft": // Ignores gamepad events that are always triggered, even when not focused. - if (document.hasFocus()) { + if (document.hasFocus()) { /* eslint-disable-line compat/compat */ playbackManager.rewind(currentPlayer); showOsd(); } @@ -1161,7 +1161,7 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med case "GamepadDPadRight": case "GamepadLeftThumbstickRight": // Ignores gamepad events that are always triggered, even when not focused. - if (document.hasFocus()) { + if (document.hasFocus()) { /* eslint-disable-line compat/compat */ playbackManager.fastForward(currentPlayer); showOsd(); } diff --git a/src/scripts/browser.js b/src/scripts/browser.js index 19153bb19f..f89df82c0c 100644 --- a/src/scripts/browser.js +++ b/src/scripts/browser.js @@ -292,6 +292,7 @@ define([], function () { } if (typeof document !== 'undefined') { + /* eslint-disable-next-line compat/compat */ if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0)) { browser.touch = true; } diff --git a/src/scripts/site.js b/src/scripts/site.js index 5eb3c2a346..f39088b380 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -612,13 +612,17 @@ var AppInfo = {}; } function registerServiceWorker() { - if (navigator.serviceWorker && "cordova" !== self.appMode && "android" !== self.appMode) { + /* eslint-disable compat/compat */ + if (navigator.serviceWorker && self.appMode !== "cordova" && self.appMode !== "android") { try { navigator.serviceWorker.register("serviceworker.js"); } catch (err) { console.error("error registering serviceWorker: " + err); } + } else { + console.warn("serviceWorker unsupported"); } + /* eslint-enable compat/compat */ } function onWebComponentsReady(browser) { @@ -696,7 +700,9 @@ var AppInfo = {}; "jellyfin-noto", "date-fns", "page", - "polyfill" + "polyfill", + "fast-text-encoding", + "intersection-observer" ] }, urlArgs: urlArgs, @@ -705,6 +711,8 @@ var AppInfo = {}; }); require(["polyfill"]); + require(["fast-text-encoding"]); + require(["intersection-observer"]); // Expose jQuery globally require(["jQuery"], function(jQuery) { diff --git a/yarn.lock b/yarn.lock index 817a8e0ae8..9b0484b163 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4365,6 +4365,11 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-text-encoding@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.1.tgz#4a428566f74fc55ebdd447555b1eb4d9cf514455" + integrity sha512-x4FEgaz3zNRtJfLFqJmHWxkMDDvXVtaznj2V9jiP8ACUJrUgist4bP9FmDL2Vew2Y9mEQI/tG4GqabaitYp9CQ== + fastq@^1.6.0: version "1.6.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.1.tgz#4570c74f2ded173e71cf0beb08ac70bb85826791" @@ -5977,6 +5982,11 @@ interpret@1.2.0, interpret@^1.1.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== +intersection-observer@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.7.0.tgz#ee16bee978db53516ead2f0a8154b09b400bbdc9" + integrity sha512-Id0Fij0HsB/vKWGeBe9PxeY45ttRiBmhFyyt/geBdDHBYNctMRTE3dC1U3ujzz3lap+hVXlEcVaB56kZP/eEUg== + into-stream@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6"