using System.ComponentModel; using System.Runtime.CompilerServices; namespace VideoDownloader.Browser; /// T3-15: "파라미터 제거 복사" — 추적용 쿼리·프래그먼트를 뺀 URL 반환. public static class UrlCleaner { public static string? StripQuery(string? url) { if (url == null) return null; var q = url.IndexOf('?'); if (q >= 0) url = url[..q]; var f = url.IndexOf('#'); if (f >= 0) url = url[..f]; return url; } } /// T3-15: 주소창 진행 바 상태 — 진행 중 네비게이션 개수 집계(탭·리다이렉트 중복 안전). public sealed class NavProgressTracker : INotifyPropertyChanged { private int _count; public bool IsNavigating => Volatile.Read(ref _count) > 0; public event PropertyChangedEventHandler? PropertyChanged; public void Started() => Update(1); public void Completed() => Update(-1); private void Update(int delta) { var before = IsNavigating; var c = _count + delta; Volatile.Write(ref _count, Math.Max(0, c)); // 과잉 완료 방지 if (before != IsNavigating) OnPropertyChanged(nameof(IsNavigating)); } private void OnPropertyChanged([CallerMemberName] string? name = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }