Whitespace

This commit is contained in:
Tamius Han 2021-10-25 23:11:34 +02:00
parent 746a78577e
commit a4948d3eef
5 changed files with 146 additions and 134 deletions

View File

@ -14,7 +14,7 @@ interface ActionScopeInterface {
code?: string,
ctrlKey?: boolean,
metaKey?: boolean,
altKey?: boolean,
altKey?: boolean,
shiftKey?: boolean,
onKeyUp?: boolean,
onKeyDown?: boolean,
@ -22,10 +22,17 @@ interface ActionScopeInterface {
}[],
}
interface RestrictionsSettings {
disableOnSmallPlayers?: boolean; // Whether ultrawidify should disable itself when the player is small
minAllowedWidth?: number; // if player is less than this many px wide, ultrawidify will disable itself
minAllowedHeight?: number; // if player is less than this many px tall, ultrawidify will disable itself
onlyAllowInFullscreen?: boolean; // if enabled, ultrawidify will be disabled when not in full screen regardless of what previous two options say
}
interface SettingsInterface {
arDetect: {
disabledReason: string, // if automatic aspect ratio has been disabled, show reason
allowedMisaligned: number, // top and bottom letterbox thickness can differ by this much.
allowedMisaligned: number, // top and bottom letterbox thickness can differ by this much.
// Any more and we don't adjust ar.
allowedArVariance: number, // amount by which old ar can differ from the new (1 = 100%)
timers: { // autodetection frequency
@ -56,14 +63,14 @@ interface SettingsInterface {
},
},
// samplingInterval: 10, // we sample at columns at (width/this) * [ 1 .. this - 1]
// samplingInterval: 10, // we sample at columns at (width/this) * [ 1 .. this - 1]
blackframe: {
sufficientColorVariance: number, // calculate difference between average intensity and pixel, for every pixel for every color
// component. Average intensity is normalized to where 0 is black and 1 is biggest value for
// that component. If sum of differences between normalized average intensity and normalized
// component varies more than this % between color components, we can afford to use less strict
// cumulative threshold.
cumulativeThresholdLax: number,
cumulativeThresholdLax: number,
cumulativeThresholdStrict: number,// if we add values of all pixels together and get more than this, the frame is bright enough.
// (note: blackframe is 16x9 px -> 144px total. cumulative threshold can be reached fast)
blackPixelsCondition: number, // How much pixels must be black (1 all, 0 none) before we consider frame as black. Takes
@ -103,7 +110,7 @@ interface SettingsInterface {
randomCols: number, // we add this many randomly selected columns to the static columns
staticRows: number, // forms grid with staticSampleCols. Determined in the same way. For black frame checks
},
guardLine: { // all pixels on the guardline need to be black, or else we trigger AR recalculation
guardLine: { // all pixels on the guardline need to be black, or else we trigger AR recalculation
// (if AR fails to be recalculated, we reset AR)
enabled: boolean,
ignoreEdgeMargin: number, // we ignore anything that pokes over the black line this close to the edge
@ -117,14 +124,14 @@ interface SettingsInterface {
safetyBorderPx: number, // determines the thickness of safety border in fallback mode
noTriggerZonePx: number // if we detect edge less than this many pixels thick, we don't correct.
},
arSwitchLimiter: { // to be implemented
arSwitchLimiter: { // to be implemented
switches: number, // we can switch this many times
period: number // per this period
},
edgeDetection: {
sampleWidth: number, // we take a sample this wide for edge detection
detectionThreshold: number, // sample needs to have this many non-black pixels to be a valid edge
confirmationThreshold: number, //
confirmationThreshold: number, //
singleSideConfirmationThreshold: number, // we need this much edges (out of all samples, not just edges) in order
// to confirm an edge in case there's no edges on top or bottom (other
// than logo, of course)
@ -138,11 +145,11 @@ interface SettingsInterface {
// are now. (NOTE: keep this less than 1 in case we implement logo detection)
},
pillarTest: {
ignoreThinPillarsPx: number, // ignore pillars that are less than this many pixels thick.
ignoreThinPillarsPx: number, // ignore pillars that are less than this many pixels thick.
allowMisaligned: number // left and right edge can vary this much (%)
},
textLineTest: {
nonTextPulse: number, // if a single continuous pulse has this many non-black pixels, we aren't dealing
nonTextPulse: number, // if a single continuous pulse has this many non-black pixels, we aren't dealing
// with text. This value is relative to canvas width (%)
pulsesToConfirm: number, // this is a threshold to confirm we're seeing text.
pulsesToConfirmIfHalfBlack: number, // this is the threshold to confirm we're seeing text if longest black pulse
@ -150,11 +157,15 @@ interface SettingsInterface {
testRowOffset: number // we test this % of height from detected edge
}
},
restrictions?: RestrictionsSettings;
zoom: {
minLogZoom: number,
maxLogZoom: number,
announceDebounce: number // we wait this long before announcing new zoom
},
miscSettings: {
mousePan: {
enabled: boolean
@ -197,8 +208,8 @@ interface SettingsInterface {
// ::: ACTIONS :::
// -----------------------------------------
// Nastavitve za ukaze. Zamenja stare nastavitve za bližnične tipke.
//
// Polje 'shortcut' je tabela, če se slučajno lotimo kdaj delati choordov.
//
// Polje 'shortcut' je tabela, če se slučajno lotimo kdaj delati choordov.
actions: {
name?: string, // name displayed in settings
label?: string, // name displayed in ui (can be overridden in scope/playerUi)
@ -226,31 +237,31 @@ interface SettingsInterface {
// -----------------------------------------
// Nastavitve za posamezno stran
// Config for a given page:
//
//
// <hostname> : {
// status: <option> // should extension work on this site?
// arStatus: <option> // should we do autodetection on this site?
//
//
// defaultAr?: <ratio> // automatically apply this aspect ratio on this side. Use extension defaults if undefined.
// stretch? <stretch mode> // automatically stretch video on this site in this manner
// videoAlignment? <left|center|right>
//
// type: <official|community|user> // 'official' — blessed by Tam.
// type: <official|community|user> // 'official' — blessed by Tam.
// // 'community' — blessed by reddit.
// // 'user' — user-defined (not here)
// override: <true|false> // override user settings for this site on update
// }
//
// Veljavne vrednosti za možnosti
// }
//
// Veljavne vrednosti za možnosti
// Valid values for options:
//
// status, arStatus, statusEmbedded:
//
//
// * enabled — always allow, full
// * basic — allow, but only the basic version without playerData
// * default — allow if default is to allow, block if default is to block
// * disabled — never allow
//
//
sites: {
[x: string]: {
mode?: ExtensionMode,
@ -286,8 +297,10 @@ interface SettingsInterface {
},
css?: string;
usePlayerArInFullscreen?: boolean;
restrictions?: RestrictionsSettings;
}
}
}
export default SettingsInterface;
export default SettingsInterface;

View File

@ -39,7 +39,7 @@ class PageInfo {
currentCrop: any;
actionHandlerInitQueue: any[] = [];
currentZoomScale: number = 1;
actionHandler: any;
//#endregion
@ -51,7 +51,7 @@ class PageInfo {
this.extensionMode = extensionMode;
this.readOnly = readOnly;
if (comms){
if (comms){
this.comms = comms;
}
@ -179,10 +179,10 @@ class PageInfo {
* of videos. Destroys all videoData objects for all the videos that don't have their
* own <video> html element on the page.
* @param rescanReason Why was the rescan triggered. Mostly used for logging.
* @returns
* @returns
*/
rescan(rescanReason?: RescanReason){
// is there any video data objects that had their HTML elements removed but not yet
// is there any video data objects that had their HTML elements removed but not yet
// destroyed? We clean that up here.
const orphans = this.videos.filter(x => !document.body.contains(x.element));
for (const orphan of orphans) {
@ -198,7 +198,7 @@ class PageInfo {
if(!vids || vids.length == 0){
this.hasVideos = false;
if(rescanReason == RescanReason.PERIODIC){
this.logger.log('info', 'videoRescan', "[PageInfo::rescan] Scheduling normal rescan.")
this.scheduleRescan(RescanReason.PERIODIC);
@ -221,14 +221,14 @@ class PageInfo {
if(!videoElement.offsetWidth || !videoElement.offsetHeight) {
continue;
}
// at this point, we're certain that we found new videos. Let's update some properties:
this.hasVideos = true;
// if PageInfo is marked as "readOnly", we actually aren't adding any videos to anything because
// that's super haram. We're only interested in whether
// that's super haram. We're only interested in whether
if (this.readOnly) {
// in lite mode, we're done. This is all the info we want, but we want to actually start doing
// 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 running a rescan, tho.
if(rescanReason == RescanReason.PERIODIC){
@ -241,11 +241,11 @@ class PageInfo {
try {
const newVideo = new VideoData(videoElement, this.settings, this);
this.videos.push({videoData: newVideo, element: videoElement});
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.log('info', 'videoRescan', "END VIDEO INITIALIZATION\n\n\n-------------------------------------\nvideos[] is now this:", this.videos,"\n\n\n\n\n\n\n\n")
}
@ -254,24 +254,24 @@ class PageInfo {
// if we're left without videos on the current page, we unregister the page.
// if we have videos, we call register.
if (this.comms) {
// We used to send "register video" requests only on the first load, or if the number of
// We used to send "register video" requests only on the first load, or if the number of
// videos on the page has changed. However, since Chrome Web Store started to require every
// extension requiring "broad permissions" to undergo manual review
// ... and since Chrome Web Store is known for taking their sweet ass time reviewing extensions,
// with review times north of an entire fucking month
// ... and since the legacy way of checking whether our frames-with-videos cache in background
// ... and since the legacy way of checking whether our frames-with-videos cache in background
// script contains any frames that no longer exist required us to use webNavigation.getFrame()/
// webNavigation.getAllFrames(), which requires a permission that triggers a review.
// webNavigation.getAllFrames(), which requires a permission that triggers a review.
//
// While the extension uses some other permissions that trigger manual review, it's said that
// less is better / has a positive effect on your manual review times ... So I guess we'll do
// less is better / has a positive effect on your manual review times ... So I guess we'll do
// things in the less-than-optimal. more-than-retarded way.
//
// no but honestly fuck Chrome.
// if (this.videos.length != oldVideoCount) {
// }
// }
if (this.videos.length > 0) {
// this.comms.registerVideo({host: window.location.hostname, location: window.location});
this.comms.registerVideo();
@ -313,7 +313,7 @@ class PageInfo {
}
let ths = this;
this.rescanTimer = setTimeout(function(rescanReason){
ths.rescanTimer = null;
ths.rescan(rescanReason);
@ -331,7 +331,7 @@ class PageInfo {
}
let ths = this;
this.urlCheckTimer = setTimeout(function(){
ths.urlCheckTimer = null;
ths.ghettoUrlCheck();
@ -345,7 +345,7 @@ class PageInfo {
ghettoUrlCheck() {
if (this.lastUrl != window.location.href){
this.logger.log('error', 'videoRescan', "[PageInfo::ghettoUrlCheck] URL has changed. Triggering a rescan!");
this.rescan(RescanReason.URL_CHANGE);
this.lastUrl = window.location.href;
}
@ -377,7 +377,7 @@ class PageInfo {
if (vd.videoData.isPlaying()) {
vd.videoData.pause();
}
}
}
} else {
for(let vd of this.videos){
vd.videoData.pause();
@ -426,7 +426,7 @@ class PageInfo {
stopArDetection(playingOnly){
if (playingOnly) {
for(let vd of this.videos){
if (vd.videoData.isPlaying()) {
if (vd.videoData.isPlaying()) {
vd.videoData.stopArDetection();
}
}
@ -474,11 +474,11 @@ class PageInfo {
}
}
}
setVideoAlignment(videoAlignment, playingOnly) {
if (playingOnly) {
for(let vd of this.videos) {
if (vd.videoData.isPlaying()) {
if (vd.videoData.isPlaying()) {
vd.videoData.setVideoAlignment(videoAlignment)
}
}
@ -555,7 +555,7 @@ class PageInfo {
}
}
markPlayer(name, color) {
markPlayer(name, color) {
for (let vd of this.videos) {
vd.videoData.markPlayer(name,color);
}
@ -604,7 +604,7 @@ class PageInfo {
setArPersistence(persistenceMode) {
// name of this function is mildly misleading — we don't really _set_ ar persistence. (Ar persistence
// mode is set and saved via popup or keyboard shortcuts, if user defined them) We just save the current
// aspect ratio whenever aspect ratio persistence mode changes.
// aspect ratio whenever aspect ratio persistence mode changes.
if (persistenceMode === CropModePersistence.CurrentSession) {
sessionStorage.setItem('uw-crop-mode-session-persistence', JSON.stringify(this.currentCrop));
} else if (persistenceMode === CropModePersistence.Forever) {
@ -615,7 +615,7 @@ class PageInfo {
this.settings.active.sites[window.location.hostname] = this.settings.getDefaultOption();
this.settings.active.sites[window.location.hostname]['defaultAr'] = this.currentCrop;
}
this.settings.saveWithoutReload();
}
}
@ -632,7 +632,7 @@ class PageInfo {
}
this.defaultCrop = ar;
if (cropModePersistence === CropModePersistence.CurrentSession) {
sessionStorage.setItem('uw-crop-mode-session-persistence', JSON.stringify(ar));
} else if (cropModePersistence === CropModePersistence.Forever) {
@ -643,7 +643,7 @@ class PageInfo {
this.settings.active.sites[window.location.hostname] = this.settings.getDefaultOption();
this.settings.active.sites[window.location.hostname]['defaultAr'] = ar;
}
this.settings.saveWithoutReload();
}
}

View File

@ -202,7 +202,7 @@ class PlayerData {
// attributeFilter: ['style', 'class'],
attributeOldValue: true,
};
this.observer.observe(this.element);
} catch (e) {
console.error("failed to set observer",e )
@ -361,7 +361,6 @@ class PlayerData {
element = element.parentNode;
}
if (element) {
this.updatePlayerDimensions(element);
return element;
}
} else if (this.settings.active.sites[host]?.DOM?.player?.querySelectors) {
@ -372,7 +371,7 @@ class PlayerData {
// Let's see how this works
if (this.collectionHas(allSelectors, element)) {
score = 100; // every matching element gets a baseline 100 points
// elements that match the size get a hefty bonus
if ( (element.offsetWidth >= videoWidth && this.equalish(element.offsetHeight, videoHeight, 2))
|| (element.offsetHeight >= videoHeight && this.equalish(element.offsetWidth, videoHeight, 2))) {
@ -414,12 +413,12 @@ class PlayerData {
element = element.parentNode;
continue;
}
// element is player, if at least one of the sides is as long as the video
// note that we can't make any additional assumptions with regards to player
// size, since there are both cases where the other side is bigger _and_ cases
// where other side is smaller than the video.
//
//
// Don't bother thinking about this too much, as any "thinking" was quickly
// corrected by bugs caused by various edge cases.
if (
@ -439,7 +438,7 @@ class PlayerData {
score -= scorePenalty * penaltyMultiplier++;
// the bigger the size difference between the video and the player,
// the more penalty we'll incur. Since we did some grace ith
// the more penalty we'll incur. Since we did some grace ith
let playerSizePenalty = 1;
if ( element.offsetHeight > (videoHeight + 5)) {
playerSizePenalty = (element.offsetWidth - videoHeight) * sizePenaltyMultiplier;
@ -455,7 +454,7 @@ class PlayerData {
score: score,
});
}
element = element.parentNode;
}
@ -465,7 +464,7 @@ class PlayerData {
if (elementQ.length) {
// return element with biggest score
const playerElement = elementQ.sort( (a,b) => b.score - a.score)[0].element;
this.updatePlayerDimensions(playerElement);
return playerElement;
}
@ -487,7 +486,7 @@ class PlayerData {
forceDetectPlayerElementChange() {
// Player dimension changes get calculated every time updatePlayerDimensions is called (which happens
// every time getPlayer() detects an element). If updatePlayerDimension detects dimensions were changed,
// it will always re-apply current crop, rendering this function little more than a fancy alias for
// it will always re-apply current crop, rendering this function little more than a fancy alias for
// getPlayer().
this.getPlayer();
}

View File

@ -57,10 +57,10 @@ class VideoData {
return 1;
}
}
constructor(video, settings, pageInfo){
(window as any).ultrawidify.addVideo(this);
this.logger = pageInfo.logger;
this.arSetupComplete = false;
this.video = video;
@ -87,15 +87,15 @@ class VideoData {
async onVideoLoaded() {
if (!this.videoLoaded) {
/**
* video.readyState 101:
* 0 no info. Can't play.
* 0 no info. Can't play.
* 1 we have metadata but nothing else
* 2 we have data for current playback position, but not future <--- meaning current frame, meaning Aard can work here or higher
* 3 we have a lil bit for the future
* 4 we'll survive to the end
*/
*/
if (!this.video?.videoWidth || !this.video?.videoHeight || this.video.readyState < 2) {
return; // onVideoLoaded is a lie in this case
}
@ -199,7 +199,7 @@ class VideoData {
// INIT OBSERVERS
try {
if (BrowserDetect.firefox) {
this.observer = new ResizeObserver(
this.observer = new ResizeObserver(
_.debounce(
this.onVideoDimensionsChanged,
250,
@ -212,11 +212,11 @@ class VideoData {
} else {
// Chrome for some reason insists that this.onPlayerDimensionsChanged is not a function
// when it's not wrapped into an anonymous function
this.observer = new ResizeObserver(
this.observer = new ResizeObserver(
_.debounce(
(m, o) => {
this.onVideoDimensionsChanged(m, o)
},
},
250,
{
leading: true,
@ -252,7 +252,7 @@ class VideoData {
// start fallback video/player size detection
this.fallbackChangeDetection();
// force reload last aspect ratio (if default crop ratio exists), but only after the video is
// force reload last aspect ratio (if default crop ratio exists), but only after the video is
if (this.pageInfo.defaultCrop) {
this.resizer.setAr(this.pageInfo.defaultCrop);
}
@ -315,7 +315,7 @@ class VideoData {
if (this.video) {
this.video.classList.remove(this.userCssClassName);
this.video.classList.remove('uw-ultrawidify-base-wide-screen');
this.video.classList.remove('uw-ultrawidify-base-wide-screen');
this.video.removeEventListener('onloadeddata', this.onLoadedData);
this.video.removeEventListener('onloadedmetadata', this.onLoadedMetadata);
@ -354,14 +354,14 @@ class VideoData {
}
//#endregion
restoreCrop() {
restoreCrop() {
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) {
this.resizer.setAr(this.pageInfo.defaultCrop);
} else {
this.resizer.reset();
this.resizer.reset();
try {
this.stopArDetection();
@ -500,7 +500,7 @@ class VideoData {
this.player.forceDetectPlayerElementChange();
this.restoreAr();
}
} catch(e) {
console.error('Validating video offsets failed:', e)
}
@ -518,7 +518,7 @@ class VideoData {
// This will _always_ give us an array. Empty string gives an array
// that contains one element. That element is an empty string.
const styleArray = (this.video.getAttribute('style') || '').split(';');
const styleObject = {};
for (const style of styleArray) {
@ -537,10 +537,10 @@ class VideoData {
}
/**
* Some sites try to accomodate ultrawide users by "cropping" videos
* Some sites try to accommodate ultrawide users by "cropping" videos
* by setting 'style' attribute of the video element to 'height: X%',
* where 'X' is something greater than 100.
*
*
* This function gets that percentage and converts it into a factor.
*/
getHeightCompensationFactor() {
@ -579,7 +579,7 @@ class VideoData {
this.arDetector.init();
}
}
startArDetection() {
this.logger.log('info', 'debug', "[VideoData::startArDetection] starting AR detection")
if(this.destroyed || this.invalid) {
@ -670,7 +670,7 @@ class VideoData {
if (this.invalid) {
return;
}
if (ar.type === AspectRatioType.Fixed || ar.type === AspectRatioType.FitHeight || ar.type === AspectRatioType.FitHeight) {
this.player.forceRefreshPlayerElement();
}
@ -788,7 +788,7 @@ class VideoData {
this.logger.log('info', 'debug', "[VideoDetect] player size changed. reason: dimension change. Old dimensions?", this.dimensions.width, this.dimensions.height, "new dimensions:", this.video.offsetWidth, this.video.offsetHeight);
}
}
// if size doesn't match, update & return true
if (this.dimensions?.width != videoWidth
|| this.dimensions?.height != videoHeight ){

View File

@ -59,7 +59,7 @@ class Resizer {
this.settings = videoData.settings;
this.scaler = new Scaler(this.conf);
this.stretcher = new Stretcher(this.conf);
this.stretcher = new Stretcher(this.conf);
this.zoom = new Zoom(this.conf);
this.videoAlignment = this.settings.getDefaultVideoAlignment(window.location.hostname); // this is initial video alignment
@ -72,17 +72,17 @@ class Resizer {
this.canPan = false;
}
this.userCssClassName = videoData.userCssClassName;
this.userCssClassName = videoData.userCssClassName;
}
injectCss(css) {
this.conf.pageInfo.injectCss(css);
}
ejectCss(css) {
this.conf.pageInfo.ejectCss(css);
}
replaceCss(oldCss, newCss) {
this.conf.pageInfo.replaceCss(oldCss, newCss);
}
@ -101,7 +101,7 @@ class Resizer {
if (ar.type !== AspectRatioType.FitWidth && ar.type !== AspectRatioType.FitHeight && ar.ratio) {
return ar;
}
// Skrbi za "stare" možnosti, kot na primer "na širino zaslona", "na višino zaslona" in "ponastavi".
// Skrbi za "stare" možnosti, kot na primer "na širino zaslona", "na višino zaslona" in "ponastavi".
// Približevanje opuščeno.
// handles "legacy" options, such as 'fit to widht', 'fit to height' and AspectRatioType.Reset. No zoom tho
let ratioOut;
@ -112,22 +112,22 @@ class Resizer {
return null;
}
if (! this.conf.player.dimensions) {
ratioOut = screen.width / screen.height;
} else {
this.logger.log('info', 'debug', `[Resizer::calculateRatioForLegacyOptions] <rid:${this.resizerId}> Player dimensions:`, this.conf.player.dimensions.width ,'x', this.conf.player.dimensions.height,'aspect ratio:', this.conf.player.dimensions.width / this.conf.player.dimensions.height)
ratioOut = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
}
// POMEMBNO: lastAr je potrebno nastaviti šele po tem, ko kličemo _res_setAr(). _res_setAr() predvideva,
// da želimo nastaviti statično (type: 'static') razmerje stranic — tudi, če funkcijo kličemo tu oz. v ArDetect.
//
// IMPORTANT NOTE: lastAr needs to be set after _res_setAr() is called, as _res_setAr() assumes we're
// setting a static aspect ratio (even if the function is called from here or ArDetect).
// setting a static aspect ratio (even if the function is called from here or ArDetect).
let fileAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
if (ar.type === AspectRatioType.FitWidth){
ar.ratio = ratioOut > fileAr ? ratioOut : fileAr;
}
@ -168,12 +168,12 @@ class Resizer {
if (this.destroyed) {
return;
}
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.conf.videoUnloaded();
}
this.logger.log('info', 'debug', '[Resizer::setAr] <rid:'+this.resizerId+'> trying to set ar. New ar:', ar);
if (ar == null) {
@ -198,10 +198,10 @@ class Resizer {
// this means here's the optimal place to set or forget aspect ratio. Saving of current crop ratio
// is handled in pageInfo.updateCurrentCrop(), which also makes sure to persist aspect ratio if ar
// is set to persist between videos / through current session / until manual reset.
if (ar.type === AspectRatioType.Automatic ||
if (ar.type === AspectRatioType.Automatic ||
ar.type === AspectRatioType.Reset ||
ar.type === AspectRatioType.Initial ) {
// reset/undo default
// reset/undo default
this.conf.pageInfo.updateCurrentCrop(undefined);
} else {
this.conf.pageInfo.updateCurrentCrop(ar);
@ -224,7 +224,7 @@ class Resizer {
// if (this.extensionMode === ExtensionMode.Basic && !PlayerData.isFullScreen() && ar.type !== AspectRatioType.Reset) {
// // don't actually apply or calculate css when using basic mode if not in fullscreen
// // ... unless we're resetting the aspect ratio to original
// return;
// return;
// }
if (! this.video) {
@ -234,7 +234,7 @@ class Resizer {
// 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 !== AspectRatioType.Automatic || this.stretcher.mode === StretchType.Basic) {
this.conf?.arDetector?.pause();
@ -245,10 +245,10 @@ class Resizer {
}
// do stretch thingy
if (this.stretcher.mode === StretchType.NoStretch
|| this.stretcher.mode === StretchType.Conditional
if (this.stretcher.mode === StretchType.NoStretch
|| this.stretcher.mode === StretchType.Conditional
|| this.stretcher.mode === StretchType.FixedSource){
stretchFactors = this.scaler.calculateCrop(ar);
if(! stretchFactors || stretchFactors.error){
@ -274,7 +274,7 @@ class Resizer {
this.stretcher.applyStretchFixedSource(stretchFactors);
}
this.logger.log('info', 'debug', "[Resizer::setAr] Processed stretch factors for ",
this.stretcher.mode === StretchType.NoStretch ? 'stretch-free crop.' :
this.stretcher.mode === StretchType.NoStretch ? 'stretch-free crop.' :
this.stretcher.mode === StretchType.Conditional ? 'crop with conditional StretchType.' : 'crop with fixed stretch',
'Stretch factors are:', stretchFactors
);
@ -343,7 +343,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.setPan(relativeX, relativeY);
@ -356,7 +356,7 @@ class Resizer {
}
setPan(relativeMousePosX, relativeMousePosY){
// relativeMousePos[X|Y] - on scale from 0 to 1, how close is the mouse to player edges.
// relativeMousePos[X|Y] - on scale from 0 to 1, how close is the mouse to player edges.
// use these values: top, left: 0, bottom, right: 1
if(! this.pan){
this.pan = {x: 0, y: 0};
@ -379,7 +379,7 @@ class Resizer {
restore() {
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 === AspectRatioType.Initial){
this.setAr({type: AspectRatioType.Reset});
@ -414,7 +414,7 @@ class Resizer {
setZoom(zoomLevel, no_announce) {
this.zoom.setZoom(zoomLevel, no_announce);
}
zoomStep(step){
this.zoom.zoomStep(step);
}
@ -439,23 +439,23 @@ class Resizer {
/**
* 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
* 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
* 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
*
* We make the assumption of the
*/
computeVideoDisplayedDimensions() {
const offsetWidth = this.conf.video.offsetWidth;
@ -464,7 +464,7 @@ class Resizer {
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
// 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 {
@ -505,19 +505,19 @@ class Resizer {
* and let the browser figure out the height through the magic of height:auto. This is bad,
* because our addon generally relies of videos always being 100% of the height of the
* container.
*
* This sometimes leads to a situation where realVideoHeight and realVideoWidth at least
*
* This sometimes leads to a situation where realVideoHeight and realVideoWidth at least
* one of which should be roughly equal to the player width or hight with the other one being
* either smaller or equal are both smaller than player width or height; and sometimes
* either smaller or equal are both smaller than player width or height; and sometimes
* rather substantially. Fortunately for us, realVideo[Width|Height] and player dimensions
* never lie, which allows us to calculate the extra scale factor we need.
*
*
* Returned factor for this function should do fit:contain, not fit:cover.
* @param realVideoWidth real video width
* @param realVideoHeight real video height
* @param playerWidth player width
* @param playerHeight player height
* @param mode whether to
* @param mode whether to
*/
computeAutoHeightCompensationFactor(realVideoWidth: number, realVideoHeight: number, playerWidth: number, playerHeight: number, mode: 'height' | 'width'): number {
const widthFactor = playerWidth / realVideoWidth;
@ -538,7 +538,7 @@ class Resizer {
// We also don't compensate for height:auto if height is provided via element style
let autoHeightCompensationFactor;
if (
stretchFactors.cropStrategy === CropStrategy.CropLetterbox
stretchFactors.cropStrategy === CropStrategy.CropLetterbox
&& (!stretchFactors.styleHeightCompensationFactor || stretchFactors.styleHeightCompensationFactor === 1)
) {
autoHeightCompensationFactor = this.computeAutoHeightCompensationFactor(realVideoWidth, realVideoHeight, this.conf.player.dimensions.width, this.conf.player.dimensions.height, 'height');
@ -551,14 +551,14 @@ class Resizer {
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,
y: hdiff * 0.5,
};
if (this.pan.relativeOffsetX || this.pan.relativeOffsetY) {
// don't offset when video is smaller than player
@ -574,7 +574,7 @@ class Resizer {
translate.x -= wdiffAfterZoom * 0.5;
}
}
this.logger.log(
'info', ['debug', 'resizer'], "[Resizer::_res_computeOffsets] <rid:"+this.resizerId+"> calculated offsets:",
'\n\n---- elements ----',
@ -588,21 +588,21 @@ class Resizer {
'\nstretch factors: ', stretchFactors,
'\npan & zoom: ', this.pan, this.zoom.scale,
'\nwdiff, hdiff: ', wdiff, 'x', hdiff,
'\nwdiff, hdiffAfterZoom:', wdiffAfterZoom, 'x', hdiffAfterZoom,
'\nwdiff, hdiffAfterZoom:', wdiffAfterZoom, 'x', hdiffAfterZoom,
'\n\n---- data out ----\n',
'translate:', translate
);
// by the way, let's do a quick sanity check whether video player is doing any fuckies wuckies
// fucky wucky examples:
// fucky wucky examples:
//
// * video width is bigger than player width AND video height is bigger than player height
// * video width is smaller than player width AND video height is smaller than player height
//
// In both examples, at most one of the two conditions can be true at the same time. If both
// In both examples, at most one of the two conditions can be true at the same time. If both
// conditions are true at the same time, we need to go 'chiny reckon' and recheck our player
// element. Chances are our video is not getting aligned correctly
if (
if (
(this.conf.video.offsetWidth > this.conf.player.dimensions.width && this.conf.video.offsetHeight > this.conf.player.dimensions.height) ||
(this.conf.video.offsetWidth < this.conf.player.dimensions.width && this.conf.video.offsetHeight < this.conf.player.dimensions.height)
) {
@ -622,9 +622,9 @@ class Resizer {
}
}
return translate;
return translate;
}
//#region css handling
buildStyleArray(existingStyleString, extraStyleString) {
if (existingStyleString) {
@ -648,15 +648,15 @@ class Resizer {
}
}
}
for (let i in styleArray) {
styleArray[i] = styleArray[i].trim();
// some sites do 'top: 50%; left: 50%; transform: <transform>' to center videos.
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("top:")
|| styleArray[i].startsWith("left:")
|| styleArray[i].startsWith("right:")
|| styleArray[i].startsWith("bottom:")
|| styleArray[i].startsWith("margin")
){
@ -682,7 +682,7 @@ class Resizer {
}
applyCss(stretchFactors, translate){
// apply extra CSS here. In case of duplicated properties, extraCss overrides
// 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.");
@ -692,7 +692,7 @@ class Resizer {
}
this.logger.log('info', ['debug', 'resizer'], "[Resizer::applyCss] <rid:"+this.resizerId+"> will apply css.", {stretchFactors, translate});
// save stuff for quick tests (before we turn numbers into css values):
this.currentVideoSettings = {
validFor: this.conf.player.dimensions,
@ -716,7 +716,7 @@ class Resizer {
// important — guarantees video will be properly aligned
// Note that position:absolute cannot be put here, otherwise old.reddit /w RES breaks — videos embedded
// from certain hosts will get a height: 0px. This is bad.
styleArray.push("top: 0px !important; left: 0px !important; bottom: 0px !important; right: 0px;");
styleArray.push("top: 0px !important; left: 0px !important; bottom: 0px !important; right: 0px;");
// important — some websites (cough reddit redesign cough) may impose some dumb max-width and max-height
// restrictions. If site has dumb shit like 'max-width: 100%' and 'max-height: 100vh' in their CSS, that