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",
|
"decycle",
|
||||||
"disneyplus",
|
"disneyplus",
|
||||||
"equalish",
|
"equalish",
|
||||||
|
"fith",
|
||||||
|
"fitw",
|
||||||
"fuckup",
|
"fuckup",
|
||||||
"gfycat",
|
"gfycat",
|
||||||
"gmail",
|
"gmail",
|
||||||
@ -28,6 +30,7 @@
|
|||||||
"letterboxed",
|
"letterboxed",
|
||||||
"manjaro",
|
"manjaro",
|
||||||
"minification",
|
"minification",
|
||||||
|
"mitigations",
|
||||||
"nogrow",
|
"nogrow",
|
||||||
"noshrink",
|
"noshrink",
|
||||||
"outro",
|
"outro",
|
||||||
|
19
CHANGELOG.md
19
CHANGELOG.md
@ -18,9 +18,24 @@
|
|||||||
|
|
||||||
## v5.x (current major)
|
## 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
|
### v5.0.1
|
||||||
* Turned off zoom limitations for Edge and Chrome.
|
* Added an option for users to turn off (and/or configure) Chrome/Edge's zoom limiter.
|
||||||
* Added an option for users to manually re-enable (and configure) Chrome/Edge's zoom limiter.
|
|
||||||
|
|
||||||
### v5.0.0
|
### 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
|
## 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).
|
[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).
|
||||||
|
|
||||||
**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).
|
|
||||||
|
|
||||||
There's also [nightly "builds"](https://stuff.lionsarch.tamius.net/ultrawidify/nightly/).
|
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
|
### 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/)
|
* [Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/)
|
||||||
* [Chrome, Opera](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi)
|
* [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi)
|
||||||
* [Chromium Edge](https://microsoftedge.microsoft.com/addons/detail/lmpgpgechmkkkehkihpiddbcbgibokbi)
|
* [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
|
### 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",
|
"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.",
|
"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>",
|
"author": "Tamius Han <tamius.han@gmail.com>",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run pre-build; cross-env NODE_ENV=production BROWSER=firefox CHANNEL=stable webpack --hide-modules",
|
"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": "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-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",
|
"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-testing-chrome": "cross-env NODE_ENV=development BROWSER=chrome CHANNEL=testing webpack --hide-modules",
|
||||||
"build-zip": "node scripts/build-zip.js",
|
"build-zip": "node scripts/build-zip.js",
|
||||||
"build:dev": "webpack --hide-modules",
|
"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",
|
"pre-build": "rm -rf ./dist-ff; rm -rf ./dist-chrome; rm -rf ./node_modules; npm ci",
|
||||||
"start": "npm run dev"
|
"start": "npm run dev"
|
||||||
},
|
},
|
||||||
@ -25,7 +25,6 @@
|
|||||||
"@types/core-js": "^2.5.3",
|
"@types/core-js": "^2.5.3",
|
||||||
"@types/es6-promise": "^3.3.0",
|
"@types/es6-promise": "^3.3.0",
|
||||||
"@types/firefox": "0.0.30",
|
"@types/firefox": "0.0.30",
|
||||||
"@types/node": "^14.14.25",
|
|
||||||
"@types/resize-observer-browser": "^0.1.5",
|
"@types/resize-observer-browser": "^0.1.5",
|
||||||
"@vue/cli": "^4.5.9",
|
"@vue/cli": "^4.5.9",
|
||||||
"@vue/cli-plugin-typescript": "^4.5.11",
|
"@vue/cli-plugin-typescript": "^4.5.11",
|
||||||
@ -36,7 +35,7 @@
|
|||||||
"concurrently": "^5.2.0",
|
"concurrently": "^5.2.0",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
"json-cyclic": "0.0.3",
|
"json-cyclic": "0.0.3",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.21",
|
||||||
"typescript": "^4.2.3",
|
"typescript": "^4.2.3",
|
||||||
"vue": "^3.0.0-beta.1",
|
"vue": "^3.0.0-beta.1",
|
||||||
"vuex": "^4.0.0-alpha.1",
|
"vuex": "^4.0.0-alpha.1",
|
||||||
@ -48,6 +47,7 @@
|
|||||||
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
|
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
|
||||||
"@babel/preset-env": "^7.12.13",
|
"@babel/preset-env": "^7.12.13",
|
||||||
"@types/lodash": "^4.14.168",
|
"@types/lodash": "^4.14.168",
|
||||||
|
"@types/node": "^14.14.25",
|
||||||
"@vue/compiler-sfc": "^3.0.3",
|
"@vue/compiler-sfc": "^3.0.3",
|
||||||
"archiver": "^3.0.0",
|
"archiver": "^3.0.0",
|
||||||
"babel-loader": "^8.2.2",
|
"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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# let's raise RAM limit for npm command globally
|
||||||
|
NODE_OPTIONS=--max_old_space_size=4096
|
||||||
|
|
||||||
npm ci
|
npm ci
|
||||||
|
|
||||||
rm -rf ./dist-zip || true # no big deal if ./dist-zip doesn't exist
|
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
|
# build firefox
|
||||||
#
|
#
|
||||||
npm run "${BUILD_SCRIPT}"
|
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_KEY}" ] ; then
|
||||||
# if [ ! -z "${AMO_API_SECRET}" ] ; then
|
# if [ ! -z "${AMO_API_SECRET}" ] ; then
|
||||||
# web-ext sign --source-dir ./dist --api-key "${AMO_API_KEY}" --api-secret "${AMO_API_SECRET}"
|
# 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
|
# build chrome
|
||||||
#
|
#
|
||||||
npm run "${BUILD_SCRIPT}-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
|
#./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
|
# 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}"
|
scp -i ~/.ssh/id_rsa -r ./dist-zip/* "ultrawidify-uploader@${RELEASE_SERVER}:${RELEASE_DIRECTORY}${BUILD_CHANNEL_DIRECTORY}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# Build finished message
|
# Build finished message
|
||||||
######################################
|
######################################
|
||||||
|
@ -189,7 +189,7 @@ interface SettingsInterface {
|
|||||||
mitigations?: {
|
mitigations?: {
|
||||||
zoomLimit?: {
|
zoomLimit?: {
|
||||||
enabled?: boolean,
|
enabled?: boolean,
|
||||||
fullscreenOnly: boolean,
|
fullscreenOnly?: boolean,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,6 +285,7 @@ interface SettingsInterface {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
css?: string;
|
css?: string;
|
||||||
|
usePlayerArInFullscreen?: boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,87 +48,96 @@ export default class UWContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reloadSettings() {
|
reloadSettings() {
|
||||||
this.logger.log('info', 'debug', 'Things happened in the popup. Will reload extension settings.');
|
try {
|
||||||
this.init();
|
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(){
|
async init(){
|
||||||
if (Debug.debug) {
|
|
||||||
console.log("[uw::main] loading configuration ...");
|
|
||||||
}
|
|
||||||
|
|
||||||
// logger init is the first thing that needs to run
|
|
||||||
try {
|
try {
|
||||||
if (!this.logger) {
|
if (Debug.debug) {
|
||||||
|
console.log("[uw::main] loading configuration ...");
|
||||||
this.logger = new Logger();
|
}
|
||||||
await this.logger.init(baseLoggingOptions);
|
|
||||||
|
// 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
|
// show popup if logging to file is enabled
|
||||||
if (this.logger.isLoggingAllowed() && this.logger.isLoggingToFile()) {
|
if (this.logger.isLoggingAllowed() && this.logger.isLoggingToFile()) {
|
||||||
console.info("[uw::init] Logging is allowed! Initalizing vue and UI!");
|
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
|
// CommsClient is not initiated yet, so we use static comms to send the command
|
||||||
Comms.sendMessage({cmd: 'show-logger'});
|
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)
|
try {
|
||||||
}
|
if (this.pageInfo) {
|
||||||
|
this.logger.log('info', 'debug', '[uw.js::setup] An instance of pageInfo already exists and will be destroyed.');
|
||||||
// init() is re-run any time settings change
|
this.pageInfo.destroy();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
this.actionHandler = new ActionHandler(this.pageInfo);
|
this.pageInfo = new PageInfo(this.comms, this.settings, this.logger, extensionMode, isSiteDisabled);
|
||||||
this.actionHandler.init();
|
this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized.");
|
||||||
|
|
||||||
this.logger.log('info', 'debug', "[uw.js::setup] ActionHandler initiated.");
|
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) {
|
} 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() {
|
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 = {
|
this.settings = new Settings({logger: this.logger});
|
||||||
isBackgroundScript: true,
|
await this.settings.init();
|
||||||
allowLogging: false,
|
this.comms = new CommsServer(this);
|
||||||
useConfFromStorage: true,
|
this.comms.subscribe('show-logger', async () => await this.initUiAndShowLogger());
|
||||||
logAll: true,
|
this.comms.subscribe('init-vue', async () => await this.initUi());
|
||||||
fileOptions: {
|
this.comms.subscribe('uwui-vue-initialized', () => this.uiLoggerInitialized = true);
|
||||||
enabled: false,
|
this.comms.subscribe('emit-logs', () => {}); // we don't need to do anything, this gets forwarded to UI content script as is
|
||||||
},
|
|
||||||
consoleOptions: {
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.logger = new Logger();
|
|
||||||
await this.logger.init(loggingOptions);
|
|
||||||
|
|
||||||
this.settings = new Settings({logger: this.logger});
|
browser.tabs.onActivated.addListener((m) => {this.onTabSwitched(m)});
|
||||||
await this.settings.init();
|
} catch (e) {
|
||||||
this.comms = new CommsServer(this);
|
console.error(`Ultrawidify [server]: failed to start. Reason:`, e);
|
||||||
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)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _promisifyTabsGet(browserObj, tabId){
|
async _promisifyTabsGet(browserObj, tabId){
|
||||||
@ -215,37 +218,42 @@ export default class UWServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} 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);
|
this.logger.log('ERROR', 'uwbg', 'UI initialization failed. Reason:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async initUiAndShowLogger() {
|
async initUiAndShowLogger() {
|
||||||
// this implementation is less than optimal and very hacky, but it should work
|
try {
|
||||||
// just fine for our use case.
|
// this implementation is less than optimal and very hacky, but it should work
|
||||||
this.uiLoggerInitialized = false;
|
// just fine for our use case.
|
||||||
|
this.uiLoggerInitialized = false;
|
||||||
|
|
||||||
await this.initUi();
|
await this.initUi();
|
||||||
|
|
||||||
await new Promise<void>( async (resolve, reject) => {
|
await new Promise<void>( async (resolve, reject) => {
|
||||||
// if content script doesn't give us a response within 5 seconds, something is
|
// if content script doesn't give us a response within 5 seconds, something is
|
||||||
// obviously wrong and we stop waiting,
|
// obviously wrong and we stop waiting,
|
||||||
|
|
||||||
// oh and btw, resolve/reject do not break the loops, so we need to do that
|
// oh and btw, resolve/reject do not break the loops, so we need to do that
|
||||||
// ourselves:
|
// ourselves:
|
||||||
// https://stackoverflow.com/questions/55207256/will-resolve-in-promise-loop-break-loop-iteration
|
// https://stackoverflow.com/questions/55207256/will-resolve-in-promise-loop-break-loop-iteration
|
||||||
let isRejected = false;
|
let isRejected = false;
|
||||||
setTimeout( async () => {isRejected = true; reject()}, 5000);
|
setTimeout( async () => {isRejected = true; reject()}, 5000);
|
||||||
|
|
||||||
// check whether UI has been initiated on the FE. If it was, we resolve the
|
// check whether UI has been initiated on the FE. If it was, we resolve the
|
||||||
// promise and off we go
|
// promise and off we go
|
||||||
while (!isRejected) {
|
while (!isRejected) {
|
||||||
if (this.uiLoggerInitialized) {
|
if (this.uiLoggerInitialized) {
|
||||||
resolve();
|
resolve();
|
||||||
return; // remember the bit about resolve() not breaking the loop?
|
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() {
|
async getCurrentTab() {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import StretchType from '../../common/enums/StretchType.enum';
|
import StretchType from '../../common/enums/StretchType.enum';
|
||||||
import ExtensionMode from '../../common/enums/ExtensionMode.enum';
|
import ExtensionMode from '../../common/enums/ExtensionMode.enum';
|
||||||
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum';
|
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum';
|
||||||
|
import BrowserDetect from './BrowserDetect';
|
||||||
|
|
||||||
const ExtensionConfPatch = [
|
const ExtensionConfPatch = [
|
||||||
{
|
{
|
||||||
@ -445,6 +446,75 @@ const ExtensionConfPatch = [
|
|||||||
// do nothing if disney+ is missing
|
// 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 AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
||||||
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
||||||
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
||||||
|
import BrowserDetect from './BrowserDetect';
|
||||||
|
|
||||||
if(Debug.debug)
|
if(Debug.debug)
|
||||||
console.log("Loading: ExtensionConf.js");
|
console.log("Loading: ExtensionConf.js");
|
||||||
@ -960,6 +961,13 @@ const ExtensionConf: SettingsInterface = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
mitigations: {
|
||||||
|
zoomLimit: {
|
||||||
|
enabled: true,
|
||||||
|
limit: 0.997,
|
||||||
|
fullscreenOnly: true
|
||||||
|
}
|
||||||
|
},
|
||||||
whatsNewChecked: true,
|
whatsNewChecked: true,
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// ::: SITE CONFIGURATION :::
|
// ::: SITE CONFIGURATION :::
|
||||||
@ -1062,9 +1070,10 @@ const ExtensionConf: SettingsInterface = {
|
|||||||
DOM: {
|
DOM: {
|
||||||
"player": {
|
"player": {
|
||||||
"manual": true,
|
"manual": true,
|
||||||
"querySelectors": ".btn-media-clients",
|
"querySelectors": ".btm-media-client-element",
|
||||||
"additionalCss": "",
|
"additionalCss": "",
|
||||||
"useRelativeAncestor": false,
|
"useRelativeAncestor": false,
|
||||||
|
"videoAncestor": 1,
|
||||||
"playerNodeCss": ""
|
"playerNodeCss": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -155,8 +155,6 @@ class Settings {
|
|||||||
const sorted = this.sortConfPatches(extconfPatches);
|
const sorted = this.sortConfPatches(extconfPatches);
|
||||||
return sorted.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
|
return sorted.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
applySettingsPatches(oldVersion, patches) {
|
applySettingsPatches(oldVersion, patches) {
|
||||||
let index = this.findFirstNecessaryPatch(oldVersion, patches);
|
let index = this.findFirstNecessaryPatch(oldVersion, patches);
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
@ -380,6 +378,14 @@ class Settings {
|
|||||||
return this.active.actions;
|
return this.active.actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSettingsForSite(site?) {
|
||||||
|
if (!site) {
|
||||||
|
site = window.location.hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.active.sites[site];
|
||||||
|
}
|
||||||
|
|
||||||
getExtensionMode(site?: string) {
|
getExtensionMode(site?: string) {
|
||||||
if (!site) {
|
if (!site) {
|
||||||
site = window.location.hostname;
|
site = window.location.hostname;
|
||||||
@ -478,7 +484,7 @@ class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extensionEnabled(){
|
extensionEnabled(){
|
||||||
return this.active.sites['@global'] !== ExtensionMode.Disabled
|
return this.active.sites['@global'].mode !== ExtensionMode.Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
extensionEnabledForSite(site) {
|
extensionEnabledForSite(site) {
|
||||||
|
@ -68,6 +68,22 @@ class PlayerData {
|
|||||||
private observer: ResizeObserver;
|
private observer: ResizeObserver;
|
||||||
//#endregion
|
//#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) {
|
constructor(videoData) {
|
||||||
try {
|
try {
|
||||||
this.logger = videoData.logger;
|
this.logger = videoData.logger;
|
||||||
@ -107,9 +123,18 @@ class PlayerData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether we're in fullscreen mode or not.
|
||||||
|
*/
|
||||||
static isFullScreen(){
|
static isFullScreen(){
|
||||||
console.info(window.innerHeight, window.screen.height, 'x', window.innerWidth, window.screen.width);
|
const ihdiff = Math.abs(window.screen.height - window.innerHeight);
|
||||||
return ( window.innerHeight == window.screen.height && window.innerWidth == window.screen.width);
|
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 {
|
try {
|
||||||
this.doPeriodicPlayerElementChangeCheck();
|
this.doPeriodicPlayerElementChangeCheck();
|
||||||
} catch (e) {
|
} 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 videoWidth = this.video.offsetWidth;
|
||||||
const videoHeight = this.video.offsetHeight;
|
const videoHeight = this.video.offsetHeight;
|
||||||
const elementQ = [];
|
const elementQ = [];
|
||||||
let scorePenalty = 0;
|
const scorePenalty = 10;
|
||||||
|
const sizePenaltyMultiplier = 0.1;
|
||||||
|
let penaltyMultiplier = 0;
|
||||||
let score;
|
let score;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -348,7 +375,7 @@ class PlayerData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// elements farther away from the video get a penalty
|
// elements farther away from the video get a penalty
|
||||||
score -= (scorePenalty++) * 20;
|
score -= (scorePenalty) * 20;
|
||||||
|
|
||||||
// push the element on the queue/stack:
|
// push the element on the queue/stack:
|
||||||
elementQ.push({
|
elementQ.push({
|
||||||
@ -375,7 +402,7 @@ class PlayerData {
|
|||||||
|
|
||||||
// try to find element the old fashioned way
|
// try to find element the old fashioned way
|
||||||
|
|
||||||
while (element){
|
while (element){
|
||||||
// odstranimo čudne elemente, ti bi pokvarili zadeve
|
// odstranimo čudne elemente, ti bi pokvarili zadeve
|
||||||
// remove weird elements, those would break our stuff
|
// remove weird elements, those would break our stuff
|
||||||
if ( element.offsetWidth == 0 || element.offsetHeight == 0){
|
if ( element.offsetWidth == 0 || element.offsetHeight == 0){
|
||||||
@ -383,34 +410,41 @@ class PlayerData {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// element je player, če je ena stranica enako velika kot video, druga pa večja ali enaka.
|
// element is player, if at least one of the sides is as long as the video
|
||||||
// za enakost dovolimo mala odstopanja
|
// note that we can't make any additional assumptions with regards to player
|
||||||
// element is player, if one of the sides is as long as the video and the other bigger (or same)
|
// size, since there are both cases where the other side is bigger _and_ cases
|
||||||
// we allow for tiny variations when checking for equality
|
// where other side is smaller than the video.
|
||||||
if ( (element.offsetWidth >= videoWidth && this.equalish(element.offsetHeight, videoHeight, 2))
|
//
|
||||||
|| (element.offsetHeight >= videoHeight && this.equalish(element.offsetWidth, videoHeight, 2))) {
|
// Don't bother thinking about this too much, as any "thinking" was quickly
|
||||||
|
// corrected by bugs caused by various edge cases.
|
||||||
// todo — in case the match is only equalish and not exact, take difference into account when
|
if (
|
||||||
// calculating score
|
this.equalish(element.offsetHeight, videoHeight, 5)
|
||||||
|
|| this.equalish(element.offsetWidth, videoWidth, 5)
|
||||||
score = 100;
|
) {
|
||||||
|
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({
|
elementQ.push({
|
||||||
element: element,
|
element: element,
|
||||||
score: score,
|
score: score,
|
||||||
|
@ -48,6 +48,15 @@ class VideoData {
|
|||||||
//#endregion
|
//#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){
|
constructor(video, settings, pageInfo){
|
||||||
window.ultrawidify.addVideo(this);
|
window.ultrawidify.addVideo(this);
|
||||||
|
|
||||||
@ -383,6 +392,12 @@ class VideoData {
|
|||||||
// verify that mutation didn't remove our class. Some pages like to do that.
|
// verify that mutation didn't remove our class. Some pages like to do that.
|
||||||
let confirmAspectRatioRestore = false;
|
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) {
|
for(const mutation of mutationList) {
|
||||||
if (mutation.type === 'attributes') {
|
if (mutation.type === 'attributes') {
|
||||||
if( mutation.attributeName === 'class'
|
if( mutation.attributeName === 'class'
|
||||||
@ -461,17 +476,17 @@ class VideoData {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
// THIS BREAKS PANNING
|
// THIS BREAKS PANNING
|
||||||
const cs = window.getComputedStyle(this.video);
|
const videoComputedStyle = window.getComputedStyle(this.video);
|
||||||
const pcs = window.getComputedStyle(this.player.element);
|
const playerComputedStyle = window.getComputedStyle(this.player.element);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const transformMatrix = cs.transform.split(')')[0].split(',');
|
const transformMatrix = videoComputedStyle.transform.split(')')[0].split(',');
|
||||||
const translateX = +transformMatrix[4];
|
const translateX = +transformMatrix[4];
|
||||||
const translateY = +transformMatrix[5];
|
const translateY = +transformMatrix[5];
|
||||||
const vh = +(cs.height.split('px')[0]);
|
const vh = +(videoComputedStyle.height.split('px')[0]);
|
||||||
const vw = +(cs.width.split('px')[0]);
|
const vw = +(videoComputedStyle.width.split('px')[0]);
|
||||||
const ph = +(pcs.height.split('px')[0]);
|
const ph = +(playerComputedStyle.height.split('px')[0]);
|
||||||
const pw = +(pcs.width.split('px')[0]);
|
const pw = +(playerComputedStyle.width.split('px')[0]);
|
||||||
|
|
||||||
// TODO: check & account for panning and alignment
|
// TODO: check & account for panning and alignment
|
||||||
if (transformMatrix[0] !== 'none'
|
if (transformMatrix[0] !== 'none'
|
||||||
@ -479,6 +494,7 @@ class VideoData {
|
|||||||
&& this.isWithin(vw, (pw - (translateX * 2)), 2)) {
|
&& this.isWithin(vw, (pw - (translateX * 2)), 2)) {
|
||||||
} else {
|
} else {
|
||||||
this.player.forceDetectPlayerElementChange();
|
this.player.forceDetectPlayerElementChange();
|
||||||
|
this.restoreAr();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@ -536,8 +552,6 @@ class VideoData {
|
|||||||
}
|
}
|
||||||
return heightCompensationFactor;
|
return heightCompensationFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
firstTimeArdInit(){
|
firstTimeArdInit(){
|
||||||
if(this.destroyed || this.invalid) {
|
if(this.destroyed || this.invalid) {
|
||||||
// throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}};
|
// throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}};
|
||||||
|
@ -174,7 +174,7 @@ class Resizer {
|
|||||||
this.conf.videoUnloaded();
|
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) {
|
if (ar == null) {
|
||||||
return;
|
return;
|
||||||
@ -527,6 +527,7 @@ class Resizer {
|
|||||||
return mode === 'height' ? heightFactor : widthFactor;
|
return mode === 'height' ? heightFactor : widthFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _computeOffsetsRecursionGuard: boolean = false;
|
||||||
computeOffsets(stretchFactors: VideoDimensions){
|
computeOffsets(stretchFactors: VideoDimensions){
|
||||||
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.settings.active.sites['@global'].videoAlignment);
|
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 wdiff = this.conf.player.dimensions.width - realVideoWidth;
|
||||||
const hdiff = this.conf.player.dimensions.height - realVideoHeight;
|
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 wdiffAfterZoom = realVideoWidth * stretchFactors.xFactor - this.conf.player.dimensions.width;
|
||||||
const hdiffAfterZoom = realVideoHeight * stretchFactors.yFactor - this.conf.player.dimensions.height;
|
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`,
|
`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.`
|
`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
|
* * 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.
|
* anything when the player is wider than the video.
|
||||||
*/
|
*/
|
||||||
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
const streamAr = this.conf.aspectRatio;
|
||||||
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
const playerAr = this.conf.player.aspectRatio;
|
||||||
const heightCompensationFactor = this.conf.getHeightCompensationFactor();
|
const heightCompensationFactor = this.conf.getHeightCompensationFactor();
|
||||||
const compensatedStreamAr = streamAr * heightCompensationFactor;
|
const compensatedStreamAr = streamAr * heightCompensationFactor;
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ class Scaler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ar.type === AspectRatioType.Reset){
|
if (ar.type === AspectRatioType.Reset){
|
||||||
return {xFactor: arCorrectionFactor, yFactor: arCorrectionFactor, arCorrectionFactor: arCorrectionFactor}
|
return {xFactor: arCorrectionFactor, yFactor: arCorrectionFactor, arCorrectionFactor: arCorrectionFactor};
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle fuckie-wuckies
|
// handle fuckie-wuckies
|
||||||
|
@ -47,8 +47,8 @@ class Stretcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyConditionalStretch(stretchFactors, actualAr){
|
applyConditionalStretch(stretchFactors, actualAr){
|
||||||
let playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
let playerAr = this.conf.player.aspectRatio;
|
||||||
let videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
let videoAr = this.conf.aspectRatio;
|
||||||
|
|
||||||
if (! actualAr){
|
if (! actualAr){
|
||||||
actualAr = playerAr;
|
actualAr = playerAr;
|
||||||
@ -102,25 +102,25 @@ class Stretcher {
|
|||||||
// This means we want to calculate stretching using those values, but we don't know
|
// This means we want to calculate stretching using those values, but we don't know
|
||||||
// them. This means we have to calculate them.
|
// them. This means we have to calculate them.
|
||||||
|
|
||||||
const videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
const streamAr = this.conf.aspectRatio;
|
||||||
if (this.conf.player.dimensions.width > this.conf.player.dimensions.height * videoAr) {
|
if (this.conf.player.dimensions.width > this.conf.player.dimensions.height * streamAr) {
|
||||||
return {
|
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
|
yFactor: 1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
xFactor: 1,
|
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) {
|
applyStretchFixedSource(postCropStretchFactors) {
|
||||||
const videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
const streamAr = this.conf.aspectRatio;
|
||||||
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
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
|
// 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
|
// 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:
|
this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we got:
|
||||||
postCropStretchFactors: x=${postCropStretchFactors.xFactor} y=${postCropStretchFactors.yFactor}
|
postCropStretchFactors: x=${postCropStretchFactors.xFactor} y=${postCropStretchFactors.yFactor}
|
||||||
fixedStretchRatio: ${this.fixedStretchRatio}
|
fixedStretchRatio: ${this.fixedStretchRatio}
|
||||||
videoAr: ${videoAr}
|
videoAr: ${streamAr}
|
||||||
playerAr: ${playerAr}
|
playerAr: ${playerAr}
|
||||||
squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
||||||
|
|
||||||
|
postCropStretchFactors.xFactor *= squeezeFactor;
|
||||||
if (this.fixedStretchRatio < playerAr) {
|
|
||||||
postCropStretchFactors.xFactor *= squeezeFactor;
|
|
||||||
} else {
|
|
||||||
postCropStretchFactors.yFactor *= squeezeFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we'll apply:\npostCropStretchFactors: x=${postCropStretchFactors.x} y=${postCropStretchFactors.y}`);
|
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() {
|
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;
|
let arCorrectionFactor = 1;
|
||||||
arCorrectionFactor = this.conf.player.dimensions.width / this.conf.video.offsetWidth;
|
arCorrectionFactor = this.conf.player.dimensions.width / this.conf.video.offsetWidth;
|
||||||
|
|
||||||
@ -161,8 +153,8 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculateStretch(actualAr, playerArOverride?) {
|
calculateStretch(actualAr, playerArOverride?) {
|
||||||
const playerAr = playerArOverride || this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
const playerAr = playerArOverride || this.conf.player.aspectRatio;
|
||||||
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
const streamAr = this.conf.aspectRatio;
|
||||||
|
|
||||||
if (! actualAr){
|
if (! actualAr){
|
||||||
actualAr = playerAr;
|
actualAr = playerAr;
|
||||||
@ -271,17 +263,15 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
|
|||||||
* style attribute does).
|
* style attribute does).
|
||||||
*/
|
*/
|
||||||
chromeBugMitigation(stretchFactors) {
|
chromeBugMitigation(stretchFactors) {
|
||||||
console.log("limit zoom?", BrowserDetect.anyChromium, this.conf.player?.dimensions, this.settings?.active?.mitigations?.zoomLimit?.enabled);
|
|
||||||
if (
|
if (
|
||||||
BrowserDetect.anyChromium
|
BrowserDetect.anyChromium
|
||||||
&& (this.conf.player?.dimensions?.fullscreen || !
|
&& (this.conf.player?.dimensions?.fullscreen || ! this.settings?.active?.mitigations?.zoomLimit?.fullscreenOnly)
|
||||||
this.settings?.active?.mitigations?.zoomLimit?.fullscreenOnly)
|
|
||||||
&& this.settings?.active?.mitigations?.zoomLimit?.enabled
|
&& this.settings?.active?.mitigations?.zoomLimit?.enabled
|
||||||
) {
|
) {
|
||||||
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
const playerAr = this.conf.player.aspectRatio;
|
||||||
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
const streamAr = this.conf.aspectRatio;
|
||||||
|
|
||||||
let maxSafeAr;
|
let maxSafeAr: number;
|
||||||
let arLimitFactor = this.settings?.active?.mitigations?.zoomLimit?.limit ?? 0.997;
|
let arLimitFactor = this.settings?.active?.mitigations?.zoomLimit?.limit ?? 0.997;
|
||||||
|
|
||||||
if (playerAr >= (streamAr * 1.1)) {
|
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
|
* 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.
|
* extension to work unless I kept this part of extension out of the ts file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import UWContent from './UWContent';
|
import UWContent from './UWContent';
|
||||||
import BrowserDetect from './conf/BrowserDetect';
|
|
||||||
|
|
||||||
if(process.env.CHANNEL !== 'stable'){
|
if(process.env.CHANNEL !== 'stable'){
|
||||||
console.warn("\n\n\n\n\n\n ——— Sᴛλʀᴛɪɴɢ Uʟᴛʀᴀᴡɪᴅɪꜰʏ ———\n << ʟᴏᴀᴅɪɴɢ ᴍᴀɪɴ ꜰɪʟᴇ >>\n\n\n\n");
|
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();
|
const main = new UWContent();
|
||||||
main.init();
|
main.init();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Ultrawidify",
|
"name": "Ultrawidify",
|
||||||
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
|
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
|
||||||
"version": "5.0.1",
|
"version": "5.0.4",
|
||||||
"applications": {
|
"applications": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
|
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
|
||||||
|
@ -20,17 +20,6 @@
|
|||||||
Build channel: {{BrowserDetect.processEnvChannel}}
|
Build channel: {{BrowserDetect.processEnvChannel}}
|
||||||
</div>
|
</div>
|
||||||
</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
|
<div
|
||||||
v-if="narrowPopup"
|
v-if="narrowPopup"
|
||||||
class="w100 show-more flex flex-row flex-center flex-cross-center menu-button"
|
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>
|
Player detection settings<br/><small>for {{site}}</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<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>
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="">
|
<div class="">
|
||||||
<input :checked="!playerManualQs"
|
<input :checked="playerManualQs"
|
||||||
@change="togglePlayerManualQs"
|
@change="togglePlayerManualQs"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
/> Detect automatically
|
/> Manually specify player
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-column">
|
<div class="flex flex-column">
|
||||||
<div class="">Query selectors:</div>
|
<div class="">Query selectors for player:</div>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
v-model="playerQs"
|
v-model="playerQs"
|
||||||
@change="updatePlayerQuerySelector"
|
@change="updatePlayerQuerySelector"
|
||||||
@ -58,24 +58,48 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="">
|
<div class="flex flex-row">
|
||||||
<input :checked="playerByNodeIndex"
|
<input :checked="playerByNodeIndex"
|
||||||
:disabled="!playerManualQs"
|
:disabled="!playerManualQs"
|
||||||
@change="toggleByNodeIndex"
|
@change="toggleByNodeIndex"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
/> Specify player node parent index instead
|
/>
|
||||||
</div>
|
<div>
|
||||||
|
Player is n-th parent of video:
|
||||||
<div class="flex flex-column">
|
</div>
|
||||||
<div class="">Player node parent index:</div>
|
<input v-model="playerParentNodeIndex"
|
||||||
<input v-model="playerParentNodeIndex"
|
|
||||||
:disabled="!playerByNodeIndex || !playerManualQs"
|
:disabled="!playerByNodeIndex || !playerManualQs"
|
||||||
@change="updatePlayerParentNodeIndex"
|
@change="updatePlayerParentNodeIndex"
|
||||||
@blur="updatePlayerParentNodeIndex"
|
@blur="updatePlayerParentNodeIndex"
|
||||||
type="number"
|
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>
|
</div>
|
||||||
|
|
||||||
<div class="label">
|
<div class="label">
|
||||||
@ -114,7 +138,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-column">
|
<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"
|
<input type="text"
|
||||||
v-model="videoCss"
|
v-model="videoCss"
|
||||||
@change="updateVideoCss"
|
@change="updateVideoCss"
|
||||||
@ -156,6 +180,7 @@
|
|||||||
<div class="flex label-secondary form-label">
|
<div class="flex label-secondary form-label">
|
||||||
<input :checked="settings?.active?.mitigations?.zoomLimit?.fullscreenOnly"
|
<input :checked="settings?.active?.mitigations?.zoomLimit?.fullscreenOnly"
|
||||||
@change="setMitigation(['zoomLimit', 'fullscreenOnly'], $event.target.checked)"
|
@change="setMitigation(['zoomLimit', 'fullscreenOnly'], $event.target.checked)"
|
||||||
|
:disabled="!settings?.active?.mitigations?.zoomLimit?.enabled"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
/> Limit zoom only while in fullscreen
|
/> Limit zoom only while in fullscreen
|
||||||
</div>
|
</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.
|
<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
|
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
|
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>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -212,6 +237,7 @@ export default {
|
|||||||
playerCss: '',
|
playerCss: '',
|
||||||
playerByNodeIndex: false,
|
playerByNodeIndex: false,
|
||||||
playerParentNodeIndex: undefined,
|
playerParentNodeIndex: undefined,
|
||||||
|
usePlayerAr: false,
|
||||||
BrowserDetect
|
BrowserDetect
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -233,6 +259,7 @@ export default {
|
|||||||
this.playerQs = this.settings.active.sites[this.site].DOM.player.querySelectors;
|
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.playerByNodeIndex = this.settings.active.sites[this.site].DOM.player.useRelativeAncestor || this.playerByNodeIndex;
|
||||||
this.playerParentNodeIndex = this.settings.active.sites[this.site].DOM.player.videoAncestor;
|
this.playerParentNodeIndex = this.settings.active.sites[this.site].DOM.player.videoAncestor;
|
||||||
|
this.usePlayerAr = this.settings.active.sites[this.site].usePlayerArInFullscreen;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// that's here just in case relevant settings for this site don't exist yet
|
// 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.active.sites[this.site].DOM.player.useRelativeAncestor = this.playerByNodeIndex;
|
||||||
this.settings.save();
|
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) {
|
setMitigation(mitigation, value) {
|
||||||
// ensure mitigations object exists.
|
// ensure mitigations object exists.
|
||||||
// it may not exist in the settings on first load
|
// 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 ShortcutButton from '../../common/components/ShortcutButton';
|
||||||
import ComputeActionsMixin from '../../common/mixins/ComputeActionsMixin';
|
import ComputeActionsMixin from '../../common/mixins/ComputeActionsMixin';
|
||||||
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
||||||
|
import BrowserDetect from '../../ext/conf/BrowserDetect';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -157,7 +158,11 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async openOptionsPage() {
|
async openOptionsPage() {
|
||||||
(browser ?? chrome).runtime.openOptionsPage();
|
if (BrowserDetect.firefox) {
|
||||||
|
browser.runtime.openOptionsPage();
|
||||||
|
} else {
|
||||||
|
chrome.runtime.openOptionsPage();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
execAction(action) {
|
execAction(action) {
|
||||||
this.exec.exec(action, 'page', this.frame);
|
this.exec.exec(action, 'page', this.frame);
|
||||||
|
@ -2,19 +2,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<h2>What's new</h2>
|
<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>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>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Disabled Chrome's and Edge's 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>
|
|
||||||
<li>
|
|
||||||
Added an option to toggle and further configure zoom limitation.
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
<small><b>NOTE:</b> zoom limitations were introduced as a workaround for a bug caused by Chrome's/Edge's faulty hardware acceleration
|
<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>
|
||||||
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>
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<small>If you experience issues with videos being stretched incorrectly at certain zoom levels, go to:</small><br/>
|
<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