Merge branch 'master' into stable
This commit is contained in:
commit
61ca9cd9f2
@ -7,6 +7,15 @@
|
||||
* Settings page looks ugly af right now. Maybe fix it some time later
|
||||
|
||||
|
||||
### v4.2.0
|
||||
|
||||
* Slightly improved popup design. (Design change suggested by PortaTrekos)
|
||||
* Player detection: youtube and twitch now have manual player element detection, with strictly defined players.
|
||||
* Improved site settings control in extension popup. It's possible to enable extension for previously disabled embedded sites.
|
||||
* Improved incompatibilities with reddit, where videos would be vertically misaligned when not using RES
|
||||
* Fixed imcompatibilities with Iridium. Flicker when clicking play/pause or switching between big and popup player is caused by either Youtube or Iridium trying to apply their styles over mine.
|
||||
* Issues with inconsistent alignment that some people reported are potentially fixed
|
||||
|
||||
### v4.1.2 (current)
|
||||
|
||||
* Fixed video alignment issues on www.reddit as well (for people who use old reddit without going to old.reddit)
|
||||
|
44
src/ext/conf/ExtConfPatches.js
Normal file
44
src/ext/conf/ExtConfPatches.js
Normal file
@ -0,0 +1,44 @@
|
||||
// How to use:
|
||||
// version: {ExtensionConf object, but only properties that get overwritten}
|
||||
|
||||
const ExtensionConfPatch = {
|
||||
'4.2.0': {
|
||||
sites: {
|
||||
"old.reddit.com" : {
|
||||
type: 'testing',
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true,
|
||||
useRelativeAncestor: false,
|
||||
querySelectors: '.media-preview-content'
|
||||
}
|
||||
},
|
||||
css: '',
|
||||
},
|
||||
"www.reddit.com" : {
|
||||
type: 'testing',
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true,
|
||||
useRelativeAncestor: false,
|
||||
querySelectors: '.media-preview-content'
|
||||
}
|
||||
},
|
||||
css: '',
|
||||
},
|
||||
"www.youtube.com" : {
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true,
|
||||
querySelectors: "#movie_player, #player",
|
||||
additionalCss: "",
|
||||
useRelativeAncestor: false,
|
||||
playerNodeCss: "",
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ExtensionConfPatch;
|
@ -836,6 +836,7 @@ var ExtensionConf = {
|
||||
}
|
||||
},
|
||||
],
|
||||
whatsNewChecked: true,
|
||||
// -----------------------------------------
|
||||
// ::: SITE CONFIGURATION :::
|
||||
// -----------------------------------------
|
||||
@ -896,6 +897,15 @@ var ExtensionConf = {
|
||||
stretch: Stretch.Default,
|
||||
videoAlignment: VideoAlignment.Default,
|
||||
keyboardShortcutsEnabled: ExtensionMode.Default,
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true,
|
||||
querySelectors: "#movie_player, #player",
|
||||
additionalCss: "",
|
||||
useRelativeAncestor: false,
|
||||
playerNodeCss: "",
|
||||
}
|
||||
}
|
||||
},
|
||||
"www.netflix.com" : {
|
||||
mode: ExtensionMode.Enabled,
|
||||
@ -919,49 +929,23 @@ var ExtensionConf = {
|
||||
}
|
||||
}
|
||||
},
|
||||
"old.reddit.com" : {
|
||||
"www.twitch.tv": {
|
||||
mode: ExtensionMode.Enabled,
|
||||
autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled,
|
||||
override: false,
|
||||
override: true,
|
||||
type: 'official',
|
||||
stretch: Stretch.Default,
|
||||
videoAlignment: VideoAlignment.Default,
|
||||
keyboardShortcutsEnabled: ExtensionMode.Default,
|
||||
DOM: {
|
||||
video: {
|
||||
manual: false,
|
||||
querySelectors: '',
|
||||
additionalCss: '',
|
||||
},
|
||||
player: {
|
||||
manual: true,
|
||||
useRelativeAncestor: true,
|
||||
videoAncestor: 1,
|
||||
querySelectors: ".video-player__container.player",
|
||||
additionalCss: "",
|
||||
useRelativeAncestor: false,
|
||||
playerNodeCss: ""
|
||||
}
|
||||
},
|
||||
css: '',
|
||||
},
|
||||
"www.reddit.com" : {
|
||||
mode: ExtensionMode.Enabled,
|
||||
autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled,
|
||||
override: false,
|
||||
type: 'official',
|
||||
stretch: Stretch.Default,
|
||||
videoAlignment: VideoAlignment.Default,
|
||||
keyboardShortcutsEnabled: ExtensionMode.Default,
|
||||
DOM: {
|
||||
video: {
|
||||
manual: false,
|
||||
querySelectors: '',
|
||||
additionalCss: '',
|
||||
},
|
||||
player: {
|
||||
manual: true,
|
||||
useRelativeAncestor: true,
|
||||
videoAncestor: 1,
|
||||
}
|
||||
},
|
||||
css: '',
|
||||
}
|
||||
},
|
||||
"vimeo.com": {
|
||||
mode: 3,
|
||||
@ -979,26 +963,63 @@ var ExtensionConf = {
|
||||
},
|
||||
css: ".player_outro_area {\n width: 100% !important;\n display: flex !important;\n justify-content: center !important;\n}\n\n.player_container, .player {\n width: 100% !important; \n}"
|
||||
},
|
||||
"old.reddit.com" : {
|
||||
mode: ExtensionMode.Enabled,
|
||||
autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled,
|
||||
override: false,
|
||||
type: 'testing',
|
||||
stretch: Stretch.Default,
|
||||
videoAlignment: VideoAlignment.Default,
|
||||
keyboardShortcutsEnabled: ExtensionMode.Default,
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true,
|
||||
useRelativeAncestor: false,
|
||||
querySelectors: '.media-preview-content'
|
||||
}
|
||||
},
|
||||
css: '',
|
||||
},
|
||||
"www.reddit.com" : {
|
||||
mode: ExtensionMode.Enabled,
|
||||
autoar: currentBrowser.firefox ? ExtensionMode.Enabled : ExtensionMode.Disabled,
|
||||
override: false,
|
||||
type: 'testing',
|
||||
stretch: Stretch.Default,
|
||||
videoAlignment: VideoAlignment.Default,
|
||||
keyboardShortcutsEnabled: ExtensionMode.Default,
|
||||
DOM: {
|
||||
player: {
|
||||
manual: true,
|
||||
useRelativeAncestor: false,
|
||||
querySelectors: '.media-preview-content'
|
||||
}
|
||||
},
|
||||
css: '',
|
||||
},
|
||||
"imgur.com": {
|
||||
mode: -1,
|
||||
autoar: -1,
|
||||
autoarFallback: 0,
|
||||
stretch: -1,
|
||||
videoAlignment: 1
|
||||
videoAlignment: 1,
|
||||
type: 'official',
|
||||
},
|
||||
"gfycat.com": {
|
||||
mode: -1,
|
||||
autoar: -1,
|
||||
autoarFallback: 0,
|
||||
stretch: -1,
|
||||
videoAlignment: 1
|
||||
videoAlignment: 1,
|
||||
type: 'official,'
|
||||
},
|
||||
"giant.gfycat.com": {
|
||||
mode: -1,
|
||||
autoar: -1,
|
||||
autoarFallback: 0,
|
||||
stretch: -1,
|
||||
videoAlignment: 1
|
||||
videoAlignment: 1,
|
||||
type: 'official',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,32 @@ class ObjectCopy {
|
||||
return out;
|
||||
}
|
||||
|
||||
static overwrite(existing, target){
|
||||
for(var k in target) {
|
||||
// if current key exist, replace it with existing value. Take no action otherwise.
|
||||
if (existing[k]) {
|
||||
|
||||
// Types and constructors of objects must match. If they don't, we always use the new value.
|
||||
if (typeof target[k] === typeof existing[k] && target[k].constructor === existing[k].constructor) {
|
||||
|
||||
// objects are special, we need to check them recursively.
|
||||
if(existing[k] && typeof existing[k] === 'object' && existing[k].constructor === Object ) {
|
||||
if(Debug.debug && Debug.settings) {
|
||||
console.log("[ObjectCopy::addNew] current key contains an object. Recursing!")
|
||||
}
|
||||
|
||||
existing[k] = this.overwrite(existing[k], target[k]);
|
||||
} else {
|
||||
existing[k] = target[k];
|
||||
}
|
||||
} else {
|
||||
existing[k] = target[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
|
||||
static pruneUnused(existing, target, ignoreKeys) {
|
||||
// TODO: implement at some other date
|
||||
// existing: object that we have.
|
||||
|
@ -5,6 +5,7 @@ import ExtensionMode from '../../common/enums/extension-mode.enum';
|
||||
import ObjectCopy from '../lib/ObjectCopy';
|
||||
import Stretch from '../../common/enums/stretch.enum';
|
||||
import VideoAlignment from '../../common/enums/video-alignment.enum';
|
||||
import ExtensionConfPatch from '../conf/ExtConfPatches';
|
||||
|
||||
|
||||
|
||||
@ -108,6 +109,7 @@ class Settings {
|
||||
if(Debug.debug) {
|
||||
console.log("[Settings::init] extension was saved with current version of ultrawidify (", this.version, "). Returning object as-is.");
|
||||
}
|
||||
|
||||
return this.active;
|
||||
}
|
||||
|
||||
@ -124,6 +126,12 @@ class Settings {
|
||||
this.active = JSON.parse(JSON.stringify(this.default));
|
||||
}
|
||||
|
||||
// in case settings in previous version contained a fucky wucky, we overwrite existing settings with a patch
|
||||
ObjectCopy.overwrite(this.active, ExtensionConfPatch['4.2.0']);
|
||||
|
||||
// set 'whatsNewChecked' flag to false when updating
|
||||
this.active.whatsNewChecked = false;
|
||||
|
||||
this.set(this.active);
|
||||
return this.active;
|
||||
}
|
||||
@ -290,11 +298,11 @@ class Settings {
|
||||
// }
|
||||
try{
|
||||
// if site is not defined, we use default mode:
|
||||
if (! this.active.sites[site]) {
|
||||
if (! this.active.sites[site] || this.active.sites[site].mode === ExtensionMode.Default) {
|
||||
return this.active.sites['@global'].mode === ExtensionMode.Enabled;
|
||||
}
|
||||
|
||||
if(this.active.sites['@global'].mode === ExtensionMode.Enabled) {
|
||||
if (this.active.sites['@global'].mode === ExtensionMode.Enabled) {
|
||||
return this.active.sites[site].mode !== ExtensionMode.Disabled;
|
||||
} else if (this.active.sites['@global'].mode === ExtensionMode.Whitelist) {
|
||||
return this.active.sites[site].mode === ExtensionMode.Enabled;
|
||||
|
@ -195,7 +195,7 @@ class ArDetector {
|
||||
this.resetBlackLevel();
|
||||
|
||||
// if we're restarting ArDetect, we need to do this in order to force-recalculate aspect ratio
|
||||
this.conf.resizer.setLastAr({type: AspectRatio.Automatic, ratio: null});
|
||||
this.conf.resizer.setLastAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()});
|
||||
|
||||
this.canvasImageDataRowLength = cwidth << 2;
|
||||
this.noLetterboxCanvasReset = false;
|
||||
@ -218,7 +218,7 @@ class ArDetector {
|
||||
}
|
||||
if (this.conf.resizer.lastAr.type === AspectRatio.Automatic) {
|
||||
// ensure first autodetection will run in any case
|
||||
this.conf.resizer.setLastAr({type: AspectRatio.Automatic, ratio: null});
|
||||
this.conf.resizer.setLastAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()});
|
||||
}
|
||||
|
||||
// launch main() if it's currently not running:
|
||||
@ -247,7 +247,7 @@ class ArDetector {
|
||||
console.log("%c[ArDetect::_ard_stop] Stopping automatic aspect ratio detection", _ard_console_stop);
|
||||
}
|
||||
this._halted = true;
|
||||
// this.conf.resizer.resetLastAr();
|
||||
// this.conf.resizer.setArLastAr();
|
||||
}
|
||||
|
||||
async main() {
|
||||
@ -428,6 +428,10 @@ class ArDetector {
|
||||
}
|
||||
//#endregion
|
||||
|
||||
getDefaultAr() {
|
||||
return this.video.videoWidth / this.video.videoHeight;
|
||||
}
|
||||
|
||||
calculateArFromEdges(edges) {
|
||||
// if we don't specify these things, they'll have some default values.
|
||||
if(edges.top === undefined){
|
||||
@ -632,7 +636,7 @@ class ArDetector {
|
||||
// da je letterbox izginil.
|
||||
// If we don't detect letterbox, we reset aspect ratio to aspect ratio of the video file. The aspect ratio could
|
||||
// have been corrected manually. It's also possible that letterbox (that was there before) disappeared.
|
||||
this.conf.resizer.reset({type: AspectRatio.Automatic, ratio: null});
|
||||
this.conf.resizer.setAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()});
|
||||
this.guardLine.reset();
|
||||
this.noLetterboxCanvasReset = true;
|
||||
|
||||
@ -675,7 +679,7 @@ class ArDetector {
|
||||
// (since the new letterbox edge isn't present in our sample due to technical
|
||||
// limitations)
|
||||
if (this.fallbackMode && guardLineOut.blackbarFail) {
|
||||
this.conf.resizer.reset({type: AspectRatio.Automatic, ratio: null});
|
||||
this.conf.resizer.setAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()});
|
||||
this.guardLine.reset();
|
||||
this.noLetterboxCanvasReset = true;
|
||||
|
||||
@ -701,7 +705,7 @@ class ArDetector {
|
||||
}
|
||||
|
||||
if(guardLineOut.blackbarFail){
|
||||
this.conf.resizer.reset({type: AspectRatio.Automatic, ratio: null});
|
||||
this.conf.resizer.setAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()});
|
||||
this.guardLine.reset();
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ class CommsClient {
|
||||
console.log(`[CommsClient::registerVideo] <${this.commsId}>`, "Registering video for current page.");
|
||||
}
|
||||
if (this.pageInfo) {
|
||||
if (this.pageInfo.videos.length) {
|
||||
if (this.pageInfo.hasVideo()) {
|
||||
this.port.postMessage({cmd: "has-video"});
|
||||
}
|
||||
} else {
|
||||
|
@ -9,7 +9,7 @@ if(Debug.debug)
|
||||
|
||||
|
||||
class PageInfo {
|
||||
constructor(comms, settings, extensionMode){
|
||||
constructor(comms, settings, extensionMode, readOnly = false){
|
||||
this.hasVideos = false;
|
||||
this.siteDisabled = false;
|
||||
this.videos = [];
|
||||
@ -18,8 +18,9 @@ class PageInfo {
|
||||
|
||||
this.lastUrl = window.location.href;
|
||||
this.extensionMode = extensionMode;
|
||||
this.readOnly = readOnly;
|
||||
|
||||
if(comms){
|
||||
if (comms){
|
||||
this.comms = comms;
|
||||
}
|
||||
|
||||
@ -27,18 +28,6 @@ class PageInfo {
|
||||
this.scheduleUrlCheck();
|
||||
|
||||
this.currentZoomScale = 1;
|
||||
|
||||
try {
|
||||
const playerStyleString = this.settings.active.sites[window.location.host].css;
|
||||
if (playerStyleString) {
|
||||
this.comms.sendMessage({
|
||||
cmd: 'inject-css',
|
||||
cssString: playerStyleString
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing. It's ok if there's no special settings for the player element
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@ -104,6 +93,10 @@ class PageInfo {
|
||||
return document.getElementsByTagName('video');
|
||||
}
|
||||
|
||||
hasVideo() {
|
||||
return this.readOnly ? this.hasVideos : this.videos.length;
|
||||
}
|
||||
|
||||
rescan(rescanReason){
|
||||
const oldVideoCount = this.videos.length;
|
||||
|
||||
@ -135,6 +128,16 @@ class PageInfo {
|
||||
// if video lacks either of the two properties, we skip all further checks cos pointless
|
||||
if(video.offsetWidth && video.offsetHeight){
|
||||
this.hasVideos = true;
|
||||
|
||||
if (this.readOnly) {
|
||||
// in lite mode, we're done. This is all the info we want, but we want to actually start doing
|
||||
// things that interfere with the website. We still want to be runnig a rescan, tho.
|
||||
|
||||
if(rescanReason == RescanReason.PERIODIC){
|
||||
this.scheduleRescan(RescanReason.PERIODIC);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -158,6 +161,7 @@ class PageInfo {
|
||||
if (Debug.debug && Debug.periodic && Debug.videoRescan) {
|
||||
console.log("[PageInfo::rescan] found new video candidate:", video, "NOTE:: Video initialization starts here:\n--------------------------------\n")
|
||||
}
|
||||
|
||||
v = new VideoData(video, this.settings, this);
|
||||
// console.log("[PageInfo::rescan] v is:", v)
|
||||
v.initArDetection();
|
||||
|
@ -381,8 +381,9 @@ class PlayerData {
|
||||
console.log("[PlayerDetect] player size changed. reason: exited fullscreen");
|
||||
}
|
||||
}
|
||||
if(! this.element)
|
||||
if(! this.element && Debug.debug && Debug.playerDetect) {
|
||||
console.log("[PlayerDetect] player element isnt defined");
|
||||
}
|
||||
|
||||
if ( this.element &&
|
||||
( this.dimensions.width != this.element.offsetWidth ||
|
||||
|
@ -65,15 +65,19 @@ class UW {
|
||||
console.log("[uw::init] Extension mode:" + (extensionMode < 0 ? "disabled" : extensionMode == '1' ? 'basic' : 'full'));
|
||||
}
|
||||
|
||||
if(extensionMode === ExtensionMode.Disabled){
|
||||
if(Debug.debug) {
|
||||
console.log("[uw::init] EXTENSION DISABLED, THEREFORE WONT BE STARTED")
|
||||
const isSiteDisabled = extensionMode === ExtensionMode.Disabled
|
||||
|
||||
if (isSiteDisabled) {
|
||||
if (this.settings.getExtensionMode('@global') === ExtensionMode.Disabled) {
|
||||
if (Debug.debug) {
|
||||
console.log("[uw::init] EXTENSION DISABLED, THEREFORE WONT BE STARTED")
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.pageInfo = new PageInfo(this.comms, this.settings, extensionMode);
|
||||
this.pageInfo = new PageInfo(this.comms, this.settings, extensionMode, isSiteDisabled);
|
||||
if(Debug.debug){
|
||||
console.log("[uw.js::setup] pageInfo initialized. Here's the object:", this.pageInfo);
|
||||
}
|
||||
@ -83,11 +87,14 @@ class UW {
|
||||
console.log("[uw.js::setup] will try to initate ActionHandler. Settings are:", this.settings, this.settings.active)
|
||||
}
|
||||
|
||||
this.actionHandler = new ActionHandler(this.pageInfo);
|
||||
this.actionHandler.init();
|
||||
// start action handler only if extension is enabled for this site
|
||||
if (!isSiteDisabled) {
|
||||
this.actionHandler = new ActionHandler(this.pageInfo);
|
||||
this.actionHandler.init();
|
||||
|
||||
if(Debug.debug) {
|
||||
console.log("[uw.js::setup] ActionHandler initiated:", this.actionHandler);
|
||||
if(Debug.debug) {
|
||||
console.log("[uw.js::setup] ActionHandler initiated:", this.actionHandler);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
"manifest_version": 2,
|
||||
"name": "Ultrawidify",
|
||||
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
|
||||
"version": "4.1.2",
|
||||
"version": "4.2.0",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="popup">
|
||||
<div class="header">
|
||||
<div class="popup flex flex-column no-overflow">
|
||||
<div class="header flex-row flex-nogrow flex-noshrink">
|
||||
<span class="smallcaps">Ultrawidify</span>: <small>Quick settings</small>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row">
|
||||
<div class="flex flex-row body no-overflow flex-grow">
|
||||
<!-- TABS/SIDEBAR -->
|
||||
<div id="tablist" class="flex flex-column flex-nogrow flex-noshrink">
|
||||
<div id="tablist" class="flex flex-column flex-nogrow flex-noshrink h100">
|
||||
<div class="menu-item"
|
||||
:class="{'selected-tab': selectedTab === 'global'}"
|
||||
@click="selectTab('global')"
|
||||
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item"
|
||||
:class="{'selected-tab': selectedTab === 'site'}"
|
||||
:class="{'selected-tab': selectedTab === 'site', 'disabled': siteTabDisabled}"
|
||||
@click="selectTab('site')"
|
||||
>
|
||||
<div class="">
|
||||
@ -28,11 +28,14 @@
|
||||
class=""
|
||||
>
|
||||
<small>Select site to control:</small>
|
||||
<div class="">
|
||||
<div class="site-list overflow-y-auto scrollbar-darker rtl no-overflow-x">
|
||||
<div v-for="site of activeSites"
|
||||
:key="site.host"
|
||||
class="tabitem"
|
||||
:class="{'tabitem-selected': site.host === selectedSite}"
|
||||
class="tabitem ltr"
|
||||
:class="{
|
||||
'tabitem-selected': site.host === selectedSite,
|
||||
'tabitem-disabled': !settings.canStartExtension(site.host)
|
||||
}"
|
||||
@click="selectSite(site.host)"
|
||||
>
|
||||
{{site.host}}
|
||||
@ -41,20 +44,23 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item"
|
||||
:class="{'selected-tab': selectedTab === 'video'}"
|
||||
:class="{'selected-tab': selectedTab === 'video', 'disabled': !canShowVideoTab.canShow}"
|
||||
@click="selectTab('video')"
|
||||
>
|
||||
<div class="">
|
||||
Video settings
|
||||
Video settings <span v-if="canShowVideoTab.canShow && canShowVideoTab.warning" class="warning-color">⚠</span>
|
||||
</div>
|
||||
<div v-if="selectedTab === 'video' && this.activeFrames.length > 0"
|
||||
class=""
|
||||
>
|
||||
<small>Select embedded frame to control:</small>
|
||||
<div class="">
|
||||
<div class="site-list overflow-y-auto scrollbar-darker rtl no-overflow-x">
|
||||
<div v-for="frame of activeFrames"
|
||||
class="tabitem"
|
||||
:class="{'tabitem-selected': selectedFrame === frame.id}"
|
||||
class="tabitem ltr"
|
||||
:class="{
|
||||
'tabitem-selected': selectedFrame === frame.id,
|
||||
'disabled': !isDefaultFrame(frame.id) && !settings.canStartExtension(frame.label)
|
||||
}"
|
||||
:key="frame.id"
|
||||
@click="selectFrame(frame.id)"
|
||||
>
|
||||
@ -69,16 +75,16 @@
|
||||
@click="selectTab('site-details')"
|
||||
>
|
||||
<div class="">
|
||||
Video and player detection
|
||||
Advanced settings
|
||||
</div>
|
||||
<div v-if="selectedTab === 'site-details' && this.activeSites.length > 1"
|
||||
class=""
|
||||
>
|
||||
<small>Select site to control:</small>
|
||||
<div class="">
|
||||
<div class="site-list overflow-y-auto scrollbar-darker rtl no-overflow-x">
|
||||
<div v-for="site of activeSites"
|
||||
:key="site.host"
|
||||
class="tabitem"
|
||||
class="tabitem ltr"
|
||||
:class="{'tabitem-selected': site.host === selectedSite}"
|
||||
@click="selectSite(site.host)"
|
||||
>
|
||||
@ -87,29 +93,32 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-item"
|
||||
<div class="flex flex-grow">
|
||||
<!-- this is spacer -->
|
||||
</div>
|
||||
<div class="menu-item menu-item-darker"
|
||||
:class="{'selected-tab': selectedTab === 'whats-new'}"
|
||||
@click="selectTab('whats-new')"
|
||||
>
|
||||
<div class="">
|
||||
<div :class="{'new': !settings.active.whatsNewChecked}"
|
||||
>
|
||||
What's new?
|
||||
</div>
|
||||
<div class="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-item"
|
||||
<div class="menu-item menu-item-darker"
|
||||
:class="{'selected-tab': selectedTab === 'about'}"
|
||||
@click="selectTab('about')"
|
||||
>
|
||||
<div class="">
|
||||
<div class="">
|
||||
Report a problem
|
||||
</div>
|
||||
<div class="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item"
|
||||
<div class="menu-item menu-item-darker"
|
||||
:class="{'selected-tab': selectedTab === 'donate'}"
|
||||
@click="selectTab('donate')"
|
||||
>
|
||||
@ -122,9 +131,10 @@
|
||||
</div>
|
||||
|
||||
<!-- PANELS/CONTENT -->
|
||||
<div id="tab-content" class="flex-grow" style="max-width: 480px !important;">
|
||||
<div id="tab-content" class="flex-grow h100 overflow-y-auto">
|
||||
<VideoPanel v-if="settings && settings.active && selectedTab === 'video'"
|
||||
class=""
|
||||
:someSitesDisabledWarning="canShowVideoTab.warning"
|
||||
:settings="settings"
|
||||
:frame="selectedFrame"
|
||||
:zoom="currentZoom"
|
||||
@ -164,6 +174,7 @@ import Settings from '../ext/lib/Settings';
|
||||
import ExecAction from './js/ExecAction.js';
|
||||
import DefaultSettingsPanel from './panels/DefaultSettingsPanel';
|
||||
import AboutPanel from './panels/AboutPanel';
|
||||
import ExtensionMode from '../common/enums/extension-mode.enum';
|
||||
|
||||
export default {
|
||||
data () {
|
||||
@ -182,6 +193,9 @@ export default {
|
||||
currentZoom: 1,
|
||||
execAction: new ExecAction(),
|
||||
settings: new Settings(undefined, () => this.updateConfig()),
|
||||
siteTabDisabled: false,
|
||||
videoTabDisabled: false,
|
||||
canShowVideoTab: {canShow: true, warning: true},
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
@ -243,20 +257,47 @@ export default {
|
||||
},
|
||||
selectTab(tab) {
|
||||
this.selectedTab = tab;
|
||||
if (tab === 'whats-new') {
|
||||
this.settings.active.whatsNewChecked = true;
|
||||
this.settings.save();
|
||||
}
|
||||
},
|
||||
selectFrame(frame) {
|
||||
this.selectedFrame = frame;
|
||||
},
|
||||
async updateConfig() {
|
||||
|
||||
// when this runs, a site could have been enabled or disabled
|
||||
// this means we must update canShowVideoTab
|
||||
this.updateCanShowVideoTab();
|
||||
},
|
||||
updateCanShowVideoTab() {
|
||||
let canShow = false;
|
||||
let warning = false;
|
||||
let t;
|
||||
|
||||
if (!this.settings) {
|
||||
this.canShowVideoTab = {canShow: true, warning: false};
|
||||
}
|
||||
for (const site of this.activeSites) {
|
||||
t = this.settings.canStartExtension(site.host);
|
||||
canShow = canShow || t;
|
||||
warning = warning || !t;
|
||||
}
|
||||
if (t === undefined) {
|
||||
// something isn't the way it should be. Show sites.
|
||||
this.canShowVideoTab = {canShow: true, warning: true};
|
||||
}
|
||||
|
||||
this.canShowVideoTab = {canShow: canShow, warning: warning};
|
||||
},
|
||||
processReceivedMessage(message, port) {
|
||||
if (Debug.debug) {
|
||||
if (Debug.debug && Debug.comms) {
|
||||
console.log("[popup.js] received message set-c", message);
|
||||
console.log("[popup.js] message cloned set-c", JSON.parse(JSON.stringify(message)));
|
||||
}
|
||||
|
||||
if(message.cmd === 'set-current-site'){
|
||||
if (message.cmd === 'set-current-site'){
|
||||
if (this.site) {
|
||||
if (!this.site.host) {
|
||||
// dunno why this fix is needed, but sometimes it is
|
||||
@ -280,6 +321,7 @@ export default {
|
||||
|
||||
// loadConfig(site.host); TODO
|
||||
this.loadFrames(this.site);
|
||||
this.showFirstTab(this.site);
|
||||
} else if (message.cmd === 'set-current-zoom') {
|
||||
this.setCurrentZoom(message.zoom);
|
||||
} else if (message.cmd === 'performance-update') {
|
||||
@ -288,7 +330,48 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
},
|
||||
showFirstTab(videoTab) {
|
||||
// determine which tab to show.
|
||||
// Extension global disabled — show 'extension settings'
|
||||
// Extension site disabled, no embedded videos — show 'site settings'
|
||||
// Extension site disabled, embedded videos from non-blacklisted hosts — show video settings
|
||||
// Extension site enabled — show vido settings
|
||||
|
||||
if (! this.settings.canStartExtension('@global')) {
|
||||
if (this.selectedTab === 'video' || this.selectedTab === 'site') {
|
||||
this.selectTab('global');
|
||||
}
|
||||
this.siteTabDisabled = true;
|
||||
this.videoTabDisabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.siteTabDisabled = false;;
|
||||
if (! this.settings.canStartExtension(this.site.host)) {
|
||||
if (videoTab.frames.length > 1) {
|
||||
for (const frame of videoTab.frames) {
|
||||
if (this.settings.canStartExtension(frame.host)) {
|
||||
this.videoTabDisabled = false;
|
||||
// video is selected by default, so no need to reselect it
|
||||
// and if video is not selected, the popup would switch to 'video'
|
||||
// tab once every 5 seconds. We don't want that.
|
||||
// this.selectTab('video');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.videoTabDisabled = true;
|
||||
if (this.selectedTab === 'video') {
|
||||
this.selectTab('site');
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.videoTabDisabled = false;
|
||||
},
|
||||
isDefaultFrame(frameId) {
|
||||
return frameId === '__playing' || frameId === '__all';
|
||||
},
|
||||
loadFrames(videoTab) {
|
||||
if (videoTab.selected) {
|
||||
@ -343,6 +426,9 @@ export default {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// update whether video tab can be shown
|
||||
this.updateCanShowVideoTab();
|
||||
},
|
||||
getRandomColor() {
|
||||
return `rgb(${Math.floor(Math.random() * 128)}, ${Math.floor(Math.random() * 128)}, ${Math.floor(Math.random() * 128)})`;
|
||||
@ -392,6 +478,7 @@ html, body {
|
||||
font-size: 2.7em;
|
||||
}
|
||||
|
||||
|
||||
.menu-item-inline-desc{
|
||||
font-size: 0.60em;
|
||||
font-weight: 300;
|
||||
@ -399,11 +486,18 @@ html, body {
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
flex-grow: 0;
|
||||
padding-left: 15px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
font-variant: small-caps;
|
||||
border-left: transparent 5px solid;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.menu-item-darker {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.suboption {
|
||||
@ -434,19 +528,27 @@ html, body {
|
||||
.tabitem {
|
||||
font-variant: normal;
|
||||
// font-size: 0.69em;
|
||||
margin-left: 1em;
|
||||
// margin-left: 16px;
|
||||
border-left: transparent 3px solid;
|
||||
padding-left: 12px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.site-list {
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.tabitem-selected {
|
||||
color: #fff !important;
|
||||
background-color: initial;
|
||||
border-left: #f0c089 3px solid !important;
|
||||
}
|
||||
.tabitem-selected::before {
|
||||
padding-right: 0.5em;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.tabitem-disabled {
|
||||
color: #cc3b0f !important;
|
||||
}
|
||||
|
||||
.tabitem-iframe::after {
|
||||
@ -455,7 +557,7 @@ html, body {
|
||||
}
|
||||
|
||||
.popup {
|
||||
max-width: 780px;
|
||||
// max-width: 780px;
|
||||
// width: 800px;
|
||||
height: 600px;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="w100 flex flex-column" style="padding-bottom: 20px">
|
||||
<div class="flex flex-column" style="padding-bottom: 20px">
|
||||
<!-- <ShortcutButton class="button"
|
||||
@click.native="wipeSettings()"
|
||||
label="Wipe settings"
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="w100 flex flex-column" style="padding-bottom: 20px">
|
||||
<div class="flex flex-column" style="padding-bottom: 20px">
|
||||
<div class="label">
|
||||
Video detection settings<br/><small>for {{site}}</small>
|
||||
</div>
|
||||
|
@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="w100" style="padding-bottom: 20px">
|
||||
<div v-if="aspectRatioActions.length"
|
||||
class="w100"
|
||||
>
|
||||
<div class="" style="padding-bottom: 20px">
|
||||
<div v-if="someSitesDisabledWarning" class="warning-lite">
|
||||
Some sites embedded on this page are disabled. Extension will not work on videos embedded from disabled sites.
|
||||
</div>
|
||||
<div v-if="aspectRatioActions.length">
|
||||
<div class="label">Cropping mode:</div>
|
||||
<div class="flex flex-row flex-wrap">
|
||||
<ShortcutButton v-for="(action, index) of aspectRatioActions"
|
||||
@ -17,16 +18,16 @@
|
||||
</div>
|
||||
|
||||
<div v-if="true"
|
||||
class="w100">
|
||||
class="">
|
||||
<div class="label experimental">Zooming and panning</div>
|
||||
<div class="row w100"
|
||||
<div class="row"
|
||||
>
|
||||
<!--
|
||||
min, max and value need to be implemented in js as this slider
|
||||
should use logarithmic scale
|
||||
-->
|
||||
<input id="_input_zoom_slider"
|
||||
class="w100"
|
||||
class="input-slider"
|
||||
type="range"
|
||||
step="any"
|
||||
min="-1"
|
||||
@ -43,7 +44,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-t-0-33em w100 display-block">
|
||||
<div class="m-t-0-33em display-block">
|
||||
<input id="_input_zoom_site_allow_pan"
|
||||
type="checkbox"
|
||||
/>
|
||||
@ -129,7 +130,8 @@ export default {
|
||||
props: [
|
||||
'settings',
|
||||
'frame',
|
||||
'zoom'
|
||||
'zoom',
|
||||
'someSitesDisabledWarning'
|
||||
],
|
||||
created() {
|
||||
this.exec = new ExecAction(this.settings);
|
||||
@ -174,4 +176,13 @@ export default {
|
||||
padding-left: 0.33rem;
|
||||
padding-right: 0.33rem;
|
||||
}
|
||||
.input-slider {
|
||||
width: 480px;
|
||||
}
|
||||
.warning-lite {
|
||||
padding-right: 16px;
|
||||
padding-bottom: 16px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -2,34 +2,20 @@
|
||||
<div>
|
||||
<h2>What's new</h2>
|
||||
<p>Full changelog for older versions <a href="https://github.com/xternal7/ultrawidify/blob/master/CHANGELOG.md">is available here</a>.</p>
|
||||
<p class="label">4.1.1 & 4.1.2</p>
|
||||
<p class="label">4.2.0</p>
|
||||
<ul>
|
||||
<li>Disabled extension on gfycat.</li>
|
||||
<li>Fix for old.reddit.com applied to www.reddit.com</li>
|
||||
<li>Slightly improved popup design. (Design change suggested by PortaTrekos)
|
||||
<li>Improved site settings control in extension popup. It's possible to enable extension for previously disabled embedded sites.</li>
|
||||
<li>Improved incompatibilities with reddit, where videos would be vertically misaligned when not using RES</li>
|
||||
<li>Fixed imcompatibilities with Iridium. Flicker when clicking play/pause or switching between big and popup player is caused by either Youtube or Iridium trying to apply their styles over mine.</li>
|
||||
<li>Youtube, reddit and twitch players are now determined by a query string (instead of less accurate automatic detection)</li>
|
||||
<li>Some people reported issues with inconsistent video alignment on youtube. While I've not been able to make that bug happen to me,
|
||||
(which means I haven't been able to fix it either), reports describe behaviour similar to what was going on with Iridium. Examining
|
||||
the Iridium issue revealed an issue that could be potentially blamed for this behaviour. That issue was fixed. Since I've never been able to make this problem
|
||||
happen to me, I'm not being able to verify whether that issue is gone. <b>If you're still experiencing issues with inconsistent video alignment,
|
||||
please contact me via github, reddit or email.</b> See 'Report a problem' tab for more details.</li>
|
||||
</ul>
|
||||
<p class="label">4.1.0</p>
|
||||
<ul>
|
||||
<li>This</li>
|
||||
<li>(Experimental) You can specify custom CSS for the page.</li>
|
||||
<li>(Experimental) You can manually specify how player element is detected</li>
|
||||
<li>Fixed old.reddit and vimeo for that. Disabled extension on imgur by default.</li>
|
||||
</ul>
|
||||
<p class="label">4.0.0</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Fixed the bug where settings wouldn't be saved.</li>
|
||||
<li><b>Autodetection improvements:</b><ul>
|
||||
<li>Implemented gradient detection. Changing aspect ratio will only happen if hard edge is detected</li>
|
||||
<li>Improved black frame detection. Some (but not all) issues about autodetection triggering on dark frames were resolved</li>
|
||||
<li>Increased autodetection frequency from 0.6s to 0.3s. <b>This isn't likely to happen, but if you notice this
|
||||
extension using excessive amounts of RAM (2+ GB), this is why. If you experience this issue, please contact me (see 'Report a problem' tab).</b>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>Settings page for extension added.</li>
|
||||
<li>(Experimental) You can define custom keyboard shortcuts in settings. See 'actions' menu.</li>
|
||||
</ul>
|
||||
For more detailed info, see <a href="https://github.com/xternal7/ultrawidify/blob/master/CHANGELOG.md">full changelog</a>.
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<!-- Load some resources only in development environment -->
|
||||
<% } %>
|
||||
</head>
|
||||
<body style="width: 800px; height: 600px; overflow-x: hidden">
|
||||
<body style="width: 800px; height: 600px; overflow: hidden !important">
|
||||
<div id="app">
|
||||
|
||||
</div>
|
||||
|
@ -40,6 +40,48 @@ body {
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* overflow stuff */
|
||||
.overflow-y-auto {
|
||||
overflow: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba($primary-color, 0.7) $background-primary;
|
||||
}
|
||||
.scrollbar-darker {
|
||||
scrollbar-color: rgba($primary-color, 0.5) $background-primary;
|
||||
}
|
||||
|
||||
|
||||
/* scrollbars for chrome/webkit */
|
||||
.overflow-y-auto::-webkit-scrollbar {
|
||||
width: 3px;
|
||||
}
|
||||
.overflow-y-auto::-webkit-scrollbar-track {
|
||||
background: $background-primary;
|
||||
}
|
||||
.overflow-y-auto::-webkit-scrollbar-thumb {
|
||||
background: rgba($primary-color, 0.7);
|
||||
}
|
||||
.overflow-y-auto::-webkit-scrollbar-button {
|
||||
display: none;
|
||||
}
|
||||
.scrollbar-darker::-webkit-scrollbar-thumb {
|
||||
background: rgba($primary-color, 0.5);
|
||||
}
|
||||
|
||||
.no-overflow {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.no-overflow-x {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.no-overflow-y {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
/* .SELECTED CLASSES */
|
||||
|
||||
.selected-tab {
|
||||
@ -255,15 +297,21 @@ small {
|
||||
|
||||
/** misc **/
|
||||
|
||||
.warning {
|
||||
.warning-color {
|
||||
color: #d6ba4a;
|
||||
}
|
||||
|
||||
.warning, .warning-lite {
|
||||
color: #d6ba4a;
|
||||
padding-left: 35px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.warning::before {
|
||||
.warning::before, .warning-lite::before {
|
||||
content: "⚠ ";
|
||||
display: inline-block;
|
||||
}
|
||||
.warning::before {
|
||||
font-weight: bold;
|
||||
font-size: 2.5em;
|
||||
margin-left: -35px;
|
||||
@ -284,6 +332,18 @@ small {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.new {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.new::after {
|
||||
content: "ⓘ";
|
||||
color: $info-color !important;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.experimental::after {
|
||||
// content: "Experimental";
|
||||
content: "Ⓔ";
|
||||
@ -318,3 +378,11 @@ small {
|
||||
bottom: 0px;
|
||||
background-color: rgba($background-primary, 0.7);
|
||||
}
|
||||
|
||||
.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.ltr {
|
||||
direction: ltr;
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ https://streamable.com/vrb4w
|
||||
|
||||
https://clips.twitch.tv/DirtyHotLampOpieOP
|
||||
|
||||
Also full stream — minor aspect ratio corrections are being triggered after the intro: https://www.twitch.tv/videos/330639009
|
||||
Gets especially bad during WoW segment: https://www.twitch.tv/videos/330639009?t=1h49m20s
|
||||
|
||||
## Youtube
|
||||
|
||||
### Variable aspect ratio
|
||||
|
Loading…
Reference in New Issue
Block a user