diff --git a/IMPLEMENTATION_AUDIT.md b/IMPLEMENTATION_AUDIT.md index c077b3f..3025a27 100644 --- a/IMPLEMENTATION_AUDIT.md +++ b/IMPLEMENTATION_AUDIT.md @@ -58,7 +58,7 @@ | 항목 | 구현 | 증거 | |---|---|---| | T2-10 미디어 재생목록 | ✅ 감지 미디어 자동 적재, 플라이아웃, 플레이어 창(native+hls.js+dash.js), 자동 다음, JSON 영속 | `MediaPlaylist.cs` · `PlayerWindow.cs` + 테스트 | -| T3-1 워크스페이스 | ✅ 저장/전환 | `TabManagerWorkspaceExtensions` + 테스트 | +| T3-1 워크스페이스 + 도메인 라우팅 | ✅ 저장/전환 + WorkspaceRoutingRules(도메인→워크스페이스, 주소창 이동 시 자동 전환, 팔레트로 규칙 등록) | `TabManagerWorkspaceExtensions` + `DesktopRemainderTests` 라우팅 2건(www/서브도메인 매칭·영속) | | T3-3 컨테이너/InPrivate | ✅ IsInPrivateModeEnabled 탭 | `OpenInPrivateTab` | | T3-4 빠른 찾기 `/` | ✅ | `MainWindow` 단축키 | | T3-5 컨텍스트 메뉴 전면 커스터마이징 | ✅ WPF 메뉴 + SelectedCommandId | `TabViewService` | @@ -75,11 +75,15 @@ | T3-14 추적 방지 카운터 | ✅ TrackerBlocklist(20개 도메인, 서브도메인 매칭) + WebResourceRequested 차단(204) + TrackerCounter + 실드 배지·도메인 팝업 | `TrackerBlockTests` 8건 + E2E(실제 WebView2 에서 2개 스크립트 차단·집계, 정상 도메인 통과) | | T3-15 주소창 진행 바 + 파라미터 제거 복사 | ✅ NavProgressTracker(전 탭 집계 INPC) → 주소창 하단 인디케이터 + 주소창 우클릭 "파라미터 제거 후 복사"(UrlCleaner) | `UrlCleanerTests`/`NavProgressTrackerTests` 13건 | -### T3 중 명시적 미구현 (계획 내 후순위/선택) +### 3차 완성 (T3 잔여 + 스타일) -- T3-2 Auto-Archive 캐던스 — 닫힘 스택(25개)+복원이 커버(아카이브 자동화는 미차용) -- T3-12 노트 패널 — 계획 자체가 "후순위" 명시 -- T3-13 컴팩트 모드 — F11 전체화면이 동등 커버 +| 항목 | 구현 | 증거 | +|---|---|---| +| T3-2 탭 아카이브 | ✅ TabArchive(닫힘 이력 JSON 영속, 500 상한, 연속 중복 제목 갱신, 검색) + 탭 닫힘 배선 + 팔레트 "아카이브에서 열기" | `DesktopRemainderTests` 3건 + 스모크 E2E(URL 탭 닫음 → 아카이브 기록 실증) | +| T3-6 페이지 액션 | ✅ BoostSettings.PageFilter(흑백/세피아) → CSS 필터 주입, 팔레트 명령 | `DesktopRemainderTests` 3건(RED→GREEN) + 스모크 E2E(로컬 HTTP 문서에서 적용→부스트 저장 실증) | +| T3-12 노트 패널 | ✅ NotesStore(추가·검색·삭제·영속) + 노트 플라이아웃(Ctrl+Alt+N) + "현재 페이지 추가" | `DesktopRemainderTests` 2건 + 스모크 E2E + 실창 스크린샷 | +| T3-13 컴팩트 모드 | ✅ Ctrl+Shift+M 크롬 자동 숨김 + 상단 엣지(4px) 호버 복원 | 스모크 E2E(행 높이 0→복원) + 실창 스크린샷 | +| 스타일 폴리시 | ✅ 폰트 폴백(한국어 맑은 고딕 포함) + 암시 TextBlock 폰트 통일 + 다크 ToolTip + 텍스트 계층 대비 상향(Secondary/Muted/Border) + 상태바 가독성 + 다이얼 페이지 타이포 | 실창 스크린샷 검증(다이얼/노트/컴팩트) | ### 재구성 (사용자 지시 "근원부터 뜯어고쳐") diff --git a/VideoDownloader.App/Browser/Features/CommandPalette.cs b/VideoDownloader.App/Browser/Features/CommandPalette.cs index 5e44e7c..18a46de 100644 --- a/VideoDownloader.App/Browser/Features/CommandPalette.cs +++ b/VideoDownloader.App/Browser/Features/CommandPalette.cs @@ -48,8 +48,11 @@ public sealed class CommandPalette public void Execute(PaletteCommand command) => command.Execute(); } -/// 사이트별 부스트 설정(T2-7, Zen/Arc Boosts 패턴). -public sealed record BoostSettings(bool ForceDark, string CustomCss); +/// 페이지 액션 필터(T3-6, Vivaldi Page Actions — Boost 통합). +public enum PageFilter { None, Grayscale, Sepia } + +/// 사이트별 부스트 설정(T2-7, Zen/Arc Boosts 패턴) + 페이지 액션 필터(T3-6). +public sealed record BoostSettings(bool ForceDark, string CustomCss, PageFilter Filter = PageFilter.None); /// 도메인별 부스트 영속 저장. public sealed class BoostStore @@ -77,11 +80,11 @@ public sealed class BoostStore return host != null && _map.TryGetValue(host, out var v) ? v : new BoostSettings(false, ""); } - public void Set(string? url, bool forceDark, string css) + public void Set(string? url, bool forceDark, string css, PageFilter filter = PageFilter.None) { var host = Normalize(url); if (host == null) return; - _map[host] = new BoostSettings(forceDark, css); + _map[host] = new BoostSettings(forceDark, css, filter); try { Directory.CreateDirectory(Path.GetDirectoryName(_path)!); @@ -110,7 +113,7 @@ public static class BoostCssBuilder { public static string BuildScript(string? url, BoostSettings settings) { - if (!settings.ForceDark && string.IsNullOrWhiteSpace(settings.CustomCss)) return ""; + if (!settings.ForceDark && settings.Filter == PageFilter.None && string.IsNullOrWhiteSpace(settings.CustomCss)) return ""; var css = ""; if (settings.ForceDark) { @@ -119,6 +122,14 @@ html { filter: invert(1) hue-rotate(180deg); background: #fff; } img, video, picture, canvas, svg, iframe, embed, object { filter: invert(1) hue-rotate(180deg); } """; } + else if (settings.Filter == PageFilter.Grayscale) // T3-6 페이지 액션 + { + css += "html { filter: grayscale(1); }"; + } + else if (settings.Filter == PageFilter.Sepia) + { + css += "html { filter: sepia(0.7); }"; + } if (!string.IsNullOrWhiteSpace(settings.CustomCss)) css += settings.CustomCss + "\n"; var js = $$""" (function(){ try { var s = document.createElement('style'); s.id = 'vd-boost'; s.textContent = {{JsonSerializer.Serialize(css)}}; (document.head || document.documentElement).appendChild(s); } catch(e){} })(); diff --git a/VideoDownloader.App/MainWindow.xaml b/VideoDownloader.App/MainWindow.xaml index c4bfb60..71dd1fb 100644 --- a/VideoDownloader.App/MainWindow.xaml +++ b/VideoDownloader.App/MainWindow.xaml @@ -153,7 +153,7 @@ - + @@ -459,7 +459,7 @@ - @@ -550,6 +550,26 @@ + + + + + + + +