parent
c18f0780c1
commit
eda5028cf4
|
|
@ -52,6 +52,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
|||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider");
|
||||
writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor");
|
||||
writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor");
|
||||
writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor");
|
||||
writer.Flush();
|
||||
|
||||
stream.Position = 0;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
private static readonly Action<ILogger, string, string, Exception> _viewLookupCacheHit;
|
||||
private static readonly Action<ILogger, string, Exception> _precompiledViewFound;
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _tagHelperComponentInitialized;
|
||||
private static readonly Action<ILogger, string, Exception> _tagHelperComponentProcessed;
|
||||
|
||||
static MvcRazorLoggerExtensions()
|
||||
{
|
||||
_razorFileToCodeCompilationStart = LoggerMessage.Define<string>(
|
||||
|
|
@ -57,6 +60,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
LogLevel.Debug,
|
||||
2,
|
||||
"Compilation of the generated code for the Razor file at '{FilePath}' completed in {ElapsedMilliseconds}ms.");
|
||||
|
||||
_tagHelperComponentInitialized = LoggerMessage.Define<string>(
|
||||
LogLevel.Debug,
|
||||
2,
|
||||
"Tag helper component '{ComponentName}' initialized.");
|
||||
|
||||
_tagHelperComponentProcessed = LoggerMessage.Define<string>(
|
||||
LogLevel.Debug,
|
||||
3,
|
||||
"Tag helper component '{ComponentName}' processed.");
|
||||
}
|
||||
|
||||
public static void RazorFileToCodeCompilationStart(this ILogger logger, string filePath)
|
||||
|
|
@ -95,6 +108,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
|
|||
_generatedCodeToAssemblyCompilationStart(logger, filePath, null);
|
||||
}
|
||||
|
||||
public static void TagHelperComponentInitialized(this ILogger logger, string componentName)
|
||||
{
|
||||
_tagHelperComponentInitialized(logger, componentName, null);
|
||||
}
|
||||
|
||||
public static void TagHelperComponentProcessed(this ILogger logger, string componentName)
|
||||
{
|
||||
_tagHelperComponentProcessed(logger, componentName, null);
|
||||
}
|
||||
|
||||
public static void GeneratedCodeToAssemblyCompilationEnd(this ILogger logger, string filePath, long startTimestamp)
|
||||
{
|
||||
// Don't log if logging wasn't enabled at start of request as time will be wildly wrong.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="TagHelperComponentTagHelper"/> targeting the <body> HTML element.
|
||||
/// </summary>
|
||||
[HtmlTargetElement("body")]
|
||||
public class BodyTagHelper : TagHelperComponentTagHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="BodyTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="components">The list of <see cref="ITagHelperComponent"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public BodyTagHelper(IEnumerable<ITagHelperComponent> components, ILoggerFactory loggerFactory)
|
||||
: base(components, loggerFactory)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="TagHelperComponentTagHelper"/> targeting the <head> HTML element.
|
||||
/// </summary>
|
||||
[HtmlTargetElement("head")]
|
||||
public class HeadTagHelper : TagHelperComponentTagHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="HeadTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="components">The list of <see cref="ITagHelperComponent"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public HeadTagHelper(IEnumerable<ITagHelperComponent> components, ILoggerFactory loggerFactory)
|
||||
: base(components, loggerFactory)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
public abstract class TagHelperComponentTagHelper : TagHelper
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private IEnumerable<ITagHelperComponent> _components;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="TagHelperComponentTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="components">The list of <see cref="ITagHelperComponent"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public TagHelperComponentTagHelper(IEnumerable<ITagHelperComponent> components,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (components == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(components));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
_components = components;
|
||||
_logger = loggerFactory.CreateLogger(GetType());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Init(TagHelperContext context)
|
||||
{
|
||||
_components = _components.OrderBy(p => p.Order);
|
||||
foreach (var component in _components)
|
||||
{
|
||||
component.Init(context);
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.TagHelperComponentInitialized(component.GetType().FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
foreach (var component in _components)
|
||||
{
|
||||
await component.ProcessAsync(context, output);
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.TagHelperComponentProcessed(component.GetType().FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||
{
|
||||
public class TagHelperComponentTagHelperTest : IClassFixture<MvcTestFixture<RazorWebSite.Startup>>
|
||||
{
|
||||
private static readonly Assembly _resourcesAssembly = typeof(TagHelperComponentTagHelperTest).GetTypeInfo().Assembly;
|
||||
|
||||
public TagHelperComponentTagHelperTest(MvcTestFixture<RazorWebSite.Startup> fixture)
|
||||
{
|
||||
Client = fixture.Client;
|
||||
}
|
||||
|
||||
public HttpClient Client { get; }
|
||||
|
||||
[Fact]
|
||||
public async Task InjectsTestHeadTagHelperComponent()
|
||||
{
|
||||
// Arrange
|
||||
var url = "http://localhost/TagHelperComponent/GetHead";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
var outputFile = "compiler/resources/RazorWebSite.TagHelperComponent.Head.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent, ignoreLineEndingDifferences: true);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InjectsTestBodyTagHelperComponent()
|
||||
{
|
||||
// Arrange
|
||||
var url = "http://localhost/TagHelperComponent/GetBody";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
var outputFile = "compiler/resources/RazorWebSite.TagHelperComponent.Body.html";
|
||||
var expectedContent =
|
||||
await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
|
||||
|
||||
// Act
|
||||
var response = await Client.SendAsync(request);
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
#if GENERATE_BASELINES
|
||||
ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
|
||||
#else
|
||||
Assert.Equal(expectedContent, responseContent, ignoreLineEndingDifferences: true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<body inject="true">
|
||||
Hello from Body Tag Helper Component
|
||||
<script>'This was injected!!'</script></body>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<head inject="true">
|
||||
Hello from Head Tag Helper Component
|
||||
<script>'This was injected!!'</script></head>
|
||||
|
|
@ -81,9 +81,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
|
|||
var importContent = GetContent(imports)
|
||||
.Split(new[] { Environment.NewLine }, StringSplitOptions.None)
|
||||
.Where(line => line.StartsWith("@addTagHelper"));
|
||||
var addTagHelper = Assert.Single(importContent);
|
||||
Assert.Equal("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor",
|
||||
addTagHelper);
|
||||
|
||||
Assert.Contains("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor",
|
||||
importContent);
|
||||
Assert.Contains("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor",
|
||||
importContent);
|
||||
Assert.Contains("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor",
|
||||
importContent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -74,6 +74,14 @@ System.Object ModelExpressionProvider = null;
|
|||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
Source Location: (13:0,13 [4] TestFiles/Input/Basic.cshtml)
|
||||
|logo|
|
||||
Generated Location: (2329:85,13 [4] )
|
||||
Generated Location: (2691:93,13 [4] )
|
||||
|logo|
|
||||
|
||||
Source Location: (43:2,5 [21] TestFiles/Input/Basic.cshtml)
|
||||
|Html.Input("SomeKey")|
|
||||
Generated Location: (2413:90,6 [21] )
|
||||
Generated Location: (2775:98,6 [21] )
|
||||
|Html.Input("SomeKey")|
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,14 @@ System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResol
|
|||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
MyApp __typeHelper = null;
|
||||
}
|
||||
))();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
Source Location: (28:1,8 [5] TestFiles/Input/Inject.cshtml)
|
||||
|MyApp|
|
||||
Generated Location: (2174:84,0 [5] )
|
||||
Generated Location: (2536:92,0 [5] )
|
||||
|MyApp|
|
||||
|
||||
Source Location: (34:1,14 [14] TestFiles/Input/Inject.cshtml)
|
||||
|MyPropertyName|
|
||||
Generated Location: (2276:88,14 [14] )
|
||||
Generated Location: (2638:96,14 [14] )
|
||||
|MyPropertyName|
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResol
|
|||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
MyModel __typeHelper = null;
|
||||
}
|
||||
))();
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
Source Location: (7:0,7 [7] TestFiles/Input/InjectWithModel.cshtml)
|
||||
|MyModel|
|
||||
Generated Location: (2091:79,0 [7] )
|
||||
Generated Location: (2453:87,0 [7] )
|
||||
|MyModel|
|
||||
|
||||
Source Location: (24:1,8 [5] TestFiles/Input/InjectWithModel.cshtml)
|
||||
|MyApp|
|
||||
Generated Location: (2181:83,0 [5] )
|
||||
Generated Location: (2543:91,0 [5] )
|
||||
|MyApp|
|
||||
|
||||
Source Location: (30:1,14 [14] TestFiles/Input/InjectWithModel.cshtml)
|
||||
|MyPropertyName|
|
||||
Generated Location: (2283:87,14 [14] )
|
||||
Generated Location: (2645:95,14 [14] )
|
||||
|MyPropertyName|
|
||||
|
||||
Source Location: (54:2,8 [17] TestFiles/Input/InjectWithModel.cshtml)
|
||||
|MyService<TModel>|
|
||||
Generated Location: (2367:91,0 [17] )
|
||||
Generated Location: (2729:99,0 [17] )
|
||||
|MyService<TModel>|
|
||||
|
||||
Source Location: (72:2,26 [4] TestFiles/Input/InjectWithModel.cshtml)
|
||||
|Html|
|
||||
Generated Location: (2481:95,14 [4] )
|
||||
Generated Location: (2843:103,14 [4] )
|
||||
|Html|
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResol
|
|||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
MyModel __typeHelper = null;
|
||||
}
|
||||
))();
|
||||
|
|
|
|||
|
|
@ -1,45 +1,45 @@
|
|||
Source Location: (7:0,7 [7] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|MyModel|
|
||||
Generated Location: (2095:79,0 [7] )
|
||||
Generated Location: (2457:87,0 [7] )
|
||||
|MyModel|
|
||||
|
||||
Source Location: (24:1,8 [5] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|MyApp|
|
||||
Generated Location: (2185:83,0 [5] )
|
||||
Generated Location: (2547:91,0 [5] )
|
||||
|MyApp|
|
||||
|
||||
Source Location: (30:1,14 [14] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|MyPropertyName|
|
||||
Generated Location: (2287:87,14 [14] )
|
||||
Generated Location: (2649:95,14 [14] )
|
||||
|MyPropertyName|
|
||||
|
||||
Source Location: (58:2,8 [17] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|MyService<TModel>|
|
||||
Generated Location: (2371:91,0 [17] )
|
||||
Generated Location: (2733:99,0 [17] )
|
||||
|MyService<TModel>|
|
||||
|
||||
Source Location: (76:2,26 [4] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|Html|
|
||||
Generated Location: (2485:95,14 [4] )
|
||||
Generated Location: (2847:103,14 [4] )
|
||||
|Html|
|
||||
|
||||
Source Location: (93:3,8 [5] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|MyApp|
|
||||
Generated Location: (2559:99,0 [5] )
|
||||
Generated Location: (2921:107,0 [5] )
|
||||
|MyApp|
|
||||
|
||||
Source Location: (99:3,14 [15] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|MyPropertyName2|
|
||||
Generated Location: (2661:103,14 [15] )
|
||||
Generated Location: (3023:111,14 [15] )
|
||||
|MyPropertyName2|
|
||||
|
||||
Source Location: (129:4,8 [17] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|MyService<TModel>|
|
||||
Generated Location: (2746:107,0 [17] )
|
||||
Generated Location: (3108:115,0 [17] )
|
||||
|MyService<TModel>|
|
||||
|
||||
Source Location: (147:4,26 [5] TestFiles/Input/InjectWithSemicolon.cshtml)
|
||||
|Html2|
|
||||
Generated Location: (2860:111,14 [5] )
|
||||
Generated Location: (3222:119,14 [5] )
|
||||
|Html2|
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResol
|
|||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Collections.IEnumerable __typeHelper = null;
|
||||
}
|
||||
))();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Source Location: (7:0,7 [30] TestFiles/Input/Model.cshtml)
|
||||
|System.Collections.IEnumerable|
|
||||
Generated Location: (2104:79,0 [30] )
|
||||
Generated Location: (2466:87,0 [30] )
|
||||
|System.Collections.IEnumerable|
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResol
|
|||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
DateTime __typeHelper = null;
|
||||
}
|
||||
))();
|
||||
|
|
|
|||
|
|
@ -1,40 +1,40 @@
|
|||
Source Location: (7:0,7 [8] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|DateTime|
|
||||
Generated Location: (2101:79,0 [8] )
|
||||
Generated Location: (2463:87,0 [8] )
|
||||
|DateTime|
|
||||
|
||||
Source Location: (33:2,14 [91] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|Microsoft.AspNetCore.Mvc.Razor.InputTestTagHelper, Microsoft.AspNetCore.Mvc.Razor.Host.Test|
|
||||
Generated Location: (2222:83,30 [91] )
|
||||
Generated Location: (2584:91,30 [91] )
|
||||
|Microsoft.AspNetCore.Mvc.Razor.InputTestTagHelper, Microsoft.AspNetCore.Mvc.Razor.Host.Test|
|
||||
|
||||
Source Location: (140:3,14 [102] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|Microsoft.AspNetCore.Mvc.Razor.DictionaryPrefixTestTagHelper, Microsoft.AspNetCore.Mvc.Razor.Host.Test|
|
||||
Generated Location: (2407:87,30 [102] )
|
||||
Generated Location: (2769:95,30 [102] )
|
||||
|Microsoft.AspNetCore.Mvc.Razor.DictionaryPrefixTestTagHelper, Microsoft.AspNetCore.Mvc.Razor.Host.Test|
|
||||
|
||||
Source Location: (263:5,17 [3] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|Now|
|
||||
Generated Location: (3397:100,133 [3] )
|
||||
Generated Location: (3759:108,133 [3] )
|
||||
|Now|
|
||||
|
||||
Source Location: (290:6,18 [5] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|Model|
|
||||
Generated Location: (3764:106,125 [5] )
|
||||
Generated Location: (4126:114,125 [5] )
|
||||
|Model|
|
||||
|
||||
Source Location: (322:8,19 [5] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|Model|
|
||||
Generated Location: (4183:112,153 [5] )
|
||||
Generated Location: (4545:120,153 [5] )
|
||||
|Model|
|
||||
|
||||
Source Location: (357:9,19 [4] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|Hour|
|
||||
Generated Location: (4611:118,161 [4] )
|
||||
Generated Location: (4973:126,161 [4] )
|
||||
|Hour|
|
||||
|
||||
Source Location: (378:9,40 [6] TestFiles/Input/ModelExpressionTagHelper.cshtml)
|
||||
|Minute|
|
||||
Generated Location: (4873:123,163 [6] )
|
||||
Generated Location: (5235:131,163 [6] )
|
||||
|Minute|
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResol
|
|||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
ThisShouldBeGenerated __typeHelper = null;
|
||||
}
|
||||
))();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
Source Location: (7:0,7 [21] TestFiles/Input/MultipleModels.cshtml)
|
||||
|ThisShouldBeGenerated|
|
||||
Generated Location: (2113:79,0 [21] )
|
||||
Generated Location: (2475:87,0 [21] )
|
||||
|ThisShouldBeGenerated|
|
||||
|
||||
Source Location: (37:1,7 [30] TestFiles/Input/MultipleModels.cshtml)
|
||||
|System.Collections.IEnumerable|
|
||||
Generated Location: (2217:83,0 [30] )
|
||||
Generated Location: (2579:91,0 [30] )
|
||||
|System.Collections.IEnumerable|
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResol
|
|||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
System.Object __typeHelper = "Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor";
|
||||
}
|
||||
))();
|
||||
((System.Action)(() => {
|
||||
IHtmlHelper<TModel> __typeHelper = null;
|
||||
}
|
||||
))();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
Source Location: (8:0,8 [19] TestFiles/Input/_ViewImports.cshtml)
|
||||
|IHtmlHelper<TModel>|
|
||||
Generated Location: (2088:79,0 [19] )
|
||||
Generated Location: (2450:87,0 [19] )
|
||||
|IHtmlHelper<TModel>|
|
||||
|
||||
Source Location: (28:0,28 [5] TestFiles/Input/_ViewImports.cshtml)
|
||||
|Model|
|
||||
Generated Location: (2204:83,14 [5] )
|
||||
Generated Location: (2566:91,14 [5] )
|
||||
|Model|
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,292 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Logging.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
||||
{
|
||||
public class TagHelperComponentTagHelperTest
|
||||
{
|
||||
[Fact]
|
||||
public void Init_InvokesComponentsInitInCorrectOrder()
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
"head",
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
|
||||
var incrementer = 0;
|
||||
var testTagHelperComponentTagHelper = new TestTagHelperComponentTagHelper(new []
|
||||
{
|
||||
new CallbackTagHelperComponent(
|
||||
order: 2,
|
||||
initCallback: () =>
|
||||
{
|
||||
Assert.Equal(1, incrementer);
|
||||
incrementer++;
|
||||
},
|
||||
processAsyncCallback: null),
|
||||
new CallbackTagHelperComponent(
|
||||
order: 3,
|
||||
initCallback: () =>
|
||||
{
|
||||
Assert.Equal(2, incrementer);
|
||||
incrementer++;
|
||||
},
|
||||
processAsyncCallback: null),
|
||||
new CallbackTagHelperComponent(
|
||||
order: 1,
|
||||
initCallback: () =>
|
||||
{
|
||||
Assert.Equal(0, incrementer);
|
||||
incrementer++;
|
||||
},
|
||||
processAsyncCallback: null),
|
||||
}, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
testTagHelperComponentTagHelper.Init(tagHelperContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3, incrementer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void ProcessAsync_InvokesComponentsProcessAsyncInCorrectOrder()
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
"head",
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
|
||||
var output = new TagHelperOutput(
|
||||
"head",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
||||
new DefaultTagHelperContent()));
|
||||
|
||||
var incrementer = 0;
|
||||
var testTagHelperComponentTagHelper = new TestTagHelperComponentTagHelper(new []
|
||||
{
|
||||
new CallbackTagHelperComponent(
|
||||
order: 2,
|
||||
initCallback: () => { },
|
||||
processAsyncCallback: () =>
|
||||
{
|
||||
Assert.Equal(1, incrementer);
|
||||
incrementer++;
|
||||
}),
|
||||
new CallbackTagHelperComponent(
|
||||
order: 3,
|
||||
initCallback: () => { },
|
||||
processAsyncCallback: () =>
|
||||
{
|
||||
Assert.Equal(2, incrementer);
|
||||
incrementer++;
|
||||
}),
|
||||
new CallbackTagHelperComponent(
|
||||
order: 1,
|
||||
initCallback: () => { },
|
||||
processAsyncCallback: () =>
|
||||
{
|
||||
Assert.Equal(0, incrementer);
|
||||
incrementer++;
|
||||
}),
|
||||
}, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
testTagHelperComponentTagHelper.Init(tagHelperContext);
|
||||
await testTagHelperComponentTagHelper.ProcessAsync(tagHelperContext, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3, incrementer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Init_InvokesTagHelperComponentInit()
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
"head",
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
|
||||
var output = new TagHelperOutput(
|
||||
"head",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
||||
new DefaultTagHelperContent()));
|
||||
|
||||
var testTagHelperComponentTagHelper = new TestTagHelperComponentTagHelper(new []
|
||||
{
|
||||
new TestTagHelperComponent()
|
||||
}, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
testTagHelperComponentTagHelper.Init(tagHelperContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Value", tagHelperContext.Items["Key"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_InvokesTagHelperComponentProcessAsync()
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
"head",
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
|
||||
var output = new TagHelperOutput(
|
||||
"head",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
||||
new DefaultTagHelperContent()));
|
||||
|
||||
var testTagHelperComponentTagHelper = new TestTagHelperComponentTagHelper(new []
|
||||
{
|
||||
new TestTagHelperComponent()
|
||||
}, NullLoggerFactory.Instance);
|
||||
|
||||
// Act
|
||||
await testTagHelperComponentTagHelper.ProcessAsync(tagHelperContext, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Processed", output.PostContent.GetContent());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Init_LogsTagHelperComponentInitialized()
|
||||
{
|
||||
// Arrange
|
||||
var sink = new TestSink();
|
||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
"head",
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
|
||||
var output = new TagHelperOutput(
|
||||
"head",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
||||
new DefaultTagHelperContent()));
|
||||
|
||||
var testTagHelperComponentTagHelper = new TestTagHelperComponentTagHelper(new []
|
||||
{
|
||||
new TestTagHelperComponent()
|
||||
}, loggerFactory);
|
||||
|
||||
// Act
|
||||
testTagHelperComponentTagHelper.Init(tagHelperContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal($"Tag helper component '{typeof(TestTagHelperComponent)}' initialized.", sink.Writes[0].State.ToString(), StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_LogsTagHelperComponentProcessed()
|
||||
{
|
||||
// Arrange
|
||||
var sink = new TestSink();
|
||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
var tagHelperContext = new TagHelperContext(
|
||||
"head",
|
||||
allAttributes: new TagHelperAttributeList(
|
||||
Enumerable.Empty<TagHelperAttribute>()),
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
|
||||
var output = new TagHelperOutput(
|
||||
"head",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(
|
||||
new DefaultTagHelperContent()));
|
||||
|
||||
var testTagHelperComponentTagHelper = new TestTagHelperComponentTagHelper(new []
|
||||
{
|
||||
new TestTagHelperComponent()
|
||||
}, loggerFactory);
|
||||
|
||||
// Act
|
||||
await testTagHelperComponentTagHelper.ProcessAsync(tagHelperContext, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal($"Tag helper component '{typeof(TestTagHelperComponent)}' processed.", sink.Writes[0].State.ToString(), StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
private class TestTagHelperComponentTagHelper : TagHelperComponentTagHelper
|
||||
{
|
||||
public TestTagHelperComponentTagHelper(
|
||||
IEnumerable<ITagHelperComponent> components,
|
||||
ILoggerFactory loggerFactory)
|
||||
: base(components, loggerFactory)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class CallbackTagHelperComponent : ITagHelperComponent
|
||||
{
|
||||
private readonly Action _initCallback;
|
||||
private readonly Action _processAsyncCallback;
|
||||
private readonly int _order;
|
||||
|
||||
public CallbackTagHelperComponent(int order, Action initCallback, Action processAsyncCallback)
|
||||
{
|
||||
_initCallback = initCallback;
|
||||
_processAsyncCallback = processAsyncCallback;
|
||||
_order = order;
|
||||
}
|
||||
|
||||
public int Order => _order;
|
||||
|
||||
public void Init(TagHelperContext context)
|
||||
{
|
||||
_initCallback();
|
||||
}
|
||||
|
||||
public Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
_processAsyncCallback();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestTagHelperComponent : ITagHelperComponent
|
||||
{
|
||||
public int Order => 1;
|
||||
|
||||
public void Init(TagHelperContext context)
|
||||
{
|
||||
context.Items["Key"] = "Value";
|
||||
}
|
||||
|
||||
public Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
output.PostContent.AppendHtml("Processed");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace RazorWebSite
|
||||
{
|
||||
public class TagHelperComponentController : Controller
|
||||
{
|
||||
// GET: /<controller>/
|
||||
public IActionResult GetHead()
|
||||
{
|
||||
return View("Head");
|
||||
}
|
||||
|
||||
public IActionResult GetBody()
|
||||
{
|
||||
return View("Body");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace RazorWebSite
|
||||
{
|
||||
public class TestBodyTagHelperComponent : TagHelperComponent
|
||||
{
|
||||
public override int Order => 1;
|
||||
|
||||
public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
if (string.Equals(context.TagName, "body", StringComparison.Ordinal) && output.Attributes.ContainsName("inject"))
|
||||
{
|
||||
output.PostContent.AppendHtml("<script>'This was injected!!'</script>");
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace RazorWebSite
|
||||
{
|
||||
public class TestHeadTagHelperComponent : TagHelperComponent
|
||||
{
|
||||
public override int Order => 1;
|
||||
|
||||
public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
if (string.Equals(context.TagName, "head", StringComparison.Ordinal) && output.Attributes.ContainsName("inject"))
|
||||
{
|
||||
output.PostContent.AppendHtml("<script>'This was injected!!'</script>");
|
||||
}
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Localization;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
|
||||
|
|
@ -20,6 +21,9 @@ namespace RazorWebSite
|
|||
{
|
||||
var updateableFileProvider = new UpdateableFileProvider();
|
||||
services.AddSingleton(updateableFileProvider);
|
||||
services.AddSingleton<ITagHelperComponent, TestHeadTagHelperComponent>();
|
||||
services.AddSingleton<ITagHelperComponent, TestBodyTagHelperComponent>();
|
||||
|
||||
services
|
||||
.AddMvc()
|
||||
.AddRazorOptions(options =>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
<body inject="true">
|
||||
Hello from Body Tag Helper Component
|
||||
</body>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<head inject="true">
|
||||
Hello from Head Tag Helper Component
|
||||
</head>
|
||||
Loading…
Reference in New Issue