diff options
author | petko <petko@524c5546-5005-0410-9a3e-e25e191bd360> | 2024-02-14 07:56:53 +0000 |
---|---|---|
committer | petko <petko@524c5546-5005-0410-9a3e-e25e191bd360> | 2024-02-14 07:56:53 +0000 |
commit | 77ce52c4e9032fdc90dda58ac0c59521dca4db97 (patch) | |
tree | dc5646107262e53269c8ef4b3c8e38c9a0f0e662 | |
parent | 0114f5240a9d4cf75e84ac23e955571a83a1fc98 (diff) | |
download | pmwiki.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.js | 143 | ||||
-rw-r--r-- | pub/pmwiki-utils.js | 112 | ||||
-rw-r--r-- | pub/skins/pmwiki-responsive/skin.css | 2 | ||||
-rw-r--r-- | scripts/utils.php | 20 |
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(); |