janito 1.10.0__py3-none-any.whl → 1.11.1__py3-none-any.whl
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.
- janito/__init__.py +1 -1
- janito/agent/conversation_api.py +178 -90
- janito/agent/conversation_ui.py +1 -1
- janito/agent/llm_conversation_history.py +12 -0
- janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +19 -4
- janito/agent/tools/__init__.py +2 -0
- janito/agent/tools/create_directory.py +1 -1
- janito/agent/tools/create_file.py +1 -1
- janito/agent/tools/fetch_url.py +1 -1
- janito/agent/tools/find_files.py +26 -13
- janito/agent/tools/get_file_outline/core.py +1 -1
- janito/agent/tools/get_file_outline/python_outline.py +139 -95
- janito/agent/tools/get_lines.py +92 -63
- janito/agent/tools/move_file.py +58 -32
- janito/agent/tools/open_url.py +31 -0
- janito/agent/tools/python_command_runner.py +85 -86
- janito/agent/tools/python_file_runner.py +85 -86
- janito/agent/tools/python_stdin_runner.py +87 -88
- janito/agent/tools/remove_directory.py +1 -1
- janito/agent/tools/remove_file.py +1 -1
- janito/agent/tools/replace_file.py +2 -2
- janito/agent/tools/replace_text_in_file.py +193 -149
- janito/agent/tools/run_bash_command.py +1 -1
- janito/agent/tools/run_powershell_command.py +4 -0
- janito/agent/tools/search_text/__init__.py +1 -0
- janito/agent/tools/search_text/core.py +176 -0
- janito/agent/tools/search_text/match_lines.py +58 -0
- janito/agent/tools/search_text/pattern_utils.py +65 -0
- janito/agent/tools/search_text/traverse_directory.py +132 -0
- janito/agent/tools/validate_file_syntax/core.py +41 -30
- janito/agent/tools/validate_file_syntax/html_validator.py +21 -5
- janito/agent/tools/validate_file_syntax/markdown_validator.py +77 -34
- janito/agent/tools_utils/gitignore_utils.py +25 -2
- janito/agent/tools_utils/utils.py +7 -1
- janito/cli/config_commands.py +112 -109
- janito/shell/main.py +51 -8
- janito/shell/session/config.py +83 -75
- janito/shell/ui/interactive.py +97 -73
- janito/termweb/static/editor.css +32 -29
- janito/termweb/static/editor.css.bak +140 -22
- janito/termweb/static/editor.html +12 -7
- janito/termweb/static/editor.html.bak +16 -11
- janito/termweb/static/editor.js +94 -40
- janito/termweb/static/editor.js.bak +97 -65
- janito/termweb/static/index.html +1 -2
- janito/termweb/static/index.html.bak +1 -1
- janito/termweb/static/termweb.css +1 -22
- janito/termweb/static/termweb.css.bak +6 -4
- janito/termweb/static/termweb.js +0 -6
- janito/termweb/static/termweb.js.bak +1 -2
- {janito-1.10.0.dist-info → janito-1.11.1.dist-info}/METADATA +1 -1
- {janito-1.10.0.dist-info → janito-1.11.1.dist-info}/RECORD +56 -51
- {janito-1.10.0.dist-info → janito-1.11.1.dist-info}/WHEEL +1 -1
- janito/agent/tools/search_text.py +0 -254
- {janito-1.10.0.dist-info → janito-1.11.1.dist-info}/entry_points.txt +0 -0
- {janito-1.10.0.dist-info → janito-1.11.1.dist-info}/licenses/LICENSE +0 -0
- {janito-1.10.0.dist-info → janito-1.11.1.dist-info}/top_level.txt +0 -0
janito/termweb/static/editor.js
CHANGED
@@ -4,39 +4,92 @@ function getQueryParam(name) {
|
|
4
4
|
return url.searchParams.get(name);
|
5
5
|
}
|
6
6
|
const filePath = getQueryParam('path');
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
|
8
|
+
// Updates the theme icon based on the current theme
|
9
|
+
function updateThemeIcon() {
|
10
|
+
var icon = document.getElementById('theme-icon');
|
11
|
+
if (!icon) return;
|
12
|
+
if (document.body.classList.contains('light-theme')) {
|
13
|
+
icon.textContent = '☀️'; // Sun for light mode
|
14
|
+
icon.title = 'Switch to dark mode';
|
15
|
+
} else {
|
16
|
+
icon.textContent = '🌙'; // Moon for dark mode
|
17
|
+
icon.title = 'Switch to light mode';
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
document.addEventListener('DOMContentLoaded', function() {
|
22
|
+
// Display filename in header if present
|
23
|
+
if (filePath) {
|
24
|
+
const filename = filePath.split(/[\\\/]/).pop();
|
25
|
+
const filenameDisplay = document.getElementById('filename-display');
|
26
|
+
if (filenameDisplay) {
|
27
|
+
filenameDisplay.textContent = '— ' + filePath;
|
28
|
+
filenameDisplay.title = filePath;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
let initialContent = "";
|
33
|
+
if (filePath) {
|
34
|
+
fetch(`/api/explorer/${encodeURIComponent(filePath)}`)
|
35
|
+
.then(resp => resp.json())
|
36
|
+
.then(data => {
|
37
|
+
if (data.type === 'file') {
|
38
|
+
initialContent = data.content;
|
39
|
+
if (window.editorInstance) {
|
40
|
+
window.editorInstance.setValue(initialContent);
|
41
|
+
}
|
42
|
+
} else if (data.error) {
|
43
|
+
initialContent = '# Error: ' + data.error;
|
44
|
+
if (window.editorInstance) {
|
45
|
+
window.editorInstance.setValue(initialContent);
|
46
|
+
}
|
16
47
|
}
|
17
|
-
}
|
18
|
-
|
48
|
+
})
|
49
|
+
.catch(err => {
|
50
|
+
initialContent = '# Error ao carregar arquivo: ' + err;
|
19
51
|
if (window.editorInstance) {
|
20
52
|
window.editorInstance.setValue(initialContent);
|
21
53
|
}
|
22
|
-
}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
54
|
+
});
|
55
|
+
}
|
56
|
+
|
57
|
+
// --- Detect file extension and set CodeMirror mode ---
|
58
|
+
function detectMode(filename) {
|
59
|
+
if (!filename) return 'python';
|
60
|
+
const ext = filename.split('.').pop().toLowerCase();
|
61
|
+
const map = {
|
62
|
+
'py': 'python',
|
63
|
+
'js': 'javascript',
|
64
|
+
'json': 'javascript',
|
65
|
+
'md': 'markdown',
|
66
|
+
'html': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
67
|
+
'htm': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
68
|
+
'jinja': 'django',
|
69
|
+
'j2': 'django',
|
70
|
+
'jinja2': 'django',
|
71
|
+
'css': 'css',
|
72
|
+
'sh': 'shell',
|
73
|
+
'bash': 'shell',
|
74
|
+
'yml': 'yaml',
|
75
|
+
'yaml': 'yaml',
|
76
|
+
};
|
77
|
+
return map[ext] || 'python';
|
78
|
+
}
|
79
|
+
var initialMode = detectMode(filePath);
|
32
80
|
var editorInstance = CodeMirror.fromTextArea(document.getElementById('code'), {
|
33
81
|
lineNumbers: true,
|
34
|
-
mode:
|
82
|
+
mode: initialMode,
|
35
83
|
theme: 'dracula',
|
36
84
|
indentUnit: 4,
|
37
85
|
tabSize: 4,
|
38
86
|
styleActiveLine: true,
|
39
87
|
});
|
88
|
+
// If file loaded later, update mode
|
89
|
+
if (filePath) {
|
90
|
+
const mode = detectMode(filePath);
|
91
|
+
editorInstance.setOption('mode', mode);
|
92
|
+
}
|
40
93
|
window.editorInstance = editorInstance;
|
41
94
|
// Add Ctrl-F handler for find
|
42
95
|
editorInstance.addKeyMap({
|
@@ -54,6 +107,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
54
107
|
'Cmd-S': function(cm) {
|
55
108
|
document.getElementById('save-btn').click();
|
56
109
|
return false;
|
110
|
+
},
|
111
|
+
'Alt-W': function(cm) {
|
112
|
+
const current = cm.getOption('lineWrapping');
|
113
|
+
cm.setOption('lineWrapping', !current);
|
57
114
|
}
|
58
115
|
});
|
59
116
|
// --- Custom floating find navigation panel ---
|
@@ -153,29 +210,26 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
153
210
|
window.addEventListener('resize', resizeEditor);
|
154
211
|
setTimeout(resizeEditor, 0);
|
155
212
|
editorInstance.setValue(initialContent);
|
213
|
+
updateThemeIcon();
|
156
214
|
|
157
|
-
// Theme switcher logic
|
158
|
-
var themeSwitcher = document.getElementById('theme-switcher');
|
159
|
-
var themeIcon = document.getElementById('theme-icon');
|
160
|
-
var isDark = true;
|
161
|
-
function updateThemeIcon() {
|
162
|
-
themeIcon.textContent = isDark ? '🌙' : '☀️';
|
163
|
-
}
|
164
|
-
themeSwitcher.addEventListener('click', function() {
|
165
|
-
isDark = !isDark;
|
166
|
-
if (isDark) {
|
167
|
-
document.body.classList.remove('light-theme');
|
168
|
-
editorInstance.setOption('theme', 'dracula');
|
169
|
-
} else {
|
170
|
-
document.body.classList.add('light-theme');
|
171
|
-
editorInstance.setOption('theme', 'default');
|
172
|
-
}
|
173
|
-
updateThemeIcon();
|
174
|
-
});
|
175
215
|
// Set initial state
|
176
216
|
document.body.classList.remove('light-theme');
|
177
217
|
editorInstance.setOption('theme', 'dracula');
|
178
218
|
updateThemeIcon();
|
219
|
+
|
220
|
+
// Theme switch button logic
|
221
|
+
var themeSwitcher = document.getElementById('theme-switcher');
|
222
|
+
if (themeSwitcher) {
|
223
|
+
themeSwitcher.addEventListener('click', function() {
|
224
|
+
var isLight = document.body.classList.toggle('light-theme');
|
225
|
+
if (isLight) {
|
226
|
+
editorInstance.setOption('theme', 'default');
|
227
|
+
} else {
|
228
|
+
editorInstance.setOption('theme', 'dracula');
|
229
|
+
}
|
230
|
+
updateThemeIcon();
|
231
|
+
});
|
232
|
+
}
|
179
233
|
// Botão de Gravar
|
180
234
|
var saveBtn = document.getElementById('save-btn');
|
181
235
|
saveBtn.addEventListener('click', function() {
|
@@ -4,39 +4,92 @@ function getQueryParam(name) {
|
|
4
4
|
return url.searchParams.get(name);
|
5
5
|
}
|
6
6
|
const filePath = getQueryParam('path');
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
|
8
|
+
// Updates the theme icon based on the current theme
|
9
|
+
function updateThemeIcon() {
|
10
|
+
var icon = document.getElementById('theme-icon');
|
11
|
+
if (!icon) return;
|
12
|
+
if (document.body.classList.contains('light-theme')) {
|
13
|
+
icon.textContent = '☀️'; // Sun for light mode
|
14
|
+
icon.title = 'Switch to dark mode';
|
15
|
+
} else {
|
16
|
+
icon.textContent = '🌙'; // Moon for dark mode
|
17
|
+
icon.title = 'Switch to light mode';
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
document.addEventListener('DOMContentLoaded', function() {
|
22
|
+
// Display filename in header if present
|
23
|
+
if (filePath) {
|
24
|
+
const filename = filePath.split(/[\\\/]/).pop();
|
25
|
+
const filenameDisplay = document.getElementById('filename-display');
|
26
|
+
if (filenameDisplay) {
|
27
|
+
filenameDisplay.textContent = '— ' + filePath;
|
28
|
+
filenameDisplay.title = filePath;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
let initialContent = "";
|
33
|
+
if (filePath) {
|
34
|
+
fetch(`/api/explorer/${encodeURIComponent(filePath)}`)
|
35
|
+
.then(resp => resp.json())
|
36
|
+
.then(data => {
|
37
|
+
if (data.type === 'file') {
|
38
|
+
initialContent = data.content;
|
39
|
+
if (window.editorInstance) {
|
40
|
+
window.editorInstance.setValue(initialContent);
|
41
|
+
}
|
42
|
+
} else if (data.error) {
|
43
|
+
initialContent = '# Error: ' + data.error;
|
44
|
+
if (window.editorInstance) {
|
45
|
+
window.editorInstance.setValue(initialContent);
|
46
|
+
}
|
16
47
|
}
|
17
|
-
}
|
18
|
-
|
48
|
+
})
|
49
|
+
.catch(err => {
|
50
|
+
initialContent = '# Error ao carregar arquivo: ' + err;
|
19
51
|
if (window.editorInstance) {
|
20
52
|
window.editorInstance.setValue(initialContent);
|
21
53
|
}
|
22
|
-
}
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
54
|
+
});
|
55
|
+
}
|
56
|
+
|
57
|
+
// --- Detect file extension and set CodeMirror mode ---
|
58
|
+
function detectMode(filename) {
|
59
|
+
if (!filename) return 'python';
|
60
|
+
const ext = filename.split('.').pop().toLowerCase();
|
61
|
+
const map = {
|
62
|
+
'py': 'python',
|
63
|
+
'js': 'javascript',
|
64
|
+
'json': 'javascript',
|
65
|
+
'md': 'markdown',
|
66
|
+
'html': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
67
|
+
'htm': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
68
|
+
'jinja': 'django',
|
69
|
+
'j2': 'django',
|
70
|
+
'jinja2': 'django',
|
71
|
+
'css': 'css',
|
72
|
+
'sh': 'shell',
|
73
|
+
'bash': 'shell',
|
74
|
+
'yml': 'yaml',
|
75
|
+
'yaml': 'yaml',
|
76
|
+
};
|
77
|
+
return map[ext] || 'python';
|
78
|
+
}
|
79
|
+
var initialMode = detectMode(filePath);
|
32
80
|
var editorInstance = CodeMirror.fromTextArea(document.getElementById('code'), {
|
33
81
|
lineNumbers: true,
|
34
|
-
mode:
|
82
|
+
mode: initialMode,
|
35
83
|
theme: 'dracula',
|
36
84
|
indentUnit: 4,
|
37
85
|
tabSize: 4,
|
38
86
|
styleActiveLine: true,
|
39
87
|
});
|
88
|
+
// If file loaded later, update mode
|
89
|
+
if (filePath) {
|
90
|
+
const mode = detectMode(filePath);
|
91
|
+
editorInstance.setOption('mode', mode);
|
92
|
+
}
|
40
93
|
window.editorInstance = editorInstance;
|
41
94
|
// Add Ctrl-F handler for find
|
42
95
|
editorInstance.addKeyMap({
|
@@ -45,15 +98,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
45
98
|
},
|
46
99
|
'Cmd-F': function(cm) {
|
47
100
|
cm.execCommand('find');
|
48
|
-
}
|
49
|
-
});
|
50
|
-
// Add Ctrl+S/Cmd+S handler for save
|
51
|
-
editorInstance.addKeyMap({
|
101
|
+
},
|
52
102
|
'Ctrl-S': function(cm) {
|
53
103
|
document.getElementById('save-btn').click();
|
104
|
+
// Prevent default browser save dialog
|
105
|
+
return false;
|
54
106
|
},
|
55
107
|
'Cmd-S': function(cm) {
|
56
108
|
document.getElementById('save-btn').click();
|
109
|
+
return false;
|
57
110
|
}
|
58
111
|
});
|
59
112
|
// --- Custom floating find navigation panel ---
|
@@ -153,41 +206,27 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
153
206
|
window.addEventListener('resize', resizeEditor);
|
154
207
|
setTimeout(resizeEditor, 0);
|
155
208
|
editorInstance.setValue(initialContent);
|
209
|
+
updateThemeIcon();
|
156
210
|
|
157
|
-
// Theme switcher logic
|
158
|
-
var themeSwitcher = document.getElementById('theme-switcher');
|
159
|
-
var themeIcon = document.getElementById('theme-icon');
|
160
|
-
var isDark = true;
|
161
|
-
function updateThemeIcon() {
|
162
|
-
themeIcon.textContent = isDark ? '🌙' : '☀️';
|
163
|
-
}
|
164
|
-
themeSwitcher.addEventListener('click', function() {
|
165
|
-
isDark = !isDark;
|
166
|
-
if (isDark) {
|
167
|
-
document.body.classList.remove('light-theme');
|
168
|
-
editorInstance.setOption('theme', 'dracula');
|
169
|
-
} else {
|
170
|
-
document.body.classList.add('light-theme');
|
171
|
-
editorInstance.setOption('theme', 'default');
|
172
|
-
}
|
173
|
-
updateThemeIcon();
|
174
|
-
});
|
175
211
|
// Set initial state
|
176
212
|
document.body.classList.remove('light-theme');
|
177
213
|
editorInstance.setOption('theme', 'dracula');
|
178
214
|
updateThemeIcon();
|
179
215
|
|
180
|
-
//
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
216
|
+
// Theme switch button logic
|
217
|
+
var themeSwitcher = document.getElementById('theme-switcher');
|
218
|
+
if (themeSwitcher) {
|
219
|
+
themeSwitcher.addEventListener('click', function() {
|
220
|
+
var isLight = document.body.classList.toggle('light-theme');
|
221
|
+
if (isLight) {
|
222
|
+
editorInstance.setOption('theme', 'default');
|
223
|
+
} else {
|
224
|
+
editorInstance.setOption('theme', 'dracula');
|
225
|
+
}
|
226
|
+
updateThemeIcon();
|
227
|
+
});
|
188
228
|
}
|
189
|
-
|
190
|
-
// Save Button
|
229
|
+
// Botão de Gravar
|
191
230
|
var saveBtn = document.getElementById('save-btn');
|
192
231
|
saveBtn.addEventListener('click', function() {
|
193
232
|
if (!filePath) {
|
@@ -205,9 +244,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
205
244
|
.then(resp => resp.json())
|
206
245
|
.then(data => {
|
207
246
|
if (data.success) {
|
208
|
-
|
209
|
-
|
210
|
-
|
247
|
+
// Show popup
|
248
|
+
var popup = document.getElementById('save-popup');
|
249
|
+
popup.style.display = 'block';
|
250
|
+
setTimeout(() => { popup.style.display = 'none'; }, 1500);
|
211
251
|
} else {
|
212
252
|
alert('Error saving: ' + (data.error || 'desconhecido'));
|
213
253
|
}
|
@@ -216,12 +256,4 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
216
256
|
alert('Error saving: ' + err);
|
217
257
|
});
|
218
258
|
});
|
219
|
-
|
220
|
-
// Prevent browser default save dialog on Ctrl+S/Cmd+S
|
221
|
-
window.addEventListener('keydown', function(e) {
|
222
|
-
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') {
|
223
|
-
e.preventDefault();
|
224
|
-
document.getElementById('save-btn').click();
|
225
|
-
}
|
226
|
-
});
|
227
259
|
});
|
janito/termweb/static/index.html
CHANGED
@@ -24,8 +24,7 @@
|
|
24
24
|
<img src="/static/termicon.svg" alt="TermWeb Logo" class="header-logo">
|
25
25
|
<span class="header-title">TermWeb</span>
|
26
26
|
<span class="header-subtitle">Explorador de Projetos com IA</span>
|
27
|
-
|
28
|
-
</div>
|
27
|
+
</div>
|
29
28
|
<div class="toolbar" id="explorer-toolbar">
|
30
29
|
|
31
30
|
</div>
|
@@ -24,7 +24,7 @@
|
|
24
24
|
<img src="/static/termicon.svg" alt="TermWeb Logo" class="header-logo">
|
25
25
|
<span class="header-title">TermWeb</span>
|
26
26
|
<span class="header-subtitle">Explorador de Projetos com IA</span>
|
27
|
-
<button class="theme-switcher" id="theme-switcher" title="
|
27
|
+
<button class="theme-switcher" id="theme-switcher" title="Alternate tema"><span id="theme-icon">🌙</span></button>
|
28
28
|
</div>
|
29
29
|
<div class="toolbar" id="explorer-toolbar">
|
30
30
|
|
@@ -20,7 +20,7 @@ body.light-theme {
|
|
20
20
|
.header {
|
21
21
|
background: #23272b;
|
22
22
|
color: #f1f1f1;
|
23
|
-
padding: 1em 2em;
|
23
|
+
padding: 0.2em 2em 1em 2em;
|
24
24
|
font-size: 1.5em;
|
25
25
|
font-weight: bold;
|
26
26
|
letter-spacing: 0.04em;
|
@@ -180,27 +180,6 @@ body.light-theme .footer a {
|
|
180
180
|
display: inline;
|
181
181
|
}
|
182
182
|
|
183
|
-
.theme-switcher {
|
184
|
-
position: absolute;
|
185
|
-
right: 20px;
|
186
|
-
top: 10px;
|
187
|
-
background: #444;
|
188
|
-
color: #f1f1f1;
|
189
|
-
border: none;
|
190
|
-
border-radius: 4px;
|
191
|
-
padding: 6px 14px;
|
192
|
-
cursor: pointer;
|
193
|
-
font-size: 1em;
|
194
|
-
transition: background 0.2s, color 0.2s;
|
195
|
-
}
|
196
|
-
body.light-theme .theme-switcher {
|
197
|
-
background: #ddd;
|
198
|
-
color: #181a1b;
|
199
|
-
}
|
200
|
-
body.dark-theme .theme-switcher {
|
201
|
-
background: #23272b;
|
202
|
-
color: #f1f1f1;
|
203
|
-
}
|
204
183
|
|
205
184
|
/* Explorer file/dir links */
|
206
185
|
.explorer-link, .explorer-link:visited {
|
@@ -20,7 +20,7 @@ body.light-theme {
|
|
20
20
|
.header {
|
21
21
|
background: #23272b;
|
22
22
|
color: #f1f1f1;
|
23
|
-
padding: 1em 2em;
|
23
|
+
padding: 0.2em 2em 1em 2em;
|
24
24
|
font-size: 1.5em;
|
25
25
|
font-weight: bold;
|
26
26
|
letter-spacing: 0.04em;
|
@@ -183,14 +183,16 @@ body.light-theme .footer a {
|
|
183
183
|
.theme-switcher {
|
184
184
|
position: absolute;
|
185
185
|
right: 20px;
|
186
|
-
top:
|
186
|
+
top: 2px;
|
187
187
|
background: #444;
|
188
188
|
color: #f1f1f1;
|
189
189
|
border: none;
|
190
190
|
border-radius: 4px;
|
191
|
-
padding: 6px
|
191
|
+
padding: 0px 6px;
|
192
|
+
margin-top: -0.2em;
|
193
|
+
margin-bottom: 2px;
|
192
194
|
cursor: pointer;
|
193
|
-
font-size:
|
195
|
+
font-size: 0.85em;
|
194
196
|
transition: background 0.2s, color 0.2s;
|
195
197
|
}
|
196
198
|
body.light-theme .theme-switcher {
|
janito/termweb/static/termweb.js
CHANGED
@@ -154,12 +154,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
154
154
|
// Initial theme
|
155
155
|
var theme = localStorage.getItem('theme') || 'dark';
|
156
156
|
setTheme(theme === 'dark');
|
157
|
-
var themeSwitcher = document.getElementById('theme-switcher');
|
158
|
-
if (themeSwitcher) {
|
159
|
-
themeSwitcher.onclick = function() {
|
160
|
-
setTheme(document.body.classList.contains('light-theme'));
|
161
|
-
};
|
162
|
-
}
|
163
157
|
setExplorerView('list'); // Always use list view
|
164
158
|
renderExplorer('.')
|
165
159
|
});
|
@@ -16,7 +16,6 @@ function getPaiPath(path) {
|
|
16
16
|
function setExplorerView(view) {
|
17
17
|
explorerView = view;
|
18
18
|
localStorage.setItem('explorerView', view);
|
19
|
-
|
20
19
|
}
|
21
20
|
|
22
21
|
function normalizeExplorerPath(path) {
|
@@ -133,7 +132,7 @@ window.renderCodePreview = function(container, content, mode) {
|
|
133
132
|
} catch (e) {
|
134
133
|
container.innerHTML = '<pre>' + (content ? String(content) : '') + '</pre>';
|
135
134
|
}
|
136
|
-
}
|
135
|
+
};
|
137
136
|
|
138
137
|
// Theme switcher logic
|
139
138
|
function setTheme(dark) {
|