summaryrefslogtreecommitdiffstats
path: root/layout/base/tests/chrome/test_color_scheme_browser.xhtml
blob: 15a6ac2282e539624879a98f0532e7eefdd241f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <head>
    <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
    <script src="chrome://mochikit/content/chrome-harness.js"></script>
    <style>
      #light { color-scheme: light }
      #dark { color-scheme: dark }
    </style>
  </head>
  <body>
    <div id="dynamic-test">
      <xul:browser type="content" remote="true" nodefaultsrc="true" class="remote" />
      <xul:browser type="content" src="about:blank" class="nonremote" />
    </div>
    <div id="light">
      <xul:browser type="content" remote="true" nodefaultsrc="true" class="remote" />
      <xul:browser type="content" src="about:blank" class="nonremote" />
    </div>
    <div id="dark">
      <xul:browser type="content" remote="true" nodefaultsrc="true" class="remote" />
      <xul:browser type="content" src="about:blank" class="nonremote" />
    </div>
    <script><![CDATA[
      // FIXME: This shouldn't be needed if remote browsers would block the load event.
      add_task(async function ensureBrowsersLoaded() {
        const triggeringPrincipal = document.nodePrincipal;
        for (let b of document.querySelectorAll("browser[remote=true]")) {
          let loaded = new Promise(resolve => {
            b.addProgressListener({
              onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
                info(`Got state change for ${b.parentNode.id}: ${aStateFlags}, ${aStatus}`);
                if (
                  aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW &&
                  aStateFlags & Ci.nsIWebProgressListener.STATE_STOP
                ) {
                  resolve();
                  b.removeProgressListener(this);
                }
              },
              QueryInterface: ChromeUtils.generateQI([
                "nsIWebProgressListener",
                "nsISupportsWeakReference",
              ]),
            });
          });
          b.loadURI(null /*blank*/, { triggeringPrincipal });
          await loaded;
        }
      });
      async function getBrowserColorScheme(browser) {
        return SpecialPowers.spawn(browser, [], () => {
          return content.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
        });
      }
      async function tick() {
        return new Promise(resolve => {
          requestAnimationFrame(() => requestAnimationFrame(resolve));
        });
      }
      async function testElement(id, expectedIfTop, expectedIfNonTop) {
        let element = document.getElementById(id);
        for (let browser of element.querySelectorAll("browser")) {
          let scheme = await getBrowserColorScheme(browser);
          let expected = browser.browsingContext.top == browser.browsingContext ? expectedIfTop : expectedIfNonTop;
          is(scheme, expected, `${id}: ${browser.className} should be ${expected}`);
        }
      }
      add_task(async function test_browser_color_scheme() {
        let current = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
        for (let id of ["dynamic-test", "light", "dark"]) {
          let expected = id == "dynamic-test" ? current : id;
          await testElement(id, expected, expected);
        }
      });

      add_task(async function test_browser_color_scheme_dynamic_style() {
        let current = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
        let dynamicTest = document.getElementById("dynamic-test");
        for (let value of ["light", "dark"]) {
          await tick();
          dynamicTest.style.colorScheme = value;
          await testElement("dynamic-test", value, value);
        }
        dynamicTest.style.colorScheme = "";
        await tick();
      });

      add_task(async function test_browser_color_scheme_dynamic_system() {
        const ACTIVE_THEME_ID = Services.prefs.getCharPref("extensions.activeThemeID");
        const DEFAULT_THEME_ID = "default-theme@mozilla.org";
        if (ACTIVE_THEME_ID != DEFAULT_THEME_ID) {
          info(`skipping test_browser_color_scheme_dynamic_system because the active theme is ${ACTIVE_THEME_ID} instead of ${DEFAULT_THEME_ID}`);
          return;
        }
        for (let dark of [true, false]) {
          await SpecialPowers.pushPrefEnv({
            set: [
              ["layout.css.prefers-color-scheme.content-override", 2],
              ["ui.systemUsesDarkTheme", dark ? 1 : 0],
            ]
          });
          await tick();
          let expected = dark ? "dark" : "light";
          await testElement("dynamic-test", expected, expected);
          await SpecialPowers.popPrefEnv();
        }
      });
    ]]></script>
  </body>
</html>