Skip to content

Commit 2ea716a

Browse files
committed
make html support html
1 parent 03aec1a commit 2ea716a

File tree

3 files changed

+70
-20
lines changed

3 files changed

+70
-20
lines changed

src/common/FilePreviewCommon/MarkdownHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static string MarkdownHtml(string fileContent, string theme, string fileP
3939
var softlineBreak = new Markdig.Extensions.Hardlines.SoftlineBreakAsHardlineExtension();
4040

4141
MarkdownPipelineBuilder pipelineBuilder;
42-
pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseEmojiAndSmiley().UseYamlFrontMatter().UseMathematics().DisableHtml();
42+
pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseEmojiAndSmiley().UseYamlFrontMatter().UseMathematics();
4343
pipelineBuilder.Extensions.Add(extension);
4444
pipelineBuilder.Extensions.Add(softlineBreak);
4545

src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public sealed partial class BrowserControl : Microsoft.UI.Xaml.Controls.UserCont
3434

3535
private Color? _originalBackgroundColor;
3636

37+
/// <summary>
38+
/// URI of the current source being previewed (for resource filtering)
39+
/// </summary>
40+
private Uri? _currentSourceUri;
41+
3742
public delegate void NavigationCompletedHandler(WebView2? sender, CoreWebView2NavigationCompletedEventArgs? args);
3843

3944
public delegate void DOMContentLoadedHandler(CoreWebView2? sender, CoreWebView2DOMContentLoadedEventArgs? args);
@@ -97,6 +102,7 @@ public BrowserControl()
97102
{
98103
this.InitializeComponent();
99104
Environment.SetEnvironmentVariable("WEBVIEW2_USER_DATA_FOLDER", TempFolderPath.Path, EnvironmentVariableTarget.Process);
105+
Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--block-new-web-contents", EnvironmentVariableTarget.Process);
100106
}
101107

102108
public void Dispose()
@@ -105,6 +111,7 @@ public void Dispose()
105111
{
106112
PreviewBrowser.CoreWebView2.DOMContentLoaded -= CoreWebView2_DOMContentLoaded;
107113
PreviewBrowser.CoreWebView2.ContextMenuRequested -= CoreWebView2_ContextMenuRequested;
114+
RemoveResourceFilter();
108115
}
109116
}
110117

@@ -123,6 +130,14 @@ public void Navigate()
123130
{
124131
/* CoreWebView2.Navigate() will always trigger a navigation even if the content/URI is the same.
125132
* Use WebView2.Source to avoid re-navigating to the same content. */
133+
_currentSourceUri = Source;
134+
135+
// Only apply resource filter for non-dev files
136+
if (!IsDevFilePreview)
137+
{
138+
ApplyResourceFilter();
139+
}
140+
126141
PreviewBrowser.CoreWebView2.Navigate(Source.ToString());
127142
}
128143
}
@@ -146,10 +161,14 @@ private void OnIsDevFilePreviewChanged()
146161
if (IsDevFilePreview)
147162
{
148163
PreviewBrowser.CoreWebView2.SetVirtualHostNameToFolderMapping(Microsoft.PowerToys.FilePreviewCommon.MonacoHelper.VirtualHostName, Microsoft.PowerToys.FilePreviewCommon.MonacoHelper.MonacoDirectory, CoreWebView2HostResourceAccessKind.Allow);
164+
165+
// Remove resource filter for dev files (Monaco needs to load resources)
166+
RemoveResourceFilter();
149167
}
150168
else
151169
{
152170
PreviewBrowser.CoreWebView2.ClearVirtualHostNameToFolderMapping(Microsoft.PowerToys.FilePreviewCommon.MonacoHelper.VirtualHostName);
171+
ApplyResourceFilter();
153172
}
154173
}
155174
}
@@ -283,6 +302,34 @@ private void CoreWebView2_ContextMenuRequested(CoreWebView2 sender, CoreWebView2
283302
}
284303
}
285304

305+
/// <summary>
306+
/// Applies strict resource filtering for non-dev files to block external resources.
307+
/// This prevents XSS attacks and unwanted external content loading.
308+
/// </summary>
309+
private void ApplyResourceFilter()
310+
{
311+
// Remove existing handler to prevent duplicate subscriptions
312+
RemoveResourceFilter();
313+
314+
// Add filter and subscribe to resource requests
315+
PreviewBrowser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
316+
PreviewBrowser.CoreWebView2.WebResourceRequested += CoreWebView2_WebResourceRequested;
317+
}
318+
319+
private void RemoveResourceFilter()
320+
{
321+
PreviewBrowser.CoreWebView2.WebResourceRequested -= CoreWebView2_WebResourceRequested;
322+
}
323+
324+
private void CoreWebView2_WebResourceRequested(CoreWebView2 sender, CoreWebView2WebResourceRequestedEventArgs args)
325+
{
326+
// Only allow loading the specified source file. Block all other resources for security.
327+
if (_currentSourceUri != null && new Uri(args.Request.Uri) != _currentSourceUri)
328+
{
329+
args.Response = PreviewBrowser.CoreWebView2.Environment.CreateWebResourceResponse(null, 403, "Forbidden", null);
330+
}
331+
}
332+
286333
private void CoreWebView2_DOMContentLoaded(CoreWebView2 sender, CoreWebView2DOMContentLoadedEventArgs args)
287334
{
288335
// If the file being previewed is HTML or HTM, reset the background color to its original state.

src/modules/peek/Peek.FilePreviewer/Previewers/WebBrowserPreviewer/WebBrowserPreviewer.cs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -113,38 +113,41 @@ public Task<bool> LoadDisplayInfoAsync(CancellationToken cancellationToken)
113113

114114
await Dispatcher.RunOnUiThread(async () =>
115115
{
116-
bool isHtml = File.Extension == ".html" || File.Extension == ".htm";
117-
bool isMarkdown = File.Extension == ".md";
118-
bool isSvg = File.Extension == ".svg";
116+
string extension = File.Extension;
119117

120-
bool supportedByMonaco = MonacoHelper.SupportedMonacoFileTypes.Contains(File.Extension);
121-
bool useMonaco = supportedByMonaco && !isHtml && !isMarkdown && !isSvg;
118+
// Default: non-dev file preview with standard context menu
119+
IsDevFilePreview = false;
120+
CustomContextMenu = false;
122121

123-
IsDevFilePreview = supportedByMonaco;
124-
CustomContextMenu = useMonaco;
125-
126-
if (useMonaco)
127-
{
128-
var raw = await ReadHelper.Read(File.Path.ToString());
129-
Preview = new Uri(MonacoHelper.PreviewTempFile(raw, File.Extension, TempFolderPath.Path, _previewSettings.SourceCodeTryFormat, _previewSettings.SourceCodeWrapText, _previewSettings.SourceCodeStickyScroll, _previewSettings.SourceCodeFontSize, _previewSettings.SourceCodeMinimap));
130-
}
131-
else if (isMarkdown)
122+
// Determine preview strategy based on file type priority
123+
if (extension == ".md")
132124
{
133-
IsDevFilePreview = false;
125+
// Markdown files use custom renderer
134126
var raw = await ReadHelper.Read(File.Path.ToString());
135127
Preview = new Uri(MarkdownHelper.PreviewTempFile(raw, File.Path, TempFolderPath.Path));
136128
}
137-
else if (isSvg)
129+
else if (extension == ".svg")
138130
{
139131
// SVG files are rendered directly by WebView2 for better compatibility
140132
// with complex SVGs from Adobe Illustrator, Inkscape, etc.
141-
IsDevFilePreview = false;
142133
Preview = new Uri(File.Path);
143134
}
144-
else
135+
else if (extension == ".html" || extension == ".htm")
145136
{
146137
// Simple html file to preview. Shouldn't do things like enabling scripts or using a virtual mapped directory.
147-
IsDevFilePreview = false;
138+
Preview = new Uri(File.Path);
139+
}
140+
else if (MonacoHelper.SupportedMonacoFileTypes.Contains(extension))
141+
{
142+
// Source code files use Monaco editor
143+
IsDevFilePreview = true;
144+
CustomContextMenu = true;
145+
var raw = await ReadHelper.Read(File.Path.ToString());
146+
Preview = new Uri(MonacoHelper.PreviewTempFile(raw, extension, TempFolderPath.Path, _previewSettings.SourceCodeTryFormat, _previewSettings.SourceCodeWrapText, _previewSettings.SourceCodeStickyScroll, _previewSettings.SourceCodeFontSize, _previewSettings.SourceCodeMinimap));
147+
}
148+
else
149+
{
150+
// Fallback for other supported file types (e.g., PDF)
148151
Preview = new Uri(File.Path);
149152
}
150153
});

0 commit comments

Comments
 (0)