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>
|