Merge branch 'master' into stable
This commit is contained in:
commit
861813e5be
53
.vscode/launch.json
vendored
53
.vscode/launch.json
vendored
@ -1,23 +1,40 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "firefox",
|
||||
"request": "attach",
|
||||
"name": "Attach",
|
||||
"pathMappings": [
|
||||
{
|
||||
"name": "Launch addon",
|
||||
"type": "firefox",
|
||||
"request": "launch",
|
||||
"port":6000,
|
||||
"reAttach": true,
|
||||
"addonType": "webExtension",
|
||||
"addonPath": "${workspaceFolder}/dist-ff",
|
||||
"url": "webpack:///ext",
|
||||
"path": "${workspaceFolder}/src/ext"
|
||||
}
|
||||
],
|
||||
"firefox": {
|
||||
"executable": "/usr/bin/firefox-developer-edition",
|
||||
"firefoxArgs": [
|
||||
"--start-debugger-server"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Launch addon",
|
||||
"type": "firefox",
|
||||
"request": "launch",
|
||||
"port": 6000,
|
||||
"reAttach": true,
|
||||
"addonType": "webExtension",
|
||||
"addonPath": "${workspaceFolder}/dist-ff",
|
||||
"pathMappings": [
|
||||
{
|
||||
"url": "webpack:///ext",
|
||||
"path": "${workspaceFolder}/src/ext"
|
||||
},
|
||||
]
|
||||
}
|
||||
],
|
||||
"firefox": {
|
||||
"executable": "/usr/bin/firefox-developer-edition",
|
||||
"firefoxArgs": [
|
||||
"--start-debugger-server"
|
||||
]
|
||||
}
|
||||
}
|
@ -13,7 +13,12 @@ QoL improvements for me:
|
||||
|
||||
* logging: allow to enable logging at will and export said logs to a file
|
||||
|
||||
### v4.4.8 (Current)
|
||||
### v4.4.9 (Current)
|
||||
|
||||
* Fixed the youtube alignment issue (previously fixed in v4.4.7.1-2), but this time for real (and in a bit more proper way)
|
||||
* Fixed the bug where extension wouldn't work when URL specified a port (e.g. www.example.com:80)
|
||||
|
||||
### v4.4.8
|
||||
|
||||
* Fixed the bug where on pages with more than one video, the list of available videos in the extension popup wouldn't remove videos that are no longer displayed on site. This resulted in extension listing videos that were no longer on the page. Reboot or navigation would also not clear the list if navigating between various pages on the same host.
|
||||
* Fixed the chrome-only bug where on sites with more than one video, the number wouldn't get hidden when the extension popup closed.
|
||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ultravidify",
|
||||
"version": "4.4.8",
|
||||
"version": "4.4.9",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ultrawidify",
|
||||
"version": "4.4.8",
|
||||
"version": "4.4.9",
|
||||
"description": "Aspect ratio fixer for youtube and other sites, with automatic aspect ratio detection. Supports ultrawide and other ratios.",
|
||||
"author": "Tamius Han <tamius.han@gmail.com>",
|
||||
"scripts": {
|
||||
|
@ -378,6 +378,18 @@ const ExtensionConfPatch = [
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
forVersion: '4.4.9',
|
||||
sites: {
|
||||
"www.youtube.com": {
|
||||
override: true,
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -1022,7 +1022,7 @@ var ExtensionConf = {
|
||||
keyboardShortcutsEnabled: ExtensionMode.Default,
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true,
|
||||
manual: false,
|
||||
querySelectors: "#movie_player, #player",
|
||||
additionalCss: "",
|
||||
useRelativeAncestor: false,
|
||||
|
@ -32,8 +32,8 @@ class ActionHandler {
|
||||
|
||||
var actions;
|
||||
try {
|
||||
if (this.settings.active.sites[window.location.host].actions) {
|
||||
actions = this.settings.active.sites[window.location.host].actions;
|
||||
if (this.settings.active.sites[window.location.hostname].actions) {
|
||||
actions = this.settings.active.sites[window.location.hostname].actions;
|
||||
} else {
|
||||
actions = this.settings.active.actions;
|
||||
}
|
||||
@ -247,7 +247,7 @@ class ActionHandler {
|
||||
this.setKeyboardLocal(cmd.arg);
|
||||
}
|
||||
} else {
|
||||
let site = action.scope === 'site' ? window.location.host : '@global';
|
||||
let site = action.scope === 'site' ? window.location.hostname : '@global';
|
||||
|
||||
if (cmd.action === "set-stretch") {
|
||||
this.settings.active.sites[site].stretch = cmd.arg;
|
||||
|
@ -227,29 +227,21 @@ class Logger {
|
||||
stackInfo['mousemove'] = false;
|
||||
stackInfo['exitLogs'] = false;
|
||||
|
||||
// here we check which source triggered the action. We know that only one of these
|
||||
// functions will appear in the trace at most once (and if more than one of these
|
||||
// appears — e.g. frameCheck triggered by user toggling autodetection in popup —
|
||||
// the most recent one will be the correct one 99% of the time)
|
||||
// here we check which source triggered the action. There can be more
|
||||
// than one source, too, so we don't break when we find the first one
|
||||
for (const line of stackInfo.stack.trace) {
|
||||
if (line === 'doPeriodicPlayerElementChangeCheck') {
|
||||
stackInfo['periodicPlayerCheck'] = true;
|
||||
break;
|
||||
} else if (line === 'doPeriodicFallbackChangeDetectionCheck') {
|
||||
stackInfo['periodicVideoStyleChangeCheck'] = true;
|
||||
break;
|
||||
} else if (line === 'frameCheck') {
|
||||
stackInfo['aard'] = true;
|
||||
break;
|
||||
} else if (line === 'execAction') {
|
||||
stackInfo['keyboard'] = true;
|
||||
break;
|
||||
} else if (line === 'processReceivedMessage') {
|
||||
stackInfo['popup'] = true;
|
||||
break;
|
||||
} else if (line === 'handleMouseMove') {
|
||||
stackInfo['mousemove'] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,9 +366,21 @@ class Logger {
|
||||
});
|
||||
}
|
||||
|
||||
logToConsole(message, stackInfo) {
|
||||
logToConsole(level, message, stackInfo) {
|
||||
try {
|
||||
console.log(...message, {stack: stackInfo});
|
||||
switch (level) {
|
||||
case 'error':
|
||||
console.error(...message, {stack: stackInfo});
|
||||
break;
|
||||
case 'warn':
|
||||
console.warn(...message, {stack: stackInfo});
|
||||
break;
|
||||
case 'info':
|
||||
console.info(...message, {stack: stackInfo});
|
||||
break;
|
||||
default:
|
||||
console.log(...message, {stack: stackInfo});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Message too big to log. Error:", e, "stackinfo:", stackInfo);
|
||||
}
|
||||
@ -399,7 +403,7 @@ class Logger {
|
||||
this.logToFile(message, stackInfo);
|
||||
}
|
||||
if (this.conf.consoleOptions?.enabled) {
|
||||
this.logToConsole(message, stackInfo);
|
||||
this.logToConsole(level, message, stackInfo);
|
||||
}
|
||||
return; // don't check further — recursion-land ahead!
|
||||
}
|
||||
@ -420,7 +424,7 @@ class Logger {
|
||||
}
|
||||
if (this.conf.consoleOptions?.enabled) {
|
||||
if (this.canLogConsole(component) || stackInfo.exitLogs) {
|
||||
this.logToConsole(message, stackInfo);
|
||||
this.logToConsole(level, message, stackInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class PlayerPickerHelper {
|
||||
}
|
||||
|
||||
findPlayerForVideo(settings, video) {
|
||||
const host = window.location.host;
|
||||
const host = window.location.hostname;
|
||||
let element = video.parentNode;
|
||||
|
||||
if (this.settings.active.sites[host]
|
||||
|
@ -47,6 +47,10 @@ class Settings {
|
||||
if (!parsedSettings.preventReload && this.onSettingsChanged) {
|
||||
try {
|
||||
this.onSettingsChanged();
|
||||
|
||||
|
||||
|
||||
|
||||
this.logger.log('info', 'settings', '[Settings] Update callback finished.')
|
||||
} catch (e) {
|
||||
this.logger.log('error', 'settings', "[Settings] CALLING UPDATE CALLBACK FAILED. Reason:", e)
|
||||
@ -491,41 +495,44 @@ class Settings {
|
||||
canStartAutoAr(site) {
|
||||
// 'site' argument is only ever used when calling this function recursively for debugging
|
||||
if (!site) {
|
||||
site = window.location.host;
|
||||
site = window.location.hostname;
|
||||
|
||||
if (!site) {
|
||||
this.logger.log('warn', ['settings', 'init', 'debug'], `[Settings::canStartAutoAr] No site — even window.location.hostname returned nothing!: ${window.location.hostname}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Debug.debug) {
|
||||
// if (Debug.debug) {
|
||||
// let's just temporarily disable debugging while recursively calling
|
||||
// this function to get extension status on current site without duplo
|
||||
// console logs (and without endless recursion)
|
||||
Debug.debug = false;
|
||||
const csar = this.canStartAutoAr(site);
|
||||
Debug.debug = true;
|
||||
// Debug.debug = false;
|
||||
// const csar = this.canStartAutoAr(site);
|
||||
// Debug.debug = true;
|
||||
|
||||
this.logger.log('info', 'settings', "[Settings::canStartAutoAr] ----------------\nCAN WE START AUTOAR ON SITE", site,
|
||||
this.logger.log('info', ['settings', 'init', 'debug'], "[Settings::canStartAutoAr] ----------------\nCAN WE START AUTOAR ON SITE", site,
|
||||
"?\n\nsettings.active.sites[site]=", this.active.sites[site], "settings.active.sites[@global]=", this.active.sites['@global'],
|
||||
"\nAutoar mode (global)?", this.active.sites['@global'].autoar,
|
||||
`\nAutoar mode (${site})`, this.active.sites[site] ? this.active.sites[site].autoar : '<not defined>',
|
||||
"\nCan autoar be started?", csar
|
||||
// "\nCan autoar be started?", csar
|
||||
);
|
||||
}
|
||||
// }
|
||||
|
||||
// if site is not defined, we use default mode:
|
||||
if (! this.active.sites[site]) {
|
||||
this.logger.log('info', ['settings', 'aard', 'init', 'debug'], "[Settings::canStartAutoAr] Settings not defined for this site, returning defaults.", site, this.active.sites[site], this.active.sites);
|
||||
return this.active.sites['@global'].autoar === ExtensionMode.Enabled;
|
||||
}
|
||||
|
||||
if (this.active.sites['@global'].autoar === ExtensionMode.Enabled) {
|
||||
this.logger.log('info', ['settings', 'aard', 'init', 'debug'], `[Settings::canStartAutoAr] Aard is enabled by default. Extension can run unless disabled for this site.`, this.active.sites[site].autoar);
|
||||
return this.active.sites[site].autoar !== ExtensionMode.Disabled;
|
||||
} else if (this.active.sites['@global'].autoar === ExtensionMode.Whitelist) {
|
||||
this.logger.log('info', 'settings', "canStartAutoAr — can(not) start csar because extension is in whitelist mode, and this site is (not) equal to", ExtensionMode.Enabled)
|
||||
this.logger.log('info', ['settings', 'init', 'debug'], "canStartAutoAr — can(not) start aard because extension is in whitelist mode, and this site is (not) equal to", ExtensionMode.Enabled)
|
||||
return this.active.sites[site].autoar === ExtensionMode.Enabled;
|
||||
} else {
|
||||
this.logger.log('info', 'settings', "canStartAutoAr — cannot start csar because extension is globally disabled")
|
||||
this.logger.log('info', ['settings', 'init', 'debug'], "canStartAutoAr — cannot start aard because extension is globally disabled")
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -556,7 +563,7 @@ class Settings {
|
||||
}
|
||||
|
||||
getDefaultStretchMode(site) {
|
||||
if (site && this.active.sites[site]?.stretch !== Stretch.Default) {
|
||||
if (site && (this.active.sites[site]?.stretch ?? Stretch.Default) !== Stretch.Default) {
|
||||
return this.active.sites[site].stretch;
|
||||
}
|
||||
|
||||
@ -564,7 +571,7 @@ class Settings {
|
||||
}
|
||||
|
||||
getDefaultCropPersistenceMode(site) {
|
||||
if (site && this.active.sites[site]?.cropModePersistence !== Stretch.Default) {
|
||||
if (site && (this.active.sites[site]?.cropModePersistence ?? Stretch.Default) !== Stretch.Default) {
|
||||
return this.active.sites[site].cropModePersistence;
|
||||
}
|
||||
|
||||
@ -573,7 +580,7 @@ class Settings {
|
||||
}
|
||||
|
||||
getDefaultVideoAlignment(site) {
|
||||
if (this.active.sites[site]?.videoAlignment !== VideoAlignment.Default) {
|
||||
if ( (this.active.sites[site]?.videoAlignment ?? VideoAlignment.Default) !== VideoAlignment.Default) {
|
||||
return this.active.sites[site].videoAlignment;
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,12 @@ class ArDetector {
|
||||
}
|
||||
|
||||
start() {
|
||||
this.logger.log('info', 'debug', `"%c[ArDetect::start] <@${this.arid}> Starting automatic aspect ratio detection`, _ard_console_start);
|
||||
if (this.settings.canStartAutoAr()) {
|
||||
this.logger.log('info', 'debug', `"%c[ArDetect::start] <@${this.arid}> Starting automatic aspect ratio detection`, _ard_console_start);
|
||||
} else {
|
||||
this.logger.log('warn', 'debug', `"%c[ArDetect::start] <@${this.arid}> Wanted to start automatic aspect ratio detection, but settings don't allow that. Aard won't be started.`, _ard_console_change);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.conf.resizer.lastAr.type === AspectRatio.Automatic) {
|
||||
// ensure first autodetection will run in any case
|
||||
@ -713,7 +718,11 @@ class ArDetector {
|
||||
// the aspect ratio to defaults
|
||||
this.logger.log('error', 'arDetect', `%c[ArDetect::frameCheck] There was a problem setting blackbar. Doing nothing. Error:`, e);
|
||||
|
||||
this.guardline.reset();
|
||||
try {
|
||||
this.guardline.reset();
|
||||
} catch (e) {
|
||||
// no guardline, no bigge
|
||||
}
|
||||
// WE DO NOT RESET ASPECT RATIO HERE IN CASE OF PROBLEMS, CAUSES UNWARRANTED RESETS:
|
||||
// (eg. here: https://www.youtube.com/watch?v=nw5Z93Yt-UQ&t=410)
|
||||
//
|
||||
|
@ -19,7 +19,7 @@ class CommsClient {
|
||||
(history) => {
|
||||
this.logger.log('info', 'comms', 'Sending logging-stop-and-save to background script ...');
|
||||
try {
|
||||
this.port.postMessage({cmd: 'logging-stop-and-save', host: window.location.host, history})
|
||||
this.port.postMessage({cmd: 'logging-stop-and-save', host: window.location.hostname, history})
|
||||
} catch (e) {
|
||||
this.logger.log('error', 'comms', 'Failed to send message to background script. Error:', e);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ class PageInfo {
|
||||
|
||||
try {
|
||||
// request inject css immediately
|
||||
const playerStyleString = this.settings.active.sites[window.location.host].css.replace('\\n', '');
|
||||
const playerStyleString = this.settings.active.sites[window.location.hostname].css.replace('\\n', '');
|
||||
this.comms.sendMessage({
|
||||
cmd: 'inject-css',
|
||||
cssString: playerStyleString
|
||||
@ -39,11 +39,11 @@ class PageInfo {
|
||||
}
|
||||
|
||||
// try getting default crop immediately.
|
||||
// const cropModePersistence = this.settings.getDefaultCropPersistenceMode(window.location.host);
|
||||
// const cropModePersistence = this.settings.getDefaultCropPersistenceMode(window.location.hostname);
|
||||
|
||||
// try {
|
||||
// if (cropModePersistence === CropModePersistence.Forever) {
|
||||
// this.defaultCrop = this.settings.active.sites[window.location.host].defaultCrop;
|
||||
// this.defaultCrop = this.settings.active.sites[window.location.hostname].defaultCrop;
|
||||
// } else if (cropModePersistence === CropModePersistence.CurrentSession) {
|
||||
// this.defaultCrop = JSON.parse(sessionStorage.getItem('uw-crop-mode-session-persistence'));
|
||||
// }
|
||||
@ -95,7 +95,7 @@ class PageInfo {
|
||||
}
|
||||
|
||||
try {
|
||||
playerStyleString = this.settings.active.sites[window.location.host].css;
|
||||
playerStyleString = this.settings.active.sites[window.location.hostname].css;
|
||||
if (playerStyleString) {
|
||||
this.comms.sendMessage({
|
||||
cmd: 'eject-css',
|
||||
@ -150,7 +150,7 @@ class PageInfo {
|
||||
const oldVideoCount = this.videos.length;
|
||||
|
||||
try{
|
||||
var vids = this.getVideos(window.location.host);
|
||||
var vids = this.getVideos(window.location.hostname);
|
||||
|
||||
if(!vids || vids.length == 0){
|
||||
this.hasVideos = false;
|
||||
@ -209,17 +209,6 @@ class PageInfo {
|
||||
|
||||
try {
|
||||
v = new VideoData(video, this.settings, this);
|
||||
|
||||
if (!this.defaultCrop) {
|
||||
if (!v.invalid) {
|
||||
v.initArDetection();
|
||||
} else {
|
||||
this.logger.log('error', 'debug', 'Video is invalid. Aard not started.', video);
|
||||
}
|
||||
} else {
|
||||
this.logger.log('info', 'debug', 'Default crop is specified for this site. Not starting aard.');
|
||||
}
|
||||
|
||||
this.videos.push(v);
|
||||
} catch (e) {
|
||||
this.logger.log('error', 'debug', "rescan error: failed to initialize videoData. Skipping this video.",e);
|
||||
@ -256,9 +245,9 @@ class PageInfo {
|
||||
// }
|
||||
|
||||
if (this.videos.length > 0) {
|
||||
this.comms.registerVideo({host: window.location.host, location: window.location});
|
||||
this.comms.registerVideo({host: window.location.hostname, location: window.location});
|
||||
} else {
|
||||
this.comms.unregisterVideo({host: window.location.host, location: window.location});
|
||||
this.comms.unregisterVideo({host: window.location.hostname, location: window.location});
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,12 +582,12 @@ class PageInfo {
|
||||
if (persistenceMode === CropModePersistence.CurrentSession) {
|
||||
sessionStorage.setItem('uw-crop-mode-session-persistence', JSON.stringify(this.currentCrop));
|
||||
} else if (persistenceMode === CropModePersistence.Forever) {
|
||||
if (this.settings.active.sites[window.location.host]) {
|
||||
if (this.settings.active.sites[window.location.hostname]) {
|
||||
// | key may be missing, so we do this
|
||||
this.settings.active.sites[window.location.host]['defaultAr'] = this.currentCrop;
|
||||
this.settings.active.sites[window.location.hostname]['defaultAr'] = this.currentCrop;
|
||||
} else {
|
||||
this.settings.active.sites[window.location.host] = this.settings.getDefaultOption();
|
||||
this.settings.active.sites[window.location.host]['defaultAr'] = this.currentCrop;
|
||||
this.settings.active.sites[window.location.hostname] = this.settings.getDefaultOption();
|
||||
this.settings.active.sites[window.location.hostname]['defaultAr'] = this.currentCrop;
|
||||
}
|
||||
|
||||
this.settings.saveWithoutReload();
|
||||
@ -610,7 +599,7 @@ class PageInfo {
|
||||
// This means crop persistance is disabled. If crop persistance is enabled, then settings for current
|
||||
// site MUST exist (crop persistence mode is disabled by default)
|
||||
|
||||
const cropModePersistence = this.settings.getDefaultCropPersistenceMode(window.location.host);
|
||||
const cropModePersistence = this.settings.getDefaultCropPersistenceMode(window.location.hostname);
|
||||
|
||||
if (cropModePersistence === CropModePersistence.Disabled) {
|
||||
return;
|
||||
@ -621,12 +610,12 @@ class PageInfo {
|
||||
if (cropModePersistence === CropModePersistence.CurrentSession) {
|
||||
sessionStorage.setItem('uw-crop-mode-session-persistence', JSON.stringify(ar));
|
||||
} else if (cropModePersistence === CropModePersistence.Forever) {
|
||||
if (this.settings.active.sites[window.location.host]) {
|
||||
if (this.settings.active.sites[window.location.hostname]) {
|
||||
// | key may be missing, so we do this
|
||||
this.settings.active.sites[window.location.host]['defaultAr'] = ar;
|
||||
this.settings.active.sites[window.location.hostname]['defaultAr'] = ar;
|
||||
} else {
|
||||
this.settings.active.sites[window.location.host] = this.settings.getDefaultOption();
|
||||
this.settings.active.sites[window.location.host]['defaultAr'] = ar;
|
||||
this.settings.active.sites[window.location.hostname] = this.settings.getDefaultOption();
|
||||
this.settings.active.sites[window.location.hostname]['defaultAr'] = ar;
|
||||
}
|
||||
|
||||
this.settings.saveWithoutReload();
|
||||
|
@ -47,7 +47,7 @@ class PlayerData {
|
||||
|
||||
this.periodicallyRefreshPlayerElement = false;
|
||||
try {
|
||||
this.periodicallyRefreshPlayerElement = this.settings.active.sites[window.location.host].DOM.player.periodicallyRefreshPlayerElement;
|
||||
this.periodicallyRefreshPlayerElement = this.settings.active.sites[window.location.hostname].DOM.player.periodicallyRefreshPlayerElement;
|
||||
} catch (e) {
|
||||
// no biggie — that means we don't have any special settings for this site.
|
||||
}
|
||||
@ -226,7 +226,7 @@ class PlayerData {
|
||||
}
|
||||
|
||||
getPlayer() {
|
||||
const host = window.location.host;
|
||||
const host = window.location.hostname;
|
||||
let element = this.video.parentNode;
|
||||
const videoWidth = this.video.offsetWidth;
|
||||
const videoHeight = this.video.offsetHeight;
|
||||
|
@ -15,20 +15,61 @@ class VideoData {
|
||||
this.settings = settings;
|
||||
this.pageInfo = pageInfo;
|
||||
this.extensionMode = pageInfo.extensionMode;
|
||||
this.videoStatusOk = false;
|
||||
|
||||
this.userCssClassName = `uw-fuck-you-and-do-what-i-tell-you_${this.vdid}`;
|
||||
|
||||
// We only init observers once player is confirmed valid
|
||||
this.videoLoaded = false;
|
||||
this.videoDimensionsLoaded = true;
|
||||
|
||||
this.dimensions = {
|
||||
width: this.video.offsetWidth,
|
||||
height: this.video.offsetHeight,
|
||||
};
|
||||
|
||||
// this is in case extension loads before the video
|
||||
video.addEventListener('loadeddata', () => {
|
||||
this.logger.log('info', 'init', '[VideoData::ctor->video.onloadeddata] Video fired event "loaded data!"');
|
||||
this.onVideoLoaded();
|
||||
});
|
||||
|
||||
// this one is in case extension loads after the video is loaded
|
||||
video.addEventListener('timeupdate', () => {
|
||||
this.onVideoLoaded();
|
||||
});
|
||||
}
|
||||
|
||||
async onVideoLoaded() {
|
||||
if (!this.videoLoaded) {
|
||||
this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— Initiating phase two of videoData setup ———————————', 'color: #0f9');
|
||||
|
||||
this.videoLoaded = true;
|
||||
this.videoDimensionsLoaded = true;
|
||||
try {
|
||||
await this.setupStageTwo();
|
||||
this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— videoData setup stage two complete ———————————', 'color: #0f9');
|
||||
} catch (e) {
|
||||
this.logger.log('error', 'init', '%c[VideoData::onVideoLoaded] ——————————— Setup stage two failed. ———————————\n', 'color: #f00', e);
|
||||
}
|
||||
} else if (!this.videoDimensionsLoaded) {
|
||||
this.logger.log('info', 'debug', "%c[VideoData::restoreCrop] Recovering from illegal video dimensions. Resetting aspect ratio.", "background: #afd, color: #132");
|
||||
|
||||
this.restoreCrop();
|
||||
this.videoDimensionsLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
async setupStageTwo() {
|
||||
// POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji)
|
||||
// NOTE: ORDERING OF OBJ INITIALIZATIONS IS IMPORTANT (arDetect needs to go last)
|
||||
|
||||
// NOTE: We only init observers once player is confirmed valid
|
||||
const observerConf = {
|
||||
attributes: true,
|
||||
// attributeFilter: ['style', 'class'],
|
||||
attributeOldValue: true,
|
||||
};
|
||||
|
||||
|
||||
|
||||
// POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji)
|
||||
// NOTE: ORDERING OF OBJ INITIALIZATIONS IS IMPORTANT (arDetect needs to go last)
|
||||
this.player = new PlayerData(this);
|
||||
if (this.player.invalid) {
|
||||
this.invalid = true;
|
||||
@ -37,22 +78,20 @@ class VideoData {
|
||||
|
||||
this.resizer = new Resizer(this);
|
||||
|
||||
const ths = this;
|
||||
this.observer = new MutationObserver( (m, o) => this.onVideoDimensionsChanged(m, o, ths));
|
||||
this.observer.observe(video, observerConf);
|
||||
|
||||
this.dimensions = {
|
||||
width: this.video.offsetWidth,
|
||||
height: this.video.offsetHeight,
|
||||
};
|
||||
|
||||
// INIT OBSERVERS
|
||||
this.observer = new MutationObserver( (m, o) => {
|
||||
this.logger.log('info', 'debug', `[VideoData::setupStageTwo->mutationObserver] Mutation observer detected a mutation:`, {m, o});
|
||||
this.onVideoDimensionsChanged(m, o, this)
|
||||
});
|
||||
this.observer.observe(this.video, observerConf);
|
||||
|
||||
// INIT AARD
|
||||
this.arDetector = new ArDetector(this); // this starts Ar detection. needs optional parameter that prevets ardetdctor from starting
|
||||
// player dimensions need to be in:
|
||||
// this.player.dimensions
|
||||
|
||||
// apply default align and stretch
|
||||
this.logger.log('info', 'debug', "%c[VideoData::ctor] Initial resizer reset!", {background: '#afd', color: '#132'});
|
||||
this.logger.log('info', 'debug', "%c[VideoData::ctor] Initial resizer reset!", "background: #afd, color: #132");
|
||||
this.resizer.reset();
|
||||
|
||||
this.logger.log('info', ['debug', 'init'], '[VideoData::ctor] Created videoData with vdid', this.vdid, '\nextension mode:', this.extensionMode)
|
||||
@ -63,10 +102,41 @@ class VideoData {
|
||||
// start fallback video/player size detection
|
||||
this.fallbackChangeDetection();
|
||||
|
||||
// force reload last aspect ratio (if default crop ratio exists)
|
||||
// force reload last aspect ratio (if default crop ratio exists), but only after the video is
|
||||
if (this.pageInfo.defaultCrop) {
|
||||
this.resizer.setAr(this.pageInfo.defaultCrop);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!this.pageInfo.defaultCrop) {
|
||||
if (!this.invalid) {
|
||||
this.initArDetection();
|
||||
} else {
|
||||
this.logger.log('error', 'debug', '[VideoData::secondStageSetup] Video is invalid. Aard not started.', this.video);
|
||||
}
|
||||
} else {
|
||||
this.logger.log('info', 'debug', '[VideoData::secondStageSetup] Default crop is specified for this site. Not starting aard.');
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.log('error', 'init', `[VideoData::secondStageSetup] Error with aard initialization (or error with default aspect ratio application)`, e)
|
||||
}
|
||||
}
|
||||
|
||||
restoreCrop() {
|
||||
this.logger.log('info', 'debug', '[VideoData::restoreCrop] Attempting to reset/restore aspect ratio.')
|
||||
// if we have default crop set for this page, apply this.
|
||||
// otherwise, reset crop
|
||||
if (this.pageInfo.defaultCrop) {
|
||||
this.resizer.setAr(this.pageInfo.defaultCrop);
|
||||
} else {
|
||||
this.resizer.reset();
|
||||
|
||||
try {
|
||||
this.startArDetection();
|
||||
} catch (e) {
|
||||
this.logger.log('warn', 'debug', '[VideoData::restoreCrop] Autodetection not resumed. Reason:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fallbackChangeDetection() {
|
||||
@ -81,7 +151,7 @@ class VideoData {
|
||||
}
|
||||
|
||||
async sleep(timeout) {
|
||||
return new Promise( (resolve, reject) => setTimeout(() => resolve(), timeout));
|
||||
return new Promise( (resolve) => setTimeout(() => resolve(), timeout));
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,7 +151,7 @@ class Resizer {
|
||||
return;
|
||||
}
|
||||
|
||||
const siteSettings = this.settings.active.sites[window.location.host];
|
||||
const siteSettings = this.settings.active.sites[window.location.hostname];
|
||||
|
||||
// reset zoom, but only on aspect ratio switch. We also know that aspect ratio gets converted to
|
||||
// AspectRatio.Fixed when zooming, so let's keep that in mind
|
||||
@ -267,28 +267,13 @@ class Resizer {
|
||||
return;
|
||||
}
|
||||
|
||||
// we could have issued calculate crop too early. Instead of spending 30 minutes trying to fix this the proper way by
|
||||
// reading documentation, let's fix it in 30 seconds with some brute force code
|
||||
// we could have issued calculate crop too early. Let's tell VideoData that there's something wrong
|
||||
// and exit this function. When <video> will receive onloadeddata or ontimeupdate (receiving either
|
||||
// of the two means video is loaded or playing, and that means video has proper dimensions), it will
|
||||
// try to reset or re-apply aspect ratio when the video is finally ready.
|
||||
if (stretchFactors?.error === 'illegal_video_dimensions') {
|
||||
let timeout = 10; // ms
|
||||
let iteration = 0;
|
||||
let maxIterations = 15;
|
||||
do {
|
||||
if (iteration > maxIterations) {
|
||||
this.logger.log('error', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> Video dimensions remain illegal after ${maxIterations} retries`);
|
||||
return;
|
||||
}
|
||||
// fire first few rechecks in quick succession, but start increasing timeout
|
||||
// later down the line.
|
||||
if (iteration > 0 && iteration % 0 == 0) {
|
||||
timeout = Math.min(2 * timeout, 1000);
|
||||
}
|
||||
this.logger.log('info', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> Sleeping for ${timeout} ms`);
|
||||
await sleep(timeout);
|
||||
stretchFactors = this.scaler.calculateCrop(ar);
|
||||
iteration++;
|
||||
} while (stretchFactors.error === 'illegal_video_dimensions');
|
||||
this.logger.log('info', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> Video dimensions have corrected themselves after retrying.`);
|
||||
this.conf.videoDimensionsLoaded = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,7 +354,7 @@ class Resizer {
|
||||
|
||||
resetPan() {
|
||||
this.pan = {};
|
||||
this.videoAlignment = this.settings.getDefaultVideoAlignment(window.location.host);
|
||||
this.videoAlignment = this.settings.getDefaultVideoAlignment(window.location.hostname);
|
||||
}
|
||||
|
||||
setPan(relativeMousePosX, relativeMousePosY){
|
||||
@ -503,6 +488,26 @@ class Resizer {
|
||||
'\nwdiff, hdiffAfterZoom:', wdiffAfterZoom, 'x', hdiffAfterZoom,
|
||||
'\n\n---- data out ----\n',
|
||||
'translate:', translate);
|
||||
|
||||
// by the way, let's do a quick sanity check whether video player is doing any fuckies wuckies
|
||||
// fucky wucky examples:
|
||||
//
|
||||
// * video width is bigger than player width AND video height is bigger than player height
|
||||
// * video width is smaller than player width AND video height is smaller than player height
|
||||
//
|
||||
// In both examples, at most one of the two conditions can be true at the same time. If both
|
||||
// conditions are true at the same time, we need to go 'chiny reckon' and recheck our player
|
||||
// element. Chances are our video is not getting aligned correctly
|
||||
if (
|
||||
(this.conf.video.offsetWidth > this.conf.player.dimensions.width && this.conf.video.offsetHeight > this.conf.player.dimensions.height) ||
|
||||
(this.conf.video.offsetWidth < this.conf.player.dimensions.width && this.conf.video.offsetHeight < this.conf.player.dimensions.height)
|
||||
) {
|
||||
this.logger.log('warn', ['debugger', 'resizer'], `[Resizer::_res_computeOffsets] <rid:${this.resizerId}> We are getting some incredibly funny results here.\n\n`,
|
||||
`Video seems to be both wider and taller (or shorter and narrower) than player element at the same time. This is super duper not supposed to happen.\n\n`,
|
||||
`Player element needs to be checked.`
|
||||
)
|
||||
this.player.checkPlayerSizeChange();
|
||||
}
|
||||
return translate;
|
||||
}
|
||||
|
||||
@ -580,7 +585,7 @@ class Resizer {
|
||||
|
||||
let extraStyleString;
|
||||
try {
|
||||
extraStyleString = this.settings.active.sites[window.location.host].DOM.video.additionalCss;
|
||||
extraStyleString = this.settings.active.sites[window.location.hostname].DOM.video.additionalCss;
|
||||
} catch (e) {
|
||||
// do nothing. It's ok if no special settings are defined for this site, we'll just do defaults
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"manifest_version": 2,
|
||||
"name": "Ultrawidify",
|
||||
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
|
||||
"version": "4.4.8",
|
||||
"version": "4.4.9",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
|
||||
|
@ -48,7 +48,7 @@ class ExecAction {
|
||||
if (scope === 'global') {
|
||||
site = '@global';
|
||||
} else if (!this.site) {
|
||||
site = window.location.host;
|
||||
site = window.location.hostname;
|
||||
}
|
||||
|
||||
if (scope === 'site' && !this.settings.active.sites[site]) {
|
||||
|
@ -2,17 +2,13 @@
|
||||
<div>
|
||||
<h2>What's new</h2>
|
||||
<p>Full changelog for older versions <a href="https://github.com/tamius-han/ultrawidify/blob/master/CHANGELOG.md">is available here</a>.</p>
|
||||
<p class="label">4.4.8</p>
|
||||
<p class="label">4.4.9</p>
|
||||
<ul>
|
||||
<li>
|
||||
Fixed the bug where on pages with more than one video, the list of available videos in the extension popup
|
||||
wouldn't remove videos that are no longer displayed on site. This resulted in extension listing videos that
|
||||
were no longer on the page. Reboot or navigation would also not clear the list if navigating between various
|
||||
pages on the same host.
|
||||
Fixed issue with video alignment on youtube under certain conditions (previously fixed in v4.4.7.1-2), but this time for real (hopefully).
|
||||
</li>
|
||||
<li>
|
||||
Fixed the chrome-only bug where on sites with more than one video, the number wouldn't get hidden when the
|
||||
extension popup closed.
|
||||
Fixed the bug where extension wouldn't work when URL specified a port (e.g. www.example.com:80)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user