Merge branch 'master' into stable
This commit is contained in:
commit
03986557fa
@ -13,7 +13,14 @@ QoL improvements for me:
|
||||
|
||||
* logging: allow to enable logging at will and export said logs to a file
|
||||
|
||||
### v4.4.9 (Current)
|
||||
### v4.4.10 (Current)
|
||||
|
||||
* Video alignment should now work on Twitch [#109](https://github.com/tamius-han/ultrawidify/issues/109)
|
||||
* Videos should now align properly on Hulu while cropped [#111](https://github.com/tamius-han/ultrawidify/issues/111) & via email
|
||||
* Fixed a problem where changing certain settings would cause multiple instances of Ultrawidify to run on a page, effectively preventing some crop options to be set until reload. (possibly [#112](https://github.com/tamius-han/ultrawidify/issues/112)?)
|
||||
* Fixed a problem where embedded videos would be misaligned after switching from full screen
|
||||
|
||||
### v4.4.9
|
||||
|
||||
* Fixed the youtube alignment issue (previously fixed in v4.4.7.1-2), but this time for real (and in a bit more proper way)
|
||||
* Fixed the bug where extension wouldn't work when URL specified a port (e.g. www.example.com:80)
|
||||
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ultrawidify",
|
||||
"version": "4.4.9",
|
||||
"version": "4.4.10",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -1863,9 +1863,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"bl": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
|
||||
"integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-3.0.1.tgz",
|
||||
"integrity": "sha512-jrCW5ZhfQ/Vt07WX1Ngs+yn9BDqPL/gw28S7s9H6QK/gupnizNzJAss5akW20ISgOrbLTlXOOCTJeNUQqruAWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "^3.0.1"
|
||||
|
@ -1,10 +1,11 @@
|
||||
var AspectRatio = Object.freeze({
|
||||
Initial: -1,
|
||||
Reset: 0,
|
||||
Automatic: 1,
|
||||
FitWidth: 2,
|
||||
FitHeight: 3,
|
||||
Fixed: 4,
|
||||
Initial: -1, // page default
|
||||
Reset: 0, // reset to initial
|
||||
Automatic: 1, // set by Aard
|
||||
FitWidth: 2, // legacy/dynamic: fit to width
|
||||
FitHeight: 3, // legacy/dynamic: fit to height
|
||||
Fixed: 4, // pre-determined aspect ratio
|
||||
Manual: 5, // ratio achieved by zooming in/zooming out
|
||||
});
|
||||
|
||||
export default AspectRatio;
|
||||
|
@ -104,14 +104,36 @@ class ActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', (event) => ths.handleKeydown(event) );
|
||||
document.addEventListener('keyup', (event) => ths.handleKeyup(event) );
|
||||
// events should be handled in handleEvent function. We need to do things this
|
||||
// way, otherwise we can't remove event listenerđ
|
||||
// https://stackoverflow.com/a/19507086
|
||||
document.addEventListener('keydown', this );
|
||||
document.addEventListener('keyup', this );
|
||||
|
||||
this.pageInfo.setActionHandler(this);
|
||||
|
||||
this.logger.log('info', 'debug', "[ActionHandler::init] initialization complete");
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
switch(event.type) {
|
||||
case 'keydown':
|
||||
this.handleKeydown(event);
|
||||
break;
|
||||
case 'keyup':
|
||||
this.handleKeyup(event);
|
||||
break;
|
||||
case 'mousemove':
|
||||
this.handleMouseMove(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
document.removeEventListener('keydown', this);
|
||||
document.removeEventListener('keyup', this);
|
||||
}
|
||||
|
||||
registerHandleMouse(videoData) {
|
||||
this.logger.log('info', ['actionHandler', 'mousemove'], "[ActionHandler::registerHandleMouse] registering handle mouse for videodata:", videoData.id)
|
||||
|
||||
|
@ -394,7 +394,7 @@ class PlayerData {
|
||||
this.getPlayer();
|
||||
}
|
||||
|
||||
checkPlayerSizeChange(){
|
||||
checkPlayerSizeChange() {
|
||||
// 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')){
|
||||
|
@ -56,6 +56,7 @@ class VideoData {
|
||||
|
||||
this.restoreCrop();
|
||||
this.videoDimensionsLoaded = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +124,7 @@ class VideoData {
|
||||
}
|
||||
|
||||
restoreCrop() {
|
||||
this.logger.log('info', 'debug', '[VideoData::restoreCrop] Attempting to reset/restore aspect ratio.')
|
||||
this.logger.log('info', 'debug', '[VideoData::restoreCrop] Attempting to reset aspect ratio.')
|
||||
// if we have default crop set for this page, apply this.
|
||||
// otherwise, reset crop
|
||||
if (this.pageInfo.defaultCrop) {
|
||||
@ -132,6 +133,7 @@ class VideoData {
|
||||
this.resizer.reset();
|
||||
|
||||
try {
|
||||
this.stopArDetection();
|
||||
this.startArDetection();
|
||||
} catch (e) {
|
||||
this.logger.log('warn', 'debug', '[VideoData::restoreCrop] Autodetection not resumed. Reason:', e);
|
||||
|
@ -155,11 +155,11 @@ class Resizer {
|
||||
|
||||
// reset zoom, but only on aspect ratio switch. We also know that aspect ratio gets converted to
|
||||
// AspectRatio.Fixed when zooming, so let's keep that in mind
|
||||
if (ar.type !== AspectRatio.Fixed) {
|
||||
this.zoom.reset();
|
||||
this.resetPan();
|
||||
} else if (ar.ratio !== this.lastAr.ratio) {
|
||||
// we must check against this.lastAR.ratio because some calls provide same value for ar and lastAr
|
||||
if (
|
||||
(ar.type !== AspectRatio.Fixed && ar.type !== AspectRatio.Manual) // anything not these two _always_ changes AR
|
||||
|| ar.type !== this.lastAr.type // this also means aspect ratio has changed
|
||||
|| ar.ratio !== this.lastAr.ratio // this also means aspect ratio has changed
|
||||
) {
|
||||
this.zoom.reset();
|
||||
this.resetPan();
|
||||
}
|
||||
@ -239,29 +239,29 @@ class Resizer {
|
||||
this.conf.destroy();
|
||||
}
|
||||
|
||||
// pause AR on basic stretch, unpause when using other modes
|
||||
// for sine reason unpause doesn't unpause. investigate that later
|
||||
try {
|
||||
if (this.stretcher.mode === Stretch.Basic) {
|
||||
this.conf.arDetector.pause();
|
||||
} else {
|
||||
if (this.lastAr.type === AspectRatio.Automatic) {
|
||||
this.conf.arDetector.unpause();
|
||||
}
|
||||
// pause AR on:
|
||||
// * ar.type NOT automatic
|
||||
// * ar.type is auto, but stretch is set to basic basic stretch
|
||||
//
|
||||
// unpause when using other modes
|
||||
if (ar.type !== AspectRatio.Automatic || this.stretcher.mode === Stretch.Basic) {
|
||||
this.conf?.arDetector?.pause();
|
||||
} else {
|
||||
if (this.lastAr.type === AspectRatio.Automatic) {
|
||||
this.conf?.arDetector?.unpause();
|
||||
}
|
||||
} catch (e) { // resizer starts before arDetector. this will do nothing but fail if arDetector isn't setup
|
||||
|
||||
}
|
||||
|
||||
// do stretch thingy
|
||||
if (this.stretcher.mode === Stretch.NoStretch
|
||||
|| this.stretcher.mode === Stretch.Conditional
|
||||
|| this.stretcher.mode === Stretch.FixedSource){
|
||||
|
||||
var stretchFactors = this.scaler.calculateCrop(ar);
|
||||
|
||||
this.logger.log('error', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> failed to set AR due to problem with calculating crop. Error:`, stretchFactors && stretchFactors.error);
|
||||
|
||||
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);
|
||||
if (stretchFactors?.error === 'no_video'){
|
||||
this.conf.destroy();
|
||||
return;
|
||||
@ -303,14 +303,17 @@ class Resizer {
|
||||
|
||||
this.zoom.applyZoom(stretchFactors);
|
||||
|
||||
//TODO: correct these two
|
||||
var translate = this.computeOffsets(stretchFactors);
|
||||
this.applyCss(stretchFactors, translate);
|
||||
|
||||
}
|
||||
|
||||
|
||||
toFixedAr() {
|
||||
this.lastAr.type = AspectRatio.Fixed;
|
||||
// converting to fixed AR means we also turn off autoAR
|
||||
this.setAr({
|
||||
ar: this.lastAr.ar,
|
||||
type: AspectRatio.Fixed
|
||||
});
|
||||
}
|
||||
|
||||
resetLastAr() {
|
||||
@ -339,7 +342,9 @@ class Resizer {
|
||||
this.videoAlignment = VideoAlignment.Center;
|
||||
|
||||
// because non-fixed aspect ratios reset panning:
|
||||
this.toFixedAr();
|
||||
if (this.lastAr.type !== AspectRatio.Fixed) {
|
||||
this.toFixedAr();
|
||||
}
|
||||
|
||||
const player = this.conf.player.element;
|
||||
|
||||
@ -380,7 +385,7 @@ class Resizer {
|
||||
}
|
||||
|
||||
restore() {
|
||||
this.logger.log('info', 'debug', "[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio", {'a_lastAr': this.lastAr} );
|
||||
this.logger.log('info', 'debug', "[Resizer::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 === AspectRatio.Initial){
|
||||
@ -442,18 +447,85 @@ class Resizer {
|
||||
|
||||
// mostly internal stuff
|
||||
|
||||
/**
|
||||
* Returns the size of the video file _as displayed_ on the screen.
|
||||
* Consider the following example:
|
||||
*
|
||||
* * player dimensions are 2560x1080
|
||||
* * <video> is child of player
|
||||
* * <video> has the following css: {width: 100%, height: 100%}
|
||||
* * video file dimensions are 1280x720
|
||||
*
|
||||
* CSS will ensure that the dimensions of <video> tag are equal to the dimension of the
|
||||
* player element — that is, 2560x1080px. This is no bueno, because the browser will upscale
|
||||
* the video file to take up as much space as it can (without stretching it). This means
|
||||
* we'll get a 1920x1080 video (as displayed) and a letterbox.
|
||||
*
|
||||
* We can't get that number out of anywhere: video.videoWidth will return 1280 (video file
|
||||
* dimensions) and .offsetWidth (and the likes) will return the <video> tag dimension. Neither
|
||||
* will return the actual size of video as displayed, which we need in order to calculate the
|
||||
* extra space to the left and right of the video.
|
||||
*
|
||||
* We make the assumption of the
|
||||
*/
|
||||
computeVideoDisplayedDimensions() {
|
||||
const offsetWidth = this.conf.video.offsetWidth;
|
||||
const offsetHeight = this.conf.video.offsetHeight;
|
||||
|
||||
const scaleX = offsetWidth / this.conf.video.videoWidth;
|
||||
const scaleY = offsetHeight / this.conf.video.videoHeight;
|
||||
|
||||
// if differences between the scale factors are minimal, we presume offsetWidth and
|
||||
// offsetHeight are the accurate enough for our needs
|
||||
if (Math.abs(scaleX - scaleY) < 0.02) {
|
||||
return {
|
||||
realVideoWidth: offsetWidth,
|
||||
realVideoHeight: offsetHeight,
|
||||
marginX: 0,
|
||||
marginY: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// if we're still here, we need to calculate real video dimensions
|
||||
const diffX = Math.abs(scaleY * this.conf.video.videoWidth - offsetWidth);
|
||||
const diffY = Math.abs(scaleX * this.conf.video.videoHeight - offsetHeight);
|
||||
|
||||
// in this case, we want to base our real dimensions off scaleX
|
||||
// otherwise, we want to base it off scaleY
|
||||
if (diffX < diffY) {
|
||||
const realHeight = this.conf.video.videoHeight * scaleX;
|
||||
return {
|
||||
realVideoWidth: offsetWidth,
|
||||
realVideoHeight: realHeight,
|
||||
marginX: 0,
|
||||
marginY: (offsetHeight - realHeight) * 0.5
|
||||
}
|
||||
} else {
|
||||
const realWidth = this.conf.video.videoWidth * scaleY;
|
||||
return {
|
||||
realVideoWidth: realWidth,
|
||||
realVideoHeight: offsetHeight,
|
||||
marginX: (offsetWidth - realWidth) * 0.5,
|
||||
marginY: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
computeOffsets(stretchFactors){
|
||||
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.settings.active.sites['@global'].videoAlignment);
|
||||
|
||||
const wdiff = this.conf.player.dimensions.width - this.conf.video.offsetWidth;
|
||||
const hdiff = this.conf.player.dimensions.height - this.conf.video.offsetHeight;
|
||||
const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();
|
||||
|
||||
|
||||
const wdiff = this.conf.player.dimensions.width - realVideoWidth;
|
||||
const hdiff = this.conf.player.dimensions.height - realVideoHeight;
|
||||
|
||||
if (wdiff < 0 && hdiff < 0 && this.zoom.scale > 1) {
|
||||
this.conf.player.re
|
||||
this.conf.player.restore();
|
||||
}
|
||||
|
||||
const wdiffAfterZoom = this.conf.video.offsetWidth * stretchFactors.xFactor - this.conf.player.dimensions.width;
|
||||
const hdiffAfterZoom = this.conf.video.offsetHeight * stretchFactors.yFactor - this.conf.player.dimensions.height;
|
||||
const wdiffAfterZoom = realVideoWidth * stretchFactors.xFactor - this.conf.player.dimensions.width;
|
||||
const hdiffAfterZoom = realVideoHeight * stretchFactors.yFactor - this.conf.player.dimensions.height;
|
||||
|
||||
const translate = {
|
||||
x: wdiff * 0.5,
|
||||
@ -482,6 +554,7 @@ class Resizer {
|
||||
'---- data in ----',
|
||||
'\nplayer dimensions: ', {w: this.conf.player.dimensions.width, h: this.conf.player.dimensions.height},
|
||||
'\nvideo dimensions: ', {w: this.conf.video.offsetWidth, h: this.conf.video.offsetHeight},
|
||||
'\nreal video dimensions:', {w: realVideoWidth, h: realVideoHeight},
|
||||
'\nstretch factors: ', stretchFactors,
|
||||
'\npan & zoom: ', this.pan, this.zoom.scale,
|
||||
'\nwdiff, hdiff: ', wdiff, 'x', hdiff,
|
||||
@ -506,8 +579,11 @@ class Resizer {
|
||||
`Video seems to be both wider and taller (or shorter and narrower) than player element at the same time. This is super duper not supposed to happen.\n\n`,
|
||||
`Player element needs to be checked.`
|
||||
)
|
||||
this.player.checkPlayerSizeChange();
|
||||
if (this.conf.player.checkPlayerSizeChange()) {
|
||||
this.conf.player.onPlayerDimensionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
return translate;
|
||||
}
|
||||
|
||||
@ -538,11 +614,13 @@ class Resizer {
|
||||
styleArray[i] = styleArray[i].trim();
|
||||
// some sites do 'top: 50%; left: 50%; transform: <transform>' to center videos.
|
||||
// we dont wanna, because we already center videos on our own
|
||||
if (styleArray[i].startsWith("transform:") ||
|
||||
styleArray[i].startsWith("top:") ||
|
||||
styleArray[i].startsWith("left:") ||
|
||||
styleArray[i].startsWith("right:") ||
|
||||
styleArray[i].startsWith("bottom:") ){
|
||||
if (styleArray[i].startsWith("transform:")
|
||||
|| styleArray[i].startsWith("top:")
|
||||
|| styleArray[i].startsWith("left:")
|
||||
|| styleArray[i].startsWith("right:")
|
||||
|| styleArray[i].startsWith("bottom:")
|
||||
|| styleArray[i].startsWith("margin")
|
||||
){
|
||||
delete styleArray[i];
|
||||
}
|
||||
}
|
||||
@ -592,9 +670,13 @@ class Resizer {
|
||||
|
||||
const styleArray = this.buildStyleArray('', extraStyleString)
|
||||
|
||||
// sometimes, site designers will center <video> by setting margin: to something. We do not like that, as
|
||||
// it prevents extension from working properly.
|
||||
styleArray.push('margin: 0px 0px 0px 0px !important; width: initial !important; height: initial !important');
|
||||
|
||||
// add remaining elements
|
||||
if (stretchFactors) {
|
||||
styleArray.push(`transform: translate(${translate.x}px, ${translate.y}px) scale(${stretchFactors.xFactor}, ${stretchFactors.yFactor})`);
|
||||
styleArray.push(`transform: translate(${translate.x}px, ${translate.y}px) scale(${stretchFactors.xFactor}, ${stretchFactors.yFactor}) !important;`);
|
||||
|
||||
// important — guarantees video will be properly aligned
|
||||
styleArray.push("top: 0px !important; left: 0px !important; bottom: 0px !important; right: 0px;");
|
||||
|
@ -32,10 +32,9 @@ class Scaler {
|
||||
}
|
||||
|
||||
|
||||
if(! this.conf.player.dimensions ){
|
||||
if (!this.conf.player.dimensions) {
|
||||
ratioOut = screen.width / screen.height;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ratioOut = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
|
||||
}
|
||||
|
||||
@ -47,17 +46,17 @@ class Scaler {
|
||||
|
||||
var fileAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
|
||||
|
||||
if (ar.type === AspectRatio.FitWidth){
|
||||
if (ar.type === AspectRatio.FitWidth) {
|
||||
ratioOut > fileAr ? ratioOut : fileAr
|
||||
ar.ratio = ratioOut;
|
||||
return ratioOut;
|
||||
}
|
||||
else if(ar.type === AspectRatio.FitHeight){
|
||||
else if (ar.type === AspectRatio.FitHeight) {
|
||||
ratioOut < fileAr ? ratioOut : fileAr
|
||||
ar.ratio = ratioOut;
|
||||
return ratioOut;
|
||||
}
|
||||
else if(ar.type === AspectRatio.Reset){
|
||||
else if (ar.type === AspectRatio.Reset) {
|
||||
this.logger.log('info', 'debug', "[Scaler.js::modeToAr] Using original aspect ratio -", fileAr)
|
||||
ar.ar = fileAr;
|
||||
return fileAr;
|
||||
|
@ -155,6 +155,10 @@ class UW {
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.pageInfo) {
|
||||
this.logger.log('info', 'debug', '[uw.js::setup] An instance of pageInfo already exists and will be destroyed.');
|
||||
this.pageInfo.destroy();
|
||||
}
|
||||
this.pageInfo = new PageInfo(this.comms, this.settings, this.logger, extensionMode, isSiteDisabled);
|
||||
this.logger.log('info', 'debug', "[uw.js::setup] pageInfo initialized.");
|
||||
|
||||
@ -162,6 +166,9 @@ class UW {
|
||||
|
||||
// start action handler only if extension is enabled for this site
|
||||
if (!isSiteDisabled) {
|
||||
if (this.actionHandler) {
|
||||
this.actionHandler.destroy();
|
||||
}
|
||||
this.actionHandler = new ActionHandler(this.pageInfo);
|
||||
this.actionHandler.init();
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"manifest_version": 2,
|
||||
"name": "Ultrawidify",
|
||||
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
|
||||
"version": "4.4.9.2",
|
||||
"version": "4.4.10",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"
|
||||
|
@ -2,25 +2,21 @@
|
||||
<div>
|
||||
<h2>What's new</h2>
|
||||
<p>Full changelog for older versions <a href="https://github.com/tamius-han/ultrawidify/blob/master/CHANGELOG.md">is available here</a>.</p>
|
||||
<p class="label">4.4.9.2</p>
|
||||
<p class="label">4.4.10</p>
|
||||
<ul>
|
||||
<li>
|
||||
Fixed issue with video alignment on youtube under certain conditions (previously fixed in v4.4.7.1-2), but this time for real (hopefully).
|
||||
Video alignment should now work on Twitch (<a href="https://github.com/tamius-han/ultrawidify/issues/109">#109</a>)
|
||||
</li>
|
||||
<li>
|
||||
Fixed the bug where extension wouldn't work when URL specified a port (e.g. www.example.com:80)
|
||||
Videos should now align properly on Hulu while cropped (<a href="https://github.com/tamius-han/ultrawidify/issues/111">#111 & via email</a>)
|
||||
</li>
|
||||
<li>
|
||||
<b>[4.4.9.1]</b> removed source maps from extension build
|
||||
Fixed a problem where changing certain settings would cause multiple instances of Ultrawidify to run on a page, effectively preventing some crop options to be set until reload. (possibly <a href="(https://github.com/tamius-han/ultrawidify/issues/112">#112</a>?)
|
||||
</li>
|
||||
<li>
|
||||
<b>[4.4.9.2]</b> updated npm packages
|
||||
Fixed a problem where embedded videos would be misaligned after switching from full screen
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
In addition to that, as of 4.4.9.1 the build process ensures removal of `node_modules` before building the extension so we can have
|
||||
reproducible builds except for real this time. Hopefully.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
Loading…
Reference in New Issue
Block a user