diff --git a/SLBr/App.xaml.cs b/SLBr/App.xaml.cs index 4d8ad27..de88e0c 100644 --- a/SLBr/App.xaml.cs +++ b/SLBr/App.xaml.cs @@ -2,7 +2,9 @@ using CefSharp.SchemeHandler; using CefSharp.Wpf.HwndHost; using Microsoft.Win32; +using SLBr.Controls; using SLBr.Handlers; +using SLBr.Pages; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; @@ -184,27 +186,6 @@ public ObservableCollection GlobalHistory RaisePropertyChanged("GlobalHistory"); } } - private ObservableCollection PrivateCompletedDownloads = new ObservableCollection(); - public ObservableCollection CompletedDownloads - { - get { return PrivateCompletedDownloads; } - set - { - PrivateCompletedDownloads = value; - /*Dispatcher.Invoke(() => - { - foreach (MainWindow _Window in AllWindows) - { - foreach (BrowserTabItem _Tab in _Window.Tabs) - { - if (_Tab.Content != null) - _Tab.Content.OpenDownloadsButton.Visibility = Visibility.Visible; - } - } - });*/ - RaisePropertyChanged("CompletedDownloads"); - } - } private ObservableCollection PrivateExtensions = new ObservableCollection(); public ObservableCollection Extensions { @@ -212,6 +193,33 @@ public ObservableCollection Extensions set { PrivateExtensions = value; + Dispatcher.Invoke(() => + { + switch (int.Parse(GlobalSave.Get("ExtensionButton"))) + { + case 0: + foreach (MainWindow _Window in AllWindows) + { + foreach (Browser BrowserView in _Window.Tabs.Select(i => i.Content)) + BrowserView.ExtensionsButton.Visibility = value.Any() ? Visibility.Visible : Visibility.Collapsed; + } + break; + case 1: + foreach (MainWindow _Window in AllWindows) + { + foreach (Browser BrowserView in _Window.Tabs.Select(i => i.Content)) + BrowserView.ExtensionsButton.Visibility = Visibility.Visible; + } + break; + case 2: + foreach (MainWindow _Window in AllWindows) + { + foreach (Browser BrowserView in _Window.Tabs.Select(i => i.Content)) + BrowserView.ExtensionsButton.Visibility = Visibility.Collapsed; + } + break; + } + }); RaisePropertyChanged("Extensions"); } } @@ -224,24 +232,12 @@ public void AddGlobalHistory(string Url, string Title) GlobalHistory.Remove(HistoryEntry); GlobalHistory.Insert(0, HistoryEntry); } - private Dictionary PrivateDownloads = new Dictionary(); - public Dictionary Downloads - { - get { return PrivateDownloads; } - set - { - PrivateDownloads = value; - RaisePropertyChanged("Downloads"); - } - } - public FastHashSet CanceledDownloads = new FastHashSet(); + public Dictionary Downloads = new Dictionary(); public void UpdateDownloadItem(DownloadItem item) { Downloads[item.Id] = item; Dispatcher.Invoke(() => { - if (item.IsComplete) - CompletedDownloads.Add(new ActionStorage(Path.GetFileName(item.FullPath), "5<,>slbr://downloads/", "")); foreach (MainWindow _Window in AllWindows) _Window.TaskbarProgress.ProgressValue = item.IsComplete ? 0 : item.PercentComplete / 100.0; }); @@ -258,102 +254,108 @@ protected override void OnStartup(StartupEventArgs e) [DllImport("shell32.dll", SetLastError = true)] static extern void SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID); + public string UserAgent; + public void LoadExtensions() { - //Extensions.Clear(); + Extensions.Clear(); if (Directory.Exists(ExtensionsPath)) { var ExtensionsDirectory = Directory.GetDirectories(ExtensionsPath); if (ExtensionsDirectory.Length != 0) { - ObservableCollection _Extensions = new ObservableCollection(); + //ObservableCollection _Extensions = new ObservableCollection(); foreach (var ExtensionParentDirectory in ExtensionsDirectory) { - string ExtensionDirectory = Directory.EnumerateDirectories(ExtensionParentDirectory).FirstOrDefault(); - if (Directory.Exists(ExtensionDirectory)) + try { - string[] Manifests = Directory.GetFiles(ExtensionDirectory, "manifest.json", SearchOption.TopDirectoryOnly); - foreach (string ManifestFile in Manifests) + string ExtensionDirectory = Directory.EnumerateDirectories(ExtensionParentDirectory).FirstOrDefault(); + if (Directory.Exists(ExtensionDirectory)) { - JsonElement Manifest = JsonDocument.Parse(File.ReadAllText(ManifestFile)).RootElement; - - Extension _Extension = new Extension() { ID = Path.GetFileName(ExtensionParentDirectory), Version = Manifest.GetProperty("version").ToString()/*, ManifestVersion = Manifest.GetProperty("manifest_version").ToString()*/ }; - - if (Manifest.TryGetProperty("action", out JsonElement ExtensionAction)) + string[] Manifests = Directory.GetFiles(ExtensionDirectory, "manifest.json", SearchOption.TopDirectoryOnly); + foreach (string ManifestFile in Manifests) { - if (ExtensionAction.TryGetProperty("default_popup", out JsonElement ExtensionPopup)) - _Extension.Popup = $"chrome-extension://{_Extension.ID}/{ExtensionPopup.GetString()}"; - /*else if (ExtensionAction.TryGetProperty("default_icon", out JsonElement defaultIconValue)) - { - var firstIcon = defaultIconValue.EnumerateObject().OrderBy(kvp => int.Parse(kvp.Name)).FirstOrDefault(); - _Extension.Icon = $"chrome-extension://{ExtensionID}/{firstIcon.Value.GetString()}"; - }*/ - } - List VarsInMessages = new List(); - if (Manifest.TryGetProperty("name", out JsonElement ExtensionName)) - { - string Name = ExtensionName.GetString(); - if (Name.StartsWith("__MSG_")) - VarsInMessages.Add($"Name<|>{Name}"); - else - _Extension.Name = Name; - } - if (Manifest.TryGetProperty("description", out JsonElement ExtensionDescription)) - { - string Description = ExtensionDescription.GetString(); - if (Description.StartsWith("__MSG_")) - VarsInMessages.Add($"Description<|>{Description}"); - else - _Extension.Description = Description; - } + JsonElement Manifest = JsonDocument.Parse(File.ReadAllText(ManifestFile)).RootElement; - foreach (string Var in VarsInMessages) - { - string _Locale = "en"; - string[] LocalesDirectory = Directory.GetDirectories(Path.Combine(ExtensionDirectory, "_locales")); - foreach (string LocaleDirectory in LocalesDirectory) + Extension _Extension = new Extension() { ID = Path.GetFileName(ExtensionParentDirectory), Version = Manifest.GetProperty("version").ToString()/*, ManifestVersion = Manifest.GetProperty("manifest_version").ToString()*/ }; + + if (Manifest.TryGetProperty("action", out JsonElement ExtensionAction)) { - string CompareLocale = Locale.Name.Replace("-", "_"); - if (Path.GetFileName(LocaleDirectory) == CompareLocale) + if (ExtensionAction.TryGetProperty("default_popup", out JsonElement ExtensionPopup)) + _Extension.Popup = $"chrome-extension://{_Extension.ID}/{ExtensionPopup.GetString()}"; + /*else if (ExtensionAction.TryGetProperty("default_icon", out JsonElement defaultIconValue)) { - _Locale = CompareLocale; - break; - } + var firstIcon = defaultIconValue.EnumerateObject().OrderBy(kvp => int.Parse(kvp.Name)).FirstOrDefault(); + _Extension.Icon = $"chrome-extension://{ExtensionID}/{firstIcon.Value.GetString()}"; + }*/ + } + List VarsInMessages = new List(); + if (Manifest.TryGetProperty("name", out JsonElement ExtensionName)) + { + string Name = ExtensionName.GetString(); + if (Name.StartsWith("__MSG_")) + VarsInMessages.Add($"Name<|>{Name}"); + else + _Extension.Name = Name; + } + if (Manifest.TryGetProperty("description", out JsonElement ExtensionDescription)) + { + string Description = ExtensionDescription.GetString(); + if (Description.StartsWith("__MSG_")) + VarsInMessages.Add($"Description<|>{Description}"); + else + _Extension.Description = Description; } - string[] MessagesFiles = Directory.GetFiles(Path.Combine(ExtensionDirectory, "_locales", _Locale), "messages.json", SearchOption.TopDirectoryOnly); - foreach (string MessagesFile in MessagesFiles) + + foreach (string Var in VarsInMessages) { - JsonElement Messages = JsonDocument.Parse(File.ReadAllText(MessagesFile)).RootElement; - string[] Vars = Var.Split("<|>"); - if (Vars[0] == "Description") + string _Locale = "en"; + string[] LocalesDirectory = Directory.GetDirectories(Path.Combine(ExtensionDirectory, "_locales")); + foreach (string LocaleDirectory in LocalesDirectory) { - _Extension.Description = Messages.GetProperty(Vars[1].Remove(0, 5).Trim('_')).GetProperty("message").ToString(); - break; + string CompareLocale = Locale.Name.Replace("-", "_"); + if (Path.GetFileName(LocaleDirectory) == CompareLocale) + { + _Locale = CompareLocale; + break; + } } - else if (Vars[0] == "Name") + string[] MessagesFiles = Directory.GetFiles(Path.Combine(ExtensionDirectory, "_locales", _Locale), "messages.json", SearchOption.TopDirectoryOnly); + foreach (string MessagesFile in MessagesFiles) { - _Extension.Name = Messages.GetProperty(Vars[1].Remove(0, 5).Trim('_')).GetProperty("message").ToString(); - break; + JsonElement Messages = JsonDocument.Parse(File.ReadAllText(MessagesFile)).RootElement; + string[] Vars = Var.Split("<|>"); + if (Vars[0] == "Description") + { + _Extension.Description = Messages.GetProperty(Vars[1].Remove(0, 5).Trim('_')).GetProperty("message").ToString(); + break; + } + else if (Vars[0] == "Name") + { + _Extension.Name = Messages.GetProperty(Vars[1].Remove(0, 5).Trim('_')).GetProperty("message").ToString(); + break; + } } } - } - //_Extension.IsEnabled = true; - _Extensions.Add(_Extension); + //_Extension.IsEnabled = true; + Extensions.Add(_Extension); + } } } + catch { } } - Extensions = _Extensions; + //Extensions = _Extensions; } } } private void InitializeApp() { - string[] Args = Environment.GetCommandLineArgs().Skip(1).ToArray(); + IEnumerable Args = Environment.GetCommandLineArgs().Skip(1); string AppUserModelID = "{ab11da56-fbdf-4678-916e-67e165b21f30}"; string CommandLineUrl = ""; - if (Args.Length > 0) + if (Args.Any()) { foreach (string Flag in Args) { @@ -384,10 +386,10 @@ private void InitializeApp() } else { - Process _otherInstance = Utils.GetAlreadyRunningInstance(Process.GetCurrentProcess()); - if (_otherInstance != null) + Process OtherInstance = Utils.GetAlreadyRunningInstance(Process.GetCurrentProcess()); + if (OtherInstance != null) { - MessageHelper.SendDataMessage(_otherInstance, CommandLineUrl); + MessageHelper.SendDataMessage(OtherInstance, CommandLineUrl); Shutdown(1); Environment.Exit(0); return; @@ -409,22 +411,23 @@ private void InitializeApp() ExecutablePath = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".exe"); ExtensionsPath = Path.Combine(UserApplicationDataPath, "User Data", "Default", "Extensions"); + UserAgent = UserAgentGenerator.BuildUserAgentFromProduct($"SLBr/{ReleaseVersion} {UserAgentGenerator.BuildChromeBrand()}"); + InitializeSaves(); - InitializeCEF(); InitializeUISaves(CommandLineUrl); if (Utils.IsAdministrator()) { - using (var checkkey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\RegisteredApplications", true)) + using (var CheckKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\RegisteredApplications", true)) { - if (checkkey.GetValue("SLBr") == null) + if (CheckKey.GetValue("SLBr") == null) { - using (var key = Registry.ClassesRoot.CreateSubKey("SLBr", true)) + using (var Key = Registry.ClassesRoot.CreateSubKey("SLBr", true)) { - key.SetValue(null, "SLBr Document"); - key.SetValue("AppUserModelId", "SLBr"); + Key.SetValue(null, "SLBr Document"); + Key.SetValue("AppUserModelId", "SLBr"); - RegistryKey ApplicationRegistry = key.CreateSubKey("Application", true); + RegistryKey ApplicationRegistry = Key.CreateSubKey("Application", true); ApplicationRegistry.SetValue("AppUserModelId", "SLBr"); ApplicationRegistry.SetValue("ApplicationIcon", $"{ExecutablePath},0"); ApplicationRegistry.SetValue("ApplicationName", "SLBr"); @@ -432,20 +435,20 @@ private void InitializeApp() ApplicationRegistry.SetValue("ApplicationDescription", "Browse the web with a fast, lightweight web browser."); ApplicationRegistry.Close(); - RegistryKey IconRegistry = key.CreateSubKey("DefaultIcon", true); + RegistryKey IconRegistry = Key.CreateSubKey("DefaultIcon", true); IconRegistry.SetValue(null, $"{ExecutablePath},0"); ApplicationRegistry.Close(); - RegistryKey CommandRegistry = key.CreateSubKey("shell\\open\\command", true); + RegistryKey CommandRegistry = Key.CreateSubKey("shell\\open\\command", true); CommandRegistry.SetValue(null, $"\"{ExecutablePath}\" \"%1\""); CommandRegistry.Close(); } - using (var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Clients\\StartMenuInternet", true).CreateSubKey("SLBr", true)) + using (var Key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Clients\\StartMenuInternet", true).CreateSubKey("SLBr", true)) { - if (key.GetValue(null) as string != "SLBr") - key.SetValue(null, "SLBr"); + if (Key.GetValue(null) as string != "SLBr") + Key.SetValue(null, "SLBr"); - RegistryKey CapabilitiesRegistry = key.CreateSubKey("Capabilities", true); + RegistryKey CapabilitiesRegistry = Key.CreateSubKey("Capabilities", true); CapabilitiesRegistry.SetValue("ApplicationDescription", "Browse the web with a fast, lightweight web browser."); CapabilitiesRegistry.SetValue("ApplicationIcon", $"{ExecutablePath},0"); CapabilitiesRegistry.SetValue("ApplicationName", $"SLBr"); @@ -471,18 +474,19 @@ private void InitializeApp() CapabilitiesRegistry.Close(); - RegistryKey DefaultIconRegistry = key.CreateSubKey("DefaultIcon", true); + RegistryKey DefaultIconRegistry = Key.CreateSubKey("DefaultIcon", true); DefaultIconRegistry.SetValue(null, $"{ExecutablePath},0"); DefaultIconRegistry.Close(); - RegistryKey CommandRegistry = key.CreateSubKey("shell\\open\\command", true); + RegistryKey CommandRegistry = Key.CreateSubKey("shell\\open\\command", true); CommandRegistry.SetValue(null, $"\"{ExecutablePath}\""); CommandRegistry.Close(); } - checkkey.SetValue("SLBr", "Software\\Clients\\StartMenuInternet\\SLBr\\Capabilities"); + CheckKey.SetValue("SLBr", "Software\\Clients\\StartMenuInternet\\SLBr\\Capabilities"); } } } + InitializeCEF(); AppInitialized = true; } @@ -496,19 +500,20 @@ private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTas { if (bool.Parse(GlobalSave.Get("SendDiagnostics"))) - DiscordWebhookSendInfo(string.Format(ReportExceptionText, ReleaseVersion, Cef.CefVersion, (Environment.Is64BitProcess ? "x64" : "x86"), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); + DiscordWebhookSendInfo(string.Format(ReportExceptionText, ReleaseVersion, Cef.CefVersion, RuntimeInformation.ProcessArchitecture.ToString(), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); //e.SetObserved(); - MessageBox.Show(string.Format(ExceptionText, ReleaseVersion, Cef.CefVersion, (Environment.Is64BitProcess ? "x64" : "x86"), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); + MessageBox.Show(string.Format(ExceptionText, ReleaseVersion, Cef.CefVersion, RuntimeInformation.ProcessArchitecture.ToString(), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); } private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { + //MessageBox.Show(e.ExceptionObject.ToString()); Exception _Exception = e.ExceptionObject as Exception; if (bool.Parse(GlobalSave.Get("SendDiagnostics"))) - DiscordWebhookSendInfo(string.Format(ReportExceptionText, ReleaseVersion, Cef.CefVersion, (Environment.Is64BitProcess ? "x64" : "x86"), _Exception.Message, _Exception.Source, _Exception.TargetSite, _Exception.StackTrace, _Exception.InnerException)); + DiscordWebhookSendInfo(string.Format(ReportExceptionText, ReleaseVersion, Cef.CefVersion, RuntimeInformation.ProcessArchitecture.ToString(), _Exception.Message, _Exception.Source, _Exception.TargetSite, _Exception.StackTrace, _Exception.InnerException)); - MessageBox.Show(string.Format(ExceptionText, ReleaseVersion, Cef.CefVersion, (Environment.Is64BitProcess ? "x64" : "x86"), _Exception.Message, _Exception.Source, _Exception.TargetSite, _Exception.StackTrace, _Exception.InnerException)); + MessageBox.Show(string.Format(ExceptionText, ReleaseVersion, Cef.CefVersion, RuntimeInformation.ProcessArchitecture.ToString(), _Exception.Message, _Exception.Source, _Exception.TargetSite, _Exception.StackTrace, _Exception.InnerException)); } string ExceptionText = @"[SLBr] {0} @@ -537,9 +542,9 @@ [Stack Trace] {6} private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { if (bool.Parse(GlobalSave.Get("SendDiagnostics"))) - DiscordWebhookSendInfo(string.Format(ReportExceptionText, ReleaseVersion, Cef.CefVersion, (Environment.Is64BitProcess ? "x64" : "x86"), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); + DiscordWebhookSendInfo(string.Format(ReportExceptionText, ReleaseVersion, Cef.CefVersion, RuntimeInformation.ProcessArchitecture.ToString(), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); - MessageBox.Show(string.Format(ExceptionText, ReleaseVersion, Cef.CefVersion, (Environment.Is64BitProcess ? "x64" : "x86"), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); + MessageBox.Show(string.Format(ExceptionText, ReleaseVersion, Cef.CefVersion, RuntimeInformation.ProcessArchitecture.ToString(), e.Exception.Message, e.Exception.Source, e.Exception.TargetSite, e.Exception.StackTrace, e.Exception.InnerException)); } public int TrackersBlocked; public int AdsBlocked; @@ -597,7 +602,7 @@ public ObservableCollection Languages set { PrivateLanguages = value; - RaisePropertyChanged("CompletedDownloads"); + RaisePropertyChanged("Languages"); } } public ActionStorage Locale; @@ -776,7 +781,8 @@ private void InitializeSaves() "http://duckduckgo.com/?q={0}", /*"http://search.brave.com/search?q={0}", "http://search.yahoo.com/search?p={0}", - "http://yandex.com/search/?text={0}",*/ + "http://yandex.com/search/?text={0}", + "https://www.qwant.com/?q="*/ }; if (LanguagesSave.Has("Count") && int.Parse(LanguagesSave.Get("Count")) != 0) @@ -809,8 +815,6 @@ private void InitializeSaves() if (!GlobalSave.Has("Homepage")) GlobalSave.Set("Homepage", "slbr://newtab"); - if (!GlobalSave.Has("Theme")) - GlobalSave.Set("Theme", "Auto"); TrackersBlocked = int.Parse(StatisticsSave.Get("BlockedTrackers", "0")); AdsBlocked = int.Parse(StatisticsSave.Get("BlockedAds", "0")); @@ -848,8 +852,10 @@ private void InitializeSaves() if (!GlobalSave.Has("ScreenshotFormat")) GlobalSave.Set("ScreenshotFormat", "Jpeg"); - if (!GlobalSave.Has("RestoreTabs")) - GlobalSave.Set("RestoreTabs", true); + //if (!GlobalSave.Has("RestoreTabs")) + // GlobalSave.Set("RestoreTabs", true); + if (!GlobalSave.Has("DownloadFavicons")) + GlobalSave.Set("DownloadFavicons", true); if (!GlobalSave.Has("SmoothScroll")) GlobalSave.Set("SmoothScroll", true); @@ -876,9 +882,6 @@ private void InitializeSaves() if (!GlobalSave.Has("FingerprintLevel")) GlobalSave.Set("FingerprintLevel", "Minimal"); - if (!GlobalSave.Has("FlagEmoji")) - GlobalSave.Set("FlagEmoji", false); - /*if (!GlobalSave.Has("DefaultBrowserEngine")) GlobalSave.Set("DefaultBrowserEngine", 0);*/ try @@ -890,7 +893,6 @@ private void InitializeSaves() { Themes.Add(new Theme("Auto", Themes[1])); } - SetAppearance(GetTheme(GlobalSave.Get("Theme", "Auto")), GlobalSave.Get("TabAlignment", "Horizontal"), bool.Parse(GlobalSave.Get("HomeButton", true.ToString())), bool.Parse(GlobalSave.Get("TranslateButton", true.ToString())), bool.Parse(GlobalSave.Get("AIButton", true.ToString())), bool.Parse(GlobalSave.Get("ReaderButton", false.ToString()))); } private void InitializeUISaves(string CommandLineUrl = "") { @@ -908,25 +910,27 @@ private void InitializeUISaves(string CommandLineUrl = "") Favourites.Add(new ActionStorage(Value[1], $"4<,>{Value[0]}", Value[0])); } } - if (bool.Parse(GlobalSave.Get("RestoreTabs"))) + SetAppearance(GetTheme(GlobalSave.Get("Theme", "Auto")), GlobalSave.Get("TabAlignment", "Horizontal"), bool.Parse(GlobalSave.Get("HomeButton", true.ToString())), bool.Parse(GlobalSave.Get("TranslateButton", true.ToString())), bool.Parse(GlobalSave.Get("AIButton", true.ToString())), bool.Parse(GlobalSave.Get("ReaderButton", false.ToString())), int.Parse(GlobalSave.Get("ExtensionButton", "0")), int.Parse(GlobalSave.Get("FavouritesBar", "0"))); + if (bool.Parse(GlobalSave.Get("RestoreTabs", true.ToString()))) { for (int t = 0; t < WindowsSaves.Count; t++) { - Saving TabsSave = WindowsSaves[t]; MainWindow _Window = new MainWindow(); + _Window.Show(); + Saving TabsSave = WindowsSaves[t]; if (int.Parse(TabsSave.Get("Count", "0")) > 0) { for (int i = 0; i < int.Parse(TabsSave.Get("Count")); i++) { string Url = TabsSave.Get(i.ToString()); - if (Url != "NOTFOUND") - _Window.NewTab(Url); + //if (Url != "NOTFOUND") + _Window.NewTab(Url); } _Window.TabsUI.SelectedIndex = int.Parse(TabsSave.Get("Selected", 0.ToString())); } else _Window.NewTab(GlobalSave.Get("Homepage")); - _Window.Show(); + _Window.TabsUI.Visibility = Visibility.Visible; } } if (!string.IsNullOrEmpty(CommandLineUrl)) @@ -988,6 +992,7 @@ public void NewWindow() private void InitializeCEF() { + //return; _LifeSpanHandler = new LifeSpanHandler(false); _DownloadHandler = new DownloadHandler(); _RequestHandler = new RequestHandler(); @@ -1073,14 +1078,13 @@ private void InitializeCEF() }); } - bool ChromeRuntime = true; - Settings.ChromeRuntime = ChromeRuntime; CefSharpSettings.RuntimeStyle = CefRuntimeStyle.Chrome; Cef.Initialize(Settings); Cef.UIThreadTaskFactory.StartNew(delegate { var GlobalRequestContext = Cef.GetGlobalRequestContext(); bool PDFViewerExtension = bool.Parse(GlobalSave.Get("PDFViewerExtension")); + /*string _Preferences = ""; foreach (KeyValuePair e in GlobalRequestContext.GetAllPreferences(true)) _Preferences = GetPreferencesString(_Preferences, "", e); @@ -1089,54 +1093,61 @@ private void InitializeCEF() outputFile.Write(_Preferences);*/ string Error; - if (ChromeRuntime) - { - GlobalRequestContext.SetPreference("download_bubble_enabled", false, out Error); - GlobalRequestContext.SetPreference("shopping_list_enabled.enabled", false, out Error); - //GlobalRequestContext.SetPreference("browser_labs_enabled", false, out Error); - //GlobalRequestContext.SetPreference("allow_dinosaur_easter_egg", false, out Error); - //GlobalRequestContext.SetPreference("feedback_allowed", false, out Error); - //GlobalRequestContext.SetPreference("ntp.promo_visible", false, out Error); - //GlobalRequestContext.SetPreference("ntp.shortcust_visible", false, out Error); - //GlobalRequestContext.SetPreference("ntp_snippets.enable", false, out Error); - //GlobalRequestContext.SetPreference("ntp_snippets_by_dse.enable", false, out Error); - //GlobalRequestContext.SetPreference("search.suggest_enabled", false, out Error); - //GlobalRequestContext.SetPreference("side_search.enabled", false, out Error); - - //GlobalRequestContext.SetPreference("https_only_mode_enabled", true, out Error); - } - //GlobalRequestContext.SetPreference("enable_do_not_track", bool.Parse(GlobalSave.Get("DoNotTrack")), out errorMessage); + GlobalRequestContext.SetPreference("autofill.credit_card_enabled", false, out Error); + GlobalRequestContext.SetPreference("autofill.profile_enabled", false, out Error); + GlobalRequestContext.SetPreference("autofill.enabled", false, out Error); + GlobalRequestContext.SetPreference("payments.can_make_payment_enabled", false, out Error); + GlobalRequestContext.SetPreference("credentials_enable_service", false, out Error); + + //GlobalRequestContext.SetPreference("scroll_to_text_fragment_enabled", false, out Error); + //GlobalRequestContext.SetPreference("url_keyed_anonymized_data_collection.enabled", false, out Error); + + GlobalRequestContext.SetPreference("download_bubble_enabled", false, out Error); + GlobalRequestContext.SetPreference("download_bubble.partial_view_enabled", false, out Error); + GlobalRequestContext.SetPreference("download_duplicate_file_prompt_enabled", false, out Error); + //GlobalRequestContext.SetPreference("profile.default_content_setting_values.automatic_downloads", 1, out Error); + GlobalRequestContext.SetPreference("shopping_list_enabled", false, out Error); + GlobalRequestContext.SetPreference("browser_labs_enabled", false, out Error); + GlobalRequestContext.SetPreference("allow_dinosaur_easter_egg", false, out Error); + GlobalRequestContext.SetPreference("feedback_allowed", false, out Error); + GlobalRequestContext.SetPreference("policy.feedback_surveys_enabled", false, out Error); + GlobalRequestContext.SetPreference("ntp.promo_visible", false, out Error); + GlobalRequestContext.SetPreference("ntp.shortcust_visible", false, out Error); + GlobalRequestContext.SetPreference("ntp_snippets.enable", false, out Error); + GlobalRequestContext.SetPreference("ntp_snippets_by_dse.enable", false, out Error); + GlobalRequestContext.SetPreference("search.suggest_enabled", false, out Error); + GlobalRequestContext.SetPreference("side_search.enabled", false, out Error); + GlobalRequestContext.SetPreference("translate.enabled", false, out Error); + GlobalRequestContext.SetPreference("history.saving_disabled", false, out Error); + GlobalRequestContext.SetPreference("media_router.enable_media_router", false, out Error); + GlobalRequestContext.SetPreference("documentsuggest.enabled", false, out Error); + GlobalRequestContext.SetPreference("alternate_error_pages.enabled", false, out Error); + //GlobalRequestContext.SetPreference("https_only_mode_enabled", true, out Error); + //GlobalRequestContext.SetPreference("enable_do_not_track", bool.Parse(GlobalSave.Get("DoNotTrack")), out errorMessage); //https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/preloading/preloading_prefs.h GlobalRequestContext.SetPreference("net.network_prediction_options", 2, out Error); - - //GlobalRequestContext.SetPreference("safebrowsing.enabled", false, out Error); + GlobalRequestContext.SetPreference("safebrowsing.enabled", false, out Error); //GlobalRequestContext.SetPreference("browser.theme.follows_system_colors", false, out Error); GlobalRequestContext.SetPreference("browser.enable_spellchecking", bool.Parse(GlobalSave.Get("SpellCheck")), out Error); + //GlobalRequestContext.SetPreference("spellcheck.use_spelling_service", false, out Error); GlobalRequestContext.SetPreference("spellcheck.dictionaries", Languages.Select(i => i.Tooltip), out Error); - GlobalRequestContext.SetPreference("background_mode.enabled", false, out Error); + GlobalRequestContext.SetPreference("intl.accept_languages", Languages.Select(i => i.Tooltip), out Error); GlobalRequestContext.SetPreference("plugins.always_open_pdf_externally", !PDFViewerExtension, out Error); GlobalRequestContext.SetPreference("download.open_pdf_in_system_reader", !PDFViewerExtension, out Error); - //GlobalRequestContext.SetPreference("profile.default_content_setting_values.automatic_downloads", 1, out Error); - - //GlobalRequestContext.SetPreference("download_bubble.partial_view_enabled", false, out Error); - if (bool.Parse(GlobalSave.Get("BlockFingerprint"))) GlobalRequestContext.SetPreference("webrtc.ip_handling_policy", "disable_non_proxied_udp", out Error); - //GlobalRequestContext.SetPreference("profile.content_settings.enable_quiet_permission_ui.geolocation", false, out Error); - - //profile.block_third_party_cookies - //cefSettings.CefCommandLineArgs.Add("ssl-version-min", "tls1.2"); - - //webkit.webprefs.encrypted_media_enabled : True - - //GlobalRequestContext.SetPreference("extensions.storage.garbagecollect", true, out errorMessage); }); LoadExtensions(); + foreach (MainWindow _Window in AllWindows) + { + foreach (Browser BrowserView in _Window.Tabs.Select(i => i.Content)) + BrowserView?.InitializeBrowserComponent(); + } } /*public string GetPreferencesString(string _String, string Parents, KeyValuePair ObjectPair) @@ -1202,7 +1213,7 @@ public string GenerateCannotConnect(string Url, CefErrorCode ErrorCode, string E return HTML; } - public string Cannot_Connect_Error = @"Unable to connect to {Site}

Unable to connect to {Site}

{Description}
{Error}
"; + public string Cannot_Connect_Error = @"Unable to connect to {Site}

Unable to connect to {Site}

{Description}
{Error}
"; public string Process_Crashed_Error = @"Process crashed

Process Crashed

Process crashed while attempting to load content. Undo / Refresh the page to resolve the problem.
Return to homepage
"; public string Deception_Error = @"Site access denied

Site Access Denied

The site ahead was detected to contain deceptive content.
Return to homepage
"; public string Malware_Error = @"Site access denied

Site Access Denied

The site ahead was detected to contain unwanted software / malware.
Return to homepage
"; @@ -1236,16 +1247,12 @@ private void SetChromeFlags(CefSettings Settings) //Settings.CefCommandLineArgs.Add("disable-client-side-phishing-detection"); Settings.CefCommandLineArgs.Add("disable-domain-reliability"); - Settings.CefCommandLineArgs.Add("hide-crash-restore-bubble"); - Settings.CefCommandLineArgs.Add("disable-chrome-login-prompt"); Settings.CefCommandLineArgs.Add("disable-chrome-tracing-computation"); - Settings.CefCommandLineArgs.Add("disable-search-engine-choice-screen"); //Settings.CefCommandLineArgs.Add("disable-scroll-to-text-fragment"); //Settings.CefCommandLineArgs.Add("disable-ntp-other-sessions-menu"); Settings.CefCommandLineArgs.Add("disable-default-apps"); - Settings.CefCommandLineArgs.Add("disable-prompt-on-repost"); Settings.CefCommandLineArgs.Add("disable-modal-animations"); //Settings.CefCommandLineArgs.Add("material-design-ink-drop-animation-speed", "fast"); @@ -1254,6 +1261,7 @@ private void SetChromeFlags(CefSettings Settings) Settings.CefCommandLineArgs.Add("disable-login-animations"); Settings.CefCommandLineArgs.Add("disable-stack-profiler"); + Settings.CefCommandLineArgs.Add("disable-system-font-check"); //Settings.CefCommandLineArgs.Add("disable-infobars"); Settings.CefCommandLineArgs.Add("disable-breakpad"); Settings.CefCommandLineArgs.Add("disable-crash-reporter"); @@ -1275,6 +1283,20 @@ private void SetChromeFlags(CefSettings Settings) //Settings.CefCommandLineArgs.Add("oobe-skip-new-user-check-for-testing"); //Settings.CefCommandLineArgs.Add("disable-gaia-services"); // https://source.chromium.org/chromium/chromium/src/+/main:ash/constants/ash_switches.cc + + Settings.CefCommandLineArgs.Add("wm-window-animations-disabled"); + Settings.CefCommandLineArgs.Add("animation-duration-scale", "0"); + Settings.CefCommandLineArgs.Add("disable-histogram-customizer"); + + //REMOVE MOST CHROMIUM POPUPS + Settings.CefCommandLineArgs.Add("suppress-message-center-popups"); + Settings.CefCommandLineArgs.Add("disable-prompt-on-repost"); + Settings.CefCommandLineArgs.Add("propagate-iph-for-testing"); + Settings.CefCommandLineArgs.Add("disable-search-engine-choice-screen"); + Settings.CefCommandLineArgs.Add("ash-no-nudges"); + Settings.CefCommandLineArgs.Add("noerrdialogs"); + //Settings.CefCommandLineArgs.Add("hide-crash-restore-bubble"); + //Settings.CefCommandLineArgs.Add("disable-chrome-login-prompt"); } private void SetFrameworkFlags(CefSettings Settings) @@ -1334,6 +1356,7 @@ private void SetBackgroundFlags(CefSettings Settings) //Settings.CefCommandLineArgs.Add("enable-raster-side-dark-mode-for-images"); Settings.CefCommandLineArgs.Add("process-per-site"); + Settings.CefCommandLineArgs.Add("password-store", "basic"); if (bool.Parse(GlobalSave.Get("LiteMode"))) { @@ -1349,37 +1372,38 @@ private void SetBackgroundFlags(CefSettings Settings) Settings.CefCommandLineArgs.Add("force-prefers-reduced-motion"); Settings.CefCommandLineArgs.Add("disable-logging"); - //https://source.chromium.org/chromium/chromium/src/+/main:components/optimization_guide/core/optimization_guide_switches.cc - //https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/optimization_guide/hints_fetcher_browsertest.cc - //https://source.chromium.org/chromium/chromium/src/+/main:components/optimization_guide/core/optimization_guide_features.cc - Settings.CefCommandLineArgs.Add("disable-fetching-hints-at-navigation-start"); - Settings.CefCommandLineArgs.Add("disable-model-download-verification"); - Settings.CefCommandLineArgs.Add("disable-component-update"); + Settings.CefCommandLineArgs.Add("max-web-media-player-count", "1"); + Settings.CefCommandLineArgs.Add("gpu-program-cache-size-kb", $"{128 * 1024}"); Settings.CefCommandLineArgs.Add("gpu-disk-cache-size-kb", $"{128 * 1024}"); Settings.CefCommandLineArgs.Add("force-effective-connection-type", "Slow-2G"); - Settings.CefCommandLineArgs.Add("num-raster-threads", "4"); //RETIRED FLAG + //Settings.CefCommandLineArgs.Add("num-raster-threads", "4"); //RETIRED FLAG Settings.CefCommandLineArgs.Add("renderer-process-limit", "4"); - Settings.CefCommandLineArgs.Add("component-updater", "disable-background-downloads,disable-delta-updates"); //https://source.chromium.org/chromium/chromium/src/+/main:components/component_updater/component_updater_command_line_config_policy.cc } else { Settings.CefCommandLineArgs.Add("gpu-program-cache-size-kb", $"{2 * 1024 * 1024}"); Settings.CefCommandLineArgs.Add("gpu-disk-cache-size-kb", $"{2 * 1024 * 1024}"); - Settings.CefCommandLineArgs.Add("component-updater", "fast-update"); + //Settings.CefCommandLineArgs.Add("component-updater", "fast-update"); if (!bool.Parse(GlobalSave.Get("ChromiumHardwareAcceleration"))) Settings.CefCommandLineArgs.Add("enable-low-res-tiling"); } - //https://www.mail-archive.com/chromium-dev@googlegroups.com/msg05368.html - //Settings.CefCommandLineArgs.Add("memory-model", "low"); //DEPRECATED + //https://source.chromium.org/chromium/chromium/src/+/main:components/optimization_guide/core/optimization_guide_switches.cc + //https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/optimization_guide/hints_fetcher_browsertest.cc + //https://source.chromium.org/chromium/chromium/src/+/main:components/optimization_guide/core/optimization_guide_features.cc + Settings.CefCommandLineArgs.Add("disable-fetching-hints-at-navigation-start"); + Settings.CefCommandLineArgs.Add("disable-model-download-verification"); + Settings.CefCommandLineArgs.Add("disable-component-update"); + Settings.CefCommandLineArgs.Add("component-updater", "disable-background-downloads,disable-delta-updates"); //https://source.chromium.org/chromium/chromium/src/+/main:components/component_updater/component_updater_command_line_config_policy.cc + Settings.CefCommandLineArgs.Add("back-forward-cache"); - Settings.CefCommandLineArgs.Add("disable-highres-timer"); //This change makes it so when EnableHighResolutionTimer(true) which is on AC power the timer is 1ms and EnableHighResolutionTimer(false) is 4ms. //https://bugs.chromium.org/p/chromium/issues/detail?id=153139 + Settings.CefCommandLineArgs.Add("disable-highres-timer"); //https://github.com/portapps/brave-portable/issues/26 //https://github.com/chromium/chromium/blob/2ca8c5037021c9d2ecc00b787d58a31ed8fc8bcb/third_party/blink/renderer/bindings/core/v8/v8_cache_options.h @@ -1391,25 +1415,16 @@ private void SetBackgroundFlags(CefSettings Settings) //Settings.CefCommandLineArgs.Add("quick-intensive-throttling-after-loading"); //Causes memory to be 100 MB more than if disabled when minimized //Settings.CefCommandLineArgs.Add("intensive-wake-up-throttling-policy", "1"); - //Settings.CefCommandLineArgs.Add("private-aggregation-developer-mode"); //Causes the Private Aggregation API to run without reporting delays. //Settings.CefCommandLineArgs.Add("font-cache-shared-handle"); //Increases memory by 5 MB Settings.CefCommandLineArgs.Add("disable-mipmap-generation"); // Disables mipmap generation in Skia. Used a workaround for select low memory devices Settings.CefCommandLineArgs.Add("enable-parallel-downloading"); - - Settings.CefCommandLineArgs.Add("wm-window-animations-disabled"); - Settings.CefCommandLineArgs.Add("animation-duration-scale", "0"); - Settings.CefCommandLineArgs.Add("disable-histogram-customizer"); } /*NEVER SLOW MODE FLAGS - num-raster-threads - renderer-process-limit - force-effective-connection-type - // The adapter selecting strategy related to GPUPowerPreference. - https://source.chromium.org/chromium/chromium/src/+/main:gpu/command_buffer/service/service_utils.cc; + https://source.chromium.org/chromium/chromium/src/+/main:gpu/command_buffer/service/service_utils.cc none = WebGPUPowerPreference::kNone default-low-power = WebGPUPowerPreference::kDefaultLowPower; default-high-performance = WebGPUPowerPreference::kDefaultHighPerformance; @@ -1499,7 +1514,6 @@ private void SetGraphicsFlags(CefSettings Settings) else { Settings.CefCommandLineArgs.Add("disable-gpu"); - //Settings.CefCommandLineArgs.Add("disable-d3d11"); Settings.CefCommandLineArgs.Add("disable-gpu-compositing"); Settings.CefCommandLineArgs.Add("disable-gpu-vsync"); Settings.CefCommandLineArgs.Add("disable-gpu-shader-disk-cache"); @@ -1609,7 +1623,12 @@ private void SetFeatureFlags(CefSettings Settings) * https://source.chromium.org/chromium/chromium/src/+/main:android_webview/common/aw_features.cc * https://source.chromium.org/chromium/chromium/src/+/main:content/public/common/content_features.cc * https://source.chromium.org/chromium/chromium/src/+/main:components/page_image_service/features.cc + * https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/scheduler/main_thread/memory_purge_manager.cc + * https://source.chromium.org/chromium/chromium/src/+/main:content/browser/loader/navigation_url_loader_impl.cc + * https://source.chromium.org/chromium/chromium/src/+/main:components/embedder_support/android/util/features.cc + * https://source.chromium.org/chromium/chromium/src/+/main:components/js_injection/renderer/js_communication.cc * + * https://source.chromium.org/chromium/chromium/src/+/main:android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java * https://chromium.googlesource.com/chromium/src/+/efa55ec49b91438d5a9c0930ef19038d517914d1 * * BackForwardCacheWithKeepaliveRequest ReduceGpuPriorityOnBackground ProcessHtmlDataImmediately SetLowPriorityForBeacon @@ -1662,11 +1681,13 @@ private void SetFeatureFlags(CefSettings Settings) string JsFlags = "--max-old-space-size=512,--optimize-gc-for-battery,--memory-reducer-favors-memory,--efficiency-mode,--battery-saver-mode";// "--always-opt,--gc-global,--gc-experiment-reduce-concurrent-marking-tasks"; - string EnableFeatures = "AutofillDisableShadowHeuristics,SimplifyLoadingTransparentPlaceholderImage,OptimizeLoadingDataUrls,ThrottleUnimportantFrameTimers,stop-in-background,Prerender2MemoryControls,PrefetchPrivacyChanges,DIPS,LowLatencyCanvas2dImageChromium,LowLatencyWebGLImageChromium,NoStatePrefetchHoldback,LightweightNoStatePrefetch,BackForwardCacheMemoryControls,BatterySaverModeAlignWakeUps,RestrictThreadPoolInBackground,IntensiveWakeUpThrottling:grace_period_seconds/5,CheckHTMLParserBudgetLessOften,Canvas2DHibernation,Canvas2DHibernationReleaseTransferMemory,SpareRendererForSitePerProcess,ReduceSubresourceResponseStartedIPC"; - string DisableFeatures = "PrivateAggregationApi,PrintCompositorLPAC,CalculateNativeWinOcclusion,CrashReporting,OptimizationHintsFetchingSRP,OptimizationGuideModelDownloading,OptimizationHintsFetching,OptimizationTargetPrediction,OptimizationHints,SegmentationPlatform,WebFontsCacheAwareTimeoutAdaption,SpeculationRulesPrefetchFuture,NavigationPredictor,Prerender2MainFrameNavigation,InstalledApp,BrowsingTopics,Fledge,MemoryCacheStrongReference,Prerender2NoVarySearch,Prerender2,InterestFeedContentSuggestions"; + //DEFAULT ENABLED: MemoryPurgeInBackground, stop-in-background + //ANDROID: InputStreamOptimizations + string EnableFeatures = "QuickIntensiveWakeUpThrottlingAfterLoading,LowerHighResolutionTimerThreshold,LazyBindJsInjection,SkipUnnecessaryThreadHopsForParseHeaders,ReduceCpuUtilization2,SimplifyLoadingTransparentPlaceholderImage,OptimizeLoadingDataUrls,ThrottleUnimportantFrameTimers,Prerender2MemoryControls,PrefetchPrivacyChanges,DIPS,LowLatencyCanvas2dImageChromium,LowLatencyWebGLImageChromium,NoStatePrefetchHoldback,LightweightNoStatePrefetch,BackForwardCacheMemoryControls,BatterySaverModeAlignWakeUps,RestrictThreadPoolInBackground,IntensiveWakeUpThrottling:grace_period_seconds/5,CheckHTMLParserBudgetLessOften,Canvas2DHibernation,Canvas2DHibernationReleaseTransferMemory,ClearCanvasResourcesInBackground,Canvas2DReclaimUnusedResources,EvictionUnlocksResources,SpareRendererForSitePerProcess,ReduceSubresourceResponseStartedIPC"; + string DisableFeatures = "Translate,InterestFeedContentSuggestions,CertificateTransparencyComponentUpdater,AutofillServerCommunication,AcceptCHFrame,PrivacySandboxSettings4,ImprovedCookieControls,GlobalMediaControls,LoadingPredictorPrefetch,WebBluetooth,MediaRouter,LiveCaption,HardwareMediaKeyHandling,PrivateAggregationApi,PrintCompositorLPAC,CrashReporting,OptimizationHintsFetchingSRP,OptimizationGuideModelDownloading,OptimizationHintsFetching,OptimizationTargetPrediction,OptimizationHints,SegmentationPlatform,WebFontsCacheAwareTimeoutAdaption,SpeculationRulesPrefetchFuture,NavigationPredictor,Prerender2MainFrameNavigation,InstalledApp,BrowsingTopics,Fledge,MemoryCacheStrongReference,Prerender2NoVarySearch,Prerender2,InterestFeedContentSuggestions"; - string EnableBlinkFeatures = "StaticAnimationOptimization,PageFreezeOptIn,FreezeFramesOnVisibility,SkipPreloadScanning,LazyInitializeMediaControls,LazyFrameLoading,LazyImageLoading"; - string DisableBlinkFeatures = "Prerender2"; + string EnableBlinkFeatures = "UnownedAnimationsSkipCSSEvents,StaticAnimationOptimization,PageFreezeOptIn,FreezeFramesOnVisibility,SkipPreloadScanning,LazyInitializeMediaControls,LazyFrameLoading,LazyImageLoading"; + string DisableBlinkFeatures = "DocumentWrite,LanguageDetectionAPI,DocumentPictureInPictureAPI,Prerender2"; try { @@ -1716,10 +1737,41 @@ public Theme GetTheme(string Name = "") protected override void OnExit(ExitEventArgs e) { - CloseSLBr(false); + CloseSLBr(true); base.OnExit(e); } + public void ClearAllData() + { + AdsBlocked = 0; + TrackersBlocked = 0; + Cef.GetGlobalCookieManager().DeleteCookies(string.Empty, string.Empty); + Cef.GetGlobalRequestContext().ClearHttpAuthCredentialsAsync(); + foreach (MainWindow _Window in AllWindows) + { + foreach (Browser BrowserView in _Window.Tabs.Select(i => i.Content)) + { + if (BrowserView != null && BrowserView.Chromium != null && BrowserView.Chromium.IsBrowserInitialized) + { + if (BrowserView.Chromium.CanExecuteJavascriptInMainFrame) + BrowserView.Chromium.ExecuteScriptAsync("localStorage.clear();sessionStorage.clear();"); + using (var DevToolsClient = BrowserView.Chromium.GetDevToolsClient()) + { + //https://github.com/cefsharp/CefSharp/issues/1234 + DevToolsClient.Storage.ClearDataForOriginAsync("*", "all"); + DevToolsClient.Page.ClearCompilationCacheAsync(); + DevToolsClient.Page.ResetNavigationHistoryAsync(); + DevToolsClient.Network.ClearBrowserCookiesAsync(); + DevToolsClient.Network.ClearBrowserCacheAsync(); + } + } + } + } + var infoWindow = new InformationDialogWindow("Alert", $"Settings", "All browsing data has been cleared", "\ue713"); + infoWindow.Topmost = true; + infoWindow.ShowDialog(); + } + public void CloseSLBr(bool ExecuteCloseEvents = true) { if (AppInitialized) @@ -1744,28 +1796,23 @@ public void CloseSLBr(bool ExecuteCloseEvents = true) LanguagesSave.Set($"{i}", Languages[i].Tooltip, false); LanguagesSave.Save(); + foreach (FileInfo _File in new DirectoryInfo(UserApplicationWindowsPath).GetFiles()) + _File.Delete(); if (bool.Parse(GlobalSave.Get("RestoreTabs"))) { - foreach (FileInfo _File in new DirectoryInfo(UserApplicationWindowsPath).GetFiles()) - _File.Delete(); foreach (MainWindow _Window in AllWindows) { Saving TabsSave = WindowsSaves[AllWindows.IndexOf(_Window)]; TabsSave.Clear(); - int Count = 0; for (int i = 0; i < _Window.Tabs.Count; i++) { BrowserTabItem Tab = _Window.Tabs[i]; if (Tab.ParentWindow != null) - { - TabsSave.Set(Count.ToString(), Tab.Content.Address, false); - if (i == _Window.TabsUI.SelectedIndex) - TabsSave.Set("Selected", Count.ToString()); - Count++; - } + TabsSave.Set(i.ToString(), Tab.Content.Address, false); } - TabsSave.Set("Count", Count.ToString()); + TabsSave.Set("Selected", _Window.TabsUI.SelectedIndex.ToString()); + TabsSave.Set("Count", (_Window.Tabs.Count - 1).ToString()); } } } @@ -1875,7 +1922,7 @@ public void SetDimUnloadedIcon(bool Toggle) foreach (MainWindow _Window in AllWindows) _Window.SetDimUnloadedIcon(Toggle); } - public void SetAppearance(Theme _Theme, string TabAlignment, bool AllowHomeButton, bool AllowTranslateButton, bool AllowAIButton, bool AllowReaderModeButton) + public void SetAppearance(Theme _Theme, string TabAlignment, bool AllowHomeButton, bool AllowTranslateButton, bool AllowAIButton, bool AllowReaderModeButton, int ShowExtensionButton, int ShowFavouritesBar) { GlobalSave.Set("TabAlignment", TabAlignment); @@ -1883,6 +1930,8 @@ public void SetAppearance(Theme _Theme, string TabAlignment, bool AllowHomeButto GlobalSave.Set("TranslateButton", AllowTranslateButton); GlobalSave.Set("HomeButton", AllowHomeButton); GlobalSave.Set("ReaderButton", AllowReaderModeButton); + GlobalSave.Set("ExtensionButton", ShowExtensionButton); + GlobalSave.Set("FavouritesBar", ShowFavouritesBar); CurrentTheme = _Theme; GlobalSave.Set("Theme", CurrentTheme.Name); @@ -2029,7 +2078,7 @@ public void SetAppearance(Theme _Theme, string TabAlignment, bool AllowHomeButto } foreach (MainWindow _Window in AllWindows) - _Window.SetAppearance(_Theme, TabAlignment, AllowHomeButton, AllowTranslateButton, AllowAIButton, AllowReaderModeButton); + _Window.SetAppearance(_Theme, TabAlignment, AllowHomeButton, AllowTranslateButton, AllowAIButton, AllowReaderModeButton, ShowExtensionButton, ShowFavouritesBar); } } @@ -2106,6 +2155,10 @@ public enum Actions Print = 30, Mute = 31, Find = 32, + + ZoomIn = 40, + ZoomOut = 41, + ZoomReset = 42, } public class ActionStorage : INotifyPropertyChanged diff --git a/SLBr/Controls/CredentialsDialog.cs b/SLBr/Controls/CredentialsDialog.cs index 89d6e0c..618f4c4 100644 --- a/SLBr/Controls/CredentialsDialog.cs +++ b/SLBr/Controls/CredentialsDialog.cs @@ -1,4 +1,6 @@ -namespace SLBr.Controls +/*using System.Windows; + +namespace SLBr.Controls { public class CredentialsDialogResult { @@ -6,9 +8,9 @@ public class CredentialsDialogResult public string Username; public string Password; - public CredentialsDialogResult(bool? _Accepted, string _Username, string _Password) + public CredentialsDialogResult(bool _Accepted, string _Username, string _Password) { - Accepted = (bool)_Accepted; + Accepted = _Accepted; Username = _Username; Password = _Password; } @@ -17,9 +19,19 @@ public static class CredentialsDialog { public static CredentialsDialogResult Show(string Question) { - CredentialsDialogWindow _CredentialsDialogWindow = new CredentialsDialogWindow(Question, "\uec19"); - _CredentialsDialogWindow.Topmost = true; - return new CredentialsDialogResult(_CredentialsDialogWindow.ShowDialog(), _CredentialsDialogWindow.Username, _CredentialsDialogWindow.Password); + CredentialsDialogWindow _CredentialsDialogWindow; + bool DialogResult = false; + string Username = ""; + string Password = ""; + Application.Current.Dispatcher.Invoke(() => + { + _CredentialsDialogWindow = new CredentialsDialogWindow(Question, "\uec19"); + _CredentialsDialogWindow.Topmost = true; + DialogResult = _CredentialsDialogWindow.ShowDialog().ToBool(); + Username = _CredentialsDialogWindow.Username; + Password = _CredentialsDialogWindow.Password; + }); + return new CredentialsDialogResult(DialogResult, Username, Password); } } -} +}*/ diff --git a/SLBr/Controls/HwndHoster.cs b/SLBr/Controls/HwndHoster.cs index b82e2ec..26854ec 100644 --- a/SLBr/Controls/HwndHoster.cs +++ b/SLBr/Controls/HwndHoster.cs @@ -28,7 +28,9 @@ private static extern IntPtr CreateWindowEx(int dwExStyle, WS_CLIPCHILDREN = 0x02000000, WM_SIZE = 0x0005, SWP_NOMOVE = 0x0002, - SWP_NOZORDER = 0x0004; + SWP_NOZORDER = 0x0004, + WM_SETFOCUS = 0x0007, + WM_MOUSEACTIVATE = 0x0021; private IntPtr hwndHost; @@ -119,9 +121,6 @@ protected override void DestroyWindowCore(HandleRef hwnd) } protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { - const int WM_SETFOCUS = 0x0007; - const int WM_MOUSEACTIVATE = 0x0021; - const int WM_SIZE = 0x0005; switch (msg) { case WM_SETFOCUS: @@ -139,11 +138,11 @@ protected override void Dispose(bool disposing) InternalDispose(disposing); base.Dispose(disposing); } - int WindowInitialized; + //int WindowInitialized; [MethodImpl(MethodImplOptions.NoInlining)] private void InternalDispose(bool disposing) { - Interlocked.Exchange(ref WindowInitialized, 0); + //Interlocked.Exchange(ref WindowInitialized, 0); if (disposing) { SizeChanged -= OnSizeChanged; @@ -197,14 +196,14 @@ private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArg SetWindowPos(hwndHost, IntPtr.Zero, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE); } - [StructLayout(LayoutKind.Sequential)] + /*[StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; - } + }*/ private IntPtr firstChildHwnd = IntPtr.Zero; private bool EnumChildProc(IntPtr hWnd, IntPtr lParam) diff --git a/SLBr/Controls/InformationDialogWindow.xaml b/SLBr/Controls/InformationDialogWindow.xaml index 261bc82..7000c1c 100644 --- a/SLBr/Controls/InformationDialogWindow.xaml +++ b/SLBr/Controls/InformationDialogWindow.xaml @@ -26,7 +26,7 @@ - + Description diff --git a/SLBr/Controls/InformationDialogWindow.xaml.cs b/SLBr/Controls/InformationDialogWindow.xaml.cs index 299358f..deeec00 100644 --- a/SLBr/Controls/InformationDialogWindow.xaml.cs +++ b/SLBr/Controls/InformationDialogWindow.xaml.cs @@ -20,8 +20,8 @@ public InformationDialogWindow(string _Title, string Question, string Descriptio DescriptionText.Text = Description; ApplyTheme(App.Instance.CurrentTheme); - Icon.Text = _FluentIconsText; - Icon.Visibility = string.IsNullOrEmpty(_FluentIconsText) ? Visibility.Collapsed : Visibility.Visible; + IconText.Text = _FluentIconsText; + IconText.Visibility = string.IsNullOrEmpty(_FluentIconsText) ? Visibility.Collapsed : Visibility.Visible; PositiveButton.Visibility = string.IsNullOrEmpty(PositiveText) ? Visibility.Collapsed : Visibility.Visible; PositiveButton.Content = PositiveText; diff --git a/SLBr/Controls/PopupBrowser.xaml.cs b/SLBr/Controls/PopupBrowser.xaml.cs index 1b6b22b..634011a 100644 --- a/SLBr/Controls/PopupBrowser.xaml.cs +++ b/SLBr/Controls/PopupBrowser.xaml.cs @@ -1,5 +1,7 @@ using CefSharp; +using CefSharp.Handler; using CefSharp.Wpf.HwndHost; +using SLBr.Handlers; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; @@ -34,8 +36,9 @@ public PopupBrowser(string _Address, int _Width, int _Height) _Browser.Address = InitialAddress; _Browser.LifeSpanHandler = App.Instance._LifeSpanHandler; - _Browser.DownloadHandler = App.Instance._DownloadHandler; _Browser.RequestHandler = App.Instance._RequestHandler; + _Browser.ResourceRequestHandlerFactory = new Handlers.ResourceRequestHandlerFactory(App.Instance._RequestHandler); + _Browser.DownloadHandler = App.Instance._DownloadHandler; _Browser.MenuHandler = App.Instance._LimitedContextMenuHandler; //_Browser.KeyboardHandler = MainWindow.Instance._KeyboardHandler; //_Browser.JsDialogHandler = MainWindow.Instance._JsDialogHandler; @@ -54,6 +57,8 @@ public PopupBrowser(string _Address, int _Width, int _Height) }; WebContent.Children.Add(_Browser); + int trueValue = 0x01; + DwmSetWindowAttribute(HwndSource.FromHwnd(new WindowInteropHelper(this).EnsureHandle()).Handle, DwmWindowAttribute.DWMWA_MICA_EFFECT, ref trueValue, Marshal.SizeOf(typeof(int))); //RenderOptions.SetBitmapScalingMode(_Browser, BitmapScalingMode.LowQuality); } @@ -74,7 +79,7 @@ private void Browser_LoadingStateChanged(object? sender, LoadingStateChangedEven return; Dispatcher.Invoke(() => { - Icon = new BitmapImage(new Uri("http://www.google.com/s2/favicons?sz=24&domain=" + Utils.CleanUrl(_Browser.Address, true, true, true, false, false))); + Icon = App.Instance.GetIcon(_Browser.Address); _Browser.GetDevToolsClient().Emulation.SetAutoDarkModeOverrideAsync(CurrentTheme.DarkWebPage); }); } @@ -90,7 +95,6 @@ public void ApplyTheme(Theme _Theme) DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref trueValue, Marshal.SizeOf(typeof(int))); else DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref falseValue, Marshal.SizeOf(typeof(int))); - DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_MICA_EFFECT, ref trueValue, Marshal.SizeOf(typeof(int))); Resources["PrimaryBrushColor"] = _Theme.PrimaryColor; Resources["SecondaryBrushColor"] = _Theme.SecondaryColor; diff --git a/SLBr/Handlers/ContextMenuHandler.cs b/SLBr/Handlers/ContextMenuHandler.cs index 51de3f6..5fceb15 100644 --- a/SLBr/Handlers/ContextMenuHandler.cs +++ b/SLBr/Handlers/ContextMenuHandler.cs @@ -12,51 +12,51 @@ namespace SLBr.Handlers { public class ContextMenuHandler : IContextMenuHandler { - public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model) + public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams Parameters, IMenuModel model) { model.Clear(); - if (parameters.IsEditable) + if (Parameters.IsEditable) { - if (parameters.DictionarySuggestions.Count != 0 && bool.Parse(App.Instance.GlobalSave.Get("SpellCheck"))) + if (Parameters.IsSpellCheckEnabled && Parameters.DictionarySuggestions.Count != 0) { - switch (parameters.DictionarySuggestions.Count) + switch (Parameters.DictionarySuggestions.Count) { case 1: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); break; case 2: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); break; case 3: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); break; case 4: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion3, parameters.DictionarySuggestions[3]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion3, Parameters.DictionarySuggestions[3]); break; case 5: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion3, parameters.DictionarySuggestions[3]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion4, parameters.DictionarySuggestions[4]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion3, Parameters.DictionarySuggestions[3]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion4, Parameters.DictionarySuggestions[4]); break; default: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion3, parameters.DictionarySuggestions[3]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion3, Parameters.DictionarySuggestions[3]); break; } model.AddItem(CefMenuCommand.AddToDictionary, "Ignore Word"); model.AddSeparator(); } - model.AddItem((CefMenuCommand)26510, "Emoji"); + model.AddItem(MenuEmoji, "Emoji"); model.AddSeparator(); model.AddItem(CefMenuCommand.Undo, "Undo"); model.AddItem(CefMenuCommand.Redo, "Redo"); @@ -67,49 +67,56 @@ public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser model.AddItem(CefMenuCommand.Delete, "Delete"); model.AddSeparator(); model.AddItem(CefMenuCommand.SelectAll, "Select All"); - if (!string.IsNullOrEmpty(parameters.SelectionText)) + if (!string.IsNullOrEmpty(Parameters.SelectionText)) { model.AddSeparator(); - model.AddItem(CefMenuCommand.Find, $"Search \"{parameters.SelectionText}\" in new tab"); + model.AddItem(CefMenuCommand.Find, $"Search \"{Parameters.SelectionText}\" in new tab"); } } - else if (!string.IsNullOrEmpty(parameters.LinkUrl)) + else if (!string.IsNullOrEmpty(Parameters.LinkUrl)) { - model.AddItem((CefMenuCommand)26502, "Open in new tab"); - model.AddItem(CefMenuCommand.Copy, "Copy link"); + model.AddItem(MenuOpenNewTab, "Open in new tab"); + model.AddItem(MenuCopyURL, "Copy link"); } - else if (!string.IsNullOrEmpty(parameters.SelectionText)) + else if (!string.IsNullOrEmpty(Parameters.SelectionText)) { - model.AddItem(CefMenuCommand.Find, $"Search \"{parameters.SelectionText}\" in new tab"); + model.AddItem(CefMenuCommand.Find, $"Search \"{Parameters.SelectionText}\" in new tab"); model.AddItem(CefMenuCommand.Copy, "Copy"); + model.AddSeparator(); + model.AddItem(CefMenuCommand.SelectAll, "Select All"); } else { - if (parameters.MediaType != ContextMenuMediaType.Image)//parameters.MediaType == ContextMenuMediaType.None + if (Parameters.MediaType == ContextMenuMediaType.None) { model.AddItem(CefMenuCommand.Back, "Back"); model.AddItem(CefMenuCommand.Forward, "Forward"); model.AddItem(CefMenuCommand.Reload, "Refresh"); model.AddSeparator(); - model.AddItem((CefMenuCommand)26501, "Save as"); + model.AddItem(MenuSaveAs, "Save as"); model.AddItem(CefMenuCommand.Print, "Print"); + model.AddItem(CefMenuCommand.SelectAll, "Select All"); model.AddSeparator(); - model.AddItem((CefMenuCommand)26506, "Screenshot"); + model.AddItem(MenuTranslate, "Translate"); + model.AddItem(MenuScreenshot, "Screenshot"); IMenuModel ZoomSubMenuModel = model.AddSubMenu(CefMenuCommand.NotFound, "Zoom"); - ZoomSubMenuModel.AddItem((CefMenuCommand)26507, "Zoom in"); - ZoomSubMenuModel.AddItem((CefMenuCommand)26508, "Zoom out"); - ZoomSubMenuModel.AddItem((CefMenuCommand)26509, "Reset"); + ZoomSubMenuModel.AddItem(MenuZoomIn, "Zoom in"); + ZoomSubMenuModel.AddItem(MenuZoomOut, "Zoom out"); + ZoomSubMenuModel.AddItem(MenuZoomReset, "Reset"); /*model.AddSeparator(); model.AddItem((CefMenuCommand)26507, "Zoom"); model.AddItem((CefMenuCommand)26508, "Zoom out"); model.AddItem((CefMenuCommand)26509, "Reset zoom");*/ model.AddSeparator(); - model.AddItem(CefMenuCommand.ViewSource, "View page source"); - model.AddItem((CefMenuCommand)26503, "Inspect"); + + IMenuModel AdvancedMenuModel = model.AddSubMenu(CefMenuCommand.NotFound, "Advanced"); + AdvancedMenuModel.AddItem(CefMenuCommand.ViewSource, "View source"); + AdvancedMenuModel.AddItem(MenuInspector, "Inspect"); + /*IMenuModel _EditSubMenuModel = model.AddSubMenu(CefMenuCommand.NotFound, "Edit"); _EditSubMenuModel.AddItem(CefMenuCommand.Undo, "Undo"); _EditSubMenuModel.AddItem(CefMenuCommand.Redo, "Redo"); @@ -125,28 +132,46 @@ public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser model.AddItem((CefMenuCommand)26509, "Inspect"); model.AddSeparator();*/ } - else + else if (Parameters.MediaType == ContextMenuMediaType.Image) { model.AddItem(CefMenuCommand.Copy, "Copy image"); - model.AddItem((CefMenuCommand)26505, "Copy image link"); - model.AddItem((CefMenuCommand)26501, "Save image as"); + model.AddItem(MenuCopyURL, "Copy image link"); + model.AddItem(MenuSaveAs, "Save image as"); //model.AddItem((CefMenuCommand)26502, "Open in paintbrush"); } + else if (Parameters.MediaType == ContextMenuMediaType.Video) + { + model.AddItem(MenuCopyURL, "Copy video link"); + model.AddItem(MenuSaveAs, "Save video as"); + /*if (Parameters.MediaStateFlags == ContextMenuMediaState.CanPictureInPicture) + model.AddItem(MenuPictureInPicture, "Picture in picture");*/ + } } - /*model.AddSeparator(); - model.AddItem(CefMenuCommand.NotFound, "Cancel");*/ } - private async void DownloadAndCopyImage(string imageUrl) + CefMenuCommand MenuSaveAs = (CefMenuCommand)26501; + CefMenuCommand MenuOpenNewTab = (CefMenuCommand)26502; + CefMenuCommand MenuInspector = (CefMenuCommand)26503; + CefMenuCommand MenuCopyURL = (CefMenuCommand)26504; + CefMenuCommand MenuScreenshot = (CefMenuCommand)26505; + CefMenuCommand MenuEmoji = (CefMenuCommand)26506; + CefMenuCommand MenuTranslate = (CefMenuCommand)26507; + //CefMenuCommand MenuPictureInPicture = (CefMenuCommand)26507; + + CefMenuCommand MenuZoomReset = (CefMenuCommand)26510; + CefMenuCommand MenuZoomIn = (CefMenuCommand)26511; + CefMenuCommand MenuZoomOut = (CefMenuCommand)26512; + + private async void DownloadAndCopyImage(string ImageUrl) { try { - using (var client = new HttpClient()) + using (var HttpClient = new HttpClient()) { - byte[] imageData = await client.GetByteArrayAsync(imageUrl); - if (imageData != null) + byte[] ImageData = await HttpClient.GetByteArrayAsync(ImageUrl); + if (ImageData != null) { - using (MemoryStream stream = new MemoryStream(imageData)) + using (MemoryStream stream = new MemoryStream(ImageData)) { BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); @@ -160,22 +185,9 @@ private async void DownloadAndCopyImage(string imageUrl) } } } - catch (Exception ex) - { - MessageBox.Show($"Failed to copy image: {ex.Message}"); - } + catch { } } - //Save as 26501 - //26502 Open in new Tab - //26503 Inspector - //26504 View source - //26505 Copy Image Url - //26506 Take screenshot - //26507 Zoom default - //26508 Zoom out - //26509 Zoom in - public bool OnContextMenuCommand(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags) { return ExecuteContextMenu(chromiumWebBrowser, browser, commandId, parameters); @@ -209,19 +221,19 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu }); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26510) + else if (CommandID == MenuEmoji) CoreInputView.GetForCurrentView().TryShow(CoreInputViewKind.Emoji); } else if (!string.IsNullOrEmpty(Parameters.LinkUrl)) { App.Current.Dispatcher.Invoke(() => { - if (CommandID == (CefMenuCommand)26502) + if (CommandID == MenuOpenNewTab) { App.Instance.CurrentFocusedWindow().NewTab(Parameters.LinkUrl, true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); ToReturn = true; } - else if (CommandID == CefMenuCommand.Copy) + else if (CommandID == MenuCopyURL) { Clipboard.SetText(Parameters.LinkUrl); ToReturn = true; @@ -242,43 +254,49 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu } else { - if (Parameters.MediaType != ContextMenuMediaType.Image) + if (Parameters.MediaType == ContextMenuMediaType.None) { App.Current.Dispatcher.Invoke(() => { - if (CommandID == (CefMenuCommand)26503) + if (CommandID == MenuInspector) { - App.Instance.CurrentFocusedWindow().DevTools("", Parameters.XCoord, Parameters.YCoord); + App.Instance.CurrentFocusedWindow().DevTools("");//, Parameters.XCoord, Parameters.YCoord); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26501) + else if (CommandID == MenuSaveAs) { Browser.StartDownload(WebBrowser.Address); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26506) + else if (CommandID == MenuTranslate) + { + Pages.Browser BrowserView = App.Instance.CurrentFocusedWindow().GetTab().Content; + BrowserView.Address = $"https://translate.google.com/translate?sl=auto&tl=en&hl=en&u={BrowserView.Address}"; + ToReturn = true; + } + else if (CommandID == MenuScreenshot) { App.Instance.CurrentFocusedWindow().Screenshot(); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26507) + else if (CommandID == MenuZoomIn) { App.Instance.CurrentFocusedWindow().Zoom(1); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26508) + else if (CommandID == MenuZoomOut) { App.Instance.CurrentFocusedWindow().Zoom(-1); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26509) + else if (CommandID == MenuZoomReset) { App.Instance.CurrentFocusedWindow().Zoom(0); ToReturn = true; } }); } - else + else if (Parameters.MediaType == ContextMenuMediaType.Image) { if (CommandID == CefMenuCommand.Copy) { @@ -286,12 +304,12 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu catch { Clipboard.SetText(Parameters.SourceUrl); } ToReturn = true; } - else if (CommandID == (CefMenuCommand)26505) + else if (CommandID == MenuCopyURL) { Clipboard.SetText(Parameters.SourceUrl); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26501) + else if (CommandID == MenuSaveAs) { Browser.StartDownload(Parameters.SourceUrl); ToReturn = true; @@ -304,6 +322,23 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu Process.Start(FileName); }*/ } + else if (Parameters.MediaType == ContextMenuMediaType.Video) + { + if (CommandID == MenuCopyURL) + { + Clipboard.SetText(Parameters.SourceUrl); + ToReturn = true; + } + else if (CommandID == MenuSaveAs) + { + Browser.StartDownload(Parameters.SourceUrl); + ToReturn = true; + } + /*else if (CommandID == MenuPictureInPicture) + { + ToReturn = true; + }*/ + } } if (!ToReturn) { @@ -441,16 +476,55 @@ void MenuClassToCollection(IEnumerable Menu, ItemCollection _ItemColl }; if (Item.CommandId == CefMenuCommand.Back) + { + _MenuItem.Icon = "\uE76B"; _MenuItem.IsEnabled = chromiumWebBrowser.CanGoBack; + } else if (Item.CommandId == CefMenuCommand.Forward) + { + _MenuItem.Icon = "\uE76C"; _MenuItem.IsEnabled = chromiumWebBrowser.CanGoForward; - else if (Item.CommandId == CefMenuCommand.Delete) - _MenuItem.IsEnabled = !string.IsNullOrEmpty(Parameters.SelectionText); + } + else if (Item.CommandId == CefMenuCommand.Reload) + _MenuItem.Icon = "\uE72C"; + + else if (Item.CommandId == CefMenuCommand.Print) + _MenuItem.Icon = "\uE749"; + else if (Item.CommandId == CefMenuCommand.ViewSource) + _MenuItem.Icon = "\ue943"; + + else if (Item.Header == "Advanced") + _MenuItem.Icon = "\uec7a"; + + else if (Item.CommandId == MenuInspector) + _MenuItem.Icon = "\uec7a"; + //_MenuItem.Icon = "\ue929"; + else if (Item.CommandId == MenuSaveAs) + _MenuItem.Icon = "\ue792"; + else if (Item.CommandId == MenuScreenshot) + _MenuItem.Icon = "\uE924"; + else if (Item.CommandId == MenuZoomIn) + _MenuItem.Icon = "\ue8a3"; + else if (Item.CommandId == MenuZoomOut) + _MenuItem.Icon = "\ue71f"; + else if (Item.CommandId == MenuZoomReset) + _MenuItem.Icon = "\ue72c"; + else if (Item.CommandId == MenuTranslate) + { + _MenuItem.Icon = "\uE8C1"; + _MenuItem.IsEnabled = Utils.IsHttpScheme(browser.MainFrame.Url); + } + + else if (Item.CommandId == MenuOpenNewTab) + _MenuItem.Icon = "\uE8A7"; + else if (Item.CommandId == MenuCopyURL) + _MenuItem.Icon = "\ue71b"; else if (Item.CommandId == CefMenuCommand.Undo) _MenuItem.InputGestureText = "Ctrl+Z"; else if (Item.CommandId == CefMenuCommand.Redo) _MenuItem.InputGestureText = "Ctrl+Y"; + else if (Item.CommandId == CefMenuCommand.Cut) _MenuItem.InputGestureText = "Ctrl+X"; else if (Item.CommandId == CefMenuCommand.Copy) @@ -459,16 +533,18 @@ void MenuClassToCollection(IEnumerable Menu, ItemCollection _ItemColl _MenuItem.InputGestureText = "Ctrl+V"; else if (Item.CommandId == CefMenuCommand.SelectAll) _MenuItem.InputGestureText = "Ctrl+A"; - else if (Item.CommandId == (CefMenuCommand)26510) + else if (Item.CommandId == CefMenuCommand.Delete) + _MenuItem.IsEnabled = !string.IsNullOrEmpty(Parameters.SelectionText); + + else if (Item.CommandId == MenuEmoji) _MenuItem.InputGestureText = "Win+Period"; + else if (Item.Header.StartsWith("Search")) _MenuItem.Icon = "\uF6Fa"; else if (Item.CommandId == CefMenuCommand.SpellCheckSuggestion0 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion1 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion2 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion3 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion4) _MenuItem.Icon = "\uf87b"; else if (Item.CommandId == CefMenuCommand.AddToDictionary) _MenuItem.Icon = "\uecc9"; - else if (Item.CommandId == (CefMenuCommand)26503) - _MenuItem.Icon = "\ue929"; //_MenuItem.SetResourceReference(Control.ForegroundProperty, "White"); //_MenuItem.SetResourceReference(Control.StyleProperty, (Style)MainWindow.Instance.Resources["ApplyableMenuItemStyle"]); diff --git a/SLBr/Handlers/DownloadHandler.cs b/SLBr/Handlers/DownloadHandler.cs index f30eaa5..3de09e4 100644 --- a/SLBr/Handlers/DownloadHandler.cs +++ b/SLBr/Handlers/DownloadHandler.cs @@ -32,26 +32,22 @@ public bool OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, D if (!callback.IsDisposed) { using (callback) - { - App.Instance.UpdateDownloadItem(downloadItem); callback.Continue(Path.Combine(App.Instance.GlobalSave.Get("DownloadPath"), downloadItem.SuggestedFileName), bool.Parse(App.Instance.GlobalSave.Get("DownloadPrompt"))); - } } return true; } + private Dictionary DownloadCallbacks = new Dictionary(); + public void OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IDownloadItemCallback callback) { App.Instance.UpdateDownloadItem(downloadItem); - - App.Current.Dispatcher.Invoke(() => + if (downloadItem.IsInProgress) + DownloadCallbacks[downloadItem.Id] = callback; + else { - if (downloadItem.IsInProgress) - { - if (App.Instance.CanceledDownloads.Contains(downloadItem.Id)) - callback.Cancel(); - } - else + DownloadCallbacks.Remove(downloadItem.Id); + App.Current.Dispatcher.Invoke(() => { if (!browser.HasDocument) { @@ -73,8 +69,14 @@ public void OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser, } }*/ } - } - }); + }); + } + } + + public void CancelDownload(int DownloadID) + { + if (DownloadCallbacks.TryGetValue(DownloadID, out IDownloadItemCallback _Callback)) + _Callback.Cancel(); } } } diff --git a/SLBr/Handlers/LimitedContextMenuHandler.cs b/SLBr/Handlers/LimitedContextMenuHandler.cs index d3f7f39..14b0b01 100644 --- a/SLBr/Handlers/LimitedContextMenuHandler.cs +++ b/SLBr/Handlers/LimitedContextMenuHandler.cs @@ -12,57 +12,57 @@ namespace SLBr.Handlers { public class LimitedContextMenuHandler : IContextMenuHandler { - public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model) + public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams Parameters, IMenuModel model) { model.Clear(); - if (parameters.IsEditable) + if (Parameters.IsEditable) { - if (parameters.DictionarySuggestions.Count != 0 && bool.Parse(App.Instance.GlobalSave.Get("SpellCheck"))) + if (Parameters.DictionarySuggestions.Count != 0 && bool.Parse(App.Instance.GlobalSave.Get("SpellCheck"))) { - switch (parameters.DictionarySuggestions.Count) + switch (Parameters.DictionarySuggestions.Count) { case 1: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); model.AddSeparator(); break; case 2: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); model.AddSeparator(); break; case 3: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); model.AddSeparator(); break; case 4: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion3, parameters.DictionarySuggestions[3]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion3, Parameters.DictionarySuggestions[3]); model.AddSeparator(); break; case 5: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion3, parameters.DictionarySuggestions[3]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion4, parameters.DictionarySuggestions[4]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion3, Parameters.DictionarySuggestions[3]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion4, Parameters.DictionarySuggestions[4]); model.AddSeparator(); break; default: - model.AddItem(CefMenuCommand.SpellCheckSuggestion0, parameters.DictionarySuggestions[0]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion1, parameters.DictionarySuggestions[1]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion2, parameters.DictionarySuggestions[2]); - model.AddItem(CefMenuCommand.SpellCheckSuggestion3, parameters.DictionarySuggestions[3]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion0, Parameters.DictionarySuggestions[0]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion1, Parameters.DictionarySuggestions[1]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion2, Parameters.DictionarySuggestions[2]); + model.AddItem(CefMenuCommand.SpellCheckSuggestion3, Parameters.DictionarySuggestions[3]); model.AddSeparator(); break; } model.AddItem(CefMenuCommand.AddToDictionary, "Ignore Word"); model.AddSeparator(); } - model.AddItem((CefMenuCommand)26510, "Emoji"); + model.AddItem(MenuEmoji, "Emoji"); model.AddSeparator(); model.AddItem(CefMenuCommand.Undo, "Undo"); model.AddItem(CefMenuCommand.Redo, "Redo"); @@ -74,37 +74,45 @@ public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser model.AddSeparator(); model.AddItem(CefMenuCommand.SelectAll, "Select All"); } - else if (!string.IsNullOrEmpty(parameters.LinkUrl)) + else if (!string.IsNullOrEmpty(Parameters.LinkUrl)) { - model.AddItem((CefMenuCommand)26502, "Open in new tab"); - model.AddItem(CefMenuCommand.Copy, "Copy link"); + model.AddItem(MenuOpenNewTab, "Open in new tab"); + model.AddItem(MenuCopyURL, "Copy link"); } - else if (!string.IsNullOrEmpty(parameters.SelectionText)) + else if (!string.IsNullOrEmpty(Parameters.SelectionText)) { - model.AddItem(CefMenuCommand.Find, $"Search \"{parameters.SelectionText}\" in new tab"); + model.AddItem(CefMenuCommand.Find, $"Search \"{Parameters.SelectionText}\" in new tab"); model.AddItem(CefMenuCommand.Copy, "Copy"); } else { - if (parameters.MediaType == ContextMenuMediaType.Image) + if (Parameters.MediaType == ContextMenuMediaType.Image) { model.AddItem(CefMenuCommand.Copy, "Copy image"); - model.AddItem((CefMenuCommand)26505, "Copy image link"); - model.AddItem((CefMenuCommand)26501, "Save image as"); + model.AddItem(MenuCopyURL, "Copy image link"); + model.AddItem(MenuSaveAs, "Save image as"); + //model.AddItem((CefMenuCommand)26502, "Open in paintbrush"); + } + else if (Parameters.MediaType == ContextMenuMediaType.Video) + { + model.AddItem(MenuCopyURL, "Copy video link"); + model.AddItem(MenuSaveAs, "Save video as"); + /*if (Parameters.MediaStateFlags == ContextMenuMediaState.CanPictureInPicture) + model.AddItem(MenuPictureInPicture, "Picture in picture");*/ } } } - private async void DownloadAndCopyImage(string imageUrl) + private async void DownloadAndCopyImage(string ImageUrl) { try { - using (var client = new HttpClient()) + using (var HttpClient = new HttpClient()) { - byte[] imageData = await client.GetByteArrayAsync(imageUrl); - if (imageData != null) + byte[] ImageData = await HttpClient.GetByteArrayAsync(ImageUrl); + if (ImageData != null) { - using (MemoryStream stream = new MemoryStream(imageData)) + using (MemoryStream stream = new MemoryStream(ImageData)) { BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); @@ -118,12 +126,21 @@ private async void DownloadAndCopyImage(string imageUrl) } } } - catch (Exception ex) - { - MessageBox.Show($"Failed to copy image: {ex.Message}"); - } + catch { } } + CefMenuCommand MenuSaveAs = (CefMenuCommand)26501; + CefMenuCommand MenuOpenNewTab = (CefMenuCommand)26502; + CefMenuCommand MenuInspector = (CefMenuCommand)26503; + CefMenuCommand MenuCopyURL = (CefMenuCommand)26504; + CefMenuCommand MenuScreenshot = (CefMenuCommand)26505; + CefMenuCommand MenuEmoji = (CefMenuCommand)26506; + //CefMenuCommand MenuPictureInPicture = (CefMenuCommand)26507; + + //CefMenuCommand MenuZoomReset = (CefMenuCommand)26510; + //CefMenuCommand MenuZoomIn = (CefMenuCommand)26511; + //CefMenuCommand MenuZoomOut = (CefMenuCommand)26512; + public bool OnContextMenuCommand(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags) { return ExecuteContextMenu(chromiumWebBrowser, browser, commandId, parameters); @@ -148,19 +165,19 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu Browser.AddWordToDictionary(Parameters.MisspelledWord); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26510) + else if (CommandID == MenuEmoji) CoreInputView.GetForCurrentView().TryShow(CoreInputViewKind.Emoji); } else if (!string.IsNullOrEmpty(Parameters.LinkUrl)) { App.Current.Dispatcher.Invoke(() => { - if (CommandID == (CefMenuCommand)26502) + if (CommandID == MenuOpenNewTab) { App.Instance.CurrentFocusedWindow().NewTab(Parameters.LinkUrl, true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); ToReturn = true; } - else if (CommandID == CefMenuCommand.Copy) + else if (CommandID == MenuCopyURL) { Clipboard.SetText(Parameters.LinkUrl); ToReturn = true; @@ -169,12 +186,11 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu } else if (!string.IsNullOrEmpty(Parameters.SelectionText)) { - string SelectedText = Parameters.SelectionText; App.Current.Dispatcher.Invoke(() => { if (CommandID == CefMenuCommand.Find) { - App.Instance.CurrentFocusedWindow().NewTab(Utils.FixUrl(string.Format(App.Instance.GlobalSave.Get("SearchEngine"), SelectedText)), true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); ; + App.Instance.CurrentFocusedWindow().NewTab(Utils.FixUrl(string.Format(App.Instance.GlobalSave.Get("SearchEngine"), Parameters.SelectionText)), true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); ; ToReturn = true; } }); @@ -189,12 +205,12 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu catch { Clipboard.SetText(Parameters.SourceUrl); } ToReturn = true; } - else if (CommandID == (CefMenuCommand)26505) + else if (CommandID == MenuCopyURL) { Clipboard.SetText(Parameters.SourceUrl); ToReturn = true; } - else if (CommandID == (CefMenuCommand)26501) + else if (CommandID == MenuSaveAs) { Browser.StartDownload(Parameters.SourceUrl); ToReturn = true; @@ -207,6 +223,23 @@ public bool ExecuteContextMenu(IWebBrowser WebBrowser, IBrowser Browser, CefMenu Process.Start(FileName); }*/ } + else if (Parameters.MediaType == ContextMenuMediaType.Video) + { + if (CommandID == MenuCopyURL) + { + Clipboard.SetText(Parameters.SourceUrl); + ToReturn = true; + } + else if (CommandID == MenuSaveAs) + { + Browser.StartDownload(Parameters.SourceUrl); + ToReturn = true; + } + /*else if (CommandID == MenuPictureInPicture) + { + ToReturn = true; + }*/ + } } if (!ToReturn) { @@ -346,17 +379,16 @@ void MenuClassToCollection(IEnumerable Menu, ItemCollection _ItemColl //_MenuItem.SetResourceReference(Control.StyleProperty, (Style)MainWindow.Instance.Resources["ApplyableMenuItemStyle"]); //_MenuItem.SetResourceReference(Control.OverridesDefaultStyleProperty, true); - if (Item.CommandId == CefMenuCommand.Back) - _MenuItem.IsEnabled = chromiumWebBrowser.CanGoBack; - else if (Item.CommandId == CefMenuCommand.Forward) - _MenuItem.IsEnabled = chromiumWebBrowser.CanGoForward; - else if (Item.CommandId == CefMenuCommand.Delete) - _MenuItem.IsEnabled = !string.IsNullOrEmpty(Parameters.SelectionText); + if (Item.CommandId == MenuOpenNewTab) + _MenuItem.Icon = "\uE8A7"; + else if (Item.CommandId == MenuCopyURL) + _MenuItem.Icon = "\ue71b"; else if (Item.CommandId == CefMenuCommand.Undo) _MenuItem.InputGestureText = "Ctrl+Z"; else if (Item.CommandId == CefMenuCommand.Redo) _MenuItem.InputGestureText = "Ctrl+Y"; + else if (Item.CommandId == CefMenuCommand.Cut) _MenuItem.InputGestureText = "Ctrl+X"; else if (Item.CommandId == CefMenuCommand.Copy) @@ -365,8 +397,14 @@ void MenuClassToCollection(IEnumerable Menu, ItemCollection _ItemColl _MenuItem.InputGestureText = "Ctrl+V"; else if (Item.CommandId == CefMenuCommand.SelectAll) _MenuItem.InputGestureText = "Ctrl+A"; - else if (Item.CommandId == (CefMenuCommand)26510) + else if (Item.CommandId == CefMenuCommand.Delete) + _MenuItem.IsEnabled = !string.IsNullOrEmpty(Parameters.SelectionText); + + else if (Item.CommandId == MenuEmoji) _MenuItem.InputGestureText = "Win+Period"; + + else if (Item.Header.StartsWith("Search")) + _MenuItem.Icon = "\uF6Fa"; else if (Item.CommandId == CefMenuCommand.SpellCheckSuggestion0 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion1 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion2 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion3 || Item.CommandId == CefMenuCommand.SpellCheckSuggestion4) _MenuItem.Icon = "\uf87b"; else if (Item.CommandId == CefMenuCommand.AddToDictionary) diff --git a/SLBr/Handlers/PermissionHandler.cs b/SLBr/Handlers/PermissionHandler.cs index 07142df..94a05fb 100644 --- a/SLBr/Handlers/PermissionHandler.cs +++ b/SLBr/Handlers/PermissionHandler.cs @@ -1,5 +1,7 @@ using CefSharp; using SLBr.Controls; +using Windows.Devices.Geolocation; +using Windows.UI.Notifications; namespace SLBr.Handlers { @@ -72,81 +74,100 @@ public bool OnShowPermissionPrompt(IWebBrowser chromiumWebBrowser, IBrowser brow { switch (option) { - case PermissionRequestType.MultipleDownloads: - Permissions += "Download multiple files automatically"; - PermissionIcons += "\xE896"; + case PermissionRequestType.AccessibilityEvents: + Permissions += "Respond to Accessibility Events"; + break; + case PermissionRequestType.ArSession: + Permissions += "Use your camera to create a 3D map of your surroundings"; + PermissionIcons += "\xE809"; + break; + case PermissionRequestType.CameraPanTiltZoom: + Permissions += "Move your camera"; + PermissionIcons += "\xE714"; break; case PermissionRequestType.CameraStream: Permissions += "Use your camera"; PermissionIcons += "\xE714"; break; - case PermissionRequestType.MicStream: - Permissions += "Use your microphone"; - PermissionIcons += "\xE720"; + case PermissionRequestType.CapturedSurfaceControl: + Permissions += "Scroll and zoom the contents of your shared tab"; + PermissionIcons += "\xec6c"; break; - case PermissionRequestType.CameraPanTiltZoom: - PermissionIcons += "\xE89E"; + case PermissionRequestType.Clipboard: + Permissions += "See text and images in clipboard"; + PermissionIcons += "\xF0E3"; break; - case PermissionRequestType.Notifications: - Permissions += "Show desktop notifications"; - PermissionIcons += "\xEA8F"; + case PermissionRequestType.TopLevelStorageAccess: + Permissions += "Access cookies and site data"; + PermissionIcons += "\xE8B7"; + break; + case PermissionRequestType.DiskQuota: + Permissions += "Store files on this device"; + PermissionIcons += "\xE8B7"; + break; + case PermissionRequestType.LocalFonts: + Permissions += "Use your computer fonts"; + PermissionIcons += "\xE8D2"; break; - case PermissionRequestType.Geolocation: Permissions += "Know your location"; PermissionIcons += "\xECAF"; break; - case PermissionRequestType.WindowPlacement: - PermissionIcons += "\xE737"; + case PermissionRequestType.Identity_Provider: + Permissions += "Use your accounts to login to websites"; + PermissionIcons += "\xef58"; break; - - case PermissionRequestType.ProtectedMediaIdentifier: - Permissions += "ProtectedMediaIdentifier"; - PermissionIcons += "\xEA69"; + case PermissionRequestType.IdleDetection: + Permissions += "Know when you're actively using this device"; + PermissionIcons += "\xEA6C"; + break; + case PermissionRequestType.MicStream: + Permissions += "Use your microphone"; + PermissionIcons += "\xE720"; break; case PermissionRequestType.MidiSysex: Permissions += "Use your MIDI devices"; PermissionIcons += "\xEC4F"; break; - - case PermissionRequestType.StorageAccess: - Permissions += "Store files on this device"; - PermissionIcons += "\xE8B7"; - break; - case PermissionRequestType.DiskQuota: + case PermissionRequestType.MultipleDownloads: + Permissions += "Download multiple files"; + PermissionIcons += "\xE896"; break; - case PermissionRequestType.LocalFonts: - Permissions += "LocalFonts"; - PermissionIcons += "\xE8D2"; + case PermissionRequestType.Notifications: + Permissions += "Show notifications"; + PermissionIcons += "\xEA8F"; break; - case PermissionRequestType.Clipboard: - Permissions += "See text and images copied to the clipboard"; - PermissionIcons += "\xF0E3"; + case PermissionRequestType.KeyboardLock: + Permissions += "Lock and use your keyboard"; + PermissionIcons += "\xf26b"; break; - - case PermissionRequestType.VrSession: - Permissions += "Use your virtual reality devices"; - PermissionIcons += "\xEC94"; + case PermissionRequestType.PointerLock: + Permissions += "Lock and use your mouse"; + PermissionIcons += "\xf271"; break; - case PermissionRequestType.ArSession: - Permissions += "Use your camera to create a 3D map of your surroundings"; - PermissionIcons += "\xE809"; - break; - - case PermissionRequestType.U2FApiRequest: - break; - - case PermissionRequestType.IdleDetection: - Permissions += "Know when you're actively using this device"; - PermissionIcons += "\xEA6C"; + case PermissionRequestType.ProtectedMediaIdentifier: + Permissions += "Know your unique device identifier"; + PermissionIcons += "\xef3f"; break; case PermissionRequestType.RegisterProtocolHandler: Permissions += "Open web links"; PermissionIcons += "\xE71B"; break; - case PermissionRequestType.AccessibilityEvents: + case PermissionRequestType.StorageAccess: + Permissions += "Access cookies and site data"; + PermissionIcons += "\xE8B7"; + break; + case PermissionRequestType.VrSession: + Permissions += "Use your virtual reality devices"; + PermissionIcons += "\xEC94"; + break; + case PermissionRequestType.WindowManagement: + Permissions += "Manage windows on all your displays"; + PermissionIcons += "\xE737"; break; - case PermissionRequestType.SecurityAttestation: + case PermissionRequestType.FileSystemAccess: + Permissions += "FileSystemAccess"; + PermissionIcons += "\xEC50";//E8B7 break; } Permissions += "\n"; diff --git a/SLBr/Handlers/PrivateJsObjectHandler.cs b/SLBr/Handlers/PrivateJsObjectHandler.cs index 530b5da..ef4ec78 100644 --- a/SLBr/Handlers/PrivateJsObjectHandler.cs +++ b/SLBr/Handlers/PrivateJsObjectHandler.cs @@ -1,6 +1,5 @@ using System.Diagnostics; using System.IO; -using System.Linq.Expressions; using System.Net; using System.Text.Json; using System.Xml; @@ -15,32 +14,35 @@ public string SearchProviderPrefix() => public string GetBackground() { string Url = ""; - string BackgroundImage = App.Instance.GlobalSave.Get("HomepageBackground"); - - if (BackgroundImage == "Bing") + switch (App.Instance.GlobalSave.Get("HomepageBackground")) { - string BingBackground = App.Instance.GlobalSave.Get("BingBackground"); - if (BingBackground == "Image of the day") - { - try + case "Bing": + string BingBackground = App.Instance.GlobalSave.Get("BingBackground"); + if (BingBackground == "Image of the day") { - XmlDocument doc = new XmlDocument(); - doc.LoadXml(new WebClient().DownloadString("http://www.bing.com/hpimagearchive.aspx?format=xml&idx=0&n=1&mbl=1&mkt=en-US")); - Url = @"http://www.bing.com/" + doc.SelectSingleNode(@"/images/image/url").InnerText; + try + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(new WebClient().DownloadString("http://www.bing.com/hpimagearchive.aspx?format=xml&idx=0&n=1&mbl=1&mkt=en-US")); + Url = @"http://www.bing.com/" + doc.SelectSingleNode(@"/images/image/url").InnerText; + } + catch { } } - catch { } - } - else if (BingBackground == "Random") - Url = "http://bingw.jasonzeng.dev/?index=random"; - } - else if (BackgroundImage == "Picsum") - Url = "http://picsum.photos/1920/1080?random"; - else if (BackgroundImage == "Custom") - { - Url = App.Instance.GlobalSave.Get("CustomBackgroundImage"); - if (!Utils.IsHttpScheme(Url) && File.Exists(Url)) - return $"url('data:image/png;base64,{Convert.ToBase64String(File.ReadAllBytes(Url))}')"; + else if (BingBackground == "Random") + Url = "http://bingw.jasonzeng.dev/?index=random"; + break; + + case "Picsum": + Url = "http://picsum.photos/1920/1080?random"; + break; + + case "Custom": + Url = App.Instance.GlobalSave.Get("CustomBackgroundImage"); + if (!Utils.IsHttpScheme(Url) && File.Exists(Url)) + Url = $"data:image/png;base64,{Convert.ToBase64String(File.ReadAllBytes(Url))}"; + break; } + return $"url('{Url}')"; } @@ -66,8 +68,7 @@ public bool OpenDownload(int DownloadId) } public bool CancelDownload(int DownloadId) { - if (!App.Instance.CanceledDownloads.Contains(DownloadId)) - App.Instance.CanceledDownloads.Add(DownloadId); + App.Instance._DownloadHandler.CancelDownload(DownloadId); return true; } } diff --git a/SLBr/Handlers/RequestHandler.cs b/SLBr/Handlers/RequestHandler.cs index 53ade6a..74f5925 100644 --- a/SLBr/Handlers/RequestHandler.cs +++ b/SLBr/Handlers/RequestHandler.cs @@ -1,12 +1,9 @@ using CefSharp; using SLBr.Controls; using SLBr.Pages; -using System; -using System.DirectoryServices.ActiveDirectory; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Windows; -using static SLBr.Handlers.SafeBrowsingHandler; namespace SLBr.Handlers { @@ -14,55 +11,26 @@ public class RequestHandler : IRequestHandler { Browser BrowserView; - public RequestHandler(/*bool _AdBlock = false, bool _TrackerBlock = false, */Browser _BrowserView = null) + public RequestHandler(Browser _BrowserView = null) { BrowserView = _BrowserView; - //AdBlock = _AdBlock; - //TrackerBlock = _TrackerBlock; } - //public bool AdBlock; - //public bool TrackerBlock; - - /*public long Image_Budget_Used; - public long Image_Budget = 2 * 1024 * 1024; - public long Stylesheet_Budget_Used; - public long Stylesheet_Budget = 400 * 1024; - public long Script_Budget_Used; - public long Script_Budget = 500 * 1024; - public long Font_Budget_Used; - public long Font_Budget = 300 * 1024;*/ - public long Image_Budget = 2 * 1024 * 1024; public long Stylesheet_Budget = 400 * 1024; public long Script_Budget = 500 * 1024; public long Font_Budget = 300 * 1024; + public long Frame_Budget = 5; - /*public long Connection_Budget_Used; - public long Connection_Budget = 10; + /*public long Connection_Budget = 10; public bool CanAffordAnotherConnection() { - return Connection_Budget_Used < Connection_Budget; + return Connection_Budget_Used > 0; }*/ public bool IsOverBudget(ResourceType _ResourceType) { - /*if (!App.Instance.NeverSlowMode) - return false;*/ - /*switch (_ResourceType) { - case ResourceType.Image: - return Image_Budget_Used >= Image_Budget; - case ResourceType.Stylesheet: - return Stylesheet_Budget_Used >= Stylesheet_Budget; - case ResourceType.Script: - return Script_Budget_Used >= Script_Budget; - case ResourceType.FontResource: - return Font_Budget_Used >= Font_Budget; - default: - //Not image, stylesheet, script, or font - return false; - }*/ switch (_ResourceType) { case ResourceType.Image: @@ -73,8 +41,9 @@ public bool IsOverBudget(ResourceType _ResourceType) return Script_Budget <= 0; case ResourceType.FontResource: return Font_Budget <= 0; + case ResourceType.SubFrame: + return Frame_Budget <= 0; default: - //Not image, stylesheet, script, or font return false; } } @@ -127,54 +96,26 @@ public bool IsOverBudget(ResourceType _ResourceType) public void DeductFromBudget(ResourceType _ResourceType, long DataLength) { /* Currently do not support budgeting for any of: - ResourceType.Object: - ResourceType::kSVGDocument: - ResourceType.Prefetch: - ResourceType::kTextTrack: - ResourceType.MainFrame: - ResourceType::kImportResource: - ResourceType.Media: - ResourceType::kManifest: - ResourceType::kMock:: - */ - /*switch (_ResourceType) - { - case ResourceType.Image: - Image_Budget_Used += DataLength; - //MessageBox.Show($"{_ResourceType} {Image_Budget_Used}:{Image_Budget}"); - return; - case ResourceType.Stylesheet: - Stylesheet_Budget_Used += DataLength; - //MessageBox.Show($"{_ResourceType} {Stylesheet_Budget_Used}:{Stylesheet_Budget}"); - return; - case ResourceType.Script: - Script_Budget_Used += DataLength; - //MessageBox.Show($"{_ResourceType} {Script_Budget_Used}:{Script_Budget}"); - return; - case ResourceType.FontResource: - Font_Budget_Used += DataLength; - //MessageBox.Show($"{_ResourceType} {Font_Budget_Used}:{Font_Budget}"); - return; - default: - break; - }*/ + * ResourceType.Object: + * ResourceType.Prefetch: + * ResourceType.MainFrame: + * ResourceType.Media:*/ switch (_ResourceType) { case ResourceType.Image: Image_Budget -= DataLength; - //MessageBox.Show($"{_ResourceType} {Image_Budget}"); return; case ResourceType.Stylesheet: Stylesheet_Budget -= DataLength; - //MessageBox.Show($"{_ResourceType} {Stylesheet_Budget}"); return; case ResourceType.Script: Script_Budget -= DataLength; - //MessageBox.Show($"{_ResourceType} {Script_Budget}"); return; case ResourceType.FontResource: Font_Budget -= DataLength; - //MessageBox.Show($"{_ResourceType} {Font_Budget}"); + return; + case ResourceType.SubFrame: + Frame_Budget -= DataLength; return; default: break; @@ -187,76 +128,202 @@ public void ResetBudgets() Stylesheet_Budget = 400 * 1024; Script_Budget = 500 * 1024; Font_Budget = 300 * 1024; - /*Image_Budget_Used = 0; - Stylesheet_Budget_Used = 0; - Script_Budget_Used = 0; - Font_Budget_Used = 0;*/ - //Connection_Budget_Used = 0; + Frame_Budget = 5; + //Connection_Budget = 10; } public bool GetAuthCredentials(IWebBrowser chromiumWebBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) - { - CredentialsDialogResult _CredentialsDialogResult = CredentialsDialog.Show($@"Sign in to {host}"); - if (_CredentialsDialogResult.Accepted == true) + { + /*CredentialsDialogWindow _CredentialsDialogWindow; + bool DialogResult = false; + string Username = ""; + string Password = ""; + App.Current.Dispatcher.Invoke(() => + { + _CredentialsDialogWindow = new CredentialsDialogWindow($"Sign in to {host}", "\uec19"); + _CredentialsDialogWindow.Topmost = true; + DialogResult = _CredentialsDialogWindow.ShowDialog().ToBool(); + Username = _CredentialsDialogWindow.Username; + Password = _CredentialsDialogWindow.Password; + }); + if (DialogResult == true) { - callback.Continue(_CredentialsDialogResult.Username, _CredentialsDialogResult.Password); + callback.Continue(Username, Password); return true; } - return false; - } + return false;*/ + + App.Current.Dispatcher.Invoke(() => + { + using (callback) + { + CredentialsDialogWindow _CredentialsDialogWindow = new CredentialsDialogWindow($"Sign in to {host}", "\uec19"); + _CredentialsDialogWindow.Topmost = true; + if (_CredentialsDialogWindow.ShowDialog().ToBool()) + callback.Continue(_CredentialsDialogWindow.Username, _CredentialsDialogWindow.Password); + else + callback.Cancel(); + } + }); + return true; + } public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect) { - if (Utils.IsHttpScheme(request.Url)) + if (App.Instance.NeverSlowMode && request.TransitionType == TransitionType.AutoSubFrame) + { + if (IsOverBudget(ResourceType.SubFrame)) + return true; + else + { + DeductFromBudget(ResourceType.SubFrame, 1); + return false; + } + } + if (Utils.IsHttpScheme(request.Url)) { if (App.Instance.GoogleSafeBrowsing) { ResourceRequestHandlerFactory _ResourceRequestHandlerFactory = (ResourceRequestHandlerFactory)chromiumWebBrowser.ResourceRequestHandlerFactory; - bool CheckSafe = true; - if (BrowserView != null && _ResourceRequestHandlerFactory.Handlers.ContainsKey(request.Url)) - CheckSafe = false; - if (CheckSafe && Utils.IsHttpScheme(request.Url)) - { - string Response = App.Instance._SafeBrowsing.Response(request.Url); - SafeBrowsingHandler.ThreatType _ThreatType = App.Instance._SafeBrowsing.GetThreatType(Response); - if (_ThreatType == SafeBrowsingHandler.ThreatType.Malware || _ThreatType == SafeBrowsingHandler.ThreatType.Unwanted_Software) - { - if (BrowserView != null) - { - if (frame.IsMain) - chromiumWebBrowser.NewLoadHtml(App.Instance.Malware_Error, request.Url, Encoding.UTF8, 1, _ThreatType.ToString()); - //chromiumWebBrowser.NewLoadHtml(App.Instance.Malware_Error, request.Url, Encoding.UTF8, true, 2, _ThreatType.ToString()); - } - return true; - } - else if (_ThreatType == SafeBrowsingHandler.ThreatType.Social_Engineering) - { - if (BrowserView != null) - { - if (frame.IsMain) - chromiumWebBrowser.NewLoadHtml(App.Instance.Deception_Error, request.Url, Encoding.UTF8, 1, _ThreatType.ToString()); - //chromiumWebBrowser.NewLoadHtml(App.Instance.Deception_Error, request.Url, Encoding.UTF8, true, 2, _ThreatType.ToString()); - } - return true; - } - } + if (!_ResourceRequestHandlerFactory.Handlers.ContainsKey(request.Url)) + { + SafeBrowsingHandler.ThreatType _ThreatType = App.Instance._SafeBrowsing.GetThreatType(App.Instance._SafeBrowsing.Response(request.Url)); + if (_ThreatType == SafeBrowsingHandler.ThreatType.Malware || _ThreatType == SafeBrowsingHandler.ThreatType.Unwanted_Software) + _ResourceRequestHandlerFactory.RegisterHandler(request.Url, ResourceHandler.GetByteArray(App.Instance.Malware_Error, Encoding.UTF8), "text/html", -1, _ThreatType.ToString()); + else if (_ThreatType == SafeBrowsingHandler.ThreatType.Social_Engineering) + _ResourceRequestHandlerFactory.RegisterHandler(request.Url, ResourceHandler.GetByteArray(App.Instance.Deception_Error, Encoding.UTF8), "text/html", -1, _ThreatType.ToString()); + } } } - if (BrowserView != null && frame.IsMain) - { - //TransitionType _TransitionType = request.TransitionType; - App.Current.Dispatcher.Invoke(async () => + else if (request.Url.StartsWith("chrome://")) + { + ResourceRequestHandlerFactory _ResourceRequestHandlerFactory = (ResourceRequestHandlerFactory)chromiumWebBrowser.ResourceRequestHandlerFactory; + if (!_ResourceRequestHandlerFactory.Handlers.ContainsKey(request.Url)) { - BrowserView.Tab.Icon = await App.Instance.SetIcon("", chromiumWebBrowser.Address); - /*if (!_TransitionType.HasFlag(TransitionType.ForwardBack) && !_TransitionType.HasFlag(TransitionType.Reload)) - BrowserView.AddNavigationEntry(chromiumWebBrowser.Address, ((ChromiumWebBrowser)chromiumWebBrowser).Title, BrowserView.CurrentNavigationEntry);*/ - }); - //MessageBox.Show($"{isRedirect.ToString()} {userGesture.ToString()} {request.TransitionType} {request.Url}"); + bool Block = false; + //https://source.chromium.org/chromium/chromium/src/+/main:ios/chrome/browser/shared/model/url/chrome_url_constants.cc + switch (request.Url.Substring(9)) + { + case string s when s.StartsWith("settings", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("history", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("downloads", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("flags", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("new-tab-page", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("bookmarks", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("apps", StringComparison.Ordinal): + Block = true; + break; + + case string s when s.StartsWith("dino", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("management", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("new-tab-page-third-party", StringComparison.Ordinal): + Block = true; + break; + + case string s when s.StartsWith("favicon", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("sandbox", StringComparison.Ordinal): + Block = true; + break; + + case string s when s.StartsWith("bookmarks-side-panel.top-chrome", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("customize-chrome-side-panel.top-chrome", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("read-later.top-chrome", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("tab-search.top-chrome", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("tab-strip.top-chrome", StringComparison.Ordinal): + Block = true; + break; + + case string s when s.StartsWith("support-tool", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("privacy-sandbox-dialog", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("chrome-signin", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("browser-switch", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("profile-picker", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("search-engine-choice", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("intro", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("sync-confirmation", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("app-settings", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("managed-user-profile-notice", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("reset-password", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("imageburner", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("connection-help", StringComparison.Ordinal): + Block = true; + break; + case string s when s.StartsWith("connection-monitoring-detected", StringComparison.Ordinal): + Block = true; + break; + //cast-feedback + } + if (Block) + _ResourceRequestHandlerFactory.RegisterHandler(request.Url, ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect(request.Url, CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ""); + } + } + if (frame.IsMain) + { + if (BrowserView != null) + { + //TransitionType _TransitionType = request.TransitionType; + App.Current.Dispatcher.Invoke(async () => + { + BrowserView.Tab.Icon = await App.Instance.SetIcon("", chromiumWebBrowser.Address); + }); + } + //if (App.Instance.NeverSlowMode) ResetBudgets(); } return false; } public bool OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) { + //callback.Dispose(); return true; } public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) @@ -272,18 +339,6 @@ public bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFram return false; } - public bool OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback) - { - var infoWindow = new InformationDialogWindow("Permission", $"Allow {Utils.Host(originUrl)} to", "", "Store files on this device", "Allow", "Block", "\xE8B7"); - infoWindow.Topmost = true; - if (infoWindow.ShowDialog() == true) - { - callback.Continue(true); - return true; - } - return false; - } - public void OnRenderViewReady(IWebBrowser browserControl, IBrowser browser) { } @@ -300,10 +355,7 @@ public IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWeb public void OnDocumentAvailableInMainFrame(IWebBrowser chromiumWebBrowser, IBrowser browser) { - chromiumWebBrowser.ExecuteScriptAsync(@"var style = document.createElement('style');style.textContent = `::-webkit-scrollbar {width:15px;border-radius:10px;border:5px solid transparent;background-clip:content-box;background-color: whitesmoke;} -::-webkit-scrollbar-thumb {height:56px;border-radius:10px;border:5px solid transparent;background-clip:content-box;background-color: gainsboro;transition:background-color 0.5s;} -::-webkit-scrollbar-thumb:hover{background-color:gray;transition:background-color 0.5s;} -::-webkit-scrollbar-corner{background-color:transparent;}`;document.head.append(style);"); + chromiumWebBrowser.ExecuteScriptAsync(@"var style=document.createElement('style');style.textContent=`::-webkit-scrollbar {width:15px;border-radius:10px;border:5px solid transparent;background-clip:content-box;background-color: whitesmoke;}::-webkit-scrollbar-thumb {height:56px;border-radius:10px;border:5px solid transparent;background-clip:content-box;background-color: gainsboro;transition:background-color 0.5s;}::-webkit-scrollbar-thumb:hover{background-color:gray;transition:background-color 0.5s;}::-webkit-scrollbar-corner{background-color:transparent;}`;document.head.append(style);"); if (bool.Parse(App.Instance.GlobalSave.Get("SmoothScroll"))) chromiumWebBrowser.ExecuteScriptAsync(@"!function(){var s,i,c,a,o={frameRate:150,animationTime:400,stepSize:100,pulseAlgorithm:!0,pulseScale:4,pulseNormalize:1,accelerationDelta:50,accelerationMax:3,keyboardSupport:!0,arrowScroll:50,fixedBackground:!0,excluded:""""},p=o,u=!1,d=!1,l={x:0,y:0},f=!1,m=document.documentElement,h=[],v={left:37,up:38,right:39,down:40,spacebar:32,pageup:33,pagedown:34,end:35,home:36},y={37:1,38:1,39:1,40:1};function b(){if(!f&&document.body){f=!0;var e=document.body,t=document.documentElement,o=window.innerHeight,n=e.scrollHeight;if(m=0<=document.compatMode.indexOf(""CSS"")?t:e,s=e,p.keyboardSupport&&Y(""keydown"",D),top!=self)d=!0;else if(o=p.animationTime,c=i?1:l/p.animationTime;p.pulseAlgorithm&&(c=F(c));var s=a.x*c-a.lastX>>0,u=a.y*c-a.lastY>>0;o+=s,n+=u,a.lastX+=s,a.lastY+=u,i&&(g.splice(r,1),r--)}h?window.scrollBy(o,n):(o&&(d.scrollLeft+=o),n&&(d.scrollTop+=n)),f||m||(g=[]),g.length?j(w,d,1e3/p.frameRate+1):(S=!1,null!=d.$scrollBehavior&&(d.style.scrollBehavior=d.$scrollBehavior,d.$scrollBehavior=null))};j(w,d,0),S=!0}}function e(e){f||b();var t=e.target;if(e.defaultPrevented||e.ctrlKey)return!0;if(N(s,""embed"")||N(t,""embed"")&&/\.pdf/i.test(t.src)||N(s,""object"")||t.shadowRoot)return!0;var o=-e.wheelDeltaX||e.deltaX||0,n=-e.wheelDeltaY||e.deltaY||0;o||n||(n=-e.wheelDelta||0),1===e.deltaMode&&(o*=40,n*=40);var r=z(t);return r?!!function(e){if(!e)return;h.length||(h=[e,e,e]);e=Math.abs(e),h.push(e),h.shift(),clearTimeout(a),a=setTimeout(function(){try{localStorage.SS_deltaBuffer=h.join("","")}catch(e){}},1e3);var t=120 { - App.Current.Dispatcher.Invoke(() => - { - ChromiumWebBrowser _ChromiumWebBrowser = (ChromiumWebBrowser)browserControl; - _ChromiumWebBrowser.Address = $"slbr://processcrashed?s={browserControl.Address}"; - }); - } - } - catch { } + chromiumWebBrowser.LoadUrl($"slbr://processcrashed?s={chromiumWebBrowser.Address}"); + }); + //} }*/ } } diff --git a/SLBr/Handlers/ResourceRequestHandler.cs b/SLBr/Handlers/ResourceRequestHandler.cs index 732b536..63e169f 100644 --- a/SLBr/Handlers/ResourceRequestHandler.cs +++ b/SLBr/Handlers/ResourceRequestHandler.cs @@ -41,16 +41,16 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, "google.com/ads", "play.google.com/log"/*, "youtube.com/ptracking", "youtube.com/pagead/adview", "youtube.com/api/stats/ads", "youtube.com/pagead/interaction",*/ }; - FastHashSet MinersFiles = new FastHashSet { + FastHashSet MinersFiles = new FastHashSet {//https://github.com/xd4rker/MinerBlock/blob/master/assets/filters.txt "cryptonight.wasm", "deepminer.js", "deepminer.min.js", "coinhive.min.js", "monero-miner.js", "wasmminer.wasm", "wasmminer.js", "cn-asmjs.min.js", "gridcash.js", "worker-asmjs.min.js", "miner.js", "webmr4.js", "webmr.js", "webxmr.js", "lib/crypta.js", "static/js/tpb.js", "bitrix/js/main/core/core_tasker.js", "bitrix/js/main/core/core_loader.js", "vbb/me0w.js", "lib/crlt.js", "pool/direct.js", "plugins/wp-monero-miner-pro", "plugins/ajcryptominer", "plugins/aj-cryptominer", "?perfekt=wss://", "?proxy=wss://", "?proxy=ws://" - };//https://github.com/xd4rker/MinerBlock/blob/master/assets/filters.txt - FastHashSet Miners = new FastHashSet { + }; + FastHashSet Miners = new FastHashSet {//https://v.firebog.net/hosts/static/w3kbl.txt "coin-hive.com", "coin-have.com", "adminer.com", "ad-miner.com", "coinminerz.com", "coinhive-manager.com", "coinhive.com", "prometheus.phoenixcoin.org", "coinhiveproxy.com", "jsecoin.com", "crypto-loot.com", "cryptonight.wasm", "cloudflare.solutions" - };//https://v.firebog.net/hosts/static/w3kbl.txt + }; FastHashSet Ads = new FastHashSet { "ads.google.com", "pagead2.googlesyndication.com", "afs.googlesyndication.com", "tpc.googlesyndication.com", "googletagservices.com", "googletagmanager.com", "ade.googlesyndication.com", "pagead2.googleadservices.com", "adservice.google.com", "googleadservices.com", "app-measurement.com", "googleads2.g.doubleclick.net", "googleads3.g.doubleclick.net", "googleads4.g.doubleclick.net", "googleads5.g.doubleclick.net", "googleads6.g.doubleclick.net", "googleads7.g.doubleclick.net", "googleads8.g.doubleclick.net", "googleads9.g.doubleclick.net", @@ -59,7 +59,7 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, "googleads.g.doubleclick.net", "pagead.l.doubleclick.net", "g.doubleclick.net", "fls.doubleclick.net", "gads.pubmatic.com", "ads.pubmatic.com", "ogads-pa.clients6.google.com",// "image6.pubmatic.com", "ads.facebook.com", "an.facebook.com", - "cdn.snigelweb.com", "cdn.connectad.io", //For w3schools + "cdn.snigelweb.com", "cdn.connectad.io", "pool.admedo.com", "c.pub.network", "media.ethicalads.io", "ad.youtube.com", "ads.youtube.com", "youtube.cleverads.vn", @@ -86,7 +86,7 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, "adsfs.oppomobile.com", "adx.ads.oppomobile.com", "ck.ads.oppomobile.com", "data.ads.oppomobile.com", "t.adx.opera.com", "bdapi-ads.realmemobile.com", "bdapi-in-ads.realmemobile.com", - "business.samsungusa.com", "samsungads.com", "ad.samsungadhub.com", "config.samsungads.com", "samsung-com.112.2o7.net", + "business.samsungusa.com", "samsungads.com", "ad.samsungadhub.com", "config.samsungads.com", "samsung-com.112.2o7.net", "ads.samsung.com", "click.oneplus.com", "click.oneplus.cn", "open.oneplus.net", "asadcdn.com", "ads.yieldmo.com", "match.adsrvr.org", "ads.servenobid.com", "e3.adpushup.com", "c1.adform.net", @@ -99,6 +99,7 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, "js.adscale.de", "gum.criteo.com", "js.hsadspixel.net", + "ad.mopub.com", "adserver.juicyads.com", "a.realsrv.com", "mc.yandex.ru", "a.vdo.ai", "adfox.yandex.ru", "adfstat.yandex.ru", "offerwall.yandex.net", "ads.msn.com", "adnxs.com", "adnexus.net", "bingads.microsoft.com", @@ -116,6 +117,12 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, "cdn.adsafeprotected.com", "rp.liadm.com", + "adx.adform.net", + "prebid.a-mo.net", + "a.pub.network", + "widgets.outbrain.com", + "hb.adscale.de", "bitcasino.io", + "h.seznam.cz", "d.seznam.cz", "ssp.seznam.cz", "cdn.performax.cz", "dale.performax.cz", "chip.performax.cz" }; @@ -191,7 +198,6 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, "ping.chartbeat.net", "logs.browser-intake-datadoghq.com", "onsiterecs.api.boomtrain.com", - "adx.adform.net", "b.6sc.co", "api.bounceexchange.com", "events.bouncex.net", @@ -212,26 +218,25 @@ public IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, "sync.sharethis.com", "bcp.crwdcntrl.net", - "prebid.a-mo.net", "tpsc-sgc.doubleverify.com", "cdn.doubleverify.com", "onetag-sys.com", "id5-sync.com", "bttrack.com", "idsync.rlcdn.com", "u.openx.net", "sync-t1.taboola.com", "x.bidswitch.net", "rtd-tm.everesttech.net", "usermatch.krxd.net", "visitor.omnitagjs.com", "ping.chartbeat.net", - "sync.outbrain.com", "widgets.outbrain.com", + "sync.outbrain.com", "collect.mopinion.com", "pb-server.ezoic.com", - "hb.adscale.de", "demand.trafficroots.com", "sync.srv.stackadapt.com", "sync.ipredictive.com", "analytics.vdo.ai", "tag-api-2-1.ccgateway.net", "sync.search.spotxchange.com", - "reporting.powerad.ai", "monitor.ebay.com", "beacon.walmart.com", "capture.condenastdigital.com", "a.pub.network" + "reporting.powerad.ai", "monitor.ebay.com", "beacon.walmart.com", "capture.condenastdigital.com" }; public CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) { - //MessageBox.Show(Utils.Host(frame.Url)); if (Utils.IsHttpScheme(request.Url)) { //https://chromium-review.googlesource.com/c/chromium/src/+/1265506/25/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc if (App.Instance.NeverSlowMode && Handler.IsOverBudget(request.ResourceType)) return CefReturnValue.Cancel; - if ((App.Instance.AdBlock || App.Instance.TrackerBlock) && !Utils.Host(frame.Url).EndsWith("ecosia.org", StringComparison.Ordinal)) + if (App.Instance.AdBlock || App.Instance.TrackerBlock) { + if (Utils.Host(browser.FocusedFrame.Url).EndsWith("ecosia.org", StringComparison.Ordinal)) + return CefReturnValue.Continue; if (request.ResourceType == ResourceType.Ping) { App.Instance.TrackersBlocked++; @@ -239,16 +244,16 @@ public CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrow } else if (Utils.IsPossiblyAd(request.ResourceType)) { - string CleanedUrl = Utils.CleanUrl(request.Url, true, true, true, true); if (request.ResourceType == ResourceType.Script || request.ResourceType == ResourceType.Xhr) { + string CleanedUrl = Utils.CleanUrl(request.Url, true, true, true, true); foreach (string Script in HasInLink) { if (CleanedUrl.AsSpan().IndexOf(Script, StringComparison.Ordinal) >= 0) return CefReturnValue.Cancel; } } - string Host = Utils.Host(CleanedUrl, true); + string Host = Utils.Host(request.Url, true); if (App.Instance.TrackerBlock && Analytics.Contains(Host)) { App.Instance.TrackersBlocked++; @@ -263,8 +268,7 @@ public CefReturnValue OnBeforeResourceLoad(IWebBrowser chromiumWebBrowser, IBrow } if (App.Instance.GoogleSafeBrowsing && Utils.CanCheckSafeBrowsing(request.ResourceType)) { - string Response = App.Instance._SafeBrowsing.Response(request.Url); - SafeBrowsingHandler.ThreatType _ThreatType = App.Instance._SafeBrowsing.GetThreatType(Response); + SafeBrowsingHandler.ThreatType _ThreatType = App.Instance._SafeBrowsing.GetThreatType(App.Instance._SafeBrowsing.Response(request.Url)); if (_ThreatType == SafeBrowsingHandler.ThreatType.Malware || _ThreatType == SafeBrowsingHandler.ThreatType.Unwanted_Software || _ThreatType == SafeBrowsingHandler.ThreatType.Social_Engineering) return CefReturnValue.Cancel; } diff --git a/SLBr/Handlers/ResourceRequestHandlerFactory.cs b/SLBr/Handlers/ResourceRequestHandlerFactory.cs index 1b086bb..9dac37d 100644 --- a/SLBr/Handlers/ResourceRequestHandlerFactory.cs +++ b/SLBr/Handlers/ResourceRequestHandlerFactory.cs @@ -10,26 +10,26 @@ public class ResourceRequestHandlerFactory : IResourceRequestHandlerFactory RequestHandler Handler; - public ResourceRequestHandlerFactory(RequestHandler _Handler, IEqualityComparer comparer = null) + public ResourceRequestHandlerFactory(RequestHandler _Handler, IEqualityComparer Comparer = null) { Handler = _Handler; - Handlers = new ConcurrentDictionary(comparer ?? StringComparer.OrdinalIgnoreCase); + Handlers = new ConcurrentDictionary(Comparer ?? StringComparer.OrdinalIgnoreCase); } - public virtual bool RegisterHandler(string url, byte[] data, string mimeType = ResourceHandler.DefaultMimeType/*, bool limitedUse = false*/, int uses = 1, string error = "") + public virtual bool RegisterHandler(string Url, byte[] Data, string MimeType = ResourceHandler.DefaultMimeType/*, bool limitedUse = false*/, int Uses = 1, string Error = "") { - if (Uri.TryCreate(url, UriKind.Absolute, out Uri URI)) + if (Uri.TryCreate(Url, UriKind.Absolute, out Uri URI)) { - var entry = new SLBrResourceRequestHandlerFactoryItem(data, mimeType/*, limitedUse*/, uses, error); - Handlers.AddOrUpdate(URI.AbsoluteUri, entry, (k, v) => entry); + var _Entry = new SLBrResourceRequestHandlerFactoryItem(Data, MimeType/*, limitedUse*/, Uses, Error); + Handlers.AddOrUpdate(URI.AbsoluteUri, _Entry, (k, v) => _Entry); return true; } return false; } - public virtual bool UnregisterHandler(string url) + public virtual bool UnregisterHandler(string Url) { - return Handlers.TryRemove(url, out _); + return Handlers.TryRemove(Url, out _); } bool IResourceRequestHandlerFactory.HasHandlers @@ -50,12 +50,12 @@ public class SLBrResourceRequestHandlerFactoryItem public int Uses; public string Error; - public SLBrResourceRequestHandlerFactoryItem(byte[] data, string mimeType, /*bool limitedUse, */int uses = 1, string _Error = "") + public SLBrResourceRequestHandlerFactoryItem(byte[] _Data, string _MimeType, /*bool limitedUse, */int _Uses = 1, string _Error = "") { - Data = data; - MimeType = mimeType; + Data = _Data; + MimeType = _MimeType; //LimitedUse = limitedUse; - Uses = uses; + Uses = _Uses; Error = _Error; } } @@ -67,10 +67,11 @@ protected virtual IResourceRequestHandler GetResourceRequestHandler(IWebBrowser if (Handlers.TryGetValue(request.Url, out SLBrResourceRequestHandlerFactoryItem Entry)) { if (Entry.Uses != -1) + { Entry.Uses -= 1; - //if (Entry.LimitedUse && Entry.Uses == 0) - if (Entry.Uses == 0) - Handlers.TryRemove(request.Url, out Entry); + if (Entry.Uses == 0) + Handlers.TryRemove(request.Url, out Entry); + } return new InMemoryResourceRequestHandler(Entry.Data, Entry.MimeType); } return new ResourceRequestHandler(Handler); diff --git a/SLBr/MainWindow.xaml b/SLBr/MainWindow.xaml index 0873922..51ab629 100644 --- a/SLBr/MainWindow.xaml +++ b/SLBr/MainWindow.xaml @@ -19,7 +19,7 @@ - + diff --git a/SLBr/MainWindow.xaml.cs b/SLBr/MainWindow.xaml.cs index 4daa0f8..b85454b 100644 --- a/SLBr/MainWindow.xaml.cs +++ b/SLBr/MainWindow.xaml.cs @@ -53,11 +53,8 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b { case MessageHelper.WM_COPYDATA: COPYDATASTRUCT _dataStruct = Marshal.PtrToStructure(lParam); - string _strMsg = Marshal.PtrToStringUni(_dataStruct.lpData, _dataStruct.cbData / 2); - NewTab(_strMsg, true); - if (Application.Current.MainWindow.WindowState == WindowState.Minimized) - Application.Current.MainWindow.WindowState = WindowState.Normal; - SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle); + NewTab(Marshal.PtrToStringUni(_dataStruct.lpData, _dataStruct.cbData / 2), true); + SetForegroundWindow(new WindowInteropHelper(this).Handle); handled = true; break; } @@ -66,35 +63,26 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b [DllImport("dwmapi.dll")] public static extern int DwmSetWindowAttribute(IntPtr hwnd, DwmWindowAttribute dwAttribute, ref int pvAttribute, int cbAttribute); - public void UpdateMica() - { - HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).EnsureHandle()); - int trueValue = 0x01; - int falseValue = 0x00; - if (App.Instance.CurrentTheme.DarkTitleBar) - DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref trueValue, Marshal.SizeOf(typeof(int))); - else - DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref falseValue, Marshal.SizeOf(typeof(int))); - DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_MICA_EFFECT, ref trueValue, Marshal.SizeOf(typeof(int))); - } - private void InitializeWindow() { Title = App.Instance.Username == "Default" ? "SLBr" : $"{App.Instance.Username} - SLBr"; ID = Utils.GenerateRandomId(); - HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).EnsureHandle()); - source.AddHook(new HwndSourceHook(WndProc)); + + HwndSource HwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).EnsureHandle()); + HwndSource.AddHook(new HwndSourceHook(WndProc)); + int trueValue = 0x01; + DwmSetWindowAttribute(HwndSource.Handle, DwmWindowAttribute.DWMWA_MICA_EFFECT, ref trueValue, Marshal.SizeOf(typeof(int))); + App.Instance.AllWindows.Add(this); if (App.Instance.WindowsSaves.Count < App.Instance.AllWindows.Count) App.Instance.WindowsSaves.Add(new Saving($"Window_{App.Instance.WindowsSaves.Count}.bin", App.Instance.UserApplicationWindowsPath)); InitializeComponent(); + UpdateUnloadTimer(); Tabs.Add(new BrowserTabItem(null) - { + /*{ TabStyle = (Style)FindResource("VerticalIconTabButton") - }); + }*/); TabsUI.ItemsSource = Tabs; - UpdateUnloadTimer(); - App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); } private void Window_Closing(object sender, CancelEventArgs e) @@ -104,7 +92,7 @@ private void Window_Closing(object sender, CancelEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e) { - SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); + SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")), int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); } public DispatcherTimer GCTimer; @@ -116,9 +104,8 @@ public void UpdateUnloadTimer() { if (bool.Parse(App.Instance.GlobalSave.Get("TabUnloading"))) { + GCTimer?.Stop(); GCTimerDuration = int.Parse(App.Instance.GlobalSave.Get("TabUnloadingTime")); - if (GCTimer != null) - GCTimer.Stop(); GCTimer = new DispatcherTimer(); if (bool.Parse(App.Instance.GlobalSave.Get("ShowUnloadProgress"))) @@ -144,37 +131,38 @@ public void UpdateUnloadTimer() } else { + GCTimer?.Stop(); foreach (BrowserTabItem _Tab in Tabs) { _Tab.ProgressBarVisibility = Visibility.Collapsed; if (!_Tab.IsUnloaded && _Tab.Content != null && _Tab.Content._Settings != null) _Tab.Content._Settings.UnloadProgressBar.Value = 0; } - if (GCTimer != null) - GCTimer.Stop(); } } private void GCCollect_Tick(object sender, EventArgs e) { - TimeSpan Elapsed = DateTime.Now - GCTimerStartTime; - double Progress = (Elapsed.TotalSeconds / (GCTimerDuration * 60)) * 1; + double Progress = (DateTime.Now - GCTimerStartTime).TotalSeconds / (GCTimerDuration * 60); if (Progress >= 1) { GCTimerStartTime = DateTime.Now; UnloadTabs(); } - double VisualProgress = Math.Min(Progress, 1) * 100; - foreach (BrowserTabItem _Tab in Tabs) + if (WindowState != WindowState.Minimized) { - if (!_Tab.IsUnloaded) + double VisualProgress = Math.Min(Progress, 1) * 100; + foreach (BrowserTabItem _Tab in Tabs) { - _Tab.Progress = VisualProgress; - if (_Tab.Content != null && _Tab.Content._Settings != null) - _Tab.Content._Settings.UnloadProgressBar.Value = VisualProgress; + if (_Tab.IsUnloaded) + _Tab.ProgressBarVisibility = Visibility.Collapsed; + else + { + _Tab.Progress = VisualProgress; + if (_Tab.Content != null && _Tab.Content._Settings != null) + _Tab.Content._Settings.UnloadProgressBar.Value = VisualProgress; + } } - else - _Tab.ProgressBarVisibility = Visibility.Collapsed; } } private void GCCollect_EfficientTick(object sender, EventArgs e) @@ -182,7 +170,7 @@ private void GCCollect_EfficientTick(object sender, EventArgs e) UnloadTabs(); } - public void SetAppearance(Theme _Theme, string TabAlignment, bool AllowHomeButton, bool AllowTranslateButton, bool AllowAIButton, bool AllowReaderModeButton) + public void SetAppearance(Theme _Theme, string TabAlignment, bool AllowHomeButton, bool AllowTranslateButton, bool AllowAIButton, bool AllowReaderModeButton, int ShowExtensionButton, int ShowFavouritesBar) { if (TabAlignment == "Vertical") { @@ -203,42 +191,34 @@ public void SetAppearance(Theme _Theme, string TabAlignment, bool AllowHomeButto Resources["IndicatorBrushColor"] = _Theme.IndicatorColor; foreach (BrowserTabItem Tab in Tabs) - { - if (Tab.Content != null) - Tab.Content.SetAppearance(_Theme, AllowHomeButton, AllowTranslateButton, AllowAIButton, AllowReaderModeButton); - } - //Why did I have this? - /*WindowStyle = WindowStyle.ThreeDBorderWindow; - WindowStyle = WindowStyle.SingleBorderWindow;*/ - UpdateMica(); + Tab.Content?.SetAppearance(_Theme, AllowHomeButton, AllowTranslateButton, AllowAIButton, AllowReaderModeButton, ShowExtensionButton, ShowFavouritesBar); + + HwndSource HwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).EnsureHandle()); + int trueValue = 0x01; + int falseValue = 0x00; + if (App.Instance.CurrentTheme.DarkTitleBar) + DwmSetWindowAttribute(HwndSource.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref trueValue, Marshal.SizeOf(typeof(int))); + else + DwmSetWindowAttribute(HwndSource.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref falseValue, Marshal.SizeOf(typeof(int))); } public void ButtonAction(object sender, RoutedEventArgs e) { - if (sender == null) - return; var Values = ((FrameworkElement)sender).Tag.ToString().Split(new string[] { "<,>" }, StringSplitOptions.None); Action((Actions)int.Parse(Values[0]), sender, (Values.Length > 1) ? Values[1] : "", (Values.Length > 2) ? Values[2] : "", (Values.Length > 3) ? Values[3] : ""); } private void Action(Actions _Action, object sender = null, string V1 = "", string V2 = "", string V3 = "") { - try - { - Browser _BrowserView = GetTab().Content; - if (_BrowserView != null) - { - V1 = V1.Replace("{CurrentUrl}", _BrowserView.Address); - V1 = V1.Replace("{CurrentInspectorUrl}", _BrowserView.Address); - } - } - catch { } + Browser _BrowserView = GetTab().Content; + if (_BrowserView != null) + V1 = V1.Replace("{CurrentUrl}", _BrowserView.Address); V1 = V1.Replace("{Homepage}", App.Instance.GlobalSave.Get("Homepage")); switch (_Action) { case Actions.Exit: - App.Instance.CloseSLBr(false); + App.Instance.CloseSLBr(true); break; case Actions.Undo: @@ -255,8 +235,11 @@ private void Action(Actions _Action, object sender = null, string V1 = "", strin break; case Actions.CreateTab: - if (V2 == "CurrentIndex") - NewTab(V1, true, TabsUI.SelectedIndex + 1); + if (V2 == "Tab") + { + BrowserTabItem _Tab = GetBrowserTabWithId(int.Parse(V1)); + NewTab(_Tab.Content.Address, true, Tabs.IndexOf(_Tab) + 1); + } else NewTab(V1, true); break; @@ -282,16 +265,32 @@ private void Action(Actions _Action, object sender = null, string V1 = "", strin private void Window_StateChanged(object sender, EventArgs e) { if (WindowState != WindowState.Minimized) - { - BrowserTabItem SelectedTab = Tabs[TabsUI.SelectedIndex]; - if (SelectedTab.Content != null) - SelectedTab.Content.ReFocus(); - } + Tabs[TabsUI.SelectedIndex].Content?.ReFocus(); } public void UnloadTabs() { - BrowserTabItem SelectedTab = Tabs[TabsUI.SelectedIndex]; + if (WindowState == WindowState.Minimized) + { + foreach (BrowserTabItem Tab in Tabs) + { + if (Tab.Content != null) + UnloadTab(Tab.Content); + } + } + else + { + for (int i = 0; i < Tabs.Count; i++) + { + if (i != TabsUI.SelectedIndex) + { + BrowserTabItem Tab = Tabs[i]; + if (Tab.Content != null) + UnloadTab(Tab.Content); + } + } + } + /*BrowserTabItem SelectedTab = Tabs[TabsUI.SelectedIndex]; foreach (BrowserTabItem Tab in Tabs) { if (WindowState == WindowState.Minimized || Tab != SelectedTab) @@ -299,7 +298,7 @@ public void UnloadTabs() if (Tab.Content != null) UnloadTab(Tab.Content); } - } + }*/ } public void ForceUnloadTab(int Id) { @@ -307,30 +306,15 @@ public void ForceUnloadTab(int Id) if (_Tab.Content != null) UnloadTab(_Tab.Content, true); } - /*private async void UnloadTab(Browser BrowserView, bool Bypass = false) - { - if (BrowserView.Chromium != null && BrowserView.Chromium.IsBrowserInitialized) - { - if (!Bypass && !await BrowserView.CanUnload()) - return; - BrowserView.Unload(); - } - }*/ private void UnloadTab(Browser BrowserView, bool Bypass = false) { - if (BrowserView.Chromium != null && BrowserView.Chromium.IsBrowserInitialized) - { - if (!Bypass && !BrowserView.CanUnload()) - return; + if (Bypass || BrowserView.CanUnload()) BrowserView.Unload(); - } } public void Favourite(string Id = "") { BrowserTabItem _Tab = string.IsNullOrEmpty(Id) ? Tabs[TabsUI.SelectedIndex] : GetBrowserTabWithId(int.Parse(Id)); - if (_Tab.Content == null) - return; - _Tab.Content.Favourite(); + _Tab.Content?.Favourite(); } public void Undo(string Id = "") { @@ -360,51 +344,42 @@ public void Refresh(string Id = "", bool IgnoreCache = false) } public void Navigate(string Url) { - Browser _Browser = GetTab().Content; - if (_Browser == null) - return; - _Browser.Navigate(Url); + GetTab().Content?.Navigate(Url); } public bool IsFullscreen; public void Fullscreen(bool Fullscreen) { IsFullscreen = Fullscreen; - if (Fullscreen) + Browser BrowserView = GetTab().Content; + if (BrowserView != null) { - Browser BrowserView = GetTab().Content; - if (BrowserView != null) + if (Fullscreen) { - BrowserView.CoreContainer.Children.Remove(BrowserView.Chromium); - FullscreenContainer.Children.Add(BrowserView.Chromium); - Keyboard.Focus(BrowserView.Chromium); - - WindowState = WindowState.Normal; + if (BrowserView.Chromium != null) + { + BrowserView.CoreContainer.Children.Remove(BrowserView.Chromium); + FullscreenContainer.Children.Add(BrowserView.Chromium); + Keyboard.Focus(BrowserView.Chromium); + } WindowStyle = WindowStyle.None; WindowState = WindowState.Maximized; } - } - else - { - WindowStyle = WindowStyle.SingleBorderWindow; - Browser BrowserView = GetTab().Content; - if (BrowserView != null) + else { - try + if (BrowserView.Chromium != null) { FullscreenContainer.Children.Remove(BrowserView.Chromium); BrowserView.CoreContainer.Children.Add(BrowserView.Chromium); Keyboard.Focus(BrowserView.Chromium); } - catch { } + WindowStyle = WindowStyle.SingleBorderWindow; } } } - public void DevTools(string Id = "", int XCoord = 0, int YCoord = 0) + public void DevTools(string Id = "")//, int XCoord = 0, int YCoord = 0) { BrowserTabItem _Tab = string.IsNullOrEmpty(Id) ? Tabs[TabsUI.SelectedIndex] : GetBrowserTabWithId(int.Parse(Id)); - if (_Tab.Content == null) - return; - _Tab.Content.DevTools(); + _Tab.Content?.DevTools();//(false, XCoord, YCoord); } public void NewTab(string Url, bool IsSelected = false, int Index = -1) { @@ -413,7 +388,6 @@ public void NewTab(string Url, bool IsSelected = false, int Index = -1) WindowState = WindowState.Normal; Activate(); } - Url = Url.Replace("{Homepage}", App.Instance.GlobalSave.Get("Homepage")); BrowserTabItem _Tab = new BrowserTabItem(this) { Header = Utils.CleanUrl(Url, true, true, true, true), BrowserCommandsVisibility = Visibility.Collapsed }; _Tab.Content = new Browser(Url, _Tab); Tabs.Insert(Index != -1 ? Index : Tabs.Count - 1, _Tab); @@ -421,12 +395,12 @@ public void NewTab(string Url, bool IsSelected = false, int Index = -1) TabsUI.SelectedIndex = Tabs.IndexOf(_Tab); } - public void SwitchToTab(BrowserTabItem _Tab) + /*public void SwitchToTab(BrowserTabItem _Tab) { TabsUI.SelectedIndex = Tabs.IndexOf(_Tab); if (_Tab.Content != null) Keyboard.Focus(_Tab.Content.Chromium); - } + }*/ public BrowserTabItem GetBrowserTabWithId(int Id) { foreach (BrowserTabItem _Tab in Tabs) @@ -470,22 +444,16 @@ public void CloseTab(int Id, int WindowId) } public void Find(string Text = "") { - Browser BrowserView = GetTab().Content; - if (BrowserView != null) - BrowserView.Find(Text); + GetTab().Content?.Find(Text); } public void Screenshot() { - Browser BrowserView = GetTab().Content; - if (BrowserView != null) - BrowserView.Screenshot(); + GetTab().Content?.Screenshot(); } public void Zoom(int Delta) { - Browser BrowserView = GetTab().Content; - if (BrowserView != null) - BrowserView.Zoom(Delta); + GetTab().Content?.Zoom(Delta); } public BrowserTabItem GetTab(Browser _Control = null) @@ -525,7 +493,10 @@ private void TabsUI_SelectionChanged(object sender, SelectionChangedEventArgs e) try { if (TabsUI.SelectedIndex == TabsUI.Items.Count - 1) - NewTab(App.Instance.GlobalSave.Get("Homepage"), true); + { + if (TabsUI.Visibility == Visibility.Visible) + NewTab(App.Instance.GlobalSave.Get("Homepage"), true); + } else { BrowserTabItem _CurrentTab = Tabs[TabsUI.SelectedIndex]; @@ -547,8 +518,7 @@ public void ExecuteCloseEvent() { foreach (BrowserTabItem Tab in Tabs) Tab.Content?.ToggleSideBar(true); - if (GCTimer != null) - GCTimer.Stop(); + GCTimer?.Stop(); if (App.Instance.AllWindows.Count == 1) App.Instance.CloseSLBr(false); else if (App.Instance.WindowsSaves.Count == App.Instance.AllWindows.Count) @@ -654,6 +624,7 @@ public int ParentWindowID get { return _ParentWindowID; } set { + DuplicateCommand = $"5<,>{ID}<,>Tab"; RefreshCommand = $"3<,>{ID}"; AddToFavouritesCommand = $"12<,>{ID}"; CloseCommand = $"6<,>{ID}<,>{value}"; @@ -695,6 +666,16 @@ public Visibility BrowserCommandsVisibility } } private Visibility _BrowserCommandsVisibility; + public string DuplicateCommand + { + get { return _DuplicateCommand; } + set + { + _DuplicateCommand = value; + RaisePropertyChanged("DuplicateCommand"); + } + } + private string _DuplicateCommand; public string RefreshCommand { get { return _RefreshCommand; } diff --git a/SLBr/Pages/Browser.xaml b/SLBr/Pages/Browser.xaml index 47b0a6c..8225d07 100644 --- a/SLBr/Pages/Browser.xaml +++ b/SLBr/Pages/Browser.xaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:SLBr.Pages" + xmlns:SLBr="clr-namespace:SLBr" xmlns:WinUI="clr-namespace:WinUI" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" GotFocus="Browser_GotFocus" Loaded="Browser_Loaded"> @@ -40,16 +41,7 @@ - - - - - + + + + --> diff --git a/SLBr/Pages/Browser.xaml.cs b/SLBr/Pages/Browser.xaml.cs index d403a2d..f145897 100644 --- a/SLBr/Pages/Browser.xaml.cs +++ b/SLBr/Pages/Browser.xaml.cs @@ -13,6 +13,7 @@ using System.IO; using System.Net; using System.Runtime.InteropServices; +using System.Security.Policy; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; @@ -56,30 +57,20 @@ public Browser(string Url, BrowserTabItem _Tab = null)//int _BrowserType = 0, { InitializeComponent(); Tab = _Tab != null ? _Tab : Tab.ParentWindow.GetTab(this); - Tab.Icon = App.Instance.GetIcon(Url); + Tab.Icon = App.Instance.GetIcon(bool.Parse(App.Instance.GlobalSave.Get("DownloadFavicons")) ? Url : ""); + Address = Url; SetAudioState(false); - CreateChromium(Url); //BrowserType = _BrowserType; + InitializeBrowserComponent(); FavouritesPanel.ItemsSource = App.Instance.Favourites; FavouriteListMenu.ItemsSource = App.Instance.Favourites; HistoryListMenu.ItemsSource = App.Instance.GlobalHistory; - DownloadListMenu.ItemsSource = App.Instance.CompletedDownloads; ExtensionsMenu.ItemsSource = App.Instance.Extensions; /*BrowserEmulatorComboBox.Items.Add("Chromium"); BrowserEmulatorComboBox.Items.Add("Edge"); BrowserEmulatorComboBox.Items.Add("Internet Explorer");*/ App.Instance.Favourites.CollectionChanged += Favourites_CollectionChanged; - SetAppearance(App.Instance.CurrentTheme, bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); - if (App.Instance.Favourites.Count == 0) - { - FavouriteScrollViewer.Margin = new Thickness(5, 0, 5, 5); - FavouriteContainer.Height = 5; - } - else - { - FavouriteScrollViewer.Margin = new Thickness(5, 5, 5, 5); - FavouriteContainer.Height = double.NaN; - } + SetAppearance(App.Instance.CurrentTheme, bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")),int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); OmniBoxTimer = new DispatcherTimer(); OmniBoxTimer.Tick += OmniBoxTimer_Tick; @@ -87,6 +78,14 @@ public Browser(string Url, BrowserTabItem _Tab = null)//int _BrowserType = 0, //BrowserEmulatorComboBox.SelectionChanged += BrowserEmulatorComboBox_SelectionChanged; } + public void InitializeBrowserComponent() + { + if (Chromium == null && Cef.IsInitialized.ToBool()) + CreateChromium(Address); + else + BrowserLoadChanged(Address, true); + } + TextBox OmniTextBox; Popup OmniBoxPopup; Grid OmniBoxPopupDropDown; @@ -124,8 +123,8 @@ private void Favourites_CollectionChanged(object? sender, System.Collections.Spe public void ButtonAction(object sender, RoutedEventArgs e) { - if (sender == null) - return; + /*if (sender == null) + return;*/ var Values = ((FrameworkElement)sender).Tag.ToString().Split(new string[] { "<,>" }, StringSplitOptions.None); Action((Actions)int.Parse(Values[0]), sender, (Values.Length > 1) ? Values[1] : "", (Values.Length > 2) ? Values[2] : "", (Values.Length > 3) ? Values[3] : ""); } @@ -136,7 +135,7 @@ public void Action(Actions _Action, object sender = null, string V1 = "", string switch (_Action) { case Actions.Exit: - App.Instance.CloseSLBr(false); + App.Instance.CloseSLBr(true); break; case Actions.Undo: @@ -153,8 +152,12 @@ public void Action(Actions _Action, object sender = null, string V1 = "", string break; case Actions.CreateTab: - if (V2 == "CurrentIndex") - Tab.ParentWindow.NewTab(V1, true, Tab.ParentWindow.TabsUI.SelectedIndex + 1); + if (V2 == "Tab") + { + BrowserTabItem _Tab = Tab.ParentWindow.GetBrowserTabWithId(int.Parse(V1)); + Tab.ParentWindow.NewTab(_Tab.Content.Address, true, Tab.ParentWindow.Tabs.IndexOf(_Tab) + 1); + //Tab.ParentWindow.NewTab(V1, true, Tab.ParentWindow.TabsUI.SelectedIndex + 1); + } else Tab.ParentWindow.NewTab(V1, true); break; @@ -213,12 +216,24 @@ public void Action(Actions _Action, object sender = null, string V1 = "", string case Actions.Find: Find(""); break; + + case Actions.ZoomIn: + App.Instance.CurrentFocusedWindow().Zoom(1); + break; + case Actions.ZoomOut: + App.Instance.CurrentFocusedWindow().Zoom(-1); + break; + case Actions.ZoomReset: + App.Instance.CurrentFocusedWindow().Zoom(0); + break; } } RequestHandler _RequestHandler; void CreateChromium(string Url) { + if (Chromium != null && (!Cef.IsInitialized.ToBool())) + return; Address = Url; Tab.IsUnloaded = true; Tab.BrowserCommandsVisibility = Visibility.Collapsed; @@ -238,22 +253,6 @@ void CreateChromium(string Url) Chromium.PermissionHandler = App.Instance._PermissionHandler; _ResourceRequestHandlerFactory = new Handlers.ResourceRequestHandlerFactory(_RequestHandler); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://settings", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://settings", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://sandbox", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://sandbox", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://apps", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://apps", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://downloads", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://downloads", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://flags", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://flags", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://history", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://history", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://new-tab-page", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://new-tab-page", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://new-tab-page-third-party", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://new-tab-page-third-party", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://bookmarks", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://bookmarks", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://management", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://management", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://bookmarks-side-panel.top-chrome", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://bookmarks-side-panel.top-chrome", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://customize-chrome-side-panel.top-chrome", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://customize-chrome-side-panel.top-chrome", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://read-later.top-chrome", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://read-later.top-chrome", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://support-tool", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://support-tool", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - _ResourceRequestHandlerFactory.RegisterHandler("chrome://tab-search.top-chrome", ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect("chrome://tab-search.top-chrome", CefErrorCode.InvalidUrl, "ERR_INVALID_URL"), Encoding.UTF8), "text/html", -1, ((int)CefErrorCode.InvalidUrl).ToString()); - Chromium.ResourceRequestHandlerFactory = _ResourceRequestHandlerFactory; Chromium.DisplayHandler = new DisplayHandler(this); Chromium.AllowDrop = true; @@ -297,11 +296,8 @@ private void Chromium_LoadError(object? sender, LoadErrorEventArgs e) bool IsMain = e.Frame.IsMain; Dispatcher.Invoke(() => { - string HTML = App.Instance.GenerateCannotConnect(e.FailedUrl, e.ErrorCode, e.ErrorText); - if (IsMain) - Chromium.NewLoadHtml(HTML, e.FailedUrl, Encoding.UTF8, 1, "Code" + ((int)e.ErrorCode).ToString()); - else - Chromium.NewNoLoadHtml(HTML, e.FailedUrl, Encoding.UTF8, 1, "Code" + ((int)e.ErrorCode).ToString()); + _ResourceRequestHandlerFactory.RegisterHandler(e.FailedUrl, ResourceHandler.GetByteArray(App.Instance.GenerateCannotConnect(e.FailedUrl, e.ErrorCode, e.ErrorText), Encoding.UTF8), "text/html", 1, ""); + e.Frame.LoadUrl(e.FailedUrl); }); } @@ -314,6 +310,11 @@ private void Chromium_IsBrowserInitializedChanged(object? sender, EventArgs e) if (bool.Parse(App.Instance.GlobalSave.Get("ShowUnloadProgress"))) Tab.ProgressBarVisibility = Visibility.Visible; Chromium.Focus(); + using (var DevToolsClient = Chromium.GetDevToolsClient()) + { + DevToolsClient.Page.SetPrerenderingAllowedAsync(false); + DevToolsClient.Preload.DisableAsync(); + } } } private void Chromium_StatusMessage(object? sender, StatusMessageEventArgs e) @@ -420,7 +421,7 @@ private void Chromium_LoadingStateChanged(object? sender, LoadingStateChangedEve //Hardware Concurrency 1, 2, 4, 6, 8, 10, 12, 14 //Device Memory 2, 3, 4, 6, 7, 8, 15, 16, 31, 32, 64 if (App.Instance.GlobalSave.Get("FingerprintLevel") != "Minimal") - Chromium.ExecuteScriptAsync(@"Object.defineProperty(navigator, 'getBattery', { get: function() { return new Promise((resolve, reject) => { reject('Battery API is disabled.'); }); }});Object.defineProperty(navigator, 'connection', { get: function() { return null; }});"); + Chromium.ExecuteScriptAsync(@"Object.defineProperty(navigator,'getBattery',{get:function(){return new Promise((resolve,reject)=>{reject('Battery API is disabled.');});}});Object.defineProperty(navigator,'connection',{get:function(){return null;}});"); } else { @@ -445,7 +446,7 @@ private void Chromium_LoadingStateChanged(object? sender, LoadingStateChangedEve var _UserAgentMetadata = new UserAgentMetadata { Brands = Brands, - Architecture = UserAgentGenerator.GetCpuArchitecture(), + Architecture = UserAgentGenerator.GetCPUArchitecture(), Model = "", Platform = "Windows", PlatformVersion = UserAgentGenerator.GetPlatformVersion(),//https://textslashplain.com/2021/09/21/determining-os-platform-version/ @@ -463,27 +464,9 @@ private void Chromium_LoadingStateChanged(object? sender, LoadingStateChangedEve Mobile = true };*/ //navigator.userAgentData.getHighEntropyValues(["architecture","model","platform","platformVersion","uaFullVersion"]).then(ua =>{console.log(ua)}); - _DevToolsClient.Emulation.SetUserAgentOverrideAsync(UserAgentGenerator.BuildUserAgentFromProduct($"SLBr/{App.Instance.ReleaseVersion} {UserAgentGenerator.BuildChromeBrand()}"), null, null, _UserAgentMetadata); + _DevToolsClient.Emulation.SetUserAgentOverrideAsync(App.Instance.UserAgent, null, null, _UserAgentMetadata); } } - string OutputUrl = Utils.ConvertUrlToReadableUrl(App.Instance._IdnMapping, Utils.CleanUrl(Address)); - if (OmniBox.Text != OutputUrl) - { - if (IsOmniBoxModifiable()) - { - if (Address == "slbr://newtab/") - { - OmniBoxPlaceholder.Visibility = Visibility.Visible; - OmniBox.Text = ""; - } - else - { - OmniBoxPlaceholder.Visibility = Visibility.Hidden; - OmniBox.Text = OutputUrl; - } - } - OmniBox.Tag = Address; - } BrowserLoadChanged(Address, e.IsLoading); //Chromium.GetDevToolsClient().Emulation.SetEmulatedMediaAsync(null, new List() { new MediaFeature() { Name = "prefers-reduced-motion", Value = "reduce" }, new MediaFeature() { Name = "prefers-reduced-data", Value = "reduce" } }); @@ -505,267 +488,161 @@ private void Chromium_LoadingStateChanged(object? sender, LoadingStateChangedEve { if (Utils.IsHttpScheme(Address)) { - if (Address.AsSpan().IndexOf("youtube.com/watch?v=", StringComparison.Ordinal) >= 0) + if (Address.AsSpan().IndexOf("youtube.com", StringComparison.Ordinal) >= 0) { - if (App.Instance.VideoQuality != "Auto") - Chromium.ExecuteScriptAsync($@"document.querySelector('.ytp-settings-button').click(); + if (App.Instance.SkipAds) + Chromium.ExecuteScriptAsync(@"var style=document.createElement('style'); +style.textContent=`ytd-action-companion-ad-renderer,ytd-display-ad-renderer,ytd-video-masthead-ad-advertiser-info-renderer,ytd-video-masthead-ad-primary-video-renderer,ytd-in-feed-ad-layout-renderer,ytd-ad-slot-renderer,yt-about-this-ad-renderer,yt-mealbar-promo-renderer,ytd-statement-banner-renderer,ytd-ad-slot-renderer,ytd-in-feed-ad-layout-renderer,ytd-banner-promo-renderer-backgroundstatement-banner-style-type-compact,.ytd-video-masthead-ad-v3-renderer,div#root.style-scope.ytd-display-ad-renderer.yt-simple-endpoint,div#sparkles-container.style-scope.ytd-promoted-sparkles-web-renderer,div#main-container.style-scope.ytd-promoted-video-renderer,div#player-ads.style-scope.ytd-watch-flexy,ad-slot-renderer,ytm-promoted-sparkles-web-renderer,masthead-ad,tp-yt-iron-overlay-backdrop,#masthead-ad{display:none !important;}`; +document.head.appendChild(style);"); + if (Address.AsSpan().IndexOf("youtube.com/watch?v=", StringComparison.Ordinal) >= 0) + { + if (App.Instance.SkipAds) + Chromium.ExecuteScriptAsync(@"setInterval(()=>{ + const video=document.querySelector(""div.ad-showing > div.html5-video-container > video""); + if (video){ + video.currentTime=video.duration; + setTimeout(()=>{for(const adCloseOverlay of document.querySelectorAll("".ytp-ad-overlay-close-container"")){adCloseOverlay.click();}for (const skipButton of document.querySelectorAll("".ytp-ad-skip-button-modern"")){skipButton.click();}},20); + } + for(const overlayAd of document.querySelectorAll("".ytp-ad-overlay-slot"")){overlayAd.style.visibility = ""hidden"";} +},250); +setInterval(()=>{ + const modalOverlay=document.querySelector(""tp-yt-iron-overlay-backdrop""); + document.body.style.setProperty('overflow-y','auto','important'); + if (modalOverlay){modalOverlay.removeAttribute(""opened"");modalOverlay.remove();} + const popup=document.querySelector("".style-scope ytd-enforcement-message-view-model""); + if (popup){ + const popupButton=document.getElementById(""dismiss-button""); + if(popupButton)popupButton.click(); + popup.remove(); + setTimeout(() => {if(video.paused)video.play();},500); + } +},1000);"); + if (App.Instance.VideoQuality != "Auto") + Chromium.ExecuteScriptAsync($@"document.querySelector('.ytp-settings-button').click(); const qualityMenuItem = Array.from(document.querySelectorAll('.ytp-menuitem')).find(el => el.textContent.includes('Quality')); if (qualityMenuItem) qualityMenuItem.click(); const desiredQualityItem = Array.from(document.querySelectorAll('.ytp-quality-menu .ytp-menuitem')).find(el => el.textContent.includes('{App.Instance.VideoQuality}')); if (desiredQualityItem) desiredQualityItem.click();"); - if (App.Instance.SkipAds) - Chromium.ExecuteScriptAsync(@"var skipAd = () => { - const video = document.querySelector(""div.ad-showing > div.html5-video-container > video""); - if (video) { - video.currentTime = video.duration; - setTimeout(() => { - const adCloseOverlays = document.querySelectorAll("".ytp-ad-overlay-close-container""); - for (const adCloseOverlay of adCloseOverlays) { adCloseOverlay.click(); } - const skipButtons = document.querySelectorAll("".ytp-ad-skip-button-modern""); - for (const skipButton of skipButtons) { skipButton.click(); } - }, 20) - setTimeout(() => { - const adCloseOverlays = document.querySelectorAll("".ytp-ad-overlay-close-container""); - for (const adCloseOverlay of adCloseOverlays) { adCloseOverlay.click(); } - const skipButtons = document.querySelectorAll("".ytp-ad-skip-button-modern""); - for (const skipButton of skipButtons) { skipButton.click(); } - }, 50) - } - const overlayAds = document.querySelectorAll("".ytp-ad-overlay-slot""); - for (const overlayAd of overlayAds) { overlayAd.style.visibility = ""hidden""; } -} -setInterval(() => { skipAd(); }, 500)"); + } } else if (Address.AsSpan().IndexOf("chromewebstore.google.com/detail/", StringComparison.Ordinal) >= 0) //button.addEventListener('click', function(){ engine.postMessage({ type: ""Extension""}); - Chromium.ExecuteScriptAsync(@"function callback() { + Chromium.ExecuteScriptAsync(@"function scanButton(){ const buttonQueries = ['button span[jsname]:not(:empty)'] -for (const button of document.querySelectorAll(buttonQueries.join(','))) { - const text = button.textContent || '' - if (text === 'Add to Chrome' || text === 'Remove from Chrome') - button.textContent = text.replace('Chrome', 'SLBr') - }); +for (const button of document.querySelectorAll(buttonQueries.join(','))){ + const text=button.textContent||'' + if (text==='Add to Chrome'||text==='Remove from Chrome') + button.textContent=text.replace('Chrome','SLBr') } } -callback() -const observer = new MutationObserver(callback) -observer.observe(document.body, { attributes: true, childList: true, subtree: true })"); +scanButton(); +new MutationObserver(scanButton).observe(document.body,{attributes:true,childList:true,subtree:true});"); //if (bool.Parse(App.Instance.GlobalSave.Get("LiteMode"))) //{ //Chromium.ExecuteScriptAsync(@"var style = document.createElement('style');style.type ='text/css';style.appendChild(document.createTextNode('*{ transition: none!important;-webkit-transition: none!important; }')); document.getElementsByTagName('head')[0].appendChild(style);"); //Chromium.ExecuteScriptAsync(@"Object.defineProperty(navigator.connection, 'saveData', { value: true, writable: false });"); //} if (bool.Parse(App.Instance.GlobalSave.Get("WebNotifications"))) - Chromium.ExecuteScriptAsync(@"(function(){ class Notification { - constructor(title, options) { - let packageSet = new Set(); + Chromium.ExecuteScriptAsync(@"class Notification { + constructor(title,options) { + let packageSet=new Set(); packageSet.add(title).add(options); - let json_package = JSON.stringify([...packageSet]); + let json_package=JSON.stringify([...packageSet]); engine.postMessage({type:""Notification"",data:json_package}); } - static requestPermission() { return new Promise((res, rej) => {res('granted');}) } -}; -window.Notification = Notification; -})();"); + static requestPermission(){return new Promise((res,rej)=>{res('granted');})} +};window.Notification=Notification;"); } else if (Address.StartsWith("file:///", StringComparison.Ordinal)) - Chromium.ExecuteScriptAsync(@" -var headerElement = document.getElementById('header'); -if (headerElement) + Chromium.ExecuteScriptAsync(@"document.documentElement.setAttribute('style',""display:table;margin:auto;"") +document.body.setAttribute('style',""margin:35px auto;font-family:system-ui;"") +var HeaderElement=document.getElementById('header'); +HeaderElement.setAttribute('style',""border:2px solid grey;border-radius:5px;padding:0 10px;margin:0 0 10px 0;"") +HeaderElement.textContent=HeaderElement.textContent.replace('Index of ',''); +document.getElementById('nameColumnHeader').setAttribute('style',""text-align:left;padding:7.5px;""); +document.getElementById('sizeColumnHeader').setAttribute('style',""text-align:center;padding:7.5px;""); +document.getElementById('dateColumnHeader').setAttribute('style',""text-align:center;padding:7.5px;""); +var style=document.createElement('style'); +style.type='text/css'; +style.innerHTML=`@media (prefers-color-scheme:light){a{color:black;}tr:nth-child(even){background-color: gainsboro;}#theader{background-color:gainsboro;}} +@media (prefers-color-scheme:dark){a{color:white;}tr:nth-child(even){background-color:#202225;}#theader{background-color:#202225;}} +td:first-child,th:first-child{border-radius:5px 0 0 5px;} +td:last-child,th:last-child{border-radius:0 5px 5px 0;}`; +document.body.appendChild(style); +const ParentDir=document.getElementById('parentDirLinkBox'); +if (ParentDir) { - document.documentElement.setAttribute('style', ""display: table; margin: auto;"") - document.body.setAttribute('style', ""margin: 35px auto;font-family: system-ui;"") - headerElement.setAttribute('style', ""border:2px solid grey; border-radius:5px; padding:0 10px; margin: 0 0 10px 0;"") - headerElement.textContent = headerElement.textContent.replace('Index of ', ''); - document.getElementById('nameColumnHeader').setAttribute('style', ""text-align: left; padding: 7.5px;""); - document.getElementById('sizeColumnHeader').setAttribute('style', ""text-align: center; padding: 7.5px;""); - document.getElementById('dateColumnHeader').setAttribute('style', ""text-align: center; padding: 7.5px;""); - var style = document.createElement('style'); - style.type = 'text/css'; - style.innerHTML = `@media (prefers-color-scheme: light) { a { color: black; } tr:nth-child(even) { background-color: gainsboro; } #theader { background-color: gainsboro; } } -@media (prefers-color-scheme: dark) { a { color: white; } tr:nth-child(even) { background-color: #202225; } #theader { background-color: #202225; } } -td:first-child, th:first-child { border-radius: 5px 0 0 5px; } -td:last-child, th:last-child { border-radius: 0 5px 5px 0; }`; - document.body.appendChild(style); - const parent_dir = document.getElementById('parentDirLinkBox'); - if (parent_dir) - { - if (window.getComputedStyle(parent_dir).display === 'block') { parent_dir.setAttribute('style', 'display: block; padding: 7.5px; margin:0 0 10px 0;'); } - else { parent_dir.setAttribute('style', 'display: none;'); } - parent_dir.querySelector('a.icon.up').setAttribute('style', 'background: none; padding-inline-start: .25em;'); - var element = document.createElement('p'); - element.setAttribute('style', ""font-family:'Segoe Fluent Icons'; margin:0; padding:0; display:inline; vertical-align:middle; user-select:none; color:navajowhite;"") - element.innerHTML = ''; - parent_dir.prepend(element); - parent_dir.querySelector('#parentDirText').innerHTML = ""Parent Directory""; - } - document.querySelectorAll('tbody > tr').forEach(row => { - const link = row.querySelector('a.icon'); - if (link) { - link.setAttribute('style', 'background: none; padding-inline-start: .5em;'); - var element = document.createElement('p'); - if (row.querySelector('a.icon.dir')) - { - link.textContent = link.textContent.replace(/\/$/, ''); - element.innerHTML = ''; - element.setAttribute('style', ""font-family:'Segoe Fluent Icons'; margin:0; padding:0; display:inline; vertical-align:middle; user-select:none; color:navajowhite;"") - } - else if (row.querySelector('a.icon.file')) - { - if (link.innerHTML.endsWith("".pdf"")) - element.innerHTML = ''; - else if (link.innerHTML.endsWith("".png"") || link.innerHTML.endsWith("".jpg"") || link.innerHTML.endsWith("".jpeg"") || link.innerHTML.endsWith("".avif"") || link.innerHTML.endsWith("".svg"") || link.innerHTML.endsWith("".webp"") || link.innerHTML.endsWith("".jfif"") || link.innerHTML.endsWith("".bmp"")) - element.innerHTML = ''; - else if (link.innerHTML.endsWith("".mp4"") || link.innerHTML.endsWith("".avi"") || link.innerHTML.endsWith("".ogg"") || link.innerHTML.endsWith("".webm"") || link.innerHTML.endsWith("".mov"") || link.innerHTML.endsWith("".mpej"") || link.innerHTML.endsWith("".wmv"") || link.innerHTML.endsWith("".h264"") || link.innerHTML.endsWith("".mkv"")) - element.innerHTML = ''; - else if (link.innerHTML.endsWith("".zip"") || link.innerHTML.endsWith("".rar"") || link.innerHTML.endsWith("".7z"") || link.innerHTML.endsWith("".tar.gz"") || link.innerHTML.endsWith("".tgz"")) - element.innerHTML = ''; - else if (link.innerHTML.endsWith("".txt"")) - element.innerHTML = ''; - else if (link.innerHTML.endsWith("".mp3"") || link.innerHTML.endsWith("".mp2"")) - element.innerHTML = ''; - else if (link.innerHTML.endsWith("".gif"")) - element.innerHTML = ''; - else if (link.innerHTML.endsWith("".blend"") || link.innerHTML.endsWith("".obj"") || link.innerHTML.endsWith("".fbx"") || link.innerHTML.endsWith("".max"") || link.innerHTML.endsWith("".stl"") || link.innerHTML.endsWith("".x3d"") || link.innerHTML.endsWith("".3ds"") || link.innerHTML.endsWith("".dae"") || link.innerHTML.endsWith("".glb"") || link.innerHTML.endsWith("".gltf"") || link.innerHTML.endsWith("".ply"")) - element.innerHTML = ''; - else - element.innerHTML = ''; - element.setAttribute('style', ""font-family:'Segoe Fluent Icons'; margin:0; padding:0; display:inline; vertical-align:middle; user-select:none;"") - } - row.querySelector('td').prepend(element); - row.children.item(0).setAttribute('style', ""text-align: left; padding: 7.5px;""); - row.children.item(1).setAttribute('style', ""text-align: center; padding: 7.5px;""); - row.children.item(2).setAttribute('style', ""text-align: center; padding: 7.5px;""); + if (window.getComputedStyle(ParentDir).display === 'block'){ParentDir.setAttribute('style','display:block;padding:7.5px;margin:0 0 10px 0;');} + else{ParentDir.setAttribute('style','display:none;');} + ParentDir.querySelector('a.icon.up').setAttribute('style','background:none;padding-inline-start:.25em;'); + var element=document.createElement('p'); + element.setAttribute('style',""font-family:'Segoe Fluent Icons';margin:0;padding:0;display:inline;vertical-align:middle;user-select:none;color:navajowhite;"") + element.innerHTML=''; + ParentDir.prepend(element); + ParentDir.querySelector('#parentDirText').innerHTML=""Parent Directory""; +} +document.querySelectorAll('tbody > tr').forEach(row => { + const link=row.querySelector('a.icon'); + if (link){ + link.setAttribute('style', 'background: none; padding-inline-start: .5em;'); + var element=document.createElement('p'); + if (row.querySelector('a.icon.dir')){ + link.textContent=link.textContent.replace(/\/$/,''); + element.innerHTML=''; + element.setAttribute('style',""font-family:'Segoe Fluent Icons';margin:0;padding:0;display:inline;vertical-align:middle;user-select:none;color:navajowhite;"") + } + else if (row.querySelector('a.icon.file')){ + if (link.innerHTML.endsWith("".pdf"")) + element.innerHTML=''; + else if (link.innerHTML.endsWith("".png"")||link.innerHTML.endsWith("".jpg"")||link.innerHTML.endsWith("".jpeg"")||link.innerHTML.endsWith("".avif"")||link.innerHTML.endsWith("".svg"")||link.innerHTML.endsWith("".webp"")||link.innerHTML.endsWith("".jfif"")||link.innerHTML.endsWith("".bmp"")) + element.innerHTML=''; + else if (link.innerHTML.endsWith("".mp4"")||link.innerHTML.endsWith("".avi"")||link.innerHTML.endsWith("".ogg"")||link.innerHTML.endsWith("".webm"")||link.innerHTML.endsWith("".mov"")||link.innerHTML.endsWith("".mpej"")||link.innerHTML.endsWith("".wmv"")||link.innerHTML.endsWith("".h264"")||link.innerHTML.endsWith("".mkv"")) + element.innerHTML=''; + else if (link.innerHTML.endsWith("".zip"")||link.innerHTML.endsWith("".rar"")||link.innerHTML.endsWith("".7z"")||link.innerHTML.endsWith("".tar.gz"")||link.innerHTML.endsWith("".tgz"")) + element.innerHTML=''; + else if (link.innerHTML.endsWith("".txt"")) + element.innerHTML=''; + else if (link.innerHTML.endsWith("".mp3"")||link.innerHTML.endsWith("".mp2"")) + element.innerHTML=''; + else if (link.innerHTML.endsWith("".gif"")) + element.innerHTML=''; + else if (link.innerHTML.endsWith("".blend"")||link.innerHTML.endsWith("".obj"")||link.innerHTML.endsWith("".fbx"")||link.innerHTML.endsWith("".max"")||link.innerHTML.endsWith("".stl"")||link.innerHTML.endsWith("".x3d"")||link.innerHTML.endsWith("".3ds"")||link.innerHTML.endsWith("".dae"")||link.innerHTML.endsWith("".glb"")||link.innerHTML.endsWith("".gltf"")||link.innerHTML.endsWith("".ply"")) + element.innerHTML=''; + else + element.innerHTML=''; + element.setAttribute('style',""font-family:'Segoe Fluent Icons';margin:0;padding:0;display:inline;vertical-align:middle;user-select:none;"") } - }); -}"); - //https://issues.chromium.org/issues/40766658 - if (bool.Parse(App.Instance.GlobalSave.Get("FlagEmoji"))) - // Unicode range generated by: https://wakamaifondue.com/beta/ - Chromium.ExecuteScriptAsync(@"var style = document.createElement(""style""); -style.setAttribute(""type"", ""text/css""); -style.textContent = ` - @font-face {font-family:""Twemoji Country Flags"";font-style: normal;src: url('https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1/dist/TwemojiCountryFlags.woff2') format('woff2');unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;} - @font-face {font-family: ""Twemoji Country Flags"";font-style: italic; /* Defined to prevent italic styled flags */src: url('https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1/dist/TwemojiCountryFlags.woff2') format('woff2');unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065, U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;} -`; -if (document.head != undefined){document.head.appendChild(style);} -var extentionStyleTagId = ""country-flag-feature""; -var extractFontFamilyRules = () => -{ - var fontFamilyRules = []; - for (var sheet of document.styleSheets) { - if (sheet.ownerNode.id == extentionStyleTagId) - continue; - var sheetMediaBlacklist = ['print', 'speech', 'aural', 'braille', 'handheld', 'projection', 'tty']; - if (sheetMediaBlacklist.includes(sheet.media.mediaText)) - continue; - try { - for (var rule of sheet.cssRules) { - if (!rule.style || !rule.style?.fontFamily) - continue; - var fontFamily = rule.style.fontFamily; - if (fontFamily == 'inherit') - continue; - if (fontFamily.toLowerCase().includes(""Twemoji Country Flags"".toLowerCase())) - continue; - var selectorText = rule.selectorText; - fontFamilyRules.push({ selectorText, fontFamily }); - } + row.querySelector('td').prepend(element); + row.children.item(0).setAttribute('style',""text-align:left;padding:7.5px;""); + row.children.item(1).setAttribute('style',""text-align:center;padding:7.5px;""); + row.children.item(2).setAttribute('style',""text-align:center;padding:7.5px;""); } - catch (e) { - } - } - return fontFamilyRules; -}; - -var createNewStyleTag = (fontFamilyRules) => -{ - var style = document.createElement(""style""); - style.setAttribute(""type"", ""text/css""); - style.setAttribute(""id"", extentionStyleTagId); - fontFamilyRules.forEach((rule) => {style.textContent += `${rule.selectorText} { font-family: 'Twemoji Country Flags', ${rule.fontFamily} !important; }\n`;}); - return style; -}; - -var applyCustomFontStyles = () => -{ - var existingSheet = document.getElementById(extentionStyleTagId); - if (existingSheet) - existingSheet.parentNode.removeChild(existingSheet); - if (document.head == null) - return; - document.head.appendChild(createNewStyleTag(extractFontFamilyRules())); -}; - -var preserveCustomFonts = (element) => -{ - if (element == undefined) - return; - var inlineStyle = element.getAttribute('style'); - if (!inlineStyle || !inlineStyle.includes('font-family')) - return; - var fontFamilyRegex = /font-family\s*:\s*([^;]+?)(\s*!important)?\s*(;|$)/; - var match = fontFamilyRegex.exec(inlineStyle); - if (!match) - return; - if (match[2] && match[2].includes('!important')) - return; - element.style.setProperty('font-family', match[1].trim(), 'important'); -} - -var lastStyleSheets = new Set(Array.from(document.styleSheets).map(sheet => sheet.href || sheet.ownerNode.textContent)); -var SLBrEmojiObserver = new MutationObserver((mutations) => -{ - mutations.forEach(mutation => - { - mutation.addedNodes.forEach(node => - { - if (node.id === extentionStyleTagId) - return; - var isStylesheet = node.nodeName === 'LINK' && node.rel === 'stylesheet'; - if (!isStylesheet && !(node.nodeName === 'STYLE')) - return; - var newStylesheetIdentifier = isStylesheet ? node.href : node.textContent; - if (lastStyleSheets.has(newStylesheetIdentifier)) - return; - applyCustomFontStyles(); - lastStyleSheets.add(newStylesheetIdentifier); - }); - }); - document.querySelectorAll('*').forEach(preserveCustomFonts); -}); -SLBrEmojiObserver.observe(document, { childList: true, subtree: true }); -applyCustomFontStyles(); -"); +});"); App.Instance.AddGlobalHistory(Address, Title); } if (bool.Parse(App.Instance.GlobalSave.Get("TabUnloading"))) - Chromium.ExecuteScriptAsync(@"(function() { - function SLBrSetupMediaListeners(mediaElement) { - if (mediaElement.tagName === 'AUDIO' && (mediaElement.muted || mediaElement.volume === 0)){return;} - mediaElement.removeEventListener('play',function(){engine.postMessage({type:""Media"",event:'Started'});}); - mediaElement.removeEventListener('pause',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); - mediaElement.removeEventListener('ended',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); - mediaElement.addEventListener('play',function(){engine.postMessage({type:""Media"",event:'Started'});}); - mediaElement.addEventListener('pause',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); - mediaElement.addEventListener('ended',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); - } - function SLBrSetupExistingMediaElements() {document.querySelectorAll('video, audio').forEach(function(mediaElement) {SLBrSetupMediaListeners(mediaElement);});} - const SLBrObserver = new MutationObserver(function(mutationsList) { - for (let mutation of mutationsList) { - if (mutation.type === 'childList') { - mutation.addedNodes.forEach(function(node) { - if (node.tagName === 'VIDEO' || node.tagName === 'AUDIO') - SLBrSetupMediaListeners(node); - else if (node.querySelectorAll) - node.querySelectorAll('video, audio').forEach(function(mediaElement) {SLBrSetupMediaListeners(mediaElement);}); - }); - } + Chromium.ExecuteScriptAsync(@"function SLBrSetupMediaListeners(mediaElement) { + if (mediaElement.tagName==='AUDIO'&&(mediaElement.muted||mediaElement.volume===0)){return;} + mediaElement.removeEventListener('play',function(){engine.postMessage({type:""Media"",event:'Started'});}); + mediaElement.removeEventListener('pause',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); + mediaElement.removeEventListener('ended',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); + mediaElement.addEventListener('play',function(){engine.postMessage({type:""Media"",event:'Started'});}); + mediaElement.addEventListener('pause',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); + mediaElement.addEventListener('ended',function(){engine.postMessage({type:""Media"",event:'Stopped'});}); +} +new MutationObserver(function(mutationsList){ + for (let mutation of mutationsList){ + if (mutation.type==='childList'){ + mutation.addedNodes.forEach(function(node) { + if (node.tagName==='VIDEO'||node.tagName==='AUDIO') + SLBrSetupMediaListeners(node); + else if (node.querySelectorAll) + node.querySelectorAll('video,audio').forEach(function(mediaElement) {SLBrSetupMediaListeners(mediaElement);}); + }); } - }); - SLBrObserver.observe(document.body, { childList: true, subtree: true }); - SLBrSetupExistingMediaElements(); -})();"); + } +}).observe(document.body,{childList:true,subtree:true}); +document.querySelectorAll('video,audio').forEach(function(mediaElement){SLBrSetupMediaListeners(mediaElement);});"); if (bool.Parse(App.Instance.GlobalSave.Get("AdaptiveTheme"))) { var contentSize = await Chromium.GetContentSizeAsync(); @@ -835,7 +712,7 @@ function SLBrSetupMediaListeners(mediaElement) { (byte)Math.Max(0, PrimaryColor.B * 1.95f)); } SiteTheme.PrimaryColor = PrimaryColor; - SetAppearance(SiteTheme, AllowHomeButton, AllowTranslateButton, AllowAIButton, AllowReaderModeButton); + SetAppearance(SiteTheme, AllowHomeButton, AllowTranslateButton, AllowAIButton, AllowReaderModeButton, ShowExtensionButton, ShowFavouritesBar); TabItem _TabItem = Tab.ParentWindow.TabsUI.ItemContainerGenerator.ContainerFromItem(Tab) as TabItem; _TabItem.Foreground = new SolidColorBrush(SiteTheme.FontColor); _TabItem.Background = new SolidColorBrush(SiteTheme.PrimaryColor); @@ -849,7 +726,7 @@ function SLBrSetupMediaListeners(mediaElement) { public bool CanUnload() { - return Muted || !AudioPlaying; + return (Muted || !AudioPlaying) && Chromium != null && Chromium.IsBrowserInitialized; } public async Task IsArticle() @@ -865,11 +742,26 @@ public async Task IsArticle() async void BrowserLoadChanged(string Address, bool IsLoading) { + string OutputUrl = Utils.ConvertUrlToReadableUrl(App.Instance._IdnMapping, Utils.CleanUrl(Address)); + if (OmniBox.Text != OutputUrl) + { + if (IsOmniBoxModifiable()) + { + if (Address == "slbr://newtab/") + { + OmniBoxPlaceholder.Visibility = Visibility.Visible; + OmniBox.Text = ""; + } + else + { + OmniBoxPlaceholder.Visibility = Visibility.Hidden; + OmniBox.Text = OutputUrl; + } + } + OmniBox.Tag = Address; + } if (App.Instance.Favourites.Count == 0) { - FavouriteScrollViewer.Margin = new Thickness(5, 0, 5, 5); - FavouriteContainer.Height = 5; - FavouriteButton.Content = "\xEB51"; FavouriteButton.Foreground = (SolidColorBrush)FindResource("FontBrush"); FavouriteButton.ToolTip = "Add from favourites"; @@ -877,8 +769,6 @@ async void BrowserLoadChanged(string Address, bool IsLoading) } else { - FavouriteScrollViewer.Margin = new Thickness(5, 5, 5, 5); - FavouriteContainer.Height = double.NaN; if (FavouriteExists(Address) != -1) { FavouriteButton.Content = "\xEB52"; @@ -894,6 +784,7 @@ async void BrowserLoadChanged(string Address, bool IsLoading) Tab.FavouriteCommandHeader = "Add from favourites"; } } + SetFavouritesBarVisibility(); AIChatButton.Visibility = AllowAIButton ? Visibility.Visible : Visibility.Collapsed; if (Address.StartsWith("slbr://settings")) { @@ -971,6 +862,8 @@ async void BrowserLoadChanged(string Address, bool IsLoading) SetSiteInfo = "File"; else if (Address.StartsWith("slbr:")) SetSiteInfo = "SLBr"; + else if (Address.StartsWith("chrome-extension:")) + SetSiteInfo = "Extension"; else SetSiteInfo = "Protocol"; } @@ -1011,6 +904,14 @@ async void BrowserLoadChanged(string Address, bool IsLoading) AIChatButton.Visibility = Visibility.Collapsed; //OpenFileExplorerButton.Visibility = Visibility.Visible; break; + case "Danger": + SiteInformationIcon.Text = "\xE730"; + SiteInformationIcon.Foreground = new SolidColorBrush(Colors.Red); + SiteInformationText.Text = $"Danger"; + SiteInformationPanel.ToolTip = $"Dangerous site"; + TranslateButton.Visibility = Visibility.Collapsed; + //OpenFileExplorerButton.Visibility = Visibility.Collapsed; + break; case "Protocol": SiteInformationIcon.Text = "\xE774"; SiteInformationIcon.Foreground = new SolidColorBrush(Colors.CornflowerBlue); @@ -1019,17 +920,17 @@ async void BrowserLoadChanged(string Address, bool IsLoading) TranslateButton.Visibility = Visibility.Collapsed; //OpenFileExplorerButton.Visibility = Visibility.Collapsed; break; - case "Danger": - SiteInformationIcon.Text = "\xE730"; - SiteInformationIcon.Foreground = new SolidColorBrush(Colors.Red); - SiteInformationText.Text = $"Danger"; - SiteInformationPanel.ToolTip = $"Dangerous site"; + case "Extension": + SiteInformationIcon.Text = "\xEA86"; + SiteInformationIcon.Foreground = new SolidColorBrush(App.Instance.GetTheme().FontColor); + SiteInformationText.Text = $"Extension"; + SiteInformationPanel.ToolTip = $"Extension"; TranslateButton.Visibility = Visibility.Collapsed; //OpenFileExplorerButton.Visibility = Visibility.Collapsed; break; case "Teapot": SiteInformationIcon.Text = "\xEC32"; - SiteInformationIcon.Foreground = new SolidColorBrush(Colors.CornflowerBlue); + SiteInformationIcon.Foreground = new SolidColorBrush(App.Instance.GetTheme().FontColor); SiteInformationText.Text = $"Teapot"; SiteInformationPanel.ToolTip = $"I'm a teapot"; TranslateButton.Visibility = AllowTranslateButton ? Visibility.Visible : Visibility.Collapsed; @@ -1051,13 +952,13 @@ async void BrowserLoadChanged(string Address, bool IsLoading) Tab.ProgressBarVisibility = Visibility.Visible; }*/ } - else + else if (SiteInformationText.Text != "Loading") { //SiteInformationIcon.Text = "\xED5A"; SiteInformationIcon.Text = "\xF16A"; SiteInformationIcon.Foreground = (SolidColorBrush)FindResource("FontBrush"); - SiteInformationText.Text = $"Loading"; - SiteInformationPanel.ToolTip = $"Loading"; + SiteInformationText.Text = "Loading"; + SiteInformationPanel.ToolTip = "Loading"; //TranslateButton.Visibility = Visibility.Collapsed; LoadingStoryboard.Begin(); } @@ -1146,8 +1047,7 @@ public void Unload() } public void ReFocus() { - if (Chromium == null) - CreateChromium(Address); + InitializeBrowserComponent(); if (Address.StartsWith("slbr://settings")) { if (Chromium != null) @@ -1236,8 +1136,6 @@ public async void Find(string Text, bool Forward = true, bool FindNext = false) private void FindButton_Click(object sender, RoutedEventArgs e) { - if (sender == null) - return; var Values = ((Button)sender).ToolTip.ToString().Split(new string[] { "<,>" }, StringSplitOptions.None); if (Values[0] == "Close") StopFinding(true); @@ -1413,6 +1311,7 @@ public void ToggleSideBar(bool ForceClose = false) SideBarRowTop.Height = new GridLength(0); if (IsUtilityContainerOpen) { + SideBarCoreContainer.Children.Clear(); _NewsFeed = null; AIChatBrowser?.Dispose(); AIChatBrowser = null; @@ -1469,29 +1368,26 @@ public void ToggleReaderMode() IsReaderMode = !IsReaderMode; if (IsReaderMode) { - var script = @"(function() { - const tagsToRemove = ['header', 'footer', 'nav', 'aside', 'ads', 'script']; - tagsToRemove.forEach(tag => { - const elements = document.getElementsByTagName(tag); - while(elements[0]) { elements[0].parentNode.removeChild(elements[0]); } - }); - const selectorsToRemove = ['.ad', '.sidebar', '#ad-container', '.footer', '.nav', '.site-top-menu', '.site-header', '.site-footer', '.sub-headerbar', '.article-left-sidebar', '.article-right-sidebar', '.article_bottom_text', '.read-next-panel', '.article-meta-author-details', '.onopen-discussion-panel', '.author-wrapper', '.follow', '.share-list', '.article-social-share-top', '.recommended-intersection-ref', '.engagement-widgets', '#further-reading', '.trending', '.detailDiscovery', '.globalFooter', '.relatedlinks', '#social_zone', '#user-feedback', '#user-feedback-button', '.feedback-section', '#opinionsListing']; - selectorsToRemove.forEach(selector => { - const elements = document.querySelectorAll(selector); - elements.forEach(element => { element.parentNode.removeChild(element); }); - }); - const article = document.querySelector('article'); - if (article) { - document.body.innerHTML = ''; - document.body.appendChild(article); - } else { - const mainContent = document.getElementById('main-content'); - if (mainContent) { - document.body.innerHTML = ''; - document.body.appendChild(mainContent); - } + var script = @"const tagsToRemove=['header','footer','nav','aside','ads','script']; +tagsToRemove.forEach(tag=>{ + const elements=document.getElementsByTagName(tag); + while(elements[0]){elements[0].parentNode.removeChild(elements[0]);} +}); +const selectorsToRemove=['.ad','.sidebar','#ad-container','.footer','.nav','.site-top-menu','.site-header','.site-footer','.sub-headerbar','.article-left-sidebar','.article-right-sidebar','.article_bottom_text','.read-next-panel','.article-meta-author-details','.onopen-discussion-panel','.author-wrapper','.follow','.share-list','.article-social-share-top','.recommended-intersection-ref','.engagement-widgets','#further-reading','.trending','.detailDiscovery','.globalFooter','.relatedlinks','#social_zone','#user-feedback','#user-feedback-button','.feedback-section','#opinionsListing']; +selectorsToRemove.forEach(selector=>{ + document.querySelectorAll(selector).forEach(element=>{element.parentNode.removeChild(element);}); +}); +const article=document.querySelector('article'); +if (article){ + document.body.innerHTML=''; + document.body.appendChild(article); +} else { + const mainContent=document.getElementById('main-content'); + if (mainContent){ + document.body.innerHTML=''; + document.body.appendChild(mainContent); } -})();"; +}"; Chromium.ExecuteScriptAsync(script); var css = @"* { @@ -1591,7 +1487,7 @@ public void ToggleReaderMode() height: auto !important; border-radius: 10px !important; }"; - Chromium.ExecuteScriptAsync($"var style = document.createElement('style'); style.innerHTML = `{css}`; document.head.appendChild(style);"); + Chromium.ExecuteScriptAsync($"var style=document.createElement('style');style.innerHTML=`{css}`;document.head.appendChild(style);"); } else Reload(); @@ -1694,7 +1590,7 @@ private void AIChatBrowser_LoadingStateChanged(object? sender, LoadingStateChang Color _IndicatorColor = (Color)FindResource("IndicatorBrushColor"); string IndicatorHex = $"#{_IndicatorColor.R:X2}{_IndicatorColor.G:X2}{_IndicatorColor.B:X2}{_IndicatorColor.A:X2}"; - string ChatJS = $@"const CSSVariables = `body {{ + string ChatJS = $@"const CSSVariables=`body {{ --cib-border-radius-circular: 5px; --cib-border-radius-extra-large: 5px; --cib-border-radius-large: 5px; @@ -1755,7 +1651,7 @@ private void AIChatBrowser_LoadingStateChanged(object? sender, LoadingStateChang element.parentNode.removeChild(element); }});"; - string ComposeJS = $@"const CSSVariables = `::-webkit-scrollbar {{ + string ComposeJS = $@"const CSSVariables=`::-webkit-scrollbar {{ background: {PrimaryHex} !important; }} .uds_coauthor_wrapper .sidebar {{ @@ -2059,7 +1955,7 @@ .uds_coauthor_wrapper .change-suggestion.tag {{ if (AIChatBrowser != null && AIChatBrowser.IsBrowserInitialized) { AIChatBrowser.Visibility = Visibility.Visible; - if (AIChatBrowser.Address.StartsWith("http://edgeservices.bing.com/edgesvc/compose")) + if (AIChatBrowser.Address.StartsWith("https://edgeservices.bing.com/edgesvc/compose", StringComparison.Ordinal)) AIChatBrowser.ExecuteScriptAsync(ComposeJS); else { @@ -2068,11 +1964,11 @@ .uds_coauthor_wrapper .change-suggestion.tag {{ Task.Factory.StartNew(() => Thread.Sleep(500)) .ContinueWith((t) => { - AIChatBrowser.ExecuteScriptAsync(@"var elements = document.querySelectorAll('.b_wlcmLogo'); -elements.forEach(function(logo) { - if (logo.shadowRoot) { - const defsElement = logo.shadowRoot.querySelector(""defs""); - if (defsElement) { + AIChatBrowser.ExecuteScriptAsync(@"var elements=document.querySelectorAll('.b_wlcmLogo'); +elements.forEach(function(logo){ + if (logo.shadowRoot){ + const defsElement=logo.shadowRoot.querySelector(""defs""); + if (defsElement){ defsElement.innerHTML = ` @@ -2108,57 +2004,41 @@ .uds_coauthor_wrapper .change-suggestion.tag {{ } } }); -function applyStyles() { - const applyCSS = (element, css) => { const style = document.createElement('style'); style.textContent = css; element.appendChild(style); }; - var elements = document.querySelectorAll('.b_wlcmPersName'); - elements.forEach(function(element) { element.parentNode.removeChild(element); }); - var elements = document.querySelectorAll('.b_wlcmPersDesc'); - elements.forEach(function(element) { element.parentNode.removeChild(element); }); - var elements = document.querySelectorAll('.b_wlcmPersAuthorText'); - elements.forEach(function(element) { element.parentNode.removeChild(element); }); - var elements = document.querySelectorAll('.b_wlcmCont'); - elements.forEach(function(element) { - if (element.id == 'b_sydWelcomeTemplate_') { - var elements = document.querySelectorAll('.b_ziCont'); - elements.forEach(function(element) { element.parentNode.removeChild(element); }); - } - }); - const cibSerpMain = document.querySelector('.cib-serp-main'); - const cibConversation = cibSerpMain.shadowRoot.querySelector('#cib-conversation-main'); - const cibChatTurns = cibConversation.shadowRoot.querySelectorAll('cib-chat-turn'); - cibChatTurns.forEach(cibChatTurn=> { - const cibMessageGroups = cibChatTurn.shadowRoot.querySelectorAll('cib-message-group'); +function applyStyles(){ + const applyCSS=(element,css)=>{const style=document.createElement('style');style.textContent=css;element.appendChild(style);}; + document.querySelectorAll('.b_wlcmPersName').forEach(function(element){element.parentNode.removeChild(element);}); + document.querySelectorAll('.b_wlcmPersDesc').forEach(function(element){element.parentNode.removeChild(element);}); + document.querySelectorAll('.b_wlcmPersAuthorText').forEach(function(element){element.parentNode.removeChild(element);}); + document.querySelectorAll('.b_wlcmCont').forEach(function(element){if (element.id=='b_sydWelcomeTemplate_'){document.querySelectorAll('.b_ziCont').forEach(function(element){element.parentNode.removeChild(element);});}}); + const cibChatTurns=document.querySelector('.cib-serp-main').shadowRoot.querySelector('#cib-conversation-main').shadowRoot.querySelectorAll('cib-chat-turn'); + cibChatTurns.forEach(cibChatTurn=>{ + const cibMessageGroups=cibChatTurn.shadowRoot.querySelectorAll('cib-message-group'); cibMessageGroups.forEach(cibMessageGroup => { - const cibMessageGroupShadowRoot = cibMessageGroup.shadowRoot; - const header = cibMessageGroupShadowRoot.querySelector('.header'); - const cibMessage = cibMessageGroupShadowRoot.querySelector('cib-message'); - if (cibMessage) { - const cibShared = cibMessage.shadowRoot.querySelector('cib-shared'); - const footer = cibMessage.shadowRoot.querySelector('.footer'); - if (cibShared) { - applyCSS(cibMessage.shadowRoot, `:host([source=user]) .text-message-content div { - background: var(--cib-color-fill-accent-gradient-primary) !important; - border-radius: 5px !important; - padding: 15px !important; - text-align: right !important; - align-self: flex-end; - color: white !important; -} -:host([source=user]) .text-message-content[user] img { - margin-inline-end: 0px !important; - margin-inline-start: auto !important; + const cibMessageGroupShadowRoot=cibMessageGroup.shadowRoot; + const header=cibMessageGroupShadowRoot.querySelector('.header'); + const cibMessage=cibMessageGroupShadowRoot.querySelector('cib-message'); + if (cibMessage){ + const cibShared=cibMessage.shadowRoot.querySelector('cib-shared'); + const footer=cibMessage.shadowRoot.querySelector('.footer'); + if (cibShared){ + applyCSS(cibMessage.shadowRoot,`:host([source=user]) .text-message-content div{ + background:var(--cib-color-fill-accent-gradient-primary) !important; + border-radius:5px !important; + padding:15px !important; + text-align:right !important; + align-self:flex-end; + color:white !important; } -:host([source=user]) .footer { - align-self: flex-end !important; -}`); +:host([source=user]) .text-message-content[user] img{margin-inline-end:0px !important;margin-inline-start:auto !important;} +:host([source=user]) .footer{align-self:flex-end !important;}`); } - if (footer) { - const cibMessageActions = footer.querySelector('cib-message-actions'); - if (cibMessageActions) { - const cibMessageActionsShadowRoot = cibMessageActions.shadowRoot; + if (footer){ + const cibMessageActions=footer.querySelector('cib-message-actions'); + if (cibMessageActions){ + const cibMessageActionsShadowRoot=cibMessageActions.shadowRoot; const container = cibMessageActionsShadowRoot.querySelector('.container'); - if (container) { - const searchButton = container.querySelector('#search-on-bing-button'); + if (container){ + const searchButton=container.querySelector('#search-on-bing-button'); if (searchButton) searchButton.remove(); } @@ -2166,21 +2046,20 @@ function applyStyles() { } } if (header) - applyCSS(cibMessageGroupShadowRoot, `:host([source=user]) .header { align-self: flex-end !important; } :host([source=user]) { align-items: flex-end; } `); + applyCSS(cibMessageGroupShadowRoot,`:host([source=user]) .header{align-self:flex-end !important;} :host([source=user]){align-items:flex-end;}`); }); }); } applyStyles(); -const observer = new MutationObserver(applyStyles); -observer.observe(document.body, { attributes: true, childList: true, subtree: true });"); +new MutationObserver(applyStyles).observe(document.body,{attributes:true,childList:true,subtree:true});"); - if (AIChatBrowser.Address.Contains("mobfull,moblike")) - AIChatBrowser.ExecuteScriptAsync(@"const LateStyle = document.createElement('style'); -LateStyle.type = 'text/css'; -LateStyle.innerHTML = `.zero_state_item { border-radius: 5px !important; }`; + /*if (AIChatBrowser.Address.Contains("mobfull,moblike")) + AIChatBrowser.ExecuteScriptAsync(@"const LateStyle=document.createElement('style'); +LateStyle.type='text/css'; +LateStyle.innerHTML=`.zero_state_item{border-radius:5px !important;}`; document.querySelector('.cib-serp-main').shadowRoot.querySelector('#cib-conversation-main').shadowRoot.querySelector('cib-welcome-container').shadowRoot.querySelector('.zero_state_wrap').shadowRoot.appendChild(LateStyle); -document.querySelector('.cib-serp-main').shadowRoot.querySelector('#cib-conversation-main').shadowRoot.querySelector('cib-welcome-container').shadowRoot.querySelector('.zero_state_wrap').shadowRoot.querySelector('.hello_text').innerHTML = ""Suggestions""; -document.querySelector('.cib-serp-main').shadowRoot.querySelector('#cib-conversation-main').shadowRoot.querySelector('cib-welcome-container').shadowRoot.querySelector('.preview-container').remove();"); +document.querySelector('.cib-serp-main').shadowRoot.querySelector('#cib-conversation-main').shadowRoot.querySelector('cib-welcome-container').shadowRoot.querySelector('.zero_state_wrap').shadowRoot.querySelector('.hello_text').innerHTML=""Suggestions""; +document.querySelector('.cib-serp-main').shadowRoot.querySelector('#cib-conversation-main').shadowRoot.querySelector('cib-welcome-container').shadowRoot.querySelector('.preview-container').remove();");*/ }, syncContextScheduler); } } @@ -2216,13 +2095,13 @@ public void AIChatFeature(int Feature) if (App.Instance.CurrentTheme.DarkWebPage) AIChatAddress += "&darkschemeovr=1"; AIChatBrowser.Address = AIChatAddress; - break; - case 1: + break; + /*case 1: string AIMobAddress = "http://edgeservices.bing.com/edgesvc/chat?udsframed=1&form=SHORUN&clientscopes=chat,noheader,mobfull,moblike"; if (App.Instance.CurrentTheme.DarkWebPage) AIMobAddress += "&darkschemeovr=1"; AIChatBrowser.Address = AIMobAddress; - break; + break;*/ case 2: string AIComposeAddress = "http://edgeservices.bing.com/edgesvc/compose?udsframed=1&clientscopes=chat,noheader"; if (App.Instance.CurrentTheme.DarkWebPage) @@ -2246,7 +2125,7 @@ public void Favourite() } else if (!IsLoading) { - var infoWindow = new PromptDialogWindow("Prompt", $"Add favourite", "Name", Title); + var infoWindow = new PromptDialogWindow("Prompt", $"Add Favourite", "Name", Title); infoWindow.Topmost = true; if (infoWindow.ShowDialog() == true) { @@ -2257,28 +2136,40 @@ public void Favourite() Tab.FavouriteCommandHeader = "Remove from favourites"; } } - if (App.Instance.Favourites.Count == 0) + } + + public void SetFavouritesBarVisibility() + { + if (ShowFavouritesBar == 0) { - FavouriteScrollViewer.Margin = new Thickness(5, 0, 5, 5); - FavouriteContainer.Height = 5; + if (App.Instance.Favourites.Count == 0) + { + FavouriteScrollViewer.Margin = new Thickness(0); + FavouriteContainer.Height = 5; + } + else + { + FavouriteScrollViewer.Margin = new Thickness(5, 5, 5, 5); + FavouriteContainer.Height = 41.25f; + } } - else + else if (ShowFavouritesBar == 1) { FavouriteScrollViewer.Margin = new Thickness(5, 5, 5, 5); - FavouriteContainer.Height = double.NaN; + FavouriteContainer.Height = 41.25f; + } + else if (ShowFavouritesBar == 2) + { + FavouriteScrollViewer.Margin = new Thickness(0); + FavouriteContainer.Height = 5; } } + int FavouriteExists(string Url) { if (App.Instance.Favourites.Count == 0) return -1; - string[] FavouriteUrls = App.Instance.Favourites.Select(item => item.Tooltip).ToArray(); - for (int i = 0; i < FavouriteUrls.Length; i++) - { - if (FavouriteUrls[i] == Url) - return i; - } - return -1; + return App.Instance.Favourites.ToList().FindIndex(0, i => i.Tooltip == Url); } public void Zoom(int Delta) { @@ -2504,14 +2395,18 @@ private void CoreContainer_SizeChanged(object sender, SizeChangedEventArgs e) bool AllowTranslateButton; bool AllowAIButton; bool AllowReaderModeButton; + int ShowExtensionButton; + int ShowFavouritesBar; - public async void SetAppearance(Theme _Theme, bool _AllowHomeButton, bool _AllowTranslateButton, bool _AllowAIButton, bool _AllowReaderModeButton) + public async void SetAppearance(Theme _Theme, bool _AllowHomeButton, bool _AllowTranslateButton, bool _AllowAIButton, bool _AllowReaderModeButton, int _ShowExtensionButton, int _ShowFavouritesBar) { AllowHomeButton = _AllowHomeButton; AllowTranslateButton = _AllowTranslateButton; AllowAIButton = _AllowAIButton; AllowReaderModeButton = _AllowReaderModeButton; - + ShowExtensionButton = _ShowExtensionButton; + ShowFavouritesBar = _ShowFavouritesBar; + SetFavouritesBarVisibility(); HomeButton.Visibility = AllowHomeButton ? Visibility.Visible : Visibility.Collapsed; AIChatButton.Visibility = AllowAIButton ? Visibility.Visible : Visibility.Collapsed; if (!IsLoading) @@ -2540,6 +2435,13 @@ public async void SetAppearance(Theme _Theme, bool _AllowHomeButton, bool _Allow else ReaderModeButton.Visibility = Visibility.Collapsed; + if (ShowExtensionButton == 0) + ExtensionsButton.Visibility = App.Instance.Extensions.Any() ? Visibility.Visible : Visibility.Collapsed; + else if (ShowExtensionButton == 1) + ExtensionsButton.Visibility = Visibility.Visible; + else + ExtensionsButton.Visibility = Visibility.Collapsed; + Resources["PrimaryBrushColor"] = _Theme.PrimaryColor; Resources["SecondaryBrushColor"] = _Theme.SecondaryColor; Resources["BorderBrushColor"] = _Theme.BorderColor; @@ -2761,15 +2663,17 @@ private void Browser_Loaded(object sender, RoutedEventArgs e) Window ExtensionWindow; private void LoadExtensionPopup(object sender, RoutedEventArgs e) { - if (sender == null) - return; Extension _Extension = App.Instance.Extensions.ToList().Find(i => i.ID == ((FrameworkElement)sender).Tag.ToString()); ExtensionWindow = new Window(); ChromiumWebBrowser ExtensionBrowser = new ChromiumWebBrowser(_Extension.Popup); + ExtensionBrowser.JavascriptObjectRepository.Settings.JavascriptBindingApiGlobalObjectName = "engine"; + HwndSource _HwndSource = HwndSource.FromHwnd(new WindowInteropHelper(ExtensionWindow).EnsureHandle()); + _HwndSource.AddHook(WndProc); + int trueValue = 0x01; ExtensionBrowser.LoadingStateChanged += (s, args) => { if (!args.IsLoading) - ExtensionBrowser.ExecuteScriptAsync(@"var rect = document.body.getBoundingClientRect();cefSharp.postMessage({ width: rect.width + 16, height: rect.height + 40 });"); + ExtensionBrowser.ExecuteScriptAsync(@"var rect=document.body.getBoundingClientRect();engine.postMessage({width:rect.width+16,height:rect.height+40});"); /*function getBoundingClientRect(element) { var rect = element.getBoundingClientRect(); return { @@ -2783,7 +2687,14 @@ private void LoadExtensionPopup(object sender, RoutedEventArgs e) y: rect.y }; }*/ + int trueValue = 0x01; + int falseValue = 0x00; + if (App.Instance.CurrentTheme.DarkTitleBar) + DwmSetWindowAttribute(_HwndSource.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref trueValue, Marshal.SizeOf(typeof(int))); + else + DwmSetWindowAttribute(_HwndSource.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref falseValue, Marshal.SizeOf(typeof(int))); }; + DwmSetWindowAttribute(_HwndSource.Handle, DwmWindowAttribute.DWMWA_MICA_EFFECT, ref trueValue, Marshal.SizeOf(typeof(int))); ExtensionBrowser.JavascriptMessageReceived += ExtensionBrowser_JavascriptMessageReceived; ExtensionBrowser.SnapsToDevicePixels = true; ExtensionBrowser.MenuHandler = App.Instance._LimitedContextMenuHandler; @@ -2794,16 +2705,10 @@ private void LoadExtensionPopup(object sender, RoutedEventArgs e) ExtensionWindow.Title = _Extension.Name + " - Extension"; ExtensionWindow.ResizeMode = ResizeMode.NoResize; ExtensionWindow.SizeChanged += ExtensionWindow_SizeChanged; - ExtensionWindow.SourceInitialized += ExtensionWindow_SourceInitialized; ExtensionWindow.MaxHeight = 700; ExtensionWindow.MaxWidth = 700; ExtensionWindow.ShowDialog(); } - - private void ExtensionWindow_SourceInitialized(object? sender, EventArgs e) - { - HwndSource.FromHwnd(new WindowInteropHelper(ExtensionWindow).Handle).AddHook(WndProc); - } const int WM_SYSCOMMAND = 0x0112; const int SC_MOVE = 0xF010; private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) @@ -2837,14 +2742,6 @@ private void ExtensionBrowser_JavascriptMessageReceived(object? sender, Javascri ExtensionWindow.Height = data.height; ExtensionWindow.Width = data.width; //MessageBox.Show(JsonSerializer.Serialize(e.Message)); - HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(ExtensionWindow).EnsureHandle()); - int trueValue = 0x01; - int falseValue = 0x00; - if (App.Instance.CurrentTheme.DarkTitleBar) - DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref trueValue, Marshal.SizeOf(typeof(int))); - else - DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_USE_IMMERSIVE_DARK_MODE, ref falseValue, Marshal.SizeOf(typeof(int))); - DwmSetWindowAttribute(source.Handle, DwmWindowAttribute.DWMWA_MICA_EFFECT, ref trueValue, Marshal.SizeOf(typeof(int))); }); } } diff --git a/SLBr/Pages/Settings.xaml b/SLBr/Pages/Settings.xaml index 5b5d077..24dcdca 100644 --- a/SLBr/Pages/Settings.xaml +++ b/SLBr/Pages/Settings.xaml @@ -8,16 +8,7 @@ mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" Loaded="Page_Loaded"> - - - - - - - - - - + @@ -64,25 +55,13 @@ Start - + + - - Youtube - - - - - - - - - - - - + @@ -204,10 +183,14 @@ - + + + + + @@ -236,7 +219,7 @@ - + + + + @@ -282,6 +273,26 @@ + + + Privacy + + + + + + + + + + @@ -355,6 +366,18 @@ + + + YouTube + + + + + + + + + Screenshot @@ -378,7 +401,7 @@ - Never Slow Mode limits the size and quantity of stylesheets, scripts, images and fonts + Never Slow Mode limits the size and quantity of sub frames, stylesheets, scripts, images and fonts @@ -655,7 +678,7 @@ - Restart SLBr for changes to take effect. + Restart SLBr for changes to take effect @@ -694,14 +717,19 @@ + + + Licensed under the + GNU General Public License v3.0. + Made possible by CefSharp - and + and other - other open-source software + open-source software . @@ -713,11 +741,22 @@ CefSharp . - - - Licensed under the - GNU General Public License v3.0. - + + + + + + + + + + + + + diff --git a/SLBr/Pages/Settings.xaml.cs b/SLBr/Pages/Settings.xaml.cs index 79f1111..0d6298d 100644 --- a/SLBr/Pages/Settings.xaml.cs +++ b/SLBr/Pages/Settings.xaml.cs @@ -55,7 +55,7 @@ public void RemoveLocale(object sender, RoutedEventArgs e) { if (App.Instance.Languages.Count == 1) { - var infoWindow = new InformationDialogWindow("Alert", $"Settings", "You can no longer remove languages because only one language remains.", "\uece4"); + var infoWindow = new InformationDialogWindow("Alert", $"Settings", "Unable to remove languages", "\uece4"); infoWindow.Topmost = true; infoWindow.ShowDialog(); return; @@ -98,14 +98,13 @@ public void AddLocale(object sender, RoutedEventArgs e) private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) { - App.Instance.CurrentFocusedWindow().NewTab(e.Uri.ToString(), true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); + BrowserView.Tab.ParentWindow.NewTab(e.Uri.ToString(), true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); e.Handled = true; } private void HyperlinkButton_Click(object sender, RoutedEventArgs e) { - if (sender != null) - App.Instance.CurrentFocusedWindow().NewTab(((FrameworkElement)sender).Tag.ToString(), true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); + App.Instance.CurrentFocusedWindow().NewTab(((FrameworkElement)sender).Tag.ToString(), true, App.Instance.CurrentFocusedWindow().TabsUI.SelectedIndex + 1); } private void LanguageSelection_SelectionChanged(object sender, SelectionChangedEventArgs e) @@ -134,12 +133,15 @@ private void Page_Loaded(object sender, RoutedEventArgs e) { SettingsInitialized = false; List ISOs = App.Instance.Languages.Select(i => i.Tooltip).ToList(); - foreach (KeyValuePair Locale in App.Instance.AllLocales) + if (AddableLanguages.Count == 0) { - if (!ISOs.Contains(Locale.Key)) - AddableLanguages.Add(new ActionStorage(Locale.Value, App.Instance.GetLocaleIcon(Locale.Key), Locale.Key)); + foreach (KeyValuePair Locale in App.Instance.AllLocales) + { + if (!ISOs.Contains(Locale.Key)) + AddableLanguages.Add(new ActionStorage(Locale.Value, App.Instance.GetLocaleIcon(Locale.Key), Locale.Key)); + } + AddableLanguages = new ObservableCollection(AddableLanguages.OrderBy(x => x.Tooltip)); } - AddableLanguages = new ObservableCollection(AddableLanguages.OrderBy(x => x.Tooltip)); LanguageSelection.ItemsSource = App.Instance.Languages; LanguageSelection.SelectedValue = App.Instance.Locale; @@ -167,8 +169,8 @@ private void Page_Loaded(object sender, RoutedEventArgs e) ScreenshotPathTextBox.Text = App.Instance.GlobalSave.Get("ScreenshotPath"); RestoreTabsCheckBox.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("RestoreTabs")); + DownloadFaviconsCheckBox.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("DownloadFavicons")); SmoothScrollCheckBox.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("SmoothScroll")); - FlagEmojiCheckBox.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("FlagEmoji")); SpellCheckCheckBox.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("SpellCheck")); DownloadPromptCheckBox.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("DownloadPrompt")); @@ -329,14 +331,10 @@ private void Page_Loaded(object sender, RoutedEventArgs e) } } - AboutVersion.Text = $"Version {App.Instance.ReleaseVersion}"; CEFVersion.Text = $"CEF: {(Cef.CefVersion.StartsWith("r") ? Cef.CefVersion.Substring(1, Cef.CefVersion.IndexOf("-") - 10) : Cef.CefVersion.Substring(0, Cef.CefVersion.IndexOf("-") - 10))}"; ChromiumVersion.Text = $"Version: {Cef.ChromiumVersion}"; - //ChromiumJSVersion.Text = $"Javascript: V8 ({App.Instance.ChromiumJSVersion})"; - //ChromiumWebkit.Text = $"Webkit: 537.36 ({App.Instance.ChromiumRevision})"; - AdsBlocked.Text = App.Instance.AdsBlocked.ToString(); TrackersBlocked.Text = App.Instance.TrackersBlocked.ToString(); @@ -345,6 +343,24 @@ private void Page_Loaded(object sender, RoutedEventArgs e) TranslateButtonToggleButton.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")); ReaderButtonToggleButton.IsChecked = bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")); + if (ExtensionButtonComboBox.Items.Count == 0) + { + ExtensionButtonComboBox.Items.Add("Show automatically"); + ExtensionButtonComboBox.Items.Add("Always show"); + ExtensionButtonComboBox.Items.Add("Never show"); + } + ExtensionButtonComboBox.SelectionChanged += ExtensionButtonComboBox_SelectionChanged; + ExtensionButtonComboBox.SelectedIndex = int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")); + + if (FavouritesBarComboBox.Items.Count == 0) + { + FavouritesBarComboBox.Items.Add("Show automatically"); + FavouritesBarComboBox.Items.Add("Always show"); + FavouritesBarComboBox.Items.Add("Never show"); + } + FavouritesBarComboBox.SelectionChanged += FavouritesBarComboBox_SelectionChanged; + FavouritesBarComboBox.SelectedIndex = int.Parse(App.Instance.GlobalSave.Get("FavouritesBar")); + App.Instance.LoadExtensions(); ExtensionsList.ItemsSource = App.Instance.Extensions; @@ -417,7 +433,25 @@ private void TabAlignmentComboBox_SelectionChanged(object sender, SelectionChang { string TabAlignment = TabAlignmentComboBox.SelectedValue.ToString(); App.Instance.GlobalSave.Set("TabAlignment", TabAlignment); - App.Instance.SetAppearance(App.Instance.CurrentTheme, TabAlignment, bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); + App.Instance.SetAppearance(App.Instance.CurrentTheme, TabAlignment, bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")), int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); + } + } + private void ExtensionButtonComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (SettingsInitialized) + { + int ExtensionButton = ExtensionButtonComboBox.SelectedIndex; + App.Instance.GlobalSave.Set("ExtensionButton", ExtensionButton); + App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")), ExtensionButton, int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); + } + } + private void FavouritesBarComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (SettingsInitialized) + { + int FavouritesBar = FavouritesBarComboBox.SelectedIndex; + App.Instance.GlobalSave.Set("FavouritesBar", FavouritesBar); + App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")), int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), FavouritesBar); } } @@ -501,15 +535,15 @@ private void RestoreTabsCheckBox_Click(object sender, RoutedEventArgs e) if (SettingsInitialized) App.Instance.GlobalSave.Set("RestoreTabs", RestoreTabsCheckBox.IsChecked.ToBool().ToString()); } - private void SmoothScrollCheckBox_Click(object sender, RoutedEventArgs e) + private void DownloadFaviconsCheckBox_Click(object sender, RoutedEventArgs e) { if (SettingsInitialized) - App.Instance.GlobalSave.Set("SmoothScroll", SmoothScrollCheckBox.IsChecked.ToBool().ToString()); + App.Instance.GlobalSave.Set("DownloadFavicons", DownloadFaviconsCheckBox.IsChecked.ToBool().ToString()); } - private void FlagEmojiCheckBox_Click(object sender, RoutedEventArgs e) + private void SmoothScrollCheckBox_Click(object sender, RoutedEventArgs e) { if (SettingsInitialized) - App.Instance.GlobalSave.Set("FlagEmoji", FlagEmojiCheckBox.IsChecked.ToBool().ToString()); + App.Instance.GlobalSave.Set("SmoothScroll", SmoothScrollCheckBox.IsChecked.ToBool().ToString()); } private void SpellCheckCheckBox_Click(object sender, RoutedEventArgs e) { @@ -629,7 +663,7 @@ private void AIButtonToggleButton_Click(object sender, RoutedEventArgs e) if (SettingsInitialized) { App.Instance.GlobalSave.Set("AIButton", AIButtonToggleButton.IsChecked.ToBool().ToString()); - App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); + App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")),int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); } } private void TranslateButtonToggleButton_Click(object sender, RoutedEventArgs e) @@ -637,20 +671,20 @@ private void TranslateButtonToggleButton_Click(object sender, RoutedEventArgs e) if (SettingsInitialized) { App.Instance.GlobalSave.Set("TranslateButton", TranslateButtonToggleButton.IsChecked.ToBool().ToString()); - App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); + App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")),int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); } } private void HomeButtonToggleButton_Click(object sender, RoutedEventArgs e) { App.Instance.GlobalSave.Set("HomeButton", HomeButtonToggleButton.IsChecked.ToBool().ToString()); - App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); + App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")),int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); } private void ReaderButtonToggleButton_Click(object sender, RoutedEventArgs e) { if (SettingsInitialized) { App.Instance.GlobalSave.Set("ReaderButton", ReaderButtonToggleButton.IsChecked.ToBool().ToString()); - App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); + App.Instance.SetAppearance(App.Instance.CurrentTheme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")),int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); } } @@ -664,7 +698,7 @@ private void ThemeSelection_SelectionChanged(object sender, SelectionChangedEven Theme _Theme = App.Instance.GetTheme(Text); if (_Theme == null) return; - App.Instance.SetAppearance(_Theme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton"))); + App.Instance.SetAppearance(_Theme, App.Instance.GlobalSave.Get("TabAlignment"), bool.Parse(App.Instance.GlobalSave.Get("HomeButton")), bool.Parse(App.Instance.GlobalSave.Get("TranslateButton")), bool.Parse(App.Instance.GlobalSave.Get("AIButton")), bool.Parse(App.Instance.GlobalSave.Get("ReaderButton")),int.Parse(App.Instance.GlobalSave.Get("ExtensionButton")), int.Parse(App.Instance.GlobalSave.Get("FavouritesBar"))); //App.Instance.ApplyTheme(_Theme); ApplyTheme(_Theme); } @@ -695,12 +729,19 @@ private void SwitchUserButton_Click(object sender, RoutedEventArgs e) BrowserView.Action(Actions.SwitchUserPopup); } + private void ClearAllDataButton_Click(object sender, RoutedEventArgs e) + { + var infoWindow = new InformationDialogWindow("Confirmation", "Settings", "Clear all browsing data permanently?", "\uea99", "Yes", "No"); + infoWindow.Topmost = true; + + if (infoWindow.ShowDialog() == true) + App.Instance.ClearAllData(); + } + private void ExtensionToggleButton_Click(object sender, RoutedEventArgs e) { if (SettingsInitialized) { - if (sender == null) - return; var Target = (ToggleButton)sender; var Values = Target.Tag.ToString().Split(new string[] { "<,>" }, StringSplitOptions.None); if (Values[0] == "PDF") diff --git a/SLBr/Program.cs b/SLBr/Program.cs index ede99c0..ae46b86 100644 --- a/SLBr/Program.cs +++ b/SLBr/Program.cs @@ -1,56 +1,13 @@ using CefSharp; using CefSharp.BrowserSubprocess; +using System.ComponentModel; using System.Diagnostics; +using System.Reflection.Metadata; using System.Runtime.InteropServices; using System.Windows.Threading; namespace SLBr { - static class MessageHelper - { - public const int WM_COPYDATA = 0x004A; - /*public const int WM_NCHITTEST = 0x0084; - public const int WM_SYSTEMMENU = 0xa4; - public const int WP_SYSTEMMENU = 0x02; - public const int WM_GETMINMAXINFO = 0x0024; - public const int HTMAXBUTTON = 9;*/ - public const int HWND_BROADCAST = 0xffff; - - [DllImport("user32", EntryPoint = "SendMessageA")] - private static extern int SendMessage(IntPtr Hwnd, int wMsg, IntPtr wParam, IntPtr lParam); - - public static void SendDataMessage(Process targetProcess, string msg) - { - IntPtr _stringMessageBuffer = Marshal.StringToHGlobalUni(msg); - - COPYDATASTRUCT _copyData = new COPYDATASTRUCT(); - _copyData.dwData = IntPtr.Zero; - _copyData.lpData = _stringMessageBuffer; - _copyData.cbData = msg.Length * 2; - IntPtr _copyDataBuff = IntPtrAlloc(_copyData); - - SendMessage((IntPtr)HWND_BROADCAST, WM_COPYDATA, IntPtr.Zero, _copyDataBuff); - - Marshal.FreeHGlobal(_copyDataBuff); - Marshal.FreeHGlobal(_stringMessageBuffer); - } - - private static IntPtr IntPtrAlloc(T param) - { - IntPtr retval = Marshal.AllocHGlobal(Marshal.SizeOf(param)); - Marshal.StructureToPtr(param, retval, false); - return retval; - } - } - - [StructLayout(LayoutKind.Sequential)] - struct COPYDATASTRUCT - { - public IntPtr dwData; - public int cbData; - public IntPtr lpData; - } - internal static class Program { [STAThread] @@ -66,40 +23,98 @@ private static int Main(string[] args) return SelfHost.Main(args); else { + /*DispatcherTimer FlushTimer = new DispatcherTimer(); + FlushTimer.Interval = new TimeSpan(500); + FlushTimer.Tick += FlushTimer_Tick;*/ + BackgroundWorker worker = new BackgroundWorker(); + worker.DoWork += worker_DoWork; + worker.RunWorkerAsync(); App.Main(); Cef.Shutdown(); return Environment.ExitCode; } } - - /*private static void FlushTimer_Tick(object? sender, EventArgs e) + private static void worker_DoWork(object sender, DoWorkEventArgs e) { - FlushMemory(); + OptimizeMemoryUsage(); + } + private static void OptimizeMemoryUsage() + { + while (true) + { + try + { + FlushMemory(); + MinimizeFootprint(); + } + finally + { + Thread.Sleep(60000); + } + } } + /*[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")] + static extern bool SetProcessWorkingSetSize32(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize); + + [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")] + static extern bool SetProcessWorkingSetSize64(IntPtr pProcess, long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize);*/ + + [DllImport("kernel32.dll")] + private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max); + [DllImport("psapi.dll")] + static extern int EmptyWorkingSet(IntPtr hwProc); + private static void FlushMemory() { - GC.Collect(GC.MaxGeneration); + GC.Collect(2, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); + /*if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + if (IntPtr.Size == 8) + SetProcessWorkingSetSize64(Process.GetCurrentProcess().Handle, -1, -1); + else + SetProcessWorkingSetSize32(Process.GetCurrentProcess().Handle, -1, -1); + }*/ + } + + private static void MinimizeFootprint() + { + EmptyWorkingSet(Process.GetCurrentProcess().Handle); + } + + /*private static void FlushTimer_Tick(object? sender, EventArgs e) + { + Process[] SubProcesses = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName); + foreach (Process SubProcess in SubProcesses) + { + int CurrentMemoryUsage = (int)SubProcess.WorkingSet64; + int CurrentMemoryMB = (CurrentMemoryUsage / 1024 / 1024); + int MaxMemoryUsage = (int)Math.Round(CurrentMemoryMB * 0.3f); + Utils.LimitMemoryUsage(SubProcess.Handle, MaxMemoryUsage); + } + Utils.LimitMemoryUsage(Process.GetCurrentProcess().Handle, 10); + GC.Collect(); + GC.WaitForPendingFinalizers(); + Chromium.ExecuteScriptAsync("window.gc();"); }*/ private static void MinimizeMemory() { - //Process CurrentProcess = Process.GetCurrentProcess(); - //CurrentProcess.PriorityClass = ProcessPriorityClass.BelowNormal; + Process CurrentProcess = Process.GetCurrentProcess(); //SetCpuAffinity(0x0001); - GC.Collect(GC.MaxGeneration); - GC.WaitForPendingFinalizers(); - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); + /*CurrentProcess.PriorityBoostEnabled = false; + CurrentProcess.PriorityClass = ProcessPriorityClass.Idle; + Thread.CurrentThread.Priority = ThreadPriority.Lowest;*/ + + //GC.Collect(GC.MaxGeneration); + //GC.WaitForPendingFinalizers(); + //if (Environment.OSVersion.Platform == PlatformID.Win32NT) //It will only run on Windows regardless + SetProcessWorkingSetSize(CurrentProcess.Handle, -1, -1); + //EmptyWorkingSet(CurrentProcess.Handle); } - [DllImport("kernel32.dll")] - private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max); - /*[DllImport("kernel32.dll")] private static extern bool SetProcessAffinityMask(IntPtr handle, IntPtr affinity); diff --git a/SLBr/SLBr.csproj b/SLBr/SLBr.csproj index 093c06d..99a5a7e 100644 --- a/SLBr/SLBr.csproj +++ b/SLBr/SLBr.csproj @@ -12,8 +12,8 @@ False Resources\SLBr.ico Copyright (c) SLT Softwares. All rights reserved. - 2024.9.5.0 - 2024.9.5.0 + 2024.10.20.0 + 2024.10.20.0 true AnyCPU;x64 @@ -49,7 +49,7 @@ - + @@ -128,15 +128,15 @@ - + - + - + diff --git a/SLBr/Utils.cs b/SLBr/Utils.cs index edebeae..683647d 100644 --- a/SLBr/Utils.cs +++ b/SLBr/Utils.cs @@ -1,15 +1,62 @@ using CefSharp; +using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; -using System.Net.NetworkInformation; +using System.Reflection.Metadata; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using System.Security.Principal; using System.Text; using System.Windows.Media.Imaging; namespace SLBr { + static class MessageHelper + { + public const int WM_COPYDATA = 0x004A; + /*public const int WM_NCHITTEST = 0x0084; + public const int WM_SYSTEMMENU = 0xa4; + public const int WP_SYSTEMMENU = 0x02; + public const int WM_GETMINMAXINFO = 0x0024; + public const int HTMAXBUTTON = 9;*/ + public const int HWND_BROADCAST = 0xffff; + + [DllImport("user32", EntryPoint = "SendMessageA")] + private static extern int SendMessage(IntPtr Hwnd, int wMsg, IntPtr wParam, IntPtr lParam); + + public static void SendDataMessage(Process targetProcess, string msg) + { + IntPtr StringMessageBuffer = Marshal.StringToHGlobalUni(msg); + + COPYDATASTRUCT CopyData = new COPYDATASTRUCT(); + CopyData.dwData = IntPtr.Zero; + CopyData.lpData = StringMessageBuffer; + CopyData.cbData = msg.Length * 2; + IntPtr CopyDataBuffer = IntPtrAlloc(CopyData); + + SendMessage((IntPtr)HWND_BROADCAST, WM_COPYDATA, IntPtr.Zero, CopyDataBuffer); + + Marshal.FreeHGlobal(CopyDataBuffer); + Marshal.FreeHGlobal(StringMessageBuffer); + } + + private static IntPtr IntPtrAlloc(T param) + { + IntPtr retval = Marshal.AllocHGlobal(Marshal.SizeOf(param)); + Marshal.StructureToPtr(param, retval, false); + return retval; + } + } + + [StructLayout(LayoutKind.Sequential)] + struct COPYDATASTRUCT + { + public IntPtr dwData; + public int cbData; + public IntPtr lpData; + } + /*public enum DWMWINDOWATTRIBUTE { DWMWA_NCRENDERING_ENABLED = 1, // [get] Is non-client rendering enabled/disabled @@ -66,34 +113,172 @@ public static string GetChromiumGitRevision() return CHROMIUM_GIT_REVISION; }*/ - public static string BuildCpuInfo() + /*[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWow64Process2([In] IntPtr hProcess, [Out] ImageFileMachine pProcessMachine, [Out, Optional] ImageFileMachine pNativeMachine);*/ + + /*[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern unsafe bool IsWow64Process2(IntPtr hProcess, ImageFileMachine* pProcessMachine, [Optional] ImageFileMachine* pNativeMachine); + + public static unsafe void IsWow64Process2(SafeHandle hProcess, out ImageFileMachine pProcessMachine, out ImageFileMachine pNativeMachine) + { + bool hProcessAddRef = false; + try + { + fixed (ImageFileMachine* pProcessMachineLocal = &pProcessMachine) + { + fixed (ImageFileMachine* pNativeMachineLocal = &pNativeMachine) + { + IntPtr hProcessLocal; + if (hProcess is object) + { + hProcess.DangerousAddRef(ref hProcessAddRef); + hProcessLocal = hProcess.DangerousGetHandle(); + if (IsWow64Process2(hProcessLocal, pProcessMachineLocal, pNativeMachineLocal)) + return; + else throw new Win32Exception(); + } + else + throw new ArgumentNullException(nameof(hProcess)); + } + } + } + finally + { + if (hProcessAddRef) + hProcess.DangerousRelease(); + } + }*/ + + /*[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process); + + public static bool IsWow64() + { + //if (Environment.OSVersion.Version.Major >= 6 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1)) + //{ + if (!IsWow64Process(Process.GetCurrentProcess().Handle, out bool RetVal)) + return false; + return RetVal; + //} + //return false; + }*/ + + [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWow64Process2(IntPtr process, out ushort processMachine, out ushort nativeMachine); + + public static bool IsIA64() + { + /*IsWow64Process2(Process.GetCurrentProcess().SafeHandle, out ImageFileMachine pProcessMachine, out ImageFileMachine pNativeMachine); + //pProcessMachine.ToString() // IMAGE_FILE_MACHINE_UNKNOWN + return pNativeMachine == ImageFileMachine.IA64;*/ + IsWow64Process2(Process.GetCurrentProcess().Handle, out ushort pProcessMachine, out ushort pNativeMachine); + return pNativeMachine == 512; + } + + //https://gist.github.com/BinToss/aa6a269f5eb58088425cdb5a2341e14e + //http://zuga.net/articles/cs-is64bitprocess-vs-iswow64process/ + + /*public enum ImageFileMachine : ushort + { + AXP64 = 644, + I386 = 332, + IA64 = 512, + AMD64 = 34404, + UNKNOWN = 0, + TARGET_HOST = 1, + R3000 = 354, + R4000 = 358, + R10000 = 360, + WCEMIPSV2 = 361, + ALPHA = 388, + SH3 = 418, + SH3DSP = 419, + SH3E = 420, + SH4 = 422, + SH5 = 424, + ARM = 448, + THUMB = 450, + ARMNT = 452, + AM33 = 467, + POWERPC = 496, + POWERPCFP = 497, + MIPS16 = 614, + ALPHA64 = 644, + MIPSFPU = 870, + MIPSFPU16 = 1126, + TRICORE = 1312, + CEF = 3311, + EBC = 3772, + M32R = 36929, + ARM64 = 43620, + CEE = 49390, + }*/ + + /*private static bool? PIsWindows11OrGreater; + + internal static bool IsWindows11OrGreater + { + get + { + if (PIsWindows11OrGreater.HasValue) + return PIsWindows11OrGreater.Value; + PIsWindows11OrGreater = Environment.OSVersion.Version >= new Version(10, 0, 22000); + return PIsWindows11OrGreater.Value; + } + }*/ + + public static string BuildCPUInfo() { if (Environment.Is64BitOperatingSystem) { - if (!Environment.Is64BitProcess) + if (!Environment.Is64BitProcess) //IsWow64() return "WOW64"; else + { + if (IsIA64()) + return "Win64; x64"; + else + return "Win64; IA64"; + } + + /*if (Environment.Is64BitProcess) return "Win64; x64"; - /* - else if (windows_architecture == base::win::OSInfo::IA64_ARCHITECTURE) - cpuinfo = "Win64; IA64"; - }*/ + else if (IsIA64()) + return "Win64; IA64"; + else if (IsWow64()) + return "WOW64";*/ } - else - return "Win32"; + return ""; } - public static string GetCpuArchitecture() + public static string GetCPUArchitecture() { - if (Environment.Is64BitOperatingSystem) + //return (RuntimeInformation.ProcessArchitecture == Architecture.Arm || (RuntimeInformation.ProcessArchitecture) == Architecture.Arm64) ? "arm" : "x86"; + switch (RuntimeInformation.ProcessArchitecture) { - if (!Environment.Is64BitProcess) + case Architecture.X86: + return "x86"; + case Architecture.X64: + return "x86"; + case Architecture.Arm: + case Architecture.Arm64: return "arm"; - else + } + return "x86"; + /*if (Environment.Is64BitOperatingSystem) + { + if (Environment.Is64BitProcess) return "x86"; + else + return "arm"; } else - return "x86"; + return "x86";*/ + //return Environment.Is64BitOperatingSystem ? (Environment.Is64BitProcess ? "x86" : "arm") : "x86"; } /*public static string GetCpuBitness() @@ -120,15 +305,15 @@ public static string BuildChromeBrand() public static string BuildOSCpuInfo() { - return BuildOSCpuInfoFromOSVersionAndCpuType(GetOSVersion(), BuildCpuInfo()); + return BuildOSCpuInfoFromOSVersionAndCpuType(GetOSVersion(), BuildCPUInfo()); } - public static string BuildOSCpuInfoFromOSVersionAndCpuType(string os_version, string cpu_type) + public static string BuildOSCpuInfoFromOSVersionAndCpuType(string OSVersion, string CPUType) { - if (cpu_type.Length == 0) - return string.Format("Windows NT {0}", os_version); + if (CPUType.Length == 0) + return string.Format("Windows NT {0}", OSVersion); else - return string.Format("Windows NT {0}; {1}", os_version, cpu_type); + return string.Format("Windows NT {0}; {1}", OSVersion, CPUType); } /*public static string GetReducedUserAgent(string major_version) @@ -141,39 +326,41 @@ public static string BuildUnifiedPlatformUserAgentFromProduct(string product) return BuildUserAgentFromOSAndProduct(GetUnifiedPlatform(), product); }*/ - public static string BuildUserAgentFromProduct(string product) + public static string BuildUserAgentFromProduct(string Product) { - return BuildUserAgentFromOSAndProduct(/*GetUserAgentPlatform()+*/BuildOSCpuInfo(), product); + return BuildUserAgentFromOSAndProduct(/*GetUserAgentPlatform()+*/BuildOSCpuInfo(), Product); } - public static string BuildUserAgentFromOSAndProduct(string os_info, string product) + public static string BuildUserAgentFromOSAndProduct(string OSInfo, string Product) { /* Derived from Safari's UA string. * This is done to expose our product name in a manner that is maximally compatible with Safari, we hope!!*/ - return $"Mozilla/5.0 ({os_info}) AppleWebKit/537.36 (KHTML, like Gecko) {product} Safari/537.36"; + return $"Mozilla/5.0 ({OSInfo}) AppleWebKit/537.36 (KHTML, like Gecko) {Product} Safari/537.36"; } } public static class ClassExtensions { - public static bool NewLoadHtml(this IWebBrowser browser, string html, string url, Encoding encoding, /*bool limitedUse = false, */int uses = 1, string error = "") + /*public static bool NewLoadHtml(this IWebBrowser browser, string html, string url, Encoding encoding, int uses = 1, string error = "") { - if (!(browser.ResourceRequestHandlerFactory is Handlers.ResourceRequestHandlerFactory resourceRequestHandlerFactory)) - throw new Exception("LoadHtml can only be used with the SLBr's IResourceRequestHandlerFactory implementation"); - if (resourceRequestHandlerFactory.RegisterHandler(url, ResourceHandler.GetByteArray(html, encoding), "text/html", /*limitedUse, */uses, error)) + //if (!(browser.ResourceRequestHandlerFactory is Handlers.ResourceRequestHandlerFactory resourceRequestHandlerFactory)) + // throw new Exception("LoadHtml can only be used with the SLBr's IResourceRequestHandlerFactory implementation"); + Handlers.ResourceRequestHandlerFactory resourceRequestHandlerFactory = (Handlers.ResourceRequestHandlerFactory)browser.ResourceRequestHandlerFactory; + if (resourceRequestHandlerFactory.RegisterHandler(url, ResourceHandler.GetByteArray(html, encoding), "text/html", uses, error)) { browser.Load(url); return true; } return false; - } - public static bool NewNoLoadHtml(this IWebBrowser browser, string html, string url, Encoding encoding, /*bool limitedUse = false, */int uses = 1, string error = "") + }*/ + /*public static bool NewNoLoadHtml(this IWebBrowser browser, string html, string url, Encoding encoding, int uses = 1, string error = "") { - if (!(browser.ResourceRequestHandlerFactory is Handlers.ResourceRequestHandlerFactory resourceRequestHandlerFactory)) - throw new Exception("LoadHtml can only be used with the SLBr's IResourceRequestHandlerFactory implementation"); - resourceRequestHandlerFactory.RegisterHandler(url, ResourceHandler.GetByteArray(html, encoding), "text/html", /*limitedUse, */uses, error); + //if (!(browser.ResourceRequestHandlerFactory is Handlers.ResourceRequestHandlerFactory resourceRequestHandlerFactory)) + // throw new Exception("LoadHtml can only be used with the SLBr's IResourceRequestHandlerFactory implementation"); + Handlers.ResourceRequestHandlerFactory resourceRequestHandlerFactory = (Handlers.ResourceRequestHandlerFactory)browser.ResourceRequestHandlerFactory; + resourceRequestHandlerFactory.RegisterHandler(url, ResourceHandler.GetByteArray(html, encoding), "text/html", uses, error); return true; - } + }*/ /*public static int CountChars(this string source, char toFind) { @@ -186,13 +373,13 @@ public static bool NewNoLoadHtml(this IWebBrowser browser, string html, string u return count; }*/ public static bool ToBool(this bool? self) => - self == null || self == false ? false : true; + self == true; /*public static CefState ToCefState(this bool self) => self ? CefState.Enabled : CefState.Disabled; public static bool ToBoolean(this CefState self) => self == CefState.Enabled ? true : false;*/ - public static FastHashSet ToFastHashSet(this IEnumerable collection) => - new FastHashSet(collection); + /*public static FastHashSet ToFastHashSet(this IEnumerable collection) => + new FastHashSet(collection);*/ /*public static BitmapSource ToBitmapSource(this DrawingImage source) { DrawingVisual drawingVisual = new DrawingVisual(); @@ -235,28 +422,24 @@ public static class Utils { public static BitmapImage ConvertBase64ToBitmapImage(string base64String) { - int base64Start = base64String.IndexOf("base64,"); - if (base64String.StartsWith("data:image/") && base64Start != -1) + int base64Start = base64String.IndexOf("base64,", StringComparison.Ordinal); + if (base64String.StartsWith("data:image/", StringComparison.Ordinal) && base64Start != -1) base64String = base64String.Substring(base64Start + 7); - - byte[] imageBytes = Convert.FromBase64String(base64String); - - using (MemoryStream stream = new MemoryStream(imageBytes)) + using (MemoryStream _Stream = new MemoryStream(Convert.FromBase64String(base64String))) { - BitmapImage bitmap = new BitmapImage(); - bitmap.BeginInit(); - bitmap.CacheOption = BitmapCacheOption.OnLoad; - bitmap.StreamSource = stream; - bitmap.EndInit(); - bitmap.Freeze(); - return bitmap; + BitmapImage _Bitmap = new BitmapImage(); + _Bitmap.BeginInit(); + _Bitmap.CacheOption = BitmapCacheOption.OnLoad; + _Bitmap.StreamSource = _Stream; + _Bitmap.EndInit(); + _Bitmap.Freeze(); + return _Bitmap; } } public static Process GetAlreadyRunningInstance(Process CurrentProcess) { Process[] AllProcesses = Process.GetProcessesByName(CurrentProcess.ProcessName); - for (int i = 0; i < AllProcesses.Length; i++) { if (AllProcesses[i].Id != CurrentProcess.Id) @@ -319,8 +502,8 @@ public enum FolderGuids private static extern int SHGetKnownFolderPath(ref Guid id, int flags, IntPtr token, out IntPtr path); public static string GetFolderPath(FolderGuids FolderGuid) { - if (Environment.OSVersion.Version.Major < 6) throw new NotSupportedException(); - IntPtr pathPtr = IntPtr.Zero; + //if (Environment.OSVersion.Version.Major < 6) throw new NotSupportedException(); + IntPtr PathPtr = IntPtr.Zero; try { Guid _FolderGuid = new Guid(); @@ -342,12 +525,12 @@ public static string GetFolderPath(FolderGuids FolderGuid) _FolderGuid = SavedGamesGuid; break; } - SHGetKnownFolderPath(ref _FolderGuid, 0, IntPtr.Zero, out pathPtr); - return Marshal.PtrToStringUni(pathPtr); + SHGetKnownFolderPath(ref _FolderGuid, 0, IntPtr.Zero, out PathPtr); + return Marshal.PtrToStringUni(PathPtr); } finally { - Marshal.FreeCoTaskMem(pathPtr); + Marshal.FreeCoTaskMem(PathPtr); } } @@ -365,6 +548,15 @@ public static bool IsAdministrator() => return FinalString; }*/ + /*public static void LimitMemoryUsage(IntPtr _Process, int MaxMemory)//MB + { + int MaxMemoryBytes = MaxMemory * 1024 * 1024; + SetProcessWorkingSetSize(_Process, MaxMemoryBytes, MaxMemoryBytes); + } + + [DllImport("kernel32.dll")] + private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);*/ + public static string GetFileExtensionFromUrl(string Url) { Url = Url.Split('?')[0].Split('/').Last(); @@ -375,8 +567,8 @@ public static string GetFileExtensionFromUrl(string Url) (IsInternalUrl(Url) || Url.StartsWith("ws:") || Url.StartsWith("wss:") || Url.StartsWith("javascript:") || Url.StartsWith("file:") || Url.StartsWith("localhost:") || IsAboutUrl(Url) || Url.StartsWith("view-source:") || Url.StartsWith("devtools:") || Url.StartsWith("data:"));*/ public static bool IsProgramUrl(string Url) => Url.StartsWith("callto:", StringComparison.Ordinal) || Url.StartsWith("mailto:", StringComparison.Ordinal) || Url.StartsWith("news:", StringComparison.Ordinal) || Url.StartsWith("feed:", StringComparison.Ordinal); - public static bool IsAboutUrl(string Url) => - Url.StartsWith("about:", StringComparison.Ordinal); + /*public static bool IsAboutUrl(string Url) => + Url.StartsWith("about:", StringComparison.Ordinal);*/ public static bool CanCheckSafeBrowsing(ResourceType _ResourceType) => _ResourceType == ResourceType.NavigationPreLoadSubFrame || _ResourceType == ResourceType.NavigationPreLoadMainFrame || _ResourceType == ResourceType.SubFrame; public static bool IsPossiblyAd(ResourceType _ResourceType) => @@ -471,8 +663,11 @@ public static string FilterUrlForBrowser(string Url, string SearchEngineUrl) public static string Host(string Url, bool RemoveWWW = true) { string Host = CleanUrl(Url, true, false, true, RemoveWWW); - if (Url.Length != 0) - return Host.Split('/')[0]; + if (IsHttpScheme(Url) || Url.StartsWith("file:///", StringComparison.Ordinal)) + { + if (Url.Length != 0) + return Host.Split('/')[0]; + } return Host; } public static string CleanUrl(string Url, bool RemoveParameters = false, bool RemoveLastSlash = true, bool RemoveFragment = true, bool RemoveWWW = false, bool RemoveProtocol = true) @@ -544,11 +739,11 @@ public static bool checkInternet() int connDescription = default(int); return InternetGetConnectedState(ref connDescription, 0); }*/ - public static bool CheckForInternetConnection(int TimeoutMS = 1500)//, string url = null) + /*public static bool CheckForInternetConnection(int TimeoutMS = 1500)//, string url = null) { try { - /*url = "http://www.gstatic.com/generate_204"; + url = "http://www.gstatic.com/generate_204"; switch (CultureInfo.InstalledUICulture.Name) { case string s when s.StartsWith("fa"): @@ -562,11 +757,18 @@ public static bool CheckForInternetConnection(int TimeoutMS = 1500)//, string ur request.KeepAlive = false; request.Timeout = timeoutMs; using (var response = (HttpWebResponse)request.GetResponse()) - return true;*/ + return true; + } + catch { return false; } + }*/ + /*public static bool CheckForInternetConnection(int TimeoutMS = 1500)//, string url = null) + { + try + { return new Ping().Send("8.8.8.8", TimeoutMS, new byte[32]).Status == IPStatus.Success; } catch { return false; } - } + }*/ } public class Saving @@ -577,7 +779,6 @@ public class Saving Dictionary Data = new Dictionary(); public string SaveFolderPath; public string SaveFilePath; - public bool UseContinuationIndex; public Saving(string FileName, string FolderPath) { @@ -586,12 +787,8 @@ public Saving(string FileName, string FolderPath) Load(); } - public bool Has(string Key, bool IsValue = false) - { - if (IsValue) - return Data.ContainsValue(Key); - return Data.ContainsKey(Key); - } + public bool Has(string Key) => + Data.ContainsKey(Key); public void Remove(string Key) => Data.Remove(Key); @@ -633,7 +830,7 @@ public string Get(string Key, string Default = "NOTFOUND") return Default; } public string[] Get(string Key, bool UseListParameter) => - Get(Key).Split(new[] { ValueSeparator }, StringSplitOptions.None); + Get(Key).Split(ValueSeparator, StringSplitOptions.None); public void Clear() => Data.Clear(); public void Save() @@ -642,7 +839,7 @@ public void Save() Directory.CreateDirectory(SaveFolderPath); if (!File.Exists(SaveFilePath)) File.Create(SaveFilePath).Close(); - FastHashSet Contents = new FastHashSet(); + List Contents = new List(); foreach (KeyValuePair KVP in Data) Contents.Add(KVP.Key + KeyValueSeparator + KVP.Value); File.WriteAllText(SaveFilePath, string.Join(KeySeparator, Contents)); @@ -653,12 +850,12 @@ public void Load() Directory.CreateDirectory(SaveFolderPath); if (!File.Exists(SaveFilePath)) File.Create(SaveFilePath).Close(); - FastHashSet Contents = File.ReadAllText(SaveFilePath).Split(new string[] { KeySeparator }, StringSplitOptions.None).ToFastHashSet(); + string[] Contents = File.ReadAllText(SaveFilePath).Split(KeySeparator, StringSplitOptions.None); foreach (string Content in Contents) { if (string.IsNullOrWhiteSpace(Content)) continue; - string[] Values = Content.Split(new string[] { KeyValueSeparator }, 2, StringSplitOptions.None); + string[] Values = Content.Split(KeyValueSeparator, 2, StringSplitOptions.None); Data[Values[0]] = Values[1]; } } diff --git a/SLBr/WinUIStyleDictionary.xaml b/SLBr/WinUIStyleDictionary.xaml index 1569b5b..da149a8 100644 --- a/SLBr/WinUIStyleDictionary.xaml +++ b/SLBr/WinUIStyleDictionary.xaml @@ -821,6 +821,20 @@ + + + + + + + + + + + + + + @@ -1022,6 +1036,7 @@ Margin="{TemplateBinding Padding}"/>