-
-
Save dalf/0f983799c20b75b441f8c089372f0cfe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html class="no-js theme-auto"> | |
<head> | |
<!-- | |
* theme-auto by default | |
* theme-dark / theme-light according to the preferences (set in the Jinja2 templates) | |
so it follows the user preference even if javascript is disabled. | |
--> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=1"> | |
<title>Theme</title> | |
<style> | |
html { | |
--brand-basic: #dee8f3; | |
--brand-accent: #31456a; | |
--theme-variant: "light"; | |
} | |
html.theme-dark { | |
--brand-basic: #31456a; | |
--brand-accent: #dee8f3; | |
--theme-variant: "dark"; | |
} | |
@media (prefers-color-scheme: dark) { | |
html.theme-auto { | |
/* I don't know how to avoid a copy / paste of the values | |
between html.theme-auto and html.theme-dark | |
:is is supported only on recent browsers | |
(and I'm not sure it supports media queries) | |
if there is no solution, we can include the dark theme values twice from a .less file | |
*/ | |
--brand-basic: #31456a; | |
--brand-accent: #dee8f3; | |
--theme-variant: "dark"; | |
} | |
} | |
html.no-js #toggleDarkMode { | |
/* hide the button when javascript is disabled */ | |
display: none; | |
} | |
body { | |
margin: 0 | |
} | |
.container { | |
background-color: var(--brand-basic); | |
/* start of out of topic statmements */ | |
height: 100vh; | |
display: flex; | |
justify-content: right; | |
align-items: flex-start; | |
transition: color 0.3s, background-color 0.3s; | |
} | |
.btn { | |
background-color: var(--brand-basic); | |
color: var(--brand-accent); | |
border: 3px solid var(--brand-accent); | |
/* start of out of topic statmements */ | |
height: 48px; | |
width: 200px; | |
font-family: sans-serif; | |
font-size: 16px; | |
border-radius: 6px; | |
letter-spacing: 3px; | |
font-weight: bold; | |
text-decoration: none; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
transition: color 0.3s, background-color 0.3s; | |
cursor: pointer; | |
margin: 1rem; | |
} | |
.btn:focus { | |
outline: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<a class="btn" href="theme.html">RELOAD</a> | |
<button id="toggleDarkMode" type="button" class="btn" onclick="toggleDarkMode()"></button> | |
</div> | |
<script> | |
/* ------------------------------------------------------ */ | |
// update of https://github.com/searxng/searxng/blob/a582cf3d8231f5ed8a881aa87576dfc0600e1c07/searx/static/themes/simple/src/js/main/00_searx_toolkit.js#L73-L110 | |
const searx = { | |
_timers: new Map(), | |
_unloading: false, | |
http: function (method, url, data=null) { | |
var req = new XMLHttpRequest(), | |
resolve = function () { }, | |
reject = function () { }, | |
promise = { | |
then: function (callback) { resolve = callback; return promise; }, | |
catch: function (callback) { reject = callback; return promise; } | |
}; | |
try { | |
req.open(method, url, true); | |
// On load | |
req.onload = function () { | |
if (req.status == 200) { | |
resolve(req.response, req.responseType); | |
} else { | |
reject(Error(req.statusText)); | |
} | |
}; | |
// Handle network errors | |
req.onerror = function () { | |
reject(Error("Network Error")); | |
}; | |
req.onabort = function () { | |
reject(Error("Transaction is aborted")); | |
}; | |
// | |
if (data) { | |
// from https://developer.mozilla.org/en-US/docs/Learn/Forms/Sending_forms_through_JavaScript | |
let urlEncodedData = "", | |
urlEncodedDataPairs = [], | |
name; | |
// Turn the data object into an array of URL-encoded key/value pairs. | |
for( name in data ) { | |
urlEncodedDataPairs.push( encodeURIComponent( name ) + '=' + encodeURIComponent( data[name] ) ); | |
} | |
// Combine the pairs into a single string and replace all %-encoded spaces to | |
// the '+' character; matches the behavior of browser form submissions. | |
urlEncodedData = urlEncodedDataPairs.join( '&' ).replace( /%20/g, '+' ); | |
req.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ); | |
// Make the request | |
req.send(urlEncodedData); | |
} else { | |
// Make the request | |
req.send(); | |
} | |
} catch (ex) { | |
reject(ex); | |
} | |
return promise; | |
}, | |
delay: function(name, delay, f) { | |
if (searx._timers.has(name)) { | |
clearTimeout(searx._timers.get(name)[0]); | |
} | |
function call_f() { | |
searx._timers.delete(name); | |
f(); | |
} | |
h = setTimeout(call_f, delay); | |
searx._timers.set(name, [h, f]); | |
}, | |
beforeunload: function() { | |
searx._unloading = true; | |
for(v in searx._timers.values()) { | |
v[1](); | |
} | |
} | |
}; | |
/* ------------------------------------------------------ */ | |
function getThemeVariant() { | |
const themeVariant = getComputedStyle(document.documentElement).getPropertyValue('--theme-variant'); | |
// Chrom* browsers require trim() | |
return themeVariant.trim().slice(1, -1); | |
} | |
function updateThemeVariantButton() { | |
const buttonDarkMode = document.getElementById('toggleDarkMode'); | |
if (getThemeVariant() == "dark") { | |
buttonDarkMode.innerHTML = '☀️ LIGHT MODE'; | |
} else { | |
buttonDarkMode.innerHTML = '🌑 DARK MODE'; | |
} | |
} | |
function saveThemeVariant(themeVariant) { | |
// send a POST request to /preferences so on the next HTTP request, <html class=""> will get the right CSS class (theme-dark, theme-light) | |
// theme-variant is similar to the oscar-style preference. | |
searx.delay('theme-variant', 300, function() { | |
searx.http('post', 'preferences', data = { | |
'theme-variant': themeVariant, | |
// new parameter in webapp.py to avoid HTTP redirect | |
// see https://github.com/searxng/searxng/blob/a582cf3d8231f5ed8a881aa87576dfc0600e1c07/searx/webapp.py#L911 | |
// alternative: an HTTP header | |
'$redirect': 0, | |
}); | |
}); | |
} | |
function toggleDarkMode() { | |
const htmlElement = document.getElementsByTagName('html')[0]; | |
const themeVariant = getThemeVariant(); | |
["theme-light", "theme-dark", "theme-auto"].forEach(v => htmlElement.classList.remove(v)); | |
if (themeVariant == "dark") { | |
htmlElement.classList.add("theme-light"); | |
} else { | |
htmlElement.classList.add("theme-dark"); | |
} | |
updateThemeVariantButton(); | |
saveThemeVariant(themeVariant); | |
} | |
document.addEventListener("DOMContentLoaded", function () { | |
// https://github.com/searxng/searxng/blob/c23aa5760cb42003c1372ccdef1611695504eb9e/searx/static/themes/simple/src/js/head/00_init.js#L39-L40 | |
// set the classes instead of updating them. | |
const htmlElement = document.getElementsByTagName('html')[0]; | |
const touch = (("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch) || false; | |
htmlElement.classList.replace("no-js", "js"); | |
if (touch) { | |
htmlElement.classList.add("touch"); | |
} | |
// new | |
updateThemeVariantButton(); | |
}); | |
// | |
window.addEventListener("beforeunload", searx.beforeunload); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment