Fast Shallow Array Cloning in Javascript
This commit is contained in:
-635
@@ -1,635 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import("./HTMLMediaElement.mjs");
|
||||
|
||||
async function xmr_media_lazyload_perform(element) {
|
||||
let content = element.querySelector("noscript");
|
||||
if (content) {
|
||||
element.innerHTML = content.innerText;
|
||||
}
|
||||
}
|
||||
|
||||
async function xmr_media_lazyload_initialize() {
|
||||
// Figure out what to load.
|
||||
let elements = document.querySelectorAll(".block-this._media > [data-lazyload]");
|
||||
let stack = Array.from(elements);
|
||||
console.debug("Lazily loading " + stack.length + " elements...");
|
||||
|
||||
// Add a lazyloading handler to all entries.
|
||||
for (let el of stack) {
|
||||
xmr_media_lazyload_perform(el);
|
||||
}
|
||||
}
|
||||
|
||||
class XMediaPlayer {
|
||||
constructor(element) {
|
||||
this._media = element;
|
||||
|
||||
// Replace the original video element with a player.
|
||||
this._container = document.createElement("player");
|
||||
this._media.parentElement.replaceChild(this._container, this._media);
|
||||
|
||||
// Insert the original video element. This must be done here, else we have Z-fighting on mobile!
|
||||
this._container.appendChild(this._media);
|
||||
|
||||
// Insert the container for our overlays.
|
||||
this._overlay = document.createElement("overlay");
|
||||
this._container.appendChild(this._overlay);
|
||||
|
||||
// Build the variant menu.
|
||||
this._variants = document.createElement("select");
|
||||
this._variants.size = 2;
|
||||
this._variants.classList.add("variants", "hide");
|
||||
this._overlay.appendChild(this._variants);
|
||||
console.log(this._media.currentSrc);
|
||||
for (let source of this._media.querySelectorAll("source")) {
|
||||
let variant = document.createElement("option")
|
||||
if (source.src == this._media.currentSrc) {
|
||||
variant.selected = true;
|
||||
}
|
||||
variant.value = source.src;
|
||||
if (source.title) {
|
||||
variant.innerText = source.title;
|
||||
} else {
|
||||
variant.innerText = (new URL(source.src)).pathname;
|
||||
}
|
||||
this._variants.appendChild(variant);
|
||||
}
|
||||
|
||||
// Build the control overlay.
|
||||
this._controls = document.createElement("controls");
|
||||
this._overlay.appendChild(this._controls);
|
||||
// - Play Button
|
||||
this._controlPlay = document.createElement("div");
|
||||
this._controlPlay.classList.add("play", "symbol")
|
||||
this._controlPlay.tabIndex = 0;
|
||||
this._controlPlay.dataset.symbol = "⏵";
|
||||
this._controlPlay.ariaLabel = "Play";
|
||||
this._controlPlay.update = () => {
|
||||
if (this._media.paused) {
|
||||
this._controlPlay.classList.remove("playing");
|
||||
this._controlPlay.dataset.symbol = "⏵";
|
||||
this._controlPlay.ariaLabel = "Play";
|
||||
} else if (this._media.error || this._media.ended) {
|
||||
this._controlPlay.classList.remove("playing");
|
||||
this._controlPlay.dataset.symbol = "⏹";
|
||||
this._controlPlay.ariaLabel = "Stopped";
|
||||
} else {
|
||||
this._controlPlay.classList.add("playing");
|
||||
this._controlPlay.dataset.symbol = "⏸";
|
||||
this._controlPlay.ariaLabel = "Pause";
|
||||
}
|
||||
this._controlPlay.innerText = this._controlPlay.dataset.symbol;
|
||||
}
|
||||
this._controls.appendChild(this._controlPlay);
|
||||
// - Time Display
|
||||
this._controlTime = document.createElement("div");
|
||||
this._controlTime.classList.add("time");
|
||||
this._controlTime.innerHTML = "00:00 / 00:00";
|
||||
this._controlTime.update = () => {
|
||||
function formatSeconds(seconds, with_ms, with_minutes, with_hour) {
|
||||
let result = [];
|
||||
if (isFinite(seconds) && !isNaN(seconds)) {
|
||||
let tainted_seconds = seconds % 60;
|
||||
let pure_seconds = Math.floor(seconds % 60);
|
||||
let tainted_minutes = ((seconds - pure_seconds) / 60);
|
||||
let pure_minutes = Math.floor(tainted_minutes % 60);
|
||||
let pure_hours = Math.floor((tainted_minutes - pure_minutes) / 60);
|
||||
|
||||
result.unshift(`${pure_seconds.toString(10).padStart(2, '0')}`);
|
||||
if (with_ms) {
|
||||
result[0] = `${result[0]}.${Math.floor((tainted_seconds % 1) * 100).toString(10).padStart(2, '0')}`
|
||||
}
|
||||
if ((with_minutes === true) || ((with_minutes === undefined) && (pure_minutes > 0))) {
|
||||
result[0] = result[0].padStart(2, '0');
|
||||
result.unshift(`${pure_minutes.toString(10)}`);
|
||||
}
|
||||
if ((with_hour === true) || ((with_hour === undefined) && (pure_hours > 0))) {
|
||||
result[0] = result[0].padStart(2, '0');
|
||||
result.unshift(`${pure_hours.toString(10)}`);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let duration = formatSeconds(this._media.duration, true);
|
||||
let current = formatSeconds(this._media.currentTime, true, duration.length >= 2, duration.length >= 3);
|
||||
for (let idx in duration) {
|
||||
current[idx].padStart(duration[idx].length, '0');
|
||||
}
|
||||
|
||||
if (duration.length > 0) {
|
||||
this._controlTime.innerText = `${current.join(':')} / ${duration.join(':')}`;
|
||||
} else {
|
||||
this._controlTime.innerText = `${current.join(':')}`;
|
||||
}
|
||||
}
|
||||
this._controls.appendChild(this._controlTime);
|
||||
// - Progress Bar
|
||||
this._controlProgress = document.createElement("input");
|
||||
this._controlProgress.classList.add("progress");
|
||||
this._controlProgress.type = "range";
|
||||
this._controlProgress.tabIndex = 0;
|
||||
this._controlProgress.min = -2147483648;
|
||||
this._controlProgress.max = 2147483647;
|
||||
this._controlProgress.update = () => {
|
||||
let min = parseInt(this._controlVolume.min, 10);
|
||||
let max = parseInt(this._controlVolume.max, 10);
|
||||
let dlt = max - min;
|
||||
this._controlProgress.disabled = !this._media.seekable;
|
||||
this._controlProgress.value = (this._media.currentTime / this._media.duration) * dlt + min;
|
||||
}
|
||||
this._controls.appendChild(this._controlProgress);
|
||||
// - Mute Button
|
||||
this._controlMute = document.createElement("div");
|
||||
this._controlMute.classList.add("mute", "symbol");
|
||||
this._controlMute.tabIndex = 0;
|
||||
this._controlMute.ariaLabel = "Mute";
|
||||
this._controlMute.dataset.symbol = "🔊";
|
||||
this._controlMute.update = () => {
|
||||
if (this._media.muted) {
|
||||
this._controlMute.classList.add("muted");
|
||||
this._controlMute.dataset.symbol = "🔇";
|
||||
this._controlMute.ariaLabel = "Unmute";
|
||||
} else {
|
||||
this._controlMute.classList.remove("muted");
|
||||
if (this._media.volume > 0.5) {
|
||||
this._controlMute.dataset.symbol = "🔊";
|
||||
} else if (this._media.volume > 0.25) {
|
||||
this._controlMute.dataset.symbol = "🔉";
|
||||
} else {
|
||||
this._controlMute.dataset.symbol = "🔈";
|
||||
}
|
||||
this._controlMute.ariaLabel = `Volume: ${(this._media.volume * 100).toString(10)}%`;
|
||||
}
|
||||
this._controlMute.innerText = this._controlMute.dataset.symbol;
|
||||
}
|
||||
this._controls.appendChild(this._controlMute);
|
||||
// - Volume Controls
|
||||
this._controlVolume = document.createElement("input");
|
||||
this._controlVolume.classList.add("volume");
|
||||
this._controlVolume.type = "range";
|
||||
this._controlVolume.tabIndex = 0;
|
||||
this._controlVolume.min = -2147483648;
|
||||
this._controlVolume.max = 2147483647;
|
||||
this._controlVolume.value = this._controlVolume.max;
|
||||
this._controlVolume.update = () => {
|
||||
let min = parseInt(this._controlVolume.min, 10);
|
||||
let max = parseInt(this._controlVolume.max, 10);
|
||||
let dlt = max - min;
|
||||
this._controlVolume.value = (this._media.volume * dlt) + min;
|
||||
this._controlVolume.ariaLabel = `Volume: ${(this._media.volume * 100).toString(10)}%`;
|
||||
if (this._media.muted) {
|
||||
this._controlVolume.classList.add("muted");
|
||||
} else {
|
||||
this._controlVolume.classList.remove("muted");
|
||||
}
|
||||
}
|
||||
this._controls.appendChild(this._controlVolume);
|
||||
// - Variant Button
|
||||
this._controlVariant = document.createElement("div");
|
||||
this._controlVariant.classList.add("variant", "symbol");
|
||||
this._controlVariant.tabIndex = 0;
|
||||
this._controlVariant.ariaLabel = "Change Variant";
|
||||
this._controlVariant.dataset.symbol = "⚙";
|
||||
this._controlVariant.update = () => {
|
||||
this._controlVariant.value = this._media.currentSrc;
|
||||
};
|
||||
this._controls.appendChild(this._controlVariant);
|
||||
// - Fullscreen Button
|
||||
this._controlFullscreen = document.createElement("div");
|
||||
this._controlFullscreen.classList.add("fullscreen", "symbol");
|
||||
this._controlFullscreen.tabIndex = 0;
|
||||
this._controlFullscreen.ariaLabel = "Toggle Fullscreen";
|
||||
this._controlFullscreen.dataset.symbol = "⛶";
|
||||
this._controlFullscreen.update = () => {
|
||||
if (document.fullscreenElement == this._container) {
|
||||
this._controlFullscreen.dataset.symbol = "\u200F⬚";
|
||||
} else {
|
||||
this._controlFullscreen.dataset.symbol = "⛶";
|
||||
}
|
||||
this._controlFullscreen.innerText = this._controlFullscreen.dataset.symbol;
|
||||
};
|
||||
this._controls.appendChild(this._controlFullscreen);
|
||||
|
||||
// Now begin listening to all events that are relevant.
|
||||
for (let event of [
|
||||
"Abort",
|
||||
"CanPlay",
|
||||
"CanPlayThrough",
|
||||
"Click",
|
||||
"DblClick",
|
||||
"DurationChange",
|
||||
"Emptied",
|
||||
"Encrypted",
|
||||
"Ended",
|
||||
"Error",
|
||||
"FullscreenChange",
|
||||
"FullscreenError",
|
||||
"Input",
|
||||
"KeyDown",
|
||||
"LoadedData",
|
||||
"LoadedMetaData",
|
||||
"LoadStart",
|
||||
"MouseEnter",
|
||||
"MouseLeave",
|
||||
"MouseMove",
|
||||
"MouseDown",
|
||||
"MouseUp",
|
||||
"Pause",
|
||||
"Play",
|
||||
"Playing",
|
||||
"Progress",
|
||||
"RateChange",
|
||||
"Seeked",
|
||||
"Seeking",
|
||||
"Stalled",
|
||||
"Suspend",
|
||||
"TimeUpdate",
|
||||
"VolumeChange",
|
||||
"Waiting",
|
||||
"Wheel"
|
||||
]) {
|
||||
for (let element of [this._media, this._container, this._controlPlay, this._controlProgress, this._controlMute, this._controlVolume, this._variants, this._controlVariant, this._controlFullscreen]) {
|
||||
element.addEventListener(event.toLocaleLowerCase(), (ev) => {
|
||||
try {
|
||||
this[`_on${event}`](ev);
|
||||
} catch (ex) {
|
||||
console.error(`Event '${event}' handler encountered exception: ${ex}`);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// And update all controls once.
|
||||
this._controlPlay.update();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
this._controlMute.update();
|
||||
this._controlVolume.update();
|
||||
this._controlVariant.update();
|
||||
this._controlFullscreen.update();
|
||||
|
||||
// And tell the media element to load.
|
||||
this._media.load();
|
||||
}
|
||||
|
||||
_hideAudioControlWithoutAudio() {
|
||||
let hasAudio = Boolean(this._media.mozHasAudio)
|
||||
|| Boolean(this._media.webkitAudioDecodedByteCount)
|
||||
|| Boolean(this._media.audioTracks && this._media.audioTracks.length);
|
||||
this._controlMute.style.display = hasAudio ? "" : "none";
|
||||
this._controlVolume.style.display = hasAudio ? "" : "none";
|
||||
}
|
||||
|
||||
// Media Playback Status
|
||||
_onAbort(ev) {
|
||||
this.showOverlay();
|
||||
this._controlPlay.update();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onEnded(ev) {
|
||||
this.showOverlay();
|
||||
this._controlPlay.update();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onError(ev) {
|
||||
this.showOverlay();
|
||||
this._controlPlay.update();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onPlay(ev) {
|
||||
this._controlPlay.update();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onPlaying(ev) {
|
||||
this._controlPlay.update();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onPause(ev) {
|
||||
this.showOverlay();
|
||||
this._controlPlay.update();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onProgress(ev) {
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onRateChange(ev) {
|
||||
this._controlPlay.update();
|
||||
}
|
||||
_onTimeUpdate(ev) {
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onVolumeChange(ev) {
|
||||
this._controlMute.update();
|
||||
this._controlVolume.update();
|
||||
}
|
||||
|
||||
// Media Stream Status
|
||||
_onCanPlay(ev) { }
|
||||
_onCanPlayThrough(ev) { }
|
||||
_onDurationChange(ev) {
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onEmptied(ev) { }
|
||||
_onEncrypted(ev) { }
|
||||
_onLoadedData(ev) {
|
||||
this._hideAudioControlWithoutAudio();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onLoadedMetaData(ev) {
|
||||
this._hideAudioControlWithoutAudio();
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onLoadStart(ev) { }
|
||||
_onSeeked(ev) {
|
||||
this._controlTime.update();
|
||||
this._controlProgress.update();
|
||||
}
|
||||
_onSeeking(ev) { }
|
||||
_onSuspend(ev) { }
|
||||
_onWaiting(ev) { }
|
||||
|
||||
// User Input
|
||||
_onClick(ev) {
|
||||
if ((ev.target == this._controlPlay) || (ev.target == this._media)) {
|
||||
this.togglePlayPause();
|
||||
} else if (ev.target == this._controlMute) {
|
||||
this.toggleMute();
|
||||
} else if (ev.target == this._controlFullscreen) {
|
||||
this.toggleFullscreen();
|
||||
} else if (ev.target == this._controlVariant) {
|
||||
this.toggleVariants();
|
||||
} else {
|
||||
// If we can't handle this, let it fall to the next handler.
|
||||
return
|
||||
}
|
||||
|
||||
// Prevent default behavior and stop propagation.
|
||||
this.showOverlay();
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
_onDblClick(ev) {
|
||||
this._controlFullscreen.click();
|
||||
this.showOverlay();
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
_onMouseEnter(ev) { }
|
||||
_onMouseMove(ev) {
|
||||
this.showOverlay();
|
||||
}
|
||||
_onMouseLeave(ev) { }
|
||||
_onMouseDown(ev) {
|
||||
this.showOverlay();
|
||||
|
||||
if (ev.target == this._controlProgress) {
|
||||
if ((ev.button == 0) && (!this._isSeeking)) {
|
||||
this._isSeeking = true;
|
||||
this._isSeekingPaused = this._media.paused;
|
||||
this._media.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
_onMouseUp(ev) {
|
||||
this.showOverlay();
|
||||
|
||||
if (ev.target == this._controlProgress) {
|
||||
if ((ev.button == 0) && (this._isSeeking)) {
|
||||
if (!this._isSeekingPaused) // Resume playback after dragging the dot.
|
||||
this._media.play();
|
||||
this._isSeeking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_onKeyDown(ev) {
|
||||
this.showOverlay();
|
||||
|
||||
// Ignore IME compositing.
|
||||
if (ev.isComposing || ev.keyCode === 229) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (["Space", "Enter"].includes(ev.code)) {
|
||||
// Most likely an attempt to simulate a click.
|
||||
ev.target.click();
|
||||
} else if (["Escape"].includes(ev.key)) {
|
||||
if (document.fullscreenElement) {
|
||||
this.toggleFullscreen(false);
|
||||
} else {
|
||||
this.toggleTheater(false);
|
||||
}
|
||||
} else if (["f", "F"].includes(ev.key)) {
|
||||
this._controlFullscreen.click();
|
||||
} else if (["m", "M"].includes(ev.key)) {
|
||||
this._controlMute.click();
|
||||
} else if (ev.code === "Home") {
|
||||
this._media.currentTime = 0;
|
||||
} else if (ev.code === "ArrowLeft") {
|
||||
this._media.currentTime -= 5;
|
||||
} else if (ev.code === "Comma") {
|
||||
this._media.currentTime -= .1;
|
||||
} else if (ev.code === "Period") {
|
||||
this._media.currentTime += .1;
|
||||
} else if (ev.code === "ArrowRight") {
|
||||
this._media.currentTime += 5;
|
||||
} else if (ev.code === "End") {
|
||||
this._media.currentTime = this._media.duration;
|
||||
} else if (ev.code === "ArrowUp") {
|
||||
this._media.volume = Math.max(0, Math.min(this._media.volume + 0.05, 1.0));
|
||||
} else if (ev.code === "ArrowDown") {
|
||||
this._media.volume = Math.max(0, Math.min(this._media.volume - 0.05, 1.0));
|
||||
} else if (["p", "P"].includes(ev.key)) {
|
||||
this._media.preservesPitch = !this._media.preservesPitch;
|
||||
} else if (ev.code === "PageDown") {
|
||||
this._media.playbackRate = Math.max(0.25, Math.min(this._media.playbackRate - 0.05, 4.0));
|
||||
} else if (ev.code === "PageUp") {
|
||||
this._media.playbackRate = Math.max(0.25, Math.min(this._media.playbackRate + 0.05, 4.0));
|
||||
} else if (["r", "R"].includes(ev.key)) {
|
||||
this._media.playbackRate = 1.0;
|
||||
} else {
|
||||
// If we can't handle this, let it fall to the next handler.
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent default behavior and stop propagation.
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
_onWheel(ev) {
|
||||
this.showOverlay();
|
||||
}
|
||||
_onInput(ev) {
|
||||
this.toggleVariants(false);
|
||||
if (ev.target == this._controlProgress) {
|
||||
ev.preventDefault();
|
||||
if (isFinite(this._media.duration)) {
|
||||
let min = parseInt(this._controlProgress.min, 10);
|
||||
let max = parseInt(this._controlProgress.max, 10);
|
||||
let val = parseInt(this._controlProgress.value, 10);
|
||||
let dlt = max - min;
|
||||
let time = (val - min) / dlt;
|
||||
this._media.currentTime = time * this._media.duration;
|
||||
}
|
||||
} else if (ev.target == this._controlVolume) {
|
||||
let min = parseInt(this._controlVolume.min, 10);
|
||||
let max = parseInt(this._controlVolume.max, 10);
|
||||
let val = parseInt(this._controlVolume.value, 10);
|
||||
let dlt = max - min;
|
||||
let vol = (val - min) / dlt;
|
||||
this._media.volume = vol;
|
||||
this._media.muted = (this._media.volume < 0.01);
|
||||
} else if (ev.target == this._variants) {
|
||||
// Switch out the video file.
|
||||
// Store current state and pause.
|
||||
let paused = this._media.paused;
|
||||
let muted = this._media.muted;
|
||||
let volume = this._media.volume;
|
||||
let time = this._media.currentTime;
|
||||
this._media.pause();
|
||||
this._controlPlay.update();
|
||||
|
||||
// Tell the this._media source to begin loading.
|
||||
this._media.src = this._variants.value;
|
||||
this._media.load();
|
||||
this._media.currentTime = time;
|
||||
|
||||
this._media.addEventListener("loadeddata", () => {
|
||||
this._media.currentTime = time;
|
||||
this._media.volume = volume;
|
||||
this._media.muted = muted;
|
||||
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}, {
|
||||
"once": true,
|
||||
"capture": true
|
||||
})
|
||||
this._media.addEventListener("seeked", () => {
|
||||
if (paused) {
|
||||
this._media.pause();
|
||||
} else {
|
||||
this._media.play();
|
||||
}
|
||||
this._controlPlay.update();
|
||||
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}, {
|
||||
"once": true,
|
||||
"capture": true
|
||||
});
|
||||
}
|
||||
}
|
||||
_onChange(ev) {}
|
||||
|
||||
// Visibility
|
||||
_onFullscreenChange(ev) {
|
||||
this._controlFullscreen.update();
|
||||
}
|
||||
|
||||
// Control Functions
|
||||
togglePlayPause() {
|
||||
if (this._isSeeking) {
|
||||
this._isSeekingPaused = !this._isSeekingPaused;
|
||||
} else {
|
||||
if (this._media.paused) {
|
||||
this._media.play();
|
||||
} else {
|
||||
this._media.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toggleMute() {
|
||||
this._media.muted = !this._media.muted;
|
||||
}
|
||||
|
||||
toggleVariants(state) {
|
||||
if ((state == false) || (!this._variants.classList.contains("hide"))) {
|
||||
this._variants.classList.add("hide");
|
||||
} else {
|
||||
this._variants.classList.remove("hide");
|
||||
}
|
||||
}
|
||||
|
||||
toggleFullscreen(state) {
|
||||
if ((state == false) || (document.fullscreenElement == this._container)) {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
} else {
|
||||
this._container.requestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
showOverlay() {
|
||||
if (this._overlayTimeout) {
|
||||
clearTimeout(this._overlayTimeout);
|
||||
}
|
||||
|
||||
this._container.classList.remove("hide");
|
||||
this._overlayTimeout = setTimeout(() => { this.hideOverlay(); }, 2500);
|
||||
}
|
||||
|
||||
hideOverlay() {
|
||||
if (this._overlayTimeout) {
|
||||
clearTimeout(this._overlayTimeout);
|
||||
}
|
||||
|
||||
// Prevent overlay from hiding during special operations.
|
||||
if (
|
||||
this._media.paused ||
|
||||
this._media.ended ||
|
||||
this._media.error ||
|
||||
(this._media.readyState !== 4) ||
|
||||
(!this._variants.classList.contains("hide")) ||
|
||||
this._isSeeking) {
|
||||
this.showOverlay();
|
||||
return;
|
||||
}
|
||||
|
||||
// In all other cases, just continue.
|
||||
this._container.classList.add("hide");
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
// Support for Mobile Devices
|
||||
document.querySelector("#navigation-toggle").addEventListener("click", (ev) => {
|
||||
document.querySelector("#header #navigation").classList.toggle("open");
|
||||
});
|
||||
|
||||
// Shims
|
||||
// - :has() is missing in many browsers.
|
||||
document.querySelectorAll("*").forEach((v, k) => {
|
||||
let s = new Set();
|
||||
for (let c of v.children) {
|
||||
s.add(c.tagName.toLocaleLowerCase());
|
||||
}
|
||||
if (s.size > 0)
|
||||
v.dataset["has"] = Array.from(s.values()).join(" ");
|
||||
});
|
||||
|
||||
// Lazily load this._media
|
||||
xmr_media_lazyload_initialize();
|
||||
|
||||
// Initialize this._media player.
|
||||
for (let el of document.querySelectorAll("video")) {
|
||||
el.player = new XMediaPlayer(el);
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user