opencode-replay 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/dist/assets/highlight.js +300 -0
- package/dist/assets/prism.css +273 -0
- package/dist/assets/search.js +445 -0
- package/dist/assets/styles.css +3384 -0
- package/dist/assets/theme.js +111 -0
- package/dist/index.js +2569 -0
- package/package.json +44 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Replay - Theme Management
|
|
3
|
+
* Handles dark/light mode toggle with localStorage persistence
|
|
4
|
+
*/
|
|
5
|
+
(function initTheme() {
|
|
6
|
+
const THEME_KEY = 'opencode-replay-theme';
|
|
7
|
+
const THEME_TIME_KEY = 'opencode-replay-theme-time';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Safe localStorage getter (handles private browsing mode)
|
|
11
|
+
*/
|
|
12
|
+
function getStorageItem(key) {
|
|
13
|
+
try {
|
|
14
|
+
return localStorage.getItem(key);
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Safe localStorage setter (handles quota exceeded and private browsing)
|
|
22
|
+
*/
|
|
23
|
+
function setStorageItem(key, value) {
|
|
24
|
+
try {
|
|
25
|
+
localStorage.setItem(key, value);
|
|
26
|
+
} catch {
|
|
27
|
+
// Ignore storage errors (private browsing, quota exceeded)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get the user's preferred theme
|
|
33
|
+
* Priority: localStorage > system preference > light
|
|
34
|
+
*/
|
|
35
|
+
function getPreferredTheme() {
|
|
36
|
+
var storedTheme = getStorageItem(THEME_KEY);
|
|
37
|
+
|
|
38
|
+
if (storedTheme === 'dark' || storedTheme === 'light') {
|
|
39
|
+
return storedTheme;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check system preference
|
|
43
|
+
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
44
|
+
return 'dark';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return 'light';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Apply theme to document
|
|
52
|
+
*/
|
|
53
|
+
function setTheme(theme, saveTime) {
|
|
54
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
55
|
+
setStorageItem(THEME_KEY, theme);
|
|
56
|
+
if (saveTime !== false) {
|
|
57
|
+
setStorageItem(THEME_TIME_KEY, String(Date.now()));
|
|
58
|
+
}
|
|
59
|
+
updateToggleButton(theme);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Update toggle button accessibility attributes
|
|
64
|
+
*/
|
|
65
|
+
function updateToggleButton(theme) {
|
|
66
|
+
const toggle = document.getElementById('theme-toggle');
|
|
67
|
+
if (toggle) {
|
|
68
|
+
toggle.setAttribute('aria-label',
|
|
69
|
+
theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'
|
|
70
|
+
);
|
|
71
|
+
toggle.setAttribute('aria-pressed', String(theme === 'dark'));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Toggle between light and dark themes
|
|
77
|
+
*/
|
|
78
|
+
function toggleTheme() {
|
|
79
|
+
const currentTheme = document.documentElement.getAttribute('data-theme') || getPreferredTheme();
|
|
80
|
+
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
|
81
|
+
setTheme(newTheme, true);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Initialize theme on page load
|
|
85
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
86
|
+
const theme = getPreferredTheme();
|
|
87
|
+
setTheme(theme, false);
|
|
88
|
+
|
|
89
|
+
// Set up toggle button click handler
|
|
90
|
+
const toggle = document.getElementById('theme-toggle');
|
|
91
|
+
if (toggle) {
|
|
92
|
+
toggle.addEventListener('click', toggleTheme);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Listen for system theme changes (when no explicit preference is set)
|
|
97
|
+
if (window.matchMedia) {
|
|
98
|
+
var mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
99
|
+
|
|
100
|
+
mediaQuery.addEventListener('change', function(e) {
|
|
101
|
+
// Only auto-switch if user hasn't set an explicit preference recently
|
|
102
|
+
var lastSet = getStorageItem(THEME_TIME_KEY);
|
|
103
|
+
var now = Date.now();
|
|
104
|
+
|
|
105
|
+
// If preference was set more than 24 hours ago, follow system
|
|
106
|
+
if (!lastSet || (now - parseInt(lastSet, 10)) > 86400000) {
|
|
107
|
+
setTheme(e.matches ? 'dark' : 'light', false);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
})();
|