diff --git a/js/conf/Debug.js b/js/conf/Debug.js index efd99fe..446be10 100644 --- a/js/conf/Debug.js +++ b/js/conf/Debug.js @@ -1,6 +1,6 @@ // Set prod to true when releasing -_prod = true; -// _prod = false; +// _prod = true; +_prod = false; Debug = { debug: true, diff --git a/js/conf/ExtensionConf.js b/js/conf/ExtensionConf.js index fd8ac87..b876b75 100644 --- a/js/conf/ExtensionConf.js +++ b/js/conf/ExtensionConf.js @@ -110,6 +110,9 @@ var ExtensionConf = { retryTimeout: 200 } }, + pan: { + mousePanEnabled: false + }, pageInfo: { timeouts: { urlCheck: 200, @@ -163,6 +166,18 @@ var ExtensionConf = { "u": { action: "zoom", arg: -0.1 + }, + "p": { + action: "pan", + arg: 'toggle' // possible: 'enable', 'disable', 'toggle' + }, + "Shift": { + action: "pan", + arg: 'toggle', + keyup: { + action: 'pan', + arg: 'toggle' + } } //#endregion }, diff --git a/js/conf/Keybinds.js b/js/conf/Keybinds.js index e27bf2e..0364bae 100644 --- a/js/conf/Keybinds.js +++ b/js/conf/Keybinds.js @@ -11,9 +11,10 @@ class Keybinds { setup(){ var ths = this; document.addEventListener('keydown', (event) => ths.handleKeypress(event) ); + document.addEventListener('keyup', (event) => ths.handleKeypress(event,true) ); } - handleKeypress(event) { // Tukaj ugotovimo, katero tipko smo pritisnili + handleKeypress(event, isKeyUp) { // Tukaj ugotovimo, katero tipko smo pritisnili if(Debug.debug && Debug.keyboard ){ console.log("%c[Keybinds::_kbd_process] we pressed a key: ", "color: #ff0", event.key , " | keydown: ", event.keydown, "event:", event); @@ -55,20 +56,29 @@ class Keybinds { if(this.settings.active.keyboard.shortcuts[keypress]){ var conf = this.settings.active.keyboard.shortcuts[keypress]; + + if (isKeyUp) { + if (conf.keyup) { + conf = conf.keyup; + } else { + return; + } + } - if(Debug.debug && Debug.keyboard) - console.log("[Keybinds::_kbd_process] there's an action associated with this keypress. conf:", conf); - - if(conf.action === "crop"){ + if(Debug.debug && Debug.keyboard) { + console.log("[Keybinds::_kbd_process] there's an action associated with this keypress. conf:", conf, "conf.arg:", conf.arg); + } + + if (conf.action === "crop"){ this.pageInfo.stopArDetection(); this.pageInfo.setAr(conf.arg); - } - if(conf.action === "zoom"){ + } else if (conf.action === "zoom"){ this.pageInfo.stopArDetection(); this.pageInfo.zoomStep(conf.arg); - } - if(conf.action === "auto-ar"){ + } else if (conf.action === "auto-ar"){ this.pageInfo.startArDetection(); + } else if (conf.action === "pan") { + this.pageInfo.setPanMode(conf.arg); } } } diff --git a/js/lib/PlayerData.js b/js/lib/PlayerData.js index b25a9ce..fe90fcc 100644 --- a/js/lib/PlayerData.js +++ b/js/lib/PlayerData.js @@ -32,9 +32,11 @@ class PlayerData { constructor(videoData) { this.videoData = videoData; this.video = videoData.video; + this.settings = videoData.settings; this.element = undefined; this.dimensions = undefined; + this.getPlayerDimensions(); this.startChangeDetection(); } @@ -139,6 +141,10 @@ class PlayerData { this.scheduleGhettoWatcher(); } + panHandler(event) { + this.videoData.panHandler(event); + } + getPlayerDimensions(elementNames){ // element names — reserved for future use. If element names are provided, this function should return first element that // has classname or id that matches at least one in the elementNames array. @@ -148,6 +154,10 @@ class PlayerData { if(Debug.debug) console.log("[PlayerDetect::_pd_getPlayerDimensions] element is not valid, doing nothing.", element) + if(this.element) { + const ths = this; + this.element.removeEventListener('mousemove', (event) => ths.panHandler(event)); + } this.element = undefined; this.dimensions = undefined; return; @@ -212,14 +222,24 @@ class PlayerData { height: window.innerHeight, fullscreen: true } + const ths = this; + if(this.element) { + this.element.removeEventListener('mousemove', (event) => ths.panHandler(event)); + } this.element = element; + this.element.addEventListener('mousemove', (event) => ths.panHandler(event)); } else { this.dimensions = { width: candidate_width, height: candidate_height, fullscreen: isFullScreen }; + const ths = this; + if(this.element) { + this.element.removeEventListener('mousemove', (event) => ths.panHandler(event)); + } this.element = playerCandidateNode; + this.element.addEventListener('mousemove', (event) => ths.panHandler(event)); } } diff --git a/js/lib/Settings.js b/js/lib/Settings.js index 130e340..f4d7e89 100644 --- a/js/lib/Settings.js +++ b/js/lib/Settings.js @@ -193,12 +193,6 @@ class Settings { Debug.debug = false; const cse = this.canStartExtension(site); Debug.debug = true; - - // console.log("[Settings::canStartExtension] ----------------\nCAN WE START THIS EXTENSION ON SITE", site, - // "?\n\nsettings.active.sites[site]=", this.active.sites[site], - // "\nExtension mode?", this.active.extensionMode, - // "\nCan extension be started?", cse - // ); } try{ // if site is not defined, we use default mode: diff --git a/js/lib/VideoData.js b/js/lib/VideoData.js index 419029b..2352aba 100644 --- a/js/lib/VideoData.js +++ b/js/lib/VideoData.js @@ -106,6 +106,14 @@ class VideoData { this.resizer.setAr(ar, lastAr); } + panHandler(event) { + this.resizer.panHandler(event); + } + + setPanMode(mode) { + this.resizer.setPanMode(mode); + } + restoreAr(){ this.resizer.restore(); } @@ -115,7 +123,7 @@ class VideoData { } zoomStep(step){ - this.resizer.zoomStep(); + this.resizer.zoomStep(step); } } \ No newline at end of file diff --git a/js/modules/PageInfo.js b/js/modules/PageInfo.js index fd496e1..3759e1c 100644 --- a/js/modules/PageInfo.js +++ b/js/modules/PageInfo.js @@ -226,6 +226,12 @@ class PageInfo { } } + setPanMode(mode) { + for(var vd of this.videos) { + vd.setPanMode(mode); + } + } + restoreAr() { for(var vd of this.videos){ vd.restoreAr() diff --git a/js/modules/Resizer.js b/js/modules/Resizer.js index 882fa3a..c6ae418 100644 --- a/js/modules/Resizer.js +++ b/js/modules/Resizer.js @@ -38,6 +38,13 @@ class Resizer { this.destroyed = false; this.resizerId = (Math.random(99)*100).toFixed(0); + + if (this.settings.active.pan) { + console.log("can pan:", this.settings.active.pan.mousePanEnabled, "(default:", this.settings.active.pan.mousePanEnabled, ")") + this.canPan = this.settings.active.pan.mousePanEnabled; + } else { + this.canPan = false; + } } start(){ @@ -138,6 +145,24 @@ class Resizer { this.restore(); } + panHandler(event) { + // console.log("this.conf.canPan:", this.conf.canPan) + if (this.canPan) { + // console.log("event?", event) + // console.log("this?", this) + + if(!this.conf.player || !this.conf.player.element) { + return; + } + const player = this.conf.player.element; + + const relativeX = (event.pageX - player.offsetLeft) / player.offsetWidth; + const relativeY = (event.pageY - player.offsetTop) / player.offsetHeight; + + this.setPan(relativeX, relativeY); + } + } + setPan(relativeMousePosX, relativeMousePosY){ // 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 @@ -145,8 +170,13 @@ class Resizer { this.pan = {}; } - this.pan.relativeOffsetX = relativeMousePosX*2.5 - 1.25; - this.pan.relativeOffsetY = relativeMousePosY*2.5 - 1.25; + this.pan.relativeOffsetX = -(relativeMousePosX * 1.1) + 0.55; + this.pan.relativeOffsetY = -(relativeMousePosY * 1.1) + 0.55; + + // if(Debug.debug){ + // console.log("[Resizer::setPan] relative cursor pos:", relativeMousePosX, ",",relativeMousePosY, " | new pan obj:", this.pan) + // } + this.restore(); } startCssWatcher(){ @@ -219,6 +249,16 @@ class Resizer { this.setAr('reset'); } + setPanMode(mode) { + if (mode === 'enable') { + this.canPan = true; + } else if (mode === 'disable') { + this.canPan = false; + } else if (mode === 'toggle') { + this.canPan = !this.canPan; + } + } + resetPan(){ this.pan = undefined; } @@ -246,33 +286,48 @@ class Resizer { computeOffsets(stretchFactors){ - if(Debug.debug) + if (Debug.debug) { console.log("[Resizer::_res_computeOffsets] video will be aligned to ", this.settings.active.miscFullscreenSettings.videoFloat); - + } + var actualWidth = this.conf.video.offsetWidth * stretchFactors.xFactor; var actualHeight = this.conf.video.offsetHeight * stretchFactors.yFactor; + var wdiff = actualWidth - this.conf.player.dimensions.width; + var hdiff = actualHeight - this.conf.player.dimensions.height; + var translate = {x: 0, y: 0}; if (this.pan) { - // todo: calculate translate + // don't offset when video is smaller than player + if(wdiff < 0 && hdiff < 0) { + return translate; + } + translate.x = wdiff * this.pan.relativeOffsetX / this.zoom.scale; + translate.y = hdiff * this.pan.relativeOffsetY / this.zoom.scale; } else { if (this.settings.active.miscFullscreenSettings.videoFloat == "left") { - translate.x = (this.conf.player.dimensions.width - actualWidth) * -0.5; + translate.x = wdiff * 0.5; } else if (this.settings.active.miscFullscreenSettings.videoFloat == "right") { - translate.x = (this.conf.player.dimensions.width - actualWidth) * 0.5; + translate.x = wdiff * -0.5; } } + if(Debug.debug) { + console.log("[Resizer::_res_computeOffsets] calculated offsets:", translate); + } + return translate; } applyCss(stretchFactors, translate){ if (! this.video) { - if(Debug.debug) + if(Debug.debug) { console.log("[Resizer::_res_applyCss] Video went missing, doing nothing."); + } + this.conf.destroy(); return; } diff --git a/js/modules/Zoom.js b/js/modules/Zoom.js index 11c503d..6bb7267 100644 --- a/js/modules/Zoom.js +++ b/js/modules/Zoom.js @@ -44,6 +44,12 @@ class Zoom { if (this.scale >= this.maxScale) { this.scale = this.maxScale; } + + if (Debug.debug) { + console.log("[Zoom::zoomStep] changing zoom by", amount, ". New zoom level:", this.scale); + } + + this.conf.restoreAr(); } setZoom(scale){ diff --git a/js/uw-bg.js b/js/uw-bg.js index ce40531..20ebe93 100644 --- a/js/uw-bg.js +++ b/js/uw-bg.js @@ -59,16 +59,16 @@ class UWServer { console.log("[uw-bg::onTabSwitched] TAB CHANGED, GETTING INFO FROM MAIN TAB"); try { - var tabId = activeInfo.tabId; // just for readability + var tabId = activeInfo.tabId; // just for readability - var tab; - if (BrowserDetect.firefox) { - var tab = await browser.tabs.get(tabId); - } else if (BrowserDetect.chrome) { - var tab = await this._promisifyTabsGet(chrome, tabId); - } + var tab; + if (BrowserDetect.firefox) { + var tab = await browser.tabs.get(tabId); + } else if (BrowserDetect.chrome) { + var tab = await this._promisifyTabsGet(chrome, tabId); + } - this.currentSite = this.extractHostname(tab.url); + this.currentSite = this.extractHostname(tab.url); } catch(e) { console.log(e); } diff --git a/manifest.json b/manifest.json index 4a8b7b5..7f1f995 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Ultrawidify", - "version": "3.1.0", + "version": "3.2.0", "applications": { "gecko": { "id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}"