vivaldi-fox icon indicating copy to clipboard operation
vivaldi-fox copied to clipboard

[REQUEST] Listen for theme-color changes.

Open easyaspi314 opened this issue 8 years ago • 4 comments

Demo of issue

What should happen:

When clicking the button, the titlebar color would change to the text color of the button.

What happens:

Nothing at all.

Note that by default, the page has this in its head:

<meta id="themeColour" name="theme-color" content="">

My idea is to use the MutationObserver API. It is pretty lightweight. I'm no JavaScript guru (I'm a Java geek), but my guess would to be this pseudocode:

var observer;
////// ^global^ 
var metaThemeColor = // meta tag
if (metaThemeColor) { // if this is not found, this should be considered false am I right?
  setUpMetaObserver(metaThemeColor);
} else {
  // if we don't do this, then it won't work, and it is also good practice.
  if (observer instanceof MutationObserver) 
    observer.disconnect();

  // create an observer instance
  observer = new MutationObserver(function(mutations) {
    mutations.addedNodes.forEach(function(addedNode) {
      // First check if it is an element and if it is a meta tag
      if (addedNode.nodeType == 1 && addedNode.nodeName.toUpperCase() == "META")
        if (addedNode.getAttribute("name") == "theme-color") {
          updateColor(addedNode);
          setUpMetaObserver(addedNode);
        }
    });    
  });
  // Listening for added elements to the head.
  var config = { childList: true };
 
  // pass in the target node, as well as the observer options
  observer.observe(document.head, config);
}
// ...
function setUpMetaObserver(/* Node */ metaThemeColor) {
  // if we don't do this, then it won't work, and it is also good practice.
  if (observer instanceof MutationObserver) 
    observer.disconnect();

  // create an observer instance
  observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.attributeName == "content") // Maybe a triple equals?
        updateColor(metaThemeColor);
    });    
  });
 
  // since we have the theme-color in our grasp, we just need to listen for the attributes to change.
  var config = { attributes: true };
 
  // pass in the target node, as well as the observer options
  observer.observe(metaThemeColor, config);
}

Do you get what I am saying?

easyaspi314 avatar Jan 06 '17 15:01 easyaspi314

Thanks for the code snippet and the demo! Happy new year as well :)

I'm aware of the issue, but I wonder how much it would slow down the browser to have the MutationObserver. If it does slow down the browser significantly, can we have a pref?

Anyway, I won't have time to work on this soon (not next week at least), but feel free submit a PR in the meantime, I'll be glad to accept any working prototype.

All the magic happens here: https://github.com/nt1m/vivaldi-fox/blob/master/data/contentscript.js

Basically, self.port.emit("theme-colour-change", color) is the equivalent of updateColor(color) in your snippet. As for getting the meta tag, let el = (...) shows you how to do it, I would probably change (...) to be a function to avoid duplication.

Hopefully that helps, feel free to ask questions if not :)

nt1m avatar Jan 06 '17 21:01 nt1m

Thanks for the relatively fast reply! :)

By the way, I was the one who commented on the Bugzilla.

MutationObserver isn't very taxing as long as you do it right (forEach is worse than a plain for loop)

And I was also considering disconnecting when we switch tabs.

easyaspi314 avatar Jan 06 '17 22:01 easyaspi314

Disconnecting when switching tabs is a good idea!

nt1m avatar Jan 06 '17 23:01 nt1m

From @sorin-davidoi:

Chrome for Android listens for mutations of the theme-color meta tag and applies the color to the browser chrome dynamically. An example of a page exhibiting this is mdBook - change the theme from the dropdown and theme-color gets updated as well (implementation and screenshots here). Would be nice if VivaldiFox could support this.

nt1m avatar Jan 17 '18 07:01 nt1m