Support components and static content in external NuGet packages (#247)
* On build, drop <BlazorPackageContentFiles> items into dist\_content\(PackageName)\ * Add <script> and <link> tags to generated index.html * Add testapp coverage of external content package. Still need to add E2E tests that uses it. * Add missing unit test update * Add example of packaging an entire Blazor component including CSS and images * Add E2E test for component from NuGet package
This commit is contained in:
parent
9549dccc54
commit
0e9d52fe11
11
Blazor.sln
11
Blazor.sln
|
|
@ -87,6 +87,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.Lang
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.BlazorExtension", "tooling\Microsoft.VisualStudio.BlazorExtension\Microsoft.VisualStudio.BlazorExtension.csproj", "{9088E4E4-B855-457F-AE9E-D86709A5E1F4}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestContentPackage", "test\testapps\TestContentPackage\TestContentPackage.csproj", "{C57382BC-EE93-49D5-BC40-5C98AF8AA048}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -301,6 +303,14 @@ Global
|
|||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -340,6 +350,7 @@ Global
|
|||
{FF25111E-5A3E-48A3-96D8-08A2C5A2A91C} = {ADA3AE29-F6DE-49F6-8C7C-B321508CAE8E}
|
||||
{43E39257-7DC1-46BD-9BD9-2319A1313D07} = {F563ABB6-85FB-4CFC-B0D2-1D5130E8246D}
|
||||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4} = {F563ABB6-85FB-4CFC-B0D2-1D5130E8246D}
|
||||
{C57382BC-EE93-49D5-BC40-5C98AF8AA048} = {4AE0D35B-D97A-44D0-8392-C9240377DCCE}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {504DA352-6788-4DC0-8705-82167E72A4D3}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,14 @@ namespace Microsoft.AspNetCore.Blazor.Build.Cli.Commands
|
|||
"The path from the _bin folder to a given referenced dll file (Typically just the dll name)",
|
||||
CommandOptionType.MultipleValue);
|
||||
|
||||
var jsReferences = command.Option("--js",
|
||||
"Adds a <script> tag with the specified 'src' value",
|
||||
CommandOptionType.MultipleValue);
|
||||
|
||||
var cssReferences = command.Option("--css",
|
||||
"Adds a <link rel=stylesheet> tag with the specified 'href' value",
|
||||
CommandOptionType.MultipleValue);
|
||||
|
||||
var outputPath = command.Option("--output",
|
||||
"Path to the output file",
|
||||
CommandOptionType.SingleValue);
|
||||
|
|
@ -36,7 +44,13 @@ namespace Microsoft.AspNetCore.Blazor.Build.Cli.Commands
|
|||
|
||||
try
|
||||
{
|
||||
IndexHtmlWriter.UpdateIndex(clientPage.Value(), mainAssemblyPath.Value, references.Values.ToArray(), outputPath.Value());
|
||||
IndexHtmlWriter.UpdateIndex(
|
||||
clientPage.Value(),
|
||||
mainAssemblyPath.Value,
|
||||
references.Values.ToArray(),
|
||||
jsReferences.Values.ToArray(),
|
||||
cssReferences.Values.ToArray(),
|
||||
outputPath.Value());
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,13 @@ namespace Microsoft.AspNetCore.Blazor.Build
|
|||
{
|
||||
internal class IndexHtmlWriter
|
||||
{
|
||||
public static void UpdateIndex(string path, string assemblyPath, IEnumerable<string> references, string outputPath)
|
||||
public static void UpdateIndex(
|
||||
string path,
|
||||
string assemblyPath,
|
||||
IEnumerable<string> assemblyReferences,
|
||||
IEnumerable<string> jsReferences,
|
||||
IEnumerable<string> cssReferences,
|
||||
string outputPath)
|
||||
{
|
||||
var template = GetTemplate(path);
|
||||
if (template == null)
|
||||
|
|
@ -24,7 +30,7 @@ namespace Microsoft.AspNetCore.Blazor.Build
|
|||
}
|
||||
var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
|
||||
var entryPoint = GetAssemblyEntryPoint(assemblyPath);
|
||||
var updatedContent = GetIndexHtmlContents(template, assemblyName, entryPoint, references);
|
||||
var updatedContent = GetIndexHtmlContents(template, assemblyName, entryPoint, assemblyReferences, jsReferences, cssReferences);
|
||||
var normalizedOutputPath = Normalize(outputPath);
|
||||
Console.WriteLine("Writing index to: " + normalizedOutputPath);
|
||||
File.WriteAllText(normalizedOutputPath, updatedContent);
|
||||
|
|
@ -93,7 +99,9 @@ namespace Microsoft.AspNetCore.Blazor.Build
|
|||
string htmlTemplate,
|
||||
string assemblyName,
|
||||
string assemblyEntryPoint,
|
||||
IEnumerable<string> binFiles)
|
||||
IEnumerable<string> assemblyReferences,
|
||||
IEnumerable<string> jsReferences,
|
||||
IEnumerable<string> cssReferences)
|
||||
{
|
||||
var resultBuilder = new StringBuilder();
|
||||
|
||||
|
|
@ -132,9 +140,19 @@ namespace Microsoft.AspNetCore.Blazor.Build
|
|||
resultBuilder,
|
||||
assemblyName,
|
||||
assemblyEntryPoint,
|
||||
binFiles,
|
||||
assemblyReferences,
|
||||
tag.Attributes);
|
||||
|
||||
// Emit tags to reference any specified JS/CSS files
|
||||
AppendReferenceTags(
|
||||
resultBuilder,
|
||||
cssReferences,
|
||||
"<link rel=\"stylesheet\" href=\"{0}\" />");
|
||||
AppendReferenceTags(
|
||||
resultBuilder,
|
||||
jsReferences,
|
||||
"<script src=\"{0}\" defer></script>");
|
||||
|
||||
// Set a flag so we know not to emit anything else until the special
|
||||
// tag is closed
|
||||
isInBlazorBootTag = true;
|
||||
|
|
@ -160,6 +178,15 @@ namespace Microsoft.AspNetCore.Blazor.Build
|
|||
}
|
||||
}
|
||||
|
||||
private static void AppendReferenceTags(StringBuilder resultBuilder, IEnumerable<string> urls, string format)
|
||||
{
|
||||
foreach (var url in urls)
|
||||
{
|
||||
resultBuilder.AppendLine();
|
||||
resultBuilder.AppendFormat(format, url);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsBlazorBootTag(HtmlTagToken tag)
|
||||
=> string.Equals(tag.Name, "script", StringComparison.Ordinal)
|
||||
&& tag.Attributes.Any(pair =>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
<PropertyGroup Label="Blazor build outputs">
|
||||
<AdditionalMonoLinkerOptions>-c link -u link -t --verbose </AdditionalMonoLinkerOptions>
|
||||
<BaseBlazorPackageContentOutputPath>dist/_content/</BaseBlazorPackageContentOutputPath>
|
||||
<BaseBlazorRuntimeOutputPath>dist/_framework/</BaseBlazorRuntimeOutputPath>
|
||||
<BaseBlazorRuntimeBinOutputPath>$(BaseBlazorRuntimeOutputPath)_bin/</BaseBlazorRuntimeBinOutputPath>
|
||||
<BaseBlazorRuntimeAsmjsOutputPath>$(BaseBlazorRuntimeOutputPath)asmjs/</BaseBlazorRuntimeAsmjsOutputPath>
|
||||
|
|
|
|||
|
|
@ -168,6 +168,14 @@
|
|||
</BlazorItemOutput>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Label="Static content supplied by NuGet packages">
|
||||
<_BlazorPackageContentOutput Include="@(BlazorPackageContentFile)" Condition="%(SourcePackage) != ''">
|
||||
<TargetOutputPath>$(ProjectDir)$(OutputPath)$(BaseBlazorPackageContentOutputPath)%(SourcePackage)\%(RecursiveDir)\%(Filename)%(Extension)</TargetOutputPath>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</_BlazorPackageContentOutput>
|
||||
<BlazorItemOutput Include="@(_BlazorPackageContentOutput)" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Label="Intermediate output paths">
|
||||
|
||||
<!-- /obj/<<configuration>>/<<targetframework>>/blazor -->
|
||||
|
|
@ -522,6 +530,8 @@
|
|||
<ItemGroup>
|
||||
<BlazorIndexHtmlInput Include="$(BlazorIndexHtml)" />
|
||||
<BlazorIndexHtmlInput Include="@(BlazorItemOutput->WithMetadataValue('Type','Assembly')->'%(FullPath)')" />
|
||||
<BlazorIndexHtmlInput Include="@(BlazorPackageJsRef->'%(FullPath)')" />
|
||||
<BlazorIndexHtmlInput Include="@(BlazorPackageCssRef->'%(FullPath)')" />
|
||||
</ItemGroup>
|
||||
|
||||
<WriteLinesToFile
|
||||
|
|
@ -543,9 +553,11 @@
|
|||
Outputs="$(BlazorIndexHtmlOutputPath)">
|
||||
<ItemGroup>
|
||||
<_AppReferences Include="@(BlazorItemOutput->WithMetadataValue('Type','Assembly')->WithMetadataValue('PrimaryOutput','')->'%(FileName)%(Extension)')" />
|
||||
<_JsReferences Include="@(BlazorPackageJsRef->'_content/%(SourcePackage)/%(RecursiveDir)%(FileName)%(Extension)')" />
|
||||
<_CssReferences Include="@(BlazorPackageCssRef->'_content/%(SourcePackage)/%(RecursiveDir)%(FileName)%(Extension)')" />
|
||||
</ItemGroup>
|
||||
|
||||
<Exec Command="$(BlazorBuildExe) build @(IntermediateAssembly) --html-page "$(BlazorIndexHtml)" @(_AppReferences->'--reference %(Identity)', ' ') --output "$(BlazorIndexHtmlOutputPath)"" />
|
||||
<Exec Command="$(BlazorBuildExe) build @(IntermediateAssembly) --html-page "$(BlazorIndexHtml)" @(_AppReferences->'--reference %(Identity)', ' ') @(_JsReferences->'--js %(Identity)', ' ') @(_CssReferences->'--css %(Identity)', ' ') --output "$(BlazorIndexHtmlOutputPath)"" />
|
||||
|
||||
<ItemGroup Condition="Exists('$(BlazorIndexHtmlOutputPath)')">
|
||||
<_BlazorIndex Include="$(BlazorIndexHtmlOutputPath)" />
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using AngleSharp.Parser.Html;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.Build.Test
|
||||
|
|
@ -25,15 +26,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
|
|||
$@"{htmlTemplatePrefix}
|
||||
<script type='blazor-boot' custom1 custom2=""value"">some text that should be removed</script>
|
||||
{htmlTemplateSuffix}";
|
||||
var dependencies = new string[]
|
||||
{
|
||||
"System.Abc.dll",
|
||||
"MyApp.ClassLib.dll",
|
||||
};
|
||||
var assemblyReferences = new string[] { "System.Abc.dll", "MyApp.ClassLib.dll", };
|
||||
var jsReferences = new string[] { "some/file.js", "another.js" };
|
||||
var cssReferences = new string[] { "my/styles.css" };
|
||||
var instance = IndexHtmlWriter.GetIndexHtmlContents(
|
||||
htmlTemplate,
|
||||
"MyApp.Entrypoint",
|
||||
"MyNamespace.MyType::MyMethod", dependencies);
|
||||
"MyNamespace.MyType::MyMethod",
|
||||
assemblyReferences,
|
||||
jsReferences,
|
||||
cssReferences);
|
||||
|
||||
// Act & Assert: Start and end is not modified (including formatting)
|
||||
Assert.StartsWith(htmlTemplatePrefix, instance);
|
||||
|
|
@ -42,7 +44,9 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
|
|||
// Assert: Boot tag is correct
|
||||
var scriptTagText = instance.Substring(htmlTemplatePrefix.Length, instance.Length - htmlTemplatePrefix.Length - htmlTemplateSuffix.Length);
|
||||
var parsedHtml = new HtmlParser().Parse("<html><body>" + scriptTagText + "</body></html>");
|
||||
var scriptElem = parsedHtml.Body.QuerySelector("script");
|
||||
var scriptElems = parsedHtml.Body.QuerySelectorAll("script");
|
||||
var linkElems = parsedHtml.Body.QuerySelectorAll("link");
|
||||
var scriptElem = scriptElems[0];
|
||||
Assert.False(scriptElem.HasChildNodes);
|
||||
Assert.Equal("_framework/blazor.js", scriptElem.GetAttribute("src"));
|
||||
Assert.Equal("MyApp.Entrypoint.dll", scriptElem.GetAttribute("main"));
|
||||
|
|
@ -51,6 +55,16 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
|
|||
Assert.False(scriptElem.HasAttribute("type"));
|
||||
Assert.Equal(string.Empty, scriptElem.Attributes["custom1"].Value);
|
||||
Assert.Equal("value", scriptElem.Attributes["custom2"].Value);
|
||||
|
||||
// Assert: Also contains script tags referencing JS files
|
||||
Assert.Equal(
|
||||
scriptElems.Skip(1).Select(tag => tag.GetAttribute("src")),
|
||||
jsReferences);
|
||||
|
||||
// Assert: Also contains link tags referencing CSS files
|
||||
Assert.Equal(
|
||||
linkElems.Select(tag => tag.GetAttribute("href")),
|
||||
cssReferences);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -58,14 +72,12 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
|
|||
{
|
||||
// Arrange
|
||||
var htmlTemplate = "<!DOCTYPE html><html><body><h1 style='color:red'>Hello</h1>Some text<script type='irrelevant'>blah</script></body></html>";
|
||||
var dependencies = new string[]
|
||||
{
|
||||
"System.Abc.dll",
|
||||
"MyApp.ClassLib.dll",
|
||||
};
|
||||
var assemblyReferences = new string[] { "System.Abc.dll", "MyApp.ClassLib.dll" };
|
||||
var jsReferences = new string[] { "some/file.js", "another.js" };
|
||||
var cssReferences = new string[] { "my/styles.css" };
|
||||
|
||||
var content = IndexHtmlWriter.GetIndexHtmlContents(
|
||||
htmlTemplate, "MyApp.Entrypoint", "MyNamespace.MyType::MyMethod", dependencies);
|
||||
htmlTemplate, "MyApp.Entrypoint", "MyNamespace.MyType::MyMethod", assemblyReferences, jsReferences, cssReferences);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(htmlTemplate, content);
|
||||
|
|
|
|||
|
|
@ -199,5 +199,34 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests
|
|||
elem => Assert.Equal(typeof(Complex).FullName, elem.Text),
|
||||
elem => Assert.Equal(typeof(AssemblyHashAlgorithm).FullName, elem.Text));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanUseComponentAndStaticContentFromExternalNuGetPackage()
|
||||
{
|
||||
var appElement = MountTestComponent<ExternalContentPackage>();
|
||||
|
||||
// NuGet packages can use Blazor's JS interop features to provide
|
||||
// .NET code access to browser APIs
|
||||
var showPromptButton = appElement.FindElements(By.TagName("button")).First();
|
||||
showPromptButton.Click();
|
||||
var modal = Browser.SwitchTo().Alert();
|
||||
modal.SendKeys("Some value from test");
|
||||
modal.Accept();
|
||||
var promptResult = appElement.FindElement(By.TagName("strong"));
|
||||
Assert.Equal("Some value from test", promptResult.Text);
|
||||
|
||||
// NuGet packages can also embed entire Blazor components (themselves
|
||||
// authored as Razor files), including static content. The CSS value
|
||||
// here is in a .css file, so if it's correct we know that static content
|
||||
// file was loaded.
|
||||
var specialStyleDiv = appElement.FindElement(By.ClassName("special-style"));
|
||||
Assert.Equal("50px", specialStyleDiv.GetCssValue("padding"));
|
||||
|
||||
// The external Blazor components are fully functional, not just static HTML
|
||||
var externalComponentButton = specialStyleDiv.FindElement(By.TagName("button"));
|
||||
Assert.Equal("Click me", externalComponentButton.Text);
|
||||
externalComponentButton.Click();
|
||||
Assert.Equal("It works", externalComponentButton.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,4 +16,10 @@
|
|||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Blazor\Microsoft.AspNetCore.Blazor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Local alternative to <PackageReference> to the content package -->
|
||||
<Import Project="..\TestContentPackage\build\TestContentPackage.props" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\TestContentPackage\TestContentPackage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
@addTagHelper *, TestContentPackage
|
||||
@using TestContentPackage
|
||||
|
||||
<h1>Functionality and content from an external package</h1>
|
||||
|
||||
<p>
|
||||
NuGet packages can embed .NET code, which can in turn call Blazor's
|
||||
JS interop features if desired. This can be used to distribute new
|
||||
browser APIs as NuGet packages.
|
||||
</p>
|
||||
|
||||
<p>Click the following button to invoke a JavaScript function.</p>
|
||||
|
||||
<button @onclick(ShowJavaScriptPrompt)>Show JavaScript prompt</button>
|
||||
|
||||
@if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
<p>Result: <strong>@result</strong></p>
|
||||
}
|
||||
|
||||
<hr />
|
||||
|
||||
<p>
|
||||
Additionally, NuGet packages can contain Blazor components, and even
|
||||
static resources such as CSS files and images.
|
||||
</p>
|
||||
|
||||
<ComponentFromPackage />
|
||||
|
||||
@functions
|
||||
{
|
||||
string result;
|
||||
|
||||
void ShowJavaScriptPrompt()
|
||||
{
|
||||
result = MyPrompt.Show("Hello!");
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
<option value="BasicTestApp.HierarchicalImportsTest.Subdir.ComponentUsingImports">Imports statement</option>
|
||||
<option value="BasicTestApp.HttpClientTest.HttpRequestsComponent">HttpClient tester</option>
|
||||
<option value="BasicTestApp.BindCasesComponent">@bind cases</option>
|
||||
<option value="BasicTestApp.ExternalContentPackage">External content package</option>
|
||||
<!--<option value="BasicTestApp.RouterTest.Default">Router</option> Excluded because it requires additional setup to work correctly when loaded manually -->
|
||||
</select>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
<div class="special-style">
|
||||
This component, including the CSS and image required to produce its
|
||||
elegant styling, is in an external NuGet package.
|
||||
<button @onclick(ChangeLabel)>@buttonLabel </button>
|
||||
</div>
|
||||
|
||||
@functions
|
||||
{
|
||||
string buttonLabel = "Click me";
|
||||
|
||||
void ChangeLabel()
|
||||
{
|
||||
buttonLabel = "It works";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using Microsoft.AspNetCore.Blazor.Browser.Interop;
|
||||
|
||||
namespace TestContentPackage
|
||||
{
|
||||
public static class MyPrompt
|
||||
{
|
||||
// Keep in sync with the identifier in the .js file
|
||||
const string ShowPromptIdentifier = "TestContentPackage.showPrompt";
|
||||
|
||||
public static string Show(string message)
|
||||
{
|
||||
return RegisteredFunction.Invoke<string>(
|
||||
ShowPromptIdentifier,
|
||||
message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<OutputType>library</OutputType>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="**" />
|
||||
<Content Include="build\**" PackagePath="build" />
|
||||
<Content Include="content\**" PackagePath="content" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- In real content packages, use a <PackageReference> to Microsoft.AspNetCore.Blazor.Browser instead. -->
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.AspNetCore.Blazor.Browser\Microsoft.AspNetCore.Blazor.Browser.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- In real content packages, use a <PackageReference> to Microsoft.AspNetCore.Blazor.Build instead. -->
|
||||
<Import Project="..\..\..\src\Microsoft.AspNetCore.Blazor.Build\ReferenceFromSource.props" />
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- Update this to match your package ID exactly -->
|
||||
<_PackageId>TestContentPackage</_PackageId>
|
||||
<_ContentDir>$(MSBuildThisFileDirectory)..\content\</_ContentDir>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- All files under "content" will be included with the Blazor app build output -->
|
||||
<BlazorPackageContentFile Include="$(_ContentDir)**" SourcePackage="$(_PackageId)" />
|
||||
|
||||
<!-- We'll generate a <script> tag importing each of the following JavaScript files -->
|
||||
<!-- Change the "Include" pattern if you don't want to include all .js files. -->
|
||||
<BlazorPackageJsRef Include="$(_ContentDir)**\*.js" SourcePackage="$(_PackageId)" />
|
||||
|
||||
<!-- We'll generate a <link> tag importing each of the following CSS files -->
|
||||
<!-- Change the "Include" pattern if you don't want to include all .css files. -->
|
||||
<BlazorPackageCssRef Include="$(_ContentDir)**\*.css" SourcePackage="$(_PackageId)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
Blazor.registerFunction('TestContentPackage.showPrompt', function (message) {
|
||||
return prompt(message, "Type anything here");
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
.special-style {
|
||||
background-image: url('./face.png');
|
||||
padding: 50px;
|
||||
background-repeat: repeat-x;
|
||||
border: 5px dashed red;
|
||||
font-family: "Comic Sans MS";
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
animation: hideous-rainbow 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes hideous-rainbow {
|
||||
0% { color: red; }
|
||||
20% { color: orange; }
|
||||
40% { color: yellow; }
|
||||
60% { color: green; }
|
||||
80% { color: blue; }
|
||||
}
|
||||
Loading…
Reference in New Issue