Compare commits
12 Commits
069f81d2ed
...
42cde0a2b3
Author | SHA1 | Date | |
---|---|---|---|
42cde0a2b3 | |||
95a41a2eb2 | |||
0af32d6892 | |||
aa35dac108 | |||
64089fa3c1 | |||
93f404b2ed | |||
f59b6af3af | |||
601514a7c8 | |||
3ed3aca001 | |||
8c6010ffe1 | |||
600f055c65 | |||
cbef965645 |
@ -332,6 +332,7 @@ export interface SiteSettingsInterface {
|
||||
override?: boolean; // whether settings for this site will be overwritten by extension upgrade script
|
||||
|
||||
workarounds?: {
|
||||
iframeTransparencyWarningDismissed?: boolean;
|
||||
disableColorSchemeAwareness?: boolean;
|
||||
forceColorScheme?: 'normal' | 'light' | 'dark',
|
||||
lastColorSchemeAwarenessCheck?: Date;
|
||||
|
@ -36,6 +36,17 @@
|
||||
</div>
|
||||
|
||||
Ultrawidify
|
||||
|
||||
<div
|
||||
v-if="!siteSettings?.data.workarounds?.iframeTransparencyWarningDismissed"
|
||||
class="absolute ui-warning small uw-clickable">
|
||||
If all you see is white or black screen,<br/>disable UI and report your GPU to github.<br/>Open.<br/>
|
||||
|
||||
<br />
|
||||
<br /> You can also <a href="" @click="iframeAutofix()">click here to attempt a fix</a>.
|
||||
<br />
|
||||
<br /> If you experience no issues, <a href="" @click="iframeDismiss()">click here to hide this warning.</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
@ -452,6 +463,7 @@ export default {
|
||||
this.sendToParentLowLevel('uw-bus-tunnel', {
|
||||
action: 'get-player-dimensions'
|
||||
});
|
||||
this.sendToParentLowLevel('uw-get-page-stats', null);
|
||||
},
|
||||
|
||||
destroyed() {
|
||||
@ -585,6 +597,22 @@ export default {
|
||||
|
||||
handleBusTunnelIn(payload) {
|
||||
this.eventBus.send(payload.action, payload.config, payload.routingData);
|
||||
},
|
||||
|
||||
async iframeAutofix() {
|
||||
console.log('site:', this.site, this.siteSettings);
|
||||
if (this.siteSettings?.data.workarounds?.disableColorSchemeAwareness === false) {
|
||||
await this.settings.setProp(['sites', this.site, 'workarounds', 'disableColorSchemeAwareness'], true);
|
||||
} else {
|
||||
await this.settings.setProp(['sites', this.site, 'workarounds', 'disableColorSchemeAwareness'], false);
|
||||
}
|
||||
await this.settings.saveWithoutReload();
|
||||
this.eventBus.sendToTunnel('uw-reload-window');
|
||||
},
|
||||
async iframeDismiss() {
|
||||
await this.settings.setProp(['sites', this.site, 'workarounds', 'iframeTransparencyWarningDismissed'], true);
|
||||
await this.settings.save();
|
||||
this.eventBus.sendToTunnel('uw-reload-window');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -656,10 +684,14 @@ export default {
|
||||
.ui-warning {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translateY(-100%);
|
||||
|
||||
max-width: 16rem;
|
||||
width: 16rem;
|
||||
max-width: 20rem;
|
||||
width: 20rem;
|
||||
|
||||
padding: 1rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
overflow: hidden;
|
||||
overflow-wrap: break-word;
|
||||
@ -667,6 +699,17 @@ export default {
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
word-wrap: break-word;
|
||||
|
||||
&.small {
|
||||
font-size: 0.85rem;
|
||||
color: #888;
|
||||
background-color: rgba(0,0,0,0.69);
|
||||
|
||||
a {
|
||||
color: #fa6;
|
||||
opacity: 0.69;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,6 +16,27 @@
|
||||
<li> <a target="_blank" href="https://github.com/tamius-han/ultrawidify/issues"><b>Github (preferred)</b></a><br/></li>
|
||||
<li>Email: <a target="_blank" :href="mailtoLink">tamius.han@gmail.com</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<b>Is your screen entirely white or entirely black?</b>
|
||||
|
||||
<p>This appears to be a rare issue that happens to some people. If you're experiencing this issue, please consider contacting me and sharing the following data:</p>
|
||||
|
||||
<ul>
|
||||
<li>Which sites this problem appears on and whether it happens on youtube. If you use youtube premium, please try signing out of youtube (or use a new profile in Google Chrome) in order to see whether youtube premium is required.</li>
|
||||
<li>your browser (get full version from <code>chrome://settings/help</code>). if using browsers other than Chrome, please try to reproduce this issue in Chrome</li>
|
||||
<li>your operating system</li>
|
||||
<li>your graphics card</li>
|
||||
<li>whether you're using dark theme in your OS, and whether you're using website's built-in dark/light theme.</li>
|
||||
</ul>
|
||||
|
||||
<p>Please post this info to <a href="https://github.com/tamius-han/ultrawidify/issues/262" target="_blank">this thread</a>, or message me via e-mail.</p>
|
||||
|
||||
<p>Then, disable the in-player UI.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>
|
||||
When reporting bugs, please include the following information:
|
||||
</p>
|
||||
@ -67,6 +88,7 @@ export default {
|
||||
mailtoLink: '',
|
||||
redditLink: '',
|
||||
showEasterEgg: false,
|
||||
pageData: {}
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
|
@ -32,7 +32,7 @@
|
||||
<li>Half-fixed in-player UI on sites where player is not detected correctly</li>
|
||||
</ul>
|
||||
|
||||
<h3>6.2.3</h3>
|
||||
<h3>6.2.3 (current)</h3>
|
||||
<ul>
|
||||
<li>Fixed default persistent mode</li>
|
||||
</ul>
|
||||
|
@ -111,7 +111,7 @@ export default class UWContent {
|
||||
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] KeyboardHandler initiated.");
|
||||
|
||||
this.globalUi = new UI('ultrawidify-global-ui', {eventBus: this.eventBus, isGlobal: true});
|
||||
this.globalUi = new UI('ultrawidify-global-ui', {eventBus: this.eventBus, isGlobal: true, siteSettings: this.siteSettings});
|
||||
this.globalUi.enable();
|
||||
this.globalUi.setUiVisibility(false);
|
||||
|
||||
|
@ -379,7 +379,7 @@ export default class UWServer {
|
||||
}
|
||||
|
||||
async verifyUiTransparency(verificationData: IframeVerificationPlayerData, sender: MessageSender, telemetryData?: any) {
|
||||
const hasTransparency = this.IframeTransparencyVerifier.verifyUiTransparency(
|
||||
const transparencyVerificationResult = await this.IframeTransparencyVerifier.verifyUiTransparency(
|
||||
sender.tab.windowId,
|
||||
{
|
||||
player: verificationData,
|
||||
@ -390,8 +390,13 @@ export default class UWServer {
|
||||
}
|
||||
);
|
||||
|
||||
console.log('Transparency confirmed.');
|
||||
|
||||
this.eventBus.send(
|
||||
'iframe-transparency-results',
|
||||
{
|
||||
transparencyVerificationResult
|
||||
},
|
||||
{
|
||||
comms: {
|
||||
forwardTo: 'active'
|
||||
@ -399,12 +404,12 @@ export default class UWServer {
|
||||
}
|
||||
);
|
||||
|
||||
axios.post(
|
||||
'https://uw-telemetry.tamius.net/iframe-transparency',
|
||||
{
|
||||
...telemetryData,
|
||||
transparencyCheckResult: hasTransparency,
|
||||
}
|
||||
);
|
||||
// axios.post(
|
||||
// 'https://uw-telemetry.tamius.net/iframe-transparency',
|
||||
// {
|
||||
// ...telemetryData,
|
||||
// transparencyCheckResult: hasTransparency,
|
||||
// }
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
@ -34,41 +34,53 @@ interface IframeCheckPosition {
|
||||
|
||||
export class IframeTransparencyVerifier {
|
||||
|
||||
async verifyUiTransparency(windowId: number, tabDimensions: IframeVerificationData): Promise<TransparencyVerificationResult> {
|
||||
const {visibleX, visibleY} = this.getVisibleMarkers(tabDimensions);
|
||||
if (!visibleX.length || visibleY.length) {
|
||||
return TransparencyVerificationResult.NoVisibleElements;
|
||||
}
|
||||
async verifyUiTransparency(windowId: number, tabDimensions: IframeVerificationData): Promise<{result: TransparencyVerificationResult, dataUrl?: string}> { console.info('Verifying UI transparency:', tabDimensions);
|
||||
|
||||
const checkPositions = this.processMarkers(visibleX, visibleY);
|
||||
// const {visibleX, visibleY} = this.getVisibleMarkers(tabDimensions);
|
||||
// if (!visibleX.length || !visibleY.length) {
|
||||
// console.warn('[transparency check] No visible elements.');
|
||||
return {result: TransparencyVerificationResult.NoVisibleElements};
|
||||
// }
|
||||
|
||||
const dataUrl = await chrome.tabs.captureVisibleTab(
|
||||
windowId,
|
||||
{
|
||||
format: "png"
|
||||
}
|
||||
);
|
||||
// const checkPositions = this.processMarkers(visibleX, visibleY);
|
||||
|
||||
try {
|
||||
const canvas = new OffscreenCanvas(tabDimensions.tab.width, tabDimensions.tab.height);
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
// const dataUrl = await chrome.tabs.captureVisibleTab(
|
||||
// undefined, // windowId,
|
||||
// {
|
||||
// format: "png"
|
||||
// }
|
||||
// );
|
||||
|
||||
const image = new Image();
|
||||
const imageLoadPromise = new Promise(r => image.onload = r);
|
||||
image.src = dataUrl;
|
||||
await imageLoadPromise;
|
||||
(ctx as any).drawImage(image, 0, 0);
|
||||
// try {
|
||||
// const canvas = new OffscreenCanvas(tabDimensions.tab.width, tabDimensions.tab.height);
|
||||
// const ctx = canvas.getContext('2d')!;
|
||||
|
||||
const imageData = (ctx as any).getImageData(0, 0, tabDimensions.tab.width, tabDimensions.tab.height).data;
|
||||
// const res = await fetch(dataUrl);
|
||||
// const blob = await res.blob();
|
||||
|
||||
if (this.detectMarkers(checkPositions, tabDimensions.tab.width, imageData)) {
|
||||
return TransparencyVerificationResult.Ok;
|
||||
} else {
|
||||
return TransparencyVerificationResult.Fail;
|
||||
}
|
||||
} catch (e) {
|
||||
return TransparencyVerificationResult.Error;
|
||||
}
|
||||
// const bitmap = createImageBitmap(blob);
|
||||
|
||||
// (ctx as any).drawImage(bitmap, 0, 0);
|
||||
|
||||
// const imageData = (ctx as any).getImageData(0, 0, tabDimensions.tab.width, tabDimensions.tab.height).data;
|
||||
|
||||
// if (this.detectMarkers(checkPositions, tabDimensions.tab.width, imageData)) {
|
||||
// console.info('Verified transparency');
|
||||
// return {
|
||||
// result: TransparencyVerificationResult.Ok,
|
||||
// dataUrl: dataUrl
|
||||
// };
|
||||
// } else {
|
||||
// console.info('Transparency checks came back negative');
|
||||
// return {
|
||||
// result: TransparencyVerificationResult.Fail,
|
||||
// dataUrl: dataUrl
|
||||
// };
|
||||
// }
|
||||
// } catch (e) {
|
||||
// console.error('[transparency check] Error while checking for transparency:', e);
|
||||
// return {result: TransparencyVerificationResult.Error};
|
||||
// }
|
||||
}
|
||||
|
||||
private getVisibleMarkers({tab, player}: IframeVerificationData) {
|
||||
@ -78,6 +90,8 @@ export class IframeTransparencyVerifier {
|
||||
// Determine which markers should be visible.
|
||||
|
||||
// Visibility: TOP ROW
|
||||
console.log('player:', player.y, tab.height);
|
||||
|
||||
if (player.y >= 0 && player.y < tab.height) {
|
||||
visibleY.push({
|
||||
position: 'top',
|
||||
@ -87,7 +101,7 @@ export class IframeTransparencyVerifier {
|
||||
|
||||
// Visibility: CENTER
|
||||
const yHalfPosition = Math.floor(player.y + player.height / 2);
|
||||
if (player.y + yHalfPosition - 2 > 0 || player.y + yHalfPosition + 2 < tab.height) {
|
||||
if (player.y + yHalfPosition - 2 > 0 && player.y + yHalfPosition + 2 < tab.height) {
|
||||
visibleY.push({
|
||||
position: 'center',
|
||||
offset: player.y + yHalfPosition,
|
||||
@ -95,7 +109,7 @@ export class IframeTransparencyVerifier {
|
||||
}
|
||||
|
||||
// Visibility: BOTTOM ROW
|
||||
if (player.y + player.height - 1 > 0 || player.y + player.height + 1 < tab.height) {
|
||||
if (player.y + player.height - 1 > 0 && player.y + player.height + 1 < tab.height) {
|
||||
visibleY.push({
|
||||
position: 'bottom',
|
||||
offset: player.y + player.height - 1,
|
||||
@ -112,21 +126,23 @@ export class IframeTransparencyVerifier {
|
||||
|
||||
// Visibility: X CENTER
|
||||
const xHalfPosition = Math.floor(player.x + player.width / 2);
|
||||
if (player.x + xHalfPosition - 2 > 0 || player.x + xHalfPosition + 2 < tab.width) {
|
||||
visibleY.push({
|
||||
if (player.x + xHalfPosition - 2 > 0 && player.x + xHalfPosition + 2 < tab.width) {
|
||||
visibleX.push({
|
||||
position: 'center',
|
||||
offset: player.x + xHalfPosition,
|
||||
});
|
||||
}
|
||||
|
||||
// Visibility: RIGHT SIDE
|
||||
if (player.x + player.width - 1 > 0 || player.x + player.width + 1 < tab.width) {
|
||||
if (player.x + player.width - 1 > 0 && player.x + player.width + 1 < tab.width) {
|
||||
visibleX.push({
|
||||
position: 'right',
|
||||
offset: player.x + player.width - 1,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('visible candidates', visibleX, visibleY);
|
||||
|
||||
return {
|
||||
visibleX,
|
||||
visibleY,
|
||||
|
@ -323,8 +323,38 @@ class Settings {
|
||||
this.active = activeSettings;
|
||||
}
|
||||
|
||||
async setProp(prop, value) {
|
||||
this.active[prop] = value;
|
||||
/**
|
||||
* Sets value of a prop at given path.
|
||||
* @param propPath path to property we want to set. If prop path does not exist,
|
||||
* this function will recursively create it. It is assumed that uninitialized properties
|
||||
* are objects.
|
||||
* @param value
|
||||
*/
|
||||
async setProp(propPath: string | string[], value: any, options?: {forceReload?: boolean}, currentPath?: any) {
|
||||
if (!Array.isArray(propPath)) {
|
||||
propPath = propPath.split('.');
|
||||
}
|
||||
|
||||
if (!currentPath) {
|
||||
currentPath = this.active;
|
||||
}
|
||||
|
||||
const currentProp = propPath.shift();
|
||||
|
||||
if (propPath.length) {
|
||||
if (!currentPath[currentProp]) {
|
||||
currentPath[currentProp] = {};
|
||||
}
|
||||
return this.setProp(propPath, value, options, currentPath[currentProp]);
|
||||
} else {
|
||||
currentPath[currentProp] = value;
|
||||
|
||||
if (options?.forceReload) {
|
||||
return this.save();
|
||||
} else {
|
||||
return this.saveWithoutReload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async save(options?) {
|
||||
|
@ -15,8 +15,8 @@ if (process.env.CHANNEL !== 'stable'){
|
||||
// As of 1. 1. 2025, 'light' and 'dark' are commented out in order to force 'csui-overlay-normal' everywhere.
|
||||
const csuiVersions = {
|
||||
'normal': 'csui', // csui-overlay-normal.html, maps to csui.html
|
||||
// 'light': 'csui-light', // csui-overlay-light.html, maps to csui-light.html
|
||||
// 'dark': 'csui-dark' // csui-overlay-dark.html, maps to csui-dark.html
|
||||
'light': 'csui-light', // csui-overlay-light.html, maps to csui-light.html
|
||||
'dark': 'csui-dark' // csui-overlay-dark.html, maps to csui-dark.html
|
||||
};
|
||||
|
||||
const MAX_IFRAME_ERROR_COUNT = 5;
|
||||
@ -29,14 +29,10 @@ class UI {
|
||||
this.interfaceId = interfaceId;
|
||||
this.uiConfig = uiConfig;
|
||||
this.lastProbeResponseTs = null;
|
||||
this.isVisible = false;
|
||||
this.isOpaque = false;
|
||||
|
||||
this.isGlobal = uiConfig.isGlobal ?? false;
|
||||
// TODO: at some point, UI should be different for global popup and in-player UI
|
||||
const preferredScheme = window.getComputedStyle( document.body ,null).getPropertyValue('color-scheme');
|
||||
const csuiVersion = csuiVersions[preferredScheme] ?? csuiVersions.normal;
|
||||
|
||||
this.uiURI = chrome.runtime.getURL(`/csui/${csuiVersion}.html`);
|
||||
this.extensionBase = chrome.runtime.getURL('').replace(/\/$/, "");
|
||||
|
||||
this.eventBus = uiConfig.eventBus;
|
||||
this.disablePointerEvents = false;
|
||||
@ -44,15 +40,44 @@ class UI {
|
||||
this.saveState = undefined;
|
||||
this.playerData = uiConfig.playerData;
|
||||
this.uiSettings = uiConfig.uiSettings;
|
||||
this.siteSettings = uiConfig.siteSettings;
|
||||
this.settings = uiConfig.settings;
|
||||
|
||||
this.iframeErrorCount = 0;
|
||||
this.iframeConfirmed = false;
|
||||
this.iframeRejected = false;
|
||||
|
||||
this.preventHiding = false;
|
||||
this.wantsToHide = false;
|
||||
this.wantsToTransparent = false;
|
||||
this.performedTransparencyCheck = false;
|
||||
|
||||
// TODO: at some point, UI should be different for global popup and in-player UI
|
||||
const csuiVersion = this.getCsuiVersion();
|
||||
this.uiURI = chrome.runtime.getURL(`/csui/${csuiVersion}.html`);
|
||||
this.extensionBase = chrome.runtime.getURL('').replace(/\/$/, "");
|
||||
}
|
||||
|
||||
async init() {
|
||||
try {
|
||||
this.initIframes();
|
||||
this.initMessaging();
|
||||
} catch (e) {
|
||||
console.error('failed to init ui:', e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getCsuiVersion() {
|
||||
if (this.siteSettings?.workarounds?.forceColorScheme) {
|
||||
return csuiVersions[this.siteSettings.workarounds.forceColorScheme];
|
||||
}
|
||||
if (this.siteSettings?.data?.workarounds?.disableColorSchemeAwareness !== false) {
|
||||
return csuiVersions.normal;
|
||||
}
|
||||
|
||||
const preferredScheme = window.getComputedStyle( document.body ,null).getPropertyValue('color-scheme');
|
||||
return csuiVersions[preferredScheme] ?? csuiVersions.normal;
|
||||
}
|
||||
|
||||
initIframes() {
|
||||
@ -94,8 +119,8 @@ class UI {
|
||||
iframe.style.position = "absolute";
|
||||
iframe.style.zIndex = this.isGlobal ? '90009' : '90000';
|
||||
iframe.style.border = 0;
|
||||
iframe.style.pointerEvents = 'none';
|
||||
iframe.style.opacity = 0;
|
||||
iframe.style.pointerEvents = 'none';
|
||||
iframe.style.backgroundColor = 'transparent !important';
|
||||
|
||||
/* so we have a problem: we want iframe to be clickthrough everywhere except
|
||||
@ -158,6 +183,18 @@ class UI {
|
||||
document.addEventListener('mousemove', fn, true);
|
||||
}
|
||||
|
||||
// Add some squares to the page.
|
||||
// Sets up checks for conditions that cause these two mutually exclusive issues:
|
||||
// * https://github.com/tamius-han/ultrawidify/issues/262
|
||||
// * https://github.com/tamius-han/ultrawidify/issues/259
|
||||
for (const x of ['left', 'center', 'right']) {
|
||||
for (const y of ['top', 'center', 'bottom']) {
|
||||
if (x !== y) {
|
||||
rootDiv.appendChild(this.generateDebugMarker(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootDiv.appendChild(iframe);
|
||||
}
|
||||
|
||||
@ -173,6 +210,11 @@ class UI {
|
||||
|
||||
this.eventBus.subscribeMulti(
|
||||
{
|
||||
'uw-reload-window': {
|
||||
function: () => {
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
'uw-config-broadcast': {
|
||||
function: (config, routingData) => {
|
||||
this.sendToIframe('uw-config-broadcast', config, routingData);
|
||||
@ -190,24 +232,6 @@ class UI {
|
||||
this.sendToIframe('uw-set-ui-state', {...config, isGlobal: this.isGlobal}, routingData);
|
||||
}
|
||||
},
|
||||
'uw-get-page-stats': {
|
||||
function: (config, routingData) => {
|
||||
console.log('got get page stats!');
|
||||
this.eventBus.send(
|
||||
'uw-page-stats',
|
||||
{
|
||||
pcsDark: window.matchMedia('(prefers-color-scheme: dark)').matches,
|
||||
pcsLight: window.matchMedia('(prefers-color-scheme: light)').matches,
|
||||
colorScheme: window.getComputedStyle( document.body ,null).getPropertyValue('color-scheme')
|
||||
},
|
||||
{
|
||||
comms: {
|
||||
forwardTo: 'popup'
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
'uw-restore-ui-state': {
|
||||
function: (config, routingData) => {
|
||||
if (!this.isGlobal) {
|
||||
@ -215,7 +239,25 @@ class UI {
|
||||
this.sendToIframe('uw-restore-ui-state', config, routingData);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'iframe-transparency-results': {
|
||||
function: (data, routingData) => {
|
||||
console.log('——————————— iframe transparency results are back!', data);
|
||||
}
|
||||
},
|
||||
'uw-get-page-stats': {
|
||||
function: (config, routingData) => {
|
||||
console.log('uw:Č Got page stats request')
|
||||
this.sendToIframeLowLevel(
|
||||
'uw-page-stats',
|
||||
{
|
||||
pcsDark: window.matchMedia('(prefers-color-scheme: dark)').matches,
|
||||
pcsLight: window.matchMedia('(prefers-color-scheme: light)').matches,
|
||||
colorScheme: window.getComputedStyle( document.body ,null).getPropertyValue('color-scheme')
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
this
|
||||
);
|
||||
@ -229,7 +271,151 @@ class UI {
|
||||
this.handleMessage(message);
|
||||
}
|
||||
|
||||
|
||||
verifyIframeTransparency() {
|
||||
if (this.isGlobal) {
|
||||
return;
|
||||
}
|
||||
if (!this.siteSettings || !this.settings) {
|
||||
console.warn('settings not provided, not verifying transparency');
|
||||
return;
|
||||
}
|
||||
if (this.performedTransparencyCheck || !this.isOpaque || !this.uiConfig?.parentElement) {
|
||||
// console.warn('transparency was already checked, opacity is zero, or parent element isnt a thing:', this.performedTransparencyCheck, 'is opaque:', this.isOpaque, this.uiConfig?.parentElement);
|
||||
return;
|
||||
}
|
||||
|
||||
let reportTelemetry = true;
|
||||
|
||||
// if (this.siteSettings.data.workarounds?.disableSchemeAwareness) {
|
||||
// if (this.settings.active.telemetry?.iframeTransparency?.[window.location.hostname]?.reportedWithColorSchemeDisabled) {
|
||||
// reportTelemetry = false;
|
||||
// } else {
|
||||
// this.settings.setProp(['telemetry', window.location.hostname, 'reportedWithColorSchemaDisabled'], true)
|
||||
// }
|
||||
// } else {
|
||||
// if (this.settings.active.telemetry?.iframeTransparency?.[window.location.hostname]?.reportedWithColorSchemeAllowed) {
|
||||
// reportTelemetry = false;
|
||||
// } else {
|
||||
// this.settings.setProp(['telemetry', window.location.hostname, 'reportedWithColorSchemeAllowed'], true)
|
||||
// }
|
||||
// }
|
||||
|
||||
const rect = this.uiConfig.parentElement.getBoundingClientRect();
|
||||
|
||||
this.preventHiding = true;
|
||||
setTimeout( () => {
|
||||
this.eventBus.send(
|
||||
'verify-iframe-transparency',
|
||||
{
|
||||
playerData: {
|
||||
y: rect.top,
|
||||
x: rect.left,
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
},
|
||||
telemetryData: {
|
||||
reportTelemetry,
|
||||
}
|
||||
}
|
||||
);
|
||||
}, 50);
|
||||
this.performedTransparencyCheck = true;
|
||||
|
||||
setTimeout(() => {
|
||||
this.preventHiding = false;
|
||||
if (this.wantsToHide) {
|
||||
this.setUiVisibility(false);
|
||||
}
|
||||
if (this.wantsToTransparent) {
|
||||
this.setUiOpacity(false);
|
||||
}
|
||||
this.wantsToHide = false;
|
||||
this.wantsToTransparent = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates marker positions for bug mitigations
|
||||
*/
|
||||
generateDebugMarker(x, y) {
|
||||
const [parentMainDimension, parentCrossDimension] = y === 'center' ? ['height', 'width'] : ['width', 'height'];
|
||||
|
||||
let anchorStyle;
|
||||
|
||||
if (x === 'center' && x === y) {
|
||||
anchorStyle = 'left: 50%; top: 50%; transform: translate(-50%, -50%);';
|
||||
} else {
|
||||
switch (x) {
|
||||
case 'left':
|
||||
anchorStyle = 'left: 0px;';
|
||||
break;
|
||||
case 'center':
|
||||
anchorStyle = 'left: 50%; transform: translateX(-50%);';
|
||||
break;
|
||||
case 'right':
|
||||
anchorStyle = 'right: 0px;';
|
||||
break;
|
||||
}
|
||||
switch (y) {
|
||||
case 'top':
|
||||
anchorStyle = `${anchorStyle} top: 0px;`;
|
||||
break;
|
||||
case 'center':
|
||||
anchorStyle = `${anchorStyle} top: 50%; transform: translateY(-50%);`;
|
||||
break;
|
||||
case 'bottom':
|
||||
anchorStyle = `${anchorStyle} bottom: 0px;`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let [mainAxis, crossAxis] = y === 'center' ? ['left', 'top'] : ['top', 'left'];
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<div style="position: absolute; ${anchorStyle} ${parentMainDimension}: 4px; ${parentCrossDimension}: 1px; pointer-events: none;">
|
||||
<div style="position: relative; width: 100%; height: 100%">
|
||||
<div style="position: absolute; ${mainAxis}: 0px; ${crossAxis}: 0px; width: 1px; height: 1px; background-color: #000102"></div>
|
||||
<div style="position: absolute; ${mainAxis}: 1px; ${crossAxis}: 0px; width: 1px; height: 1px; background-color: #030405"></div>
|
||||
<div style="position: absolute; ${mainAxis}: 2px; ${crossAxis}: 0px; width: 1px; height: 1px; background-color: #050403"></div>
|
||||
<div style="position: absolute; ${mainAxis}: 3px; ${crossAxis}: 0px; width: 1px; height: 1px; background-color: #020100"></div>
|
||||
</div>
|
||||
<div style="top: 5px; left: 5px; opacity: 0">
|
||||
This marker is Chrome Shitiness Mitigation mechanism for Ultrawidify. It turns out that as of 2025-01, Chrome does not correctly respect
|
||||
allowTransparency property on certain iframes, and will force white or black background across the entire element. It is unclear what's
|
||||
causing the issue — so far, it seems to appear randomly.
|
||||
</div>
|
||||
</div>
|
||||
`.replace(/\s+/g, ' ').trim();
|
||||
|
||||
return template.content.firstChild;
|
||||
}
|
||||
|
||||
|
||||
setUiOpacity(visible) {
|
||||
if (!visible && this.isVisible && this.preventHiding) {
|
||||
this.wantsToTransparent = true;
|
||||
return;
|
||||
|
||||
}
|
||||
this.uiIframe.style.opacity = visible ? '100' : '0';
|
||||
this.isOpaque = visible;
|
||||
|
||||
if (visible) {
|
||||
this.verifyIframeTransparency();
|
||||
}
|
||||
}
|
||||
|
||||
setUiVisibility(visible) {
|
||||
if (!visible && this.isVisible && this.preventHiding) {
|
||||
this.wantsToHide = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.isVisible = visible;
|
||||
|
||||
if (visible) {
|
||||
this.element.style.width = '100%';
|
||||
this.element.style.height = '100%';
|
||||
@ -241,6 +427,7 @@ class UI {
|
||||
this.uiIframe.style.width = '0px';
|
||||
this.uiIframe.style.height = '0px';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async enable() {
|
||||
@ -342,7 +529,8 @@ class UI {
|
||||
}
|
||||
|
||||
this.uiIframe.style.pointerEvents = event.data.clickable ? 'auto' : 'none';
|
||||
this.uiIframe.style.opacity = event.data.opacity || this.isGlobal ? '100' : '0';
|
||||
this.setUiOpacity(event.data.opacity || this.isGlobal);
|
||||
// this.setUiVisibility( event.data.opacity || this.isGlobal );
|
||||
break;
|
||||
case 'uw-bus-tunnel':
|
||||
const busCommand = event.data.payload;
|
||||
@ -355,7 +543,8 @@ class UI {
|
||||
this.setUiVisibility(!this.isGlobal);
|
||||
break;
|
||||
case 'uwui-hidden':
|
||||
this.uiIframe.style.opacity = event.data.opacity || this.isGlobal ? '100' : '0';
|
||||
this.setUiOpacity(event.data.opacity || this.isGlobal);
|
||||
// this.setUiVisibility(event.data.opacity || this.isGlobal);
|
||||
break;
|
||||
case 'uwui-global-window-hidden':
|
||||
if (!this.isGlobal) {
|
||||
|
@ -248,7 +248,11 @@ class PlayerData {
|
||||
//#endregion
|
||||
|
||||
deferredUiInitialization(playerDimensions) {
|
||||
if (this.ui || ! this.videoData.settings.active.ui?.inPlayer?.enabled) {
|
||||
if (
|
||||
this.ui
|
||||
|| ! this.videoData.settings.active.ui?.inPlayer?.enabled
|
||||
|| (this.siteSettings.data.ui && !this.siteSettings.data.ui.enabled)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -265,7 +269,9 @@ class PlayerData {
|
||||
parentElement: this.element,
|
||||
eventBus: this.eventBus,
|
||||
playerData: this,
|
||||
uiSettings: this.videoData.settings.active.ui
|
||||
uiSettings: this.videoData.settings.active.ui,
|
||||
settings: this.videoData.settings,
|
||||
siteSettings: this.siteSettings
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user