Tab Loading State Styling?
-
I'm looking for a way to style the active tab when the page is loading. As far as I can tell, there is no ancestor with any attribute to use for styles specific to when the current page is loading. Is there any way -- i.e. event hook -- to add/remove a class?
-
in js? you could use chrome.tabs.onUpdate
-
That's a great suggestion. Thanks. I'll try that.
-
There used to be a dedicated class for the loading state, it was removed a long time ago. Sad really. They should bring it back and even if it's only for modding purposes. The extra class doesn't hurt anyone.
edit: made a request to bring the class back: https://forum.vivaldi.net/topic/31549/loading-class-for-tabs
-
Turns out to be fairly trivial to add/remove the loading class on the tabs...
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => { const isLoading = changeInfo.status === 'loading', isComplete = changeInfo.status === 'complete', uiTab = document.querySelector(`#tab-${tabId}`); if(isLoading) uiTab.classList.add('loading'); if(isComplete) uiTab.classList.remove('loading'); });
-
Unfortunately that solution leaves a bit to be desired. The event doesn't appear to fire until a the initial network response is returned. As a result there is a lag between the UI update to the stop/reload button and the address bar progress and the "loading" class being added. If a url is slow to return an initial response, it doesn't work well. I tried to see if chrome.webRequest.onBeforeRequest might work somehow, but it doesn't seem to fire in the custom js context? Surprising. Wondering if there is some other event to hook into??
-
@dndrsn Not all chrome apis work in the UI. Chrome webrequest is sadly one of them. There is no list of working and non working apis, it's trial and error.
-
AHA!
I have devised a way of changing the tab via css when it reaches different "load states". I'll leave it up to someone else to make something nice out of this, but the pieces are all there now.
- As webRequest isn't accessible through the browser, we use an extension to do that work for us.
- We use message passing to talk to the browser
- We apply a state attribute to the tabs as needed
- We use CSS to style based on the presence of the attribute
Play around with the code HERE
In my example
- Red - Request sent, no response yet (Contacting server)
- Cyan - The page is starting to load (Downloading data)
- Green - Primary loading complete
-
@lonm Well that's nice, especially for people who really can't live without it. But it's also silly, we used to be able to do this with a few lines of css, now it's an extension plus a js mod… Vivaldi just needs to bring back the class
-
@luetage Over-engineer everything, that's the one true path to enlightenment.
-
That's pretty slick. I thought about doing something similar. I ended up putting a mutation observer on the reload button to add an "active page loading" class in the browser dom. Ugly hack, but it works as I want it to.
-
@dndrsn Looks good.
-
@lonm You used the wrong smiley there
But I kinda agree, if Vivaldi was perfect we would have nothing to play around with… -
@dndrsn How did you do that?
-
@goldnoway Currently I have a mutation listener on the reload button that adds/removes a class...
function initReloadObserver() { const browserDiv = document.getElementById('browser'), reloadButton = document.querySelector('.button-toolbar.reload'); if(!browserDiv || !reloadButton) { setTimeout(initReloadObserver, 100); return; } const observer = new MutationObserver(mutationsList => { for(let mutation of mutationsList) { if (mutation.type === 'attributes' && mutation.attributeName === 'class') { if(mutation.target.classList.contains('loading')) { browserDiv.classList.add('active-tab-loading'); } else { browserDiv.classList.remove('active-tab-loading'); } } } }); observer.observe(reloadButton, { attributes: true }); } setTimeout(initReloadObserver, 0);
But I plan to move to the "proxy webRequest via an extension" method @lonm posted above (or something similar). I think it is a better approach because it gives much more control and flexibility to where/when/how to add classes and attribute hooks for styling.
As far as the styling goes, this is what I have currently...
@keyframes loading-animation { 0% { transform: rotate(0deg) } 100% { transform: rotate(360deg) } } #browser.active-tab-loading .tab.active .favicon { background-image: url(./images/sync-alt-solid-gray.svg) !important; background-position: center center; background-size: 78%; animation: loading-animation 1.25s infinite linear; } #browser.active-tab-loading .tab.active .favicon svg { display: none; }
-
@dndrsn Nice, I'll try it. Can you share the svg used?
-
@hadden89 it’s a FontAwesome svg — https://fontawesome.com/icons/sync-alt?style=solid
Edit the color in the svg to taste — I think I did #666666. There are a few additional FA options that work well.
-