aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpetko <petko@524c5546-5005-0410-9a3e-e25e191bd360>2024-02-14 07:56:53 +0000
committerpetko <petko@524c5546-5005-0410-9a3e-e25e191bd360>2024-02-14 07:56:53 +0000
commit77ce52c4e9032fdc90dda58ac0c59521dca4db97 (patch)
treedc5646107262e53269c8ef4b3c8e38c9a0f0e662
parent0114f5240a9d4cf75e84ac23e955571a83a1fc98 (diff)
downloadpmwiki.svn-77ce52c4e9032fdc90dda58ac0c59521dca4db97.tar.bz2
Dark theme toggle: refactor into a separate script pub/pmwiki-darktoggle.js, inject at the top of $HTMLHeaderFmt.
git-svn-id: svn://pmwiki.org/pmwiki/trunk@4643 524c5546-5005-0410-9a3e-e25e191bd360
-rw-r--r--pub/pmwiki-darktoggle.js143
-rw-r--r--pub/pmwiki-utils.js112
-rw-r--r--pub/skins/pmwiki-responsive/skin.css2
-rw-r--r--scripts/utils.php20
4 files changed, 159 insertions, 118 deletions
diff --git a/pub/pmwiki-darktoggle.js b/pub/pmwiki-darktoggle.js
new file mode 100644
index 00000000..a9991cb7
--- /dev/null
+++ b/pub/pmwiki-darktoggle.js
@@ -0,0 +1,143 @@
+/*
+ Dark mode toggle for PmWiki
+ (c) 2024 Petko Yotov www.pmwiki.org/petko
+ licensed GNU GPLv2 or any more recent version released by the FSF.
+*/
+
+
+(function(__script__){
+ try {
+ var Config = JSON.parse(__script__.dataset.config);
+ }
+ catch(e) {
+ var Config = {};
+ }
+
+ function aE(el, ev, fn) {
+ if(typeof el == 'string') el = dqsa(el);
+ for(var i=0; i<el.length; i++) el[i].addEventListener(ev, fn);
+ }
+ function dqsa(str) { return document.querySelectorAll(str); }
+ function dce(tag) { return document.createElement(tag); }
+ function setStyles(el, obj) {
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ el.style[key] = obj[key];
+ }
+ }
+ }
+ var wLS = window.localStorage;
+
+ function getLS(key, parse) {
+ return wLS? wLS.getItem(key) : null;
+ }
+ function setLS(key, value) {
+ if(wLS) wLS.setItem(key, value);
+ }
+
+ function wmmd() {
+ if(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
+ return 1;
+ return 0;
+ }
+
+ function pref(enabled) {
+ var x = getLS('pmDarkToggled');
+ if(x === null) x = conftheme;
+ else x = parseInt(x);
+ if(enabled && x==2) return wmmd();
+ return x;
+ }
+
+ function toggleSheets(enabled) {
+ var themesheets = dqsa('link[rel="stylesheet"][data-theme]');
+ for(var i=0; i<themesheets.length; i++) {
+ var sheet = themesheets[i];
+ var isDark = sheet.dataset.theme == 'dark'? 1:0;
+ sheet.disabled = (isDark != enabled);
+ }
+ }
+
+ var clist = document.documentElement.classList,
+ conftheme = Config.enable - 1, label = false, current = false;
+
+ var prev_dark = pref(1)
+ if(prev_dark) clist.add('pmDarkTheme');
+ toggleSheets(prev_dark);
+
+ function update(toggle) {
+ var isToggled = pref(); // 0=light, 1=dark, 2=auto
+
+ if(toggle) {
+ isToggled = (isToggled+1)%3;
+ setLS('pmDarkToggled', isToggled);
+ if(current) current.textContent = Config.modes[isToggled];
+ }
+
+ var enabled = isToggled==2? wmmd() : isToggled;
+
+ if(enabled == prev_dark) return;
+ prev_dark = enabled+0;
+
+ if(enabled) clist.add('pmDarkTheme');
+ else clist.remove('pmDarkTheme');
+ toggleSheets(enabled);
+ }
+
+ function initLabel() {
+ label = dce('div');
+ label.className = 'frame darkThemeLabel';
+ setStyles(label, {
+ display: 'none',
+ fontSize: '.9rem',
+ zIndex: 1000,
+ position: 'fixed'
+ });
+ document.body.appendChild(label);
+ current = dce('mark');
+ setStyles(current, {
+ padding: '.2em .5em',
+ fontWeight: 700
+ });
+ label.append(Config.label, current);
+ }
+
+ function over() {
+ if(!label) initLabel();
+ current.textContent = Config.modes[pref()];
+
+ label.style.display = 'block';
+
+ var lrect = label.getBoundingClientRect()
+ rect = this.getBoundingClientRect(),
+ iw = window.innerWidth, ih = window.innerHeight,
+ lh = lrect.height, lw = lrect.width;
+
+ var left = (rect.left < iw-lw)
+ ? rect.left + 'px'
+ : (iw-lw-10) + 'px';
+ label.style.left = left;
+
+ var top = (rect.top < lh)
+ ? (rect.bottom) + 'px'
+ : (rect.top-lh) + 'px';
+ label.style.top = top;
+ }
+
+ function out(e) {
+ label.style.display = 'none';
+ }
+
+ if(wLS) {
+ setInterval(update, 1000);// sync other tabs
+ }
+
+ document.addEventListener('DOMContentLoaded', function(){
+ toggleSheets(prev_dark);
+ if(! wLS) return;
+ aE('.pmToggleDarkTheme', 'mouseenter', over);
+ aE('.pmToggleDarkTheme', 'mouseleave', out);
+ aE('.pmToggleDarkTheme', 'click', update);
+ });
+
+})(document.currentScript);
diff --git a/pub/pmwiki-utils.js b/pub/pmwiki-utils.js
index 5e41062f..5b68101b 100644
--- a/pub/pmwiki-utils.js
+++ b/pub/pmwiki-utils.js
@@ -590,128 +590,18 @@
}
});
}
-
- var clist = document.documentElement.classList;
-
- var prev_dark = 0;
-
- var darkModes = Config.darktheme.modes;
-
- function wmmd() {
- if(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
- return 1;
- return 0;
- }
- function getDarkPref() {
- var conftheme = Config.darktheme.enable - 1;
- var isToggled = getLS('pmDarkToggled');
- if(isToggled === null) isToggled = conftheme;
- else isToggled = parseInt(isToggled);
- return isToggled;
- }
-
- function updateDarkTheme(toggle) {
- var isToggled = getDarkPref(); // 0=light, 1=dark, 2=auto
-
- if(toggle === 1) {
- isToggled = (isToggled+1)%3;
- setLS('pmDarkToggled', isToggled);
- if(darkThemeLabelMode)
- darkThemeLabelMode.textContent = darkModes[isToggled];
- }
-
- var enabled = isToggled==2? wmmd() : isToggled;
-
- if(enabled == prev_dark && toggle !== -1) return;
- prev_dark = enabled+0;
-
- if(enabled) clist.add('pmDarkTheme');
- else clist.remove('pmDarkTheme');
-
- var themesheets = dqsa('link[rel="stylesheet"][data-theme]');
- for(var i=0; i<themesheets.length; i++) {
- var sheet = themesheets[i];
- var isDark = sheet.dataset.theme == 'dark'? 1:0;
- sheet.disabled = (isDark != enabled);
- }
- }
-
- if(Config.darktheme.enable && window.localStorage) {
- updateDarkTheme(-1);
- setInterval(updateDarkTheme, 1000);// sync other tabs
- }
-
+
if(Config.rediquiet) {
var url = location.href.replace(/\?from=[^?&#]*[&]quiet=1/, '');
if(url != location.href)
history.replaceState(null, null, url);
}
- var darkThemeLabel = false;
- var darkThemeLabelMode = false;
- function darkToggleOver(e) {
- if(!darkThemeLabel) {
- var d = dce('div');
- d.className = 'frame darkThemeLabel';
- d.style.display = 'none';
- d.style.fontSize = '.9rem';
- d.style.zIndex = 1000;
- d.style.position = 'fixed';
- dqs('body').appendChild(d);
- var title = dce('strong');
- title.textContent = Config.darktheme.label;
- d.appendChild(title);
- d.appendChild(dce('br'));
- var currently = dce('span');
- currently.textContent = Config.darktheme.currently + ' ';
- d.appendChild(currently);
- var m = dce('mark');
- m.style.padding = '.2em .5em';
- m.style.fontWeight = 700;
- d.appendChild(m);
- darkThemeLabel = d;
- darkThemeLabelMode = m;
- }
- else {
- var d = darkThemeLabel, m = darkThemeLabelMode;
- }
- m.textContent = darkModes[getDarkPref()];
- d.style.display = 'block';
-
- var lrect = d.getBoundingClientRect();
- var rect = this.getBoundingClientRect(),
- iw = window.innerWidth, ih = window.innerHeight,
- lh = lrect.height, lw = lrect.width;
-
- var left = (rect.left < iw-lw)
- ? rect.left + 'px'
- : (iw-lw-10) + 'px';
- d.style.left = left;
-
- var top = (rect.top < lh)
- ? (rect.bottom) + 'px'
- : (rect.top-lh) + 'px';
- d.style.top = top;
- }
-
- function darkToggleOut(e) {
- darkThemeLabel.style.display = 'none';
- }
-
function ready(){
- updateDarkTheme(-1);
wikitext = document.getElementById('wikitext');
var fn = [autotoc, inittoggle, PmXMail, localTimes, highlight_pre, copy_pre, confirmForms];
fn.forEach(function(a){a();});
makesortable();
-
- if(Config.darktheme.enable && window.localStorage) {
- tap('.pmToggleDarkTheme', function(e){
- updateDarkTheme(1);
- });
- aE('.pmToggleDarkTheme', 'mouseenter', darkToggleOver);
- aE('.pmToggleDarkTheme', 'mouseleave', darkToggleOut);
- }
}
if( document.readyState !== 'loading' ) ready();
else window.addEventListener('DOMContentLoaded', ready);
diff --git a/pub/skins/pmwiki-responsive/skin.css b/pub/skins/pmwiki-responsive/skin.css
index 6673e65c..af5fb8b4 100644
--- a/pub/skins/pmwiki-responsive/skin.css
+++ b/pub/skins/pmwiki-responsive/skin.css
@@ -610,7 +610,7 @@ table.sortable th.dir-d::after {
--pm-diffbox-bordercolor: #6a6a6a;
--pm-difftime-bgcolor: #2c2c2c;
--pm-diffadd-bgcolor: #002f00;
- --pm-diffdel-bgcolor: #1a1300;
+ --pm-diffdel-bgcolor: #4e1200;
--pm-rcplus-hover-color: #000;
--pm-rcplus-hover-bgcolor: #c281ff;
--pm-rcnew-bgcolor: #171200;
diff --git a/scripts/utils.php b/scripts/utils.php
index dc40ae11..ba95b24f 100644
--- a/scripts/utils.php
+++ b/scripts/utils.php
@@ -28,6 +28,7 @@ function PmUtilsJS() {
$EnableCopyCode, $EnableDarkThemeToggle, $EnableRedirectQuiet;
$utils = "$FarmD/pub/pmwiki-utils.js";
+ $dark = "$FarmD/pub/pmwiki-darktoggle.js";
$cc = IsEnabled($EnableCopyCode, 0)? PHSC(XL('Copy code'), ENT_QUOTES) : '';
@@ -50,12 +51,6 @@ function PmUtilsJS() {
'copycode' => $cc,
'toggle' => IsEnabled($ToggleNextSelector, 0),
'localtimes' => IsEnabled($EnableLocalTimes, 0),
- 'darktheme' => array(
- 'enable'=> IsEnabled($EnableDarkThemeToggle, 0),
- 'label'=> XL('Toggle theme'),
- 'currently'=> XL('Currently:'),
- 'modes'=> array( XL('Light'), XL('Dark'), XL('Auto'), ),
- ),
'rediquiet' => IsEnabled($EnableRedirectQuiet, 0),
);
$enabled = $PmTOC['Enable'];
@@ -81,6 +76,19 @@ function PmUtilsJS() {
data-label=\"$[Highlight]\" data-mode='$EnablePmSyntax'
data-custom=\"$cs\"></script>");
}
+
+ // Dark theme toggle, needs to be very early
+ $enabled = IsEnabled($EnableDarkThemeToggle, 0);
+ if ($enabled && file_exists($dark)) {
+ $config = array(
+ 'enable' => $enabled,
+ 'label'=> XL('Dark theme: '),
+ 'modes'=> array( XL('Light'), XL('Dark'), XL('Auto'), ),
+ );
+ $json = pm_json_encode($config);
+ array_unshift($HTMLHeaderFmt, "<script src='\$FarmPubDirUrl/pmwiki-darktoggle.js'
+ data-config='$json'></script>");
+ }
}
PmUtilsJS();