Compare commits

...

4 Commits

Author SHA1 Message Date
7c1ccd2cc9 Add contributing.md and license.md 2025-05-04 02:30:56 +02:00
e3a12bc601 Cleanup of unused imports 2025-05-04 02:29:33 +02:00
e20508956a Replace old logger with new logger 2025-05-04 02:18:58 +02:00
4000d0e027 Start rewriting logs 2025-05-01 00:55:22 +02:00
26 changed files with 676 additions and 310 deletions

39
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,39 @@
# Contributing to Ultrawidify
Thank you for considering contributing to this project! We welcome contributions from the community and are grateful for your efforts.
## How to Contribute
0. Open an issue, where you introduce the feature you want to add or thing you want to fix
1. Fork the repository.
2. Create a new branch for your contribution.
3. Write readable code
4. Check that your additions do not break existing features
5. Open a pull request
## Code of Conduct
Please follow the code of conduct:
* don't be too much of an asshole
* language policing my code comments is not a worthwhile contribution, and is considered spam. If you're here to do that, fuck off. I'm looking at you, ScamOSS and co.
## Code Style
- Use formatting consistent with the rest of the project
- Write meaningful commit messages.
- Include comments where necessary to explain complex logic.
## Licensing & Contribution Agreement
By submitting a contribution (e.g., via pull request), you agree to the following:
- You grant the project maintainer(s) a non-exclusive, irrevocable, worldwide, royalty-free license to use, copy, modify, and distribute your contributions as part of the project.
- You certify that your contributions are your original work and that you have the right to submit them.
- You agree that your contributions are licensed under the same license as the rest of the project, unless explicitly stated otherwise.
**TL;DR:** once your code is in the project, there's no take-backsies.
## Questions?
The discussion board is right over there, three tabs to the right.

35
LICENSE.MD Normal file
View File

@ -0,0 +1,35 @@
# License
Copyright (c) 2025 @tamius-han
The source code is provided on the "you can look, but you can't take" basis.
## Permissions
You are permitted to:
* You can view the code
* You can create forks and modify the code for personal use
* You can build and run modified versions of this project for personal use on your local machine
* Push modifications to your personal github fork
## Restrictions
You may NOT:
* Distribute this project or any modified versions outside of your personal Github fork
* Publish or distribute compiled binaries, builds, or packages of this project or any derivative work
* Use the code in commercial products, services, or other public-facing deployments.
* Sub-license, sell, or otherwise make the software or derivatives available to third parties.
## Contributions
By submitting a pull request or other contribution, you agree that:
- You grant the project maintainer(s) a non-exclusive, irrevocable, worldwide, royalty-free license to use, copy, modify, and distribute your contributions as part of the project.
- You certify that your contributions are your original work and that you have the right to submit them.
- You agree that your contributions are licensed under the same license as the rest of the project, unless explicitly stated otherwise.
## Disclaimer
This software is provided "as is", without warranty of any kind, express or implied. Use at your own risk.

View File

@ -121,13 +121,13 @@ import PopupVideoSettings from './src/popup/panels/PopupVideoSettings.vue'
import AboutPanel from '@csui/src/popup/panels/AboutPanel.vue'
import Debug from '../ext/conf/Debug';
import BrowserDetect from '../ext/conf/BrowserDetect';
import Comms from '../ext/lib/comms/Comms';
import CommsClient, {CommsOrigin} from '../ext/lib/comms/CommsClient';
import Settings from '../ext/lib/Settings';
import Logger from '../ext/lib/Logger';
import EventBus from '../ext/lib/EventBus';
import {ChromeShittinessMitigations as CSM} from '../common/js/ChromeShittinessMitigations';
import SupportLevelIndicator from '@csui/src/components/SupportLevelIndicator.vue'
import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import { ComponentLogger } from '@src/ext/lib/logging/ComponentLogger';
export default {
components: {
@ -148,6 +148,7 @@ export default {
settingsInitialized: false,
narrowPopup: null,
sideMenuVisible: null,
logAggregator: undefined,
logger: undefined,
site: undefined,
siteSettings: undefined,
@ -173,7 +174,8 @@ export default {
},
async created() {
try {
this.logger = new Logger();
this.logAggregator = new LogAggregator('🔵ext-popup🔵');
this.logger = new ComponentLogger(this.logAggregator, 'Popup');
await this.logger.init({
allowLogging: true,
});

View File

@ -23,7 +23,7 @@
</template>
<script>
import Logger from '../../../ext/lib/Logger';
export default {
components: {

View File

@ -27,7 +27,7 @@
</template>
<script>
import Logger, { baseLoggingOptions } from '../../../ext/lib/Logger';
import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import JsonEditor from '@csui/src/components/JsonEditor';
export default {
@ -86,14 +86,14 @@ export default {
this.lastSettings = baseLoggingOptions;
},
async getLoggerSettings() {
this.lastSettings = await Logger.getConfig() || baseLoggingOptions;
this.lastSettings = await LogAggregator.getConfig() || baseLoggingOptions;
},
saveLoggerSettings() {
Logger.saveConfig({...this.lastSettings});
LogAggregator.saveConfig({...this.lastSettings});
},
async startLogging(){
this.logStringified = undefined;
await Logger.saveConfig({...this.lastSettings, allowLogging: true});
await LogAggregator.saveConfig({...this.lastSettings, allowLogging: true});
window.location.reload();
},
}

View File

@ -1,15 +1,13 @@
import Debug from './conf/Debug';
import ExtensionMode from '../common/enums/ExtensionMode.enum';
import Settings from './lib/Settings';
import Comms from './lib/comms/Comms';
import CommsClient from './lib/comms/CommsClient';
import PageInfo from './lib/video-data/PageInfo';
import Logger, { baseLoggingOptions } from './lib/Logger';
import UWGlobals from './lib/UWGlobals';
import EventBus from './lib/EventBus';
import KeyboardHandler from './lib/kbm/KeyboardHandler';
import { SiteSettings } from './lib/settings/SiteSettings';
import UI from './lib/uwui/UI';
import { BLANK_LOGGER_CONFIG, LogAggregator } from './lib/logging/LogAggregator';
import { ComponentLogger } from './lib/logging/ComponentLogger';
export default class UWContent {
pageInfo: PageInfo;
@ -17,7 +15,8 @@ export default class UWContent {
settings: Settings;
siteSettings: SiteSettings;
keyboardHandler: KeyboardHandler;
logger: Logger;
logAggregator: LogAggregator;
logger: ComponentLogger;
eventBus: EventBus;
isIframe: boolean = false;
@ -34,7 +33,7 @@ export default class UWContent {
reloadSettings() {
try {
this.logger.log('info', 'debug', 'Things happened in the popup. Will reload extension settings.');
this.logger.debug('reloadSettings', 'Things happened in the popup. Will reload extension settings.');
this.init();
} catch (e) {
console.warn('Ultrawidify: settings reload failed. This probably shouldn\'t outright kill the extension, but page reload is recommended.');
@ -50,8 +49,9 @@ export default class UWContent {
// logger init is the first thing that needs to run
try {
if (!this.logger) {
this.logger = new Logger();
await this.logger.init(baseLoggingOptions);
this.logAggregator = new LogAggregator('◈');
this.logger = new ComponentLogger(this.logAggregator, 'UWContent');
await this.logAggregator.init(BLANK_LOGGER_CONFIG);
}
} catch (e) {
console.error("logger init failed!", e)
@ -67,7 +67,7 @@ export default class UWContent {
if (!this.settings) {
this.settings = new Settings({
onSettingsChanged: () => this.reloadSettings(),
logger: this.logger
logAggregator: this.logAggregator
});
await this.settings.init();
this.siteSettings = this.settings.getSiteSettings();
@ -81,13 +81,13 @@ export default class UWContent {
function: () => this.initPhase2()
}
);
this.comms = new CommsClient('content-main-port', this.logger, this.eventBus);
this.comms = new CommsClient('content-main-port', this.logAggregator, this.eventBus);
this.eventBus.setComms(this.comms);
this.initPhase2();
} catch (e) {
console.error('Ultrawidify initalization failed for some reason:', e);
console.error('Ultrawidify initialization failed for some reason:', e);
}
}
@ -95,21 +95,21 @@ export default class UWContent {
initPhase2() {
try {
if (this.pageInfo) {
this.logger.log('info', 'debug', '[uw.js::setup] An instance of pageInfo already exists and will be destroyed.');
this.logger.info('setup', 'An instance of pageInfo already exists and will be destroyed.');
this.pageInfo.destroy();
}
this.pageInfo = new PageInfo(this.eventBus, this.siteSettings, this.settings, this.logger);
this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized.");
this.pageInfo = new PageInfo(this.eventBus, this.siteSettings, this.settings, this.logAggregator);
this.logger.debug('setup', "pageInfo initialized.");
this.logger.log('info', 'debug', "[uw.js::setup] will try to initate KeyboardHandler.");
this.logger.debug('setup', "will try to initate KeyboardHandler.");
if (this.keyboardHandler) {
this.keyboardHandler.destroy();
}
this.keyboardHandler = new KeyboardHandler(this.eventBus, this.siteSettings, this.settings, this.logger);
this.keyboardHandler = new KeyboardHandler(this.eventBus, this.siteSettings, this.settings, this.logAggregator);
this.keyboardHandler.init();
this.logger.log('info', 'debug', "[uw.js::setup] KeyboardHandler initiated.");
this.logger.debug('setup', "KeyboardHandler initiated.");
this.globalUi = new UI('ultrawidify-global-ui', {eventBus: this.eventBus, isGlobal: true});
this.globalUi.enable();
@ -117,7 +117,7 @@ export default class UWContent {
} catch (e) {
console.error('Ultrawidify: failed to start extension. Error:', e)
this.logger.log('error', 'debug', "[uw::init] FAILED TO START EXTENSION. Error:", e);
this.logger.error('setup', "FAILED TO START EXTENSION. Error:", e);
}
}

View File

@ -2,13 +2,20 @@ import Debug from './conf/Debug.js';
import BrowserDetect from './conf/BrowserDetect';
import CommsServer from './lib/comms/CommsServer';
import Settings from './lib/Settings';
import Logger, { baseLoggingOptions } from './lib/Logger';
import { sleep } from '../common/js/utils';
import EventBus, { EventBusCommand } from './lib/EventBus';
import { ComponentLogger } from './lib/logging/ComponentLogger';
import { BLANK_LOGGER_CONFIG, LogAggregator } from './lib/logging/LogAggregator';
const BASE_LOGGING_STYLES = {
'log': 'background-color: #243; color: #4a8',
}
export default class UWServer {
settings: Settings;
logger: Logger;
logger: ComponentLogger;
logAggregator: LogAggregator;
comms: CommsServer;
eventBus: EventBus;
@ -64,22 +71,13 @@ export default class UWServer {
async setup() {
try {
// logger is the first thing that goes up
const loggingOptions = {
isBackgroundScript: true,
allowLogging: false,
useConfFromStorage: true,
logAll: true,
fileOptions: {
enabled: false,
},
consoleOptions: {
enabled: false
}
};
this.logger = new Logger();
await this.logger.init(loggingOptions);
const loggingOptions = BLANK_LOGGER_CONFIG;
this.settings = new Settings({logger: this.logger});
this.logAggregator = new LogAggregator('🔶bg-script🔶');
this.logger = new ComponentLogger(this.logAggregator, 'UwServer', {styles: BASE_LOGGING_STYLES});
await this.logAggregator.init(loggingOptions);
this.settings = new Settings({logAggregator: this.logAggregator});
await this.settings.init();
this.eventBus = new EventBus({isUWServer: true});
@ -130,7 +128,7 @@ export default class UWServer {
});
}
} catch (e) {
this.logger.log('error','debug', '[UwServer::injectCss] Error while injecting css:', {error: e, css, sender});
this.logger.error('injectCss', 'Error while injecting css:', {error: e, css, sender});
}
}
async removeCss(css, sender) {
@ -160,7 +158,7 @@ export default class UWServer {
});
}
} catch (e) {
this.logger.log('error','debug', '[UwServer::injectCss] Error while removing css:', {error: e, css, sender});
this.logger.error('injectCss', 'Error while removing css:', {error: e, css, sender});
}
}
async replaceCss(oldCss, newCss, sender) {
@ -205,9 +203,9 @@ export default class UWServer {
}
this.currentSite = this.extractHostname(tab.url);
this.logger.log('info', 'debug', '[UwServer::onTabSwitched] user switched tab. New site:', this.currentSite);
this.logger.info('onTabSwitched', 'user switched tab. New site:', this.currentSite);
} catch(e) {
this.logger.log('error', 'debug', '[UwServer::onTabSwitched] there was a problem getting currnet site:', e)
this.logger.info('onTabSwitched', 'there was a problem getting current site:', e)
}
this.selectedSubitem = {
@ -220,7 +218,7 @@ export default class UWServer {
}
registerVideo(sender) {
this.logger.log('info', 'comms', '[UWServer::registerVideo] Registering video.\nsender:', sender);
this.logger.info('registerVideo', 'Registering video.\nsender:', sender);
const tabHostname = this.extractHostname(sender.tab.url);
const frameHostname = this.extractHostname(sender.url);
@ -254,11 +252,11 @@ export default class UWServer {
}
}
this.logger.log('info', 'comms', '[UWServer::registerVideo] Video registered. current videoTabs:', this.videoTabs);
this.logger.info('registerVideo', 'Video registered. current videoTabs:', this.videoTabs);
}
unregisterVideo(sender) {
this.logger.log('info', 'comms', '[UwServer::unregisterVideo] Unregistering video.\nsender:', sender);
this.logger.info('unregisterVideo', 'Unregistering video.\nsender:', sender);
if (this.videoTabs[sender.tab.id]) {
if ( Object.keys(this.videoTabs[sender.tab.id].frames).length <= 1) {
delete this.videoTabs[sender.tab.id]
@ -268,27 +266,27 @@ export default class UWServer {
}
}
}
this.logger.log('info', 'comms', '[UwServer::unregisterVideo] Video has been unregistered. Current videoTabs:', this.videoTabs);
this.logger.info('unregisterVideo', 'Video has been unregistered. Current videoTabs:', this.videoTabs);
}
setSelectedTab(menu, subitem) {
this.logger.log('info', 'comms', '[UwServer::setSelectedTab] saving selected tab for', menu, ':', subitem);
this.logger.info('setSelectedTab', 'saving selected tab for', menu, ':', subitem);
this.selectedSubitem[menu] = subitem;
}
async getCurrentSite() {
this.logger.log('info', 'comms', '%c[UWServer::getCurrentSite] received get-current-site ...', 'background-color: #243; color: #4a8');
this.logger.info('getCurrentSite', 'received get-current-site ...');
const site = await this.getVideoTab();
// Don't propagate 'INVALID SITE' to the popup.
if (site.host === 'INVALID SITE') {
this.logger.log('info', 'comms', '%c[UWServer::getCurrentSite] Host is not valid — no info for current tab.', 'background-color: #243; color: #4a8');
this.logger.info('getCurrentSite', 'Host is not valid — no info for current tab.');
return;
}
const tabHostname = await this.getCurrentTabHostname();
this.logger.log('info', 'comms', '%c[UWServer::getCurrentSite] Returning data:', 'background-color: #243; color: #4a8', {site, tabHostname});
this.logger.info('getCurrentSite', 'Returning data:', {site, tabHostname});
this.eventBus.send(

View File

@ -1,27 +1,34 @@
import Debug from '../conf/Debug';
import currentBrowser from '../conf/BrowserDetect';
import ExtensionConf from '../conf/ExtensionConf';
import ExtensionMode from '../../common/enums/ExtensionMode.enum';
import ObjectCopy from './ObjectCopy';
import StretchType from '../../common/enums/StretchType.enum';
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum';
import ExtensionConfPatch from '../conf/ExtConfPatches';
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
import BrowserDetect from '../conf/BrowserDetect';
import Logger from './Logger';
import SettingsInterface from '../../common/interfaces/SettingsInterface';
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
import { SiteSettings } from './settings/SiteSettings';
import { SettingsSnapshotManager } from './settings/SettingsSnapshotManager';
import { ComponentLogger } from './logging/ComponentLogger';
import { LogAggregator } from './logging/LogAggregator';
if(process.env.CHANNEL !== 'stable'){
console.info("Loading Settings");
}
interface SettingsOptions {
logAggregator: LogAggregator,
onSettingsChanged?: () => void,
afterSettingsSaved?: () => void,
activeSettings?: SettingsInterface,
}
interface SetSettingsOptions {
forcePreserveVersion?: boolean,
}
const SETTINGS_LOGGER_STYLES = {
log: 'color: #81d288',
}
class Settings {
//#region flags
useSync: boolean = false;
@ -29,7 +36,9 @@ class Settings {
//#endregion
//#region helper classes
logger: Logger;
logAggregator: LogAggregator;
logger: ComponentLogger;
//#endregion
//#region data
@ -49,12 +58,12 @@ class Settings {
//#endregion
constructor(options) {
constructor(options: SettingsOptions) {
// Options: activeSettings, updateCallback, logger
this.logger = options?.logger;
this.onSettingsChanged = options?.onSettingsChanged;
this.afterSettingsSaved = options?.afterSettingsSaved;
this.active = options?.activeSettings ?? undefined;
this.logger = options.logAggregator && new ComponentLogger(options.logAggregator, 'Settings', {styles: SETTINGS_LOGGER_STYLES}) || undefined;;
this.onSettingsChanged = options.onSettingsChanged;
this.afterSettingsSaved = options.afterSettingsSaved;
this.active = options.activeSettings ?? undefined;
this.default = ExtensionConf;
this.snapshotManager = new SettingsSnapshotManager();
@ -67,14 +76,14 @@ class Settings {
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?.info('storageOnChange', "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));
// }
const parsedSettings = JSON.parse(changes.uwSettings.newValue);
this.setActive(parsedSettings);
this.logger?.log('info', 'debug', 'Does parsedSettings.preventReload exist?', parsedSettings.preventReload, "Does callback exist?", !!this.onSettingsChanged);
this.logger?.info('storageOnChange', 'Does parsedSettings.preventReload exist?', parsedSettings.preventReload, "Does callback exist?", !!this.onSettingsChanged);
if (!parsedSettings.preventReload) {
try {
@ -82,23 +91,23 @@ class Settings {
try {
fn();
} catch (e) {
this.logger?.log('warn', 'settings', "[Settings] afterSettingsChanged fallback failed. It's possible that a vue component got destroyed, and this function is nothing more than vestigal remains. It would be nice if we implemented something that allows us to remove callback functions from array, and remove vue callbacks from the callback array when their respective UI component gets destroyed. Or this could be an error with the function itself. IDK, here's the error.", e)
this.logger?.warn('storageOnChange', "afterSettingsChanged fallback failed. It's possible that a vue component got destroyed, and this function is nothing more than vestigal remains. It would be nice if we implemented something that allows us to remove callback functions from array, and remove vue callbacks from the callback array when their respective UI component gets destroyed. Or this could be an error with the function itself. IDK, here's the error.", e)
}
}
if (this.onSettingsChanged) {
this.onSettingsChanged();
}
this.logger?.log('info', 'settings', '[Settings] Update callback finished.')
this.logger?.info('storageOnChange', 'Update callback finished.')
} catch (e) {
this.logger?.log('error', 'settings', "[Settings] CALLING UPDATE CALLBACK FAILED. Reason:", e)
this.logger?.error('storageOnChange', "CALLING UPDATE CALLBACK FAILED. Reason:", e)
}
}
for (const fn of this.afterSettingsChangedCallbacks) {
try {
fn();
} catch (e) {
this.logger?.log('warn', 'settings', "[Settings] afterSettingsChanged fallback failed. It's possible that a vue component got destroyed, and this function is nothing more than vestigal remains. It would be nice if we implemented something that allows us to remove callback functions from array, and remove vue callbacks from the callback array when their respective UI component gets destroyed. Or this could be an error with the function itself. IDK, here's the error.", e)
this.logger?.warn('storageOnChange', "afterSettingsChanged fallback failed. It's possible that a vue component got destroyed, and this function is nothing more than vestigal remains. It would be nice if we implemented something that allows us to remove callback functions from array, and remove vue callbacks from the callback array when their respective UI component gets destroyed. Or this could be an error with the function itself. IDK, here's the error.", e)
}
}
if (this.afterSettingsSaved) {
@ -188,7 +197,7 @@ class Settings {
let index = this.findFirstNecessaryPatch(oldVersion);
if (index === -1) {
this.logger?.log('info','settings','[Settings::applySettingsPatches] There are no pending conf patches.');
this.logger?.info('applySettingsPatches','There are no pending conf patches.');
return;
}
@ -205,20 +214,14 @@ class Settings {
// apply all remaining patches
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${ExtensionConfPatch.length - index} settings patches to apply`);
this.logger?.info('applySettingsPatches', `There are ${ExtensionConfPatch.length - index} settings patches to apply`);
while (index < ExtensionConfPatch.length) {
const updateFn = ExtensionConfPatch[index].updateFn;
if (updateFn) {
try {
updateFn(this.active, this.getDefaultSettings());
} catch (e) {
this.logger?.log('error', 'settings', '[Settings::applySettingsPatches] Failed to execute update function. Keeping settings object as-is. Error:', e);
console.warn(
'————————————————————————————————————\n',
'Applying patch', index, ' failed :', '\n',
e, '\n',
'————————————————————————————————————\n',
);
this.logger?.error('applySettingsPatches', 'Failed to execute update function. Keeping settings object as-is. Error:', e);
}
}
@ -230,7 +233,7 @@ class Settings {
let settings = await this.get();
if (settings?.dev?.loadFromSnapshot) {
this.logger?.log('info', 'settings', '[Settings::init] Dev mode is enabled, Loading settings from snapshot:', settings.dev.loadFromSnapshot);
this.logger?.info('init', 'Dev mode is enabled, Loading settings from snapshot:', settings.dev.loadFromSnapshot);
const snapshot = await this.snapshotManager.getSnapshot();
if (snapshot) {
settings = snapshot.settings;
@ -245,7 +248,7 @@ class Settings {
const oldVersion = settings?.version ?? this.version;
if (settings) {
this.logger?.log('info', 'settings', "[Settings::init] Configuration fetched from storage:", settings,
this.logger?.info('init', "Configuration fetched from storage:", settings,
"\nlast saved with:", settings.version,
"\ncurrent version:", this.version
);
@ -253,10 +256,9 @@ class Settings {
// if there's no settings saved, return default settings.
if(! settings || (Object.keys(settings).length === 0 && settings.constructor === Object)) {
this.logger?.log(
'info',
'settings',
'[Settings::init] settings don\'t exist. Using defaults.\n#keys:',
this.logger?.info(
'init',
'settings don\'t exist. Using defaults.\n#keys:',
settings ? Object.keys(settings).length : 0,
'\nsettings:',
settings
@ -281,7 +283,7 @@ class Settings {
// check if extension has been updated. If not, return settings as they were retrieved
if (this.active.version === this.version) {
this.logger?.log('info', 'settings', "[Settings::init] extension was saved with current version of ultrawidify. Returning object as-is.");
this.logger?.info('init', "extension was saved with current version of ultrawidify. Returning object as-is.");
return this.active;
}
@ -292,7 +294,7 @@ class Settings {
// if extension has been updated, update existing settings with any options added in the
// new version. In addition to that, we remove old keys that are no longer used.
const patched = ObjectCopy.addNew(settings, this.default);
this.logger?.log('info', 'settings',"[Settings.init] Results from ObjectCopy.addNew()?", patched, "\n\nSettings from storage", settings, "\ndefault?", this.default);
this.logger?.info('init',"Results from ObjectCopy.addNew()?", patched, "\n\nSettings from storage", settings, "\ndefault?", this.default);
if (patched) {
this.active = patched;
@ -315,7 +317,7 @@ class Settings {
ret = await chrome.storage.local.get('uwSettings');
this.logger?.log('info', 'settings', 'Got settings:', ret && ret.uwSettings && JSON.parse(ret.uwSettings));
this.logger?.info('get', 'Got settings:', ret && ret.uwSettings && JSON.parse(ret.uwSettings));
try {
return JSON.parse(ret.uwSettings) as SettingsInterface;
@ -328,7 +330,7 @@ class Settings {
if (!options || !options.forcePreserveVersion) {
extensionConf.version = this.version;
}
this.logger?.log('info', 'settings', "[Settings::set] setting new settings:", extensionConf)
this.logger?.info('set', "setting new settings:", extensionConf)
return chrome.storage.local.set( {'uwSettings': JSON.stringify(extensionConf)});
}

View File

@ -3,7 +3,6 @@ import ExtensionMode from '@src/common/enums/ExtensionMode.enum';
import { ArVariant } from '@src/common/interfaces/ArInterface';
import { ExtensionEnvironment } from '@src/common/interfaces/SettingsInterface';
import EventBus from '../EventBus';
import Logger from '../Logger';
import Settings from '../Settings';
import { SiteSettings } from '../settings/SiteSettings';
import VideoData from '../video-data/VideoData';
@ -19,6 +18,7 @@ import { AardDetectionSample, generateSampleArray, resetSamples } from './interf
import { AardStatus, initAardStatus } from './interfaces/aard-status.interface';
import { AardTestResults, initAardTestResults, resetAardTestResults, resetGuardLine } from './interfaces/aard-test-results.interface';
import { AardTimers, initAardTimers } from './interfaces/aard-timers.interface';
import { ComponentLogger } from '../logging/ComponentLogger';
/**
@ -221,7 +221,7 @@ import { AardTimers, initAardTimers } from './interfaces/aard-timers.interface';
*/
export class Aard {
//#region configuration parameters
private logger: Logger;
private logger: ComponentLogger;
private videoData: VideoData;
private settings: Settings;
private siteSettings: SiteSettings;
@ -292,7 +292,7 @@ export class Aard {
//#region lifecycle
constructor(videoData: VideoData){
this.logger = videoData.logger;
this.logger = new ComponentLogger(videoData.logAggregator, 'Aard', {});
this.videoData = videoData;
this.video = videoData.video;
this.settings = videoData.settings;
@ -304,7 +304,7 @@ export class Aard {
this.arid = (Math.random()*100).toFixed();
// we can tick manually, for debugging
this.logger.log('info', 'init', `[ArDetector::ctor] creating new ArDetector. arid: ${this.arid}`);
this.logger.log('ctor', `creating new ArDetector. arid: ${this.arid}`);
this.timer = new AardTimer();
this.init();
@ -372,14 +372,14 @@ export class Aard {
if (this.settings.active.arDetect.aardType !== 'webgl') {
return new FallbackCanvas({...this.settings.active.arDetect.canvasDimensions.sampleCanvas, id: 'main-legacy'});
}
console.error('[ultrawidify|Aard::createCanvas] could not create webgl canvas:', e);
this.logger.error('createCanvas', 'could not create webgl canvas:', e);
this.eventBus.send('uw-config-broadcast', {type: 'aard-error', aardErrors: {webglError: true}});
throw e;
}
} else if (this.settings.active.arDetect.aardType === 'legacy') {
return new FallbackCanvas({...this.settings.active.arDetect.canvasDimensions.sampleCanvas, id: 'main-legacy'});
} else {
console.error('[ultrawidify|Aard::createCanvas] invalid value in settings.arDetect.aardType:', this.settings.active.arDetect.aardType);
this.logger.error('createCanvas', 'invalid value in settings.arDetect.aardType:', this.settings.active.arDetect.aardType);
this.eventBus.send('uw-config-broadcast', {type: 'aard-error', aardErrors: {invalidSettings: true}});
throw 'AARD_INVALID_SETTINGS';
}
@ -725,7 +725,7 @@ export class Aard {
return VideoPlaybackState.Playing;
}
} catch (e) {
this.logger.log('warn', 'debug', `[ArDetect::getVideoPlaybackState] There was an error while determining video playback state.`, e);
this.logger.warn('getVideoPlaybackState]', `There was an error while determining video playback state.`, e);
return VideoPlaybackState.Error;
}
}

View File

@ -1,8 +1,7 @@
import Debug from '../../conf/Debug';
import BrowserDetect from '../../conf/BrowserDetect';
import Logger from '../Logger';
import Settings from '../Settings';
import EventBus, { EventBusContext } from '../EventBus';
import { ComponentLogger } from '../logging/ComponentLogger';
import { LogAggregator } from '../logging/LogAggregator';
if (process.env.CHANNEL !== 'stable'){
console.info("Loading CommsClient");
@ -73,7 +72,7 @@ class CommsClient {
name: string;
origin: CommsOrigin;
logger: Logger;
logger: ComponentLogger;
settings: any; // sus?
eventBus: EventBus;
@ -82,10 +81,10 @@ class CommsClient {
port: chrome.runtime.Port;
//#region lifecycle
constructor(name: string, logger: Logger, eventBus: EventBus) {
constructor(name: string, logAggregator: LogAggregator, eventBus: EventBus) {
this.name = name;
try {
this.logger = logger;
this.logger = new ComponentLogger(logAggregator, 'CommsClient', {});
this.eventBus = eventBus;
if (name === 'popup-port') {
@ -101,16 +100,16 @@ class CommsClient {
this.port = chrome.runtime.connect(null, {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.hostname, history})
} catch (e) {
this.logger.log('error', 'comms', 'Failed to send message to background script. Error:', e);
}
}
);
// 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.hostname, history})
// } catch (e) {
// this.logger.log('error', 'comms', 'Failed to send message to background script. Error:', e);
// }
// }
// );
this._listener = m => this.processReceivedMessage(m);
this.port.onMessage.addListener(this._listener);
@ -118,7 +117,7 @@ class CommsClient {
this.commsId = (Math.random() * 20).toFixed(0);
} catch (e) {
console.error("CONSTRUCOTR FAILED:", e)
console.error("CONSTRUCTOR FAILED:", e)
}
}
@ -130,6 +129,8 @@ class CommsClient {
//#endregion
async sendMessage(message, context?: EventBusContext){
this.logger.info('sendMessage', ' <<< Sending message to background script:', message);
message = JSON.parse(JSON.stringify(message)); // vue quirk. We should really use vue store instead
// content script client and popup client differ in this one thing

View File

@ -1,16 +1,16 @@
import { EventBusContext } from './../EventBus';
import Debug from '../../conf/Debug';
import BrowserDetect from '../../conf/BrowserDetect';
import Logger from '../Logger';
import { ComponentLogger } from './../logging/ComponentLogger';
import Settings from '../Settings';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import EventBus from '../EventBus';
import { CommsOrigin } from './CommsClient';
const BASE_LOGGING_STYLES = {
log: "background-color: #11D; color: #aad",
};
class CommsServer {
server: any;
logger: Logger;
logger: ComponentLogger;
settings: Settings;
eventBus: EventBus;
@ -61,7 +61,7 @@ class CommsServer {
//#region lifecycle
constructor(server) {
this.server = server;
this.logger = server.logger;
this.logger = new ComponentLogger(server.logAggregator, 'CommsServer', {styles: BASE_LOGGING_STYLES});
this.settings = server.settings;
this.eventBus = server.eventBus;
@ -106,6 +106,7 @@ class CommsServer {
//#endregion
sendMessage(message, context?) {
this.logger.debug('sendMessage', `preparing to send message ${message.command ?? ''} ...`, {message, context});
// stop messages from returning where they came from, and prevent
// cross-pollination between content scripts running in different
// tabs.
@ -129,11 +130,16 @@ class CommsServer {
// okay I lied! Messages originating from content script can be forwarded to
// content scripts running in _other_ frames of the tab
let forwarded = false;
if (context?.origin === CommsOrigin.ContentScript) {
if (context?.comms.forwardTo === 'all-frames') {
forwarded = true;
this.sendToOtherFrames(message, context);
}
}
if (!forwarded) {
this.logger.warn('sendMessage', `message ${message.command ?? ''} was not forwarded to any destination!`, {message, context});
}
}
/**
@ -148,10 +154,13 @@ class CommsServer {
* Does NOT send a message to popup.
**/
private sendToAll(message){
this.logger.info('sendToAll', "sending message to all content scripts", message);
for(const tid in this.ports){
const tab = this.ports[tid];
for(const frame in tab){
for (const port in tab[frame]) {
this.logger.info('sendToAll', ` <——— attempting to send message ${message.command ?? ''} to tab ${tab}, frame ${frame}, port ${port}`, message);
tab[frame][port].postMessage(message);
}
}
@ -168,9 +177,11 @@ class CommsServer {
private async sendToFrameContentScripts(message, tab, frame, port?) {
if (port !== undefined) {
this.ports[tab][frame][port].postMessage(message);
this.logger.info('sendToOtherFrames', ` <——— attempting to send message ${message.command ?? ''} to tab ${tab}, frame ${frame}, port ${port}`, message);
return;
}
for (const framePort in this.ports[tab][frame]) {
this.logger.info('sendToOtherFrames', ` <——— attempting to send message ${message.command ?? ''} to tab ${tab}, frame ${frame}`, message);
this.ports[tab][frame][framePort].postMessage(JSON.parse(JSON.stringify(message)));
}
}
@ -198,7 +209,7 @@ class CommsServer {
}
private async sendToFrame(message, tab, frame, port?) {
this.logger.log('info', 'comms', `%c[CommsServer::sendToFrame] attempting to send message to tab ${tab}, frame ${frame}`, "background: #dda; color: #11D", message);
this.logger.info('sendToFrame', ` <——— attempting to send message ${message.command ?? ''} to tab ${tab}, frame ${frame}`, message);
if (isNaN(tab)) {
if (frame === '__playing') {
@ -212,33 +223,32 @@ class CommsServer {
[tab, frame] = frame.split('-');
}
this.logger.log('info', 'comms', `%c[CommsServer::sendToFrame] attempting to send message to tab ${tab}, frame ${frame}`, "background: #dda; color: #11D", message);
this.logger.info('sendToFrame', ` <——— attempting to send message ${message.command ?? ''} to tab ${tab}, frame ${frame}`, message);
try {
this.sendToFrameContentScripts(message, tab, frame, port);
} catch (e) {
this.logger.log('error', 'comms', `%c[CommsServer::sendToFrame] Sending message failed. Reason:`, "background: #dda; color: #11D", e);
this.logger.error('sendToFrame', ` Sending message failed. Reason:`, e);
}
}
private async sendToActive(message) {
this.logger.log('info', 'comms', "%c[CommsServer::sendToActive] trying to send a message to active tab. Message:", "background: #dda; color: #11D", message);
this.logger.info('sendToActive', ` <——— trying to send a message ${message.command ?? ''} to active tab. Message:`, message);
const tabs = await this.activeTab;
this.logger.log('info', 'comms', "[CommsServer::_sendToActive] currently active tab(s)?", tabs);
for (const frame in this.ports[tabs[0].id]) {
this.logger.log('info', 'comms', "key?", frame, this.ports[tabs[0].id]);
}
this.logger.info('sendToActive', "currently active tab(s)?", tabs);
for (const frame in this.ports[tabs[0].id]) {
this.logger.info('sendToActive', "sending message to frame:", frame, this.ports[tabs[0].id][frame], '; message:', message);
this.sendToFrameContentScripts(message, tabs[0].id, frame);
}
}
private async processReceivedMessage(message, port, sender?: {frameId: string, tabId: string}){
this.logger.info('processMessage', ` ==> Received message ${message.command ?? ''} from content script or port`, "background-color: #11D; color: #aad", message, port, sender);
// this triggers events
this.eventBus.send(
message.command,
@ -259,7 +269,7 @@ class CommsServer {
}
private processReceivedMessage_nonpersistent(message, sender){
this.logger.log('info', 'comms', "%c[CommsServer.js::processMessage_nonpersistent] Received message from background script!", "background-color: #11D; color: #aad", message, sender);
this.logger.info('processMessage_nonpersistent', ` ==> Received message from background script!`, "background-color: #11D; color: #aad", message, sender);
this.eventBus.send(
message.command,

View File

@ -1,11 +1,11 @@
import EventBus, { EventBusCommand } from '../EventBus';
import Logger from '../Logger';
import { ComponentLogger } from '../logging/ComponentLogger';
import Settings from '../Settings';
import { SiteSettings } from '../settings/SiteSettings';
export class KbmBase {
listenFor: string[] = [];
logger: Logger;
logger: ComponentLogger;
settings: Settings;
siteSettings: SiteSettings;
eventBus: EventBus;
@ -28,7 +28,7 @@ export class KbmBase {
},
}
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger) {
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: ComponentLogger) {
this.logger = logger;
this.settings = settings;
this.eventBus = eventBus;

View File

@ -1,18 +1,19 @@
import Debug from '../../conf/Debug';
import PlayerData from '../video-data/PlayerData';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import Logger from '../Logger';
import PageInfo from '../video-data/PageInfo';
import Settings from '../Settings';
import VideoData from '../video-data/VideoData';
import EventBus, { EventBusCommand } from '../EventBus';
import KbmBase from './KbmBase';
import { SiteSettings } from '../settings/SiteSettings';
import { LogAggregator } from '../logging/LogAggregator';
import { ComponentLogger } from '../logging/ComponentLogger';
if(process.env.CHANNEL !== 'stable'){
console.info("Loading KeyboardHandler");
}
const BASE_LOGGING_STYLES = {
log: "color: #ff0"
};
/**
* Handles keypresses and mouse movement.
*
@ -23,7 +24,6 @@ if(process.env.CHANNEL !== 'stable'){
*/
export class KeyboardHandler extends KbmBase {
listenFor: string[] = ['keyup'];
logger: Logger;
settings: Settings;
siteSettings: SiteSettings;
eventBus: EventBus;
@ -45,14 +45,14 @@ export class KeyboardHandler extends KbmBase {
}
//#region lifecycle
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger) {
super(eventBus, siteSettings, settings, logger);
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logAggregator: LogAggregator) {
const tmpLogger = new ComponentLogger(logAggregator, 'KeyboardHandler', {styles: BASE_LOGGING_STYLES});
super(eventBus, siteSettings, settings, tmpLogger);
this.init();
}
init() {
this.logger.log('info', 'debug', "[KeyboardHandler::init] starting init");
this.logger.debug("init", "starting init");
// reset keypressActions when re-initializing, otherwise keypressActions will
// multiply in an unwanted way
@ -119,28 +119,28 @@ export class KeyboardHandler extends KbmBase {
preventAction(event) {
var activeElement = document.activeElement;
if (this.logger.canLog('keyboard')) {
this.logger.pause(); // temp disable to avoid recursing;
const preventAction = this.preventAction(event);
this.logger.resume(); // undisable
// if (this.logger.canLog('keyboard')) {
// this.logger.pause(); // temp disable to avoid recursing;
// const preventAction = this.preventAction(event);
// this.logger.resume(); // undisable
this.logger.log('info', 'keyboard', "[KeyboardHandler::preventAction] Testing whether we're in a textbox or something. Detailed rundown of conditions:\n" +
"\nis tag one of defined inputs? (yes->prevent):", this.inputs.indexOf(activeElement.tagName.toLocaleLowerCase()) !== -1,
"\nis role = textbox? (yes -> prevent):", activeElement.getAttribute("role") === "textbox",
"\nis type === 'text'? (yes -> prevent):", activeElement.getAttribute("type") === "text",
"\nevent.target.isContentEditable? (yes -> prevent):", event.target.isContentEditable,
"\nis keyboard local disabled? (yes -> prevent):", this.keyboardLocalDisabled,
// "\nis keyboard enabled in settings? (no -> prevent)", this.settings.keyboardShortcutsEnabled(window.location.hostname),
"\nwill the action be prevented? (yes -> prevent)", preventAction,
"\n-----------------{ extra debug info }-------------------",
"\ntag name? (lowercase):", activeElement.tagName, activeElement.tagName.toLocaleLowerCase(),
"\nrole:", activeElement.getAttribute('role'),
"\ntype:", activeElement.getAttribute('type'),
"\ninsta-fail inputs:", this.inputs,
"\nevent:", event,
"\nevent.target:", event.target
);
}
// this.logger.log('info', 'keyboard', "[KeyboardHandler::preventAction] Testing whether we're in a textbox or something. Detailed rundown of conditions:\n" +
// "\nis tag one of defined inputs? (yes->prevent):", this.inputs.indexOf(activeElement.tagName.toLocaleLowerCase()) !== -1,
// "\nis role = textbox? (yes -> prevent):", activeElement.getAttribute("role") === "textbox",
// "\nis type === 'text'? (yes -> prevent):", activeElement.getAttribute("type") === "text",
// "\nevent.target.isContentEditable? (yes -> prevent):", event.target.isContentEditable,
// "\nis keyboard local disabled? (yes -> prevent):", this.keyboardLocalDisabled,
// // "\nis keyboard enabled in settings? (no -> prevent)", this.settings.keyboardShortcutsEnabled(window.location.hostname),
// "\nwill the action be prevented? (yes -> prevent)", preventAction,
// "\n-----------------{ extra debug info }-------------------",
// "\ntag name? (lowercase):", activeElement.tagName, activeElement.tagName.toLocaleLowerCase(),
// "\nrole:", activeElement.getAttribute('role'),
// "\ntype:", activeElement.getAttribute('type'),
// "\ninsta-fail inputs:", this.inputs,
// "\nevent:", event,
// "\nevent.target:", event.target
// );
// }
if (this.keyboardLocalDisabled) {
return true;
@ -213,19 +213,15 @@ export class KeyboardHandler extends KbmBase {
handleKeyup(event) {
// if (!this.keyboardEnabled) {
// this.logger.log('info', 'keyboard', "%c[KeyboardHandler::handleKeyup] kbmHandler.keyboardEnabled is set to false. Doing nothing.");
// return;
// }
this.logger.log('info', 'keyboard', "%c[KeyboardHandler::handleKeyup] we pressed a key: ", "color: #ff0", event.key , " | keyup: ", event.keyup, "event:", event);
this.logger.info('handleKeyup', "we pressed a key: ", event.key , " | keyup: ", event.keyup, "event:", event);
try {
if (this.preventAction(event)) {
this.logger.log('info', 'keyboard', "[KeyboardHandler::handleKeyup] we are in a text box or something. Doing nothing.");
this.logger.info('handleKeyup', "we are in a text box or something. Doing nothing.");
return;
}
this.logger.log('info', 'keyboard', "%c[KeyboardHandler::handleKeyup] Trying to find and execute action for event. Actions/event: ", "color: #ff0", this.keypressActions, event);
this.logger.info('handleKeyup', "Trying to find and execute action for event. Actions/event:", this.keypressActions, event);
const isLatin = this.isLatin(event.key);
for (const command of this.keypressActions) {
@ -234,7 +230,7 @@ export class KeyboardHandler extends KbmBase {
}
}
} catch (e) {
this.logger.log('info', 'debug', '[KeyboardHandler::handleKeyup] Failed to handle keyup!', e);
this.logger.debug('handleKeyup', 'Failed to handle keyup!', e);
}
}

View File

@ -1,5 +1,6 @@
import { LogAggregator } from './../logging/LogAggregator';
import EventBus, { EventBusCommand } from '../EventBus';
import Logger from '../Logger';
import { ComponentLogger } from '../logging/ComponentLogger';
import Settings from '../Settings';
import { SiteSettings } from '../settings/SiteSettings';
import KbmBase from './KbmBase';
@ -9,6 +10,10 @@ if(process.env.CHANNEL !== 'stable'){
}
const BASE_LOGGING_STYLES = {
log: "color: #ff0"
};
/**
* Handles keypress
*/
@ -36,21 +41,21 @@ export class MouseHandler extends KbmBase {
}
//#region lifecycle
constructor(playerElement: HTMLElement, eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger) {
super(eventBus, siteSettings, settings, logger);
constructor(playerElement: HTMLElement, eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logAggregator: LogAggregator) {
const tmpLogger = new ComponentLogger(logAggregator, 'MouseHandler', {styles: BASE_LOGGING_STYLES});
super(eventBus, siteSettings, settings, tmpLogger);
this.logger = logger;
this.settings = settings;
this.siteSettings = siteSettings;
this.eventBus = eventBus;
this.playerElement = playerElement;
this.init();
}
init() {
this.logger.log('info', 'debug', '[MouseHandler::init] starting init');
// this.logger.debug('init', 'starting init');
}
load() {

View File

@ -0,0 +1,70 @@
import { LogAggregator, LogSourceOptions } from './LogAggregator';
export enum LogLevel {
Debug = 'debug',
Info = 'info',
Log = 'log',
Warn = 'warn',
Error = 'error',
}
export type ComponentLoggerOptions = {
styles?: {
[x in LogLevel]?: string;
}
}
export class ComponentLogger {
private logAggregator: LogAggregator;
private component: string;
private componentOptions?: ComponentLoggerOptions;
constructor(logAggregator: LogAggregator, component: string, componentOptions?: ComponentLoggerOptions) {
this.logAggregator = logAggregator;
this.component = component;
}
private handleLog(logLevel: LogLevel, sourceFunction: string | LogSourceOptions, ...message: any) {
let functionSource = typeof sourceFunction === 'string' ? sourceFunction : sourceFunction?.src;
let consoleMessageString = `[${this.component}${functionSource ? `::${functionSource}` : ''}] `;
const consoleMessageData = []
for (const m of message) {
if (typeof m === 'string') {
consoleMessageString = `${consoleMessageString} ${m}`;
} else if (typeof m === 'number') {
consoleMessageString = `${consoleMessageString} %f`;
} else if (m instanceof HTMLElement) {
consoleMessageString = `${consoleMessageString} %o`;
} else {
consoleMessageString = `${consoleMessageString} %O`;
}
}
const style = this.componentOptions?.styles?.[logLevel] ?? this.componentOptions?.styles?.[LogLevel.Log];
if (style) {
consoleMessageString = `%c${consoleMessageString}`;
consoleMessageData.unshift(style);
}
this.logAggregator.log(this.component, logLevel, typeof sourceFunction === 'object' ? sourceFunction : undefined, consoleMessageString, ...consoleMessageData);
}
debug(sourceFunction: string | LogSourceOptions, ...message: any[]) {
this.handleLog(LogLevel.Debug, sourceFunction, ...message);
}
info(sourceFunction: string | LogSourceOptions, ...message: any[]) {
this.handleLog(LogLevel.Info, sourceFunction, ...message);
}
log(sourceFunction: string | LogSourceOptions, ...message: any[]) {
this.handleLog(LogLevel.Log, sourceFunction, ...message);
}
warn(sourceFunction: string | LogSourceOptions, ...message: any[]) {
this.handleLog(LogLevel.Warn, sourceFunction, ...message);
}
error(sourceFunction: string | LogSourceOptions, ...message: any[]) {
this.handleLog(LogLevel.Error, sourceFunction, ...message);
}
}

View File

@ -1,14 +1,218 @@
import { log } from 'console';
export const BLANK_LOGGER_CONFIG: LogConfig = {
logToConsole: false,
logToFile: false,
component: {
aard: { enabled: false },
resizer: { enabled: false },
comms: { enabled: false },
settings: { enabled: false },
eventBus: { enabled: false },
},
origins: {
videoRescan: { disabled: true},
}
}
export interface LogSourceOptions {
src?: string;
origin?: string;
}
export interface LogComponentConfig {
enabled: boolean;
}
export interface LogConfig {
logToConsole?: boolean;
logToFile?: boolean;
stopAfter?: number;
component?: {[x: string]: LogComponentConfig};
origins?: {
videoRescan?: {
disabled: boolean;
}
}
}
export class LogAggregator {
private segment: string;
private config: LogConfig;
private startTime: number;
history: any[];
log(message: any, originData: any) {
static async getConfig() {
let ret = await chrome.storage.local.get('uw-log-config');
if (process.env.CHANNEL === 'dev') {
try {
console.info("[Logger::getSaved] Got settings:", JSON.parse(ret.uwLogger));
} catch (e) {
console.info("[Logger::getSaved] No settings.")
}
}
try {
return JSON.parse(ret['uw-log-config']);
} catch (e) {
return JSON.parse(JSON.stringify(BLANK_LOGGER_CONFIG));
}
}
static saveConfig(conf: LogConfig) {
if (process.env.CHANNEL === 'dev') {
console.info('Saving logger conf:', conf)
}
chrome.storage.local.set( {'uw-log-config': JSON.stringify(conf)});
}
static syncConfig(callback: (x) => void) {
chrome.storage.onChanged.addListener( (changes, area) => {
if (changes.uwLogger) {
const newLoggerConf = JSON.parse(changes.uwLogger.newValue)
if (process.env.CHANNEL === 'dev') {
console.info('Logger settings reloaded. New conf:', newLoggerConf);
}
callback(newLoggerConf);
}
});
}
constructor(segment: string) {
this.segment = segment;
chrome.storage.onChanged.addListener((changes, area) => {
this.storageChangeListener(changes, area)
});
}
private canLog(component: string, sourceOptions?: LogSourceOptions): boolean {
if (this.config?.component?.[component]?.enabled) {
if (sourceOptions?.origin && this.config?.origins?.[sourceOptions.origin]?.disabled) {
return false;
}
return true;
}
return false;
}
private storageChangeListener(changes, area) {
if (!changes.uwLogger) {
console.info('We dont have any logging settings, not processing frther');
return;
}
try {
this.config = JSON.parse(changes['uw-log-config'].newValue);
} catch (e) {
console.warn('[uwLogger] Error while trying to parse new conf for logger:', e, '\nWe received the following changes:', changes, 'for area:', area);
}
// This code can only execute if user tried to enable or disable logging
// through the popup. In cases like this, we do not gate the console.log
// behind a check, since we _always_ want to have this feedback in response
// to an action.
console.info(
'[uwLogger] logger config changed! New configuration:',
this.config, '\nraw changes:', changes, 'area?', area,
'\n————————————————————————————————————————————————————————————————————————\n\n\n\n\n\n\n\n\n\n\n\n-----\nLogging with new settings starts now.'
);
this.init(this.config);
}
private parseStack() {
const trace = (new Error()).stack;
const stackInfo: any = {};
// 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. There can be more
// than one source, too, so we don't break when we find the first one
for (const line of stackInfo.stack.trace) {
if (line === 'doPeriodicPlayerElementChangeCheck') {
stackInfo['periodicPlayerCheck'] = true;
} else if (line === 'doPeriodicFallbackChangeDetectionCheck') {
stackInfo['periodicVideoStyleChangeCheck'] = true;
} else if (line === 'frameCheck') {
stackInfo['aard'] = true;
} else if (line === 'execAction') {
stackInfo['keyboard'] = true;
} else if (line === 'processReceivedMessage') {
stackInfo['popup'] = true;
} else if (line === 'handleMouseMove') {
stackInfo['mousemove'] = true;
}
}
// 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;
}
// TODO: implement this
private stopLogging() {
}
async init(config: LogConfig) {
this.config = config;
this.startTime = performance.now();
if (this.config?.stopAfter) {
setTimeout(
() => {
this.stopLogging();
},
this.config.stopAfter * 1000
);
}
}
log(component: string, logLevel: string, sourceOptions: LogSourceOptions, message: string, ...data: any[]) {
if (! this.canLog(component, sourceOptions)) {
return;
}
if (this.config.logToFile) {
}
if (this.config.logToConsole) {
console[logLevel](`[${this.segment}]>>${message}`, ...data, {stack: this.parseStack()});
}
}
}

View File

@ -1,15 +1,12 @@
import Debug from '../../conf/Debug';
import VideoData from './VideoData';
import RescanReason from './enums/RescanReason.enum';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
import Logger from '../Logger';
import Settings from '../Settings';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import CommsClient from '../comms/CommsClient';
import EventBus from '../EventBus';
import { SiteSettings } from '../settings/SiteSettings';
import IframeManager from './IframeManager';
import { LogAggregator } from '../logging/LogAggregator';
import { ComponentLogger } from '../logging/ComponentLogger';
if (process.env.CHANNEL !== 'stable'){
console.info("Loading PageInfo");
@ -52,7 +49,8 @@ class PageInfo {
//#endregion
//#region helper objects
logger: Logger;
logAggregator: LogAggregator;
logger: ComponentLogger;
settings: Settings;
siteSettings: SiteSettings;
comms: CommsClient;
@ -80,8 +78,9 @@ class PageInfo {
}
};
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logger: Logger, readOnly = false){
this.logger = logger;
constructor(eventBus: EventBus, siteSettings: SiteSettings, settings: Settings, logAggregator: LogAggregator, readOnly = false){
this.logAggregator = logAggregator;
this.logger = new ComponentLogger(logAggregator, 'PageInfo', {});
this.settings = settings;
this.siteSettings = siteSettings;
@ -109,10 +108,18 @@ class PageInfo {
this.scheduleUrlCheck();
document.addEventListener('fullscreenchange', this.fsEventListener);
this.eventBus.subscribeMulti({
'probe-video': {
function: () => {
console.warn('[uw] probe-video event received..');
}
}
})
}
destroy() {
// this.logger.log('info', ['debug', 'init'], "[PageInfo::destroy] destroying all videos!")
// this.logger.debug('destroy', 'destroying all videos!")
if(this.rescanTimer){
clearTimeout(this.rescanTimer);
}
@ -121,7 +128,7 @@ class PageInfo {
this.eventBus.send('noVideo', undefined);
video.videoData.destroy();
} catch (e) {
this.logger.log('error', ['debug', 'init'], '[PageInfo::destroy] unable to destroy video! Error:', e);
this.logger.error('destroy', 'unable to destroy video! Error:', e);
}
}
@ -228,7 +235,7 @@ class PageInfo {
this.hasVideos = false;
if(rescanReason == RescanReason.PERIODIC){
this.logger.log('info', 'videoRescan', "[PageInfo::rescan] Scheduling normal rescan.")
this.logger.info({src: 'rescan', origin: 'videoRescan'}, "Scheduling normal rescan.")
this.scheduleRescan(RescanReason.PERIODIC);
}
return;
@ -265,16 +272,16 @@ class PageInfo {
return;
}
this.logger.log('info', 'videoRescan', "[PageInfo::rescan] found new video candidate:", videoElement, "NOTE:: Video initialization starts here:\n--------------------------------\n")
this.logger.info({src: 'rescan', origin: 'videoRescan'}, "found new video candidate:", videoElement, "NOTE:: Video initialization starts here:\n--------------------------------\n")
try {
const newVideo = new VideoData(videoElement, this.settings, this.siteSettings, this);
this.videos.push({videoData: newVideo, element: videoElement});
} catch (e) {
this.logger.log('error', 'debug', "rescan error: failed to initialize videoData. Skipping this video.",e);
this.logger.error('rescan', "rescan error: failed to initialize videoData. Skipping this video.",e);
}
this.logger.log('info', 'videoRescan', "END VIDEO INITIALIZATION\n\n\n-------------------------------------\nvideos[] is now this:", this.videos,"\n\n\n\n\n\n\n\n")
this.logger.info({src: 'rescan', origin: 'videoRescan'}, "END VIDEO INITIALIZATION\n\n\n-------------------------------------\nvideos[] is now this:", this.videos,"\n\n\n\n\n\n\n\n")
}
this.removeDestroyed();
@ -313,7 +320,7 @@ class PageInfo {
// if we encounter a fuckup, we can assume that no videos were found on the page. We destroy all videoData
// objects to prevent multiple initialization (which happened, but I don't know why). No biggie if we destroyed
// videoData objects in error — they'll be back in the next rescan
this.logger.log('error', 'debug', "rescan error: — destroying all videoData objects",e);
this.logger.error('rescan', "rescan error: — destroying all videoData objects",e);
for (const v of this.videos) {
v.videoData.destroy();
}
@ -348,7 +355,7 @@ class PageInfo {
ths = null;
}, this.settings.active.pageInfo.timeouts.rescan, RescanReason.PERIODIC)
} catch(e) {
this.logger.log('error', 'debug', "[PageInfo::scheduleRescan] scheduling rescan failed. Here's why:",e)
this.logger.error('scheduleRescan', "scheduling rescan failed. Here's why:",e)
}
}
@ -366,13 +373,13 @@ class PageInfo {
ths = null;
}, this.settings.active.pageInfo.timeouts.urlCheck)
} catch(e){
this.logger.log('error', 'debug', "[PageInfo::scheduleUrlCheck] scheduling URL check failed. Here's why:",e)
this.logger.log('scheduleUrlCheck', "scheduling URL check failed. Here's why:",e)
}
}
ghettoUrlCheck() {
if (this.lastUrl != window.location.href){
this.logger.log('error', 'videoRescan', "[PageInfo::ghettoUrlCheck] URL has changed. Triggering a rescan!");
this.logger.warn('ghettoUrlCheck', "URL has changed. Triggering a rescan!");
this.rescan(RescanReason.URL_CHANGE);
this.lastUrl = window.location.href;

View File

@ -1,19 +1,16 @@
import Debug from '../../conf/Debug';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum'
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import PlayerNotificationUi from '../uwui/PlayerNotificationUI';
import BrowserDetect from '../../conf/BrowserDetect';
import * as _ from 'lodash';
import { sleep } from '../../../common/js/utils';
import VideoData from './VideoData';
import Settings from '../Settings';
import Logger from '../Logger';
import EventBus from '../EventBus';
import UI from '../uwui/UI';
import { SiteSettings } from '../settings/SiteSettings';
import PageInfo from './PageInfo';
import { RunLevel } from '../../enum/run-level.enum';
import { ExtensionEnvironment } from '../../../common/interfaces/SettingsInterface';
import { ComponentLogger } from '../logging/ComponentLogger';
if (process.env.CHANNEL !== 'stable'){
console.info("Loading: PlayerData.js");
@ -69,7 +66,7 @@ class PlayerData {
private playerCssClass = 'uw-ultrawidify-player-css';
//#region helper objects
logger: Logger;
logger: ComponentLogger;
videoData: VideoData;
pageInfo: PageInfo;
siteSettings: SiteSettings;
@ -193,7 +190,7 @@ class PlayerData {
constructor(videoData) {
try {
// set all our helper objects
this.logger = videoData.logger;
this.logger = new ComponentLogger(videoData.logAggregator, 'PlayerData', {styles: Debug.getLoggingStyles()});
this.videoData = videoData;
this.videoElement = videoData.video;
this.pageInfo = videoData.pageInfo;
@ -457,13 +454,13 @@ class PlayerData {
private handleDimensionChanges(newDimensions: PlayerDimensions, oldDimensions: PlayerDimensions) {
if (this.runLevel === RunLevel.Off ) {
this.logger.log('info', 'debug', "[PlayerDetect] player size changed, but PlayerDetect is in disabled state. The player element is probably too small.");
this.logger.info('handleDimensionChanges', "player size changed, but PlayerDetect is in disabled state. The player element is probably too small.");
return;
}
// 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)
this.logger.log('info', 'debug', "[PlayerDetect] player size potentially changed.\n\nold dimensions:", oldDimensions, '\nnew dimensions:', newDimensions);
this.logger.info('handleDimensionChanges', "player size potentially changed.\n\nold dimensions:", oldDimensions, '\nnew dimensions:', newDimensions);
// if size doesn't match, trigger onPlayerDimensionChange
if (

View File

@ -1,11 +1,7 @@
import Debug from '../../conf/Debug';
import PlayerData from './PlayerData';
import Resizer from '../video-transform/Resizer';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
import * as _ from 'lodash';
import BrowserDetect from '../../conf/BrowserDetect';
import Logger from '../Logger';
import Settings from '../Settings';
import PageInfo from './PageInfo';
import { sleep } from '../../../common/js/utils';
@ -19,6 +15,8 @@ import { Aard } from '../aard/Aard';
import { Stretch } from '../../../common/interfaces/StretchInterface';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import { ExtensionEnvironment } from '../../../common/interfaces/SettingsInterface';
import { LogAggregator } from '../logging/LogAggregator';
import { ComponentLogger } from '../logging/ComponentLogger';
/**
* VideoData handles CSS for the video element.
@ -67,7 +65,8 @@ class VideoData {
//#endregion
//#region helper objects
logger: Logger;
logger: ComponentLogger;
logAggregator: LogAggregator
settings: Settings; // AARD needs it
siteSettings: SiteSettings;
pageInfo: PageInfo;
@ -117,7 +116,9 @@ class VideoData {
* @param pageInfo
*/
constructor(video, settings: Settings, siteSettings: SiteSettings, pageInfo: PageInfo){
this.logger = pageInfo.logger;
this.logAggregator = pageInfo.logAggregator;
this.logger = new ComponentLogger(this.logAggregator, 'VideoData', {});
this.arSetupComplete = false;
this.video = video;
this.destroyed = false;
@ -167,7 +168,7 @@ class VideoData {
if (!this.video?.videoWidth || !this.video?.videoHeight || this.video.readyState < 2) {
return; // onVideoLoaded is a lie in this case
}
this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— Initiating phase two of videoData setup ———————————', 'color: #0f9');
this.logger.info('onVideoLoaded', '%c ——————————— Initiating phase two of videoData setup ———————————', 'color: #0f9');
this.hasDrm = hasDrm(this.video);
this.eventBus.send(
@ -179,12 +180,12 @@ class VideoData {
this.videoDimensionsLoaded = true;
try {
await this.setupStageTwo();
this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— videoData setup stage two complete ———————————', 'color: #0f9');
this.logger.info('onVideoLoaded', '%c——————————— videoData setup stage two complete ———————————', 'color: #0f9');
} catch (e) {
this.logger.log('error', 'init', '%c[VideoData::onVideoLoaded] ——————————— Setup stage two failed. ———————————\n', 'color: #f00', e);
this.logger.error('onVideoLoaded', '%c ——————————— Setup stage two failed. ———————————\n', 'color: #f00', e);
}
} else if (!this.videoDimensionsLoaded) {
this.logger.log('info', 'debug', "%c[VideoData::restoreCrop] Recovering from illegal video dimensions. Resetting aspect ratio.", "background: #afd, color: #132");
this.logger.debug('onVideoLoaded', "%cRecovering from illegal video dimensions. Resetting aspect ratio.", "background: #afd, color: #132");
this.restoreCrop();
this.videoDimensionsLoaded = true;
@ -213,11 +214,11 @@ class VideoData {
//#region <video> event handlers
onLoadedData() {
this.logger.log('info', 'init', '[VideoData::ctor->video.onloadeddata] Video fired event "loaded data!"');
this.logger.info('onLoadedData', 'Video fired event "loaded data!"');
this.onVideoLoaded();
}
onLoadedMetadata() {
this.logger.log('info', 'init', '[VideoData::ctor->video.onloadedmetadata] Video fired event "loaded metadata!"');
this.logger.log('onLoadedData', 'Video fired event "loaded metadata!"');
this.onVideoLoaded();
}
onTimeUpdate() {
@ -231,7 +232,7 @@ class VideoData {
* Sets up event listeners for this video
*/
async setupEventListeners() {
this.logger.log('info', 'init', '%c[VideoData::setupEventListeners] ——————————— Starting event listener setup! ———————————', 'color: #0f9');
this.logger.info('setupEventListeners', '%c——————————— Starting event listener setup! ———————————', 'color: #0f9');
// this is in case extension loads before the video
this.video.addEventListener('loadeddata', this.onLoadedData.bind(this));
@ -240,7 +241,7 @@ class VideoData {
// this one is in case extension loads after the video is loaded
this.video.addEventListener('timeupdate', this.onTimeUpdate.bind(this));
this.logger.log('info', 'init', '%c[VideoData::setupEventListeners] ——————————— Event listeners setup complete! ———————————', 'color: #0f9');
this.logger.info('setupEventListeners', '%c——————————— Event listeners setup complete! ———————————', 'color: #0f9');
}
/**
@ -264,7 +265,7 @@ class VideoData {
}
this.logger.log('info', ['debug', 'init'], '[VideoData::ctor] Created videoData with vdid', this.vdid);
this.logger.info('setupStageTwo', 'Created videoData with vdid', this.vdid);
// Everything is set up at this point. However, we are still purely "read-only" at this point. Player CSS should not be changed until
@ -363,7 +364,7 @@ class VideoData {
* cleans up handlers and stuff when the show is over
*/
destroy() {
this.logger.log('info', ['debug', 'init'], `[VideoData::destroy] <vdid:${this.vdid}> received destroy command`);
this.logger.info('destroy', `<vdid:${this.vdid}> received destroy command`);
if (this.video) {
this.video.classList.remove(this.userCssClassName);
@ -403,7 +404,8 @@ class VideoData {
return;
}
if (this.currentEnvironment !== this.player.environment) {
console.warn('environment changed to:', this.player.environment);
this.logger.warn('onEnvironmentChanged', 'environment changed from:', this.currentEnvironment, 'to:', this.player.environment);
this.currentEnvironment = this.player.environment;
if (this.siteSettings.data.enable[this.player.environment] === ExtensionMode.Disabled) {
this.setRunLevel(RunLevel.Off);
@ -473,10 +475,10 @@ class VideoData {
restoreCrop() {
if (!this.resizer) {
this.logger.log('warn', 'debug', '[VideoData::restoreCrop] Resizer has not been initialized yet. Crop will not be restored.');
this.logger.warn('restoreCrop', 'Resizer has not been initialized yet. Crop will not be restored.');
return;
}
this.logger.log('info', 'debug', '[VideoData::restoreCrop] Attempting to reset aspect ratio.')
this.logger.info('restoreCrop', 'Attempting to reset aspect ratio.');
// if we have default crop set for this page, apply this.
// otherwise, reset crop
@ -489,7 +491,7 @@ class VideoData {
this.stopArDetection();
this.startArDetection();
} catch (e) {
this.logger.log('warn', 'debug', '[VideoData::restoreCrop] Autodetection not resumed. Reason:', e);
this.logger.warn('restoreCrop', 'Autodetection not resumed. Reason:', e);
}
}
}
@ -516,13 +518,13 @@ class VideoData {
let confirmAspectRatioRestore = false;
if (!this.video) {
this.logger.log('error', 'debug', '[VideoData::onVideoMutation] mutation was triggered, but video element is missing. Something is fishy. Terminating this uw instance.');
this.logger.error('onVideoMutation', 'mutation was triggered, but video element is missing. Something is fishy. Terminating this uw instance.');
this.destroy();
return;
}
if (!this.enabled) {
this.logger.log('info', 'info', '[VideoData::onVideoMutation] mutation was triggered, but the extension is disabled. Is the player window too small?');
this.logger.info('onVideoMutation', 'mutation was triggered, but the extension is disabled. Is the player window too small?');
return;
}
@ -552,8 +554,8 @@ class VideoData {
onVideoDimensionsChanged(mutationList, observer) {
if (!mutationList || this.video === undefined) { // something's wrong
if (observer && this.video) {
this.logger.log(
'warn', 'debug',
this.logger.warn(
'onVideoDimensionChanged',
'onVideoDimensionChanged encountered a weird state. video and observer exist, but mutationlist does not.\n\nmutationList:', mutationList,
'\nobserver:', observer,
'\nvideo:', this.video,
@ -573,7 +575,7 @@ class VideoData {
*/
private _processDimensionsChanged() {
if (!this.player) {
this.logger.log('warn', 'debug', `[VideoData::_processDimensionsChanged] Player is not defined. This is super haram.`, this.player);
this.logger.warn('_processDimensionsChanged', `Player is not defined. This is super haram.`, this.player);
return;
}
// adding player observer taught us that if element size gets triggered by a class, then
@ -706,7 +708,7 @@ class VideoData {
startArDetection() {
this.logger.log('info', 'debug', "[VideoData::startArDetection] starting AR detection")
this.logger.info('startArDetection', 'starting AR detection');
if(this.destroyed || this.invalid) {
// throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}};
return;
@ -725,7 +727,7 @@ class VideoData {
}
this.aard.startCheck();
} catch (e) {
this.logger.log('warn', 'debug', '[VideoData::startArDetection()] Could not start aard for some reason. Was the function was called too early?', e);
this.logger.warn('startArDetection', 'Could not start aard for some reason. Was the function was called too early?', e);
}
}
@ -754,17 +756,16 @@ class VideoData {
checkVideoSizeChange(){
const videoWidth = this.video.offsetWidth;
const videoHeight = this.video.offsetHeight;
// 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.video) {
this.logger.log('info', 'videoDetect', "[VideoDetect] player element isn't defined");
this.logger.warn('checkVideoSizeChange', "player element isn't defined");
}
if ( this.video &&
( this.dimensions?.width != videoWidth ||
this.dimensions?.height != videoHeight )
( 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);
this.logger.debug('checkVideoSizeChange', "player size changed. reason: dimension change. Old dimensions?", this.dimensions.width, this.dimensions.height, "new dimensions:", this.video.offsetWidth, this.video.offsetHeight);
}
}

View File

@ -3,15 +3,9 @@ import Debug from '../../conf/Debug';
import Scaler, { CropStrategy, VideoDimensions } from './Scaler';
import Stretcher from './Stretcher';
import Zoom from './Zoom';
import PlayerData from '../video-data/PlayerData';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import StretchType from '../../../common/enums/StretchType.enum';
import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import CropModePersistance from '../../../common/enums/CropModePersistence.enum';
import { sleep } from '../Util';
import Logger from '../Logger';
import siteSettings from '../Settings';
import VideoData from '../video-data/VideoData';
import EventBus from '../EventBus';
import { _cp } from '../../../common/js/utils';
@ -21,6 +15,7 @@ import { RunLevel } from '../../enum/run-level.enum';
import * as _ from 'lodash';
import getElementStyles from '../../util/getElementStyles';
import { Stretch } from '../../../common/interfaces/StretchInterface';
import { ComponentLogger } from '../logging/ComponentLogger';
if(Debug.debug) {
console.log("Loading: Resizer.js");
@ -46,7 +41,7 @@ class Resizer {
//#endregion
//#region helper objects
logger: Logger;
logger: ComponentLogger;
settings: Settings;
siteSettings: SiteSettings;
scaler: Scaler;
@ -180,7 +175,7 @@ class Resizer {
constructor(videoData) {
this.resizerId = (Math.random()*100).toFixed(0);
this.videoData = videoData;
this.logger = videoData.logger;
this.logger = new ComponentLogger(videoData.logAggregator, 'Resizer');
this.video = videoData.video;
this.settings = videoData.settings;
this.siteSettings = videoData.siteSettings;
@ -234,7 +229,7 @@ class Resizer {
}
destroy(){
this.logger.log('info', ['debug', 'init'], `[Resizer::destroy] <rid:${this.resizerId}> received destroy command.`);
this.logger.info('destroy', `<rid:${this.resizerId}> received destroy command.`);
this.destroyed = true;
}
@ -251,7 +246,7 @@ class Resizer {
let ratioOut;
if (!this.videoData.video) {
this.logger.log('info', 'debug', "[Scaler.js::modeToAr] No video??",this.videoData.video, "killing videoData");
this.logger.info('calculateRatioForLegacyOptions', "No video??", this.videoData.video, "killing videoData");
this.videoData.destroy();
return null;
}
@ -260,7 +255,7 @@ class Resizer {
if (! this.videoData.player.dimensions) {
ratioOut = screen.width / screen.height;
} else {
this.logger.log('info', 'debug', `[Resizer::calculateRatioForLegacyOptions] <rid:${this.resizerId}> Player dimensions:`, this.videoData.player.dimensions.width ,'x', this.videoData.player.dimensions.height,'aspect ratio:', this.videoData.player.dimensions.width / this.videoData.player.dimensions.height)
this.logger.info('calculateRatioForLegacyOptions', `<rid:${this.resizerId}> Player dimensions:`, this.videoData.player.dimensions.width ,'x', this.videoData.player.dimensions.height,'aspect ratio:', this.videoData.player.dimensions.width / this.videoData.player.dimensions.height)
ratioOut = this.videoData.player.dimensions.width / this.videoData.player.dimensions.height;
}
@ -276,7 +271,7 @@ class Resizer {
ar.ratio = ratioOut < fileAr ? ratioOut : fileAr;
}
else if(ar.type === AspectRatioType.Reset){
this.logger.log('info', 'debug', "[Scaler.js::modeToAr] Using original aspect ratio -", fileAr);
this.logger.info('modeToAr', "Using original aspect ratio -", fileAr);
ar.ratio = fileAr;
} else {
return null;
@ -350,11 +345,11 @@ class Resizer {
}
if (!this.video.videoWidth || !this.video.videoHeight) {
this.logger.log('warning', 'debug', '[Resizer::setAr] <rid:'+this.resizerId+'> Video has no width or no height. This is not allowed. Aspect ratio will not be set, and videoData will be uninitialized.');
this.logger.warn('setAr', `<rid:${this.resizerId}> Video has no width or no height. This is not allowed. Aspect ratio will not be set, and videoData will be uninitialized.`);
this.videoData.videoUnloaded();
}
this.logger.log('info', 'debug', '%c[Resizer::setAr] <rid:'+this.resizerId+'> trying to set ar. New ar:', 'background-color: #4c3a2f, color: #ffa349', ar);
this.logger.info('setAr', `<rid:${this.resizerId}> trying to set ar. New ar:`, ar);
let stretchFactors: VideoDimensions | any;
@ -391,7 +386,7 @@ class Resizer {
// I'm not sure whether they do. Check that.
ar = this.calculateRatioForLegacyOptions(ar);
if (! ar) {
this.logger.log('info', 'resizer', `[Resizer::setAr] <${this.resizerId}> Something wrong with ar or the player. Doing nothing.`);
this.logger.info('setAr', `<rid:${this.resizerId}> Something wrong with ar or the player. Doing nothing.`);
return;
}
this.lastAr = {type: ar.type, ratio: ar.ratio};
@ -406,7 +401,7 @@ class Resizer {
stretchFactors = this.scaler.calculateCrop(ar);
if (!stretchFactors || stretchFactors.error){
this.logger.log('error', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> failed to set AR due to problem with calculating crop. Error:`, stretchFactors?.error);
this.logger.error('setAr', ` <rid:${this.resizerId}> failed to set AR due to problem with calculating crop. Error:`, stretchFactors?.error);
if (stretchFactors?.error === 'no_video'){
this.videoData.destroy();
return;
@ -427,24 +422,24 @@ class Resizer {
} else if (this.stretcher.stretch.type === StretchType.FixedSource) {
this.stretcher.applyStretchFixedSource(stretchFactors);
}
this.logger.log('info', 'debug', "[Resizer::setAr] Processed stretch factors for ",
this.logger.info('setAr', "Processed stretch factors for ",
this.stretcher.stretch.type === StretchType.NoStretch ? 'stretch-free crop.' :
this.stretcher.stretch.type === StretchType.Conditional ? 'crop with conditional StretchType.' : 'crop with fixed stretch',
'Stretch factors are:', stretchFactors
);
} else if (this.stretcher.stretch.type === StretchType.Hybrid) {
stretchFactors = this.stretcher.calculateStretch(ar.ratio);
this.logger.log('info', 'debug', '[Resizer::setAr] Processed stretch factors for hybrid stretch/crop. Stretch factors are:', stretchFactors);
this.logger.info('setAr', 'Processed stretch factors for hybrid stretch/crop. Stretch factors are:', stretchFactors);
} else if (this.stretcher.stretch.type === StretchType.Fixed) {
stretchFactors = this.stretcher.calculateStretchFixed(ar.ratio);
} else if (this.stretcher.stretch.type === StretchType.Basic) {
stretchFactors = this.stretcher.calculateBasicStretch();
this.logger.log('info', 'debug', '[Resizer::setAr] Processed stretch factors for basic StretchType. Stretch factors are:', stretchFactors);
this.logger.log('setAr', 'Processed stretch factors for basic StretchType. Stretch factors are:', stretchFactors);
} else {
stretchFactors = this.scaler.calculateCrop(ar);
this.logger.log(
'error', 'debug',
'[Resizer::setAr] Okay wtf happened? If you see this, something has gone wrong. Pretending stretchMode is set tu NoStretch. Stretch factors are:', stretchFactors,
this.logger.error(
'setAr',
'Okay wtf happened? If you see this, something has gone wrong. Pretending stretchMode is set tu NoStretch. Stretch factors are:', stretchFactors,
"\n------[ i n f o d u m p ]------\nstretcher:", this.stretcher,
'\nargs: ar (corrected for legacy):', ar, 'last ar (optional argument):', lastAr
);
@ -501,7 +496,7 @@ class Resizer {
const relativeX = (event.pageX - player.offsetLeft) / player.offsetWidth;
const relativeY = (event.pageY - player.offsetTop) / player.offsetHeight;
this.logger.log('info', 'mousemove', "[Resizer::panHandler] mousemove.pageX, pageY:", event.pageX, event.pageY, "\nrelativeX/Y:", relativeX, relativeY)
this.logger.info({src: 'panHandler', origin: 'mousemove'}, "mousemove.pageX, pageY:", event.pageX, event.pageY, "\nrelativeX/Y:", relativeX, relativeY);
this.setPan(relativeX, relativeY);
}
@ -564,7 +559,7 @@ class Resizer {
*/
restore() {
if (!this.manualZoom) {
this.logger.log('info', 'debug', "[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio", {'lastAr': this.lastAr} );
this.logger.info('restore', `<rid:${this.resizerId}> attempting to restore aspect ratio`, {'lastAr': this.lastAr} );
// this is true until we verify that css has actually been applied
if(this.lastAr.type === AspectRatioType.Initial){
@ -749,7 +744,7 @@ class Resizer {
private _computeOffsetsRecursionGuard: boolean = false;
computeOffsets(stretchFactors: VideoDimensions, ar?: Ar){
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment, '— stretch factors before processing:', stretchFactors);
this.logger.info('computeOffsets', `<rid:${this.resizerId}> video will be aligned to `, this.videoAlignment, '— stretch factors before processing:', stretchFactors);
const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();
@ -817,8 +812,9 @@ class Resizer {
}
}
this.logger.log(
'info', ['debug', 'resizer'], "[Resizer::_res_computeOffsets] <rid:"+this.resizerId+"> calculated offsets:",
this.logger.info(
'computeOffsets',
`<rid:${this.resizerId}> calculated offsets:`,
'\n\n---- elements ----',
'\nplayer element: ', this.videoData.player.element,
'\nvideo element: ', this.videoData.video,
@ -851,10 +847,10 @@ class Resizer {
(this.videoData.video.offsetWidth < this.videoData.player.dimensions.width && this.videoData.video.offsetHeight < this.videoData.player.dimensions.height)
) && ar?.variant !== ArVariant.Zoom
) {
this.logger.log('warn', ['debugger', 'resizer'], `[Resizer::_res_computeOffsets] <rid:${this.resizerId}> We are getting some incredibly funny results here.\n\n`,
this.logger.warn('computeOffsets', `<rid:${this.resizerId}> We are getting some incredibly funny results here.\n\n`,
`Video seems to be both wider and taller (or shorter and narrower) than player element at the same time. This is super duper not supposed to happen.\n\n`,
`Player element needs to be checked.`
)
);
// sometimes this appears to randomly recurse.
// There seems to be no way to reproduce it.
@ -928,13 +924,13 @@ class Resizer {
// apply extra CSS here. In case of duplicated properties, extraCss overrides
// default styleString
if (! this.video) {
this.logger.log('warn', 'debug', "[Resizer::applyCss] <rid:"+this.resizerId+"> Video went missing, doing nothing.");
this.logger.warn('applyCss', `<rid:${this.resizerId}> Video went missing, doing nothing.`);
this.videoData.destroy();
return;
}
this.logger.log('info', ['debug', 'resizer'], "[Resizer::applyCss] <rid:"+this.resizerId+"> will apply css.", {stretchFactors, translate});
this.logger.info('applyCss', `<rid:${this.resizerId}> will apply css.`, {stretchFactors, translate});
// save stuff for quick tests (before we turn numbers into css values):
this.currentVideoSettings = {
@ -969,18 +965,18 @@ class Resizer {
// inject new CSS or replace existing one
if (!this.userCss) {
this.logger.log('info', ['debug', 'resizer'], "[Resizer::setStyleString] <rid:"+this.resizerId+"> Setting new css: ", newCssString);
this.logger.debug('setStyleString', `<rid:${this.resizerId}> Setting new css: `, newCssString);
this.eventBus.send('inject-css', {cssString: newCssString});
this.userCss = newCssString;
} else if (newCssString !== this.userCss) {
this.logger.log('info', ['debug', 'resizer'], "[Resizer::setStyleString] <rid:"+this.resizerId+"> Replacing css.\nOld string:", this.userCss, "\nNew string:", newCssString);
this.logger.debug('setStyleString', `<rid:${this.resizerId}}> Replacing css.\nOld string:`, this.userCss, "\nNew string:", newCssString)
// we only replace css if it
this.eventBus.send('replace-css', {oldCssString: this.userCss, newCssString});
this.userCss = newCssString;
} else {
this.logger.log('info', ['debug', 'resizer'], "[Resizer::setStyleString] <rid:"+this.resizerId+"> Existing css is still valid, doing nothing.");
this.logger.debug('setStyleString', `<rid:${this.resizerId}> Existing css is still valid, doing nothing.`);
}
}

View File

@ -1,9 +1,7 @@
import Debug from '../../conf/Debug';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import BrowserDetect from '../../conf/BrowserDetect';
import VideoData from '../video-data/VideoData';
import Logger from '../Logger';
import { Ar, ArVariant } from '../../../common/interfaces/ArInterface';
import { ComponentLogger } from '../logging/ComponentLogger';
export enum CropStrategy {
@ -46,13 +44,13 @@ export type VideoDimensions = {
class Scaler {
//#region helper objects
conf: VideoData;
logger: Logger;
logger: ComponentLogger;
//#endregion
// functions
constructor(videoData) {
this.conf = videoData;
this.logger = videoData.logger;
this.logger = new ComponentLogger(videoData.logAggregator, 'Scaler', {});
}
@ -65,7 +63,7 @@ class Scaler {
let ratioOut;
if (!this.conf.video) {
this.logger.log('error', 'debug', "[Scaler.js::modeToAr] No video??",this.conf.video, "killing videoData");
this.logger.error('modeToAr', "No video??",this.conf.video, "killing videoData");
this.conf.destroy();
return null;
}
@ -93,7 +91,7 @@ class Scaler {
return ratioOut;
}
else if (ar.type === AspectRatioType.Reset) {
this.logger.log('info', 'debug', "[Scaler.js::modeToAr] Using original aspect ratio -", fileAr)
this.logger.info('modeToAr', "Using original aspect ratio -", fileAr)
ar.ar = fileAr;
return fileAr;
}
@ -137,7 +135,7 @@ class Scaler {
}
if(!this.conf.video){
this.logger.log('info', 'debug', "[Scaler::calculateCrop] ERROR — no video detected. Conf:", this.conf, "video:", this.conf.video, "video dimensions:", this.conf.video && this.conf.video.videoWidth, '×', this.conf.video && this.conf.video.videoHeight);
this.logger.info('calculateCrop', "ERROR — no video detected. Conf:", this.conf, "video:", this.conf.video, "video dimensions:", this.conf.video && this.conf.video.videoWidth, '×', this.conf.video && this.conf.video.videoHeight);
this.conf.destroy();
return {error: "no_video"};
@ -145,7 +143,7 @@ class Scaler {
if (this.conf.video.videoWidth == 0 || this.conf.video.videoHeight == 0) {
// that's illegal, but not illegal enough to just blast our shit to high hell
// mr officer will let you go with a warning this time around
this.logger.log('error', 'debug', "[Scaler::calculateCrop] Video has illegal dimensions. Video dimensions:", this.conf.video && this.conf.video.videoWidth, '×', this.conf.video && this.conf.video.videoHeight);
this.logger.error('calculateCrop', "Video has illegal dimensions. Video dimensions:", this.conf.video && this.conf.video.videoWidth, '×', this.conf.video && this.conf.video.videoHeight);
return {error: "illegal_video_dimensions"};
}
@ -165,16 +163,16 @@ class Scaler {
// handle fuckie-wuckies
if (!ar.ratio){
this.logger.log('error', 'scaler', "[Scaler::calculateCrop] no ar?", ar.ratio, " -- we were given this mode:", ar);
this.logger.error('calculateCrop', "no ar?", ar.ratio, " -- we were given this mode:", ar);
return {error: "no_ar", ratio: ar.ratio};
}
this.logger.log('info', 'scaler', "[Scaler::calculateCrop] trying to set ar. args are: ar->",ar.ratio,"; this.conf.player.dimensions->",this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions);
this.logger.info('calculateCrop', "trying to set ar. args are: ar->",ar.ratio,"; this.conf.player.dimensions->",this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions);
// If we encounter invalid players, we try to update its dimensions
// ONCE before throwing an error
if( (! this.conf.player.dimensions) || this.conf.player.dimensions.width === 0 || this.conf.player.dimensions.height === 0 ){
this.logger.log('error', 'scaler', "[Scaler::calculateCrop] ERROR — no (or invalid) this.conf.player.dimensions:",this.conf.player.dimensions);
this.logger.error('calculateCrop', "ERROR — no (or invalid) this.conf.player.dimensions:",this.conf.player.dimensions);
this.conf.player.updatePlayer();
if( (! this.conf.player.dimensions) || this.conf.player.dimensions.width === 0 || this.conf.player.dimensions.height === 0 ){
@ -191,7 +189,7 @@ class Scaler {
}
this.logger.log('info', 'scaler', "[Scaler::calculateCrop] ar is " ,ar.ratio, ", file ar is", streamAr, ",ar variant", ar.variant ,"\nthis.conf.player.dimensions are ", this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions, this.conf.player.element);
this.logger.info('calculateCrop', "ar is " ,ar.ratio, ", file ar is", streamAr, ",ar variant", ar.variant ,"\nthis.conf.player.dimensions are ", this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions, this.conf.player.element);
const videoDimensions: VideoDimensions = {
xFactor: 1,

View File

@ -1,11 +1,9 @@
import { SiteSettings } from './../settings/SiteSettings';
import StretchType from '../../../common/enums/StretchType.enum';
import BrowserDetect from '../../conf/BrowserDetect';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import VideoData from '../video-data/VideoData';
import Logger from '../Logger';
import Settings from '../Settings';
import { Stretch } from '../../../common/interfaces/StretchInterface';
import { ComponentLogger } from '../logging/ComponentLogger';
// računa vrednosti za transform-scale (x, y)
// transform: scale(x,y) se uporablja za raztegovanje videa, ne pa za približevanje
@ -19,7 +17,7 @@ class Stretcher {
//#region helper objects
conf: VideoData;
logger: Logger;
logger: ComponentLogger;
settings: Settings;
siteSettings: SiteSettings;
//#endregion
@ -29,7 +27,7 @@ class Stretcher {
// functions
constructor(videoData) {
this.conf = videoData;
this.logger = videoData.logger;
this.logger = new ComponentLogger(videoData.logAggregator, 'Stretcher', {});;
this.siteSettings = videoData.siteSettings;
this.settings = videoData.settings;
@ -111,7 +109,7 @@ class Stretcher {
// * we squeeze X axis, if target AR is narrower than player size
// * we squeeze Y axis, if target AR is wider than the player size
this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we got:
this.logger.info('applyStretchFixedSource', `here's what we got:
postCropStretchFactors: x=${postCropStretchFactors.xFactor} y=${postCropStretchFactors.yFactor}
fixedStretchRatio: ${this.stretch.ratio}
videoAr: ${streamAr}
@ -120,7 +118,7 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
postCropStretchFactors.xFactor *= squeezeFactor;
this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we'll apply:\npostCropStretchFactors: x=${postCropStretchFactors.x} y=${postCropStretchFactors.y}`);
this.logger.info('applyStretchFixedSource', `here's what we'll apply:\npostCropStretchFactors: x=${postCropStretchFactors.x} y=${postCropStretchFactors.y}`);
return postCropStretchFactors;
}

View File

@ -1,5 +1,4 @@
import Debug from '../../conf/Debug';
import Logger from '../Logger';
import { ComponentLogger } from '../logging/ComponentLogger';
import VideoData from '../video-data/VideoData';
// calculates zooming and video offsets/panning
@ -16,7 +15,7 @@ class Zoom {
//#region helper objects
conf: VideoData;
logger: Logger;
logger: ComponentLogger;
//#endregion
//#region misc data
@ -34,7 +33,7 @@ class Zoom {
constructor(videoData) {
this.conf = videoData;
this.logger = videoData.logger;
this.logger = new ComponentLogger(videoData.logAggregator, 'Zoom', {});
}
reset(){
@ -66,7 +65,7 @@ class Zoom {
this.scale = Math.pow(2, this.logScale);
this.scaleY = Math.pow(2, this.logScaleY);
this.logger.log('info', 'debug', "[Zoom::zoomStep] changing zoom by", amount, ". New zoom level:", this.scale);
this.logger.info('zoomStep', "changing zoom by", amount, ". New zoom level:", this.scale);
this.processZoom();
}
@ -100,12 +99,12 @@ class Zoom {
if (!stretchFactors) {
return;
}
this.logger.log('info', 'debug', "[Zoom::setZoom] Applying zoom. Stretch factors pre:", stretchFactors, " —> scale:", this.scale);
this.logger.info('setZoom', "Applying zoom. Stretch factors pre:", stretchFactors, " —> scale:", this.scale);
stretchFactors.xFactor *= this.scale;
stretchFactors.yFactor *= this.scale;
this.logger.log('info', 'debug', "[Zoom::setZoom] Applying zoom. Stretch factors post:", stretchFactors);
this.logger.info('setZoom', "Applying zoom. Stretch factors post:", stretchFactors);
}
}

View File

@ -53,9 +53,9 @@
</template>
<script>
import Debug from '../../ext/conf/Debug';
import BrowserDetect from '../../ext/conf/BrowserDetect';
import Logger from '../../ext/lib/Logger';
import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import { ComponentLogger } from '@src/ext/lib/logging/ComponentLogger';
export default {
data () {
@ -75,6 +75,7 @@ export default {
settings: {},
settingsInitialized: false,
logger: {},
logAggregator: {},
siteTabDisabled: false,
videoTabDisabled: false,
canShowVideoTab: {canShow: true, warning: true},
@ -82,7 +83,8 @@ export default {
}
},
async created() {
this.logger = new Logger();
this.logAggregator = new LogAggregator('');
this.logger = new ComponentLogger(this.logAggregator, 'App.vue');
await this.logger.init({
allowLogging: true,
});

View File

@ -54,9 +54,9 @@
</template>
<script>
import Debug from '../../ext/conf/Debug';
import BrowserDetect from '../../ext/conf/BrowserDetect';
import Logger from '../../ext/lib/Logger';
import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import { ComponentLogger } from '@src/ext/lib/logging/ComponentLogger';
export default {
data () {
@ -75,6 +75,7 @@ export default {
currentZoom: 1,
settings: {},
settingsInitialized: false,
logAggregator: {},
logger: {},
siteTabDisabled: false,
videoTabDisabled: false,
@ -83,7 +84,9 @@ export default {
}
},
async created() {
this.logger = new Logger();
this.logAggregator = new LogAggregator('');
this.logger = new ComponentLogger(this.logAggregator, 'App.vue');
await this.logger.init({
allowLogging: true,
});

View File

@ -123,7 +123,8 @@ import ConfirmPopup from './common/ConfirmationPopup';
import About from './about'
import AutodetectionSettings from './AutodetectionSettings';
// import SuperAdvancedSettings from './'
import Logger from '../ext/lib/Logger';
import { LogAggregator } from '@src/ext/lib/logging/LogAggregator';
import { ComponentLogger } from '@src/ext/lib/logging/ComponentLogger';
export default {
name: "Ultrawidify",
@ -132,6 +133,7 @@ export default {
selectedTab: "general",
selectedTabTitle: "General settings",
settings: {},
logAggregator: {},
logger: {},
settingsInitialized: false,
editActionPopupVisible: false,
@ -145,7 +147,8 @@ export default {
}
},
async created () {
this.logger = new Logger();
this.logAggregator = new LogAggregator('');
this.logger = new ComponentLogger(this.logAggregator, 'App.vue');
await this.logger.init({
allowLogging: true,
});