Skip to content

Commit

Permalink
Fix for light-dark theming bugs (#1359, #1462) (#1501)
Browse files Browse the repository at this point in the history
  • Loading branch information
daveoconnor authored Nov 27, 2024
1 parent f85c533 commit 765a5b7
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 119 deletions.
16 changes: 0 additions & 16 deletions static/js/DetectMode.js

This file was deleted.

64 changes: 64 additions & 0 deletions static/js/theme_handling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
this file contains any theme related code that can be removed from the header/base,
they should only be placed there when performance is needed.
*/

function changeTheme() {
const storedColorMode = localStorage.getItem("colorMode");
const browserColorMode = getBrowserColorMode(window);
let newColorMode = null;
if (storedColorMode) {
newColorMode = storedColorMode === "dark" ? "light" : "dark";
} else {
newColorMode = browserColorMode === "dark" ? "light" : "dark";
}
saveColorMode(newColorMode); // triggers theme change via storage event
}

function saveColorMode(colorMode) {
const oldColorMode = localStorage.getItem("colorMode");
const allowedModes = ['light', 'dark'];
if (!allowedModes.includes(colorMode)) {
if (console) {
console.warn(`Invalid color mode: ${colorMode}`);
}
return;
}
localStorage.setItem("colorMode", colorMode);
// this is dumb but only on pages that AREN'T the current page do normal
// localStorage events get picked up, so they need to be triggered manually here.
// To prevent errors from triggering twice actions should be idempotent.
window.dispatchEvent(
new StorageEvent('storage', {
key: 'colorMode',
oldValue: oldColorMode,
newValue: colorMode,
})
);
}

// here we handle the picking up of the change in color mode from the storage event
// which is then handled differently for iframes with very slight delay for the
// parent so there's minimal disparity between iframe and parent changing
window.addEventListener('storage', function (e) {
if (e.key === 'colorMode' && e.newValue) {
let isIframe = window.location.pathname === "srcdoc";
if (isIframe) {
setColorElements(e.newValue);
}
else {
setTimeout(() => setColorElements(e.newValue), 1);
}
document.getElementById("gecko-search-button").setAttribute(
'data-theme-mode',
e.newValue
);
}
});

document.addEventListener("alpine:init", function() {
document.getElementById("gecko-search-button").setAttribute(
'data-theme-mode',
localStorage.getItem("colorMode") || getBrowserColorMode(window)
);
});
3 changes: 1 addition & 2 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
<script src="https://unpkg.com/[email protected]" integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2" crossorigin="anonymous"></script>
<!-- TODO bring this local if we like it -->
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<!-- detect dark or light mode -->
<script src="{% static 'js/DetectMode.js' %}"></script>
<script src="{% static 'js/theme_handling.js' %}"></script>
<script src="{% static 'js/scroll-to-link.js' %}" defer></script>
<script src="{% static 'js/boost-gecko/main.062e4862.js' %}" defer></script>
{% block extra_head %}
Expand Down
141 changes: 40 additions & 101 deletions templates/includes/_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,6 @@
<div class="right-menubar" x-data="{ 'searchOpen': false }">
<span style="position: relative;" x-ref="desktopSearchArea">
<i id="gecko-search-button" data-current-boost-version="{{ current_version.stripped_boost_url_slug }}" data-theme-mode="light" data-font-family="sans-serif" class="fas fa-search icon-link"></i>
<script>
const geckoSearchButton = document.getElementById('gecko-search-button');
geckoSearchButton.setAttribute('data-theme-mode', localStorage.getItem('colorMode') === 'dark' ? 'dark' : 'light');
</script>
</span>
<span x-data="{ 'guideOpen': false }" style="position:relative;">
<i class="icon-link fas fa-question-circle" @click="guideOpen = !guideOpen"></i>
Expand All @@ -419,26 +415,46 @@
</div>
</div>
<script>
document.addEventListener("alpine:init", function() {
Alpine.data("searchToggleComponent", () => ({
searchButton: null,
desktopSearchArea: null,
mobileSearchArea: null,
init() {
this.searchButton = document.getElementById("gecko-search-button");
this.desktopSearchArea = this.$el.querySelector('[x-ref="desktopSearchArea"]');
this.mobileSearchArea = this.$el.querySelector('[x-ref="mobileSearchArea"]');
this.updateSearchButtonLocation();
},
updateSearchButtonLocation() {
if (window.innerWidth > 769) {
this.desktopSearchArea.appendChild(this.searchButton);
} else {
this.mobileSearchArea.appendChild(this.searchButton);
}
}
}))
});
// *********** manage theming *************
function setColorElements(colorMode) {
let iconchange = document.getElementById("light-dark")
if (!iconchange) {
return;
}
if (colorMode == "dark") {
iconchange.classList.remove('fa-moon');
iconchange.classList.add('fa-sun');
document.documentElement.classList.remove("light");
} else {
iconchange.classList.remove('fa-sun');
iconchange.classList.add('fa-moon');
document.documentElement.classList.remove("dark");
}
document.documentElement.classList.add(colorMode);
}

function getBrowserColorMode(win) {
// win is the appropriate window object
const prefersDark = win.matchMedia('(prefers-color-scheme: dark)').matches;
return prefersDark ? "dark" : "light";
}

function checkmedia() {
const relevantWindow = window.parent || window;
let browserColorMode = null;
const userColorMode = localStorage.getItem("colorMode");
if (!relevantWindow.matchMedia) {
browserColorMode = getBrowserColorMode(relevantWindow);
// transparently removed on next load if matches browser setting
if (userColorMode === browserColorMode) {
localStorage.removeItem("colorMode");
}
}
setColorElements(userColorMode || browserColorMode || "light");
}

checkmedia();

// ************ Mobile Navigation **************
let containingElement = document.getElementById("pageselector");
document.body.addEventListener('click', function( event ){
Expand Down Expand Up @@ -498,83 +514,6 @@
}
}, 2000);
}
// *********** manage theming *************
function makeDark() {
localStorage.setItem("colorMode", "dark");
// interval is used here to cause a tiny delay to allow iframe dark mode to
// be set closer to when the parent dark mode is set
setTimeout(() => {
document.documentElement.classList.add('dark');
var iconchange = document.getElementById("light-dark")
iconchange.classList.remove('fa-moon');
iconchange.classList.add('fa-sun');
}, 0)
}
function makeLight() {
localStorage.setItem("colorMode", "light");
// timeout is used here to cause a tiny delay to allow iframe dark mode to
// be set closer to when the parent dark mode is set
setTimeout(() => {
document.documentElement.classList.remove('dark');
var iconchange = document.getElementById("light-dark")
iconchange.classList.remove('fa-sun');
iconchange.classList.add('fa-moon');
}, 0);
}
function changeTheme() {
if (document.documentElement.classList.contains("dark")) {
makeLight();
return;
}
makeDark();
}
function setTheme(theme) {
if (theme == "dark") {
makeDark();
return;
} else if (theme == "light") {
makeLight();
return;
} else {
makeLight();
}
}
function checkmedia() {
const relevantWindow = window.parent || window;
if (relevantWindow.matchMedia) {
// Check if the dark-mode Media-Query matches
if(relevantWindow.matchMedia('(prefers-color-scheme: dark)').matches){
if(localStorage.getItem("colorMode") === null || localStorage.getItem("colorMode") == "dark" ) {
makeDark();
localStorage.removeItem("colorMode")
} else {
makeLight();
};
} else if (relevantWindow.matchMedia('(prefers-color-scheme: light)').matches) {
if(localStorage.getItem("colorMode") === null || localStorage.getItem("colorMode") == "light" ) {
makeLight();
localStorage.removeItem("colorMode")
} else {
makeDark();
};
} else {
setTheme(localStorage.getItem("colorMode"));
}
}
}
if (window.parent) {
window.addEventListener('storage', function(e) {
if (e.key === 'colorMode') {
if (localStorage.getItem("colorMode") === "light"){
document.documentElement.classList.remove('dark');
}
else {
document.documentElement.classList.add('dark');
}
}
});
}
checkmedia();
function removejscssfile(filename, filetype){
var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none" //determine element type to create nodelist from
var targetattr=(filetype=="js")? "src" : (filetype=="css")? "href" : "none" //determine corresponding attribute to test for
Expand Down

0 comments on commit 765a5b7

Please sign in to comment.