Merge branch 'master' into feature/player-ui
This commit is contained in:
commit
56dcd0feb3
8
.vscode/extensions.json
vendored
Normal file
8
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"hollowtree.vue-pack",
|
||||
"msjsdiag.debugger-for-chrome",
|
||||
"firefox-devtools.vscode-firefox-debug",
|
||||
"msjsdiag.debugger-for-edge"
|
||||
]
|
||||
}
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -17,6 +17,8 @@
|
||||
"decycle",
|
||||
"disneyplus",
|
||||
"equalish",
|
||||
"fith",
|
||||
"fitw",
|
||||
"fuckup",
|
||||
"gfycat",
|
||||
"gmail",
|
||||
@ -28,6 +30,7 @@
|
||||
"letterboxed",
|
||||
"manjaro",
|
||||
"minification",
|
||||
"mitigations",
|
||||
"nogrow",
|
||||
"noshrink",
|
||||
"outro",
|
||||
|
19
CHANGELOG.md
19
CHANGELOG.md
@ -18,9 +18,24 @@
|
||||
|
||||
## v5.x (current major)
|
||||
|
||||
### v5.0.4
|
||||
* Attempt to fix disney+ again, courtesy of [@jwannebo](https://github.com/tamius-han/ultrawidify/issues/84#issuecomment-846334005) on github.
|
||||
|
||||
|
||||
### v5.0.3
|
||||
|
||||
* Fixed the issue where the videos were sometimes offset up and left. Again.
|
||||
* Fix the issue where correcting source stretch was squished incorrectly ([#153](https://github.com/tamius-han/ultrawidify/issues/153))
|
||||
|
||||
### v5.0.2
|
||||
|
||||
* When in full screen, the extension will assume player element dimensions are the same as the screen resolution. This should help with sites where ultrawidify doesn't correctly identify the player, as cropping generally doesn't work if player element is not identified. Old behaviour can be restored in advanced extension settings by toggling the "use player aspect ratio in fullscreen" checkbox under 'player detection settings'.
|
||||
* Extension should now respect 'disable extension' option for real.
|
||||
* Fixed the issue where player wouldn't get detected if video was wider than the player.
|
||||
|
||||
|
||||
### v5.0.1
|
||||
* Turned off zoom limitations for Edge and Chrome.
|
||||
* Added an option for users to manually re-enable (and configure) Chrome/Edge's zoom limiter.
|
||||
* Added an option for users to turn off (and/or configure) Chrome/Edge's zoom limiter.
|
||||
|
||||
### v5.0.0
|
||||
|
||||
|
12
README.md
12
README.md
@ -2,9 +2,7 @@
|
||||
|
||||
## Super TL;DR: I'm just looking for the install links, thanks
|
||||
|
||||
[Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/), [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi).
|
||||
|
||||
**Microsoft Edge is not supported at this time, as Edge features some bugs that make it impossible for extension to work.** [Read more](https://github.com/tamius-han/ultrawidify/issues/117#issuecomment-747109695).
|
||||
[Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/), [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi), [Edge](https://microsoftedge.microsoft.com/addons/detail/ultrawidify/lmpgpgechmkkkehkihpiddbcbgibokbi).
|
||||
|
||||
There's also [nightly "builds"](https://stuff.lionsarch.tamius.net/ultrawidify/nightly/).
|
||||
|
||||
@ -51,13 +49,13 @@ If extension doesn't work for a site I'm not testing on out of the box, follow [
|
||||
|
||||
### Installing this extension
|
||||
|
||||
You can download this extension from Firefox' and Chrome's extension stores:
|
||||
You can download this extension from the relevant extension stores:
|
||||
|
||||
* [Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/)
|
||||
* [Chrome, Opera](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi)
|
||||
* [Chromium Edge](https://microsoftedge.microsoft.com/addons/detail/lmpgpgechmkkkehkihpiddbcbgibokbi)
|
||||
* [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi)
|
||||
* [Edge](https://microsoftedge.microsoft.com/addons/detail/ultrawidify/lmpgpgechmkkkehkihpiddbcbgibokbi)
|
||||
|
||||
Users of beta and developer branches of Opera can find Ultrawidify on Opera store as well, but given Opera's review process is unacceptably slow (awaiting moderator review since 2020-03-15) not only am I not going to maintain Opera store presence, Opera users are advised to use Chrome version of the extension in order to avoid waiting years for new features to be approved by Opera moderators.
|
||||
Other browsers are not officially supported. If you're using a different Chromium-based browser, you can try installing the addon from the Chrome Web Store — but if things don't work, you're on your own.
|
||||
|
||||
### Nightly builds
|
||||
|
||||
|
22226
package-lock.json
generated
22226
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "ultrawidify",
|
||||
"version": "5.0.1",
|
||||
"version": "5.0.4",
|
||||
"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": {
|
||||
"build": "npm run pre-build; cross-env NODE_ENV=production BROWSER=firefox CHANNEL=stable webpack --hide-modules",
|
||||
"build-all": "mkdir -p ./build/old; npm run pre-build; rm ./dist-zip/uw-amo-source.zip; mv -f ./dist-zip/*.zip ./build/old; npm run build; node scripts/build-zip.js ff; npm run build-chrome; node scripts/build-zip.js chrome; npm run build-edge; node scripts/build-zip.js edge; ./scripts/prepare-amo-source.sh",
|
||||
"build-all": "bash ./scripts/build-all.sh",
|
||||
"build-chrome": "cross-env NODE_ENV=production BROWSER=chrome CHANNEL=stable webpack --hide-modules",
|
||||
"build-chrome:dev": "cross-env NODE_ENV=development BROWSER=chrome webpack --hide-modules",
|
||||
"build-edge": "cross-env NODE_ENV=production BROWSER=edge CHANNEL=stable webpack --hide-modules",
|
||||
@ -15,7 +15,7 @@
|
||||
"build-testing-chrome": "cross-env NODE_ENV=development BROWSER=chrome CHANNEL=testing webpack --hide-modules",
|
||||
"build-zip": "node scripts/build-zip.js",
|
||||
"build:dev": "webpack --hide-modules",
|
||||
"dev": "cross-env NODE_ENV=development CHANNEL=dev concurrently \"cross-env BROWSER=firefox npm run build:dev -- --watch\" \"cross-env BROWSER=chrome npm run build:dev -- --watch\"",
|
||||
"dev": "cross-env NODE_ENV=development CHANNEL=dev concurrently \"cross-env BROWSER=firefox npm run build:dev -- --watch\" \"cross-env BROWSER=chrome npm run build:dev -- --watch\" \"cross-env BROWSER=edge npm run build:dev -- --watch\"",
|
||||
"pre-build": "rm -rf ./dist-ff; rm -rf ./dist-chrome; rm -rf ./node_modules; npm ci",
|
||||
"start": "npm run dev"
|
||||
},
|
||||
@ -25,7 +25,6 @@
|
||||
"@types/core-js": "^2.5.3",
|
||||
"@types/es6-promise": "^3.3.0",
|
||||
"@types/firefox": "0.0.30",
|
||||
"@types/node": "^14.14.25",
|
||||
"@types/resize-observer-browser": "^0.1.5",
|
||||
"@vue/cli": "^4.5.9",
|
||||
"@vue/cli-plugin-typescript": "^4.5.11",
|
||||
@ -36,7 +35,7 @@
|
||||
"concurrently": "^5.2.0",
|
||||
"fs-extra": "^7.0.1",
|
||||
"json-cyclic": "0.0.3",
|
||||
"lodash": "^4.17.20",
|
||||
"lodash": "^4.17.21",
|
||||
"typescript": "^4.2.3",
|
||||
"vue": "^3.0.0-beta.1",
|
||||
"vuex": "^4.0.0-alpha.1",
|
||||
@ -48,6 +47,7 @@
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
|
||||
"@babel/preset-env": "^7.12.13",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/node": "^14.14.25",
|
||||
"@vue/compiler-sfc": "^3.0.3",
|
||||
"archiver": "^3.0.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
|
42
scripts/build-all.sh
Normal file
42
scripts/build-all.sh
Normal file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NOTE: this script needs to be run with the npm run build-all
|
||||
# command from the root directory of the project. Running it in
|
||||
# any other way probably isn't going to work.
|
||||
|
||||
# pre-build steps:
|
||||
mkdir -p ./build/old
|
||||
npm run pre-build
|
||||
rm ./dist-zip/uw-amo-source.zip
|
||||
mv -f ./dist-zip/*.zip ./build/old
|
||||
|
||||
# lets force raise ram limit, but the improper way
|
||||
# export NODE_OPTIONS=--max_old_space_size=4096
|
||||
|
||||
# build the version for each browser and create a zip afterwards
|
||||
# step 1: define build functions
|
||||
#function buildFF {
|
||||
npm run build
|
||||
node scripts/build-zip.js ff
|
||||
#}
|
||||
#function buildChrome {
|
||||
npm run build-chrome
|
||||
node scripts/build-zip.js chrome
|
||||
#}
|
||||
#function buildEdge {
|
||||
npm run build-edge
|
||||
node scripts/build-zip.js edge
|
||||
#}
|
||||
|
||||
# step 2: execute them all at once
|
||||
# buildFF &
|
||||
# buildChrome &
|
||||
# buildEdge &
|
||||
|
||||
# wait < <(jobs -p)
|
||||
|
||||
# prepare AMO source
|
||||
# source code needs to be prepared AFTER
|
||||
# the code has been built, to ensure that
|
||||
# package-lock.json remains unchanged
|
||||
./scripts/prepare-amo-source.sh
|
@ -37,6 +37,9 @@ if [ ! -z "$GIT_COMMIT" ] ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# let's raise RAM limit for npm command globally
|
||||
NODE_OPTIONS=--max_old_space_size=4096
|
||||
|
||||
npm ci
|
||||
|
||||
rm -rf ./dist-zip || true # no big deal if ./dist-zip doesn't exist
|
||||
@ -46,7 +49,7 @@ mkdir dist-zip # create it back
|
||||
# build firefox
|
||||
#
|
||||
npm run "${BUILD_SCRIPT}"
|
||||
node scripts/build-zip.js ff nightly
|
||||
node --max-old-space-size=2048 scripts/build-zip.js ff nightly
|
||||
# if [ ! -z "${AMO_API_KEY}" ] ; then
|
||||
# if [ ! -z "${AMO_API_SECRET}" ] ; then
|
||||
# web-ext sign --source-dir ./dist --api-key "${AMO_API_KEY}" --api-secret "${AMO_API_SECRET}"
|
||||
@ -57,12 +60,18 @@ node scripts/build-zip.js ff nightly
|
||||
# build chrome
|
||||
#
|
||||
npm run "${BUILD_SCRIPT}-chrome"
|
||||
node scripts/build-zip.js chrome nightly
|
||||
|
||||
node --max-old-space-size=2048 scripts/build-zip.js chrome nightly
|
||||
#
|
||||
#./scripts/build-crx.sh
|
||||
#
|
||||
|
||||
#
|
||||
# build edge
|
||||
#
|
||||
npm run "${BUILD_SCRIPT}-edge"
|
||||
node --max-old-space-size=2048 scripts/build-zip.js chrome nightly
|
||||
|
||||
|
||||
######################################
|
||||
# UPLOAD TO WEB SERVER
|
||||
######################################
|
||||
@ -76,7 +85,6 @@ echo "Uploading to server ..."
|
||||
scp -i ~/.ssh/id_rsa -r ./dist-zip/* "ultrawidify-uploader@${RELEASE_SERVER}:${RELEASE_DIRECTORY}${BUILD_CHANNEL_DIRECTORY}"
|
||||
|
||||
|
||||
|
||||
######################################
|
||||
# Build finished message
|
||||
######################################
|
||||
|
@ -189,7 +189,7 @@ interface SettingsInterface {
|
||||
mitigations?: {
|
||||
zoomLimit?: {
|
||||
enabled?: boolean,
|
||||
fullscreenOnly: boolean,
|
||||
fullscreenOnly?: boolean,
|
||||
limit?: number,
|
||||
}
|
||||
}
|
||||
@ -285,6 +285,7 @@ interface SettingsInterface {
|
||||
}
|
||||
},
|
||||
css?: string;
|
||||
usePlayerArInFullscreen?: boolean;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,87 +48,96 @@ export default class UWContent {
|
||||
}
|
||||
|
||||
reloadSettings() {
|
||||
this.logger.log('info', 'debug', 'Things happened in the popup. Will reload extension settings.');
|
||||
this.init();
|
||||
try {
|
||||
this.logger.log('info', 'debug', 'Things happened in the popup. Will reload extension settings.');
|
||||
this.init();
|
||||
} catch (e) {
|
||||
console.warn('Ultrawidify: settings reload failed. This probably shouldn\'t outright kill the extension, but page reload is recommended.');
|
||||
}
|
||||
}
|
||||
|
||||
async init(){
|
||||
if (Debug.debug) {
|
||||
console.log("[uw::main] loading configuration ...");
|
||||
}
|
||||
|
||||
// logger init is the first thing that needs to run
|
||||
try {
|
||||
if (!this.logger) {
|
||||
|
||||
this.logger = new Logger();
|
||||
await this.logger.init(baseLoggingOptions);
|
||||
if (Debug.debug) {
|
||||
console.log("[uw::main] loading configuration ...");
|
||||
}
|
||||
|
||||
// logger init is the first thing that needs to run
|
||||
try {
|
||||
if (!this.logger) {
|
||||
|
||||
this.logger = new Logger();
|
||||
await this.logger.init(baseLoggingOptions);
|
||||
|
||||
// show popup if logging to file is enabled
|
||||
if (this.logger.isLoggingAllowed() && this.logger.isLoggingToFile()) {
|
||||
console.info("[uw::init] Logging is allowed! Initalizing vue and UI!");
|
||||
// show popup if logging to file is enabled
|
||||
if (this.logger.isLoggingAllowed() && this.logger.isLoggingToFile()) {
|
||||
console.info("[uw::init] Logging is allowed! Initalizing vue and UI!");
|
||||
|
||||
// CommsClient is not initiated yet, so we use static comms to send the command
|
||||
Comms.sendMessage({cmd: 'show-logger'});
|
||||
// CommsClient is not initiated yet, so we use static comms to send the command
|
||||
Comms.sendMessage({cmd: 'show-logger'});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("logger init failed!", e)
|
||||
}
|
||||
|
||||
// init() is re-run any time settings change
|
||||
if (this.comms) {
|
||||
this.comms.destroy();
|
||||
}
|
||||
if (!this.settings) {
|
||||
this.settings = new Settings({
|
||||
onSettingsChanged: () => this.reloadSettings(),
|
||||
logger: this.logger
|
||||
});
|
||||
await this.settings.init();
|
||||
}
|
||||
|
||||
this.comms = new CommsClient('content-main-port', this.logger, this.commsHandlers);
|
||||
|
||||
// če smo razširitev onemogočili v nastavitvah, ne naredimo ničesar
|
||||
// If extension is soft-disabled, don't do shit
|
||||
|
||||
var extensionMode = this.settings.getExtensionMode();
|
||||
|
||||
this.logger.log('info', 'debug', "[uw::init] Extension mode:" + (extensionMode < 0 ? "disabled" : extensionMode == '1' ? 'basic' : 'full'));
|
||||
|
||||
const isSiteDisabled = extensionMode === ExtensionMode.Disabled
|
||||
|
||||
if (isSiteDisabled) {
|
||||
if (this.settings.getExtensionMode('@global') === ExtensionMode.Disabled) {
|
||||
this.logger.log('info', 'debug', "[uw::init] EXTENSION DISABLED, THEREFORE WONT BE STARTED")
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("logger init failed!", e)
|
||||
}
|
||||
|
||||
// init() is re-run any time settings change
|
||||
if (this.comms) {
|
||||
this.comms.destroy();
|
||||
}
|
||||
if (!this.settings) {
|
||||
this.settings = new Settings({
|
||||
onSettingsChanged: () => this.reloadSettings(),
|
||||
logger: this.logger
|
||||
});
|
||||
await this.settings.init();
|
||||
}
|
||||
|
||||
this.comms = new CommsClient('content-main-port', this.logger, this.commsHandlers);
|
||||
|
||||
// če smo razširitev onemogočili v nastavitvah, ne naredimo ničesar
|
||||
// If extension is soft-disabled, don't do shit
|
||||
|
||||
var extensionMode = this.settings.getExtensionMode();
|
||||
|
||||
this.logger.log('info', 'debug', "[uw::init] Extension mode:" + (extensionMode < 0 ? "disabled" : extensionMode == '1' ? 'basic' : 'full'));
|
||||
|
||||
const isSiteDisabled = extensionMode === ExtensionMode.Disabled
|
||||
|
||||
if (isSiteDisabled) {
|
||||
if (this.settings.getExtensionMode('@global') === ExtensionMode.Disabled) {
|
||||
this.logger.log('info', 'debug', "[uw::init] EXTENSION DISABLED, THEREFORE WONT BE STARTED")
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.pageInfo) {
|
||||
this.logger.log('info', 'debug', '[uw.js::setup] An instance of pageInfo already exists and will be destroyed.');
|
||||
this.pageInfo.destroy();
|
||||
}
|
||||
this.pageInfo = new PageInfo(this.comms, this.settings, this.logger, extensionMode, isSiteDisabled);
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized.");
|
||||
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] will try to initate ActionHandler.");
|
||||
|
||||
// start action handler only if extension is enabled for this site
|
||||
if (!isSiteDisabled) {
|
||||
if (this.actionHandler) {
|
||||
this.actionHandler.destroy();
|
||||
|
||||
try {
|
||||
if (this.pageInfo) {
|
||||
this.logger.log('info', 'debug', '[uw.js::setup] An instance of pageInfo already exists and will be destroyed.');
|
||||
this.pageInfo.destroy();
|
||||
}
|
||||
this.actionHandler = new ActionHandler(this.pageInfo);
|
||||
this.actionHandler.init();
|
||||
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] ActionHandler initiated.");
|
||||
}
|
||||
this.pageInfo = new PageInfo(this.comms, this.settings, this.logger, extensionMode, isSiteDisabled);
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized.");
|
||||
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] will try to initate ActionHandler.");
|
||||
|
||||
// start action handler only if extension is enabled for this site
|
||||
if (!isSiteDisabled) {
|
||||
if (this.actionHandler) {
|
||||
this.actionHandler.destroy();
|
||||
}
|
||||
this.actionHandler = new ActionHandler(this.pageInfo);
|
||||
this.actionHandler.init();
|
||||
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] ActionHandler initiated.");
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error('Ultrawidify: failed to start extension. Error:', e)
|
||||
this.logger.log('error', 'debug', "[uw::init] FAILED TO START EXTENSION. Error:", e);
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.log('error', 'debug', "[uw::init] FAILED TO START EXTENSION. Error:", e);
|
||||
console.error('Ultrawidify initalization failed for some reason:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,32 +33,35 @@ export default class UWServer {
|
||||
}
|
||||
|
||||
async setup() {
|
||||
// logger is the first thing that goes up
|
||||
try {
|
||||
// logger is the first thing that goes up
|
||||
const loggingOptions = {
|
||||
isBackgroundScript: true,
|
||||
allowLogging: false,
|
||||
useConfFromStorage: true,
|
||||
logAll: true,
|
||||
fileOptions: {
|
||||
enabled: false,
|
||||
},
|
||||
consoleOptions: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
this.logger = new Logger();
|
||||
await this.logger.init(loggingOptions);
|
||||
|
||||
const loggingOptions = {
|
||||
isBackgroundScript: true,
|
||||
allowLogging: false,
|
||||
useConfFromStorage: true,
|
||||
logAll: true,
|
||||
fileOptions: {
|
||||
enabled: false,
|
||||
},
|
||||
consoleOptions: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
this.logger = new Logger();
|
||||
await this.logger.init(loggingOptions);
|
||||
this.settings = new Settings({logger: this.logger});
|
||||
await this.settings.init();
|
||||
this.comms = new CommsServer(this);
|
||||
this.comms.subscribe('show-logger', async () => await this.initUiAndShowLogger());
|
||||
this.comms.subscribe('init-vue', async () => await this.initUi());
|
||||
this.comms.subscribe('uwui-vue-initialized', () => this.uiLoggerInitialized = true);
|
||||
this.comms.subscribe('emit-logs', () => {}); // we don't need to do anything, this gets forwarded to UI content script as is
|
||||
|
||||
this.settings = new Settings({logger: this.logger});
|
||||
await this.settings.init();
|
||||
this.comms = new CommsServer(this);
|
||||
this.comms.subscribe('show-logger', async () => await this.initUiAndShowLogger());
|
||||
this.comms.subscribe('init-vue', async () => await this.initUi());
|
||||
this.comms.subscribe('uwui-vue-initialized', () => this.uiLoggerInitialized = true);
|
||||
this.comms.subscribe('emit-logs', () => {}); // we don't need to do anything, this gets forwarded to UI content script as is
|
||||
|
||||
browser.tabs.onActivated.addListener((m) => {this.onTabSwitched(m)});
|
||||
browser.tabs.onActivated.addListener((m) => {this.onTabSwitched(m)});
|
||||
} catch (e) {
|
||||
console.error(`Ultrawidify [server]: failed to start. Reason:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
async _promisifyTabsGet(browserObj, tabId){
|
||||
@ -215,37 +218,42 @@ export default class UWServer {
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.warn('Ultrawidify [server]: UI setup failed. While problematic, this problem shouldn\'t completely crash the extension.');
|
||||
this.logger.log('ERROR', 'uwbg', 'UI initialization failed. Reason:', e);
|
||||
}
|
||||
}
|
||||
|
||||
async initUiAndShowLogger() {
|
||||
// this implementation is less than optimal and very hacky, but it should work
|
||||
// just fine for our use case.
|
||||
this.uiLoggerInitialized = false;
|
||||
try {
|
||||
// this implementation is less than optimal and very hacky, but it should work
|
||||
// just fine for our use case.
|
||||
this.uiLoggerInitialized = false;
|
||||
|
||||
await this.initUi();
|
||||
await this.initUi();
|
||||
|
||||
await new Promise<void>( async (resolve, reject) => {
|
||||
// if content script doesn't give us a response within 5 seconds, something is
|
||||
// obviously wrong and we stop waiting,
|
||||
await new Promise<void>( async (resolve, reject) => {
|
||||
// if content script doesn't give us a response within 5 seconds, something is
|
||||
// obviously wrong and we stop waiting,
|
||||
|
||||
// oh and btw, resolve/reject do not break the loops, so we need to do that
|
||||
// ourselves:
|
||||
// https://stackoverflow.com/questions/55207256/will-resolve-in-promise-loop-break-loop-iteration
|
||||
let isRejected = false;
|
||||
setTimeout( async () => {isRejected = true; reject()}, 5000);
|
||||
// oh and btw, resolve/reject do not break the loops, so we need to do that
|
||||
// ourselves:
|
||||
// https://stackoverflow.com/questions/55207256/will-resolve-in-promise-loop-break-loop-iteration
|
||||
let isRejected = false;
|
||||
setTimeout( async () => {isRejected = true; reject()}, 5000);
|
||||
|
||||
// check whether UI has been initiated on the FE. If it was, we resolve the
|
||||
// promise and off we go
|
||||
while (!isRejected) {
|
||||
if (this.uiLoggerInitialized) {
|
||||
resolve();
|
||||
return; // remember the bit about resolve() not breaking the loop?
|
||||
// check whether UI has been initiated on the FE. If it was, we resolve the
|
||||
// promise and off we go
|
||||
while (!isRejected) {
|
||||
if (this.uiLoggerInitialized) {
|
||||
resolve();
|
||||
return; // remember the bit about resolve() not breaking the loop?
|
||||
}
|
||||
await sleep(100);
|
||||
}
|
||||
await sleep(100);
|
||||
}
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn('Ultrawidify [server]: failed to set up logger UI. While problematic, this problem shouldn\'t completely crash the extension.');
|
||||
}
|
||||
}
|
||||
|
||||
async getCurrentTab() {
|
||||
|
@ -3,6 +3,7 @@
|
||||
import StretchType from '../../common/enums/StretchType.enum';
|
||||
import ExtensionMode from '../../common/enums/ExtensionMode.enum';
|
||||
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum';
|
||||
import BrowserDetect from './BrowserDetect';
|
||||
|
||||
const ExtensionConfPatch = [
|
||||
{
|
||||
@ -445,6 +446,75 @@ const ExtensionConfPatch = [
|
||||
// do nothing if disney+ is missing
|
||||
}
|
||||
}
|
||||
}, {
|
||||
forVersion: '5.0.1',
|
||||
updateFn: (userOptions, defaultOptions) => {
|
||||
try {
|
||||
userOptions.mitigations = {
|
||||
zoomLimit: {
|
||||
enabled: BrowserDetect.edge || BrowserDetect.isEdgeUA,
|
||||
limit: 0.997,
|
||||
fullscreenOnly: true
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}, {
|
||||
forVersion: '5.0.1.1',
|
||||
updateFn: (userOptions, defaultOptions) => {
|
||||
try {
|
||||
userOptions.mitigations = {
|
||||
zoomLimit: {
|
||||
enabled: true,
|
||||
limit: 0.997,
|
||||
fullscreenOnly: true
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}, {
|
||||
forVersion: '5.0.2',
|
||||
updateFn: (userOptions, defaultOptions) => {
|
||||
try {
|
||||
if (! userOptions.mitigations) {
|
||||
userOptions.mitigations = {
|
||||
zoomLimit: {
|
||||
enabled: true,
|
||||
limit: 0.997,
|
||||
fullscreenOnly: true
|
||||
}
|
||||
}
|
||||
} else if (BrowserDetect.chrome) {
|
||||
userOptions.mitigations = {
|
||||
zoomLimit: {
|
||||
enabled: true,
|
||||
limit: 0.997,
|
||||
fullscreenOnly: true
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}, {
|
||||
forVersion: '5.0.4',
|
||||
updateFn: (userOptions, defaultOptions) => {
|
||||
try {
|
||||
userOptions.sites['wwww.disneyplus.com'].DOM.player = {
|
||||
... userOptions.sites['wwww.disneyplus.com'].DOM.player,
|
||||
querySelectors: ".btm-media-client-element",
|
||||
useRelativeAncestor: false,
|
||||
videoAncestor: 1
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -7,6 +7,7 @@ import AntiGradientMode from '../../common/enums/AntiGradientMode.enum';
|
||||
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
||||
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
||||
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
||||
import BrowserDetect from './BrowserDetect';
|
||||
|
||||
if(Debug.debug)
|
||||
console.log("Loading: ExtensionConf.js");
|
||||
@ -960,6 +961,13 @@ const ExtensionConf: SettingsInterface = {
|
||||
}
|
||||
},
|
||||
],
|
||||
mitigations: {
|
||||
zoomLimit: {
|
||||
enabled: true,
|
||||
limit: 0.997,
|
||||
fullscreenOnly: true
|
||||
}
|
||||
},
|
||||
whatsNewChecked: true,
|
||||
// -----------------------------------------
|
||||
// ::: SITE CONFIGURATION :::
|
||||
@ -1062,9 +1070,10 @@ const ExtensionConf: SettingsInterface = {
|
||||
DOM: {
|
||||
"player": {
|
||||
"manual": true,
|
||||
"querySelectors": ".btn-media-clients",
|
||||
"querySelectors": ".btm-media-client-element",
|
||||
"additionalCss": "",
|
||||
"useRelativeAncestor": false,
|
||||
"videoAncestor": 1,
|
||||
"playerNodeCss": ""
|
||||
}
|
||||
},
|
||||
|
@ -155,8 +155,6 @@ class Settings {
|
||||
const sorted = this.sortConfPatches(extconfPatches);
|
||||
return sorted.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
|
||||
}
|
||||
|
||||
|
||||
applySettingsPatches(oldVersion, patches) {
|
||||
let index = this.findFirstNecessaryPatch(oldVersion, patches);
|
||||
if (index === -1) {
|
||||
@ -380,6 +378,14 @@ class Settings {
|
||||
return this.active.actions;
|
||||
}
|
||||
|
||||
getSettingsForSite(site?) {
|
||||
if (!site) {
|
||||
site = window.location.hostname;
|
||||
}
|
||||
|
||||
return this.active.sites[site];
|
||||
}
|
||||
|
||||
getExtensionMode(site?: string) {
|
||||
if (!site) {
|
||||
site = window.location.hostname;
|
||||
@ -478,7 +484,7 @@ class Settings {
|
||||
}
|
||||
|
||||
extensionEnabled(){
|
||||
return this.active.sites['@global'] !== ExtensionMode.Disabled
|
||||
return this.active.sites['@global'].mode !== ExtensionMode.Disabled
|
||||
}
|
||||
|
||||
extensionEnabledForSite(site) {
|
||||
|
@ -68,6 +68,22 @@ class PlayerData {
|
||||
private observer: ResizeObserver;
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* Gets player aspect ratio. If in full screen, it returns screen aspect ratio unless settings say otherwise.
|
||||
*/
|
||||
get aspectRatio() {
|
||||
try {
|
||||
if (this.dimensions?.fullscreen && !this.settings.getSettingsForSite()?.usePlayerArInFullscreen) {
|
||||
return window.innerWidth / window.innerHeight;
|
||||
}
|
||||
|
||||
return this.dimensions.width / this.dimensions.height;
|
||||
} catch (e) {
|
||||
console.error('cannot determine aspect ratio!', e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(videoData) {
|
||||
try {
|
||||
this.logger = videoData.logger;
|
||||
@ -107,9 +123,18 @@ class PlayerData {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we're in fullscreen mode or not.
|
||||
*/
|
||||
static isFullScreen(){
|
||||
console.info(window.innerHeight, window.screen.height, 'x', window.innerWidth, window.screen.width);
|
||||
return ( window.innerHeight == window.screen.height && window.innerWidth == window.screen.width);
|
||||
const ihdiff = Math.abs(window.screen.height - window.innerHeight);
|
||||
const iwdiff = Math.abs(window.screen.width - window.innerWidth);
|
||||
|
||||
// Chrome on linux on X on mixed PPI displays may return ever so slightly different values
|
||||
// for innerHeight vs screen.height abd innerWidth vs. screen.width, probably courtesy of
|
||||
// fractional scaling or something. This means we'll give ourself a few px of margin — the
|
||||
// window elements visible in not-fullscreen are usually double digit px tall
|
||||
return ( ihdiff < 5 && iwdiff < 5 );
|
||||
}
|
||||
|
||||
|
||||
@ -188,7 +213,7 @@ class PlayerData {
|
||||
try {
|
||||
this.doPeriodicPlayerElementChangeCheck();
|
||||
} catch (e) {
|
||||
console.error('[PlayerData::legacycd] this message is pretty high on the list of messages you shouldnt see', e);
|
||||
console.error('[PlayerData::legacycd] this message is pretty high on the list of messages you shouldn\'t see', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,7 +319,9 @@ class PlayerData {
|
||||
const videoWidth = this.video.offsetWidth;
|
||||
const videoHeight = this.video.offsetHeight;
|
||||
const elementQ = [];
|
||||
let scorePenalty = 0;
|
||||
const scorePenalty = 10;
|
||||
const sizePenaltyMultiplier = 0.1;
|
||||
let penaltyMultiplier = 0;
|
||||
let score;
|
||||
|
||||
try {
|
||||
@ -348,7 +375,7 @@ class PlayerData {
|
||||
}
|
||||
|
||||
// elements farther away from the video get a penalty
|
||||
score -= (scorePenalty++) * 20;
|
||||
score -= (scorePenalty) * 20;
|
||||
|
||||
// push the element on the queue/stack:
|
||||
elementQ.push({
|
||||
@ -375,7 +402,7 @@ class PlayerData {
|
||||
|
||||
// try to find element the old fashioned way
|
||||
|
||||
while (element){
|
||||
while (element){
|
||||
// odstranimo čudne elemente, ti bi pokvarili zadeve
|
||||
// remove weird elements, those would break our stuff
|
||||
if ( element.offsetWidth == 0 || element.offsetHeight == 0){
|
||||
@ -383,34 +410,41 @@ class PlayerData {
|
||||
continue;
|
||||
}
|
||||
|
||||
// element je player, če je ena stranica enako velika kot video, druga pa večja ali enaka.
|
||||
// za enakost dovolimo mala odstopanja
|
||||
// element is player, if one of the sides is as long as the video and the other bigger (or same)
|
||||
// we allow for tiny variations when checking for equality
|
||||
if ( (element.offsetWidth >= videoWidth && this.equalish(element.offsetHeight, videoHeight, 2))
|
||||
|| (element.offsetHeight >= videoHeight && this.equalish(element.offsetWidth, videoHeight, 2))) {
|
||||
|
||||
// todo — in case the match is only equalish and not exact, take difference into account when
|
||||
// calculating score
|
||||
|
||||
score = 100;
|
||||
// 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
|
||||
// size, since there are both cases where the other side is bigger _and_ cases
|
||||
// where other side is smaller than the video.
|
||||
//
|
||||
// Don't bother thinking about this too much, as any "thinking" was quickly
|
||||
// corrected by bugs caused by various edge cases.
|
||||
if (
|
||||
this.equalish(element.offsetHeight, videoHeight, 5)
|
||||
|| this.equalish(element.offsetWidth, videoWidth, 5)
|
||||
) {
|
||||
score = 1000;
|
||||
|
||||
// This entire section is disabled because of some bullshit on vk and some shady CIS streaming sites.
|
||||
// Possibly removal of this criteria is not necessary, because there was also a bug with force player
|
||||
//
|
||||
// -------------------
|
||||
// PENALTIES
|
||||
// -------------------
|
||||
//
|
||||
// Our ideal player will be as close to the video element, and it will als
|
||||
// be as close to the size of the video.
|
||||
|
||||
// prefer elements closer to <video>
|
||||
score -= scorePenalty * penaltyMultiplier++;
|
||||
|
||||
// the bigger the size difference between the video and the player,
|
||||
// the more penalty we'll incur. Since we did some grace ith
|
||||
let playerSizePenalty = 1;
|
||||
if ( element.offsetHeight > (videoHeight + 5)) {
|
||||
playerSizePenalty = (element.offsetWidth - videoHeight) * sizePenaltyMultiplier;
|
||||
}
|
||||
if ( element.offsetWidth > (videoWidth + 5)) {
|
||||
playerSizePenalty *= (element.offsetWidth - videoWidth) * sizePenaltyMultiplier
|
||||
}
|
||||
|
||||
score -= playerSizePenalty;
|
||||
|
||||
// if (element.id.indexOf('player') !== -1) { // prefer elements with 'player' in id
|
||||
// score += 75;
|
||||
// }
|
||||
// this has only been observed on steam
|
||||
// if (element.id.indexOf('movie') !== -1) {
|
||||
// score += 75;
|
||||
// }
|
||||
// if (element.classList.toString().indexOf('player') !== -1) { // prefer elements with 'player' in classlist, but a bit less than id
|
||||
// score += 50;
|
||||
// }
|
||||
score -= scorePenalty++; // prefer elements closer to <video>
|
||||
|
||||
elementQ.push({
|
||||
element: element,
|
||||
score: score,
|
||||
|
@ -48,6 +48,15 @@ class VideoData {
|
||||
//#endregion
|
||||
|
||||
|
||||
get aspectRatio() {
|
||||
try {
|
||||
return this.video.videoWidth / this.video.videoHeight;
|
||||
} catch (e) {
|
||||
console.error('cannot determine stream aspect ratio!', e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(video, settings, pageInfo){
|
||||
window.ultrawidify.addVideo(this);
|
||||
|
||||
@ -383,6 +392,12 @@ class VideoData {
|
||||
// verify that mutation didn't remove our class. Some pages like to do that.
|
||||
let confirmAspectRatioRestore = false;
|
||||
|
||||
if (!this.video) {
|
||||
this.logger.log('error', 'debug', '[VideoData::onVideoMutation] mutation was triggered, but video element is missing. Something is fishy. Terminating this uw instance.');
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
for(const mutation of mutationList) {
|
||||
if (mutation.type === 'attributes') {
|
||||
if( mutation.attributeName === 'class'
|
||||
@ -461,17 +476,17 @@ class VideoData {
|
||||
} catch (e) {
|
||||
}
|
||||
// THIS BREAKS PANNING
|
||||
const cs = window.getComputedStyle(this.video);
|
||||
const pcs = window.getComputedStyle(this.player.element);
|
||||
const videoComputedStyle = window.getComputedStyle(this.video);
|
||||
const playerComputedStyle = window.getComputedStyle(this.player.element);
|
||||
|
||||
try {
|
||||
const transformMatrix = cs.transform.split(')')[0].split(',');
|
||||
const transformMatrix = videoComputedStyle.transform.split(')')[0].split(',');
|
||||
const translateX = +transformMatrix[4];
|
||||
const translateY = +transformMatrix[5];
|
||||
const vh = +(cs.height.split('px')[0]);
|
||||
const vw = +(cs.width.split('px')[0]);
|
||||
const ph = +(pcs.height.split('px')[0]);
|
||||
const pw = +(pcs.width.split('px')[0]);
|
||||
const vh = +(videoComputedStyle.height.split('px')[0]);
|
||||
const vw = +(videoComputedStyle.width.split('px')[0]);
|
||||
const ph = +(playerComputedStyle.height.split('px')[0]);
|
||||
const pw = +(playerComputedStyle.width.split('px')[0]);
|
||||
|
||||
// TODO: check & account for panning and alignment
|
||||
if (transformMatrix[0] !== 'none'
|
||||
@ -479,6 +494,7 @@ class VideoData {
|
||||
&& this.isWithin(vw, (pw - (translateX * 2)), 2)) {
|
||||
} else {
|
||||
this.player.forceDetectPlayerElementChange();
|
||||
this.restoreAr();
|
||||
}
|
||||
|
||||
} catch(e) {
|
||||
@ -536,8 +552,6 @@ class VideoData {
|
||||
}
|
||||
return heightCompensationFactor;
|
||||
}
|
||||
|
||||
|
||||
firstTimeArdInit(){
|
||||
if(this.destroyed || this.invalid) {
|
||||
// throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}};
|
||||
|
@ -174,7 +174,7 @@ class Resizer {
|
||||
this.conf.videoUnloaded();
|
||||
}
|
||||
|
||||
this.logger.log('info', 'debug', '[Resizer::setAr] <rid:'+this.resizerId+'> trying to set ar. New ar:', ar)
|
||||
this.logger.log('info', 'debug', '[Resizer::setAr] <rid:'+this.resizerId+'> trying to set ar. New ar:', ar);
|
||||
|
||||
if (ar == null) {
|
||||
return;
|
||||
@ -527,6 +527,7 @@ class Resizer {
|
||||
return mode === 'height' ? heightFactor : widthFactor;
|
||||
}
|
||||
|
||||
private _computeOffsetsRecursionGuard: boolean = false;
|
||||
computeOffsets(stretchFactors: VideoDimensions){
|
||||
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.settings.active.sites['@global'].videoAlignment);
|
||||
|
||||
@ -549,10 +550,6 @@ class Resizer {
|
||||
const wdiff = this.conf.player.dimensions.width - realVideoWidth;
|
||||
const hdiff = this.conf.player.dimensions.height - realVideoHeight;
|
||||
|
||||
if (wdiff < 0 && hdiff < 0 && this.zoom.scale > 1) {
|
||||
this.conf.resizer.restore();
|
||||
}
|
||||
|
||||
const wdiffAfterZoom = realVideoWidth * stretchFactors.xFactor - this.conf.player.dimensions.width;
|
||||
const hdiffAfterZoom = realVideoHeight * stretchFactors.yFactor - this.conf.player.dimensions.height;
|
||||
|
||||
@ -614,8 +611,15 @@ class Resizer {
|
||||
`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.`
|
||||
)
|
||||
if (this.conf.player.checkPlayerSizeChange()) {
|
||||
this.conf.player.onPlayerDimensionsChanged();
|
||||
|
||||
// sometimes this appears to randomly recurse.
|
||||
// There seems to be no way to reproduce it.
|
||||
if (! this._computeOffsetsRecursionGuard) {
|
||||
this._computeOffsetsRecursionGuard = true;
|
||||
if (this.conf.player.checkPlayerSizeChange()) {
|
||||
this.conf.player.onPlayerDimensionsChanged();
|
||||
}
|
||||
this._computeOffsetsRecursionGuard = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,8 +118,8 @@ class Scaler {
|
||||
* * because video width is normalized on 100% of the parent, we don't need to correct
|
||||
* anything when the player is wider than the video.
|
||||
*/
|
||||
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
const streamAr = this.conf.aspectRatio;
|
||||
const playerAr = this.conf.player.aspectRatio;
|
||||
const heightCompensationFactor = this.conf.getHeightCompensationFactor();
|
||||
const compensatedStreamAr = streamAr * heightCompensationFactor;
|
||||
|
||||
@ -148,7 +148,7 @@ class Scaler {
|
||||
}
|
||||
|
||||
if (ar.type === AspectRatioType.Reset){
|
||||
return {xFactor: arCorrectionFactor, yFactor: arCorrectionFactor, arCorrectionFactor: arCorrectionFactor}
|
||||
return {xFactor: arCorrectionFactor, yFactor: arCorrectionFactor, arCorrectionFactor: arCorrectionFactor};
|
||||
}
|
||||
|
||||
// handle fuckie-wuckies
|
||||
|
@ -47,8 +47,8 @@ class Stretcher {
|
||||
}
|
||||
|
||||
applyConditionalStretch(stretchFactors, actualAr){
|
||||
let playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
let videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
let playerAr = this.conf.player.aspectRatio;
|
||||
let videoAr = this.conf.aspectRatio;
|
||||
|
||||
if (! actualAr){
|
||||
actualAr = playerAr;
|
||||
@ -102,25 +102,25 @@ class Stretcher {
|
||||
// This means we want to calculate stretching using those values, but we don't know
|
||||
// them. This means we have to calculate them.
|
||||
|
||||
const videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
if (this.conf.player.dimensions.width > this.conf.player.dimensions.height * videoAr) {
|
||||
const streamAr = this.conf.aspectRatio;
|
||||
if (this.conf.player.dimensions.width > this.conf.player.dimensions.height * streamAr) {
|
||||
return {
|
||||
xFactor: this.conf.player.dimensions.width / (this.conf.player.dimensions.height * videoAr),
|
||||
xFactor: this.conf.player.dimensions.width / (this.conf.player.dimensions.height * streamAr),
|
||||
yFactor: 1
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
xFactor: 1,
|
||||
yFactor: this.conf.player.dimensions.height / (this.conf.player.dimensions.width / videoAr)
|
||||
yFactor: this.conf.player.dimensions.height / (this.conf.player.dimensions.width / streamAr)
|
||||
};
|
||||
}
|
||||
|
||||
applyStretchFixedSource(postCropStretchFactors) {
|
||||
const videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
const streamAr = this.conf.aspectRatio;
|
||||
const playerAr = this.conf.player.aspectRatio;
|
||||
|
||||
const squeezeFactor = this.fixedStretchRatio / videoAr;
|
||||
const squeezeFactor = this.fixedStretchRatio / streamAr;
|
||||
|
||||
// Whether squeezing happens on X or Y axis depends on whether required AR is wider or narrower than
|
||||
// the player, in which the video is displayed
|
||||
@ -130,16 +130,11 @@ class Stretcher {
|
||||
this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we got:
|
||||
postCropStretchFactors: x=${postCropStretchFactors.xFactor} y=${postCropStretchFactors.yFactor}
|
||||
fixedStretchRatio: ${this.fixedStretchRatio}
|
||||
videoAr: ${videoAr}
|
||||
videoAr: ${streamAr}
|
||||
playerAr: ${playerAr}
|
||||
squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
||||
|
||||
|
||||
if (this.fixedStretchRatio < playerAr) {
|
||||
postCropStretchFactors.xFactor *= squeezeFactor;
|
||||
} else {
|
||||
postCropStretchFactors.yFactor *= squeezeFactor;
|
||||
}
|
||||
postCropStretchFactors.xFactor *= squeezeFactor;
|
||||
|
||||
this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we'll apply:\npostCropStretchFactors: x=${postCropStretchFactors.x} y=${postCropStretchFactors.y}`);
|
||||
|
||||
@ -151,9 +146,6 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
||||
}
|
||||
|
||||
getArCorrectionFactor() {
|
||||
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
|
||||
let arCorrectionFactor = 1;
|
||||
arCorrectionFactor = this.conf.player.dimensions.width / this.conf.video.offsetWidth;
|
||||
|
||||
@ -161,8 +153,8 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
||||
}
|
||||
|
||||
calculateStretch(actualAr, playerArOverride?) {
|
||||
const playerAr = playerArOverride || this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
const playerAr = playerArOverride || this.conf.player.aspectRatio;
|
||||
const streamAr = this.conf.aspectRatio;
|
||||
|
||||
if (! actualAr){
|
||||
actualAr = playerAr;
|
||||
@ -271,17 +263,15 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
||||
* style attribute does).
|
||||
*/
|
||||
chromeBugMitigation(stretchFactors) {
|
||||
console.log("limit zoom?", BrowserDetect.anyChromium, this.conf.player?.dimensions, this.settings?.active?.mitigations?.zoomLimit?.enabled);
|
||||
if (
|
||||
BrowserDetect.anyChromium
|
||||
&& (this.conf.player?.dimensions?.fullscreen || !
|
||||
this.settings?.active?.mitigations?.zoomLimit?.fullscreenOnly)
|
||||
&& (this.conf.player?.dimensions?.fullscreen || ! this.settings?.active?.mitigations?.zoomLimit?.fullscreenOnly)
|
||||
&& this.settings?.active?.mitigations?.zoomLimit?.enabled
|
||||
) {
|
||||
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
const playerAr = this.conf.player.aspectRatio;
|
||||
const streamAr = this.conf.aspectRatio;
|
||||
|
||||
let maxSafeAr;
|
||||
let maxSafeAr: number;
|
||||
let arLimitFactor = this.settings?.active?.mitigations?.zoomLimit?.limit ?? 0.997;
|
||||
|
||||
if (playerAr >= (streamAr * 1.1)) {
|
||||
|
@ -2,9 +2,7 @@
|
||||
* NOTE: we cannot get rid of this js file. I tried for 30 seconds and I couldn't get
|
||||
* extension to work unless I kept this part of extension out of the ts file.
|
||||
*/
|
||||
|
||||
import UWContent from './UWContent';
|
||||
import BrowserDetect from './conf/BrowserDetect';
|
||||
|
||||
if(process.env.CHANNEL !== 'stable'){
|
||||
console.warn("\n\n\n\n\n\n ——— Sᴛλʀᴛɪɴɢ Uʟᴛʀᴀᴡɪᴅɪꜰʏ ———\n << ʟᴏᴀᴅɪɴɢ ᴍᴀɪɴ ꜰɪʟᴇ >>\n\n\n\n");
|
||||
@ -20,9 +18,5 @@ if(process.env.CHANNEL !== 'stable'){
|
||||
}
|
||||
}
|
||||
|
||||
if (BrowserDetect.edge) {
|
||||
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
|
||||
}
|
||||
|
||||
const main = new UWContent();
|
||||
main.init();
|
||||
|
@ -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": "5.0.1",
|
||||
"version": "5.0.4",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
|
||||
|
@ -20,17 +20,6 @@
|
||||
Build channel: {{BrowserDetect.processEnvChannel}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="BrowserDetect.isEdgeUA" style="margin: 2px 12px; border: 1px solid #fa6; color: #fa6" class="flex flex-row flex-center">
|
||||
<div class="flex-nogrow flex-nosrhink flex flex-center" style="font-size: 2em">
|
||||
<Icon icon="exclamation-triangle"></Icon>
|
||||
</div>
|
||||
<div class="flex-grow padding-right: 1em; line-height: 1">
|
||||
<small>
|
||||
<b>NOTE:</b> please ensure your Windows and Edge have the latest updates in order for this extension to work on DRM-protected sites.
|
||||
If your Windows and Edge are not up to date, videos on sites like Netflix, Hulu, and Disney+ may not be aligned and cropped correctly.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="narrowPopup"
|
||||
class="w100 show-more flex flex-row flex-center flex-cross-center menu-button"
|
||||
|
@ -38,18 +38,18 @@
|
||||
Player detection settings<br/><small>for {{site}}</small>
|
||||
</div>
|
||||
<div class="description">
|
||||
Player is the frame around the video. Extension crops/stretches the video to fit the player.
|
||||
If extension doesn't work, you can help a little by telling it where to look for the player.<br/>
|
||||
</div>
|
||||
<div class="">
|
||||
<div class="">
|
||||
<input :checked="!playerManualQs"
|
||||
<input :checked="playerManualQs"
|
||||
@change="togglePlayerManualQs"
|
||||
type="checkbox"
|
||||
/> Detect automatically
|
||||
/> Manually specify player
|
||||
</div>
|
||||
|
||||
<div class="flex flex-column">
|
||||
<div class="">Query selectors:</div>
|
||||
<div class="">Query selectors for player:</div>
|
||||
<input type="text"
|
||||
v-model="playerQs"
|
||||
@change="updatePlayerQuerySelector"
|
||||
@ -58,24 +58,48 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
<div class="flex flex-row">
|
||||
<input :checked="playerByNodeIndex"
|
||||
:disabled="!playerManualQs"
|
||||
@change="toggleByNodeIndex"
|
||||
type="checkbox"
|
||||
/> Specify player node parent index instead
|
||||
</div>
|
||||
|
||||
<div class="flex flex-column">
|
||||
<div class="">Player node parent index:</div>
|
||||
<input v-model="playerParentNodeIndex"
|
||||
/>
|
||||
<div>
|
||||
Player is n-th parent of video:
|
||||
</div>
|
||||
<input v-model="playerParentNodeIndex"
|
||||
:disabled="!playerByNodeIndex || !playerManualQs"
|
||||
@change="updatePlayerParentNodeIndex"
|
||||
@blur="updatePlayerParentNodeIndex"
|
||||
type="number"
|
||||
/>
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<small>
|
||||
<b>Hint:</b> Player is a HTML element that represents the portion of the page you expect the video to play in.
|
||||
You can provide player's query selector, or you can tick the 'player is the n-th parent of video'
|
||||
checkbox and try entering values 1-12ish and see if anything works. Note that you need to save
|
||||
settings and reload the page every time you change the number.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row">
|
||||
<input :checked="usePlayerAr"
|
||||
@change="toggleUsePlayerAr"
|
||||
type="checkbox"
|
||||
/>
|
||||
<div>
|
||||
Do not use monitor AR in fullscreen
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<small>
|
||||
<b>Hint:</b> When in full screen, the extension will assume that player element is as big as your screen.
|
||||
You generally want to keep this option off, unless you like to browse in fullscreen a lot.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="label">
|
||||
@ -114,7 +138,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-column">
|
||||
<div class="flex label-secondary form-label">Additional css</div>
|
||||
<div class="flex label-secondary form-label">Additional style for video element</div>
|
||||
<input type="text"
|
||||
v-model="videoCss"
|
||||
@change="updateVideoCss"
|
||||
@ -156,6 +180,7 @@
|
||||
<div class="flex label-secondary form-label">
|
||||
<input :checked="settings?.active?.mitigations?.zoomLimit?.fullscreenOnly"
|
||||
@change="setMitigation(['zoomLimit', 'fullscreenOnly'], $event.target.checked)"
|
||||
:disabled="!settings?.active?.mitigations?.zoomLimit?.enabled"
|
||||
type="checkbox"
|
||||
/> Limit zoom only while in fullscreen
|
||||
</div>
|
||||
@ -164,7 +189,7 @@
|
||||
<b>Fix for:</b> Chrome and Edge used to have a bug where videos would get incorrectly stretched when zoomed in too far.
|
||||
The issue only appeared in fullscreen, on nVidia GPUs, and with hardware acceleration enabled. While this option only
|
||||
needs to be applied in fullscreen, fullscreen detection in Chrome can be a bit unreliable (depending on your OS and/or
|
||||
display scaling settings).
|
||||
display scaling settings). <a href="https://stuff.tamius.net/sacred-texts/2021/02/01/ultrawidify-and-chrome-2021-edition/" target="_blank">More about the issue</a>.
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
@ -212,6 +237,7 @@ export default {
|
||||
playerCss: '',
|
||||
playerByNodeIndex: false,
|
||||
playerParentNodeIndex: undefined,
|
||||
usePlayerAr: false,
|
||||
BrowserDetect
|
||||
};
|
||||
},
|
||||
@ -233,6 +259,7 @@ export default {
|
||||
this.playerQs = this.settings.active.sites[this.site].DOM.player.querySelectors;
|
||||
this.playerByNodeIndex = this.settings.active.sites[this.site].DOM.player.useRelativeAncestor || this.playerByNodeIndex;
|
||||
this.playerParentNodeIndex = this.settings.active.sites[this.site].DOM.player.videoAncestor;
|
||||
this.usePlayerAr = this.settings.active.sites[this.site].usePlayerArInFullscreen;
|
||||
} catch (e) {
|
||||
// that's here just in case relevant settings for this site don't exist yet
|
||||
}
|
||||
@ -329,6 +356,12 @@ export default {
|
||||
this.settings.active.sites[this.site].DOM.player.useRelativeAncestor = this.playerByNodeIndex;
|
||||
this.settings.save();
|
||||
},
|
||||
toggleUsePlayerAr() {
|
||||
this.ensureSettings('player');
|
||||
this.usePlayerAr = !this.usePlayerAr;
|
||||
this.settings.active.sites[this.site].usePlayerArInFullscreen = this.usePlayerAr;
|
||||
this.settings.save();
|
||||
},
|
||||
setMitigation(mitigation, value) {
|
||||
// ensure mitigations object exists.
|
||||
// it may not exist in the settings on first load
|
||||
|
@ -126,6 +126,7 @@ import KeyboardShortcutParser from '../../common/js/KeyboardShortcutParser';
|
||||
import ShortcutButton from '../../common/components/ShortcutButton';
|
||||
import ComputeActionsMixin from '../../common/mixins/ComputeActionsMixin';
|
||||
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
||||
import BrowserDetect from '../../ext/conf/BrowserDetect';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -157,7 +158,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async openOptionsPage() {
|
||||
(browser ?? chrome).runtime.openOptionsPage();
|
||||
if (BrowserDetect.firefox) {
|
||||
browser.runtime.openOptionsPage();
|
||||
} else {
|
||||
chrome.runtime.openOptionsPage();
|
||||
}
|
||||
},
|
||||
execAction(action) {
|
||||
this.exec.exec(action, 'page', this.frame);
|
||||
|
@ -2,19 +2,14 @@
|
||||
<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">5.0.1</p>
|
||||
<p class="label">5.0.4</p>
|
||||
<ul>
|
||||
<li>
|
||||
Disabled Chrome's and Edge's zoom limitation.
|
||||
</li>
|
||||
<li>
|
||||
Added an option to toggle and further configure zoom limitation.
|
||||
Updated config for disney+. Hopefully it works now. Special thanks to <a href="https://github.com/tamius-han/ultrawidify/issues/84#issuecomment-846334005" target="_blank">@jwannebo</a>.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<small><b>NOTE:</b> zoom limitations were introduced as a workaround for a bug caused by Chrome's/Edge's faulty hardware acceleration
|
||||
which caused videos to be incorrectly stretched on nVidia GPUs while in fullscreens. While this issue is reportedly fixed as
|
||||
of few weeks ago, a few people reported having this issue within the past two weeks.</small>
|
||||
<small><b>NOTE from older versions:</b> zoom limitations were introduced as a workaround for a bug caused by Chrome's/Edge's faulty hardware acceleration.</small>
|
||||
</p>
|
||||
<p>
|
||||
<small>If you experience issues with videos being stretched incorrectly at certain zoom levels, go to:</small><br/>
|
||||
|
Loading…
Reference in New Issue
Block a user