Merge branch 'master' into stable

This commit is contained in:
Tamius Han 2020-02-11 19:59:33 +01:00
commit ef52eec860
35 changed files with 2445 additions and 1050 deletions

View File

@ -1,5 +1,6 @@
{ {
"plugins": [ "plugins": [
"@babel/plugin-proposal-optional-chaining"
], ],
"presets": [ "presets": [
["@babel/preset-env", { ["@babel/preset-env", {

View File

@ -6,8 +6,10 @@
"blackframe", "blackframe",
"canvas", "canvas",
"comms", "comms",
"decycle",
"equalish", "equalish",
"insta", "insta",
"minification",
"recursing", "recursing",
"reddit", "reddit",
"rescan", "rescan",

View File

@ -5,6 +5,7 @@
### Plans for the future ### Plans for the future
* WebGL * WebGL
* Native builds for Chromium Edge and Opera
* Settings page looks ugly af right now. Maybe fix it some time later * Settings page looks ugly af right now. Maybe fix it some time later
* other bug fixes * other bug fixes
@ -12,7 +13,13 @@ QoL improvements for me:
* logging: allow to enable logging at will and export said logs to a file * logging: allow to enable logging at will and export said logs to a file
### v4.4.3 ### v4.4.4 (current)
* Tab detection in extension popup has been made more accurate
* QoL: Added user-accessible logger (to make fixing sites I can't access a bit easier)
* Changed links to reflect my github username change
### v4.4.3
* Fixed conf patch for disney+ (hopefully) (v4.4.3.1: but for real) * Fixed conf patch for disney+ (hopefully) (v4.4.3.1: but for real)
* `Settings.save()` adds missing values to site config when saving extension configuration. * `Settings.save()` adds missing values to site config when saving extension configuration.

View File

@ -14,4 +14,4 @@ todo
#This extension asks for permission that isn't listed above. #This extension asks for permission that isn't listed above.
Sometimes (and by 'sometimes' I mean 'way too often') I forget to update README files. If there's a permission that I haven't wrote an explanation for, please [open an issue](https://github.com/xternal7/ultrawidify/issues). Sometimes (and by 'sometimes' I mean 'way too often') I forget to update README files. If there's a permission that I haven't wrote an explanation for, please [open an issue](https://github.com/tamius-han/ultrawidify/issues).

View File

@ -2,7 +2,9 @@
## 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), [Edge](https://github.com/xternal7/ultrawidify#microsoft-edge) (Chromium-based only) [Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/), [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi), [Edge](https://github.com/tamius-han/ultrawidify#microsoft-edge) (Chromium-based only)
There's also [nightly "builds"](https://stuff.lionsarch.tamius.net/ultrawidify/nightly/).
## TL;DR ## TL;DR
@ -15,7 +17,7 @@ If you own an ultrawide monitor, you have probably noticed that sometimes videos
## Known issues ## Known issues
* Netflix autodetection not working in Chrome, wontfix as issue is fundamentally unfixable. * Netflix autodetection not working in Chrome, wontfix as issue is fundamentally unfixable.
* Everything reported in [issues](https://github.com/xternal7/ultrawidify/issues) * Everything reported in [issues](https://github.com/tamius-han/ultrawidify/issues)
### Limitations ### Limitations
@ -49,10 +51,17 @@ I am not actively testing extension on other sites. You can try your luck and en
You can download this extension from Firefox' and Chrome's extension stores: You can download this extension from Firefox' and Chrome's extension stores:
* [Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/) * [Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/)
* [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi) * [Chrome, Opera, Chromium Edge](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi)
Opera users and users of the new, Chromium-based Edge can install Ultrawidify from Chrome Web Store as well. Opera users and users of the new, Chromium-based Edge can install Ultrawidify from Chrome Web Store as well.
### Nightly builds
* Nightly builds can be downloaded [here](https://stuff.lionsarch.tamius.net/ultrawidify/) as an unpacked extension that can
only be installed temporarily.
If I did anything during the day, the nightly version will be sorta-built at whatever my VPS provider thinks is 4AM CE(S)T.
# Beggathon (donations) # Beggathon (donations)
If you want to support this project, please consider a donation. Working on this extension takes time, money, coffee and motivation. Sometimes also [a very precise amount of alco](https://xkcd.com/323/). If you want to support this project, please consider a donation. Working on this extension takes time, money, coffee and motivation. Sometimes also [a very precise amount of alco](https://xkcd.com/323/).
@ -218,7 +227,7 @@ The keyboard shortcuts have already been listed, but let's list them all again i
### Rebinding keyboard shortcuts ### Rebinding keyboard shortcuts
is currently not possible. Settings page for this extension has been disabled sometime with 2.0 release (because it [broke](https://github.com/xternal7/ultrawidify/issues/16)), and fixing the setting page has been very low priority as I've had more important issues to work on. is currently not possible. Settings page for this extension has been disabled sometime with 2.0 release (because it [broke](https://github.com/tamius-han/ultrawidify/issues/16)), and fixing the setting page has been very low priority as I've had more important issues to work on.
However, I do plan on implementing this feature. Hopefully by the end of the year, but given how consistently I've been breaking self-imposed deadlines and goals for this extension don't hold your breath. After all, [Hofstadter's a bitch](https://en.wikipedia.org/wiki/Hofstadter%27s_law). However, I do plan on implementing this feature. Hopefully by the end of the year, but given how consistently I've been breaking self-imposed deadlines and goals for this extension don't hold your breath. After all, [Hofstadter's a bitch](https://en.wikipedia.org/wiki/Hofstadter%27s_law).

1666
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
{ {
"name": "ultravidify", "name": "ultravidify",
"version": "4.4.3", "version": "4.4.4",
"description": "Aspect ratio fixer for youtube that works around some people's disability to properly encode 21:9 (and sometimes, 16:9) videos.", "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": {
"start": "cross-env HMR=true npm run build:dev -- --watch", "start": "cross-env HMR=true npm run build:dev -- --watch",
"build": "cross-env NODE_ENV=production BROWSER=firefox webpack --hide-modules", "build": "cross-env NODE_ENV=production BROWSER=firefox CHANNEL=stable webpack --hide-modules",
"build-chrome": "cross-env NODE_ENV=production BROWSER=chrome webpack --hide-modules", "build-chrome": "cross-env NODE_ENV=production BROWSER=chrome CHANNEL=stable webpack --hide-modules",
"build-edge": "cross-env NODE_ENV=production BROWSER=edge webpack --hide-modules", "build-edge": "cross-env NODE_ENV=production BROWSER=edge CHANNEL=stable webpack --hide-modules",
"build:dev": "cross-env NODE_ENV=development BROWSER=firefox webpack --hide-modules", "build:dev": "cross-env NODE_ENV=development BROWSER=firefox CHANNEL=dev webpack --hide-modules",
"build-testing": "cross-env NODE_ENV=development BROWSER=firefox CHANNEL=testing webpack --hide-modules", "build-testing": "cross-env NODE_ENV=development BROWSER=firefox CHANNEL=testing webpack --hide-modules",
"build-nightly": "cross-env NODE_ENV=development BROWSER=firefox CHANNEL=nightly webpack --hide-modules", "build-nightly": "cross-env NODE_ENV=development BROWSER=firefox CHANNEL=nightly webpack --hide-modules",
"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",
@ -17,7 +17,8 @@
"build-edge:dev": "cross-env NODE_ENV=development BROWSER=edge webpack --hide-modules", "build-edge:dev": "cross-env NODE_ENV=development BROWSER=edge webpack --hide-modules",
"build-all": "rm ./dist-zip/uw-amo-source.zip; mv ./dist-zip/*.zip ./dist-zip/old/; npm run build; node scripts/build-zip.js ff; npm run build-chrome; node scripts/build-zip.js chrome; ./scripts/prepare-amo-source.sh", "build-all": "rm ./dist-zip/uw-amo-source.zip; mv ./dist-zip/*.zip ./dist-zip/old/; npm run build; node scripts/build-zip.js ff; npm run build-chrome; node scripts/build-zip.js chrome; ./scripts/prepare-amo-source.sh",
"build-zip": "node scripts/build-zip.js", "build-zip": "node scripts/build-zip.js",
"watch": "npm run build -- --watch", "dev": "npm run build:dev -- --watch",
"watch": "npm run build:dev -- --watch",
"watch-chrome": "npm run build-chrome -- --watch", "watch-chrome": "npm run build-chrome -- --watch",
"watch-edge": "npm run build-edge -- --watch", "watch-edge": "npm run build-edge -- --watch",
"watch:dev": "cross-env HMR=true npm run build:dev -- --watch", "watch:dev": "cross-env HMR=true npm run build:dev -- --watch",
@ -28,30 +29,32 @@
"@types/core-js": "^2.5.0", "@types/core-js": "^2.5.0",
"@types/es6-promise": "^3.3.0", "@types/es6-promise": "^3.3.0",
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",
"vue": "^2.5.17", "json-cyclic": "0.0.3",
"vuex": "^3.0.1", "vue": "^2.6.11",
"vuex-webextensions": "^1.2.6" "vuex": "^3.1.2",
"vuex-webextensions": "^1.3.0",
"webextension-polyfill": "^0.6.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.1.2", "@babel/core": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.0.0", "@babel/plugin-proposal-optional-chaining": "^7.8.3",
"@babel/preset-env": "^7.1.0", "@babel/preset-env": "^7.8.3",
"archiver": "^3.0.0", "archiver": "^3.0.0",
"babel-loader": "^8.0.2", "babel-loader": "^8.0.6",
"copy-webpack-plugin": "^4.5.3", "copy-webpack-plugin": "^4.5.3",
"cross-env": "^5.2.0", "cross-env": "^5.2.0",
"css-loader": "^0.28.11", "css-loader": "^0.28.11",
"ejs": "^2.6.1", "ejs": "^2.7.4",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"mini-css-extract-plugin": "^0.4.4", "mini-css-extract-plugin": "^0.4.4",
"node-sass": "^4.9.3", "node-sass": "^4.13.1",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"vue-loader": "^15.4.2", "vue-loader": "^15.8.3",
"vue-template-compiler": "^2.5.17", "vue-template-compiler": "^2.6.11",
"web-ext-types": "^2.1.0", "web-ext-types": "^2.1.0",
"webpack": "^4.20.2", "webpack": "^4.41.5",
"webpack-chrome-extension-reloader": "^0.8.3", "webpack-chrome-extension-reloader": "^0.8.3",
"webpack-cli": "^3.1.2", "webpack-cli": "^3.3.10",
"webpack-shell-plugin": "^0.5.0" "webpack-shell-plugin": "^0.5.0"
} }
} }

View File

@ -27,7 +27,7 @@ echo " -> BUILD_CHANNEL_DIRECTORY: $BUILD_CHANNEL_DIRECTORY"
if [ ! -z "$GIT_COMMIT" ] ; then if [ ! -z "$GIT_COMMIT" ] ; then
if [ ! -z "$GIT_PREVIOUS_COMMIT" ] ; then if [ ! -z "$GIT_PREVIOUS_COMMIT" ] ; then
if [ "$GIT_COMMIT" == "$GIT_PREVIOUS_COMMIT" ] ; then if [ "$GIT_COMMIT" == "$GIT_PREVIOUS_COMMIT" ] ; then
if [ $FORCE_BUILD == true ] ; then if [ $FORCE_BUILD == false ] ; then
echo "--------------------------------------------" echo "--------------------------------------------"
echo " Nothing has changed. Aborting build." echo " Nothing has changed. Aborting build."
echo "--------------------------------------------" echo "--------------------------------------------"
@ -40,23 +40,24 @@ fi
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
mkdir dist-zip # create it back
# #
# build firefox # build firefox
# #
npm run "${BUILD_SCRIPT}" npm run "${BUILD_SCRIPT}"
node scripts/build-zip.js ff node 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}"
fi # fi
fi # fi
# #
# build chrome # build chrome
# #
npm run "${BUILD_SCRIPT}-chrome" npm run "${BUILD_SCRIPT}-chrome"
node scripts/build-zip.js chrome node scripts/build-zip.js chrome nightly
# #
#./scripts/build-crx.sh #./scripts/build-crx.sh
@ -66,21 +67,20 @@ node scripts/build-zip.js chrome
# UPLOAD TO WEB SERVER # UPLOAD TO WEB SERVER
###################################### ######################################
# # add ssh key, if not added echo "--------------------------------------------"
# if [ -z "$SSH_AUTH_SOCK" ] ; then echo " files ready for upload"
# eval `ssh-agent -s` echo "--------------------------------------------"
# ssh-add echo ""
# fi echo "Uploading to server ..."
# push all built stuff to the server
# # push all built stuff to the server scp -i ~/.ssh/id_rsa -r ./dist-zip/* "ultrawidify-uploader@${RELEASE_SERVER}:${RELEASE_DIRECTORY}${BUILD_CHANNEL_DIRECTORY}"
# scp -r ./build-zip/* "ultrawidify-uploader@${RELEASE_SERVER}:${RELEASE_DIRECTORY}${BUILD_CHANNEL_DIRECTORY}"
###################################### ######################################
# Build finished message # Build finished message
###################################### ######################################
echo ""
echo "--------------------------------------------" echo "--------------------------------------------"
echo " BUILD FINISHED SUCCESSFULLY" echo " BUILD FINISHED SUCCESSFULLY"
echo "--------------------------------------------" echo "--------------------------------------------"

View File

@ -52,15 +52,19 @@ const main = () => {
let realZipDir; let realZipDir;
if (!!testingOrNightly) { if (!!testingOrNightly) {
realZipDir = path.join(DEST_ZIP_DIR, baseFilename); realZipDir = path.join(DEST_ZIP_DIR, version);
} else { } else {
realZipDir = DEST_ZIP_DIR; realZipDir = path.join(DEST_ZIP_DIR);
} }
const zipFilename = `${baseFilename}-${browser}.zip`; const zipFilename = `${baseFilename}-${browser}.zip`;
makeDirIfNotExists(realZipDir); try {
makeDirIfNotExists(realZipDir, {recursive: true});
} catch (e) {
console.error('Failed to make directory.\nDirectory we wanted to make', realZipDir, '\nerror we got:\n', e)
return 1;
}
buildZip(DEST_DIR, realZipDir, zipFilename) buildZip(DEST_DIR, realZipDir, zipFilename)
.then(() => console.info('OK')) .then(() => console.info('OK'))
.catch(console.err); .catch(console.err);

24
src/common/js/IO.js Normal file
View File

@ -0,0 +1,24 @@
class IO {
/**
* Export a (presumably json) string to file. Meant for use with content script.
* @param {*} jsonString string to be saved
*/
static async csStringToFile(jsonString) {
console.info("\n\n\n\n---------- Starting export of log to file ----------------");
console.info("[info] json string for exportObject:", jsonString.length);
const blob = new Blob([jsonString], {type: 'application/json'});
const fileUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = fileUrl;
a.download = 'ultrawidify-log.log';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(fileUrl);
}
}
export default IO;

3
src/common/js/utils.js Normal file
View File

@ -0,0 +1,3 @@
export async function sleep(timeout) {
return new Promise( (resolve, reject) => setTimeout(() => resolve(), timeout));
}

370
src/csui/LoggerUi.vue Normal file
View File

@ -0,0 +1,370 @@
<template>
<div v-if="showLoggerUi" class="root-window flex flex-column overflow-hidden">
<div class="header">
<div class="header-top flex flex-row">
<div class="flex-grow">
<h1>{{header.header}}</h1>
</div>
<div class="button flex-noshrink button-header"
@click="hidePopup()"
>
<template v-if="logStringified">Finish logging</template>
<template v-else>Hide popup</template>
</div>
<!-- <div class="button flex-noshrink button-header"
@click="stopLogging()"
>
Stop logging
</div> -->
</div>
<div class="header-bottom">
<div>{{header.subheader}}</div>
</div>
</div>
<div class="content flex flex-row flex-grow overflow-hidden">
<!-- LOGGER SETTINGS PANEL -->
<div class="settings-panel flex flex-noshrink flex-column">
<div class="panel-top flex-nogrow">
<h2>Logger configuration</h2>
<p>Paste logger configuration in this box</p>
</div>
<div class="panel-middle scrollable flex-grow p-t-025em">
<div ref="settingsEditArea"
style="white-space: pre-wrap; border: 1px solid orange; padding: 10px;"
class="monospace h100"
:class="{'jsonbg': !confHasError, 'jsonbg-error': confHasError}"
contenteditable="true"
@input="updateSettings"
>
{{parsedSettings}}
</div>
</div>
<div class="flex-noshrink flex flex-row flex-cross-center p-t-025em">
<div class="button button-bar"
@click="restoreLoggerSettings()"
>
Revert logger config
</div>
</div>
</div>
<!-- LOGGER OUTPUT/START LOGGING -->
<div class="results-panel flex flex-shrink flex-column overflow-hidden">
<div class="panel-top flex-nogrow">
<h2>Logger results</h2>
</div>
<template v-if="logStringified">
<div v-if="confHasError" class="warn">
Logger configuration contains an error. You can export current log, but you will be unable to record a new log.
</div>
<div class="panel-middle scrollable flex-grow p-t-025em">
<pre>
{{logStringified}}
</pre>
</div>
<div class="flex-noshrink flex flex-row flex-end p-t-025em">
<div class="button button-bar"
@click="startLogging()"
>
New log
</div>
<div class="button button-bar"
@click="exportLog()"
>
Export log
</div>
<div class="button button-bar button-primary"
@click="exportAndQuit()"
>
Export & finish
</div>
</div>
</template>
<template v-else>
<div class="panel-middle scrollable flex-grow">
<div v-if="!parsedSettings" class="text-center w100">
Please paste logger config into the text box to the left.
</div>
<div v-else-if="confHasError" class="warn">
Logger configuration contains an error. Cannot start logging.
</div>
<div v-else-if="lastSettings && lastSettings.allowLogging && lastSettings.consoleOptions && lastSettings.consoleOptions.enabled"
class="flex flex-column flex-center flex-cross-center w100 h100"
>
<p class="m-025em">
Logging in progress ...
</p>
<div class="button button-big button-primary"
@click="stopLogging()"
>
Stop logging
</div>
<p v-if="lastSettings && lastSettings.timeout"
class="m-025em"
>
... or wait until logging ends.
</p>
</div>
<div v-else class="flex flex-column flex-center flex-cross-center w100 h100">
<div class="button button-big button-primary"
@click="startLogging()"
>
Start logging
</div>
</div>
</div>
</template>
</div>
</div>
<!-- <div>
button row is heres
</div> -->
</div>
</template>
<script>
import { mapState } from 'vuex';
import Logger from '../ext/lib/Logger';
import Comms from '../ext/lib/comms/Comms';
import IO from '../common/js/IO';
export default {
data() {
return {
showLoggerUi: false,
header: {
header: 'whoopsie daisy',
subheader: 'you broke the header choosing script'
},
parsedSettings: '',
lastSettings: {},
confHasError: false,
logStringified: '',
}
},
async created() {
const headerRotation = [{
header: "DEFORESTATOR 5000",
subheader: "Iron Legion's finest logging tool"
}, {
header: "Astinus",
subheader: "Ultrawidify logging tool"
}, {
header: "Tracer",
subheader: "I'm already printing stack traces"
}];
this.header = headerRotation[Math.floor(+Date.now() / (3600000*24)) % headerRotation.length] || this.header;
this.getLoggerSettings();
},
computed: {
...mapState([
'uwLog',
'showLogger'
]),
},
watch: {
uwLog(newValue, oldValue) {
if (oldValue !== newValue) {
this.$store.dispatch('uw-show-logger');
this.logStringified = JSON.stringify(newValue, null, 2);
}
},
async showLogger(newValue) {
this.showLoggerUi = newValue;
// update logger settings (they could have changed while the popup was closed)
if (newValue) {
this.getLoggerSettings();
}
}
},
methods: {
async getLoggerSettings() {
this.lastSettings = await Logger.getConfig() || {};
this.parsedSettings = JSON.stringify(this.lastSettings, null, 2) || '';
},
updateSettings(val) {
try {
this.parsedSettings = JSON.stringify(JSON.parse(val.target.textContent.trim()), null, 2);
this.lastSettings = JSON.parse(val.target.textContent.trim());
this.confHasError = false;
} catch (e) {
this.confHasError = true;
}
},
restoreLoggerSettings() {
this.getLoggerSettings();
this.confHasError = false;
},
async startLogging(){
this.logStringified = undefined;
await Logger.saveConfig({...this.lastSettings, allowLogging: true});
window.location.reload();
},
hidePopup() {
// this function only works as 'close' if logging has finished
if (this.logStringified) {
Logger.saveConfig({...this.lastSettings, allowLogging: false});
this.logStringified = undefined;
}
this.$store.dispatch('uw-hide-logger');
},
closePopupAndStopLogging() {
Logger.saveConfig({...this.lastSettings, allowLogging: false});
this.logStringified = undefined;
this.$store.dispatch('uw-hide-logger');
},
stopLogging() {
Logger.saveConfig({...this.lastSettings, allowLogging: false});
this.lastSettings.allowLogging = false;
},
exportLog() {
IO.csStringToFile(this.logStringified);
},
exportAndQuit() {
this.exportLog();
this.logStringified = undefined;
this.closePopupAndStopLogging();
}
}
}
</script>
<style lang="scss" scoped>
@import '../res/css/colors.scss';
@import '../res/css/font/overpass.css';
@import '../res/css/font/overpass-mono.css';
@import '../res/css/common.scss';
@import '../res/css/flex.css';
.root-window {
position: fixed !important;
top: 5vh !important;
left: 5vw !important;
width: 90vw !important;
height: 90vh !important;
z-index: 999999 !important;
background-color: rgba( $page-background, 0.9) !important;
color: #f1f1f1 !important;
font-size: 14px !important;
box-sizing: border-box !important;
}
div {
font-family: 'Overpass';
}
h1, h2 {
font-family: 'Overpass Thin';
}
h1 {
font-size: 4em;
}
h2 {
font-size: 2em;
}
.header {
h1 {
margin-bottom: -0.20em;
margin-top: 0.0em;
}
.header-top, .header-bottom {
padding-left: 16px;
padding-right: 16px;
}
.header-top {
background-color: $popup-header-background !important;
}
.header-bottom {
font-size: 1.75em;
}
}
.content {
box-sizing: border-box;
padding: 8px 32px;
width: 100%;
}
.settings-panel {
box-sizing: border-box;
padding-right: 8px;
flex-grow: 2 !important;
min-width: 30% !important;
flex-shrink: 0 !important;
height: inherit !important;
}
.results-panel {
box-sizing: border-box;
padding-left: 8px;
max-width: 70% !important;
flex-grow: 5 !important;
flex-shrink: 0 !important;
height: inherit !important;
}
.scrollable {
overflow: auto;
}
.overflow-hidden {
overflow: hidden;
}
pre {
font-family: 'Overpass Mono';
}
.m-025em {
margin: 0.25em;
}
.p-t-025em {
padding-top: 0.25em;
}
.button {
display: inline-flex;
align-items: center;
justify-items: center;
padding-left: 2em;
padding-right: 2em;
}
.button-primary {
background-color: $primary;
color: #fff;
}
.button-big {
font-size: 1.5em;
padding: 1.75em 3.25em;
}
.button-bar {
font-size: 1.25em;
padding: 0.25em 1.25em;
margin-left: 0.25em;
}
.button-header {
font-size: 2em;
padding-top: 0.1em;
padding-left: 1em;
padding-right: 1em;
}
.jsonbg {
background-color: #131313;
}
.jsonbg-error {
background-color: #884420;
}
</style>

View File

@ -109,7 +109,7 @@ class ActionHandler {
} }
registerHandleMouse(videoData) { registerHandleMouse(videoData) {
this.logger.log('info', ['actionHandler', 'mousemove'], "[ActionHandler::registerHandleMouse] registering handle mouse for videodata:", videoData) this.logger.log('info', ['actionHandler', 'mousemove'], "[ActionHandler::registerHandleMouse] registering handle mouse for videodata:", videoData.id)
var ths = this; var ths = this;
if (videoData.player && videoData.player.element) { if (videoData.player && videoData.player.element) {
@ -136,9 +136,9 @@ class ActionHandler {
preventAction(event) { preventAction(event) {
var activeElement = document.activeElement; var activeElement = document.activeElement;
if(this.logger.canLog('keyboard')) { if (this.logger.canLog('keyboard')) {
this.logger.pause(); // temp disable to avoid recursing; this.logger.pause(); // temp disable to avoid recursing;
const preventAction = this.preventAction(); const preventAction = this.preventAction(event);
this.logger.resume(); // undisable this.logger.resume(); // undisable
this.logger.log('info', 'keyboard', "[ActionHandler::preventAction] Testing whether we're in a textbox or something. Detailed rundown of conditions:\n" + this.logger.log('info', 'keyboard', "[ActionHandler::preventAction] Testing whether we're in a textbox or something. Detailed rundown of conditions:\n" +

View File

@ -1,57 +1,45 @@
import Debug from '../conf/Debug';
import currentBrowser from '../conf/BrowserDetect'; import currentBrowser from '../conf/BrowserDetect';
import { decycle } from 'json-cyclic';
class Logger { class Logger {
constructor(conf) { constructor(options) {
this.initLogger(); this.onLogEndCallbacks = [];
if (conf) {
this.conf = conf;
}
this.history = []; this.history = [];
this.startTime = performance.now(); this.globalHistory = {};
this.temp_disable = false; this.isContentScript = false;
this.isBackgroundScript = true;
this.vuexStore = options?.vuexStore;
} }
initLogger() { static saveConfig(conf) {
const ths = this; if (process.env.CHANNEL === 'dev') {
console.info('Saving logger conf:', conf)
}
if (currentBrowser.firefox || currentBrowser.edge) {
return browser.storage.local.set( {'uwLogger': JSON.stringify(conf)});
} else if (currentBrowser.chrome) {
return chrome.storage.local.set( {'uwLogger': JSON.stringify(conf)});
}
}
static syncConfig(callback) {
const br = currentBrowser.firefox ? browser : chrome; const br = currentBrowser.firefox ? browser : chrome;
br.storage.onChanged.addListener( (changes, area) => { br.storage.onChanged.addListener( (changes, area) => {
if (Debug.debug && Debug.debugStorage) { if (changes.uwLogger) {
console.log("[Logger::<storage/on change>] Settings have been changed outside of here. Updating active settings. Changes:", changes, "storage area:", area); const newLoggerConf = JSON.parse(changes.uwLogger.newValue)
if (changes['uwLogger'] && changes['uwLogger'].newValue) { if (process.env.CHANNEL === 'dev') {
console.log("[Logger::<storage/on change>] new settings object:", JSON.parse(changes.uwLogger.newValue)); console.info('Logger settings reloaded. New conf:', conf);
} }
} callback(newLoggerConf);
if(changes['uwLogger'] && changes['uwLogger'].newValue) {
ths.conf = JSON.parse(changes.uwLogger.newValue);
} }
}); });
} }
async init() { static async getConfig() {
if (!this.conf) {
this.conf = await this.getSaved();
}
}
clear() {
this.log = [];
this.startTime = performance.now();
}
setConf(conf) {
this.conf = conf; // effective immediately
// also persist settings:
if (currentBrowser.firefox || currentBrowser.edge) {
return browser.storage.local.set( {'uwLogger': JSON.stringify(this.conf)});
} else if (currentBrowser.chrome) {
return chrome.storage.local.set( {'uwLogger': JSON.stringify(this.logger)});
}
}
async getSaved() {
let ret; let ret;
if (currentBrowser.firefox) { if (currentBrowser.firefox) {
ret = await browser.storage.local.get('uwLogger'); ret = await browser.storage.local.get('uwLogger');
} else if (currentBrowser.chrome) { } else if (currentBrowser.chrome) {
@ -64,21 +52,84 @@ class Logger {
}); });
} }
if (Debug.debug && Debug.debugStorage) { if (process.env.CHANNEL === 'dev') {
try { try {
console.log("[Logger::getSaved] Got settings:", JSON.parse(ret.uwLogger)); console.info("[Logger::getSaved] Got settings:", JSON.parse(ret.uwLogger));
} catch (e) { } catch (e) {
console.log("[Logger::getSaved] No settings.") console.info("[Logger::getSaved] No settings.")
} }
} }
try { try {
return JSON.parse(ret.uwLogger); return JSON.parse(ret.uwLogger);
} catch(e) { } catch(e) {
return {logToFile: false, logToConsole: false, consoleOptions: {}, fileOptions: {}}; return {consoleOptions: {}, fileOptions: {}};
} }
} }
async init(conf) {
// this is the only property that always gets passed via conf
// and doesn't get ignored even if the rest of the conf gets
// loaded from browser storage
if (conf.isContentScript) {
this.isContentScript = true;
this.isBackgroundScript = false;
} else if (conf.isBackgroundScript) {
this.isContentScript = false;
this.isBackgroundScript = true;
}
if (conf && process.env.CHANNEL === 'dev' && !conf.useConfFromStorage) {
this.conf = conf;
} else {
this.conf = await Logger.getConfig();
}
if (this.conf.consoleOptions === undefined) {
this.conf.consoleOptions = {};
}
if (this.conf.fileOptions === undefined) {
this.conf.fileOptions = {};
}
this.startTime = performance.now();
this.temp_disable = false;
this.stopTime = this.conf.timeout ? performance.now() + (this.conf.timeout * 1000) : undefined;
const br = currentBrowser.firefox ? browser : chrome;
br.storage.onChanged.addListener( (changes, area) => {
if (process.env.CHANNEL === 'dev') {
console.log("[Logger::<storage/on change>] Settings have been changed outside of here. Updating active settings. Changes:", changes, "storage area:", area);
if (changes['uwLogger'] && changes['uwLogger'].newValue) {
console.log("[Logger::<storage/on change>] new settings object:", JSON.parse(changes.uwLogger.newValue));
}
}
if (changes['uwLogger'] && changes['uwLogger'].newValue) {
const newConf = JSON.parse(changes.uwLogger.newValue);
if (this.isContentScript && this.conf.allowLogging && !newConf.allowLogging) {
this.saveToVuex();
}
this.conf = newConf;
}
});
}
clear() {
this.log = [];
this.startTime = performance.now();
this.stopTime = this.conf.timeout ? performance.now() + (this.conf.timeout * 1000) : undefined;
}
setConf(conf) {
this.conf = conf; // effective immediately
// also persist settings:
Logger.saveConfig(conf);
}
async getSaved() {
return Logger.getSaved();
}
// allow syncing of start times between bg and page scripts. // allow syncing of start times between bg and page scripts.
// may result in negative times in the log file, but that doesn't // may result in negative times in the log file, but that doesn't
@ -94,15 +145,21 @@ class Logger {
} }
} }
getLogFileString() { // getLogFileString() {
let logfileStr = ''; // let logfileStr = '';
let logTs = ''; // number of seconds since extension started on a given page¸ // let logTs = ''; // number of seconds since extension started on a given page¸
for (let i = 0; i < this.history.length; i++) { // for (let i = 0; i < this.history.length; i++) {
logTs = ((this.history[i].ts - Math.floor(this.performance.now)) / 3).toFixed(3); // logTs = ((this.history[i].ts - Math.floor(this.performance.now)) / 3).toFixed(3);
logfileStr = `${logfileStr}[@${logTs}] -- ${this.history[i].message}\n` // logfileStr = `${logfileStr}[@${logTs}] -- ${this.history[i].message}\n`
} // }
return logfileStr; // return logfileStr;
// }
getFileLogJSONString() {
return {
site: window && window.location,
log: JSON.toString(this.history),
}
} }
pause() { pause() {
@ -112,8 +169,144 @@ class Logger {
this.temp_disable = false; this.temp_disable = false;
} }
onLogEnd(callback) {
this.onLogEndCallbacks.push(callback);
}
// this should be used mostly in background page instance of logger, btw
//
addToGlobalHistory(key, log) {
this.globalHistory[key] = log;
this.log('info', 'debug', 'Added log for', key, 'to global history. Current history:', this.globalHistory);
}
finish() {
if (!this.isBackgroundScript) {
this.conf.allowLogging = false;
// const logJson = JSON.stringify(decycle(this.history));
// this.log('force', 'debugr', 'Calling all log end callbacks. There\'s this many of them:', 1);
// for(const f of this.onLogEndCallbacks) {
// f(logJson);
// }
// } else {
// this.exportLogToFile();
}
this.saveToVuex();
}
parseStack() {
const trace = (new Error()).stack;
const stackInfo = {};
// we turn our stack into array and remove the "file::line" part of the trace,
// since that is useless because minification/webpack
stackInfo['stack'] = {trace: trace.split('\n').map(a => a.split('@')[0])};
// here's possible sources that led to this log entry
stackInfo['periodicPlayerCheck'] = false;
stackInfo['periodicVideoStyleChangeCheck'] = false;
stackInfo['aard'] = false;
stackInfo['keyboard'] = false;
stackInfo['popup'] = false;
stackInfo['mousemove'] = false;
stackInfo['exitLogs'] = false;
// here we check which source triggered the action. We know that only one of these
// functions will appear in the trace at most once (and if more than one of these
// appears — e.g. frameCheck triggered by user toggling autodetection in popup —
// the most recent one will be the correct one 99% of the time)
for (const line of stackInfo.stack.trace) {
if (line === 'doPeriodicPlayerElementChangeCheck') {
stackInfo['periodicPlayerCheck'] = true;
break;
} else if (line === 'doPeriodicFallbackChangeDetectionCheck') {
stackInfo['periodicVideoStyleChangeCheck'] = true;
break;
} else if (line === 'frameCheck') {
stackInfo['aard'] = true;
break;
} else if (line === 'execAction') {
stackInfo['keyboard'] = true;
break;
} else if (line === 'processReceivedMessage') {
stackInfo['popup'] = true;
break;
} else if (line === 'handleMouseMove') {
stackInfo['mousemove'] = true;
break;
}
}
// exitLog overrides any other exclusions, so we look for it separately.
// we also remove some of the unnecessary messages to reduce log file size
for(let i = 0; i < stackInfo.stack.trace.length; i++) {
if (stackInfo.stack.trace[i] === 'finish') {
stackInfo['exitLogs'] = true;
break;
}
// if we hit one of these, we remove the rest of the array and call it a
// day. Chances are there's nothing of value past this point.
if (stackInfo.stack.trace[i].indexOf('promise callback') !== -1
|| stackInfo.stack.trace[i].indexOf('asyncGeneratorStep') !== -1
|| stackInfo.stack.trace[i].indexOf('_asyncToGenerator') !== -1
|| stackInfo.stack.trace[i].startsWith('_next')) {
stackInfo.stack.trace.splice(i);
break;
}
}
return stackInfo;
}
// test for blacklisted origin
isBlacklistedOrigin(stackInfo) {
if (stackInfo.periodicPlayerCheck) {
return !this.conf.allowBlacklistedOrigins?.periodicPlayerCheck;
}
if (stackInfo.periodicVideoStyleChangeCheck) {
return !this.conf.allowBlacklistedOrigins?.periodicVideoStyleChangeCheck;
}
if (stackInfo.mousemove) {
return !this.conf.allowBlacklistedOrigins?.handleMouseMove;
}
return false;
}
isTimeUp() {
// we don't do timeouts on background script
if (this.isBackgroundScript) {
return false;
}
if (this.stopTime && performance.now() > this.stopTime) {
if (this.conf.allowLogging) {
this.log('force', 'debug', '-----[ alloted time has run out. logging will stop ]-----');
this.finish();
}
return true;
}
return false;
}
isLoggingToFile() {
return this.conf.allowLogging && this.conf.fileOptions?.enabled;
}
// NOTE: THIS FUNCTION IS NEVER USED INTERNALLY!
canLog(component) { canLog(component) {
return this.canLogFile(component) || this.canLogConsole(component); const stackInfo = this.parseStack();
if (!this.conf.allowLogging && !stackInfo.exitLogs) {
return false;
}
if (this.isBlacklistedOrigin(stackInfo)) {
return false;
}
// if either of these two is true, we allow logging to happen (forbidden origins were checked above)
return (this.canLogFile(component) || this.canLogConsole(component) || stackInfo.exitLogs);
} }
canLogFile(component) { canLogFile(component) {
@ -130,8 +323,9 @@ class Logger {
return this.conf.fileOptions[component]; return this.conf.fileOptions[component];
} }
} }
canLogConsole(component) {
if (!this.conf.consoleOptions.enabled || this.temp_disable) { canLogConsole(component, stackInfo) {
if (!this.conf.consoleOptions?.enabled || this.temp_disable) {
return false; return false;
} }
if (Array.isArray(component) && component.length) { if (Array.isArray(component) && component.length) {
@ -141,36 +335,77 @@ class Logger {
} }
} }
} else { } else {
return this.conf.consoleOptions[component]; return this.conf.consoleOptions[component] !== undefined ? this.conf.consoleOptions[component] : this.conf.logAll;
}
return this.conf.logAll;
}
logToFile(message, stackInfo) {
let ts = performance.now();
if (ts <= this.history[this.history.length - 1]) {
ts = this.history[this.history.length - 1] + 0.00001;
}
this.history.push({
ts: ts,
message: message,
stack: stackInfo,
});
}
logToConsole(message, stackInfo) {
try {
console.log(...message, {stack: stackInfo});
} catch (e) {
console.error("Message too big to log. Error:", e, "stackinfo:", stackInfo);
} }
} }
// level is unused as of now, but this may change in the future // level is unused as of now, but this may change in the future
// levels: 'info', 'warn', 'error' // levels: 'info', 'warn', 'error'.
// if level is `true` (bool), logging happens regardless of any other
// settings
log(level, component, ...message) { log(level, component, ...message) {
if (!this.conf) { const stackInfo = this.parseStack();
if (!this.conf || (!this.conf.allowLogging && !stackInfo.exitLogs)) {
return; return;
} }
if (this.conf.logToFile) {
if (this.canLogFile(component)) {
let ts = performance.now();
if (ts <= this.history[this.history.length - 1]) {
ts = this.history[this.history.length - 1] + 0.00001;
}
this.history.push({ // skip all checks if we force log
ts: ts, if (level === 'force') {
message: JSON.stringify(message), if (this.conf.fileOptions?.enabled) {
}) this.logToFile(message, stackInfo);
}
if (this.conf.consoleOptions?.enabled) {
this.logToConsole(message, stackInfo);
}
return; // don't check further — recursion-land ahead!
}
if (this.isTimeUp() && !stackInfo.exitLogs) {
return;
}
// don't log stuff from blacklisted origin (unless logger conf says otherwise)
if (this.isBlacklistedOrigin(stackInfo)) {
return;
}
if (this.conf.fileOptions?.enabled) {
if (this.canLogFile(component) || stackInfo.exitLogs) {
this.logToFile(message, stackInfo);
} }
} }
if (this.conf.logToConsole) { if (this.conf.consoleOptions?.enabled) {
if (this.canLogConsole(component)) { if (this.canLogConsole(component) || stackInfo.exitLogs) {
console.log(...message); this.logToConsole(message, stackInfo);
} }
} }
} }
// leaves a noticeable mark in the file log at the time it got triggered, as well as // leaves a noticeable mark in the file log at the time it got triggered, as well as
// at the intervals of 1s and .5s before the trigger moment // at the intervals of 1s and .5s before the trigger moment
cahen() { cahen() {
@ -207,7 +442,56 @@ class Logger {
} }
} }
addLogFromPage(host, tabId, frameId, pageHistory) {
if (! this.globalHistory[host]) {
this.globalHistory[host] = {};
}
if (! this.globalHistory[tabId || 'tab']) {
this.globalHistory[host][tabId || 'tab'] = {};
}
if (!this.globalHistory[frameId || 'top']) {
this.globalHistory[host][tabId || 'tab'][frameId || 'top'] = pageHistory;
} else {
this.globalHistory[host][tabId || 'tab'][frameId || 'top'].push(...pageHistory);
}
}
saveToVuex() {
console.info('[info] will attempt to save to vuex store.');
if (!this.conf?.fileOptions?.enabled || this.isBackgroundScript) {
console.info('[info] Logging to file is either disabled or we\'re not on the content script. Not saving.');
return;
}
if (!this.vuexStore) {
console.error("[info] No vue store. Log will not be exported.");
return;
}
console.info('[info] vuex store present. Parsing logs.');
let exportObject;
try {
exportObject = {
pageLogs: decycle(this.history),
backgroundLogs: decycle(this.globalHistory),
loggerFileOptions: this.conf.fileOptions,
}
} catch (e) {
console.error("[fail] error parsing logs!", e)
return;
}
console.info('[info] Logs were parsed successfuly. Putting stuff to vuex ...');
try {
this.vuexStore.dispatch('uw-set-log', exportObject);
} catch (e) {
console.log("[fail] error saving to vuex", e);
return;
}
console.info('[info] Export object saved to vuex store.')
}
} }
export default Logger; export default Logger;

View File

@ -35,6 +35,9 @@ class Settings {
} }
storageChangeListener(changes, area) { storageChangeListener(changes, area) {
if (!changes.uwSettings) {
return;
}
this.logger.log('info', 'settings', "[Settings::<storage/on change>] Settings have been changed outside of here. Updating active settings. Changes:", changes, "storage area:", area); this.logger.log('info', 'settings', "[Settings::<storage/on change>] Settings have been changed outside of here. Updating active settings. Changes:", changes, "storage area:", area);
if (changes['uwSettings'] && changes['uwSettings'].newValue) { if (changes['uwSettings'] && changes['uwSettings'].newValue) {
this.logger.log('info', 'settings',"[Settings::<storage/on change>] new settings object:", JSON.parse(changes.uwSettings.newValue)); this.logger.log('info', 'settings',"[Settings::<storage/on change>] new settings object:", JSON.parse(changes.uwSettings.newValue));
@ -555,7 +558,7 @@ class Settings {
} }
getDefaultStretchMode(site) { getDefaultStretchMode(site) {
if (site && this.active.sites[site] && this.active.sites[site].stretch !== Stretch.Default) { if (site && this.active.sites[site]?.stretch !== Stretch.Default) {
return this.active.sites[site].stretch; return this.active.sites[site].stretch;
} }
@ -563,7 +566,7 @@ class Settings {
} }
getDefaultCropPersistenceMode(site) { getDefaultCropPersistenceMode(site) {
if (site && this.active.sites[site] && this.active.sites[site].cropModePersistence !== Stretch.Default) { if (site && this.active.sites[site]?.cropModePersistence !== Stretch.Default) {
return this.active.sites[site].cropModePersistence; return this.active.sites[site].cropModePersistence;
} }
@ -572,7 +575,7 @@ class Settings {
} }
getDefaultVideoAlignment(site) { getDefaultVideoAlignment(site) {
if (site && this.active.sites[site] && this.active.sites[site].videoAlignment !== VideoAlignment.Default) { if (this.active.sites[site]?.videoAlignment !== VideoAlignment.Default) {
return this.active.sites[site].videoAlignment; return this.active.sites[site].videoAlignment;
} }

View File

@ -5,7 +5,7 @@ class Comms {
static async sendMessage(message){ static async sendMessage(message){
if(BrowserDetect.firefox){ if(BrowserDetect.firefox){
return browser.runtime.sendMessage(message) return browser.runtime.sendMessage(message);
} else { } else {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try{ try{

View File

@ -4,6 +4,7 @@ import BrowserDetect from '../../conf/BrowserDetect';
class CommsClient { class CommsClient {
constructor(name, settings, logger) { constructor(name, settings, logger) {
this.logger = logger; this.logger = logger;
if (BrowserDetect.firefox) { if (BrowserDetect.firefox) {
this.port = browser.runtime.connect({name: name}); this.port = browser.runtime.connect({name: name});
} else if (BrowserDetect.chrome) { } else if (BrowserDetect.chrome) {
@ -12,6 +13,17 @@ class CommsClient {
this.port = browser.runtime.connect({name: name}) this.port = browser.runtime.connect({name: name})
} }
this.logger.onLogEnd(
(history) => {
this.logger.log('info', 'comms', 'Sending logging-stop-and-save to background script ...');
try {
this.port.postMessage({cmd: 'logging-stop-and-save', host: window.location.host, history})
} catch (e) {
this.logger.log('error', 'comms', 'Failed to send message to background script. Error:', e);
}
}
);
var ths = this; var ths = this;
this._listener = m => ths.processReceivedMessage(m); this._listener = m => ths.processReceivedMessage(m);
this.port.onMessage.addListener(this._listener); this.port.onMessage.addListener(this._listener);
@ -19,6 +31,34 @@ class CommsClient {
this.settings = settings; this.settings = settings;
this.pageInfo = undefined; this.pageInfo = undefined;
this.commsId = (Math.random() * 20).toFixed(0); this.commsId = (Math.random() * 20).toFixed(0);
this.commands = {
'get-current-zoom': [() => this.pageInfo.requestCurrentZoom()],
'set-ar': [(message) => this.pageInfo.setAr({type: message.arg, ratio: message.customArg}, message.playing)],
'set-alignment': [(message) => {
this.pageInfo.setVideoAlignment(message.arg, message.playing);
this.pageInfo.restoreAr();
}],
'set-stretch': [(message) => this.pageInfo.setStretchMode(message.arg, message.playing, message.customArg)],
'set-keyboard': [(message) => this.pageInfo.setKeyboardShortcutsEnabled(message.arg)],
'autoar-start': [(message) => {
if (message.enabled !== false) {
this.pageInfo.initArDetection(message.playing);
this.pageInfo.startArDetection(message.playing);
} else {
this.pageInfo.stopArDetection(message.playing);
}
}],
'pause-processing': [(message) => this.pageInfo.pauseProcessing(message.playing)],
'resume-processing': [(message) => this.pageInfo.resumeProcessing(message.autoArStatus, message.playing)],
'set-zoom': [(message) => this.pageInfo.setZoom(message.arg, true, message.playing)],
'change-zoom': [(message) => this.pageInfo.zoomStep(message.arg, message.playing)],
'mark-player': [(message) => this.pageInfo.markPlayer(message.name, message.color)],
'unmark-player': [() => this.pageInfo.unmarkPlayer()],
'autoar-set-manual-tick': [(message) => this.pageInfo.setManualTick(message.arg)],
'autoar-tick': [() => this.pageInfo.tick()],
'set-ar-persistence': [() => this.pageInfo.setArPersistence(message.arg)],
};
} }
destroy() { destroy() {
@ -29,11 +69,19 @@ class CommsClient {
} }
} }
subscribe(command, callback) {
if (!this.commands[command]) {
this.commands[command] = [callback];
} else {
this.commands[command].push(callback);
}
}
setPageInfo(pageInfo){ setPageInfo(pageInfo){
this.pageInfo = pageInfo; this.pageInfo = pageInfo;
this.logger.log('info', 'debug', `[CommsClient::setPageInfo] <${this.commsId}>`, "SETTING PAGEINFO —", this.pageInfo, this) this.logger.log('info', 'debug', `[CommsClient::setPageInfo] <${this.commsId}>`, "setting pageinfo");
var ths = this; var ths = this;
this._listener = m => ths.processReceivedMessage(m); this._listener = m => ths.processReceivedMessage(m);
@ -55,45 +103,10 @@ class CommsClient {
return; return;
} }
if (message.cmd === 'get-current-zoom') { if (this.commands[message.cmd]) {
this.pageInfo.requestCurrentZoom(); for (const c of this.commands[message.cmd]) {
} c(message);
if (message.cmd === "set-ar") {
this.pageInfo.setAr({type: message.arg, ratio: message.customArg}, message.playing);
} else if (message.cmd === 'set-alignment') {
this.pageInfo.setVideoAlignment(message.arg, message.playing);
this.pageInfo.restoreAr();
} else if (message.cmd === "set-stretch") {
this.pageInfo.setStretchMode(message.arg, message.playing, message.customArg);
} else if (message.cmd === 'set-keyboard') {
this.pageInfo.setKeyboardShortcutsEnabled(message.arg)
} else if (message.cmd === "autoar-start") {
if (message.enabled !== false) {
this.pageInfo.initArDetection(message.playing);
this.pageInfo.startArDetection(message.playing);
} else {
this.pageInfo.stopArDetection(message.playing);
} }
} else if (message.cmd === "pause-processing") {
this.pageInfo.pauseProcessing(message.playing);
} else if (message.cmd === "resume-processing") {
// todo: autoArStatus
this.pageInfo.resumeProcessing(message.autoArStatus, message.playing);
} else if (message.cmd === 'set-zoom') {
this.pageInfo.setZoom(message.arg, true, message.playing);
} else if (message.cmd === 'change-zoom') {
this.pageInfo.zoomStep(message.arg, message.playing);
} else if (message.cmd === 'mark-player') {
this.pageInfo.markPlayer(message.name, message.color);
} else if (message.cmd === 'unmark-player') {
this.pageInfo.unmarkPlayer();
} else if (message.cmd === 'autoar-set-manual-tick') {
this.pageInfo.setManualTick(message.arg);
} else if (message.cmd === 'autoar-tick') {
this.pageInfo.tick();
} else if (message.cmd === 'set-ar-persistence') {
this.pageInfo.setArPersistence(message.arg);
} }
} }
@ -175,6 +188,7 @@ class CommsClient {
this.registerVideo() this.registerVideo()
} }
} }
export default CommsClient; export default CommsClient;

View File

@ -7,6 +7,7 @@ class CommsServer {
this.logger = server.logger; this.logger = server.logger;
this.settings = server.settings; this.settings = server.settings;
this.ports = []; this.ports = [];
this.popupPort = null;
var ths = this; var ths = this;
@ -17,6 +18,122 @@ class CommsServer {
chrome.runtime.onConnect.addListener(p => ths.onConnect(p)); chrome.runtime.onConnect.addListener(p => ths.onConnect(p));
chrome.runtime.onMessage.addListener((m, sender, callback) => ths.processReceivedMessage_nonpersistent(m, sender, callback)); chrome.runtime.onMessage.addListener((m, sender, callback) => ths.processReceivedMessage_nonpersistent(m, sender, callback));
} }
// commands — functions that handle incoming messages
// functions can have the following arguments, which are,
// in this order:
// message — the message we received
// port|sender — on persistent channels, second argument is port on which the server
// listens. If the message was sent in non-persistent way, this is the
// sender script/frame/whatever of the message
// sendResponse — callback function on messages received via non-persistent channel
this.commands = {
'announce-zoom': [
(message) => {
try {
// forward message to the popup
this.popupPort.postMessage({cmd: 'set-current-zoom', zoom: message.zoom});
} catch (e) {
// if popup is closed, this will/may fail. This is okay, so we just ignore this error
}
},
],
'get-current-zoom': [
(message) => this.sendToActive(message),
],
'get-current-site': [
async (message, port) => {
port.postMessage({
cmd: 'set-current-site',
site: await this.server.getVideoTab(),
tabHostname: await this.getCurrentTabHostname()
});
},
],
'popup-set-selected-tab': [
(message) => this.server.setSelectedTab(message.selectedMenu, message.selectedSubitem),
],
'get-config': [
(message, port) => {
this.logger.log('info', 'comms', "CommsServer: received get-config. Active settings?", this.settings.active, "\n(settings:", this.settings, ")");
port.postMessage(
{cmd: "set-config", conf: this.settings.active, site: this.server.currentSite}
);
},
],
'has-video': [
(message, port) => this.server.registerVideo(port.sender),
],
'noVideo': [
(message, port) => this.server.unregisterVideo(port.sender),
],
'inject-css': [
(message, sender) => this.server.injectCss(message.cssString, sender),
],
'eject-css': [
(message, sender) => this.server.removeCss(message.cssString, sender),
],
'replace-css': [
(message, sender) => this.server.replaceCss(message.oldCssString, message.newCssString, sender),
],
'get-config': [
(message, sender, sendResponse) => {
if (BrowserDetect.firefox) {
var ret = {extensionConf: JSON.stringify(this.settings.active)};
this.logger.log('info', 'comms', "%c[CommsServer.js::processMessage_nonpersistent] Returning this:", "background-color: #11D; color: #aad", ret);
Promise.resolve(ret);
} else {
sendResponse({extensionConf: JSON.stringify(this.settings.active)});
return true;
}
}
],
'autoar-enable': [
() => {
this.settings.active.sites['@global'].autoar = "blacklist";
this.settings.save();
this.sendToAll({cmd: "reload-settings", sender: "uwbg"})
this.logger.log('info', 'comms', "[uw-bg] autoar set to enabled (blacklist). evidenz:", this.settings.active);
}
],
'autoar-disable': [
(message) => {
this.settings.active.sites['@global'].autoar = "disabled";
if (message.reason){
this.settings.active.arDetect.disabledReason = message.reason;
} else {
this.settings.active.arDetect.disabledReason = 'User disabled';
}
this.settings.save();
this.sendToAll({cmd: 'reload-settings', newConf: this.settings.active});
this.logger.log('info', 'comms', "[uw-bg] autoar set to disabled. evidenz:", this.settings.active);
}
],
'autoar-set-interval': [
(message) => {
this.logger.log('info', 'comms', `[uw-bg] trying to set new interval for autoAr. New interval is, ${message.timeout} ms`);
// set fairly liberal limit
var timeout = message.timeout < 4 ? 4 : message.timeout;
this.settings.active.arDetect.timer_playing = timeout;
this.settings.save();
this.sendToAll({cmd: 'reload-settings', newConf: this.settings.active});
}
],
'logging-stop-and-save': [ // TODO: possibly never used/superseded — check
(message, sender) => {
this.logger.log('info', 'comms', "Received command to stop logging and export the received input");
this.logger.addToGlobalHistory(`${message.host}::${sender?.tab?.id ?? '×'}-${sender.frameId ?? '×'}`, JSON.parse(message.history));
this.logger.finish();
}
],
'logging-save': [
(message, sender) => {
this.logger.log('info', 'comms', `Received command to save log for site ${message.host} (tabId ${sender.tab.id}, frameId ${sender.frameId}`);
this.logger.addToGlobalHistory(`${message?.host}::${sender?.tab?.id ?? '×'}-${sender?.frameId ?? '×'}`, JSON.parse(message.history));
}
]
}
} }
async getCurrentTabHostname() { async getCurrentTabHostname() {
@ -60,7 +177,7 @@ class CommsServer {
} }
async sendToFrame(message, tab, frame) { async sendToFrame(message, tab, frame) {
this.logger.log('info', 'CommsServer', `%c[CommsServer::sendToFrame] attempting to send message to tab ${tab}, frame ${frame}`, "background: #dda; color: #11D", message); this.logger.log('info', 'comms', `%c[CommsServer::sendToFrame] attempting to send message to tab ${tab}, frame ${frame}`, "background: #dda; color: #11D", message);
if (isNaN(tab)) { if (isNaN(tab)) {
if (tab === '__playing') { if (tab === '__playing') {
@ -74,23 +191,23 @@ class CommsServer {
[tab, frame] = tab.split('-') [tab, frame] = tab.split('-')
} }
this.logger.log('info', 'CommsServer', `%c[CommsServer::sendToFrame] attempting to send message to tab ${tab}, frame ${frame}`, "background: #dda; color: #11D", message); this.logger.log('info', 'comms', `%c[CommsServer::sendToFrame] attempting to send message to tab ${tab}, frame ${frame}`, "background: #dda; color: #11D", message);
try { try {
this.ports[tab][frame].postMessage(message); this.ports[tab][frame].postMessage(message);
} catch (e) { } catch (e) {
this.logger.log('error', 'CommsServer', `%c[CommsServer::sendToFrame] Sending message failed. Reason:`, "background: #dda; color: #11D", e); this.logger.log('error', 'comms', `%c[CommsServer::sendToFrame] Sending message failed. Reason:`, "background: #dda; color: #11D", e);
} }
} }
async sendToActive(message) { async sendToActive(message) {
this.logger.log('info', 'CommsServer', "%c[CommsServer::sendToActive] trying to send a message to active tab. Message:", "background: #dda; color: #11D", message); this.logger.log('info', 'comms', "%c[CommsServer::sendToActive] trying to send a message to active tab. Message:", "background: #dda; color: #11D", message);
var tabs = await this._getActiveTab(); var tabs = await this._getActiveTab();
this.logger.log('info', 'CommsServer', "[CommsServer::_sendToActive] currently active tab(s)?", tabs); this.logger.log('info', 'comms', "[CommsServer::_sendToActive] currently active tab(s)?", tabs);
for (var key in this.ports[tabs[0].id]) { for (var key in this.ports[tabs[0].id]) {
this.logger.log('info', 'CommsServer', "key?", key, this.ports[tabs[0].id]); this.logger.log('info', 'comms', "key?", key, this.ports[tabs[0].id]);
} }
for (var key in this.ports[tabs[0].id]) { for (var key in this.ports[tabs[0].id]) {
@ -123,114 +240,49 @@ class CommsServer {
}); });
} }
async processReceivedMessage(message, port){
this.logger.log('info', 'CommsServer', "[CommsServer.js::processReceivedMessage] Received message from popup/content script!", message, "port", port, "\nsettings and server:", this.settings,this.server);
execCmd(message, portOrSender, sendResponse) {
this.logger.log(
'info', 'comms', '[CommsServer.js::execCmd] Received message', message,
". Port/sender:", portOrSender, "sendResponse:", sendResponse, "\nThere is ", this.commands[message.cmd]?.length ?? 0,
" command(s) for action", message.cmd
);
for (const c of this.commands[message.cmd]) {
c(message, portOrSender, sendResponse);
}
}
handleMessage(message, portOrSender, sendResponse) {
if (message.forwardToContentScript) { if (message.forwardToContentScript) {
this.logger.log('info', 'CommsServer', "[CommsServer.js::processReceivedMessage] Message has 'forward to content script' flag set. Forwarding message as is. Message:", message); this.logger.log('info', 'comms', "[CommsServer.js::processReceivedMessage] Message has 'forward to content script' flag set. Forwarding message as is. Message:", message);
this.sendToFrame(message, message.targetTab, message.targetFrame); this.sendToFrame(message, message.targetTab, message.targetFrame);
return;
} }
if (message.forwardToAll) { if (message.forwardToAll) {
this.logger.log('info', 'CommsServer', "[CommsServer.js::processReceivedMessage] Message has 'forward to all' flag set. Forwarding message as is. Message:", message); this.logger.log('info', 'comms', "[CommsServer.js::processReceivedMessage] Message has 'forward to all' flag set. Forwarding message as is. Message:", message);
this.sendToAll(message); this.sendToAll(message);
return;
} }
if (message.forwardToActive) { if (message.forwardToActive) {
this.logger.log('info', 'CommsServer', "[CommsServer.js::processReceivedMessage] Message has 'forward to active' flag set. Forwarding message as is. Message:", message); this.logger.log('info', 'comms', "[CommsServer.js::processReceivedMessage] Message has 'forward to active' flag set. Forwarding message as is. Message:", message);
this.sendToActive(message)
}
if (message.cmd === 'announce-zoom') {
// forward off to the popup, no use for this here
try {
this.popupPort.postMessage({cmd: 'set-current-zoom', zoom: message.zoom});
} catch (e) {
// can't forward stuff to popup if it isn't open
}
} else if (message.cmd === 'get-current-zoom') {
this.sendToActive(message); this.sendToActive(message);
return;
} }
if (message.cmd === 'get-current-site') { this.execCmd(message, portOrSender, sendResponse);
port.postMessage({ }
cmd: 'set-current-site',
site: this.server.getVideoTab(),
tabHostname: await this.getCurrentTabHostname()
});
}
if (message.cmd === 'popup-set-selected-tab') {
this.server.setSelectedTab(message.selectedMenu, message.selectedSubitem);
}
if (message.cmd === 'get-config') { async processReceivedMessage(message, port){
this.logger.log('info', 'CommsServer', "CommsServer: received get-config. Active settings?", this.settings.active, "\n(settings:", this.settings, ")"); this.logger.log('info', 'comms', "[CommsServer.js::processReceivedMessage] Received message from popup/content script!", message, "port", port);
port.postMessage(
{cmd: "set-config", conf: this.settings.active, site: this.server.currentSite} this.handleMessage(message, port)
);
} else if (message.cmd === 'has-video') {
this.server.registerVideo(port.sender);
} else if (message.cmd === 'noVideo') {
this.server.unregisterVideo(port.sender);
}
} }
processReceivedMessage_nonpersistent(message, sender, sendResponse){ processReceivedMessage_nonpersistent(message, sender, sendResponse){
this.logger.log('info', 'CommsServer', "%c[CommsServer.js::processMessage_nonpersistent] Received message from background script!", "background-color: #11D; color: #aad", message, sender); this.logger.log('info', 'comms', "%c[CommsServer.js::processMessage_nonpersistent] Received message from background script!", "background-color: #11D; color: #aad", message, sender);
if (message.cmd === 'inject-css') { this.handleMessage(message, sender, sendResponse);
this.server.injectCss(message.cssString, sender);
return;
}
if (message.cmd === 'remove-css' || message.cmd === 'eject-css') {
this.server.removeCss(message.cssString, sender);
return;
}
if (message.cmd === 'replace-css') {
this.server.replaceCss(message.oldCssString, message.newCssString, sender);
}
if (message.forwardToContentScript) {
this.logger.log('info', 'CommsServer', "[CommsServer.js::processMessage_nonpersistent] Message has 'forward to content script' flag set. Forwarding message as is. Message:", message);
this.logger.log('info', 'CommsServer', "[CommsServer.js::processMessage_nonpersistent] (btw we probably shouldn't be seeing this. This should prolly happen in persistent connection?");
this.sendToFrame(message, message.targetFrame);
}
if (message.cmd === 'get-config') {
if (BrowserDetect.firefox) {
var ret = {extensionConf: JSON.stringify(this.settings.active)};
this.logger.log('info', 'CommsServer', "%c[CommsServer.js::processMessage_nonpersistent] Returning this:", "background-color: #11D; color: #aad", ret);
Promise.resolve(ret);
} else {
sendResponse({extensionConf: JSON.stringify(this.settings.active)});
return true;
}
} else if (message.cmd === "autoar-enable") {
this.settings.active.sites['@global'].autoar = "blacklist";
this.settings.save();
this.sendToAll({cmd: "reload-settings", sender: "uwbg"})
this.logger.log('info', 'CommsServer', "[uw-bg] autoar set to enabled (blacklist). evidenz:", this.settings.active);
} else if (message.cmd === "autoar-disable") {
this.settings.active.sites['@global'].autoar = "disabled";
if(message.reason){
this.settings.active.arDetect.disabledReason = message.reason;
} else {
this.settings.active.arDetect.disabledReason = 'User disabled';
}
this.settings.save();
this.sendToAll({cmd: 'reload-settings', newConf: this.settings.active});
this.logger.log('info', 'CommsServer', "[uw-bg] autoar set to disabled. evidenz:", this.settings.active);
} else if (message.cmd === "autoar-set-interval") {
this.logger.log('info', 'CommsServer', `[uw-bg] trying to set new interval for autoAr. New interval is, ${message.timeout} ms`);
// set fairly liberal limit
var timeout = message.timeout < 4 ? 4 : message.timeout;
this.settings.active.arDetect.timer_playing = timeout;
this.settings.save();
this.sendToAll({cmd: 'reload-settings', newConf: this.settings.active});
}
} }
} }
export default CommsServer; export default CommsServer;

View File

@ -99,7 +99,7 @@ class PageInfo {
playerStyleString = this.settings.active.sites[window.location.host].css; playerStyleString = this.settings.active.sites[window.location.host].css;
if (playerStyleString) { if (playerStyleString) {
this.comms.sendMessage({ this.comms.sendMessage({
cmd: 'remove-css', cmd: 'eject-css',
cssString: playerStyleString cssString: playerStyleString
}); });
} }
@ -132,11 +132,8 @@ class PageInfo {
} }
getVideos(host) { getVideos(host) {
if (this.settings.active.sites[host] if (this.settings.active.sites[host]?.DOM?.video?.manual
&& this.settings.active.sites[host].DOM && this.settings.active.sites[host]?.DOM?.video?.querySelector){
&& this.settings.active.sites[host].DOM.video
&& this.settings.active.sites[host].DOM.video.manual
&& this.settings.active.sites[host].DOM.video.querySelector){
const videos = document.querySelectorAll(this.settings.active.sites[host].DOM.video.querySelector); const videos = document.querySelectorAll(this.settings.active.sites[host].DOM.video.querySelector);
if (videos.length) { if (videos.length) {

View File

@ -127,18 +127,21 @@ class PlayerData {
while (!this.halted) { while (!this.halted) {
await this.sleep(1000); await this.sleep(1000);
try { try {
if (this.periodicallyRefreshPlayerElement) { this.doPeriodicPlayerElementChangeCheck();
this.forceRefreshPlayerElement();
}
if (this.checkPlayerSizeChange()) {
this.videoData.resizer.restore();
}
} 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 shouldnt see', e);
} }
} }
} }
doPeriodicPlayerElementChangeCheck() {
if (this.periodicallyRefreshPlayerElement) {
if (this.forceDetectPlayerElementChange()) {
this.videoData.resizer.restore();
}
}
}
stopChangeDetection(){ stopChangeDetection(){
this.observer.disconnect(); this.observer.disconnect();
} }
@ -215,7 +218,8 @@ class PlayerData {
getPlayer() { getPlayer() {
const host = window.location.host; const host = window.location.host;
let element = this.video.parentNode; let element = this.video.parentNode;
const videoWidth = this.video.offsetWidth, videoHeight = this.video.offsetHeight; const videoWidth = this.video.offsetWidth;
const videoHeight = this.video.offsetHeight;
const elementQ = []; const elementQ = [];
let scorePenalty = 0; let scorePenalty = 0;
let score; let score;
@ -231,12 +235,21 @@ class PlayerData {
return; return;
} }
if (this.settings.active.sites[host] // log the entire hierarchy from <video> to root
&& this.settings.active.sites[host].DOM if (this.logger.canLog('playerDetect')) {
&& this.settings.active.sites[host].DOM.player const logObj = [];
&& this.settings.active.sites[host].DOM.player.manual) { logObj.push(`window size: ${window.innerWidth} x ${window.innerHeight}`);
if (this.settings.active.sites[host].DOM.player.useRelativeAncestor let e = element;
&& this.settings.active.sites[host].DOM.player.videoAncestor) { while (e) {
logObj.push({offsetSize: {width: e.offsetWidth, height: e.offsetHeight}, clientSize: {width: e.clientWidth, height: e.clientHeight}, element: e});
e = e.parentNode;
}
this.logger.log('info', 'playerDetect', "\n\n[PlayerDetect::getPlayer()] element hierarchy (video->root)", logObj);
}
if (this.settings.active.sites[host]?.DOM?.player?.manual) {
if (this.settings.active.sites[host]?.DOM?.player?.useRelativeAncestor
&& this.settings.active.sites[host]?.DOM?.player?.videoAncestor) {
let parentsLeft = this.settings.active.sites[host].DOM.player.videoAncestor - 1; let parentsLeft = this.settings.active.sites[host].DOM.player.videoAncestor - 1;
while (parentsLeft --> 0) { while (parentsLeft --> 0) {
@ -246,7 +259,7 @@ class PlayerData {
this.updatePlayerDimensions(element); this.updatePlayerDimensions(element);
return element; return element;
} }
} else if (this.settings.active.sites[host].DOM.player.querySelectors) { } else if (this.settings.active.sites[host]?.DOM?.player?.querySelectors) {
const allSelectors = document.querySelectorAll(this.settings.active.sites[host].DOM.player.querySelectors); const allSelectors = document.querySelectorAll(this.settings.active.sites[host].DOM.player.querySelectors);
// actually we'll also score this branch in a similar way we score the regular, auto branch // actually we'll also score this branch in a similar way we score the regular, auto branch
while (element) { while (element) {
@ -274,6 +287,9 @@ class PlayerData {
element = element.parentNode; element = element.parentNode;
} }
// log player candidates
this.logger.log('info', 'playerDetect', 'player detect via query selector: element queue and final element:', {queue: elementQ, bestCandidate: elementQ.length ? elementQ.sort( (a,b) => b.score - a.score)[0].element : 'n/a'});
if (elementQ.length) { if (elementQ.length) {
// return element with biggest score // return element with biggest score
// if video player has not been found, proceed to automatic detection // if video player has not been found, proceed to automatic detection
@ -331,9 +347,13 @@ class PlayerData {
element = element.parentNode; element = element.parentNode;
} }
// log player candidates
this.logger.log('info', 'playerDetect', 'player detect, auto/fallback: element queue and final element:', {queue: elementQ, bestCandidate: elementQ.length ? elementQ.sort( (a,b) => b.score - a.score)[0].element : 'n/a'});
if (elementQ.length) { if (elementQ.length) {
// return element with biggest score // return element with biggest score
const playerElement = elementQ.sort( (a,b) => b.score - a.score)[0].element; const playerElement = elementQ.sort( (a,b) => b.score - a.score)[0].element;
this.updatePlayerDimensions(playerElement); this.updatePlayerDimensions(playerElement);
return playerElement; return playerElement;
} }
@ -352,6 +372,20 @@ class PlayerData {
return a > b - tolerance && a < b + tolerance; return a > b - tolerance && a < b + tolerance;
} }
forceDetectPlayerElementChange() {
// save current dimensions before refreshing the player object
const oldDimensions = this.dimensions;
this.getPlayer();
// compare new player object dimensions with the old dimensions
// don't fucking trigger changes if nothing changed
if (this.dimensions.width === this.dimensions.width && this.dimensions.height === this.dimensions.height) {
return false;
} else {
return true;
}
}
forceRefreshPlayerElement() { forceRefreshPlayerElement() {
this.getPlayer(); this.getPlayer();
} }
@ -360,9 +394,7 @@ class PlayerData {
// this 'if' is just here for debugging — real code starts later. It's safe to collapse and // this 'if' is just here for debugging — real code starts later. It's safe to collapse and
// ignore the contents of this if (unless we need to change how logging works) // ignore the contents of this if (unless we need to change how logging works)
if (this.logger.canLog('debug')){ if (this.logger.canLog('debug')){
if (!this.dimensions) { if (this.dimensions?.fullscreen){
} else if (this.dimensions && this.dimensions.fullscreen){
if(! PlayerData.isFullScreen()){ if(! PlayerData.isFullScreen()){
this.logger.log('info', 'debug', "[PlayerDetect] player size changed. reason: exited fullscreen"); this.logger.log('info', 'debug', "[PlayerDetect] player size changed. reason: exited fullscreen");
} }
@ -371,19 +403,17 @@ class PlayerData {
this.logger.log('info', 'playerDetect', "[PlayerDetect] player element isn't defined"); this.logger.log('info', 'playerDetect', "[PlayerDetect] player element isn't defined");
} }
if ( this.element && this.dimensions && if ( this.element &&
( this.dimensions.width != this.element.offsetWidth || ( +this.dimensions?.width != +this.element?.offsetWidth ||
this.dimensions.height != this.element.offsetHeight ) +this.dimensions?.height != +this.element?.offsetHeight )
) { ) {
this.logger.log('info', 'debug', "[PlayerDetect] player size changed. reason: dimension change. Old dimensions?", this.dimensions.width, this.dimensions.height, "new dimensions:", this.element.offsetWidth, this.element.offsetHeight); this.logger.log('info', 'debug', "[PlayerDetect] player size changed. reason: dimension change. Old dimensions?", this.dimensions?.width, this.dimensions?.height, "new dimensions:", this.element?.offsetWidth, this.element?.offsetHeight);
} }
} }
// if size doesn't match, update & return true // if size doesn't match, update & return true
if (!this.dimensions if (this.dimensions?.width != this.element.offsetWidth
|| this.dimensions.width != this.element.offsetWidth || this.dimensions?.height != this.element.offsetHeight ){
|| this.dimensions.height != this.element.offsetHeight ){
const isFullScreen = PlayerData.isFullScreen(); const isFullScreen = PlayerData.isFullScreen();

View File

@ -71,10 +71,14 @@ class VideoData {
async fallbackChangeDetection() { async fallbackChangeDetection() {
while (!this.destroyed && !this.invalid) { while (!this.destroyed && !this.invalid) {
await this.sleep(500); await this.sleep(500);
this.validateVideoOffsets(); this.doPeriodicFallbackChangeDetectionCheck();
} }
} }
doPeriodicFallbackChangeDetectionCheck() {
this.validateVideoOffsets();
}
async sleep(timeout) { async sleep(timeout) {
return new Promise( (resolve, reject) => setTimeout(() => resolve(), timeout)); return new Promise( (resolve, reject) => setTimeout(() => resolve(), timeout));
} }
@ -154,8 +158,12 @@ class VideoData {
&& this.isWithin(vh, (ph - (translateY * 2)), 2) && this.isWithin(vh, (ph - (translateY * 2)), 2)
&& this.isWithin(vw, (pw - (translateX * 2)), 2)) { && this.isWithin(vw, (pw - (translateX * 2)), 2)) {
} else { } else {
this.player.forceRefreshPlayerElement(); if (this.player.forceDetectPlayerElementChange()) {
this.restoreAr(); this.logger.log('info', 'debug', "Video dimensions changed. Triggering restoreAr()");
this.restoreAr();
} else {
this.logger.log('info', 'playerRescan', "Video dimensions didn't change.");
}
} }
} catch(e) { } catch(e) {
@ -412,18 +420,17 @@ class VideoData {
if(! this.video) { if(! this.video) {
this.logger.log('info', 'videoDetect', "[VideoDetect] player element isn't defined"); this.logger.log('info', 'videoDetect', "[VideoDetect] player element isn't defined");
} }
if ( this.video && this.dimensions && if ( this.video &&
( this.dimensions.width != videoWidth || ( this.dimensions?.width != videoWidth ||
this.dimensions.height != videoHeight ) this.dimensions?.height != videoHeight )
) { ) {
this.logger.log('info', 'debug', "[VideoDetect] player size changed. reason: dimension change. Old dimensions?", this.dimensions.width, this.dimensions.height, "new dimensions:", this.video.offsetWidth, this.video.offsetHeight); this.logger.log('info', 'debug', "[VideoDetect] player size changed. reason: dimension change. Old dimensions?", this.dimensions.width, this.dimensions.height, "new dimensions:", this.video.offsetWidth, this.video.offsetHeight);
} }
} }
// if size doesn't match, update & return true // if size doesn't match, update & return true
if (!this.dimensions if (this.dimensions?.width != videoWidth
|| this.dimensions.width != videoWidth || this.dimensions?.height != videoHeight ){
|| this.dimensions.height != videoHeight ){
this.dimensions = { this.dimensions = {
width: videoWidth, width: videoWidth,
height: videoHeight, height: videoHeight,

View File

@ -167,32 +167,30 @@ class Resizer {
ar.type === AspectRatio.Reset && this.lastAr.type === AspectRatio.Initial) { ar.type === AspectRatio.Reset && this.lastAr.type === AspectRatio.Initial) {
// some sites do things that interfere with our site (and aspect ratio setting in general) // some sites do things that interfere with our site (and aspect ratio setting in general)
// first, we check whether video contains anything we don't like // first, we check whether video contains anything we don't like
if (siteSettings && siteSettings.autoarPreventConditions) { if (siteSettings?.autoarPreventConditions?.videoStyleString) {
if (siteSettings.autoarPreventConditions.videoStyleString) { const styleString = (this.video.getAttribute('style') || '').split(';');
const styleString = (this.video.getAttribute('style') || '').split(';');
if (siteSettings.autoarPreventConditions.videoStyleString.containsProperty) {
if (siteSettings.autoarPreventConditions.videoStyleString.containsProperty) { const bannedProperties = siteSettings.autoarPreventConditions.videoStyleString.containsProperty;
const bannedProperties = siteSettings.autoarPreventConditions.videoStyleString.containsProperty; for (const prop in bannedProperties) {
for (const prop in bannedProperties) { for (const s of styleString) {
for (const s of styleString) { if (s.trim().startsWith(prop)) {
if (s.trim().startsWith(prop)) {
// check if css property has a list of allowed values:
// check if css property has a list of allowed values: if (bannedProperties[prop].allowedValues) {
if (bannedProperties[prop].allowedValues) { const styleValue = s.split(':')[1].trim();
const styleValue = s.split(':')[1].trim();
// check if property value is on the list of allowed values
// check if property value is on the list of allowed values // if it's not, we aren't allowed to start aard
// if it's not, we aren't allowed to start aard if (bannedProperties[prop].allowedValues.indexOf(styleValue) === -1) {
if (bannedProperties[prop].allowedValues.indexOf(styleValue) === -1) { this.logger.log('error', 'debug', "%c[Resizer::setAr] video style contains forbidden css property/value combo: ", "color: #900, background: #100", prop, " — we aren't allowed to start autoar.")
this.logger.log('error', 'debug', "%c[Resizer::setAr] video style contains forbidden css property/value combo: ", "color: #900, background: #100", prop, " — we aren't allowed to start autoar.")
return;
}
} else {
// no allowed values, no problem. We have forbidden property
// and this means aard can't start.
this.logger.log('info', 'debug', "%c[Resizer::setAr] video style contains forbidden css property: ", "color: #900, background: #100", prop, " — we aren't allowed to start autoar.")
return; return;
} }
} else {
// no allowed values, no problem. We have forbidden property
// and this means aard can't start.
this.logger.log('info', 'debug', "%c[Resizer::setAr] video style contains forbidden css property: ", "color: #900, background: #100", prop, " — we aren't allowed to start autoar.")
return;
} }
} }
} }
@ -361,14 +359,14 @@ class Resizer {
} }
restore() { restore() {
this.logger.log('info', 'debug', "[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio. this & settings:", {'a_lastAr': this.lastAr, 'this': this, "settings": this.settings} ); this.logger.log('info', 'debug', "[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio", {'a_lastAr': this.lastAr} );
// this is true until we verify that css has actually been applied // this is true until we verify that css has actually been applied
if(this.lastAr.type === AspectRatio.Initial){ if(this.lastAr.type === AspectRatio.Initial){
this.setAr({type: AspectRatio.Reset}); this.setAr({type: AspectRatio.Reset});
} }
else { else {
if (this.lastAr && this.lastAr.ratio === null) { if (this.lastAr?.ratio === null) {
// if this is the case, we do nothing as we have the correct aspect ratio // if this is the case, we do nothing as we have the correct aspect ratio
// throw "Last ar is null!" // throw "Last ar is null!"
return; return;
@ -378,7 +376,7 @@ class Resizer {
} }
reset(){ reset(){
this.setStretchMode(this.settings.active.sites[window.location.hostname] ? this.settings.active.sites[window.location.hostname].stretch : this.settings.active.sites['@global'].stretch); this.setStretchMode(this.settings.active.sites[window.location.hostname]?.stretch ?? this.settings.active.sites['@global'].stretch);
this.zoom.setZoom(1); this.zoom.setZoom(1);
this.resetPan(); this.resetPan();
this.setAr({type: AspectRatio.Reset}); this.setAr({type: AspectRatio.Reset});
@ -464,7 +462,7 @@ class Resizer {
'\nplayer dimensions: ', {w: this.conf.player.dimensions.width, h: this.conf.player.dimensions.height}, '\nplayer dimensions: ', {w: this.conf.player.dimensions.width, h: this.conf.player.dimensions.height},
'\nvideo dimensions: ', {w: this.conf.video.offsetWidth, h: this.conf.video.offsetHeight}, '\nvideo dimensions: ', {w: this.conf.video.offsetWidth, h: this.conf.video.offsetHeight},
'\nstretch factors: ', stretchFactors, '\nstretch factors: ', stretchFactors,
'\npan & zoom: ', this.pan, this.zoom, '\npan & zoom: ', this.pan, this.zoom.scale,
'\nwdiff, hdiff: ', wdiff, 'x', hdiff, '\nwdiff, hdiff: ', wdiff, 'x', hdiff,
'\nwdiff, hdiffAfterZoom:', wdiffAfterZoom, 'x', hdiffAfterZoom, '\nwdiff, hdiffAfterZoom:', wdiffAfterZoom, 'x', hdiffAfterZoom,
'\n\n---- data out ----\n', '\n\n---- data out ----\n',

View File

@ -31,11 +31,20 @@ class UWServer {
async setup() { async setup() {
// logger is the first thing that goes up // logger is the first thing that goes up
this.logger = new Logger({ const loggingOptions = {
logToFile: false, isBackgroundScript: true,
logToConsole: false allowLogging: true,
}); useConfFromStorage: true,
await this.logger.init(); logAll: true,
fileOptions: {
enabled: true,
},
consoleOptions: {
enabled: true
}
};
this.logger = new Logger();
await this.logger.init(loggingOptions);
this.settings = new Settings({logger: this.logger}); this.settings = new Settings({logger: this.logger});
await this.settings.init(); await this.settings.init();
@ -178,16 +187,10 @@ class UWServer {
// preveri za osirotele/zastarele vrednosti ter jih po potrebi izbriši // preveri za osirotele/zastarele vrednosti ter jih po potrebi izbriši
// check for orphaned/outdated values and remove them if neccessary // check for orphaned/outdated values and remove them if neccessary
if (this.videoTabs[sender.tab.id]) { if (this.videoTabs[sender.tab.id]?.host != tabHostname) {
if (this.videoTabs[sender.tab.id].host != tabHostname) { delete this.videoTabs[sender.tab.id]
delete this.videoTabs[sender.tab.id] } else if(this.videoTabs[sender.tab.id]?.frames[sender.frameId]?.host != frameHostname) {
} else { delete this.videoTabs[sender.tab.id].frames[sender.frameId];
if(this.videoTabs[sender.tab.id].frames[sender.frameId]) {
if (this.videoTabs[sender.tab.id].frames[sender.frameId].host != frameHostname) {
delete this.videoTabs[sender.tab.id].frames[sender.frameId];
}
}
}
} }
if (this.videoTabs[sender.tab.id]) { if (this.videoTabs[sender.tab.id]) {
@ -236,12 +239,33 @@ class UWServer {
this.selectedSubitem[menu] = subitem; this.selectedSubitem[menu] = subitem;
} }
getVideoTab() { async getCurrentTab() {
if (BrowserDetect.firefox) {
return (await browser.tabs.query({active: true, currentWindow: true}))[0];
} else if (BrowserDetect.chrome) {
return new Promise((resolve, reject) => chrome.tabs.query({active: true, currentWindow: true}, (x) => resolve(x[0])));
}
}
async getVideoTab() {
// friendly reminder: if current tab doesn't have a video, // friendly reminder: if current tab doesn't have a video,
// there won't be anything in this.videoTabs[this.currentTabId] // there won't be anything in this.videoTabs[this.currentTabId]
if (this.videoTabs[this.currentTabId]) {
const ctab = await this.getCurrentTab();
console.log('Current tab:', ctab);
if (!ctab || !ctab.id) {
return { return {
...this.videoTabs[this.currentTabId], host: 'INVALID SITE',
frames: [],
}
}
if (this.videoTabs[ctab.id]) {
return {
...this.videoTabs[ctab.id],
host: this.extractHostname(ctab.url),
selected: this.selectedSubitem selected: this.selectedSubitem
}; };
} }
@ -249,7 +273,7 @@ class UWServer {
// return something more or less empty if this tab doesn't have // return something more or less empty if this tab doesn't have
// a video registered for it // a video registered for it
return { return {
host: this.currentSite, host: this.extractHostname(ctab.url),
frames: [], frames: [],
selected: this.selectedSubitem selected: this.selectedSubitem
} }

View File

@ -7,6 +7,15 @@ import CommsClient from './lib/comms/CommsClient';
import PageInfo from './lib/video-data/PageInfo'; import PageInfo from './lib/video-data/PageInfo';
import Logger from './lib/Logger'; import Logger from './lib/Logger';
// vue dependency imports
import Vue from 'vue';
import Vuex from 'vuex';
import VuexWebExtensions from 'vuex-webextensions';
global.browser = require('webextension-polyfill');
import LoggerUi from '../csui/LoggerUi';
if(Debug.debug){ if(Debug.debug){
console.log("\n\n\n\n\n\n ——— Sᴛλʀᴛɪɴɢ Uʟᴛʀᴀɪɪʏ ———\n << ʟᴏᴀᴅɪɴɢ ᴍᴀɪɴ ꜰɪʟᴇ >>\n\n\n\n"); console.log("\n\n\n\n\n\n ——— Sᴛλʀᴛɪɴɢ Uʟᴛʀᴀɪɪʏ ———\n << ʟᴏᴀᴅɪɴɢ ᴍᴀɪɴ ꜰɪʟᴇ >>\n\n\n\n");
try { try {
@ -32,6 +41,7 @@ class UW {
this.settings = undefined; this.settings = undefined;
this.actionHandler = undefined; this.actionHandler = undefined;
this.logger = undefined; this.logger = undefined;
this.vuexStore = {};
} }
async init(){ async init(){
@ -43,31 +53,48 @@ class UW {
try { try {
if (!this.logger) { if (!this.logger) {
const loggingOptions = { const loggingOptions = {
logToFile: false, isContentScript: true,
logToConsole: false, allowLogging: true,
useConfFromStorage: true,
fileOptions: { fileOptions: {
// really the same stuff as consoleOptions enabled: false
}, },
consoleOptions: { consoleOptions: {
enabled: true, // if logging is enabled at all enabled: true,
// 'debug': true, 'debug': true,
// 'init': true, 'init': true,
// 'settings': true, 'settings': true,
// 'keyboard': true, 'keyboard': true,
// 'mousemove': false, 'mousemove': false,
// 'actionHandler': false, 'actionHandler': true,
// 'comms': false, 'comms': true,
// 'playerDetect': false, 'playerDetect': true,
// 'resizer': true, 'resizer': true,
// 'scaler': true, 'scaler': true,
// 'stretcher': true, 'stretcher': true,
// 'videoRescan': false, // 'videoRescan': true,
// 'arDetect': true, // 'playerRescan': true,
// 'arDetect_verbose': true, 'arDetect': true,
'arDetect_verbose': true
},
allowBlacklistedOrigins: {
'periodicPlayerCheck': false,
'periodicVideoStyleChangeCheck': false,
'handleMouseMove': false
} }
}; };
this.logger = new Logger(loggingOptions); this.logger = new Logger({vuexStore: this.vuexStore});
// await this.logger.init(); // not needed if logging options are provided at creation await this.logger.init(loggingOptions);
// show popup if logging to file is enabled
if (this.logger.isLoggingToFile()) {
console.info('[uw::init] Logging to file is enabled. Will show popup!');
try {
this.vuexStore.dispatch('uw-show-logger');
} catch (e) {
console.error('[uw::init] Failed to open popup!', e)
}
}
} }
} catch (e) { } catch (e) {
console.error("logger init failed!", e) console.error("logger init failed!", e)
@ -82,8 +109,6 @@ class UW {
if (this.comms) { if (this.comms) {
this.comms.destroy(); this.comms.destroy();
} }
if (!this.settings) { if (!this.settings) {
var ths = this; var ths = this;
@ -91,9 +116,11 @@ class UW {
await this.settings.init(); await this.settings.init();
} }
this.comms = new CommsClient('content-client-port', this.settings, this.logger); this.comms = new CommsClient('content-client-port', this.settings, this.logger);
// add showPopup, hidePopup listener to comms
this.comms.subscribe('show-logger', () => this.showLogger());
this.comms.subscribe('hide-logger', () => this.hideLogger());
// če smo razširitev onemogočili v nastavitvah, ne naredimo ničesar // če smo razširitev onemogočili v nastavitvah, ne naredimo ničesar
// If extension is soft-disabled, don't do shit // If extension is soft-disabled, don't do shit
@ -113,26 +140,96 @@ class UW {
try { try {
this.pageInfo = new PageInfo(this.comms, this.settings, this.logger, extensionMode, isSiteDisabled); this.pageInfo = new PageInfo(this.comms, this.settings, this.logger, extensionMode, isSiteDisabled);
this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized. Here's the object:", this.pageInfo); this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized.");
this.comms.setPageInfo(this.pageInfo); this.comms.setPageInfo(this.pageInfo);
this.logger.log('info', 'debug', "[uw.js::setup] will try to initate ActionHandler. Settings are:", this.settings, this.settings.active) this.logger.log('info', 'debug', "[uw.js::setup] will try to initate ActionHandler.");
// start action handler only if extension is enabled for this site // start action handler only if extension is enabled for this site
if (!isSiteDisabled) { if (!isSiteDisabled) {
this.actionHandler = new ActionHandler(this.pageInfo); this.actionHandler = new ActionHandler(this.pageInfo);
this.actionHandler.init(); this.actionHandler.init();
this.logger.log('info', 'debug', "[uw.js::setup] ActionHandler initiated:", this.actionHandler); this.logger.log('info', 'debug', "[uw.js::setup] ActionHandler initiated.");
} }
} catch (e) { } catch (e) {
this.logger.log('error', 'debug', "[uw::init] FAILED TO START EXTENSION. Error:", e); this.logger.log('error', 'debug', "[uw::init] FAILED TO START EXTENSION. Error:", e);
} }
}
initVue() {
Vue.prototype.$browser = global.browser;
Vue.use(Vuex);
this.vuexStore = new Vuex.Store({
plugins: [VuexWebExtensions({
persistentStates: [
'uwLog',
'showLogger',
],
})],
state: {
uwLog: '',
showLogger: false,
},
mutations: {
'uw-set-log'(state, payload) {
state['uwLog'] = payload;
},
'uw-show-logger'(state) {
state['showLogger'] = true;
},
'uw-hide-logger'(state) {
state['showLogger'] = false;
}
},
actions: {
'uw-set-log' ({commit}, payload) {
commit('uw-set-log', payload);
},
'uw-show-logger'({commit}) {
commit('uw-show-logger');
},
'uw-hide-logger'({commit}) {
commit('uw-hide-logger');
}
}
})
}
initUi() {
console.log("CREATING UI");
const random = Math.round(Math.random() * 69420);
const uwid = `uw-ui-root-${random}`;
const rootDiv = document.createElement('div');
rootDiv.setAttribute("style", "position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 999999; background-color: #ff0000;");
rootDiv.setAttribute("id", uwid);
document.body.appendChild(rootDiv);
new Vue({
el: `#${uwid}`,
components: {
LoggerUi
},
store: this.vuexStore,
render(h) {
return h('logger-ui');
}
})
}
showLogger() {
this.vuexStore.dispatch('uw-show-logger');
}
hideLogger() {
this.vuexStore.dispatch('uw-hide-logger');
} }
} }
var main = new UW(); var main = new UW();
main.initVue();
main.initUi();
main.init(); main.init();

View File

@ -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": "4.4.3.1", "version": "4.4.4",
"applications": { "applications": {
"gecko": { "gecko": {
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}" "id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
@ -21,7 +21,10 @@
"matches": ["*://*/*"], "matches": ["*://*/*"],
"js": [ "js": [
"ext/uw.js" "ext/uw.js"
], ],
"css": [
"ext/uw.css"
],
"all_frames": true "all_frames": true
}], }],

View File

@ -145,11 +145,10 @@ export default {
} }
}, },
async created () { async created () {
this.logger = new Logger({ this.logger = new Logger();
logToFile: false, await this.logger.init({
logToConsole: false allowLogging: true,
}); });
await this.logger.init();
this.settings = new Settings({updateCallback: this.updateSettings, logger: this.logger}); this.settings = new Settings({updateCallback: this.updateSettings, logger: this.logger});
await this.settings.init(); await this.settings.init();

View File

@ -4,7 +4,7 @@
<p>Ultrawidify version: {{addonVersion}}. Created by Tamius Han (me).</p> <p>Ultrawidify version: {{addonVersion}}. Created by Tamius Han (me).</p>
<p><b>Having an issue?</b> Report <strike>undocumented features</strike> bugs using one of the following options: <p><b>Having an issue?</b> Report <strike>undocumented features</strike> bugs using one of the following options:
<ul> <ul>
<li> <a target="_blank" href="https://github.com/xternal7/ultrawidify/issues"><b>Github</b></a> <b>(strongly preferred)</b><br/></li> <li> <a target="_blank" href="https://github.com/tamius-han/ultrawidify/issues"><b>Github</b></a> <b>(strongly preferred)</b><br/></li>
<li>Email: <a target="_blank" :href="mailtoLink">tamius.han@gmail.com</a></li> <li>Email: <a target="_blank" :href="mailtoLink">tamius.han@gmail.com</a></li>
<li>PM me on <a target="_blank" :href="redditLink">reddit</a><br/></li> <li>PM me on <a target="_blank" :href="redditLink">reddit</a><br/></li>
</ul> </ul>
@ -12,7 +12,7 @@
<p>&nbsp;</p> <p>&nbsp;</p>
<p>If you're curious about the source code, <a href="https://github.com/xternal7/ultrawidify">github's here</a>. It's available under sorta-you-can-look-but-you-can't-touch licence, meaning: you can look, I won't mind if you shoot me a pull request, but I will mind if you're just gonna reupload this extension to the AMO/Chrome store.</p> <p>If you're curious about the source code, <a href="https://github.com/tamius-han/ultrawidify">github's here</a>. It's available under sorta-you-can-look-but-you-can't-touch licence, meaning: you can look, I won't mind if you shoot me a pull request, but I will mind if you're just gonna reupload this extension to the AMO/Chrome store.</p>
<p>If you're looking at this page because you're bored and want to be bored some more, <a href="https://tamius.net">my website's here</a> and <a href="https://stuff.tamius.net/sacred-texts/">my blog is here</a>.</p> <p>If you're looking at this page because you're bored and want to be bored some more, <a href="https://tamius.net">my website's here</a> and <a href="https://stuff.tamius.net/sacred-texts/">my blog is here</a>.</p>
<p>I already have a 'donation' tab, but if you want to buy me a beer, <a href="https://paypal.me/tamius">my paypal's here</a>.</p> <p>I already have a 'donation' tab, but if you want to buy me a beer, <a href="https://paypal.me/tamius">my paypal's here</a>.</p>
<h2>Plans for the future</h2> <h2>Plans for the future</h2>

View File

@ -205,11 +205,10 @@ export default {
} }
}, },
async created() { async created() {
this.logger = new Logger({ this.logger = new Logger();
logToFile: false, await this.logger.init({
logToConsole: false allowLogging: true,
}); });
await this.logger.init();
this.settings = new Settings({updateCallback: () => this.updateConfig(), logger: this.logger}); this.settings = new Settings({updateCallback: () => this.updateConfig(), logger: this.logger});
await this.settings.init(); await this.settings.init();

View File

@ -1,26 +1,50 @@
<template> <template>
<div> <div class="flex flex-column h100">
<div class="row"> <div class="row">
<span class="label">Ultrawidify version:</span><br/> {{addonVersion}} <span class="label">Ultrawidify version:</span><br/> {{addonVersion}}
</div> </div>
<div class="row"> <div class="row">
<span class="label">Having an issue?</span><br/> Report <strike>undocumented features</strike> bugs using one of the following options: <span class="label">Having an issue?</span><br/> Report <strike>undocumented features</strike> bugs using one of the following options (in order of preference):
<ul> <ul>
<li> <a target="_blank" href="https://github.com/xternal7/ultrawidify/issues"><b>Github (preferred)</b></a><br/></li> <li> <a target="_blank" href="https://github.com/tamius-han/ultrawidify/issues"><b>Github (preferred)</b></a><br/></li>
<li>Email: <a target="_blank" :href="mailtoLink">tamius.han@gmail.com</a></li> <li>Email: <a target="_blank" :href="mailtoLink">tamius.han@gmail.com</a></li>
<li>PM me on <a target="_blank" :href="redditLink">reddit</a><br/></li> <li>PM me on <a target="_blank" :href="redditLink">reddit</a><br/></li>
</ul> </ul>
<br/> </div>
If reporting perfomrance/RAM usage issue, please include your CPU model and RAM.
<br/> <div class="flex-grow"></div>
<br/>
If reporting issues with autodetection, please also include a screenshot and a link to the video > with timestamp(s) if possible. <div class="row">
<span class="label">Swatter mode (logging)</span><br/>
</div>
<div v-if="showEasterEgg" class="center"><small>You've made plenty of marks, all in the wrong places!</small></div>
<div class="flex flex-row">
<ShortcutButton class="flex flex-grow button"
label="Show logger"
:active="loggingEnabled"
@click.native="showLogger()"
></ShortcutButton>
<ShortcutButton class="flex flex-grow button"
label="Make a mark"
@click.native="sendMark()"
></ShortcutButton>
<ShortcutButton class="flex flex-grow button"
label="Hide logger"
@click.native="hideLogger()"
></ShortcutButton>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Comms from '../../ext/lib/comms/Comms';
import ShortcutButton from '../../common/components/ShortcutButton';
import BrowserDetect from '../../ext/conf/BrowserDetect'; import BrowserDetect from '../../ext/conf/BrowserDetect';
export default { export default {
components: {
ShortcutButton,
},
data() { data() {
return { return {
addonVersion: browser.runtime.getManifest().version || chrome.runtime.getManifest().version, addonVersion: browser.runtime.getManifest().version || chrome.runtime.getManifest().version,
@ -28,16 +52,26 @@ export default {
redditLink: '', redditLink: '',
} }
}, },
created() { data() {
return {
loggingEnabled: false,
loggerSettings: '',
loggerSettingsError: false,
lastLoadedLoggerSettings: undefined,
mailtoLink: '',
redditLink: '',
showEasterEgg: false,
}
},
async created() {
const messageTemplate = encodeURIComponent( const messageTemplate = encodeURIComponent(
`Describe your issue in more detail. In case of misaligned videos, please provide screenshots. When reporting\ `Describe your issue in more detail. In case of misaligned videos, please provide screenshots. When reporting\
issues with autodetection not detecting aspect ratio correctly, please provide a link with timestamp to the\ issues with autodetection not detecting aspect ratio correctly, please provide a link with timestamp to the\
problematic video at the time where the problem happens. You may delete this paragraph, as it's only a template. problematic video at the time where the problem happens. You may delete this paragraph, as it's only a template.
Extension info (do not change or remove): Extension info (AUTOGENERATED DO NOT CHANGE OR REMOVE):
* Extension version: ${this.addonVersion} * Build: ${BrowserDetect.processEnvBrowser}-${this.addonVersion}-stable
* Browser (env): ${BrowserDetect.processEnvBrowser}
Browser-related stuff (please ensure this section is correct): Browser-related stuff (please ensure this section is correct):
* User Agent string: ${window.navigator.userAgent} * User Agent string: ${window.navigator.userAgent}
@ -47,6 +81,32 @@ Browser-related stuff (please ensure this section is correct):
); );
this.mailtoLink = `mailto:tamius.han@gmail.com?subject=%5BUltrawidify%5D%20ENTER%20SUMMARY%20OF%20YOUR%20ISSUE%20HERE&body=${messageTemplate}`; this.mailtoLink = `mailto:tamius.han@gmail.com?subject=%5BUltrawidify%5D%20ENTER%20SUMMARY%20OF%20YOUR%20ISSUE%20HERE&body=${messageTemplate}`;
this.redditLink = `https://www.reddit.com/message/compose?to=xternal7&subject=[Ultrawidify]%20ENTER%20SUMMARY%20OF%20YOUR%20PROBLEM%20HERE&message=${messageTemplate}`; this.redditLink = `https://www.reddit.com/message/compose?to=xternal7&subject=[Ultrawidify]%20ENTER%20SUMMARY%20OF%20YOUR%20PROBLEM%20HERE&message=${messageTemplate}`;
},
methods: {
async updateLoggerSettings(allowLogging) {
// this.loggingEnabled = allowLogging;
// if (allowLogging) {
// const parsedSettings = JSON.parse(this.loggerSettings);
// Logger.saveConfig({
// allowLogging: allowLogging,
// timeout: parsedSettings.timeout || undefined,
// fileOptions: parsedSettings.fileOptions || {},
// consoleOptions: parsedSettings.consoleOptions || {},
// });
// } else {
// // we need to save logger settings because logging is triggered by allow logging
// Logger.saveConfig({allowLogging: allowLogging, ...lastLoadedLoggerSettings});
// }
},
showLogger() {
Comms.sendMessage({cmd: 'show-logger', forwardToActive: true});
},
sendMark() {
this.showEasterEgg = !this.showEasterEgg;
},
hideLogger() {
Comms.sendMessage({cmd: 'hide-logger', forwardToActive: true});
}
} }
} }
</script> </script>

View File

@ -1,12 +1,12 @@
<template> <template>
<div> <div>
<h2>What's new</h2> <h2>What's new</h2>
<p>Full changelog for older versions <a href="https://github.com/xternal7/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">4.4.3.1</p> <p class="label">4.4.4</p>
This update mostly attempts to fix disney+ (again). Consider commenting <a href="https://github.com/xternal7/ultrawidify/issues/84">on this issue</a> if issues with disney+ persist.
<ul> <ul>
<li>Fixed conf patch for disney+ (hopefully)</li> <li>Tab detection in extension popup has been made more accurate</li>
<li><code>Settings.save()</code> adds missing values to site config when saving extension configuration.</li> <li>QoL: Added user-accessible logger (to make fixing sites I can't access a bit easier)</li>
<li>Changed links to reflect my github username change</li>
</ul> </ul>
</div> </div>
</template> </template>

View File

@ -2,11 +2,13 @@ $text-normal: #ddd;
$text-dim: #999; $text-dim: #999;
$text-dark: #666; $text-dark: #666;
$primary-color: #fb772a; $primary-color: #fb772a;
$primary: $primary-color;
$secondary-color: #e70c0c; $secondary-color: #e70c0c;
$input-background: #141414; $input-background: #141414;
$input-border: #4e3527; $input-border: #4e3527;
$page-background: #101010; $page-background: #101010;
$popup-header-background: #7f1416;
$background-primary: #101010; $background-primary: #101010;
$selected-color: #f5cbaf; $selected-color: #f5cbaf;

View File

@ -215,7 +215,9 @@ small {
text-align: center; text-align: center;
width: 100%; width: 100%;
} }
.text-center {
text-align: center;
}
.invalid-input { .invalid-input {
@ -386,3 +388,6 @@ small {
.ltr { .ltr {
direction: ltr; direction: ltr;
} }
.monospace {
font-family: 'Overpass Mono';
}

View File

@ -34,6 +34,7 @@
.flex-center { .flex-center {
align-content: center; align-content: center;
align-items: center;
} }
.flex-end { .flex-end {
@ -42,6 +43,7 @@
.flex-cross-center { .flex-cross-center {
justify-content: center; justify-content: center;
justify-items: center;
} }
.flex-self-center { .flex-self-center {

View File

@ -59,9 +59,9 @@ https://www.reddit.com/r/videos/comments/a137pj/daily_reminder_that_shelly_misca
#### Incorrect crops #### Incorrect crops
~~Incorrect crop when fixing vertical videos with letterbox: https://www.youtube.com/watch?v=9DP0TbOQcOw — [Issue 48](https://github.com/xternal7/ultrawidify/issues/48)~~ ~~Incorrect crop when fixing vertical videos with letterbox: https://www.youtube.com/watch?v=9DP0TbOQcOw — [Issue 48](https://github.com/tamius-han/ultrawidify/issues/48)~~
~~Incorrect crop on 4:3 in certain circumstances: https://www.reddit.com/r/videos/comments/a137pj/daily_reminder_that_shelly_miscavige_wife_of/ (embedded) — [Issue 54](https://github.com/xternal7/ultrawidify/issues/54)~~ ~~Incorrect crop on 4:3 in certain circumstances: https://www.reddit.com/r/videos/comments/a137pj/daily_reminder_that_shelly_miscavige_wife_of/ (embedded) — [Issue 54](https://github.com/tamius-han/ultrawidify/issues/54)~~
# Examples for sites without official support # Examples for sites without official support

View File

@ -60,6 +60,11 @@ const config = {
name: '[path][name].[ext]', name: '[path][name].[ext]',
}, },
}, },
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
], ],
}, },
plugins: [ plugins: [
@ -69,7 +74,7 @@ const config = {
}), }),
new CopyWebpackPlugin([ new CopyWebpackPlugin([
{ from: 'res', to: 'res'}, { from: 'res', to: 'res'},
{ from: 'ext', to: 'ext'}, { from: 'ext', to: 'ext', ignore: ['conf/*', 'lib/**']},
{ from: 'icons', to: 'icons', ignore: ['icon.xcf'] }, { from: 'icons', to: 'icons', ignore: ['icon.xcf'] },
{ from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml }, { from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml },
{ from: 'options/options.html', to: 'options/options.html', transform: transformHtml }, { from: 'options/options.html', to: 'options/options.html', transform: transformHtml },
@ -130,7 +135,8 @@ const config = {
onBuildEnd: ['node scripts/remove-evals.js'], onBuildEnd: ['node scripts/remove-evals.js'],
}), }),
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env.BROWSER': JSON.stringify(process.env.BROWSER) 'process.env.BROWSER': JSON.stringify(process.env.BROWSER),
'process.env.CHANNEL': JSON.stringify(process.env.CHANNEL)
}) })
], ],
}; };