From dd84b1d4de3de9034a7a2e0891d39ff2bfe55c8f Mon Sep 17 00:00:00 2001 From: Javier Calvarro Nelson Date: Thu, 18 Mar 2021 13:00:57 -0700 Subject: [PATCH 1/4] [Blazor] Add support for static web assets in Blazor desktop --- AspNetCore.sln | 15 + .../BlazorWinFormsApp.csproj | 6 +- .../BlazorWinFormsApp/Pages/Index.razor | 4 + .../BlazorWinFormsApp/wwwroot/index.html | 1 + .../Samples/BlazorWpfApp/BlazorWpfApp.csproj | 4 + .../Samples/BlazorWpfApp/Pages/Index.razor | 5 +- .../Samples/BlazorWpfApp/wwwroot/index.html | 1 + .../WebviewAppShared/ExampleJsInterop.cs | 39 +++ .../WebviewAppShared/SharedComponent.razor | 3 + .../SharedComponent.razor.css | 6 + .../WebviewAppShared/WebviewAppShared.csproj | 16 + .../Samples/WebviewAppShared/_Imports.razor | 1 + .../WebviewAppShared/wwwroot/background.png | Bin 0 -> 378 bytes .../wwwroot/exampleJsInterop.js | 6 + ...osoft.AspNetCore.Components.WebView.csproj | 1 + .../WebView/src/StaticWebAssetsLoader.cs | 292 ++++++++++++++++++ .../WebView/WebView/src/WebViewManager.cs | 2 + 17 files changed, 400 insertions(+), 2 deletions(-) create mode 100644 src/Components/WebView/Samples/WebviewAppShared/ExampleJsInterop.cs create mode 100644 src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor create mode 100644 src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor.css create mode 100644 src/Components/WebView/Samples/WebviewAppShared/WebviewAppShared.csproj create mode 100644 src/Components/WebView/Samples/WebviewAppShared/_Imports.razor create mode 100644 src/Components/WebView/Samples/WebviewAppShared/wwwroot/background.png create mode 100644 src/Components/WebView/Samples/WebviewAppShared/wwwroot/exampleJsInterop.js create mode 100644 src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs diff --git a/AspNetCore.sln b/AspNetCore.sln index 28f62ede717c..591baf0d56bf 100644 --- a/AspNetCore.sln +++ b/AspNetCore.sln @@ -1626,6 +1626,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTestApp", "src\Components\WebView\Platforms\Wpf\testassets\WpfTestApp\WpfTestApp.csproj", "{036C6BDA-7B69-4E8C-A921-822DA5972A56}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebviewAppShared", "src\Components\WebView\Samples\WebviewAppShared\WebviewAppShared.csproj", "{64C3BAC8-C4F8-466A-9E84-0400EE54B25A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -7685,6 +7687,18 @@ Global {036C6BDA-7B69-4E8C-A921-822DA5972A56}.Release|x64.Build.0 = Release|Any CPU {036C6BDA-7B69-4E8C-A921-822DA5972A56}.Release|x86.ActiveCfg = Release|Any CPU {036C6BDA-7B69-4E8C-A921-822DA5972A56}.Release|x86.Build.0 = Release|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Debug|x64.ActiveCfg = Debug|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Debug|x64.Build.0 = Debug|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Debug|x86.ActiveCfg = Debug|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Debug|x86.Build.0 = Debug|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Release|Any CPU.Build.0 = Release|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Release|x64.ActiveCfg = Release|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Release|x64.Build.0 = Release|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Release|x86.ActiveCfg = Release|Any CPU + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -8488,6 +8502,7 @@ Global {99EE7769-3C81-477B-B947-0A5CBCD5B27D} = {F0849E7E-61DB-4849-9368-9E7BC125DCB0} {94D0D6F3-8632-41DE-908B-47A787D570FF} = {5241CF68-66A0-4724-9BAA-36DB959A5B11} {036C6BDA-7B69-4E8C-A921-822DA5972A56} = {94D0D6F3-8632-41DE-908B-47A787D570FF} + {64C3BAC8-C4F8-466A-9E84-0400EE54B25A} = {D3B76F4E-A980-45BF-AEA1-EA3175B0B5A1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3E8720B3-DBDD-498C-B383-2CC32A054E8F} diff --git a/src/Components/WebView/Samples/BlazorWinFormsApp/BlazorWinFormsApp.csproj b/src/Components/WebView/Samples/BlazorWinFormsApp/BlazorWinFormsApp.csproj index cafb88085e68..46a1aaa75786 100644 --- a/src/Components/WebView/Samples/BlazorWinFormsApp/BlazorWinFormsApp.csproj +++ b/src/Components/WebView/Samples/BlazorWinFormsApp/BlazorWinFormsApp.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework)-windows @@ -11,6 +11,10 @@ + + + + PreserveNewest diff --git a/src/Components/WebView/Samples/BlazorWinFormsApp/Pages/Index.razor b/src/Components/WebView/Samples/BlazorWinFormsApp/Pages/Index.razor index dc62a9fb5de3..ef4c042ed3ce 100644 --- a/src/Components/WebView/Samples/BlazorWinFormsApp/Pages/Index.razor +++ b/src/Components/WebView/Samples/BlazorWinFormsApp/Pages/Index.razor @@ -1,5 +1,6 @@ @page "/" @inject AppState AppState +@using WebviewAppShared

Hello, world!

@@ -8,6 +9,9 @@ +

This is a shared component

+ + @code { void IncrementCount() { diff --git a/src/Components/WebView/Samples/BlazorWinFormsApp/wwwroot/index.html b/src/Components/WebView/Samples/BlazorWinFormsApp/wwwroot/index.html index ebfb7123838b..228867852716 100644 --- a/src/Components/WebView/Samples/BlazorWinFormsApp/wwwroot/index.html +++ b/src/Components/WebView/Samples/BlazorWinFormsApp/wwwroot/index.html @@ -7,6 +7,7 @@ Blazor WinForms app + diff --git a/src/Components/WebView/Samples/BlazorWpfApp/BlazorWpfApp.csproj b/src/Components/WebView/Samples/BlazorWpfApp/BlazorWpfApp.csproj index 7aee04cb06ac..093ee74f7c66 100644 --- a/src/Components/WebView/Samples/BlazorWpfApp/BlazorWpfApp.csproj +++ b/src/Components/WebView/Samples/BlazorWpfApp/BlazorWpfApp.csproj @@ -7,6 +7,10 @@ false
+ + + + diff --git a/src/Components/WebView/Samples/BlazorWpfApp/Pages/Index.razor b/src/Components/WebView/Samples/BlazorWpfApp/Pages/Index.razor index c905713a14e8..e8ceefc23d93 100644 --- a/src/Components/WebView/Samples/BlazorWpfApp/Pages/Index.razor +++ b/src/Components/WebView/Samples/BlazorWpfApp/Pages/Index.razor @@ -1,5 +1,5 @@ @page "/" - +@using WebviewAppShared // NOTE: The full namespace is included here to work around this bug: https://github.com/dotnet/aspnetcore/issues/30851 @inject BlazorWpfApp.AppState AppState @@ -10,6 +10,9 @@ +

This is a shared component

+ + @code { void IncrementCount() { diff --git a/src/Components/WebView/Samples/BlazorWpfApp/wwwroot/index.html b/src/Components/WebView/Samples/BlazorWpfApp/wwwroot/index.html index b3e976b666c1..3887aef9712e 100644 --- a/src/Components/WebView/Samples/BlazorWpfApp/wwwroot/index.html +++ b/src/Components/WebView/Samples/BlazorWpfApp/wwwroot/index.html @@ -7,6 +7,7 @@ Blazor WPF app + diff --git a/src/Components/WebView/Samples/WebviewAppShared/ExampleJsInterop.cs b/src/Components/WebView/Samples/WebviewAppShared/ExampleJsInterop.cs new file mode 100644 index 000000000000..e4f19d8ccce7 --- /dev/null +++ b/src/Components/WebView/Samples/WebviewAppShared/ExampleJsInterop.cs @@ -0,0 +1,39 @@ +using Microsoft.JSInterop; +using System; +using System.Threading.Tasks; + +namespace WebviewAppShared +{ + // This class provides an example of how JavaScript functionality can be wrapped + // in a .NET class for easy consumption. The associated JavaScript module is + // loaded on demand when first needed. + // + // This class can be registered as scoped DI service and then injected into Blazor + // components for use. + + public class ExampleJsInterop : IAsyncDisposable + { + private readonly Lazy> moduleTask; + + public ExampleJsInterop(IJSRuntime jsRuntime) + { + moduleTask = new(() => jsRuntime.InvokeAsync( + "import", "./_content/WebviewAppShared/exampleJsInterop.js").AsTask()); + } + + public async ValueTask Prompt(string message) + { + var module = await moduleTask.Value; + return await module.InvokeAsync("showPrompt", message); + } + + public async ValueTask DisposeAsync() + { + if (moduleTask.IsValueCreated) + { + var module = await moduleTask.Value; + await module.DisposeAsync(); + } + } + } +} diff --git a/src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor b/src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor new file mode 100644 index 000000000000..0d9cbc425c97 --- /dev/null +++ b/src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor @@ -0,0 +1,3 @@ +
+ This Blazor component is defined in the WebviewAppShared package. +
diff --git a/src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor.css b/src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor.css new file mode 100644 index 000000000000..c6afca404296 --- /dev/null +++ b/src/Components/WebView/Samples/WebviewAppShared/SharedComponent.razor.css @@ -0,0 +1,6 @@ +.my-component { + border: 2px dashed red; + padding: 1em; + margin: 1em 0; + background-image: url('background.png'); +} diff --git a/src/Components/WebView/Samples/WebviewAppShared/WebviewAppShared.csproj b/src/Components/WebView/Samples/WebviewAppShared/WebviewAppShared.csproj new file mode 100644 index 000000000000..6836c303c123 --- /dev/null +++ b/src/Components/WebView/Samples/WebviewAppShared/WebviewAppShared.csproj @@ -0,0 +1,16 @@ + + + + $(DefaultNetCoreTargetFramework) + + + + + + + + + + + + diff --git a/src/Components/WebView/Samples/WebviewAppShared/_Imports.razor b/src/Components/WebView/Samples/WebviewAppShared/_Imports.razor new file mode 100644 index 000000000000..77285129dabe --- /dev/null +++ b/src/Components/WebView/Samples/WebviewAppShared/_Imports.razor @@ -0,0 +1 @@ +@using Microsoft.AspNetCore.Components.Web diff --git a/src/Components/WebView/Samples/WebviewAppShared/wwwroot/background.png b/src/Components/WebView/Samples/WebviewAppShared/wwwroot/background.png new file mode 100644 index 0000000000000000000000000000000000000000..e15a3bde6e2bdb380df6a0b46d7ed00bdeb0aaa8 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK1SGdsl%54rjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucLCF%=h?3y^w370~qEv>0#LT=By}Z;C1rt33 zJwr2>%=KS^ie7oTIEF;HpS|GCbyPusHSqiXaCu3qf)82(9Gq&mZq2{Kq}M*X&MWtJ zSi1Jo7ZzfImg%g=t(qo=wsSR2lZoP(Rj#3wacN=q0?Br(rXzgZEGK2$ID{|A=5S{xJEuzSH>!M+7wSY6hB<=-E^*n0W7 S8wY^CX7F_Nb6Mw<&;$S{dxtsz literal 0 HcmV?d00001 diff --git a/src/Components/WebView/Samples/WebviewAppShared/wwwroot/exampleJsInterop.js b/src/Components/WebView/Samples/WebviewAppShared/wwwroot/exampleJsInterop.js new file mode 100644 index 000000000000..ea8d76ad2d12 --- /dev/null +++ b/src/Components/WebView/Samples/WebviewAppShared/wwwroot/exampleJsInterop.js @@ -0,0 +1,6 @@ +// This is a JavaScript module that is loaded on demand. It can export any number of +// functions, and may import other JavaScript modules if required. + +export function showPrompt(message) { + return prompt(message, 'Type anything here'); +} diff --git a/src/Components/WebView/WebView/src/Microsoft.AspNetCore.Components.WebView.csproj b/src/Components/WebView/WebView/src/Microsoft.AspNetCore.Components.WebView.csproj index af89f25af168..7cf89005ecfb 100644 --- a/src/Components/WebView/WebView/src/Microsoft.AspNetCore.Components.WebView.csproj +++ b/src/Components/WebView/WebView/src/Microsoft.AspNetCore.Components.WebView.csproj @@ -32,6 +32,7 @@ + new StaticWebAssetsFileProvider(cr.BasePath, cr.Path)) + .OfType() // Upcast so we can insert on the resulting list. + .ToList(); + + if (additionalFiles.Count == 0) + { + return systemProvider; + } + else + { + additionalFiles.Insert(0, webRootFileProvider); + return new CompositeFileProvider(additionalFiles); + } + } + + private static string? ResolveRelativeToAssembly() + { + var assembly = Assembly.GetEntryAssembly(); + if (string.IsNullOrEmpty(assembly?.Location)) + { + return null; + } + + var name = Path.GetFileNameWithoutExtension(assembly.Location); + + return Path.Combine(Path.GetDirectoryName(assembly.Location)!, $"{name}.StaticWebAssets.xml"); + } + + internal static class StaticWebAssetsReader + { + private const string ManifestRootElementName = "StaticWebAssets"; + private const string VersionAttributeName = "Version"; + private const string ContentRootElementName = "ContentRoot"; + + internal static IEnumerable Parse(Stream manifest) + { + var document = XDocument.Load(manifest); + if (!string.Equals(document.Root!.Name.LocalName, ManifestRootElementName, StringComparison.OrdinalIgnoreCase)) + { + throw new InvalidOperationException($"Invalid manifest format. Manifest root must be '{ManifestRootElementName}'"); + } + + var version = document.Root.Attribute(VersionAttributeName); + if (version == null) + { + throw new InvalidOperationException($"Invalid manifest format. Manifest root element must contain a version '{VersionAttributeName}' attribute"); + } + + if (version.Value != "1.0") + { + throw new InvalidOperationException($"Unknown manifest version. Manifest version must be '1.0'"); + } + + foreach (var element in document.Root.Elements()) + { + if (!string.Equals(element.Name.LocalName, ContentRootElementName, StringComparison.OrdinalIgnoreCase)) + { + throw new InvalidOperationException($"Invalid manifest format. Invalid element '{element.Name.LocalName}'. All {StaticWebAssetsLoader.StaticWebAssetsManifestName} child elements must be '{ContentRootElementName}' elements."); + } + if (!element.IsEmpty) + { + throw new InvalidOperationException($"Invalid manifest format. {ContentRootElementName} can't have content."); + } + + var basePath = ParseRequiredAttribute(element, "BasePath"); + var path = ParseRequiredAttribute(element, "Path"); + yield return new ContentRootMapping(basePath, path); + } + } + + private static string ParseRequiredAttribute(XElement element, string attributeName) + { + var attribute = element.Attribute(attributeName); + if (attribute == null) + { + throw new InvalidOperationException($"Invalid manifest format. Missing {attributeName} attribute in '{ContentRootElementName}' element."); + } + return attribute.Value; + } + + internal readonly struct ContentRootMapping + { + public ContentRootMapping(string basePath, string path) + { + BasePath = basePath; + Path = path; + } + + public string BasePath { get; } + public string Path { get; } + } + } + + internal class StaticWebAssetsFileProvider : IFileProvider + { + private static readonly StringComparison FilePathComparison = OperatingSystem.IsWindows() ? + StringComparison.OrdinalIgnoreCase : + StringComparison.Ordinal; + + public StaticWebAssetsFileProvider(string pathPrefix, string contentRoot) + { + BasePath = NormalizePath(pathPrefix); + InnerProvider = new PhysicalFileProvider(contentRoot); + } + + public PhysicalFileProvider InnerProvider { get; } + + public PathString BasePath { get; } + + /// + public IDirectoryContents GetDirectoryContents(string subpath) + { + var modifiedSub = NormalizePath(subpath); + + if (BasePath == "/") + { + return InnerProvider.GetDirectoryContents(modifiedSub); + } + + if (StartsWithBasePath(modifiedSub, out var physicalPath)) + { + return InnerProvider.GetDirectoryContents(physicalPath.Value); + } + else if (string.Equals(subpath, string.Empty) || string.Equals(modifiedSub, "/")) + { + return new StaticWebAssetsDirectoryRoot(BasePath); + } + else if (BasePath.StartsWithSegments(modifiedSub, FilePathComparison, out var remaining)) + { + return new StaticWebAssetsDirectoryRoot(remaining); + } + + return NotFoundDirectoryContents.Singleton; + } + + /// + public IFileInfo GetFileInfo(string subpath) + { + var modifiedSub = NormalizePath(subpath); + + if (BasePath == "/") + { + return InnerProvider.GetFileInfo(subpath); + } + + if (!StartsWithBasePath(modifiedSub, out var physicalPath)) + { + return new NotFoundFileInfo(subpath); + } + else + { + return InnerProvider.GetFileInfo(physicalPath.Value); + } + } + + /// + public IChangeToken Watch(string filter) + { + return InnerProvider.Watch(filter); + } + + private static string NormalizePath(string path) + { + path = path.Replace('\\', '/'); + return path.StartsWith('/') ? path : "/" + path; + } + + private bool StartsWithBasePath(string subpath, out PathString rest) + { + return new PathString(subpath).StartsWithSegments(BasePath, FilePathComparison, out rest); + } + + private class StaticWebAssetsDirectoryRoot : IDirectoryContents + { + private readonly string _nextSegment; + + public StaticWebAssetsDirectoryRoot(PathString remainingPath) + { + // We MUST use the Value property here because it is unescaped. + _nextSegment = remainingPath.Value?.Split("/", StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ?? string.Empty; + } + + public bool Exists => true; + + public IEnumerator GetEnumerator() + { + return GenerateEnum(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GenerateEnum(); + } + + private IEnumerator GenerateEnum() + { + return new[] { new StaticWebAssetsFileInfo(_nextSegment) } + .Cast().GetEnumerator(); + } + + private class StaticWebAssetsFileInfo : IFileInfo + { + public StaticWebAssetsFileInfo(string name) + { + Name = name; + } + + public bool Exists => true; + + public long Length => throw new NotImplementedException(); + + public string PhysicalPath => throw new NotImplementedException(); + + public DateTimeOffset LastModified => throw new NotImplementedException(); + + public bool IsDirectory => true; + + public string Name { get; } + + public Stream CreateReadStream() + { + throw new NotImplementedException(); + } + } + } + } + } +} +#nullable restore diff --git a/src/Components/WebView/WebView/src/WebViewManager.cs b/src/Components/WebView/WebView/src/WebViewManager.cs index 2a69f87c3e47..ed72ebfa35ef 100644 --- a/src/Components/WebView/WebView/src/WebViewManager.cs +++ b/src/Components/WebView/WebView/src/WebViewManager.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; @@ -44,6 +45,7 @@ public WebViewManager(IServiceProvider provider, Dispatcher dispatcher, Uri appB _provider = provider ?? throw new ArgumentNullException(nameof(provider)); _dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher)); _appBaseUri = EnsureTrailingSlash(appBaseUri ?? throw new ArgumentNullException(nameof(appBaseUri))); + fileProvider = StaticWebAssetsLoader.UseStaticWebAssets(fileProvider); _staticContentProvider = new StaticContentProvider(fileProvider, appBaseUri, hostPageRelativePath); _ipcSender = new IpcSender(_dispatcher, SendMessage); _ipcReceiver = new IpcReceiver(AttachToPageAsync); From 33e29ae2493ae883a4f1c88366c1ff4220728e41 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 18 Mar 2021 16:51:12 -0700 Subject: [PATCH 2/4] Update src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs --- src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs b/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs index 48620b07315c..c355a181d1c0 100644 --- a/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs +++ b/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs @@ -23,7 +23,7 @@ internal class StaticWebAssetsLoader internal static IFileProvider UseStaticWebAssets(IFileProvider systemProvider) { using var manifest = GetManifestStream(); - if(manifest != null) + if (manifest != null) { return UseStaticWebAssetsCore(systemProvider, manifest); }else From b36be67330b21ae0b01684ab65f63aeca26fb243 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 18 Mar 2021 16:51:16 -0700 Subject: [PATCH 3/4] Update src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs --- src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs b/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs index c355a181d1c0..269a0def0030 100644 --- a/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs +++ b/src/Components/WebView/WebView/src/StaticWebAssetsLoader.cs @@ -26,7 +26,8 @@ internal static IFileProvider UseStaticWebAssets(IFileProvider systemProvider) if (manifest != null) { return UseStaticWebAssetsCore(systemProvider, manifest); - }else + } + else { return systemProvider; } From 14244e0c014427e63f7ffbbeff4ac21a14df076b Mon Sep 17 00:00:00 2001 From: Javier Calvarro Nelson Date: Fri, 19 Mar 2021 01:13:25 -0700 Subject: [PATCH 4/4] Update solution filter for components no deps --- src/Components/ComponentsNoDeps.slnf | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/ComponentsNoDeps.slnf b/src/Components/ComponentsNoDeps.slnf index 81037f138f3b..a0f1f200b623 100644 --- a/src/Components/ComponentsNoDeps.slnf +++ b/src/Components/ComponentsNoDeps.slnf @@ -44,6 +44,7 @@ "src\\Components\\WebView\\Platforms\\Wpf\\testassets\\WpfTestApp\\WpfTestApp.csproj", "src\\Components\\WebView\\Samples\\BlazorWinFormsApp\\BlazorWinFormsApp.csproj", "src\\Components\\WebView\\Samples\\BlazorWpfApp\\BlazorWpfApp.csproj", + "src\\Components\\WebView\\Samples\\WebviewAppShared\\WebviewAppShared.csproj", "src\\Components\\WebView\\WebView\\src\\Microsoft.AspNetCore.Components.WebView.csproj", "src\\Components\\WebView\\WebView\\test\\Microsoft.AspNetCore.Components.WebView.Test.csproj", "src\\Components\\Web\\src\\Microsoft.AspNetCore.Components.Web.csproj",