Fix keyboard shortcut scoping; add tab switching with Ctrl+Alt+PgUp/Down
- Use sentinel element to properly clean up detail view Ctrl+E listener - Single document listener per view handles all shortcuts regardless of focus - Ctrl+S/D now work from preview tab and title input without separate listeners - Ctrl+Alt+PageUp/Down switches Write/Preview tabs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -656,15 +656,18 @@ function render_entry_detail(container) {
|
|||||||
const et = state.entry_types.find(t => t.id === entry.type);
|
const et = state.entry_types.find(t => t.id === entry.type);
|
||||||
const back_hash = 'type/' + entry.type;
|
const back_hash = 'type/' + entry.type;
|
||||||
|
|
||||||
|
const sentinel = document.createElement('div');
|
||||||
const on_keydown = e => {
|
const on_keydown = e => {
|
||||||
if (e.ctrlKey && e.key === 'e') { e.preventDefault(); navigate('edit/' + entry.id); }
|
if (e.ctrlKey && e.key === 'e') { e.preventDefault(); navigate('edit/' + entry.id); }
|
||||||
};
|
};
|
||||||
document.addEventListener('keydown', on_keydown);
|
document.addEventListener('keydown', on_keydown);
|
||||||
const observer = new MutationObserver(() => {
|
const observer = new MutationObserver(() => {
|
||||||
if (!container.isConnected) { document.removeEventListener('keydown', on_keydown); observer.disconnect(); }
|
if (!sentinel.isConnected) { document.removeEventListener('keydown', on_keydown); observer.disconnect(); }
|
||||||
});
|
});
|
||||||
observer.observe(document.body, { childList: true, subtree: true });
|
observer.observe(document.body, { childList: true, subtree: true });
|
||||||
|
|
||||||
|
container.appendChild(sentinel);
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
const header = document.createElement('div');
|
const header = document.createElement('div');
|
||||||
header.className = 'detail-header';
|
header.className = 'detail-header';
|
||||||
@@ -843,6 +846,13 @@ function render_edit_view(container) {
|
|||||||
tab_bar.appendChild(write_tab);
|
tab_bar.appendChild(write_tab);
|
||||||
tab_bar.appendChild(preview_tab);
|
tab_bar.appendChild(preview_tab);
|
||||||
|
|
||||||
|
const tabs = [write_tab, preview_tab];
|
||||||
|
function switch_tab(dir) {
|
||||||
|
const current = tabs.findIndex(t => t.classList.contains('active'));
|
||||||
|
const next = (current + dir + tabs.length) % tabs.length;
|
||||||
|
tabs[next].click();
|
||||||
|
}
|
||||||
|
|
||||||
// CodeMirror editor
|
// CodeMirror editor
|
||||||
const cm_host = document.createElement('div');
|
const cm_host = document.createElement('div');
|
||||||
cm_host.className = 'edit-cm-host';
|
cm_host.className = 'edit-cm-host';
|
||||||
@@ -861,8 +871,6 @@ function render_edit_view(container) {
|
|||||||
...defaultKeymap,
|
...defaultKeymap,
|
||||||
...historyKeymap,
|
...historyKeymap,
|
||||||
indentWithTab,
|
indentWithTab,
|
||||||
{ key: 'Ctrl-s', mac: 'Cmd-s', run: () => { save_btn.click(); return true; } },
|
|
||||||
{ key: 'Ctrl-d', run: () => { cancel_btn.click(); return true; } },
|
|
||||||
]),
|
]),
|
||||||
EditorView.lineWrapping,
|
EditorView.lineWrapping,
|
||||||
placeholder('Body (markdown)'),
|
placeholder('Body (markdown)'),
|
||||||
@@ -909,10 +917,18 @@ function render_edit_view(container) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Ctrl+S on title input
|
// Ctrl+S on title input
|
||||||
title_input.addEventListener('keydown', e => {
|
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); save_btn.click(); }
|
const on_edit_keydown = e => {
|
||||||
if ((e.ctrlKey || e.metaKey) && e.key === 'd') { e.preventDefault(); cancel_btn.click(); }
|
if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); save_btn.click(); }
|
||||||
|
if ((e.ctrlKey || e.metaKey) && e.key === 'd') { e.preventDefault(); cancel_btn.click(); }
|
||||||
|
if (e.ctrlKey && e.altKey && e.key === 'PageUp') { e.preventDefault(); switch_tab(-1); }
|
||||||
|
if (e.ctrlKey && e.altKey && e.key === 'PageDown') { e.preventDefault(); switch_tab(+1); }
|
||||||
|
};
|
||||||
|
document.addEventListener('keydown', on_edit_keydown);
|
||||||
|
const edit_observer = new MutationObserver(() => {
|
||||||
|
if (!view.isConnected) { document.removeEventListener('keydown', on_edit_keydown); edit_observer.disconnect(); }
|
||||||
});
|
});
|
||||||
|
edit_observer.observe(document.body, { childList: true, subtree: true });
|
||||||
|
|
||||||
// --- Sidebar ---
|
// --- Sidebar ---
|
||||||
const sidebar = document.createElement('div');
|
const sidebar = document.createElement('div');
|
||||||
|
|||||||
Reference in New Issue
Block a user