Update player UI element on fullscreen change; when in fullscreen, limit potential player UI elements to full screen element (if it exists)

This commit is contained in:
Tamius Han 2025-07-16 02:53:40 +02:00
parent 090f112463
commit 14f8453067

View File

@ -24,10 +24,16 @@ interface PlayerDimensions {
interface ElementData { interface ElementData {
element: HTMLElement, element: HTMLElement,
type: string, type: string, // kinda forgot what this is being used for
tagName?: string, tagName?: string,
classList?: any, classList?: any,
id?: string id?: string
width?: number;
height?: number;
heuristics?: any;
index?: number,
autoScore?: number;
} }
type ElementStack = ElementData[]; type ElementStack = ElementData[];
@ -272,7 +278,6 @@ class PlayerData {
return; return;
} }
if ( if (
this.isFullscreen this.isFullscreen
|| ( || (
@ -382,6 +387,8 @@ class PlayerData {
try { try {
// get player dimensions _once_ // get player dimensions _once_
let currentPlayerDimensions; let currentPlayerDimensions;
let fsChanged = this.isFullscreen !== !!document.fullscreenElement;
this.isFullscreen = !!document.fullscreenElement; this.isFullscreen = !!document.fullscreenElement;
if (this.isFullscreen) { if (this.isFullscreen) {
@ -424,6 +431,10 @@ class PlayerData {
// Save current dimensions to avoid triggering this function pointlessly // Save current dimensions to avoid triggering this function pointlessly
this.dimensions = currentPlayerDimensions; this.dimensions = currentPlayerDimensions;
if (fsChanged) {
this.updatePlayer();
}
} catch (e) { } catch (e) {
} }
@ -562,19 +573,21 @@ class PlayerData {
//#endregion //#endregion
private getElementStack(): ElementStack { private getElementStack(): ElementStack {
const elementStack: any[] = [{ const elementStack: ElementStack = [{
element: this.videoElement, element: this.videoElement,
type: 'video', type: 'video',
tagName: 'video', tagName: 'video',
classList: this.videoElement.classList, classList: this.videoElement.classList,
id: this.videoElement.id, id: this.videoElement.id,
}]; }];
let element = this.videoElement.parentNode as HTMLElement; let element = this.videoElement.parentNode as HTMLElement;
// first pass to generate the element stack and translate it into array // first pass to generate the element stack and translate it into array
while (element) { while (element) {
elementStack.push({ elementStack.push({
element, element,
type: '',
tagName: element.tagName, tagName: element.tagName,
classList: element.classList, classList: element.classList,
id: element.id, id: element.id,
@ -705,21 +718,31 @@ class PlayerData {
* @param videoHeight * @param videoHeight
* @returns * @returns
*/ */
private getPlayerAuto(elementStack: any[], videoWidth, videoHeight) { private getPlayerAuto(elementStack: ElementStack, videoWidth, videoHeight) {
let penaltyMultiplier = 1; let penaltyMultiplier = 2;
const sizePenaltyMultiplier = 0.1; const sizePenaltyMultiplier = 0.1;
const perLevelScorePenalty = 10; const perLevelScorePenalty = 10;
let sameSizeBonus = 0; let sameSizeBonus = 0;
for (const [index, element] of elementStack.entries()) { const fullscreenElement = document.fullscreenElement;
element.index = index;
for (const [index, elementData] of elementStack.entries()) {
elementData.index = index;
// ignore weird elements, those would break our stuff // ignore weird elements, those would break our stuff
if (element.width == 0 || element.height == 0) { if (elementData.width == 0 || elementData.height == 0) {
element.heuristics['invalidSize'] = true; elementData.heuristics['invalidSize'] = true;
continue; continue;
} }
if (elementData.element === fullscreenElement) {
// reset penalty multiplier if current element is full screen element
// penaltyMultiplier here must be smaller than initial penalty multiplier,
// so that playerElement is not above fullscreenElement. Player element must
// be a descendant of fullscreenElement for the UI to show up
penaltyMultiplier = 1;
}
// element is player, if at least one of the sides is as long as the video // element is player, if at least one of the sides is as long as the video
// note that we can't make any additional assumptions with regards to player // note that we can't make any additional assumptions with regards to player
// size, since there are both cases where the other side is bigger _and_ cases // size, since there are both cases where the other side is bigger _and_ cases
@ -728,8 +751,8 @@ class PlayerData {
// Don't bother thinking about this too much, as any "thinking" was quickly // Don't bother thinking about this too much, as any "thinking" was quickly
// corrected by bugs caused by various edge cases. // corrected by bugs caused by various edge cases.
if ( if (
this.equalish(element.height, videoHeight, 5) this.equalish(elementData.height, videoHeight, 5)
|| this.equalish(element.width, videoWidth, 5) || this.equalish(elementData.width, videoWidth, 5)
) { ) {
let score = 1000; let score = 1000;
@ -740,8 +763,8 @@ class PlayerData {
// Our ideal player will be as close to the video element, and it will als // Our ideal player will be as close to the video element, and it will als
// be as close to the size of the video. // be as close to the size of the video.
const diffX = (element.width - videoWidth); const diffX = (elementData.width - videoWidth);
const diffY = (element.height - videoHeight); const diffY = (elementData.height - videoHeight);
// we have a minimal amount of grace before we start dinking scores for // we have a minimal amount of grace before we start dinking scores for
// mismatched dimensions. The size of the dimension mismatch dink is // mismatched dimensions. The size of the dimension mismatch dink is
@ -760,14 +783,14 @@ class PlayerData {
// candidate gets dinked a bit // candidate gets dinked a bit
// score -= perLevelScorePenalty * penaltyMultiplier; // score -= perLevelScorePenalty * penaltyMultiplier;
if (element.width === elementStack[index - 1].width && element.height === elementStack[index - 1].height) { if (elementData.width === elementStack[index - 1].width && elementData.height === elementStack[index - 1].height) {
score += ++sameSizeBonus; score += ++sameSizeBonus;
} else { } else {
sameSizeBonus = 0; sameSizeBonus = 0;
} }
element.autoScore = score; elementData.autoScore = score;
element.heuristics['autoScoreDetails'] = { elementData.heuristics['autoScoreDetails'] = {
playerSizePenalty, playerSizePenalty,
diffX, diffX,
diffY, diffY,