Autoscroll Active Tab into view in Vertical Tabbar on mouseover
-
Here is a slight change to the 2nd mod from above by potmeklecbohdan...
For those who preferred on demand activation only, instead of automatic activation when mouse away from tabbar -- simply replace
tabBar.addEventListener('mouseleave', scrollToTab);
with this 2 lines:trashButton = document.querySelector('#tabs-container > div.sync-and-trash-container'); trashButton.addEventListener('click', scrollToTab);
With this change you can now click on the empty area around trashcan (or trashcan button) to scroll active tab into view. You can also replace
'click'
with'dblclick'
for double-click activation instead.Again, all thanks to potmeklecbohdan for this handy mod!
And I hope Vivaldi team will read this thread & implant this feature into future Vivaldi! -
@dude99 To make it even better:
document.querySelector('#tabs-container > div.sync-and-trash-container').addEventListener('click', scrollToTab);
and replace
setTimeout(function wait() { let activeTab = document.querySelector('#tabs-container .tab-strip .tab.active'); if (activeTab)
with
setTimeout(function wait() { let activeTab = document.querySelector('#tabs-container .tab-strip .tab.active'); let trashButton = document.querySelector('#tabs-container > div.sync-and-trash-container'); if (activeTab && trashButton)
-
@potmeklecbohdan Oh, I don't know much about JavaScript; I just learn from your code & change it. LOL
Thanks for the improvement.
-
@potmeklecbohdan this is a useful script but for my version (2.11.1811.41) I could skip the timer part and it still worked. Did you experience any race conditions when you created this and you had to add the timer?
PS: this script is not fool-proof: if you watch a video full screen, once you exit FS mode, Vivaldi scrolls to the top. Obviously this cannot be caught by the script without further tweaking.
-
@adamstyl Unfortunately this is cause by Vivaldi's default FS behavior, as it disabled the tabbar during FS mode. Thus when you exit FS it will reload the tabbar & thus it end up on top position.
I hate this behavior too, that's why I rarely use FS mode. Maybe you can add a feature request to change this behavior.
-
@dude99 You should have told me earlier! Now I'm not sure if I'll fix it (as I got even lazier than I used to be), but I don't think it's difficult.
-
@potmeklecbohdan I learn about it by studying the common.css a while back, my guess is you can do it by overwrite FS mode css so that FS mode doesn't affect the tabbar. It's a very messy method, I give up half way because it involved too many changes...
-
@potmeklecbohdan said:
but I don't think it's difficult.
Whoops! I realised it would be easier to write from scratch, as I got lost in recursive calls and callbacks…
Wait, wait… you say that it works after FS and de-FS, but the first time the tab bar is shown it is scrolled to top? Because if yes, there could be a simpler solution (just one more event listener).
-
@potmeklecbohdan Ok. I noticed 2 things:
-
All js mod seems to stop working after enter
& exitFS. I have to close & reopen the window to restore their functions, is this a "bug" or "feature"??? -
The common.css have changed since the last time I studied it, in line 6090 you will find the CSS FS mode for tabbar, it seems to simplified & should be easy to fix this time around.
EDIT:
This css mod will overwrite FS's tabbar (on left) & restore it's basic functionalities in FS:#browser.fullscreen #tabs-container { display: flex; position: fixed; top: 0; bottom: 0; left:0; z-index: 9; flex-direction: column; background: var(--colorBg); } #browser.fullscreen #tabs-container.overflow .tab-strip { overflow-x: hidden; overflow-y: auto; }
But unfortunately the result is very disappointing, because the first problem I talk about seems to begin when entering FS, not after exiting FS . All js mod seems to stop working during FS mode & never restore even exited FS.
So, that's all I can do for now, good luck on trying to fix this with js mod!
-
-
@dude99 The above post CSS mod is just for proof of concept, it's not really practical for FS browsing... For those interested in actually usable automate FS LEFT tabbar, use this css mod instead:
#browser.fullscreen #tabs-container{ display: flex; position: fixed; top: 0; bottom: 0; left: 0; z-index: 9; flex-direction: column; background: var(--colorBg); transition: opacity .2s ease-out !important; } #browser.fullscreen #tabs-container:not(:focus-within):not(:hover) { transform:translateX(-100%); opacity: 0; transition: transform 0s .4s, opacity .35s ease-out 0s !important; } #browser.fullscreen #tabs-container .fullheight {right:-7px;} #browser.fullscreen #tabs-container .tab-strip { overflow-x: hidden; overflow-y: auto; }
Caveat: For some reason FS mode have a 7px deadzone all around the screen edge, so we have to move the pointer inward a bit after touching the LEFT screen edge to reveal the tabbar!
-
@dude99 said:
is this a "bug" or "feature"???
I think it's a buggy creature
+
→
Try this, it worked (once). Don't forget to do your edits to it.
(function () { function doMod() { let isModEnabled = false; let tabBar = document.querySelector('#tabs-container'); function scrollToTab(tabInfo) { if (isModEnabled) { let tab; if (tabInfo && tabInfo.tabId) tab = document.querySelector('#tab-' + tabInfo.tabId); else tab = document.querySelector('#tabs-container .tab-strip .tab.active'); if (tab) tab.scrollIntoViewIfNeeded(); } } function checkIsModEnabled() { vivaldi.prefs.get('vivaldi.tabs.visible', function(tabsVisible){ if (tabsVisible) vivaldi.prefs.get('vivaldi.tabs.bar.position', function(barPosition){ if (barPosition === 'left' || barPosition === 'right' || barPosition === 1 || barPosition === 2) isModEnabled = true; else isModEnabled = false; }); else isModEnabled = false; }); } checkIsModEnabled(); vivaldi.prefs.onChanged.addListener(function(pref){ if (pref.path === 'vivaldi.tabs.visible' || pref.path === 'vivaldi.tabs.bar.position') checkIsModEnabled(); }); vivaldi.windowPrivate.onFullscreen.addListener((fsId, fs) => { vivaldi.windowPrivate.getCurrentId(currId => { if (currId == fsId) { tabBar = document.querySelector('#tabs-container'); if (tabBar && document.body.contains(tabBar)) tabBar.addEventListener('mouseleave', scrollToTab); scrollToTab(); } }); }); chrome.tabs.onActivated.addListener(scrollToTab); if (tabBar && document.body.contains(tabBar)) tabBar.addEventListener('mouseleave', scrollToTab); scrollToTab(); } setTimeout(function wait() { let tabs = document.querySelector('#tabs-container'); if (tabs) doMod(); else setTimeout(wait, 300); }, 300); })();
-
@potmeklecbohdan Well done, it works perfectly!
-
@potmeklecbohdan Hi, can u please update the script to include
#tabs-subcontainer
? -
@dude99 I can't test it now
so if it doesn't work you'll probably have to wait til I get my lappy
back home
(function () { function doMod() { let isModEnabled = false; let tabBars = document.querySelectorAll('#tabs-container, #tabs-subcontainer'); function scrollToTab(tabInfo) { if (isModEnabled) { let tabs; if (tabInfo && tabInfo.tabId) tabs = document.querySelectorAll('#tab-' + tabInfo.tabId); else tabs = document.querySelectorAll('.tab-strip .tab.active'); tabs.forEach(tab => tab.scrollIntoViewIfNeeded()); } } function checkIsModEnabled() { vivaldi.prefs.get('vivaldi.tabs.visible', function(tabsVisible){ if (tabsVisible) vivaldi.prefs.get('vivaldi.tabs.bar.position', function(barPosition){ if (barPosition === 'left' || barPosition === 'right' || barPosition === 1 || barPosition === 2) isModEnabled = true; else isModEnabled = false; }); else isModEnabled = false; }); } checkIsModEnabled(); vivaldi.prefs.onChanged.addListener(function(pref){ if (pref.path === 'vivaldi.tabs.visible' || pref.path === 'vivaldi.tabs.bar.position') checkIsModEnabled(); }); vivaldi.windowPrivate.onFullscreen.addListener((fsId, fs) => { vivaldi.windowPrivate.getCurrentId(currId => { if (currId == fsId) { tabBars = document.querySelectorAll('#tabs-container, #tabs-subcontainer'); tabBars.forEach(tb => { if (tb && document.body.contains(tb)) tb.addEventListener('mouseleave', scrollToTab); }); scrollToTab(); } }); }); chrome.tabs.onActivated.addListener(scrollToTab); tabBars.forEach(tb => { if (tb && document.body.contains(tb)) tb.addEventListener('mouseleave', scrollToTab); }); scrollToTab(); } setTimeout(function wait() { let tabs = document.querySelector('#tabs-tabbar-container'); if (tabs) doMod(); else setTimeout(wait, 300); }, 300); })();
-
@potmeklecbohdan Thank you! It works perfectly!! :smiling_face_with_open_mouth_closed_eyes:
I have tried edit it myself with
&&
,||
, & many combinations, but all failed miserably. never thought the correct answer is,
-
Oh awesome, I have been hoping for Vivaldi to implement this for years and just now stumbled across this post!
Personally I found the autoscroll when (accidentally) mousing out of the tab bar annoying, I just want it to autoscroll when I use keyboard shortcuts to switch tabs, so I simply commented out the two places where the mouseleave event listeners are added:
// tabBars.forEach(tb => { // if (tb && document.body.contains(tb)) // tb.addEventListener('mouseleave', scrollToTab); // });
Now it only autoscrolls when I use the Next/Previous Tab shortcuts or Ctrl-Tab, which is exactly what I want. Perhaps someone else will find this helpful!
-
@ntoivola Welcome! Thanks for voting for my request. Also, a few post before have a fork to trigger the autoscroll via Trashcan container: https://forum.vivaldi.net/post/317199
-
@potmeklecbohdan Hi again. Is it possible to add another trigger to scroll to active tab 1 time on browser's first load?
Many thanks in advance.
-
@dude99 I guess you can add something like this at the end of
doMod
chrome.tabs.query({windowId:vivaldiWindowId, active: true}, tabInfo => { if (tabInfo.length > 0) scrollToTab(tabInfo[0].id); });
-
@potmeklecbohdan like this, correct?