From 72d3c3187bc811189d7ba7c3c4ca235d01de1009 Mon Sep 17 00:00:00 2001 From: ema Date: Fri, 6 Dec 2024 12:31:51 +0800 Subject: [PATCH] Support markdown viewer fallback folder #508 --- .../WebpagePanel.cs | 79 +++++++++++++++++-- .../QuickLook.Plugin.MarkdownViewer/Plugin.cs | 16 ++-- 2 files changed, 83 insertions(+), 12 deletions(-) diff --git a/QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/WebpagePanel.cs b/QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/WebpagePanel.cs index b5a2987..36d0160 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/WebpagePanel.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/WebpagePanel.cs @@ -15,6 +15,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using Microsoft.Web.WebView2.Core; +using Microsoft.Web.WebView2.Wpf; +using QuickLook.Common.Helpers; using System; using System.Diagnostics; using System.Drawing; @@ -24,15 +27,14 @@ using System.Runtime.InteropServices; using System.Text; using System.Windows; using System.Windows.Controls; -using Microsoft.Web.WebView2.Core; -using Microsoft.Web.WebView2.Wpf; -using QuickLook.Common.Helpers; namespace QuickLook.Plugin.HtmlViewer { public class WebpagePanel : UserControl { private Uri _currentUri; + private string _primaryPath; + private string _fallbackPath; private WebView2 _webView; public WebpagePanel() @@ -53,12 +55,24 @@ namespace QuickLook.Plugin.HtmlViewer }; _webView.NavigationStarting += NavigationStarting_CancelNavigation; _webView.NavigationCompleted += WebView_NavigationCompleted; + _webView.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted; Content = _webView; } } - public void NavigateToFile(string path) + public void NavigateToFile(string path, string fallbackPath = null) { + try + { + _primaryPath = Path.GetDirectoryName(path); + _fallbackPath = fallbackPath; + } + catch (Exception e) + { + // Omit logging for less important logs + Debug.WriteLine(e); + } + var uri = Path.IsPathRooted(path) ? Helper.FilePathToFileUrl(path) : new Uri(path); NavigateToUri(uri); @@ -145,6 +159,7 @@ namespace QuickLook.Plugin.HtmlViewer } #region Get Associated App For Scheme + [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)] private static extern uint AssocQueryString( AssocF flags, @@ -208,13 +223,67 @@ namespace QuickLook.Plugin.HtmlViewer return null; } } - #endregion + + #endregion Get Associated App For Scheme private void WebView_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e) { _webView.DefaultBackgroundColor = Color.White; // Reset to white after page load to match expected default behavior } + private void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) + { + if (e.IsSuccess) + { + _webView.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All); + + _webView.CoreWebView2.WebResourceRequested += (sender, args) => + { + if (string.IsNullOrWhiteSpace(_fallbackPath) || !Directory.Exists(_fallbackPath)) + { + return; + } + + try + { + var requestedUri = new Uri(args.Request.Uri); + + // Check if the request is for a local file + if (requestedUri.Scheme == "file" && !File.Exists(requestedUri.LocalPath)) + { + // Try loading from fallback directory + var fileName = Path.GetFileName(requestedUri.LocalPath); + var fileDirectoryName = Path.GetDirectoryName(requestedUri.LocalPath); + + // Convert the primary path to fallback path + if (fileDirectoryName.StartsWith(_primaryPath)) + { + var fallbackFilePath = Path.Combine( + _fallbackPath.Trim('/', '\\'), // Make it combinable + fileDirectoryName.Substring(_primaryPath.Length).Trim('/', '\\'), // Make it combinable + fileName + ); + + if (File.Exists(fallbackFilePath)) + { + // Serve the file from the fallback directory + var fileStream = File.OpenRead(fallbackFilePath); + var response = _webView.CoreWebView2.Environment.CreateWebResourceResponse( + fileStream, 200, "OK", "Content-Type: application/octet-stream"); + args.Response = response; + } + } + } + } + catch (Exception e) + { + // We don’t need to feel burdened by any exceptions + Debug.WriteLine(e); + } + }; + } + } + public void Dispose() { _webView?.Dispose(); diff --git a/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Plugin.cs index 5c45eed..1ca828e 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Plugin.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Plugin.cs @@ -1,17 +1,17 @@ // Copyright © 2017 Paddy Xu -// +// // This file is part of QuickLook program. -// +// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program. If not, see . @@ -67,7 +67,7 @@ namespace QuickLook.Plugin.MarkdownViewer context.Title = Path.GetFileName(path); var htmlPath = GenerateMarkdownHtml(path); - _panel.NavigateToFile(htmlPath); + _panel.NavigateToFile(htmlPath, Path.GetDirectoryName(path)); _panel.Dispatcher.Invoke(() => { context.IsBusy = false; }, DispatcherPriority.Loaded); } @@ -104,6 +104,7 @@ namespace QuickLook.Plugin.MarkdownViewer } #region Cleanup + private void CleanupTempHtmlFile() { if (!string.IsNullOrEmpty(_currentHtmlPath) && File.Exists(_currentHtmlPath)) @@ -145,6 +146,7 @@ namespace QuickLook.Plugin.MarkdownViewer _panel?.Dispose(); _panel = null; } - #endregion + + #endregion Cleanup } -} \ No newline at end of file +}