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": [
"@babel/plugin-proposal-optional-chaining"
],
"presets": [
["@babel/preset-env", {

View File

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

View File

@ -5,6 +5,7 @@
### Plans for the future
* WebGL
* Native builds for Chromium Edge and Opera
* Settings page looks ugly af right now. Maybe fix it some time later
* 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
### 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)
* `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.
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
[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
@ -15,7 +17,7 @@ If you own an ultrawide monitor, you have probably noticed that sometimes videos
## Known issues
* 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
@ -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:
* [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.
### 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)
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
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).

1666
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
{
"name": "ultravidify",
"version": "4.4.3",
"description": "Aspect ratio fixer for youtube that works around some people's disability to properly encode 21:9 (and sometimes, 16:9) videos.",
"version": "4.4.4",
"description": "Aspect ratio fixer for youtube and other sites, with automatic aspect ratio detection. Supports ultrawide and other ratios.",
"author": "Tamius Han <tamius.han@gmail.com>",
"scripts": {
"start": "cross-env HMR=true npm run build:dev -- --watch",
"build": "cross-env NODE_ENV=production BROWSER=firefox webpack --hide-modules",
"build-chrome": "cross-env NODE_ENV=production BROWSER=chrome webpack --hide-modules",
"build-edge": "cross-env NODE_ENV=production BROWSER=edge webpack --hide-modules",
"build:dev": "cross-env NODE_ENV=development 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 CHANNEL=stable 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 CHANNEL=dev 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-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-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",
"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-edge": "npm run build-edge -- --watch",
"watch:dev": "cross-env HMR=true npm run build:dev -- --watch",
@ -28,30 +29,32 @@
"@types/core-js": "^2.5.0",
"@types/es6-promise": "^3.3.0",
"fs-extra": "^7.0.1",
"vue": "^2.5.17",
"vuex": "^3.0.1",
"vuex-webextensions": "^1.2.6"
"json-cyclic": "0.0.3",
"vue": "^2.6.11",
"vuex": "^3.1.2",
"vuex-webextensions": "^1.3.0",
"webextension-polyfill": "^0.6.0"
},
"devDependencies": {
"@babel/core": "^7.1.2",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/core": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"archiver": "^3.0.0",
"babel-loader": "^8.0.2",
"babel-loader": "^8.0.6",
"copy-webpack-plugin": "^4.5.3",
"cross-env": "^5.2.0",
"css-loader": "^0.28.11",
"ejs": "^2.6.1",
"ejs": "^2.7.4",
"file-loader": "^1.1.11",
"mini-css-extract-plugin": "^0.4.4",
"node-sass": "^4.9.3",
"node-sass": "^4.13.1",
"sass-loader": "^7.1.0",
"vue-loader": "^15.4.2",
"vue-template-compiler": "^2.5.17",
"vue-loader": "^15.8.3",
"vue-template-compiler": "^2.6.11",
"web-ext-types": "^2.1.0",
"webpack": "^4.20.2",
"webpack": "^4.41.5",
"webpack-chrome-extension-reloader": "^0.8.3",
"webpack-cli": "^3.1.2",
"webpack-cli": "^3.3.10",
"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_PREVIOUS_COMMIT" ] ; then
if [ "$GIT_COMMIT" == "$GIT_PREVIOUS_COMMIT" ] ; then
if [ $FORCE_BUILD == true ] ; then
if [ $FORCE_BUILD == false ] ; then
echo "--------------------------------------------"
echo " Nothing has changed. Aborting build."
echo "--------------------------------------------"
@ -40,23 +40,24 @@ fi
npm ci
rm -rf ./dist-zip || true # no big deal if ./dist-zip doesn't exist
mkdir dist-zip # create it back
#
# build firefox
#
npm run "${BUILD_SCRIPT}"
node scripts/build-zip.js ff
if [ ! -z "${AMO_API_KEY}" ] ; then
if [ ! -z "${AMO_API_SECRET}" ] ; then
web-ext sign --source-dir ./dist --api-key "${AMO_API_KEY}" --api-secret "${AMO_API_SECRET}"
fi
fi
node scripts/build-zip.js ff nightly
# if [ ! -z "${AMO_API_KEY}" ] ; then
# if [ ! -z "${AMO_API_SECRET}" ] ; then
# web-ext sign --source-dir ./dist --api-key "${AMO_API_KEY}" --api-secret "${AMO_API_SECRET}"
# fi
# fi
#
# build chrome
#
npm run "${BUILD_SCRIPT}-chrome"
node scripts/build-zip.js chrome
node scripts/build-zip.js chrome nightly
#
#./scripts/build-crx.sh
@ -66,21 +67,20 @@ node scripts/build-zip.js chrome
# UPLOAD TO WEB SERVER
######################################
# # add ssh key, if not added
# if [ -z "$SSH_AUTH_SOCK" ] ; then
# eval `ssh-agent -s`
# ssh-add
# fi
# # push all built stuff to the server
# scp -r ./build-zip/* "ultrawidify-uploader@${RELEASE_SERVER}:${RELEASE_DIRECTORY}${BUILD_CHANNEL_DIRECTORY}"
echo "--------------------------------------------"
echo " files ready for upload"
echo "--------------------------------------------"
echo ""
echo "Uploading to 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}"
######################################
# Build finished message
######################################
echo ""
echo "--------------------------------------------"
echo " BUILD FINISHED SUCCESSFULLY"
echo "--------------------------------------------"

View File

@ -52,15 +52,19 @@ const main = () => {
let realZipDir;
if (!!testingOrNightly) {
realZipDir = path.join(DEST_ZIP_DIR, baseFilename);
realZipDir = path.join(DEST_ZIP_DIR, version);
} else {
realZipDir = DEST_ZIP_DIR;
realZipDir = path.join(DEST_ZIP_DIR);
}
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)
.then(() => console.info('OK'))
.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) {
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;
if (videoData.player && videoData.player.element) {
@ -136,9 +136,9 @@ class ActionHandler {
preventAction(event) {
var activeElement = document.activeElement;
if(this.logger.canLog('keyboard')) {
if (this.logger.canLog('keyboard')) {
this.logger.pause(); // temp disable to avoid recursing;
const preventAction = this.preventAction();
const preventAction = this.preventAction(event);
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" +

View File

@ -1,57 +1,45 @@
import Debug from '../conf/Debug';
import currentBrowser from '../conf/BrowserDetect';
import { decycle } from 'json-cyclic';
class Logger {
constructor(conf) {
this.initLogger();
if (conf) {
this.conf = conf;
}
constructor(options) {
this.onLogEndCallbacks = [];
this.history = [];
this.startTime = performance.now();
this.temp_disable = false;
this.globalHistory = {};
this.isContentScript = false;
this.isBackgroundScript = true;
this.vuexStore = options?.vuexStore;
}
initLogger() {
const ths = this;
static saveConfig(conf) {
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;
br.storage.onChanged.addListener( (changes, area) => {
if (Debug.debug && Debug.debugStorage) {
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) {
const newLoggerConf = JSON.parse(changes.uwLogger.newValue)
if (process.env.CHANNEL === 'dev') {
console.info('Logger settings reloaded. New conf:', conf);
}
}
if(changes['uwLogger'] && changes['uwLogger'].newValue) {
ths.conf = JSON.parse(changes.uwLogger.newValue);
callback(newLoggerConf);
}
});
}
async init() {
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() {
static async getConfig() {
let ret;
if (currentBrowser.firefox) {
ret = await browser.storage.local.get('uwLogger');
} else if (currentBrowser.chrome) {
@ -64,21 +52,84 @@ class Logger {
});
}
if (Debug.debug && Debug.debugStorage) {
if (process.env.CHANNEL === 'dev') {
try {
console.log("[Logger::getSaved] Got settings:", JSON.parse(ret.uwLogger));
console.info("[Logger::getSaved] Got settings:", JSON.parse(ret.uwLogger));
} catch (e) {
console.log("[Logger::getSaved] No settings.")
console.info("[Logger::getSaved] No settings.")
}
}
try {
return JSON.parse(ret.uwLogger);
} 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.
// may result in negative times in the log file, but that doesn't
@ -94,15 +145,21 @@ class Logger {
}
}
getLogFileString() {
let logfileStr = '';
let logTs = ''; // number of seconds since extension started on a given page¸
for (let i = 0; i < this.history.length; i++) {
logTs = ((this.history[i].ts - Math.floor(this.performance.now)) / 3).toFixed(3);
logfileStr = `${logfileStr}[@${logTs}] -- ${this.history[i].message}\n`
}
// getLogFileString() {
// let logfileStr = '';
// let logTs = ''; // number of seconds since extension started on a given page¸
// for (let i = 0; i < this.history.length; i++) {
// logTs = ((this.history[i].ts - Math.floor(this.performance.now)) / 3).toFixed(3);
// logfileStr = `${logfileStr}[@${logTs}] -- ${this.history[i].message}\n`
// }
return logfileStr;
// return logfileStr;
// }
getFileLogJSONString() {
return {
site: window && window.location,
log: JSON.toString(this.history),
}
}
pause() {
@ -112,8 +169,144 @@ class Logger {
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) {
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) {
@ -130,8 +323,9 @@ class Logger {
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;
}
if (Array.isArray(component) && component.length) {
@ -141,36 +335,77 @@ class Logger {
}
}
} 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
// levels: 'info', 'warn', 'error'
// levels: 'info', 'warn', 'error'.
// if level is `true` (bool), logging happens regardless of any other
// settings
log(level, component, ...message) {
if (!this.conf) {
const stackInfo = this.parseStack();
if (!this.conf || (!this.conf.allowLogging && !stackInfo.exitLogs)) {
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({
ts: ts,
message: JSON.stringify(message),
})
// skip all checks if we force log
if (level === 'force') {
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.canLogConsole(component)) {
console.log(...message);
if (this.conf.consoleOptions?.enabled) {
if (this.canLogConsole(component) || stackInfo.exitLogs) {
this.logToConsole(message, stackInfo);
}
}
}
// 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
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;

View File

@ -35,6 +35,9 @@ class Settings {
}
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);
if (changes['uwSettings'] && 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) {
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;
}
@ -563,7 +566,7 @@ class Settings {
}
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;
}
@ -572,7 +575,7 @@ class Settings {
}
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;
}

View File

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

View File

@ -4,6 +4,7 @@ import BrowserDetect from '../../conf/BrowserDetect';
class CommsClient {
constructor(name, settings, logger) {
this.logger = logger;
if (BrowserDetect.firefox) {
this.port = browser.runtime.connect({name: name});
} else if (BrowserDetect.chrome) {
@ -12,6 +13,17 @@ class CommsClient {
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;
this._listener = m => ths.processReceivedMessage(m);
this.port.onMessage.addListener(this._listener);
@ -19,6 +31,34 @@ class CommsClient {
this.settings = settings;
this.pageInfo = undefined;
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() {
@ -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){
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;
this._listener = m => ths.processReceivedMessage(m);
@ -55,45 +103,10 @@ class CommsClient {
return;
}
if (message.cmd === 'get-current-zoom') {
this.pageInfo.requestCurrentZoom();
}
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);
if (this.commands[message.cmd]) {
for (const c of this.commands[message.cmd]) {
c(message);
}
} 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()
}
}
export default CommsClient;

View File

@ -7,6 +7,7 @@ class CommsServer {
this.logger = server.logger;
this.settings = server.settings;
this.ports = [];
this.popupPort = null;
var ths = this;
@ -17,6 +18,122 @@ class CommsServer {
chrome.runtime.onConnect.addListener(p => ths.onConnect(p));
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() {
@ -60,7 +177,7 @@ class CommsServer {
}
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 (tab === '__playing') {
@ -74,23 +191,23 @@ class CommsServer {
[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 {
this.ports[tab][frame].postMessage(message);
} 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) {
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();
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]) {
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]) {
@ -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) {
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);
return;
}
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);
return;
}
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.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.logger.log('info', 'comms', "[CommsServer.js::processReceivedMessage] Message has 'forward to active' flag set. Forwarding message as is. Message:", message);
this.sendToActive(message);
return;
}
if (message.cmd === 'get-current-site') {
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);
}
this.execCmd(message, portOrSender, sendResponse);
}
if (message.cmd === 'get-config') {
this.logger.log('info', 'CommsServer', "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}
);
} else if (message.cmd === 'has-video') {
this.server.registerVideo(port.sender);
} else if (message.cmd === 'noVideo') {
this.server.unregisterVideo(port.sender);
}
async processReceivedMessage(message, port){
this.logger.log('info', 'comms', "[CommsServer.js::processReceivedMessage] Received message from popup/content script!", message, "port", port);
this.handleMessage(message, port)
}
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.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});
}
this.handleMessage(message, sender, sendResponse);
}
}
export default CommsServer;

View File

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

View File

@ -127,18 +127,21 @@ class PlayerData {
while (!this.halted) {
await this.sleep(1000);
try {
if (this.periodicallyRefreshPlayerElement) {
this.forceRefreshPlayerElement();
}
if (this.checkPlayerSizeChange()) {
this.videoData.resizer.restore();
}
this.doPeriodicPlayerElementChangeCheck();
} catch (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(){
this.observer.disconnect();
}
@ -215,7 +218,8 @@ class PlayerData {
getPlayer() {
const host = window.location.host;
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 = [];
let scorePenalty = 0;
let score;
@ -231,12 +235,21 @@ class PlayerData {
return;
}
if (this.settings.active.sites[host]
&& this.settings.active.sites[host].DOM
&& this.settings.active.sites[host].DOM.player
&& 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) {
// log the entire hierarchy from <video> to root
if (this.logger.canLog('playerDetect')) {
const logObj = [];
logObj.push(`window size: ${window.innerWidth} x ${window.innerHeight}`);
let e = element;
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;
while (parentsLeft --> 0) {
@ -246,7 +259,7 @@ class PlayerData {
this.updatePlayerDimensions(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);
// actually we'll also score this branch in a similar way we score the regular, auto branch
while (element) {
@ -274,6 +287,9 @@ class PlayerData {
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) {
// return element with biggest score
// if video player has not been found, proceed to automatic detection
@ -331,9 +347,13 @@ class PlayerData {
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) {
// return element with biggest score
const playerElement = elementQ.sort( (a,b) => b.score - a.score)[0].element;
this.updatePlayerDimensions(playerElement);
return playerElement;
}
@ -352,6 +372,20 @@ class PlayerData {
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() {
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
// ignore the contents of this if (unless we need to change how logging works)
if (this.logger.canLog('debug')){
if (!this.dimensions) {
} else if (this.dimensions && this.dimensions.fullscreen){
if (this.dimensions?.fullscreen){
if(! PlayerData.isFullScreen()){
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");
}
if ( this.element && this.dimensions &&
( this.dimensions.width != this.element.offsetWidth ||
this.dimensions.height != this.element.offsetHeight )
if ( this.element &&
( +this.dimensions?.width != +this.element?.offsetWidth ||
+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 (!this.dimensions
|| this.dimensions.width != this.element.offsetWidth
|| this.dimensions.height != this.element.offsetHeight ){
if (this.dimensions?.width != this.element.offsetWidth
|| this.dimensions?.height != this.element.offsetHeight ){
const isFullScreen = PlayerData.isFullScreen();

View File

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

View File

@ -167,32 +167,30 @@ class Resizer {
ar.type === AspectRatio.Reset && this.lastAr.type === AspectRatio.Initial) {
// 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
if (siteSettings && siteSettings.autoarPreventConditions) {
if (siteSettings.autoarPreventConditions.videoStyleString) {
const styleString = (this.video.getAttribute('style') || '').split(';');
if (siteSettings.autoarPreventConditions.videoStyleString.containsProperty) {
const bannedProperties = siteSettings.autoarPreventConditions.videoStyleString.containsProperty;
for (const prop in bannedProperties) {
for (const s of styleString) {
if (s.trim().startsWith(prop)) {
// check if css property has a list of allowed values:
if (bannedProperties[prop].allowedValues) {
const styleValue = s.split(':')[1].trim();
// check if property value is on the list of allowed values
// if it's not, we aren't allowed to start aard
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.")
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.")
if (siteSettings?.autoarPreventConditions?.videoStyleString) {
const styleString = (this.video.getAttribute('style') || '').split(';');
if (siteSettings.autoarPreventConditions.videoStyleString.containsProperty) {
const bannedProperties = siteSettings.autoarPreventConditions.videoStyleString.containsProperty;
for (const prop in bannedProperties) {
for (const s of styleString) {
if (s.trim().startsWith(prop)) {
// check if css property has a list of allowed values:
if (bannedProperties[prop].allowedValues) {
const styleValue = s.split(':')[1].trim();
// check if property value is on the list of allowed values
// if it's not, we aren't allowed to start aard
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.")
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() {
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
if(this.lastAr.type === AspectRatio.Initial){
this.setAr({type: AspectRatio.Reset});
}
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
// throw "Last ar is null!"
return;
@ -378,7 +376,7 @@ class Resizer {
}
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.resetPan();
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},
'\nvideo dimensions: ', {w: this.conf.video.offsetWidth, h: this.conf.video.offsetHeight},
'\nstretch factors: ', stretchFactors,
'\npan & zoom: ', this.pan, this.zoom,
'\npan & zoom: ', this.pan, this.zoom.scale,
'\nwdiff, hdiff: ', wdiff, 'x', hdiff,
'\nwdiff, hdiffAfterZoom:', wdiffAfterZoom, 'x', hdiffAfterZoom,
'\n\n---- data out ----\n',

View File

@ -31,11 +31,20 @@ class UWServer {
async setup() {
// logger is the first thing that goes up
this.logger = new Logger({
logToFile: false,
logToConsole: false
});
await this.logger.init();
const loggingOptions = {
isBackgroundScript: true,
allowLogging: true,
useConfFromStorage: true,
logAll: true,
fileOptions: {
enabled: true,
},
consoleOptions: {
enabled: true
}
};
this.logger = new Logger();
await this.logger.init(loggingOptions);
this.settings = new Settings({logger: this.logger});
await this.settings.init();
@ -178,16 +187,10 @@ class UWServer {
// preveri za osirotele/zastarele vrednosti ter jih po potrebi izbriši
// check for orphaned/outdated values and remove them if neccessary
if (this.videoTabs[sender.tab.id]) {
if (this.videoTabs[sender.tab.id].host != tabHostname) {
delete this.videoTabs[sender.tab.id]
} else {
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]?.host != tabHostname) {
delete this.videoTabs[sender.tab.id]
} else 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]) {
@ -236,12 +239,33 @@ class UWServer {
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,
// 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 {
...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
};
}
@ -249,7 +273,7 @@ class UWServer {
// return something more or less empty if this tab doesn't have
// a video registered for it
return {
host: this.currentSite,
host: this.extractHostname(ctab.url),
frames: [],
selected: this.selectedSubitem
}

View File

@ -7,6 +7,15 @@ import CommsClient from './lib/comms/CommsClient';
import PageInfo from './lib/video-data/PageInfo';
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){
console.log("\n\n\n\n\n\n ——— Sᴛλʀᴛɪɴɢ Uʟᴛʀᴀɪɪʏ ———\n << ʟᴏᴀᴅɪɴɢ ᴍᴀɪɴ ꜰɪʟᴇ >>\n\n\n\n");
try {
@ -32,6 +41,7 @@ class UW {
this.settings = undefined;
this.actionHandler = undefined;
this.logger = undefined;
this.vuexStore = {};
}
async init(){
@ -43,31 +53,48 @@ class UW {
try {
if (!this.logger) {
const loggingOptions = {
logToFile: false,
logToConsole: false,
isContentScript: true,
allowLogging: true,
useConfFromStorage: true,
fileOptions: {
// really the same stuff as consoleOptions
enabled: false
},
consoleOptions: {
enabled: true, // if logging is enabled at all
// 'debug': true,
// 'init': true,
// 'settings': true,
// 'keyboard': true,
// 'mousemove': false,
// 'actionHandler': false,
// 'comms': false,
// 'playerDetect': false,
// 'resizer': true,
// 'scaler': true,
// 'stretcher': true,
// 'videoRescan': false,
// 'arDetect': true,
// 'arDetect_verbose': true,
enabled: true,
'debug': true,
'init': true,
'settings': true,
'keyboard': true,
'mousemove': false,
'actionHandler': true,
'comms': true,
'playerDetect': true,
'resizer': true,
'scaler': true,
'stretcher': true,
// 'videoRescan': true,
// 'playerRescan': true,
'arDetect': true,
'arDetect_verbose': true
},
allowBlacklistedOrigins: {
'periodicPlayerCheck': false,
'periodicVideoStyleChangeCheck': false,
'handleMouseMove': false
}
};
this.logger = new Logger(loggingOptions);
// await this.logger.init(); // not needed if logging options are provided at creation
};
this.logger = new Logger({vuexStore: this.vuexStore});
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) {
console.error("logger init failed!", e)
@ -82,8 +109,6 @@ class UW {
if (this.comms) {
this.comms.destroy();
}
if (!this.settings) {
var ths = this;
@ -91,9 +116,11 @@ class UW {
await this.settings.init();
}
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
// If extension is soft-disabled, don't do shit
@ -113,26 +140,96 @@ class UW {
try {
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.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
if (!isSiteDisabled) {
this.actionHandler = new ActionHandler(this.pageInfo);
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) {
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();
main.initVue();
main.initUi();
main.init();

View File

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Ultrawidify",
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
"version": "4.4.3.1",
"version": "4.4.4",
"applications": {
"gecko": {
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
@ -21,7 +21,10 @@
"matches": ["*://*/*"],
"js": [
"ext/uw.js"
],
],
"css": [
"ext/uw.css"
],
"all_frames": true
}],

View File

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

View File

@ -4,7 +4,7 @@
<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:
<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>PM me on <a target="_blank" :href="redditLink">reddit</a><br/></li>
</ul>
@ -12,7 +12,7 @@
<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>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>

View File

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

View File

@ -1,26 +1,50 @@
<template>
<div>
<div class="flex flex-column h100">
<div class="row">
<span class="label">Ultrawidify version:</span><br/> {{addonVersion}}
</div>
<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>
<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>PM me on <a target="_blank" :href="redditLink">reddit</a><br/></li>
</ul>
<br/>
If reporting perfomrance/RAM usage issue, please include your CPU model and RAM.
<br/>
<br/>
If reporting issues with autodetection, please also include a screenshot and a link to the video > with timestamp(s) if possible.
</div>
<div class="flex-grow"></div>
<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>
</template>
<script>
import Comms from '../../ext/lib/comms/Comms';
import ShortcutButton from '../../common/components/ShortcutButton';
import BrowserDetect from '../../ext/conf/BrowserDetect';
export default {
components: {
ShortcutButton,
},
data() {
return {
addonVersion: browser.runtime.getManifest().version || chrome.runtime.getManifest().version,
@ -28,16 +52,26 @@ export default {
redditLink: '',
}
},
created() {
data() {
return {
loggingEnabled: false,
loggerSettings: '',
loggerSettingsError: false,
lastLoadedLoggerSettings: undefined,
mailtoLink: '',
redditLink: '',
showEasterEgg: false,
}
},
async created() {
const messageTemplate = encodeURIComponent(
`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\
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 version: ${this.addonVersion}
* Browser (env): ${BrowserDetect.processEnvBrowser}
Extension info (AUTOGENERATED DO NOT CHANGE OR REMOVE):
* Build: ${BrowserDetect.processEnvBrowser}-${this.addonVersion}-stable
Browser-related stuff (please ensure this section is correct):
* 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.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>

View File

@ -1,12 +1,12 @@
<template>
<div>
<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 class="label">4.4.3.1</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.
<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.4</p>
<ul>
<li>Fixed conf patch for disney+ (hopefully)</li>
<li><code>Settings.save()</code> adds missing values to site config when saving extension configuration.</li>
<li>Tab detection in extension popup has been made more accurate</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>
</div>
</template>

View File

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

View File

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

View File

@ -34,6 +34,7 @@
.flex-center {
align-content: center;
align-items: center;
}
.flex-end {
@ -42,6 +43,7 @@
.flex-cross-center {
justify-content: center;
justify-items: 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 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

View File

@ -60,6 +60,11 @@ const config = {
name: '[path][name].[ext]',
},
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
],
},
plugins: [
@ -69,7 +74,7 @@ const config = {
}),
new CopyWebpackPlugin([
{ from: 'res', to: 'res'},
{ from: 'ext', to: 'ext'},
{ from: 'ext', to: 'ext', ignore: ['conf/*', 'lib/**']},
{ from: 'icons', to: 'icons', ignore: ['icon.xcf'] },
{ from: 'popup/popup.html', to: 'popup/popup.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'],
}),
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)
})
],
};