From d1e2d8280736b7a5657595e602b2ca0d227827a5 Mon Sep 17 00:00:00 2001 From: Wesley Luyten Date: Sun, 18 Jun 2023 11:01:02 -0500 Subject: [PATCH] fix: use globalThis i/o window --- scripts/react/build.js | 12 +++---- src/js/controller.js | 6 ++-- src/js/experimental/media-captions-listbox.js | 8 ++--- .../experimental/media-captions-selectmenu.js | 6 ++-- src/js/experimental/media-chrome-listbox.js | 12 +++---- src/js/experimental/media-chrome-listitem.js | 8 ++--- .../experimental/media-chrome-selectmenu.js | 8 ++--- .../media-playback-rate-listbox.js | 8 ++--- .../media-playback-rate-selectmenu.js | 6 ++-- src/js/experimental/media-settings-popup.js | 8 ++--- src/js/extras/media-clip-selector/index.js | 32 +++++++++---------- src/js/media-airplay-button.js | 8 ++--- src/js/media-captions-button.js | 10 +++--- src/js/media-cast-button.js | 8 ++--- src/js/media-chrome-button.js | 8 ++--- src/js/media-chrome-range.js | 8 ++--- src/js/media-container.js | 20 ++++++------ src/js/media-control-bar.js | 8 ++--- src/js/media-controller.js | 28 ++++++++-------- src/js/media-duration-display.js | 6 ++-- src/js/media-fullscreen-button.js | 8 ++--- src/js/media-gesture-receiver.js | 10 +++--- src/js/media-live-button.js | 13 +++----- src/js/media-loading-indicator.js | 8 ++--- src/js/media-mute-button.js | 8 ++--- src/js/media-pip-button.js | 8 ++--- src/js/media-play-button.js | 8 ++--- src/js/media-playback-rate-button.js | 8 ++--- src/js/media-poster-image.js | 8 ++--- src/js/media-preview-thumbnail.js | 8 ++--- src/js/media-preview-time-display.js | 6 ++-- src/js/media-seek-backward-button.js | 8 ++--- src/js/media-seek-forward-button.js | 8 ++--- src/js/media-text-display.js | 8 ++--- src/js/media-theme-element.js | 8 ++--- src/js/media-time-display.js | 6 ++-- src/js/media-time-range.js | 22 ++++++------- src/js/media-volume-range.js | 8 ++--- src/js/themes/demuxed-2022.js | 8 ++--- src/js/themes/microvideo.js | 6 ++-- src/js/themes/minimal.js | 6 ++-- src/js/themes/netflix.js | 6 ++-- src/js/themes/responsive.js | 6 ++-- src/js/themes/winamp.js | 6 ++-- src/js/themes/youtube.js | 6 ++-- src/js/utils/platform-tests.js | 6 ++-- src/js/utils/server-safe-globals.js | 18 ++++++++--- src/js/utils/template-parts.js | 4 +-- 48 files changed, 227 insertions(+), 224 deletions(-) diff --git a/scripts/react/build.js b/scripts/react/build.js index 046716175..6b9142cfc 100644 --- a/scripts/react/build.js +++ b/scripts/react/build.js @@ -243,15 +243,13 @@ const setupGlobalsAsync = async () => { const customElementNames = await import( path.join(projectRoot, 'dist', 'utils', 'server-safe-globals.js') ).then((exports) => { - globalThis.window = exports.Window; - globalThis.document = exports.Document; - globalThis.window.document = globalThis.document; - window.customElementNames = []; - window.customElements.define = (name, _classRef) => - window.customElementNames.push(name); + Object.assign(globalThis, exports.globalThis); + globalThis.customElementNames = []; + globalThis.customElements.define = (name, _classRef) => + globalThis.customElementNames.push(name); // NOTE: The current implementation relies on the fact that `customElementNames` will be mutated // to add the Custom Element html name for every element that's defined as a result of loading/importing the entryPoints modules (CJP). - return window.customElementNames; + return globalThis.customElementNames; }); return customElementNames; }; diff --git a/src/js/controller.js b/src/js/controller.js index 42cda9ad3..61eec0e93 100644 --- a/src/js/controller.js +++ b/src/js/controller.js @@ -1,4 +1,4 @@ -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { fullscreenApi } from './utils/fullscreen-api.js'; import { containsComposedNode } from './utils/element-utils.js'; import { @@ -511,7 +511,7 @@ export const MediaUIRequestHandlers = { if (!mediaController.hasAttribute('novolumepref')) { // Store the last set volume as a local preference, if ls is supported try { - window.localStorage.setItem( + globalThis.localStorage.setItem( 'media-chrome-pref-volume', volume.toString() ); @@ -742,7 +742,7 @@ export const MediaUIRequestHandlers = { if ( !( media.webkitShowPlaybackTargetPicker && - window.WebKitPlaybackTargetAvailabilityEvent + globalThis.WebKitPlaybackTargetAvailabilityEvent ) ) { console.warn( diff --git a/src/js/experimental/media-captions-listbox.js b/src/js/experimental/media-captions-listbox.js index 886923aa5..15c494874 100644 --- a/src/js/experimental/media-captions-listbox.js +++ b/src/js/experimental/media-captions-listbox.js @@ -1,6 +1,6 @@ import MediaChromeListbox from './media-chrome-listbox.js'; import './media-chrome-listitem.js'; -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaUIAttributes, MediaUIEvents } from '../constants.js'; import { parseTextTracksStr, formatTextTrackObj } from '../utils/captions.js'; import { toggleSubsCaps } from '../utils/captions.js'; @@ -224,7 +224,7 @@ class MediaCaptionsListbox extends MediaChromeListbox { if (!selectedOption) return; - const event = new window.CustomEvent( + const event = new globalThis.CustomEvent( MediaUIEvents.MEDIA_SHOW_SUBTITLES_REQUEST, { composed: true, @@ -236,8 +236,8 @@ class MediaCaptionsListbox extends MediaChromeListbox { } } -if (!window.customElements.get('media-captions-listbox')) { - window.customElements.define('media-captions-listbox', MediaCaptionsListbox); +if (!globalThis.customElements.get('media-captions-listbox')) { + globalThis.customElements.define('media-captions-listbox', MediaCaptionsListbox); } export default MediaCaptionsListbox; diff --git a/src/js/experimental/media-captions-selectmenu.js b/src/js/experimental/media-captions-selectmenu.js index 0dfb869a4..986b5d0c3 100644 --- a/src/js/experimental/media-captions-selectmenu.js +++ b/src/js/experimental/media-captions-selectmenu.js @@ -1,7 +1,7 @@ import MediaChromeSelectMenu from './media-chrome-selectmenu.js'; import '../media-captions-button.js'; import './media-captions-listbox.js'; -import { window, document, } from '../utils/server-safe-globals.js'; +import { globalThis, document, } from '../utils/server-safe-globals.js'; /** * @csspart button - The default button that's in the shadow DOM. @@ -34,8 +34,8 @@ class MediaCaptionsSelectMenu extends MediaChromeSelectMenu { } } -if (!window.customElements.get('media-captions-selectmenu')) { - window.customElements.define('media-captions-selectmenu', MediaCaptionsSelectMenu); +if (!globalThis.customElements.get('media-captions-selectmenu')) { + globalThis.customElements.define('media-captions-selectmenu', MediaCaptionsSelectMenu); } export default MediaCaptionsSelectMenu; diff --git a/src/js/experimental/media-chrome-listbox.js b/src/js/experimental/media-chrome-listbox.js index cd1c5835c..6ed8809eb 100644 --- a/src/js/experimental/media-chrome-listbox.js +++ b/src/js/experimental/media-chrome-listbox.js @@ -1,5 +1,5 @@ import { MediaStateReceiverAttributes } from '../constants.js'; -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; const template = document.createElement('template'); @@ -67,7 +67,7 @@ template.innerHTML = /*html*/` * @cssproperty --media-font-size - `font-size` property. * @cssproperty --media-text-content-height - `line-height` of text. */ -class MediaChromeListbox extends window.HTMLElement { +class MediaChromeListbox extends globalThis.HTMLElement { #keysSoFar = ''; #clearKeysTimeout = null; #slot; @@ -419,18 +419,18 @@ class MediaChromeListbox extends window.HTMLElement { } #clearKeysOnDelay() { - window.clearTimeout(this.#clearKeysTimeout); + globalThis.clearTimeout(this.#clearKeysTimeout); this.#clearKeysTimeout = null; - this.#clearKeysTimeout = window.setTimeout(() => { + this.#clearKeysTimeout = globalThis.setTimeout(() => { this.#keysSoFar = ''; this.#clearKeysTimeout = null; }, 500); } } -if (!window.customElements.get('media-chrome-listbox')) { - window.customElements.define('media-chrome-listbox', MediaChromeListbox); +if (!globalThis.customElements.get('media-chrome-listbox')) { + globalThis.customElements.define('media-chrome-listbox', MediaChromeListbox); } export default MediaChromeListbox; diff --git a/src/js/experimental/media-chrome-listitem.js b/src/js/experimental/media-chrome-listitem.js index 2bbd6d4b8..af3853c88 100644 --- a/src/js/experimental/media-chrome-listitem.js +++ b/src/js/experimental/media-chrome-listitem.js @@ -1,5 +1,5 @@ import { MediaStateReceiverAttributes } from '../constants.js'; -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; const template = document.createElement('template'); @@ -32,7 +32,7 @@ export const Attributes = { * @attr {boolean} disabled - The Boolean disabled attribute makes the element not mutable or focusable. * @attr {string} mediacontroller - The element `id` of the media controller to connect to (if not nested within). */ -class MediaChromeListitem extends window.HTMLElement { +class MediaChromeListitem extends globalThis.HTMLElement { static get observedAttributes() { return [ 'disabled', @@ -127,8 +127,8 @@ class MediaChromeListitem extends window.HTMLElement { handleClick() {} } -if (!window.customElements.get('media-chrome-listitem')) { - window.customElements.define('media-chrome-listitem', MediaChromeListitem); +if (!globalThis.customElements.get('media-chrome-listitem')) { + globalThis.customElements.define('media-chrome-listitem', MediaChromeListitem); } export default MediaChromeListitem; diff --git a/src/js/experimental/media-chrome-selectmenu.js b/src/js/experimental/media-chrome-selectmenu.js index aab1d1913..7a8173b2d 100644 --- a/src/js/experimental/media-chrome-selectmenu.js +++ b/src/js/experimental/media-chrome-selectmenu.js @@ -1,6 +1,6 @@ import '../media-chrome-button.js'; import './media-chrome-listbox.js'; -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { closestComposedNode, getOrInsertCSSRule } from '../utils/element-utils.js'; import { MediaStateReceiverAttributes } from '../constants.js'; @@ -45,7 +45,7 @@ template.innerHTML = /*html*/` * @csspart button - The default button that's in the shadow DOM. * @csspart listbox - The default listbox that's in the shadow DOM. */ -class MediaChromeSelectMenu extends window.HTMLElement { +class MediaChromeSelectMenu extends globalThis.HTMLElement { #handleClick; #handleChange; #enabledState = true; @@ -302,8 +302,8 @@ class MediaChromeSelectMenu extends window.HTMLElement { } -if (!window.customElements.get('media-chrome-selectmenu')) { - window.customElements.define('media-chrome-selectmenu', MediaChromeSelectMenu); +if (!globalThis.customElements.get('media-chrome-selectmenu')) { + globalThis.customElements.define('media-chrome-selectmenu', MediaChromeSelectMenu); } export default MediaChromeSelectMenu; diff --git a/src/js/experimental/media-playback-rate-listbox.js b/src/js/experimental/media-playback-rate-listbox.js index 0fed6315b..67a6c6c45 100644 --- a/src/js/experimental/media-playback-rate-listbox.js +++ b/src/js/experimental/media-playback-rate-listbox.js @@ -1,5 +1,5 @@ import MediaChromeListbox from './media-chrome-listbox.js'; -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaUIAttributes, MediaUIEvents } from '../constants.js'; const slotTemplate = document.createElement('template'); @@ -58,7 +58,7 @@ class MediaPlaybackrateListbox extends MediaChromeListbox { if (!selectedOption) return; - const event = new window.CustomEvent( + const event = new globalThis.CustomEvent( MediaUIEvents.MEDIA_PLAYBACK_RATE_REQUEST, { composed: true, @@ -70,8 +70,8 @@ class MediaPlaybackrateListbox extends MediaChromeListbox { } } -if (!window.customElements.get('media-playback-rate-listbox')) { - window.customElements.define('media-playback-rate-listbox', MediaPlaybackrateListbox); +if (!globalThis.customElements.get('media-playback-rate-listbox')) { + globalThis.customElements.define('media-playback-rate-listbox', MediaPlaybackrateListbox); } export default MediaPlaybackrateListbox; diff --git a/src/js/experimental/media-playback-rate-selectmenu.js b/src/js/experimental/media-playback-rate-selectmenu.js index e722ac217..9c9e824fc 100644 --- a/src/js/experimental/media-playback-rate-selectmenu.js +++ b/src/js/experimental/media-playback-rate-selectmenu.js @@ -2,7 +2,7 @@ import MediaChromeSelectMenu from './media-chrome-selectmenu.js'; import './media-chrome-listitem.js'; import { DEFAULT_RATES } from '../media-playback-rate-button.js'; import './media-playback-rate-listbox.js'; -import { window, document, } from '../utils/server-safe-globals.js'; +import { globalThis, document, } from '../utils/server-safe-globals.js'; const createItem = (rate) => { const item = document.createElement('media-chrome-listitem'); @@ -74,8 +74,8 @@ class MediaPlaybackrateSelectMenu extends MediaChromeSelectMenu { } } -if (!window.customElements.get('media-playback-rate-selectmenu')) { - window.customElements.define('media-playback-rate-selectmenu', MediaPlaybackrateSelectMenu); +if (!globalThis.customElements.get('media-playback-rate-selectmenu')) { + globalThis.customElements.define('media-playback-rate-selectmenu', MediaPlaybackrateSelectMenu); } export default MediaPlaybackrateSelectMenu; diff --git a/src/js/experimental/media-settings-popup.js b/src/js/experimental/media-settings-popup.js index 4a049a809..d2e654d27 100644 --- a/src/js/experimental/media-settings-popup.js +++ b/src/js/experimental/media-settings-popup.js @@ -1,6 +1,6 @@ // Work in progress -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; const template = document.createElement('template'); @@ -38,7 +38,7 @@ template.innerHTML = ` `; -class MediaSettingsPopup extends window.HTMLElement { +class MediaSettingsPopup extends globalThis.HTMLElement { constructor() { super(); @@ -47,8 +47,8 @@ class MediaSettingsPopup extends window.HTMLElement { } } -if (!window.customElements.get('media-settings-popup')) { - window.customElements.define('media-settings-popup', MediaSettingsPopup); +if (!globalThis.customElements.get('media-settings-popup')) { + globalThis.customElements.define('media-settings-popup', MediaSettingsPopup); } export default MediaSettingsPopup; diff --git a/src/js/extras/media-clip-selector/index.js b/src/js/extras/media-clip-selector/index.js index e0911bed4..bc17afad0 100644 --- a/src/js/extras/media-clip-selector/index.js +++ b/src/js/extras/media-clip-selector/index.js @@ -1,4 +1,4 @@ -import { window, document } from '../../utils/server-safe-globals.js'; +import { globalThis, document } from '../../utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from '../../constants.js'; const template = document.createElement('template'); @@ -138,7 +138,7 @@ template.innerHTML = ` /** * @extends {HTMLElement} */ -class MediaClipSelector extends window.HTMLElement { +class MediaClipSelector extends globalThis.HTMLElement { static get observedAttributes() { return [ 'thumbnails', @@ -186,12 +186,12 @@ class MediaClipSelector extends window.HTMLElement { this.wrapper.addEventListener('click', this._clickHandler, false); this.wrapper.addEventListener('touchstart', this._dragStart, false); - window.addEventListener('touchend', this._dragEnd, false); + globalThis.window?.addEventListener('touchend', this._dragEnd, false); this.wrapper.addEventListener('touchmove', this._drag, false); this.wrapper.addEventListener('mousedown', this._dragStart, false); - window.addEventListener('mouseup', this._dragEnd, false); - window.addEventListener('mousemove', this._drag, false); + globalThis.window?.addEventListener('mouseup', this._dragEnd, false); + globalThis.window?.addEventListener('mousemove', this._drag, false); this.enableThumbnails(); } @@ -356,7 +356,7 @@ class MediaClipSelector extends window.HTMLElement { */ if (this.isTimestampInBounds(timestampForClick)) { this.dispatchEvent( - new window.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { + new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail: timestampForClick, @@ -388,7 +388,7 @@ class MediaClipSelector extends window.HTMLElement { this.mediaCurrentTime > endTime ) { this.dispatchEvent( - new window.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { + new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail: startTime, @@ -407,8 +407,8 @@ class MediaClipSelector extends window.HTMLElement { this.wrapper.removeEventListener('touchmove', this._drag); this.wrapper.removeEventListener('mousedown', this._dragStart); - window.removeEventListener('mouseup', this._dragEnd); - window.removeEventListener('mousemove', this._drag); + globalThis.window?.removeEventListener('mouseup', this._dragEnd); + globalThis.window?.removeEventListener('mousemove', this._drag); } /* @@ -444,18 +444,18 @@ class MediaClipSelector extends window.HTMLElement { this.thumbnailPreview.style.left = `${thumbnailLeft}px`; this.dispatchEvent( - new window.CustomEvent(MediaUIEvents.MEDIA_PREVIEW_REQUEST, { + new globalThis.CustomEvent(MediaUIEvents.MEDIA_PREVIEW_REQUEST, { composed: true, bubbles: true, detail: mousePercent * duration, }) ); }; - window.addEventListener('mousemove', mouseMoveHandler, false); + globalThis.window?.addEventListener('mousemove', mouseMoveHandler, false); }; const stopTrackingMouse = () => { - window.removeEventListener('mousemove', mouseMoveHandler); + globalThis.window?.removeEventListener('mousemove', mouseMoveHandler); }; // Trigger when the mouse moves over the range @@ -469,12 +469,12 @@ class MediaClipSelector extends window.HTMLElement { let offRangeHandler = (evt) => { if (evt.target != this && !this.contains(evt.target)) { this.thumbnailPreview.style.display = 'none'; - window.removeEventListener('mousemove', offRangeHandler); + globalThis.window?.removeEventListener('mousemove', offRangeHandler); rangeEntered = false; stopTrackingMouse(); } }; - window.addEventListener('mousemove', offRangeHandler, false); + globalThis.window?.addEventListener('mousemove', offRangeHandler, false); } if (!this.mediaDuration) { @@ -494,8 +494,8 @@ class MediaClipSelector extends window.HTMLElement { } } -if (!window.customElements.get('media-clip-selector')) { - window.customElements.define('media-clip-selector', MediaClipSelector); +if (!globalThis.customElements.get('media-clip-selector')) { + globalThis.customElements.define('media-clip-selector', MediaClipSelector); } export default MediaClipSelector; diff --git a/src/js/media-airplay-button.js b/src/js/media-airplay-button.js index 1c74f8571..220401e80 100644 --- a/src/js/media-airplay-button.js +++ b/src/js/media-airplay-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { verbs } from './labels/labels.js'; import { getStringAttr, setStringAttr } from './utils/element-utils.js'; @@ -52,7 +52,7 @@ class MediaAirplayButton extends MediaChromeButton { } handleClick() { - const evt = new window.CustomEvent(MediaUIEvents.MEDIA_AIRPLAY_REQUEST, { + const evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_AIRPLAY_REQUEST, { composed: true, bubbles: true, }); @@ -60,8 +60,8 @@ class MediaAirplayButton extends MediaChromeButton { } } -if (!window.customElements.get('media-airplay-button')) { - window.customElements.define('media-airplay-button', MediaAirplayButton); +if (!globalThis.customElements.get('media-airplay-button')) { + globalThis.customElements.define('media-airplay-button', MediaAirplayButton); } export default MediaAirplayButton; diff --git a/src/js/media-captions-button.js b/src/js/media-captions-button.js index 5445e3f21..54e2bc901 100644 --- a/src/js/media-captions-button.js +++ b/src/js/media-captions-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIAttributes } from './constants.js'; import { nouns } from './labels/labels.js'; import { @@ -41,7 +41,7 @@ const updateAriaChecked = (el) => { }; /** - * @param {any} el Should be HTMLElement but issues with window shim + * @param {any} el Should be HTMLElement but issues with globalThis shim * @param {string} attrName * @returns {Array} An array of TextTrack-like objects. */ @@ -52,7 +52,7 @@ const getSubtitlesListAttr = (el, attrName) => { /** * - * @param {any} el Should be HTMLElement but issues with window shim + * @param {any} el Should be HTMLElement but issues with globalThis shim * @param {string} attrName * @param {Array} list An array of TextTrack-like objects */ @@ -144,8 +144,8 @@ class MediaCaptionsButton extends MediaChromeButton { } } -if (!window.customElements.get('media-captions-button')) { - window.customElements.define('media-captions-button', MediaCaptionsButton); +if (!globalThis.customElements.get('media-captions-button')) { + globalThis.customElements.define('media-captions-button', MediaCaptionsButton); } export default MediaCaptionsButton; diff --git a/src/js/media-cast-button.js b/src/js/media-cast-button.js index 0e9eccb97..e8fd92435 100644 --- a/src/js/media-cast-button.js +++ b/src/js/media-cast-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { verbs } from './labels/labels.js'; import { @@ -101,13 +101,13 @@ class MediaCastButton extends MediaChromeButton { ? MediaUIEvents.MEDIA_EXIT_CAST_REQUEST : MediaUIEvents.MEDIA_ENTER_CAST_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); } } -if (!window.customElements.get('media-cast-button')) { - window.customElements.define('media-cast-button', MediaCastButton); +if (!globalThis.customElements.get('media-cast-button')) { + globalThis.customElements.define('media-cast-button', MediaCastButton); } export default MediaCastButton; diff --git a/src/js/media-chrome-button.js b/src/js/media-chrome-button.js index ca936dfa1..f4b3c5d6e 100644 --- a/src/js/media-chrome-button.js +++ b/src/js/media-chrome-button.js @@ -1,6 +1,6 @@ import { MediaStateReceiverAttributes } from './constants.js'; import { getOrInsertCSSRule } from './utils/element-utils.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; const template = document.createElement('template'); @@ -87,7 +87,7 @@ template.innerHTML = /*html*/` * @cssproperty --media-button-icon-transform - `transform` of button icon. * @cssproperty --media-button-icon-transition - `transition` of button icon. */ -class MediaChromeButton extends window.HTMLElement { +class MediaChromeButton extends globalThis.HTMLElement { #mediaController; preventClick = false; @@ -219,8 +219,8 @@ class MediaChromeButton extends window.HTMLElement { handleClick(e) {} // eslint-disable-line } -if (!window.customElements.get('media-chrome-button')) { - window.customElements.define('media-chrome-button', MediaChromeButton); +if (!globalThis.customElements.get('media-chrome-button')) { + globalThis.customElements.define('media-chrome-button', MediaChromeButton); } export { MediaChromeButton }; diff --git a/src/js/media-chrome-range.js b/src/js/media-chrome-range.js index 3f1e0ad19..b3ecb3b9d 100644 --- a/src/js/media-chrome-range.js +++ b/src/js/media-chrome-range.js @@ -1,5 +1,5 @@ import { MediaStateReceiverAttributes } from './constants.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { getOrInsertCSSRule } from './utils/element-utils.js'; const template = document.createElement('template'); @@ -232,7 +232,7 @@ template.innerHTML = /*html*/` * @cssproperty --media-range-track-pointer-background - `background` of range track pointer. * @cssproperty --media-range-track-pointer-border-right - `border-right` of range track pointer. */ -class MediaChromeRange extends window.HTMLElement { +class MediaChromeRange extends globalThis.HTMLElement { thumbWidth; #mediaController; @@ -402,8 +402,8 @@ class MediaChromeRange extends window.HTMLElement { } } -if (!window.customElements.get('media-chrome-range')) { - window.customElements.define('media-chrome-range', MediaChromeRange); +if (!globalThis.customElements.get('media-chrome-range')) { + globalThis.customElements.define('media-chrome-range', MediaChromeRange); } export { MediaChromeRange }; diff --git a/src/js/media-container.js b/src/js/media-container.js index 0982dd359..7aa77892c 100644 --- a/src/js/media-container.js +++ b/src/js/media-container.js @@ -7,7 +7,7 @@ * Position controls at the bottom * Auto-hide controls on inactivity while playing */ -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes, @@ -247,7 +247,7 @@ function getBreakpoints(breakpoints, rect) { * @cssprop --media-background-color - `background-color` of container. * @cssprop --media-slot-display - `display` of the media slot (default none for [audio] usage). */ -class MediaContainer extends window.HTMLElement { +class MediaContainer extends globalThis.HTMLElement { constructor() { super(); @@ -391,7 +391,7 @@ class MediaContainer extends window.HTMLElement { ? MediaUIEvents.MEDIA_PLAY_REQUEST : MediaUIEvents.MEDIA_PAUSE_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); }; } @@ -419,7 +419,7 @@ class MediaContainer extends window.HTMLElement { const mediaName = media.nodeName.toLowerCase(); // Custom element. Wait until it's defined before resolving if (mediaName.includes('-')) { - return window.customElements.whenDefined(mediaName).then(() => { + return globalThis.customElements.whenDefined(mediaName).then(() => { return resolveMediaPromise(media); }); } @@ -458,7 +458,7 @@ class MediaContainer extends window.HTMLElement { this.setAttribute(Attributes.USER_INACTIVE, ''); - const evt = new window.CustomEvent( + const evt = new globalThis.CustomEvent( MediaStateChangeEvents.USER_INACTIVE, { composed: true, bubbles: true, detail: true } ); @@ -470,7 +470,7 @@ class MediaContainer extends window.HTMLElement { this.removeAttribute(Attributes.USER_INACTIVE); - const evt = new window.CustomEvent( + const evt = new globalThis.CustomEvent( MediaStateChangeEvents.USER_INACTIVE, { composed: true, bubbles: true, detail: false } ); @@ -480,12 +480,12 @@ class MediaContainer extends window.HTMLElement { const scheduleInactive = () => { setActive(); - window.clearTimeout(this._inactiveTimeout); + globalThis.clearTimeout(this._inactiveTimeout); // Setting autohide to -1 turns off autohide if (this.autohide < 0) return; - this._inactiveTimeout = window.setTimeout(() => { + this._inactiveTimeout = globalThis.setTimeout(() => { setInactive(); }, this.autohide * 1000); }; @@ -526,7 +526,7 @@ class MediaContainer extends window.HTMLElement { setActive(); // Stay visible if hovered over control bar - window.clearTimeout(this._inactiveTimeout); + globalThis.clearTimeout(this._inactiveTimeout); // If hovering over something other than controls, we're free to make inactive // @ts-ignore @@ -544,7 +544,7 @@ class MediaContainer extends window.HTMLElement { this.addEventListener('keyup', () => { this.setAttribute(Attributes.KEYBOARD_CONTROL, ''); }); - window.addEventListener('mouseup', () => { + globalThis.window?.addEventListener('mouseup', () => { this.removeAttribute(Attributes.KEYBOARD_CONTROL); }); } diff --git a/src/js/media-control-bar.js b/src/js/media-control-bar.js index 28acb59f1..a303eee8f 100644 --- a/src/js/media-control-bar.js +++ b/src/js/media-control-bar.js @@ -5,7 +5,7 @@ */ import { MediaStateReceiverAttributes } from './constants.js'; import { getOrInsertCSSRule } from './utils/element-utils.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; const template = document.createElement('template'); @@ -47,7 +47,7 @@ template.innerHTML = /*html*/` * @cssproperty --media-control-bar-display - `display` property of control bar. * @cssproperty --media-control-display - `display` property of control. */ -class MediaControlBar extends window.HTMLElement { +class MediaControlBar extends globalThis.HTMLElement { #mediaController; static get observedAttributes() { @@ -104,8 +104,8 @@ class MediaControlBar extends window.HTMLElement { } } -if (!window.customElements.get('media-control-bar')) { - window.customElements.define('media-control-bar', MediaControlBar); +if (!globalThis.customElements.get('media-control-bar')) { + globalThis.customElements.define('media-control-bar', MediaControlBar); } export default MediaControlBar; diff --git a/src/js/media-controller.js b/src/js/media-controller.js index 2acbba854..c5c36c0bd 100644 --- a/src/js/media-controller.js +++ b/src/js/media-controller.js @@ -8,7 +8,7 @@ * Auto-hide controls on inactivity while playing */ import { MediaContainer } from './media-container.js'; -import { window } from './utils/server-safe-globals.js'; +import { globalThis } from './utils/server-safe-globals.js'; import { AttributeTokenList } from './utils/attribute-token-list.js'; import { constToCamel, delay } from './utils/utils.js'; import { stringifyTextTrackList, toggleSubsCaps } from './utils/captions.js'; @@ -203,7 +203,7 @@ class MediaController extends MediaContainer { // Update the media with the last set volume preference // This would preferably live with the media element, not a control. try { - const volPref = window.localStorage.getItem('media-chrome-pref-volume'); + const volPref = globalThis.localStorage.getItem('media-chrome-pref-volume'); if (volPref !== null) media.volume = volPref; } catch (e) { console.debug('Error getting volume pref', e); @@ -253,7 +253,7 @@ class MediaController extends MediaContainer { if (previousState === this.getAttribute(attrName)) return; // TODO: I don't think we want these events to bubble? Video element states don't. (heff) - const evt = new window.CustomEvent( + const evt = new globalThis.CustomEvent( AttributeToStateChangeEventMap[attrName], { composed: true, bubbles: true, detail: state } ); @@ -409,7 +409,7 @@ class MediaController extends MediaContainer { ? MediaUIEvents.MEDIA_PLAY_REQUEST : MediaUIEvents.MEDIA_PAUSE_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); break; @@ -419,7 +419,7 @@ class MediaController extends MediaContainer { ? MediaUIEvents.MEDIA_UNMUTE_REQUEST : MediaUIEvents.MEDIA_MUTE_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); break; @@ -429,7 +429,7 @@ class MediaController extends MediaContainer { ? MediaUIEvents.MEDIA_EXIT_FULLSCREEN_REQUEST : MediaUIEvents.MEDIA_ENTER_FULLSCREEN_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); break; @@ -446,7 +446,7 @@ class MediaController extends MediaContainer { ? +currentTimeStr : DEFAULT_TIME; detail = Math.max(currentTime - seekOffset, 0); - evt = new window.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { + evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail, @@ -463,7 +463,7 @@ class MediaController extends MediaContainer { ? +currentTimeStr : DEFAULT_TIME; detail = Math.max(currentTime + seekOffset, 0); - evt = new window.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { + evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail, @@ -486,7 +486,7 @@ const getMediaUIAttributesFrom = (child) => { // observedAttributes are only available if the custom element was upgraded. // example: media-gesture-receiver in the shadow DOM requires an upgrade. if (!observedAttributes && child.nodeName?.includes('-')) { - window.customElements.upgrade(child); + globalThis.customElements.upgrade(child); ({ observedAttributes } = child.constructor); } @@ -597,12 +597,12 @@ const traverseForMediaStateReceivers = ( // a custom element (aka has a hyphen in its name), wait until it's defined before attempting traversal to determine // whether or not it or its descendants are Media State Receivers. // IMPORTANT NOTE: We're intentionally *always* waiting for the `whenDefined()` Promise to resolve here - // (instead of using `window.customElements.get(name)` to check if a custom element is already defined/registered) + // (instead of using `globalThis.customElements.get(name)` to check if a custom element is already defined/registered) // because we encountered some reliability issues with the custom element instances not being fully "ready", even if/when - // they are available in the registry via `window.customElements.get(name)`. + // they are available in the registry via `globalThis.customElements.get(name)`. const name = rootNode?.nodeName.toLowerCase(); if (name.includes('-') && !isMediaStateReceiver(rootNode)) { - window.customElements.whenDefined(name).then(() => { + globalThis.customElements.whenDefined(name).then(() => { // Try/traverse again once the custom element is defined traverseForMediaStateReceiversSync(rootNode, mediaStateReceiverCallback); }); @@ -743,8 +743,8 @@ const monitorForMediaStateReceivers = ( return unsubscribe; }; -if (!window.customElements.get('media-controller')) { - window.customElements.define('media-controller', MediaController); +if (!globalThis.customElements.get('media-controller')) { + globalThis.customElements.define('media-controller', MediaController); } export default MediaController; diff --git a/src/js/media-duration-display.js b/src/js/media-duration-display.js index 6b9ec74fd..a1829bb78 100644 --- a/src/js/media-duration-display.js +++ b/src/js/media-duration-display.js @@ -1,5 +1,5 @@ import { MediaTextDisplay } from './media-text-display.js'; -import { window } from './utils/server-safe-globals.js'; +import { globalThis } from './utils/server-safe-globals.js'; import { formatTime } from './utils/time.js'; import { MediaUIAttributes } from './constants.js'; import { getNumericAttr, setNumericAttr } from './utils/element-utils.js'; @@ -43,8 +43,8 @@ class MediaDurationDisplay extends MediaTextDisplay { } } -if (!window.customElements.get('media-duration-display')) { - window.customElements.define('media-duration-display', MediaDurationDisplay); +if (!globalThis.customElements.get('media-duration-display')) { + globalThis.customElements.define('media-duration-display', MediaDurationDisplay); } export default MediaDurationDisplay; diff --git a/src/js/media-fullscreen-button.js b/src/js/media-fullscreen-button.js index ea2932948..be1ccede7 100644 --- a/src/js/media-fullscreen-button.js +++ b/src/js/media-fullscreen-button.js @@ -7,7 +7,7 @@ If none, the button will make the media fullscreen. */ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { verbs } from './labels/labels.js'; import { @@ -113,13 +113,13 @@ class MediaFullscreenButton extends MediaChromeButton { ? MediaUIEvents.MEDIA_EXIT_FULLSCREEN_REQUEST : MediaUIEvents.MEDIA_ENTER_FULLSCREEN_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); } } -if (!window.customElements.get('media-fullscreen-button')) { - window.customElements.define( +if (!globalThis.customElements.get('media-fullscreen-button')) { + globalThis.customElements.define( 'media-fullscreen-button', MediaFullscreenButton ); diff --git a/src/js/media-gesture-receiver.js b/src/js/media-gesture-receiver.js index 5767bf7c0..9bb5572cb 100644 --- a/src/js/media-gesture-receiver.js +++ b/src/js/media-gesture-receiver.js @@ -9,7 +9,7 @@ import { getBooleanAttr, setBooleanAttr, } from './utils/element-utils.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; const template = document.createElement('template'); @@ -31,7 +31,7 @@ template.innerHTML = /*html*/` * @cssproperty --media-gesture-receiver-display - `display` property of gesture receiver. * @cssproperty --media-control-display - `display` property of control. */ -class MediaGestureReceiver extends window.HTMLElement { +class MediaGestureReceiver extends globalThis.HTMLElement { #mediaController; // NOTE: Currently "baking in" actions + attrs until we come up with @@ -174,7 +174,7 @@ class MediaGestureReceiver extends window.HTMLElement { ? MediaUIEvents.MEDIA_PLAY_REQUEST : MediaUIEvents.MEDIA_PAUSE_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); } } @@ -189,8 +189,8 @@ function getMediaControllerEl(controlEl) { return closestComposedNode(controlEl, 'media-controller'); } -if (!window.customElements.get('media-gesture-receiver')) { - window.customElements.define('media-gesture-receiver', MediaGestureReceiver); +if (!globalThis.customElements.get('media-gesture-receiver')) { + globalThis.customElements.define('media-gesture-receiver', MediaGestureReceiver); } export default MediaGestureReceiver; diff --git a/src/js/media-live-button.js b/src/js/media-live-button.js index 8d68de2f2..d562868a9 100644 --- a/src/js/media-live-button.js +++ b/src/js/media-live-button.js @@ -1,8 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { - Window as window, - Document as document, -} from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { verbs } from './labels/labels.js'; import { getBooleanAttr, setBooleanAttr } from './utils/element-utils.js'; @@ -108,7 +105,7 @@ class MediaLiveButton extends MediaChromeButton { if (!this.mediaPaused && this.mediaTimeIsLive) return; this.dispatchEvent( - new window.CustomEvent(MEDIA_SEEK_TO_LIVE_REQUEST, { + new globalThis.CustomEvent(MEDIA_SEEK_TO_LIVE_REQUEST, { composed: true, bubbles: true, }) @@ -117,7 +114,7 @@ class MediaLiveButton extends MediaChromeButton { // If we're paused, also automatically play if (this.hasAttribute(MEDIA_PAUSED)) { this.dispatchEvent( - new window.CustomEvent(MEDIA_PLAY_REQUEST, { + new globalThis.CustomEvent(MEDIA_PLAY_REQUEST, { composed: true, bubbles: true, }) @@ -126,8 +123,8 @@ class MediaLiveButton extends MediaChromeButton { } } -if (!window.customElements.get('media-live-button')) { - window.customElements.define('media-live-button', MediaLiveButton); +if (!globalThis.customElements.get('media-live-button')) { + globalThis.customElements.define('media-live-button', MediaLiveButton); } export default MediaLiveButton; diff --git a/src/js/media-loading-indicator.js b/src/js/media-loading-indicator.js index 331ff854c..c407bd296 100644 --- a/src/js/media-loading-indicator.js +++ b/src/js/media-loading-indicator.js @@ -1,6 +1,6 @@ import { MediaUIAttributes, MediaStateReceiverAttributes } from './constants.js'; import { nouns } from './labels/labels.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { getBooleanAttr, setBooleanAttr, @@ -99,7 +99,7 @@ svg, img, ::slotted(svg), ::slotted(img) { * @cssproperty --media-loading-indicator-icon-width - `width` of loading icon. * @cssproperty [ --media-loading-indicator-icon-height = 100px ] - `height` of loading icon. */ -class MediaLoadingIndicator extends window.HTMLElement { +class MediaLoadingIndicator extends globalThis.HTMLElement { #mediaController; #delay = DEFAULT_LOADING_DELAY; #style; @@ -198,8 +198,8 @@ class MediaLoadingIndicator extends window.HTMLElement { } } -if (!window.customElements.get('media-loading-indicator')) { - window.customElements.define('media-loading-indicator', MediaLoadingIndicator); +if (!globalThis.customElements.get('media-loading-indicator')) { + globalThis.customElements.define('media-loading-indicator', MediaLoadingIndicator); } export default MediaLoadingIndicator; diff --git a/src/js/media-mute-button.js b/src/js/media-mute-button.js index 06d71b577..c807a62ca 100644 --- a/src/js/media-mute-button.js +++ b/src/js/media-mute-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { verbs } from './labels/labels.js'; import { getStringAttr, setStringAttr } from './utils/element-utils.js'; @@ -103,13 +103,13 @@ class MediaMuteButton extends MediaChromeButton { ? MediaUIEvents.MEDIA_UNMUTE_REQUEST : MediaUIEvents.MEDIA_MUTE_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); } } -if (!window.customElements.get('media-mute-button')) { - window.customElements.define('media-mute-button', MediaMuteButton); +if (!globalThis.customElements.get('media-mute-button')) { + globalThis.customElements.define('media-mute-button', MediaMuteButton); } export default MediaMuteButton; diff --git a/src/js/media-pip-button.js b/src/js/media-pip-button.js index 307c65f99..330d65ef2 100644 --- a/src/js/media-pip-button.js +++ b/src/js/media-pip-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { verbs } from './labels/labels.js'; import { @@ -99,13 +99,13 @@ class MediaPipButton extends MediaChromeButton { ? MediaUIEvents.MEDIA_EXIT_PIP_REQUEST : MediaUIEvents.MEDIA_ENTER_PIP_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); } } -if (!window.customElements.get('media-pip-button')) { - window.customElements.define('media-pip-button', MediaPipButton); +if (!globalThis.customElements.get('media-pip-button')) { + globalThis.customElements.define('media-pip-button', MediaPipButton); } export default MediaPipButton; diff --git a/src/js/media-play-button.js b/src/js/media-play-button.js index f7f22659b..06e63d866 100644 --- a/src/js/media-play-button.js +++ b/src/js/media-play-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { verbs } from './labels/labels.js'; import { getBooleanAttr, setBooleanAttr } from './utils/element-utils.js'; @@ -85,13 +85,13 @@ class MediaPlayButton extends MediaChromeButton { ? MediaUIEvents.MEDIA_PLAY_REQUEST : MediaUIEvents.MEDIA_PAUSE_REQUEST; this.dispatchEvent( - new window.CustomEvent(eventName, { composed: true, bubbles: true }) + new globalThis.CustomEvent(eventName, { composed: true, bubbles: true }) ); } } -if (!window.customElements.get('media-play-button')) { - window.customElements.define('media-play-button', MediaPlayButton); +if (!globalThis.customElements.get('media-play-button')) { + globalThis.customElements.define('media-play-button', MediaPlayButton); } export default MediaPlayButton; diff --git a/src/js/media-playback-rate-button.js b/src/js/media-playback-rate-button.js index a932131c2..1e7d662df 100644 --- a/src/js/media-playback-rate-button.js +++ b/src/js/media-playback-rate-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { nouns } from './labels/labels.js'; import { getNumericAttr, setNumericAttr } from './utils/element-utils.js'; @@ -89,7 +89,7 @@ class MediaPlaybackRateButton extends MediaChromeButton { availableRates.find((r) => r > this.mediaPlaybackRate) ?? availableRates[0] ?? DEFAULT_RATE; - const evt = new window.CustomEvent( + const evt = new globalThis.CustomEvent( MediaUIEvents.MEDIA_PLAYBACK_RATE_REQUEST, { composed: true, bubbles: true, detail } ); @@ -97,8 +97,8 @@ class MediaPlaybackRateButton extends MediaChromeButton { } } -if (!window.customElements.get('media-playback-rate-button')) { - window.customElements.define( +if (!globalThis.customElements.get('media-playback-rate-button')) { + globalThis.customElements.define( 'media-playback-rate-button', MediaPlaybackRateButton ); diff --git a/src/js/media-poster-image.js b/src/js/media-poster-image.js index 0c0a715e8..0b7757d37 100644 --- a/src/js/media-poster-image.js +++ b/src/js/media-poster-image.js @@ -1,4 +1,4 @@ -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { getStringAttr, setStringAttr } from './utils/element-utils.js'; export const Attributes = { @@ -49,7 +49,7 @@ const setBackgroundImage = (el, image) => { * @cssproperty --media-object-fit - `object-fit` of poster image. * @cssproperty --media-object-position - `object-position` of poster image. */ -class MediaPosterImage extends window.HTMLElement { +class MediaPosterImage extends globalThis.HTMLElement { static get observedAttributes() { return [Attributes.PLACEHOLDER_SRC, Attributes.SRC]; } @@ -107,8 +107,8 @@ class MediaPosterImage extends window.HTMLElement { } } -if (!window.customElements.get('media-poster-image')) { - window.customElements.define('media-poster-image', MediaPosterImage); +if (!globalThis.customElements.get('media-poster-image')) { + globalThis.customElements.define('media-poster-image', MediaPosterImage); } export default MediaPosterImage; diff --git a/src/js/media-preview-thumbnail.js b/src/js/media-preview-thumbnail.js index 08ba6f5e4..6845dc4fb 100644 --- a/src/js/media-preview-thumbnail.js +++ b/src/js/media-preview-thumbnail.js @@ -1,4 +1,4 @@ -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIAttributes, MediaStateReceiverAttributes, @@ -36,7 +36,7 @@ template.innerHTML = /*html*/` * @cssproperty [--media-preview-thumbnail-display = inline-block] - `display` property of display. * @cssproperty [--media-control-display = inline-block] - `display` property of control. */ -class MediaPreviewThumbnail extends window.HTMLElement { +class MediaPreviewThumbnail extends globalThis.HTMLElement { #mediaController; static get observedAttributes() { @@ -178,8 +178,8 @@ class MediaPreviewThumbnail extends window.HTMLElement { } } -if (!window.customElements.get('media-preview-thumbnail')) { - window.customElements.define( +if (!globalThis.customElements.get('media-preview-thumbnail')) { + globalThis.customElements.define( 'media-preview-thumbnail', MediaPreviewThumbnail ); diff --git a/src/js/media-preview-time-display.js b/src/js/media-preview-time-display.js index e39364a26..9e1ff8ba0 100644 --- a/src/js/media-preview-time-display.js +++ b/src/js/media-preview-time-display.js @@ -1,5 +1,5 @@ import { MediaTextDisplay } from './media-text-display.js'; -import { window } from './utils/server-safe-globals.js'; +import { globalThis } from './utils/server-safe-globals.js'; import { formatTime } from './utils/time.js'; import { MediaUIAttributes } from './constants.js'; import { getNumericAttr, setNumericAttr } from './utils/element-utils.js'; @@ -43,8 +43,8 @@ class MediaPreviewTimeDisplay extends MediaTextDisplay { } } -if (!window.customElements.get('media-preview-time-display')) { - window.customElements.define( +if (!globalThis.customElements.get('media-preview-time-display')) { + globalThis.customElements.define( 'media-preview-time-display', MediaPreviewTimeDisplay ); diff --git a/src/js/media-seek-backward-button.js b/src/js/media-seek-backward-button.js index 5eaff8021..23804b6da 100644 --- a/src/js/media-seek-backward-button.js +++ b/src/js/media-seek-backward-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { updateAriaLabel, updateSeekIconValue } from './utils/seek.js'; import { getNumericAttr, setNumericAttr } from './utils/element-utils.js'; @@ -84,7 +84,7 @@ class MediaSeekBackwardButton extends MediaChromeButton { handleClick() { const detail = Math.max(this.mediaCurrentTime - this.seekOffset, 0); - const evt = new window.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { + const evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail, @@ -93,8 +93,8 @@ class MediaSeekBackwardButton extends MediaChromeButton { } } -if (!window.customElements.get('media-seek-backward-button')) { - window.customElements.define( +if (!globalThis.customElements.get('media-seek-backward-button')) { + globalThis.customElements.define( 'media-seek-backward-button', MediaSeekBackwardButton ); diff --git a/src/js/media-seek-forward-button.js b/src/js/media-seek-forward-button.js index 19eae86d7..79976e88a 100644 --- a/src/js/media-seek-forward-button.js +++ b/src/js/media-seek-forward-button.js @@ -1,5 +1,5 @@ import { MediaChromeButton } from './media-chrome-button.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { updateAriaLabel, updateSeekIconValue } from './utils/seek.js'; import { getNumericAttr, setNumericAttr } from './utils/element-utils.js'; @@ -84,7 +84,7 @@ class MediaSeekForwardButton extends MediaChromeButton { handleClick() { const detail = this.mediaCurrentTime + this.seekOffset; - const evt = new window.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { + const evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail, @@ -93,8 +93,8 @@ class MediaSeekForwardButton extends MediaChromeButton { } } -if (!window.customElements.get('media-seek-forward-button')) { - window.customElements.define( +if (!globalThis.customElements.get('media-seek-forward-button')) { + globalThis.customElements.define( 'media-seek-forward-button', MediaSeekForwardButton ); diff --git a/src/js/media-text-display.js b/src/js/media-text-display.js index 9da7d61aa..7f5be051b 100644 --- a/src/js/media-text-display.js +++ b/src/js/media-text-display.js @@ -1,6 +1,6 @@ import { MediaStateReceiverAttributes } from './constants.js'; import { getOrInsertCSSRule } from './utils/element-utils.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; // Todo: Use data locals: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString const template = document.createElement('template'); @@ -65,7 +65,7 @@ template.innerHTML = /*html*/` * @cssproperty --media-font-size - `font-size` property. * @cssproperty --media-text-content-height - `line-height` of text. */ -class MediaTextDisplay extends window.HTMLElement { +class MediaTextDisplay extends globalThis.HTMLElement { #mediaController; static get observedAttributes() { @@ -117,8 +117,8 @@ class MediaTextDisplay extends window.HTMLElement { } } -if (!window.customElements.get('media-text-display')) { - window.customElements.define('media-text-display', MediaTextDisplay); +if (!globalThis.customElements.get('media-text-display')) { + globalThis.customElements.define('media-text-display', MediaTextDisplay); } export { MediaTextDisplay }; diff --git a/src/js/media-theme-element.js b/src/js/media-theme-element.js index e00569b2f..477ac474d 100644 --- a/src/js/media-theme-element.js +++ b/src/js/media-theme-element.js @@ -1,4 +1,4 @@ -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { TemplateInstance } from './utils/template-parts.js'; import { processor } from './utils/template-processor.js'; import { camelCase, isNumericString } from './utils/utils.js'; @@ -42,7 +42,7 @@ prependTemplate.innerHTML = /*html*/` * * @attr {string} template - The element `id` of the template to render. */ -export class MediaThemeElement extends window.HTMLElement { +export class MediaThemeElement extends globalThis.HTMLElement { static template; static observedAttributes = ['template']; static processor = processor; @@ -250,6 +250,6 @@ async function request(resource) { return response.text(); } -if (!window.customElements.get('media-theme')) { - window.customElements.define('media-theme', MediaThemeElement); +if (!globalThis.customElements.get('media-theme')) { + globalThis.customElements.define('media-theme', MediaThemeElement); } diff --git a/src/js/media-time-display.js b/src/js/media-time-display.js index 5d7fee0da..e987d7d7f 100644 --- a/src/js/media-time-display.js +++ b/src/js/media-time-display.js @@ -6,7 +6,7 @@ import { setBooleanAttr, setNumericAttr, } from './utils/element-utils.js'; -import { window } from './utils/server-safe-globals.js'; +import { globalThis } from './utils/server-safe-globals.js'; import { formatAsTimePhrase, formatTime } from './utils/time.js'; import { MediaUIAttributes } from './constants.js'; import { nouns } from './labels/labels.js'; @@ -273,8 +273,8 @@ class MediaTimeDisplay extends MediaTextDisplay { } } -if (!window.customElements.get('media-time-display')) { - window.customElements.define('media-time-display', MediaTimeDisplay); +if (!globalThis.customElements.get('media-time-display')) { + globalThis.customElements.define('media-time-display', MediaTimeDisplay); } export default MediaTimeDisplay; diff --git a/src/js/media-time-range.js b/src/js/media-time-range.js index 9eaa4b2e9..ff57e63aa 100644 --- a/src/js/media-time-range.js +++ b/src/js/media-time-range.js @@ -1,5 +1,5 @@ import { MediaChromeRange } from './media-chrome-range.js'; -import { window, document } from './utils/server-safe-globals.js'; +import { globalThis, document } from './utils/server-safe-globals.js'; import { MediaUIEvents, MediaUIAttributes } from './constants.js'; import { nouns } from './labels/labels.js'; import { formatAsTimePhrase } from './utils/time.js'; @@ -210,7 +210,7 @@ class MediaTimeRange extends MediaChromeRange { const newTime = this.range.value; const detail = newTime; - const evt = new window.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { + const evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_SEEK_REQUEST, { composed: true, bubbles: true, detail, @@ -544,7 +544,7 @@ class MediaTimeRange extends MediaChromeRange { style.transform = `translateX(${boxPos})`; const detail = mouseRatio * duration; - const mediaPreviewEvt = new window.CustomEvent( + const mediaPreviewEvt = new globalThis.CustomEvent( MediaUIEvents.MEDIA_PREVIEW_REQUEST, { composed: true, bubbles: true, detail } ); @@ -560,19 +560,19 @@ class MediaTimeRange extends MediaChromeRange { // @ts-ignore [...this.#boxes].some((b) => evt.composedPath().includes(b)) ) { - window.removeEventListener('pointermove', this.#offRangeHandler); + globalThis.window?.removeEventListener('pointermove', this.#offRangeHandler); this.#rangeEntered = false; this.#stopTrackingMouse(); } }; #trackMouse = () => { - window.addEventListener('pointermove', this.#pointermoveHandler, false); + globalThis.window?.addEventListener('pointermove', this.#pointermoveHandler, false); }; #stopTrackingMouse = () => { - window.removeEventListener('pointermove', this.#pointermoveHandler); - const endEvt = new window.CustomEvent(MediaUIEvents.MEDIA_PREVIEW_REQUEST, { + globalThis.window?.removeEventListener('pointermove', this.#pointermoveHandler); + const endEvt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_PREVIEW_REQUEST, { composed: true, bubbles: true, detail: null, @@ -588,7 +588,7 @@ class MediaTimeRange extends MediaChromeRange { this.#rangeEntered = true; this.#trackMouse(); - window.addEventListener('pointermove', this.#offRangeHandler, false); + globalThis.window?.addEventListener('pointermove', this.#offRangeHandler, false); } }; @@ -597,15 +597,15 @@ class MediaTimeRange extends MediaChromeRange { } #disableBoxes() { - window.removeEventListener('pointermove', this.#offRangeHandler); + globalThis.window?.removeEventListener('pointermove', this.#offRangeHandler); this.removeEventListener('pointermove', this.#rangepointermoveHandler); this.#rangeEntered = false; this.#stopTrackingMouse(); } } -if (!window.customElements.get('media-time-range')) { - window.customElements.define('media-time-range', MediaTimeRange); +if (!globalThis.customElements.get('media-time-range')) { + globalThis.customElements.define('media-time-range', MediaTimeRange); } export default MediaTimeRange; diff --git a/src/js/media-volume-range.js b/src/js/media-volume-range.js index 3d556dbd4..f86042f02 100644 --- a/src/js/media-volume-range.js +++ b/src/js/media-volume-range.js @@ -1,4 +1,4 @@ -import { window } from './utils/server-safe-globals.js'; +import { globalThis } from './utils/server-safe-globals.js'; import { MediaChromeRange } from './media-chrome-range.js'; import { MediaUIAttributes, MediaUIEvents } from './constants.js'; import { nouns } from './labels/labels.js'; @@ -47,7 +47,7 @@ class MediaVolumeRange extends MediaChromeRange { this.range.addEventListener('input', () => { const newVolume = this.range.value / this.range.max; const detail = newVolume; - const evt = new window.CustomEvent(MediaUIEvents.MEDIA_VOLUME_REQUEST, { + const evt = new globalThis.CustomEvent(MediaUIEvents.MEDIA_VOLUME_REQUEST, { composed: true, bubbles: true, detail, @@ -111,8 +111,8 @@ class MediaVolumeRange extends MediaChromeRange { } } -if (!window.customElements.get('media-volume-range')) { - window.customElements.define('media-volume-range', MediaVolumeRange); +if (!globalThis.customElements.get('media-volume-range')) { + globalThis.customElements.define('media-volume-range', MediaVolumeRange); } export default MediaVolumeRange; diff --git a/src/js/themes/demuxed-2022.js b/src/js/themes/demuxed-2022.js index 9a302a000..30946e8c0 100644 --- a/src/js/themes/demuxed-2022.js +++ b/src/js/themes/demuxed-2022.js @@ -7,7 +7,7 @@ */ -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaThemeElement } from '../media-theme-element.js'; const template = document.createElement('template'); @@ -363,7 +363,7 @@ class MediaThemeDemuxed extends MediaThemeElement { connectedCallback() { this.render(); - const resizeObserver = new window.ResizeObserver((entries) => { + const resizeObserver = new globalThis.ResizeObserver((entries) => { entries.forEach((entry) => { entry.target.className = this.#getBreakpoints(entry.contentRect).join(' '); }); @@ -382,8 +382,8 @@ class MediaThemeDemuxed extends MediaThemeElement { } } -if (!window.customElements.get('media-theme-demuxed-2022')) { - window.customElements.define('media-theme-demuxed-2022', MediaThemeDemuxed); +if (!globalThis.customElements.get('media-theme-demuxed-2022')) { + globalThis.customElements.define('media-theme-demuxed-2022', MediaThemeDemuxed); } export default MediaThemeDemuxed; diff --git a/src/js/themes/microvideo.js b/src/js/themes/microvideo.js index b6369db79..9a4d8e4cd 100644 --- a/src/js/themes/microvideo.js +++ b/src/js/themes/microvideo.js @@ -7,7 +7,7 @@ */ -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaThemeElement } from '../media-theme-element.js'; const template = document.createElement('template'); @@ -504,8 +504,8 @@ class MediaThemeMicrovideo extends MediaThemeElement { static template = template; } -if (!window.customElements.get('media-theme-microvideo')) { - window.customElements.define('media-theme-microvideo', MediaThemeMicrovideo); +if (!globalThis.customElements.get('media-theme-microvideo')) { + globalThis.customElements.define('media-theme-microvideo', MediaThemeMicrovideo); } export default MediaThemeMicrovideo; diff --git a/src/js/themes/minimal.js b/src/js/themes/minimal.js index 76ee877a0..babe49bc4 100644 --- a/src/js/themes/minimal.js +++ b/src/js/themes/minimal.js @@ -7,7 +7,7 @@ */ -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaThemeElement } from '../media-theme-element.js'; const template = document.createElement('template'); @@ -407,8 +407,8 @@ class MediaThemeMinimal extends MediaThemeElement { static template = template; } -if (!window.customElements.get('media-theme-minimal')) { - window.customElements.define('media-theme-minimal', MediaThemeMinimal); +if (!globalThis.customElements.get('media-theme-minimal')) { + globalThis.customElements.define('media-theme-minimal', MediaThemeMinimal); } export default MediaThemeMinimal; diff --git a/src/js/themes/netflix.js b/src/js/themes/netflix.js index 604b378c9..3136ae842 100644 --- a/src/js/themes/netflix.js +++ b/src/js/themes/netflix.js @@ -7,7 +7,7 @@ */ -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaThemeElement } from '../media-theme-element.js'; const template = document.createElement('template'); @@ -131,8 +131,8 @@ class MediaThemeNetflix extends MediaThemeElement { static template = template; } -if (!window.customElements.get('media-theme-netflix')) { - window.customElements.define('media-theme-netflix', MediaThemeNetflix); +if (!globalThis.customElements.get('media-theme-netflix')) { + globalThis.customElements.define('media-theme-netflix', MediaThemeNetflix); } export default MediaThemeNetflix; diff --git a/src/js/themes/responsive.js b/src/js/themes/responsive.js index 9df073761..505a9069b 100644 --- a/src/js/themes/responsive.js +++ b/src/js/themes/responsive.js @@ -7,7 +7,7 @@ */ -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaThemeElement } from '../media-theme-element.js'; const template = document.createElement('template'); @@ -132,8 +132,8 @@ class MediaThemeResponsive extends MediaThemeElement { static template = template; } -if (!window.customElements.get('media-theme-responsive')) { - window.customElements.define('media-theme-responsive', MediaThemeResponsive); +if (!globalThis.customElements.get('media-theme-responsive')) { + globalThis.customElements.define('media-theme-responsive', MediaThemeResponsive); } export default MediaThemeResponsive; diff --git a/src/js/themes/winamp.js b/src/js/themes/winamp.js index beb065372..17f774b35 100644 --- a/src/js/themes/winamp.js +++ b/src/js/themes/winamp.js @@ -1,4 +1,4 @@ -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaThemeElement } from '../media-theme-element.js'; const template = document.createElement('template'); @@ -413,8 +413,8 @@ class MediaThemeWinamp extends MediaThemeElement { static template = template; } -if (!window.customElements.get('media-theme-winamp')) { - window.customElements.define('media-theme-winamp', MediaThemeWinamp); +if (!globalThis.customElements.get('media-theme-winamp')) { + globalThis.customElements.define('media-theme-winamp', MediaThemeWinamp); } export default MediaThemeWinamp; diff --git a/src/js/themes/youtube.js b/src/js/themes/youtube.js index 24af32fac..357071c0d 100644 --- a/src/js/themes/youtube.js +++ b/src/js/themes/youtube.js @@ -7,7 +7,7 @@ */ -import { window, document } from '../utils/server-safe-globals.js'; +import { globalThis, document } from '../utils/server-safe-globals.js'; import { MediaThemeElement } from '../media-theme-element.js'; const template = document.createElement('template'); @@ -139,8 +139,8 @@ class MediaThemeYoutube extends MediaThemeElement { static template = template; } -if (!window.customElements.get('media-theme-youtube')) { - window.customElements.define('media-theme-youtube', MediaThemeYoutube); +if (!globalThis.customElements.get('media-theme-youtube')) { + globalThis.customElements.define('media-theme-youtube', MediaThemeYoutube); } export default MediaThemeYoutube; diff --git a/src/js/utils/platform-tests.js b/src/js/utils/platform-tests.js index b6a00561d..ade158e6b 100644 --- a/src/js/utils/platform-tests.js +++ b/src/js/utils/platform-tests.js @@ -1,4 +1,4 @@ -import { window, document } from './server-safe-globals.js'; +import { globalThis, document } from './server-safe-globals.js'; import { delay } from './utils.js'; import { fullscreenApi } from './fullscreen-api.js'; @@ -59,5 +59,5 @@ export const hasFullscreenSupport = (mediaEl = getTestMediaEl()) => { export const fullscreenSupported = hasFullscreenSupport(); export const pipSupported = hasPipSupport(); -export const airplaySupported = !!window.WebKitPlaybackTargetAvailabilityEvent; -export const castSupported = !!window.chrome; +export const airplaySupported = !!globalThis.WebKitPlaybackTargetAvailabilityEvent; +export const castSupported = !!globalThis.chrome; diff --git a/src/js/utils/server-safe-globals.js b/src/js/utils/server-safe-globals.js index 54efe623a..810aa11af 100644 --- a/src/js/utils/server-safe-globals.js +++ b/src/js/utils/server-safe-globals.js @@ -10,7 +10,7 @@ class ResizeObserver { observe() {} } -const windowShim = { +const globalThisShim = { ResizeObserver, HTMLElement: class HTMLElement extends EventTarget {}, DocumentFragment: class DocumentFragment extends EventTarget {}, @@ -29,7 +29,7 @@ const windowShim = { const documentShim = { createElement: function () { - return new windowShim.HTMLElement(); + return new globalThisShim.HTMLElement(); }, addEventListener() {}, removeEventListener() {}, @@ -40,10 +40,12 @@ export const isServer = typeof window.customElements === 'undefined'; /** - * @type { window & { WebKitPlaybackTargetAvailabilityEvent?, + * @type { globalThis & { + * WebKitPlaybackTargetAvailabilityEvent?, * chrome?, * DocumentFragment?, * getComputedStyle, + * CastableVideoElement? * } | * {HTMLElement, * customElements, @@ -55,14 +57,17 @@ export const isServer = * clearTimeout?, * localStorage?, * WebKitPlaybackTargetAvailabilityEvent?, + * window?, * document?, * chrome?, * DocumentFragment?, * ResizeObserver?, * requestAnimationFrame, + * CastableVideoElement? * } } * */ -export const Window = isServer ? windowShim : window; +export const GlobalThis = isServer ? globalThisShim : globalThis; + /** * @type { document & { webkitExitFullscreen? } | * {createElement, @@ -79,4 +84,7 @@ export const Window = isServer ? windowShim : window; */ export const Document = isServer ? documentShim : window.document; -export { Window as window, Document as document }; +export { + GlobalThis as globalThis, + Document as document +}; diff --git a/src/js/utils/template-parts.js b/src/js/utils/template-parts.js index 00db5e246..40379e5c0 100644 --- a/src/js/utils/template-parts.js +++ b/src/js/utils/template-parts.js @@ -1,4 +1,4 @@ -import { window } from '../utils/server-safe-globals.js'; +import { globalThis } from '../utils/server-safe-globals.js'; /* Adapted from https://github.com/dy/template-parts - ISC - Dmitry Iv. */ @@ -39,7 +39,7 @@ export const defaultProcessor = { /** * @extends {DocumentFragment} */ -export class TemplateInstance extends window.DocumentFragment { +export class TemplateInstance extends globalThis.DocumentFragment { #parts; #processor;