Skip to content

Commit 5d03667

Browse files
authored
Revert "Svg thumbnail failed rendering (#32936)" as it caused a regression (#38058)
Revert "Svg thumbnail failed rendering (#32936)" This reverts commit 1d358af.
1 parent 2b4d13c commit 5d03667

File tree

1 file changed

+65
-123
lines changed

1 file changed

+65
-123
lines changed

src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs

+65-123
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
using System.Globalization;
66
using System.Reflection;
77
using System.Runtime.CompilerServices;
8-
using System.Xml.Linq;
8+
using System.Threading;
9+
910
using Common.Utilities;
1011
using ManagedCommon;
1112
using Microsoft.Web.WebView2.Core;
@@ -117,151 +118,92 @@ public Bitmap GetThumbnailImpl(uint cx)
117118
_browser.Height = (int)cx;
118119
_browser.NavigationCompleted += async (object sender, CoreWebView2NavigationCompletedEventArgs args) =>
119120
{
120-
try
121+
var a = await _browser.ExecuteScriptAsync($"document.getElementsByTagName('svg')[0].viewBox;");
122+
if (a != null)
121123
{
122-
// Check if the SVG element is present
123-
var a = await _browser.ExecuteScriptAsync($"document.getElementsByTagName('svg')[0].viewBox;");
124-
if (a != null)
125-
{
126-
var svgContent = SvgContents.Substring(SvgContents.IndexOf("<svg", StringComparison.OrdinalIgnoreCase), SvgContents.IndexOf("</svg>", StringComparison.OrdinalIgnoreCase) - SvgContents.IndexOf("<svg", StringComparison.OrdinalIgnoreCase) + "</svg>".Length);
127-
128-
Dictionary<string, string> styleDict = new Dictionary<string, string>();
129-
130-
// Try to parse the SVG content
131-
try
132-
{
133-
// Attempt to parse the svgContent
134-
var svgDocument = XDocument.Parse(svgContent);
135-
var svgElement = svgDocument.Root;
136-
var currentStyle = svgElement?.Attribute("style")?.Value;
137-
138-
// If style attribute exists, preserve existing styles
139-
if (!string.IsNullOrEmpty(currentStyle) && currentStyle != "null")
140-
{
141-
styleDict = currentStyle
142-
.Split(';', StringSplitOptions.RemoveEmptyEntries)
143-
.Select(stylePart => stylePart.Split(':', 2, StringSplitOptions.TrimEntries))
144-
.Where(styleKeyValue => styleKeyValue.Length == 2 && !string.IsNullOrEmpty(styleKeyValue[0]))
145-
.ToDictionary(
146-
styleKeyValue => styleKeyValue[0],
147-
styleKeyValue => styleKeyValue[1]);
148-
}
149-
}
150-
catch (Exception ex)
151-
{
152-
// Log the error if the SVG content is not valid or parsing fails
153-
Logger.LogError($"Failed to parse SVG content: {ex.Message}");
154-
}
155-
156-
// Add or replace width and height in the existing style
157-
styleDict["width"] = "100%";
158-
styleDict["height"] = "100%";
159-
160-
// Construct a single JavaScript string to set all properties
161-
var styleScript = string.Join(";", styleDict.Select(kv => $"document.getElementsByTagName('svg')[0].style.setProperty('{kv.Key}', '{kv.Value}');"));
162-
163-
// Apply the new style attributes using the constructed script
164-
await _browser.ExecuteScriptAsync(styleScript);
165-
}
166-
167-
// Hide scrollbar - fixes #18286
168-
await _browser.ExecuteScriptAsync("document.querySelector('body').style.overflow='hidden'");
124+
await _browser.ExecuteScriptAsync($"document.getElementsByTagName('svg')[0].style = 'width:100%;height:100%';");
125+
}
169126

170-
MemoryStream ms = new MemoryStream();
171-
await _browser.CoreWebView2.CapturePreviewAsync(CoreWebView2CapturePreviewImageFormat.Png, ms);
172-
thumbnail = new Bitmap(ms);
127+
// Hide scrollbar - fixes #18286
128+
await _browser.ExecuteScriptAsync("document.querySelector('body').style.overflow='hidden'");
173129

174-
if (thumbnail.Width != cx && thumbnail.Height != cx && thumbnail.Width != 0 && thumbnail.Height != 0)
175-
{
176-
// We are not the appropriate size for caller. Resize now while
177-
// respecting the aspect ratio.
178-
float scale = Math.Min((float)cx / thumbnail.Width, (float)cx / thumbnail.Height);
179-
int scaleWidth = (int)(thumbnail.Width * scale);
180-
int scaleHeight = (int)(thumbnail.Height * scale);
181-
thumbnail = ResizeImage(thumbnail, scaleWidth, scaleHeight);
182-
}
130+
MemoryStream ms = new MemoryStream();
131+
await _browser.CoreWebView2.CapturePreviewAsync(CoreWebView2CapturePreviewImageFormat.Png, ms);
132+
thumbnail = new Bitmap(ms);
183133

184-
thumbnailDone.Set();
185-
}
186-
catch (Exception ex)
134+
if (thumbnail.Width != cx && thumbnail.Height != cx && thumbnail.Width != 0 && thumbnail.Height != 0)
187135
{
188-
Logger.LogError("Error during NavigationCompleted: ", ex);
189-
thumbnailDone.Set();
136+
// We are not the appropriate size for caller. Resize now while
137+
// respecting the aspect ratio.
138+
float scale = Math.Min((float)cx / thumbnail.Width, (float)cx / thumbnail.Height);
139+
int scaleWidth = (int)(thumbnail.Width * scale);
140+
int scaleHeight = (int)(thumbnail.Height * scale);
141+
thumbnail = ResizeImage(thumbnail, scaleWidth, scaleHeight);
190142
}
143+
144+
thumbnailDone.Set();
191145
};
192146

193147
var webView2Options = new CoreWebView2EnvironmentOptions("--block-new-web-contents");
194148
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
195-
webView2EnvironmentAwaiter = CoreWebView2Environment
196-
.CreateAsync(userDataFolder: _webView2UserDataFolder, options: webView2Options)
197-
.ConfigureAwait(true).GetAwaiter();
149+
webView2EnvironmentAwaiter = CoreWebView2Environment
150+
.CreateAsync(userDataFolder: _webView2UserDataFolder, options: webView2Options)
151+
.ConfigureAwait(true).GetAwaiter();
198152

199153
webView2EnvironmentAwaiter.OnCompleted(async () =>
200154
{
201-
for (int attempt = 0; attempt < 3; attempt++)
155+
try
202156
{
203-
try
157+
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
158+
await _browser.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
159+
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Deny);
160+
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
161+
_browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
162+
_browser.CoreWebView2.Settings.AreDevToolsEnabled = false;
163+
_browser.CoreWebView2.Settings.AreHostObjectsAllowed = false;
164+
_browser.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;
165+
_browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
166+
_browser.CoreWebView2.Settings.IsScriptEnabled = false;
167+
_browser.CoreWebView2.Settings.IsWebMessageEnabled = false;
168+
169+
// Don't load any resources.
170+
_browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
171+
_browser.CoreWebView2.WebResourceRequested += (object sender, CoreWebView2WebResourceRequestedEventArgs e) =>
204172
{
205-
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
206-
await _browser.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
207-
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Deny);
208-
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
209-
_browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
210-
_browser.CoreWebView2.Settings.AreDevToolsEnabled = false;
211-
_browser.CoreWebView2.Settings.AreHostObjectsAllowed = false;
212-
_browser.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;
213-
_browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
214-
_browser.CoreWebView2.Settings.IsScriptEnabled = false;
215-
_browser.CoreWebView2.Settings.IsWebMessageEnabled = false;
216-
217-
// Don't load any resources.
218-
_browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
219-
_browser.CoreWebView2.WebResourceRequested += (object sender, CoreWebView2WebResourceRequestedEventArgs e) =>
220-
{
221-
// Show local file we've saved with the svg contents. Block all else.
222-
if (new Uri(e.Request.Uri) != _localFileURI)
223-
{
224-
e.Response = _browser.CoreWebView2.Environment.CreateWebResourceResponse(null, 403, "Forbidden", null);
225-
}
226-
};
227-
228-
// WebView2.NavigateToString() limitation
229-
// See https://learn.microsoft.com/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
230-
// While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
231-
SvgContentsReady.Wait();
232-
if (string.IsNullOrEmpty(SvgContents) || !SvgContents.Contains("svg"))
173+
// Show local file we've saved with the svg contents. Block all else.
174+
if (new Uri(e.Request.Uri) != _localFileURI)
233175
{
234-
thumbnailDone.Set();
235-
return;
176+
e.Response = _browser.CoreWebView2.Environment.CreateWebResourceResponse(null, 403, "Forbidden", null);
236177
}
178+
};
237179

238-
if (SvgContents.Length > 1_500_000)
239-
{
240-
string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
241-
File.WriteAllText(filename, SvgContents);
242-
_localFileURI = new Uri(filename);
243-
_browser.Source = _localFileURI;
244-
}
245-
else
246-
{
247-
_browser.NavigateToString(SvgContents);
248-
}
180+
// WebView2.NavigateToString() limitation
181+
// See https://learn.microsoft.com/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
182+
// While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
183+
SvgContentsReady.Wait();
184+
if (string.IsNullOrEmpty(SvgContents) || !SvgContents.Contains("svg"))
185+
{
186+
thumbnailDone.Set();
187+
return;
188+
}
249189

250-
break; // Exit the retry loop if initialization succeeds
190+
if (SvgContents.Length > 1_500_000)
191+
{
192+
string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
193+
File.WriteAllText(filename, SvgContents);
194+
_localFileURI = new Uri(filename);
195+
_browser.Source = _localFileURI;
251196
}
252-
catch (Exception ex)
197+
else
253198
{
254-
Logger.LogError($"Initialization attempt {attempt} failed: {ex.Message}");
255-
if (attempt == 2)
256-
{
257-
Logger.LogError($"Failed running webView2Environment completed for {FilePath} : ", ex);
258-
thumbnailDone.Set();
259-
return;
260-
}
261-
262-
await Task.Delay(1000); // Delay before retrying
199+
_browser.NavigateToString(SvgContents);
263200
}
264201
}
202+
catch (Exception ex)
203+
{
204+
Logger.LogError($"Failed running webView2Environment completed for {FilePath} : ", ex);
205+
thumbnailDone.Set();
206+
}
265207
});
266208

267209
while (!thumbnailDone.Wait(75))

0 commit comments

Comments
 (0)