@@ -32,6 +32,24 @@ | |||
<body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick"> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
<article> | |||
<h1>Bienvenue</h1> | |||
@@ -128,22 +146,6 @@ | |||
</footer> | |||
<script src="/static/david/js/instantpage-3.0.0.min.js" type="module" defer></script> | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
<script type="text/javascript"> | |||
/* This is a work in progress with Anthony https://ricaud.me */ | |||
@@ -164,11 +166,8 @@ | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const clone = themeSelectorTemplate.content.cloneNode(true) | |||
const form = document.body.insertAdjacentElement( | |||
'afterbegin', | |||
clone.firstElementChild | |||
) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
@@ -183,36 +182,39 @@ | |||
}) | |||
} | |||
const mediaQueryTest = '(prefers-color-scheme: dark)' | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let mediaRules = [] | |||
let ruleFound = false | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) continue | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== mediaQueryTest) continue | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(mediaQueryTest)) continue | |||
} | |||
// At that point, only a media cssRule matching our media query | |||
// test should remain, hence the renaming. | |||
const mediaRule = cssRule | |||
for (const innerCssRule of mediaRule.cssRules) { | |||
mediaRules.push(innerCssRule) | |||
ruleFound = true | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
mediaRules = [] | |||
} | |||
if (ruleFound) loadThemeForm('#theme-selector') | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
</body> |
@@ -2,6 +2,24 @@ | |||
{% block lang %}fr{% endblock %} | |||
{% block title %}Accueil{% endblock %} | |||
{% block content %} | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
<article> | |||
<h1>Bienvenue</h1> | |||
@@ -54,22 +72,6 @@ | |||
{% endblock content %} | |||
{% block extra_bottom %} | |||
<template id="theme-selector"> | |||
<form> | |||
<fieldset> | |||
<legend>Thème</legend> | |||
<label> | |||
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto | |||
</label> | |||
<label> | |||
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé | |||
</label> | |||
<label> | |||
<input type="radio" value="light" name="chosen-color-scheme"> Clair | |||
</label> | |||
</fieldset> | |||
</form> | |||
</template> | |||
<script type="text/javascript"> | |||
/* This is a work in progress with Anthony https://ricaud.me */ | |||
@@ -90,11 +92,8 @@ | |||
function loadThemeForm(templateName) { | |||
const themeSelectorTemplate = document.querySelector(templateName) | |||
const clone = themeSelectorTemplate.content.cloneNode(true) | |||
const form = document.body.insertAdjacentElement( | |||
'afterbegin', | |||
clone.firstElementChild | |||
) | |||
const form = themeSelectorTemplate.content.firstElementChild | |||
themeSelectorTemplate.replaceWith(form) | |||
form.addEventListener('change', (e) => { | |||
const chosenColorScheme = e.target.value | |||
@@ -109,36 +108,39 @@ | |||
}) | |||
} | |||
const mediaQueryTest = '(prefers-color-scheme: dark)' | |||
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' | |||
window.addEventListener('load', () => { | |||
let mediaRules = [] | |||
let ruleFound = false | |||
let hasDarkRules = false | |||
for (const styleSheet of Array.from(document.styleSheets)) { | |||
let mediaRules = [] | |||
for (const cssRule of styleSheet.cssRules) { | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) continue | |||
if (cssRule.type !== CSSRule.MEDIA_RULE) { | |||
continue | |||
} | |||
// WARNING: Safari does not have/supports `conditionText`. | |||
if (cssRule.conditionText) { | |||
if (cssRule.conditionText !== mediaQueryTest) continue | |||
if (cssRule.conditionText !== prefersColorSchemeDark) { | |||
continue | |||
} | |||
} else { | |||
if (cssRule.cssText.startsWith(mediaQueryTest)) continue | |||
} | |||
// At that point, only a media cssRule matching our media query | |||
// test should remain, hence the renaming. | |||
const mediaRule = cssRule | |||
for (const innerCssRule of mediaRule.cssRules) { | |||
mediaRules.push(innerCssRule) | |||
ruleFound = true | |||
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { | |||
continue | |||
} | |||
} | |||
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) | |||
} | |||
// WARNING: do not try to insert a Rule to a styleSheet you are | |||
// currently iterating on, otherwise the browser will be stuck | |||
// in a infinite loop… | |||
for (const mediaRule of mediaRules) { | |||
styleSheet.insertRule(mediaRule.cssText) | |||
hasDarkRules = true | |||
} | |||
mediaRules = [] | |||
} | |||
if (ruleFound) loadThemeForm('#theme-selector') | |||
if (hasDarkRules) { | |||
loadThemeForm('#theme-selector') | |||
} | |||
}) | |||
</script> | |||
{% endblock extra_bottom %} |