diff options
Diffstat (limited to 'api-docs/cppdocs')
| -rw-r--r-- | api-docs/cppdocs/binaryninja-darkmode.js | 129 | ||||
| -rw-r--r-- | api-docs/cppdocs/binaryninja-docs.css | 42 | ||||
| -rw-r--r-- | api-docs/cppdocs/header.html | 4 |
3 files changed, 134 insertions, 41 deletions
diff --git a/api-docs/cppdocs/binaryninja-darkmode.js b/api-docs/cppdocs/binaryninja-darkmode.js index 5dc19c13..109d5ef4 100644 --- a/api-docs/cppdocs/binaryninja-darkmode.js +++ b/api-docs/cppdocs/binaryninja-darkmode.js @@ -1,40 +1,67 @@ /** - * Binary Ninja Dark Mode - System Preference with Cookie Persistence + * Binary Ninja Dark Mode - System Preference with localStorage Persistence * Follows system color scheme automatically via CSS - * Provides console toggle for testing with cookie-based persistence + * Provides console toggle for testing with localStorage-based persistence */ (function() { 'use strict'; - const COOKIE_NAME = 'bn-docs-theme'; - const COOKIE_DAYS = 365; + const STORAGE_KEY = 'bn-docs-theme'; + const STORAGE_TIMESTAMP_KEY = 'bn-docs-theme-timestamp'; + const EXPIRY_HOURS = 24; /** - * Get cookie value by name + * Get theme from localStorage if not expired */ - function getCookie(name) { - const value = `; ${document.cookie}`; - const parts = value.split(`; ${name}=`); - if (parts.length === 2) return parts.pop().split(';').shift(); - return null; + function getTheme() { + try { + const theme = localStorage.getItem(STORAGE_KEY); + const timestamp = localStorage.getItem(STORAGE_TIMESTAMP_KEY); + + if (!theme || !timestamp) { + return null; + } + + // Check if expired (24 hours) + const now = Date.now(); + const age = now - parseInt(timestamp, 10); + const maxAge = EXPIRY_HOURS * 60 * 60 * 1000; // 24 hours in ms + + if (age > maxAge) { + // Expired, remove and return null + removeTheme(); + return null; + } + + return theme; + } catch (e) { + return null; + } } /** - * Set cookie value + * Set theme in localStorage with timestamp */ - function setCookie(name, value, days) { - const date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - const expires = `expires=${date.toUTCString()}`; - document.cookie = `${name}=${value};${expires};path=/`; + function setTheme(value) { + try { + localStorage.setItem(STORAGE_KEY, value); + localStorage.setItem(STORAGE_TIMESTAMP_KEY, Date.now().toString()); + } catch (e) { + // Silently fail if localStorage is unavailable + } } /** - * Delete cookie + * Remove theme from localStorage */ - function deleteCookie(name) { - document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`; + function removeTheme() { + try { + localStorage.removeItem(STORAGE_KEY); + localStorage.removeItem(STORAGE_TIMESTAMP_KEY); + } catch (e) { + // Silently fail if localStorage is unavailable + } } /** @@ -57,42 +84,78 @@ } /** - * Console-accessible toggle function with cookie persistence + * Console-accessible toggle function with localStorage persistence * Usage: bnToggleDarkMode('dark'), bnToggleDarkMode('light'), or bnToggleDarkMode('auto') */ window.bnToggleDarkMode = function(mode) { if (mode === 'dark') { applyTheme('dark'); - setCookie(COOKIE_NAME, 'dark', COOKIE_DAYS); - console.log('Dark mode: FORCED ON (saved to cookie, will persist across reloads)'); + setTheme('dark'); } else if (mode === 'light') { applyTheme('light'); - setCookie(COOKIE_NAME, 'light', COOKIE_DAYS); - console.log('Dark mode: FORCED OFF (saved to cookie, will persist across reloads)'); + setTheme('light'); } else if (mode === 'auto') { applyTheme('auto'); - deleteCookie(COOKIE_NAME); - console.log('Dark mode: AUTO (following system preference, cookie cleared)'); + removeTheme(); + } + }; + + /** + * Update button icon based on current theme + */ + function updateButtonIcon() { + const button = document.getElementById('bn-darkmode-toggle'); + if (!button) return; + + const savedTheme = getTheme(); + + if (savedTheme === 'light') { + button.textContent = '☀'; + button.title = 'Light mode (click for Dark)'; + } else if (savedTheme === 'dark') { + button.textContent = '☾'; + button.title = 'Dark mode (click for Light)'; } else { - console.log('Usage: bnToggleDarkMode("dark"), bnToggleDarkMode("light"), or bnToggleDarkMode("auto")'); - console.log('Current setting:', getCookie(COOKIE_NAME) || 'auto (system preference)'); + // No saved theme - show system preference + const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; + if (isDarkMode) { + button.textContent = '☾'; + button.title = 'System: Dark (click for Light)'; + } else { + button.textContent = '☀'; + button.title = 'System: Light (click for Dark)'; + } } + } + + /** + * Cycle between light and dark mode + */ + window.cycleDarkMode = function() { + const savedTheme = getTheme(); + + if (savedTheme === 'light') { + window.bnToggleDarkMode('dark'); + } else { + // From dark or system -> go to light + window.bnToggleDarkMode('light'); + } + + updateButtonIcon(); }; /** * Initialize theme on page load */ function init() { - const savedTheme = getCookie(COOKIE_NAME); + const savedTheme = getTheme(); if (savedTheme) { applyTheme(savedTheme); - console.log(`Binary Ninja Docs: Theme loaded from cookie: ${savedTheme}`); - } else { - console.log('Binary Ninja Docs: Following system preference (no cookie set)'); } - console.log('Use bnToggleDarkMode("dark"), bnToggleDarkMode("light"), or bnToggleDarkMode("auto") to change theme'); + // Update button icon after a short delay to ensure DOM is ready + setTimeout(updateButtonIcon, 100); } // Initialize on page load diff --git a/api-docs/cppdocs/binaryninja-docs.css b/api-docs/cppdocs/binaryninja-docs.css index cfdf3b4f..5ec29588 100644 --- a/api-docs/cppdocs/binaryninja-docs.css +++ b/api-docs/cppdocs/binaryninja-docs.css @@ -397,11 +397,13 @@ tr#projectrow { } #MSearchBox { - width: calc(var(--sidebar-width) - calc(2 * var(--spacing-medium)) - 1px); + width: calc(var(--sidebar-width) - calc(2 * var(--spacing-medium)) - 50px); + display: inline-block; + vertical-align: top; } #MSearchField { - width: calc(var(--sidebar-width) - calc(2 * var(--spacing-medium)) - 66px); + width: calc(var(--sidebar-width) - calc(2 * var(--spacing-medium)) - 113px); padding-left: 10px; top: -1px; } @@ -513,7 +515,7 @@ tr#projectrow { overflow: hidden; position: relative; box-shadow: none; - display: block; + display: inline-block; margin-top: 0; } @@ -1304,10 +1306,35 @@ pre.fragment { } /* ============================================================================ - * DARK MODE TOGGLE (Hidden - CSS-only system preference) + * DARK MODE TOGGLE * ============================================================================ */ -#bn-darkmode-toggle { - display: none; +.bn-darkmode-toggle { + display: inline-block; + width: 33px; + height: var(--searchbar-height); + border: 1px solid var(--border-color); + background-color: var(--page-bg); + color: var(--page-text); + cursor: pointer; + font-size: 16px; + line-height: var(--searchbar-height); + border-radius: var(--searchbar-border-radius); + vertical-align: top; + margin-left: 5px; + margin-right: 3px; + text-align: center; + padding: 0; +} + +.bn-darkmode-toggle:hover { + background-color: var(--table-header-bg); + border-color: var(--bn-red); +} + +@media screen and (max-width: 1024px) { + .bn-darkmode-toggle { + display: none; + } } /* ============================================================================ @@ -1355,6 +1382,9 @@ html.dark-mode .darkmode_inverted_image object[type="image/svg+xml"] { /* Collapsed sidebar state */ #side-nav.collapsed { + width: 0 !important; + min-width: 0 !important; + max-width: 0 !important; overflow: visible !important; } diff --git a/api-docs/cppdocs/header.html b/api-docs/cppdocs/header.html index aa33c348..cb988a38 100644 --- a/api-docs/cppdocs/header.html +++ b/api-docs/cppdocs/header.html @@ -80,14 +80,14 @@ $(document).ready(function() { <!--BEGIN DISABLE_INDEX--> <!--BEGIN SEARCHENGINE--> <!--BEGIN !FULL_SIDEBAR--> - <td>$searchbox</td> + <td>$searchbox<button id="bn-darkmode-toggle" class="bn-darkmode-toggle" onclick="cycleDarkMode()" title="Toggle theme">◐</button></td> <!--END !FULL_SIDEBAR--> <!--END SEARCHENGINE--> <!--END DISABLE_INDEX--> </tr> <!--BEGIN SEARCHENGINE--> <!--BEGIN FULL_SIDEBAR--> - <tr><td colspan="2">$searchbox</td></tr> + <tr><td colspan="2">$searchbox<button id="bn-darkmode-toggle" class="bn-darkmode-toggle" onclick="cycleDarkMode()" title="Toggle theme">◐</button></td></tr> <!--END FULL_SIDEBAR--> <!--END SEARCHENGINE--> </tbody> |
