feat: 워크스페이스 편의 개선 + 매뉴얼에 화면구성·단축키 페이지 추가
워크스페이스(탭) - 탭 전환 시 좌측 사이드바(대메뉴/소메뉴) 강조 자동 동기화 - nav 스크립트에 window.govPortalNav.syncByUrl() 공개, renderSidebar(overrideHref) 확장 - 키보드 단축키(Alt 기반): Alt+1~9 탭 이동, Alt+W 닫기, Alt+[ / Alt+] 이전·다음 - iframe 내부 포커스에서도 동작하도록 같은 출처 문서에 핸들러 부착 - 탭 가운데(휠) 클릭으로 닫기, 잘린 탭 제목 전체 툴팁 매뉴얼 - 신규 페이지 [화면 구성·워크스페이스·단축키] (05_workspace.md, 목차 2번째) - 화면 구성, 탭 사용법·유지 범위, 단축키 표, 이동/도움말 안내 - 개요 페이지에서 새 페이지로 안내 e2e: 워크스페이스(사이드바 동기화·가운데클릭) + 매뉴얼(새 페이지·단축키·검색) 케이스 추가 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -124,6 +124,8 @@ if ($effectiveLgIdx) {
|
||||
tabs[k].btn.classList.toggle('active', k === id);
|
||||
});
|
||||
if (empty) empty.style.display = 'none';
|
||||
// 현재 탭에 맞춰 좌측 사이드바(대메뉴/소메뉴) 강조 동기화
|
||||
try { if (window.govPortalNav && tabs[id]) window.govPortalNav.syncByUrl(tabs[id].url); } catch (e) {}
|
||||
persist();
|
||||
}
|
||||
|
||||
@@ -155,11 +157,16 @@ if ($effectiveLgIdx) {
|
||||
frame.className = 'ws-frame';
|
||||
frame.src = withEmbed(url);
|
||||
frame.setAttribute('title', title || '탭');
|
||||
// iframe 내부에 포커스가 있어도 단축키가 동작하도록 같은 출처 문서에 핸들러 부착
|
||||
frame.addEventListener('load', function () {
|
||||
try { frame.contentDocument.addEventListener('keydown', handleShortcut); } catch (e) {}
|
||||
});
|
||||
panels.appendChild(frame);
|
||||
|
||||
var btn = document.createElement('div');
|
||||
btn.className = 'ws-tab';
|
||||
btn.setAttribute('role', 'tab');
|
||||
btn.title = title || '탭'; // 잘린 이름 전체를 툴팁으로
|
||||
var nameSpan = document.createElement('span');
|
||||
nameSpan.className = 't-name';
|
||||
nameSpan.textContent = title || '탭';
|
||||
@@ -177,6 +184,9 @@ if ($effectiveLgIdx) {
|
||||
else if (e.target === refresh) { activate(id); reloadTab(id); }
|
||||
else { activate(id); }
|
||||
});
|
||||
// 가운데(휠) 클릭으로 탭 닫기 — 브라우저 탭과 동일한 동작
|
||||
btn.addEventListener('mousedown', function (e) { if (e.button === 1) e.preventDefault(); });
|
||||
btn.addEventListener('auxclick', function (e) { if (e.button === 1) { e.preventDefault(); closeTab(id); } });
|
||||
bar.appendChild(btn);
|
||||
|
||||
tabs[id] = { url: url, title: title, frame: frame, btn: btn };
|
||||
@@ -185,6 +195,26 @@ if ($effectiveLgIdx) {
|
||||
}
|
||||
window.wsOpenTab = openTab;
|
||||
|
||||
// 키보드 단축키 (브라우저 기본 단축키와 충돌하지 않도록 Alt 기반)
|
||||
// Alt+1~9: 해당 번호 탭으로 · Alt+W: 현재 탭 닫기 · Alt+[ / Alt+]: 이전/다음 탭
|
||||
function handleShortcut(e) {
|
||||
if (!e.altKey || e.ctrlKey || e.metaKey) return;
|
||||
var k = e.key;
|
||||
if (k >= '1' && k <= '9') {
|
||||
var i = parseInt(k, 10) - 1;
|
||||
if (order[i]) { e.preventDefault(); activate(order[i]); }
|
||||
} else if (k === 'w' || k === 'W' || k === 'ㅈ') {
|
||||
if (activeId) { e.preventDefault(); closeTab(activeId); }
|
||||
} else if (k === '[' || k === ']') {
|
||||
if (!activeId || order.length < 2) return;
|
||||
e.preventDefault();
|
||||
var cur = order.indexOf(activeId);
|
||||
var nx = k === ']' ? (cur + 1) % order.length : (cur - 1 + order.length) % order.length;
|
||||
activate(order[nx]);
|
||||
}
|
||||
}
|
||||
document.addEventListener('keydown', handleShortcut);
|
||||
|
||||
// 좌측 사이드바 소메뉴 클릭 → 탭으로 열기 (전체 페이지 이동 대신)
|
||||
document.querySelector('.sidebar').addEventListener('click', function (e) {
|
||||
var a = e.target.closest('a[href]');
|
||||
|
||||
Reference in New Issue
Block a user