Detecting theme color; current results return transparent

Hi,
I’m trying to change an addons appearance depending on the current theme a user might have. A user could have a light theme or a dark theme installed and I want to change some of the styling and icons depending on that. The default icons like downloads, bookmarks, open new tab & open menu do this automatically.

I first checked to see if the firefox sdk had a feature to detect if the theme is labeled as dark or light (like you can already do with a theme when submitting them) but it does not seem so. It has been talked about in this bugzilla report but it seems nothing was created.

With no solution I decide to create my own, I went ahead and created a JS function to calculate the YIQ to determine if the content over the background color should be lighter or darker (ex. background is black, display white text/icon/etc…).

I figured the above would be harder then finding the browsers/panel background color, however, I was wrong… I tried in data/js/globa.js (the JavaScript for the panel) to calculate the panel background color BUT it returns transparent…
data/js/global.js

console.log(window.getComputedStyle(document.body, null).backgroundColor); // Returns transparent

Assuming it was set globally I tried the the browser window (XUL document I believe?) in lib/main.js once again it returns transparent.

lib/main.js

var browserDocument = require("sdk/window/utils").getMostRecentBrowserWindow(),
    browserStyles   = browserDocument.content.getComputedStyle(browserDocument.content.document.body, null).backgroundColor,
    browserStyles2  = browserDocument.content.getDefaultComputedStyle(browserDocument.content.document.body, null).backgroundColor;
console.log(browserStyles); // Returns transparent
console.log(browserStyles2); // Returns transparent

So my questions are…

  1. Does the firefox sdk have a build in easy way to find the background color? (I searched the docs and can’t find it)
  2. If no, can you find the browser windows / system theme background color with the method above?

Since someone will most definitely ask, “why not set the panel background color manually”, I do not wish to override a users theme and break their color scheme. I would like tighter integration if possible.

Thanks

body is not the top-level element. use documentElement
What do you mean by YIQ? Just check if background color lighter than text color:

    let top_window = require("sdk/window/utils").getMostRecentBrowserWindow();
    let { getComputedStyle } = top_window;
    // color from getComputedStyle is in CSS format, so we need to parse it
    // https://github.com/deanm/css-color-parser-js
    let { parseCSSColor } = require('./csscolorparser.js');
    // but actually it is always like "rgb(r, g, b)" so you may simply parse it by yourself

    let { color, backgroundColor } = getComputedStyle(top_window.document.documentElement);
    let color_array = parseCSSColor(color).slice(0, 3);
    // parseCSSColor returns [r, g, b, a] array
    // so, we use slice() to take first 3 elements
    let backgroundColor_array = parseCSSColor(backgroundColor).slice(0, 3);
    let color_max = Math.max.apply(null, color_array);
    let backgroundColor_max = Math.max.apply(null, backgroundColor_array);
    let is_dark_theme = color_max > backgroundColor_max;
    console.log({
        color,
        backgroundColor,
        color_array,
        backgroundColor_array,
        color_max,
        backgroundColor_max,
        is_dark_theme
    });

Results:

  • for dark theme:
    {
        "color": "rgb(255, 255, 255)",
        "backgroundColor": "rgb(0, 0, 0)",
        "color_array": [
            255,
            255,
            255
        ],
        "backgroundColor_array": [
            0,
            0,
            0
        ],
        "color_max": 255,
        "backgroundColor_max": 0,
        "is_dark_theme": true
    }
    
  • for light theme:
    {
        "color": "rgb(76, 76, 76)",
        "backgroundColor": "rgb(242, 241, 240)",
        "color_array": [
            76,
            76,
            76
        ],
        "backgroundColor_array": [
            242,
            241,
            240
        ],
        "color_max": 76,
        "backgroundColor_max": 242,
        "is_dark_theme": false
    }
    

But, please note the following:

  • background-color of top-level window and background-color of panel with icons may be different
  • There may be a background-image of different color

So, try to use icons which are at least recognizable on any background and\or add an option to use icons: 1) autodetect by theme, 2) dark, 3) light.

@m_khvoinitsky Thank you very much, I was totally over complicating it.

Your approached worked like a charm!