From 7c7f6cabf7844b37b098ce03a5060efa0c1fc324 Mon Sep 17 00:00:00 2001 From: Davide Giacometti Date: Mon, 21 Aug 2023 15:51:29 +0200 Subject: [PATCH] [Peek][Monaco Preview] Open Monaco URI in default browser (#27774) * open Monaco URI in default browser * added dialog when URI is opened --- .../Controls/BrowserControl.xaml | 14 ++++-- .../Controls/BrowserControl.xaml.cs | 43 +++++++++++++++++-- .../peek/Peek.UI/Strings/en-us/Resources.resw | 16 +++++++ .../MonacoPreviewHandlerControl.cs | 11 +++++ 4 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml index f462aeaef6..1ddfee1c6f 100644 --- a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml +++ b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml @@ -12,9 +12,15 @@ mc:Ignorable="d"> - + + diff --git a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs index 5030f2f69f..39f94af55e 100644 --- a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs +++ b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs @@ -3,11 +3,13 @@ // See the LICENSE file in the project root for more information. using System; +using System.Threading.Tasks; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.Web.WebView2.Core; using Peek.Common.Constants; using Peek.Common.Helpers; +using Windows.ApplicationModel.DataTransfer; using Windows.System; using Windows.UI; @@ -96,6 +98,7 @@ namespace Peek.FilePreviewer.Controls private void SourcePropertyChanged() { + OpenUriDialog.Hide(); Navigate(); } @@ -135,6 +138,7 @@ namespace Peek.FilePreviewer.Controls } PreviewBrowser.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded; + PreviewBrowser.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested; } catch (Exception ex) { @@ -149,6 +153,16 @@ namespace Peek.FilePreviewer.Controls DOMContentLoaded?.Invoke(sender, args); } + private async void CoreWebView2_NewWindowRequested(CoreWebView2 sender, CoreWebView2NewWindowRequestedEventArgs args) + { + // Monaco opens URI in a new window. We open the URI in the default web browser. + if (args.Uri != null && args.IsUserInitiated) + { + args.Handled = true; + await ShowOpenUriDialogAsync(new Uri(args.Uri)); + } + } + private async void PreviewBrowser_NavigationStarting(WebView2 sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs args) { if (_navigatedUri == null) @@ -157,10 +171,11 @@ namespace Peek.FilePreviewer.Controls } // In case user starts or tries to navigate from within the HTML file we launch default web browser for navigation. - if (args.Uri != null && args.Uri != _navigatedUri?.ToString() && args.IsUserInitiated) + // TODO: && args.IsUserInitiated - always false for PDF files, revert the workaround when fixed in WebView2: https://github.com/microsoft/PowerToys/issues/27403 + if (args.Uri != null && args.Uri != _navigatedUri?.ToString()) { args.Cancel = true; - await Launcher.LaunchUriAsync(new Uri(args.Uri)); + await ShowOpenUriDialogAsync(new Uri(args.Uri)); } } @@ -171,7 +186,29 @@ namespace Peek.FilePreviewer.Controls _navigatedUri = Source; } - NavigationCompleted?.Invoke(sender, args); + // Don't raise NavigationCompleted event if NavigationStarting has been cancelled + if (args.WebErrorStatus != CoreWebView2WebErrorStatus.OperationCanceled) + { + NavigationCompleted?.Invoke(sender, args); + } + } + + private async Task ShowOpenUriDialogAsync(Uri uri) + { + OpenUriDialog.Content = uri.ToString(); + var result = await OpenUriDialog.ShowAsync(); + + if (result == ContentDialogResult.Primary) + { + await Launcher.LaunchUriAsync(uri); + } + } + + private void OpenUriDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) + { + var dataPackage = new DataPackage(); + dataPackage.SetText(sender.Content.ToString()); + Clipboard.SetContent(dataPackage); } } } diff --git a/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw b/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw index 756be0a1b4..d8df22b84a 100644 --- a/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw +++ b/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw @@ -237,4 +237,20 @@ {0} bytes Abbreviation for the size bytes + + Cancel + Dialog showed when an URI is clicked. Button to close the dialog. + + + Open + Dialog showed when an URI is clicked. Button to open the URI. + + + Copy + Dialog showed when an URI is clicked. Button to copy the URI. + + + Do you want Peek to open the external application? + Title of the dialog showed when an URI is clicked,"Peek" is the name of the utility. + \ No newline at end of file diff --git a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs index f137d67883..ca16bcc835 100644 --- a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs +++ b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs @@ -157,6 +157,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco _webView.NavigationCompleted += WebView2Init; _webView.Height = this.Height; _webView.Width = this.Width; + _webView.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested; Controls.Add(_webView); _webView.SendToBack(); _loadingBar.Value = 100; @@ -218,6 +219,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco } } + private async void CoreWebView2_NewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e) + { + // Monaco opens URI in a new window. We open the URI in the default web browser. + if (e.Uri != null && e.IsUserInitiated) + { + e.Handled = true; + await Launcher.LaunchUriAsync(new Uri(e.Uri)); + } + } + /// /// This event sets the height and width of the webview to the size of the form ///