From c9edf4799259fa0401e098933737facc41987a65 Mon Sep 17 00:00:00 2001 From: Tisha Jain <103413370+tishajain25@users.noreply.github.com> Date: Wed, 8 Oct 2025 17:47:14 +0530 Subject: [PATCH 01/13] Add dark mode toggle to documentation - Implement CSS custom properties for light/dark themes - Add toggle button with sun/moon icons in header - Include JavaScript for theme switching and localStorage persistence - Support system preference detection (prefers-color-scheme) - Add dark syntax highlighting theme for code blocks - Ensure accessibility with ARIA labels and proper contrast - Provide smooth transitions between themes Fixes #3793 --- docs/_document.html | 27 ++++- docs/css/hljs-github-dark.css | 205 ++++++++++++++++++++++++++++++++++ docs/css/style.css | 110 ++++++++++++++++-- docs/js/index.js | 82 ++++++++++++++ 4 files changed, 407 insertions(+), 17 deletions(-) create mode 100644 docs/css/hljs-github-dark.css diff --git a/docs/_document.html b/docs/_document.html index b76588947c..17f920debd 100644 --- a/docs/_document.html +++ b/docs/_document.html @@ -6,10 +6,11 @@ + -
- - logo - -

Marked Documentation

+
+ + logo + +

Marked Documentation

+
+
+ diff --git a/docs/js/index.js b/docs/js/index.js index 45810c1067..8661e0e4fa 100644 --- a/docs/js/index.js +++ b/docs/js/index.js @@ -26,8 +26,9 @@ function initTheme() { const text = button.querySelector('.text'); if (theme === 'auto') { - // Auto mode: show 'Dark' (next action is to go to manual dark) - icon.innerHTML = SUN_ICON_SVG; + // Auto mode: show icon based on system preference + const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; + icon.innerHTML = isDarkMode ? MOON_ICON_SVG : SUN_ICON_SVG; text.textContent = 'Dark'; } else if (theme === 'dark') { // Manual dark mode: show 'Light' (next action is to go to manual light) From 81966e0b12061a9f35333e9df7be310390bc28c9 Mon Sep 17 00:00:00 2001 From: Tisha Jain <103413370+tishajain25@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:06:23 +0530 Subject: [PATCH 09/13] Fix demo page styling issues - Fix header layout: remove wrapper that displaced links - Add comprehensive dark mode styles for demo page - Tone down textboxes and preview backgrounds - Add proper dark theme colors for all elements - Style body, panes, labels, buttons for dark mode - Add toggle button positioning styles - Ensure GitHub corner banner changes with theme Addresses UziTech's feedback on demo page styling. --- docs/demo/demo.css | 87 ++++++++++++++++++++++++++++++++++++++++++++ docs/demo/index.html | 22 +++++------ 2 files changed, 97 insertions(+), 12 deletions(-) diff --git a/docs/demo/demo.css b/docs/demo/demo.css index 703d359d2e..6329b37159 100644 --- a/docs/demo/demo.css +++ b/docs/demo/demo.css @@ -17,7 +17,9 @@ textarea { header { padding-top: 10px; display: flex; + align-items: center; height: 58px; + padding-inline-end: 70px; } header h1 { @@ -26,6 +28,11 @@ header h1 { .other-demos { margin-left: 3em; + flex-grow: 1; +} + +.theme-toggle { + margin-left: auto; } .containers { @@ -79,3 +86,83 @@ header h1 { #responseTime { display: inline-block; } + +/* Dark mode styles */ +[data-theme="dark"] { + color-scheme: dark; +} + +[data-theme="dark"] html, +[data-theme="dark"] body { + color: #e6edf3; + background-color: #0d1117; +} + +[data-theme="dark"] .pane, +[data-theme="dark"] .inputPane { + background-color: #161b22; + border-color: #30363d; + color: #e6edf3; +} + +[data-theme="dark"] .label { + color: #e6edf3; +} + +[data-theme="dark"] select, +[data-theme="dark"] button:not(.theme-toggle) { + background-color: #21262d; + color: #e6edf3; + border-color: #30363d; +} + +[data-theme="dark"] .error { + background-color: #3d1014; + border-color: #67060c; +} + +[data-theme="dark"] .loadingError { + background-color: #3d1014; + color: #ff7b72; +} + +/* Auto mode with system preference */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) { + color-scheme: dark; + } + + :root:not([data-theme="light"]) html, + :root:not([data-theme="light"]) body { + color: #e6edf3; + background-color: #0d1117; + } + + :root:not([data-theme="light"]) .pane, + :root:not([data-theme="light"]) .inputPane { + background-color: #161b22; + border-color: #30363d; + color: #e6edf3; + } + + :root:not([data-theme="light"]) .label { + color: #e6edf3; + } + + :root:not([data-theme="light"]) select, + :root:not([data-theme="light"]) button:not(.theme-toggle) { + background-color: #21262d; + color: #e6edf3; + border-color: #30363d; + } + + :root:not([data-theme="light"]) .error { + background-color: #3d1014; + border-color: #67060c; + } + + :root:not([data-theme="light"]) .loadingError { + background-color: #3d1014; + color: #ff7b72; + } +} diff --git a/docs/demo/index.html b/docs/demo/index.html index dd474ae17e..cf486c991c 100644 --- a/docs/demo/index.html +++ b/docs/demo/index.html @@ -23,19 +23,17 @@

Marked Demo

-
-
- CommonMark Demo -
- Daring Fireball (pedantic) Demo -
- +
+ CommonMark Demo +
+ Daring Fireball (pedantic) Demo
+
Loading...
From cb2a00cdda3f0bd20fd5cfef00bec3be73966a79 Mon Sep 17 00:00:00 2001 From: Tisha Jain <103413370+tishajain25@users.noreply.github.com> Date: Thu, 16 Oct 2025 12:26:33 +0530 Subject: [PATCH 10/13] Fix dark mode issues: GitHub corner banner colors and preview iframe theme inheritance --- docs/demo/demo.css | 7 +++++++ docs/demo/demo.js | 10 ++++++++++ docs/demo/index.html | 2 +- docs/demo/preview.html | 27 +++++++++++++++++++++++++++ docs/js/index.js | 12 ++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) diff --git a/docs/demo/demo.css b/docs/demo/demo.css index 6329b37159..6d529da837 100644 --- a/docs/demo/demo.css +++ b/docs/demo/demo.css @@ -121,6 +121,11 @@ header h1 { border-color: #67060c; } +[data-theme="dark"] { + --github-corner-fill: #f0f6fc; + --github-corner-color: #0d1117; +} + [data-theme="dark"] .loadingError { background-color: #3d1014; color: #ff7b72; @@ -130,6 +135,8 @@ header h1 { @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { color-scheme: dark; + --github-corner-fill: #f0f6fc; + --github-corner-color: #0d1117; } :root:not([data-theme="light"]) html, diff --git a/docs/demo/demo.js b/docs/demo/demo.js index 48f84ad8ba..60e24e34aa 100644 --- a/docs/demo/demo.js +++ b/docs/demo/demo.js @@ -135,6 +135,16 @@ function setInitialOutputType() { function handleIframeLoad() { lastInput = ''; inputDirty = true; + + // Sync theme with the iframe when it loads + const theme = localStorage.getItem('theme') || 'auto'; + try { + if ($previewIframe.contentWindow) { + $previewIframe.contentWindow.postMessage({ theme: theme }, '*'); + } + } catch (e) { + // Ignore errors + } } function handleInput() { diff --git a/docs/demo/index.html b/docs/demo/index.html index cf486c991c..baeaca0a5b 100644 --- a/docs/demo/index.html +++ b/docs/demo/index.html @@ -11,7 +11,7 @@ - marked.js preview + + diff --git a/docs/js/index.js b/docs/js/index.js index 8661e0e4fa..a8ca8af5d6 100644 --- a/docs/js/index.js +++ b/docs/js/index.js @@ -16,6 +16,18 @@ function initTheme() { } localStorage.setItem('theme', theme); updateToggleButton(theme); + + // Send theme to all iframes on the page + const iframes = document.querySelectorAll('iframe'); + iframes.forEach(iframe => { + try { + if (iframe.contentWindow) { + iframe.contentWindow.postMessage({ theme: theme }, '*'); + } + } catch (e) { + // Ignore errors, iframe might be from another origin + } + }); } function updateToggleButton(theme) { From 4c5d23d542f1b36ed925c0d658295e07404ebb5c Mon Sep 17 00:00:00 2001 From: Tisha Jain <103413370+tishajain25@users.noreply.github.com> Date: Thu, 16 Oct 2025 13:42:51 +0530 Subject: [PATCH 11/13] Ensure demo preview iframe follows theme --- docs/demo/demo.js | 12 ++++------- docs/demo/preview.html | 32 ++++++--------------------- docs/js/index.js | 49 +++++++++++++++++++++++++++++++----------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/docs/demo/demo.js b/docs/demo/demo.js index 60e24e34aa..49546c274c 100644 --- a/docs/demo/demo.js +++ b/docs/demo/demo.js @@ -135,15 +135,11 @@ function setInitialOutputType() { function handleIframeLoad() { lastInput = ''; inputDirty = true; - - // Sync theme with the iframe when it loads + + // Ensure the preview iframe inherits the current theme const theme = localStorage.getItem('theme') || 'auto'; - try { - if ($previewIframe.contentWindow) { - $previewIframe.contentWindow.postMessage({ theme: theme }, '*'); - } - } catch (e) { - // Ignore errors + if (typeof window.__markedApplyThemeToIframes === 'function') { + window.__markedApplyThemeToIframes(theme); } } diff --git a/docs/demo/preview.html b/docs/demo/preview.html index cf6137142c..445ecd8206 100644 --- a/docs/demo/preview.html +++ b/docs/demo/preview.html @@ -7,32 +7,14 @@ - + diff --git a/docs/js/index.js b/docs/js/index.js index a8ca8af5d6..5f88d31902 100644 --- a/docs/js/index.js +++ b/docs/js/index.js @@ -7,22 +7,29 @@ function initTheme() { // Get stored theme preference or default to 'auto' const storedTheme = localStorage.getItem('theme') || 'auto'; const html = document.documentElement; + const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)'); + + function applyThemeToIframes(theme) { + const effectiveTheme = theme === 'auto' + ? (darkModeQuery.matches ? 'dark' : 'light') + : theme; - function setTheme(theme) { - if (theme === 'auto') { - html.removeAttribute('data-theme'); - } else { - html.setAttribute('data-theme', theme); - } - localStorage.setItem('theme', theme); - updateToggleButton(theme); - - // Send theme to all iframes on the page const iframes = document.querySelectorAll('iframe'); iframes.forEach(iframe => { try { - if (iframe.contentWindow) { - iframe.contentWindow.postMessage({ theme: theme }, '*'); + const iframeDocument = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document); + if (!iframeDocument || !iframeDocument.documentElement) { + return; + } + + if (theme === 'auto') { + iframeDocument.documentElement.removeAttribute('data-theme'); + } else { + iframeDocument.documentElement.setAttribute('data-theme', theme); + } + + if (iframeDocument.documentElement.style) { + iframeDocument.documentElement.style.colorScheme = effectiveTheme; } } catch (e) { // Ignore errors, iframe might be from another origin @@ -30,6 +37,21 @@ function initTheme() { }); } + // Expose helper for other scripts (e.g., demo page) to reapply theme on iframe load + window.__markedApplyThemeToIframes = applyThemeToIframes; + + function setTheme(theme) { + if (theme === 'auto') { + html.removeAttribute('data-theme'); + } else { + html.setAttribute('data-theme', theme); + } + localStorage.setItem('theme', theme); + updateToggleButton(theme); + + applyThemeToIframes(theme); + } + function updateToggleButton(theme) { const button = document.getElementById('theme-toggle'); if (!button) return; @@ -78,9 +100,10 @@ function initTheme() { setTheme(storedTheme); // Listen for system theme changes - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { + darkModeQuery.addEventListener('change', () => { if (localStorage.getItem('theme') === 'auto') { updateToggleButton('auto'); + applyThemeToIframes('auto'); } }); From 8234d946fc6c011dedac92db2ab490a5accc056a Mon Sep 17 00:00:00 2001 From: Tisha Jain <103413370+tishajain25@users.noreply.github.com> Date: Fri, 17 Oct 2025 12:10:00 +0530 Subject: [PATCH 12/13] Address code review feedback: fix SVG icon and optimize JS --- docs/demo/demo.css | 7 ++----- docs/demo/index.html | 8 ++++++++ docs/js/index.js | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/demo/demo.css b/docs/demo/demo.css index 6d529da837..1cde04c107 100644 --- a/docs/demo/demo.css +++ b/docs/demo/demo.css @@ -90,6 +90,8 @@ header h1 { /* Dark mode styles */ [data-theme="dark"] { color-scheme: dark; + --github-corner-fill: #f0f6fc; + --github-corner-color: #0d1117; } [data-theme="dark"] html, @@ -121,11 +123,6 @@ header h1 { border-color: #67060c; } -[data-theme="dark"] { - --github-corner-fill: #f0f6fc; - --github-corner-color: #0d1117; -} - [data-theme="dark"] .loadingError { background-color: #3d1014; color: #ff7b72; diff --git a/docs/demo/index.html b/docs/demo/index.html index baeaca0a5b..1011fdc924 100644 --- a/docs/demo/index.html +++ b/docs/demo/index.html @@ -31,6 +31,14 @@

Marked Demo

diff --git a/docs/js/index.js b/docs/js/index.js index 5f88d31902..6f32515074 100644 --- a/docs/js/index.js +++ b/docs/js/index.js @@ -61,7 +61,7 @@ function initTheme() { if (theme === 'auto') { // Auto mode: show icon based on system preference - const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; + const isDarkMode = darkModeQuery.matches; icon.innerHTML = isDarkMode ? MOON_ICON_SVG : SUN_ICON_SVG; text.textContent = 'Dark'; } else if (theme === 'dark') { From d8965affc8c36054d135619db0c40d8844b9fabc Mon Sep 17 00:00:00 2001 From: Tisha Jain <103413370+tishajain25@users.noreply.github.com> Date: Fri, 17 Oct 2025 12:16:17 +0530 Subject: [PATCH 13/13] Fix eslint errors: remove unused catch parameter --- docs/js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/js/index.js b/docs/js/index.js index 6f32515074..983c676905 100644 --- a/docs/js/index.js +++ b/docs/js/index.js @@ -31,7 +31,7 @@ function initTheme() { if (iframeDocument.documentElement.style) { iframeDocument.documentElement.style.colorScheme = effectiveTheme; } - } catch (e) { + } catch { // Ignore errors, iframe might be from another origin } });