Fix1571 - Supporting self-closing tags for taghelpers

This commit is contained in:
Youngjune Hong 2015-02-10 09:30:47 -08:00 committed by ianhong
parent ffb388ab62
commit 23e6264715
27 changed files with 498 additions and 204 deletions

View File

@ -22,8 +22,9 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <summary>
/// Internal for testing purposes only.
/// </summary>
internal TagHelperExecutionContext(string tagName)
internal TagHelperExecutionContext(string tagName, bool selfClosing)
: this(tagName,
selfClosing,
uniqueId: string.Empty,
executeChildContentAsync: async () => await Task.FromResult(result: true),
startWritingScope: () => { },
@ -35,11 +36,15 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// Instantiates a new <see cref="TagHelperExecutionContext"/>.
/// </summary>
/// <param name="tagName">The HTML tag name in the Razor source.</param>
/// <param name="selfClosing">
/// <see cref="bool"/> indicating whether or not the tag in the Razor source was self-closing.
/// </param>
/// <param name="uniqueId">An identifier unique to the HTML element this context is for.</param>
/// <param name="executeChildContentAsync">A delegate used to execute the child content asynchronously.</param>
/// <param name="startWritingScope">A delegate used to start a writing scope in a Razor page.</param>
/// <param name="endWritingScope">A delegate used to end a writing scope in a Razor page.</param>
public TagHelperExecutionContext([NotNull] string tagName,
bool selfClosing,
[NotNull] string uniqueId,
[NotNull] Func<Task> executeChildContentAsync,
[NotNull] Action startWritingScope,
@ -50,12 +55,18 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
_startWritingScope = startWritingScope;
_endWritingScope = endWritingScope;
SelfClosing = selfClosing;
AllAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
HTMLAttributes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
TagName = tagName;
UniqueId = uniqueId;
}
/// <summary>
/// Gets a value indicating whether or not the tag in the Razor source was self-closing.
/// </summary>
public bool SelfClosing { get; }
/// <summary>
/// Indicates if <see cref="GetChildContentAsync"/> has been called.
/// </summary>

View File

@ -16,6 +16,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
private string _content;
private bool _contentSet;
private bool _isTagNameNullOrWhitespace;
private string _tagName;
// Internal for testing
internal TagHelperOutput(string tagName)
@ -44,7 +46,18 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <remarks>
/// A whitespace or <c>null</c> value results in no start or end tag being rendered.
/// </remarks>
public string TagName { get; set; }
public string TagName
{
get
{
return _tagName;
}
set
{
_tagName = value;
_isTagNameNullOrWhitespace = string.IsNullOrWhiteSpace(_tagName);
}
}
/// <summary>
/// The HTML element's pre content.
@ -88,7 +101,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
/// <summary>
/// Indicates whether or not the tag is self closing.
/// Indicates whether or not the tag is self-closing.
/// </summary>
public bool SelfClosing { get; set; }
@ -100,12 +113,12 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <summary>
/// Generates the <see cref="TagHelperOutput"/>'s start tag.
/// </summary>
/// <returns><c>string.Empty</c> if <see cref="TagName"/> is <c>string.Empty</c> or whitespace. Otherwise, the
/// <returns><c>string.Empty</c> if <see cref="TagName"/> is <c>null</c> or whitespace. Otherwise, the
/// <see cref="string"/> representation of the <see cref="TagHelperOutput"/>'s start tag.</returns>
public string GenerateStartTag()
{
// Only render a start tag if the tag name is not whitespace
if (string.IsNullOrWhiteSpace(TagName))
if (_isTagNameNullOrWhitespace)
{
return string.Empty;
}
@ -138,12 +151,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <summary>
/// Generates the <see cref="TagHelperOutput"/>'s <see cref="PreContent"/>.
/// </summary>
/// <returns><c>string.Empty</c> if <see cref="SelfClosing"/> is <c>true</c>. <see cref="PreContent"/>
/// otherwise.
/// </returns>
/// <returns><c>string.Empty</c> if <see cref="TagName"/> is not <c>null</c> or whitespace
/// and <see cref="SelfClosing"/> is <c>true</c>. Otherwise, <see cref="PreContent"/>.</returns>
public string GeneratePreContent()
{
if (SelfClosing)
if (!_isTagNameNullOrWhitespace && SelfClosing)
{
return string.Empty;
}
@ -154,11 +166,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <summary>
/// Generates the <see cref="TagHelperOutput"/>'s body.
/// </summary>
/// <returns><c>string.Empty</c> if <see cref="SelfClosing"/> is <c>true</c>. <see cref="Content"/> otherwise.
/// </returns>
/// <returns><c>string.Empty</c> if <see cref="TagName"/> is not <c>null</c> or whitespace
/// and <see cref="SelfClosing"/> is <c>true</c>. Otherwise, <see cref="Content"/>.</returns>
public string GenerateContent()
{
if (SelfClosing)
if (!_isTagNameNullOrWhitespace && SelfClosing)
{
return string.Empty;
}
@ -169,12 +181,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <summary>
/// Generates the <see cref="TagHelperOutput"/>'s <see cref="PostContent"/>.
/// </summary>
/// <returns><c>string.Empty</c> if <see cref="SelfClosing"/> is <c>true</c>. <see cref="PostContent"/>
/// otherwise.
/// </returns>
/// <returns><c>string.Empty</c> if <see cref="TagName"/> is not <c>null</c> or whitespace
/// and <see cref="SelfClosing"/> is <c>true</c>. Otherwise, <see cref="PostContent"/>.</returns>
public string GeneratePostContent()
{
if (SelfClosing)
if (!_isTagNameNullOrWhitespace && SelfClosing)
{
return string.Empty;
}
@ -185,11 +196,11 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <summary>
/// Generates the <see cref="TagHelperOutput"/>'s end tag.
/// </summary>
/// <returns><c>string.Empty</c> if <see cref="TagName"/> is <c>string.Empty</c> or whitespace. Otherwise, the
/// <returns><c>string.Empty</c> if <see cref="TagName"/> is <c>null</c> or whitespace. Otherwise, the
/// <see cref="string"/> representation of the <see cref="TagHelperOutput"/>'s end tag.</returns>
public string GenerateEndTag()
{
if (SelfClosing || string.IsNullOrWhiteSpace(TagName))
if (SelfClosing || _isTagNameNullOrWhitespace)
{
return string.Empty;
}

View File

@ -24,7 +24,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
executionContext.AllAttributes,
executionContext.UniqueId,
executionContext.GetChildContentAsync);
var tagHelperOutput = new TagHelperOutput(executionContext.TagName, executionContext.HTMLAttributes);
var tagHelperOutput = new TagHelperOutput(executionContext.TagName, executionContext.HTMLAttributes)
{
SelfClosing = executionContext.SelfClosing,
};
var orderedTagHelpers = executionContext.TagHelpers.OrderBy(tagHelper => tagHelper.Order);
foreach (var tagHelper in orderedTagHelpers)

View File

@ -27,18 +27,23 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// Starts a <see cref="TagHelperExecutionContext"/> scope.
/// </summary>
/// <param name="tagName">The HTML tag name that the scope is associated with.</param>
/// <param name="selfClosing">
/// <see cref="bool"/> indicating whether or not the tag of this scope is self-closing.
/// </param>
/// <param name="uniqueId">An identifier unique to the HTML element this scope is for.</param>
/// <param name="executeChildContentAsync">A delegate used to execute the child content asynchronously.</param>
/// <param name="startWritingScope">A delegate used to start a writing scope in a Razor page.</param>
/// <param name="endWritingScope">A delegate used to end a writing scope in a Razor page.</param>
/// <returns>A <see cref="TagHelperExecutionContext"/> to use.</returns>
public TagHelperExecutionContext Begin([NotNull] string tagName,
bool selfClosing,
[NotNull] string uniqueId,
[NotNull] Func<Task> executeChildContentAsync,
[NotNull] Action startWritingScope,
[NotNull] Func<TextWriter> endWritingScope)
{
var executionContext = new TagHelperExecutionContext(tagName,
selfClosing,
uniqueId,
executeChildContentAsync,
startWritingScope,

View File

@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
{
var tagHelperDescriptors = chunk.Descriptors;
RenderBeginTagHelperScope(chunk.TagName, chunk.Children);
RenderBeginTagHelperScope(chunk.TagName, chunk.SelfClosing, chunk.Children);
RenderTagHelpersCreation(chunk);
@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
return "__" + descriptor.TypeName.Replace('.', '_');
}
private void RenderBeginTagHelperScope(string tagName, IList<Chunk> children)
private void RenderBeginTagHelperScope(string tagName, bool selfClosing, IList<Chunk> children)
{
// Scopes/execution contexts are a runtime feature.
if (_designTimeMode)
@ -108,6 +108,8 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
// Assign a unique ID for this instance of the source HTML tag. This must be unique
// per call site, e.g. if the tag is on the view twice, there should be two IDs.
_writer.WriteStringLiteral(tagName)
.WriteParameterSeparator()
.WriteBooleanLiteral(selfClosing)
.WriteParameterSeparator()
.WriteStringLiteral(GenerateUniqueId())
.WriteParameterSeparator();
@ -466,8 +468,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
_writer.Write(ExecutionContextVariableName)
.Write(".")
.Write(_tagHelperContext.ExecutionContextOutputPropertyName)
.Write(" = ")
.WriteStartAssignment(_tagHelperContext.ExecutionContextOutputPropertyName)
.WriteStartInstanceMethodInvocation(RunnerVariableName,
_tagHelperContext.RunnerRunAsyncMethodName);

View File

@ -11,6 +11,29 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
/// </summary>
public class TagHelperChunk : ChunkBlock
{
/// <summary>
/// Instantiates a new <see cref="TagHelperChunk"/>.
/// </summary>
/// <param name="tagName">The tag name associated with the tag helpers HTML element.</param>
/// <param name="selfClosing">
/// <see cref="bool"/> indicating whether or not the tag of the tag helpers HTML element is self-closing.
/// </param>
/// <param name="attributes">The attributes associated with the tag helpers HTML element.</param>
/// <param name="descriptors">
/// The <see cref="TagHelperDescriptor"/>s associated with this tag helpers HTML element.
/// </param>
public TagHelperChunk(
string tagName,
bool selfClosing,
IDictionary<string, Chunk> attributes,
IEnumerable<TagHelperDescriptor> descriptors)
{
TagName = tagName;
SelfClosing = selfClosing;
Attributes = attributes;
Descriptors = descriptors;
}
/// <summary>
/// The HTML attributes.
/// </summary>
@ -29,5 +52,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
/// The HTML tag name.
/// </summary>
public string TagName { get; set; }
/// <summary>
/// Gets a value indicating whether or not the tag of the tag helpers HTML element is self-closing.
/// </summary>
public bool SelfClosing { get; }
}
}

View File

@ -76,12 +76,11 @@ namespace Microsoft.AspNet.Razor.Generator
}
context.CodeTreeBuilder.StartChunkBlock(
new TagHelperChunk
{
TagName = tagHelperBlock.TagName,
Attributes = attributes,
Descriptors = _tagHelperDescriptors
},
new TagHelperChunk(
tagHelperBlock.TagName,
tagHelperBlock.SelfClosing,
attributes,
_tagHelperDescriptors),
target,
topLevel: false);
}

View File

@ -31,6 +31,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
Descriptors = source.Descriptors;
Attributes = new Dictionary<string, SyntaxTreeNode>(source.Attributes);
_start = source.Start;
SelfClosing = source.SelfClosing;
source.Reset();
@ -40,6 +41,11 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
}
}
/// <summary>
/// Indicates whether or not the tag is self closing.
/// </summary>
public bool SelfClosing { get; }
/// <summary>
/// <see cref="TagHelperDescriptor"/>s for the HTML element.
/// </summary>

View File

@ -33,29 +33,36 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
/// and <see cref="BlockBuilder.Type"/> from the <paramref name="startTag"/>.
/// </summary>
/// <param name="tagName">An HTML tag name.</param>
/// <param name="selfClosing">
/// <see cref="bool"/> indicating whether or not the tag in the Razor source was self-closing.
/// </param>
/// <param name="start">Starting location of the <see cref="TagHelperBlock"/>.</param>
/// <param name="attributes">Attributes of the <see cref="TagHelperBlock"/>.</param>
/// <param name="descriptors">The <see cref="TagHelperDescriptor"/>s associated with the current HTML
/// tag.</param>
public TagHelperBlockBuilder(string tagName,
bool selfClosing,
SourceLocation start,
IDictionary<string, SyntaxTreeNode> attributes,
IEnumerable<TagHelperDescriptor> descriptors)
{
TagName = tagName;
SelfClosing = selfClosing;
Start = start;
Descriptors = descriptors;
Attributes = new Dictionary<string, SyntaxTreeNode>(attributes);
Type = BlockType.Tag;
CodeGenerator = new TagHelperCodeGenerator(descriptors);
Attributes = new Dictionary<string, SyntaxTreeNode>(attributes);
}
// Internal for testing
internal TagHelperBlockBuilder(string tagName,
bool selfClosing,
IDictionary<string, SyntaxTreeNode> attributes,
IEnumerable<SyntaxTreeNode> children)
{
TagName = tagName;
SelfClosing = selfClosing;
Attributes = attributes;
Type = BlockType.Tag;
CodeGenerator = new TagHelperCodeGenerator(tagHelperDescriptors: null);
@ -67,6 +74,11 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
}
}
/// <summary>
/// Gets a value indicating whether or not the tag in the Razor source was self-closing.
/// </summary>
public bool SelfClosing { get; }
/// <summary>
/// <see cref="TagHelperDescriptor"/>s for the HTML element.
/// </summary>

View File

@ -26,8 +26,9 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
// There will always be at least one child for the '<'.
var start = tag.Children.First().Start;
var attributes = GetTagAttributes(tagName, validStructure, tag, descriptors, errorSink);
var selfClosing = IsSelfClosing(tag);
return new TagHelperBlockBuilder(tagName, start, attributes, descriptors);
return new TagHelperBlockBuilder(tagName, selfClosing, start, attributes, descriptors);
}
private static IDictionary<string, SyntaxTreeNode> GetTagAttributes(
@ -94,6 +95,13 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
return attributes;
}
private static bool IsSelfClosing(Block beginTagBlock)
{
var childSpan = beginTagBlock.FindLastDescendentSpan();
return childSpan?.Content.EndsWith("/>") ?? false;
}
// This method handles cases when the attribute is a simple span attribute such as
// class="something moresomething". This does not handle complex attributes such as
// class="@myclass". Therefore the span.Content is equivalent to the entire attribute.

View File

@ -132,7 +132,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
// If it's a self closing block then we don't have to worry about nested children
// within the tag... complete it.
if (IsSelfClosing(tagBlock))
if (builder.SelfClosing)
{
BuildCurrentlyTrackedTagHelperBlock();
}
@ -334,15 +334,6 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
return textSymbol.Type == HtmlSymbolType.WhiteSpace ? null : textSymbol.Content;
}
private static bool IsSelfClosing(Block beginTagBlock)
{
EnsureTagBlock(beginTagBlock);
var childSpan = beginTagBlock.Children.Last() as Span;
return childSpan?.Content.EndsWith("/>") ?? false;
}
private static bool IsEndTag(Block tagBlock)
{
EnsureTagBlock(tagBlock);

View File

@ -12,6 +12,19 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
public class TagHelperExecutionContextTest
{
[Theory]
[InlineData(true)]
[InlineData(false)]
public void SelfClosing_ReturnsTrueOrFalseAsExpected(bool selfClosing)
{
// Arrange & Act
var executionContext = new TagHelperExecutionContext("p", selfClosing);
// Assert
Assert.Equal(selfClosing, executionContext.SelfClosing);
}
[Fact]
public async Task GetChildContentAsync_CachesValue()
{
@ -20,6 +33,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var expectedContent = string.Empty;
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: () =>
{
@ -52,6 +66,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var childContentExecutionCount = 0;
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: () =>
{
@ -88,7 +103,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void HtmlAttributes_IgnoresCase(string originalName, string updatedName)
{
// Arrange
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
executionContext.HTMLAttributes[originalName] = "hello";
// Act
@ -103,7 +118,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void AllAttributes_IgnoresCase(string originalName, string updatedName)
{
// Arrange
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
executionContext.AllAttributes[originalName] = false;
// Act
@ -118,7 +133,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void AddHtmlAttribute_MaintainsHTMLAttributes()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var expectedAttributes = new Dictionary<string, string>
{
{ "class", "btn" },
@ -137,7 +152,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void TagHelperExecutionContext_MaintainsAllAttributes()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var expectedAttributes = new Dictionary<string, object>
{
{ "class", "btn" },
@ -158,7 +173,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void Add_MaintainsTagHelpers()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var tagHelper = new PTagHelper();
// Act
@ -173,7 +188,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void Add_MaintainsMultipleTagHelpers()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var tagHelper1 = new PTagHelper();
var tagHelper2 = new PTagHelper();

View File

@ -191,7 +191,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Fact]
public void GeneratePreContent_ReturnsNothingIfSelfClosing()
public void GeneratePreContent_ReturnsNothingIfSelfClosingWhenTagNameIsNotNullOrWhitespace()
{
// Arrange
var tagHelperOutput = new TagHelperOutput("p")
@ -207,6 +207,29 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
Assert.Empty(output);
}
[Theory]
[InlineData(null, true)]
[InlineData("\t", true )]
[InlineData(null, false)]
[InlineData("\t", false)]
public void GeneratePreContent_ReturnsPreContentIfTagNameIsNullOrWhitespace(string tagName, bool selfClosing)
{
// Arrange
var expectedContent = "Hello World";
var tagHelperOutput = new TagHelperOutput(tagName)
{
SelfClosing = selfClosing,
PreContent = expectedContent
};
// Act
var output = tagHelperOutput.GeneratePreContent();
// Assert
Assert.Same(expectedContent, output);
}
[Fact]
public void GenerateContent_ReturnsContent()
{
@ -225,7 +248,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
[Fact]
public void GenerateContent_ReturnsNothingIfSelfClosing()
public void GenerateContent_ReturnsNothingIfSelfClosingWhenTagNameIsNotNullOrWhitespace()
{
// Arrange
var tagHelperOutput = new TagHelperOutput("p")
@ -241,6 +264,29 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
Assert.Empty(output);
}
[Theory]
[InlineData(null, true)]
[InlineData("\t", true )]
[InlineData(null, false)]
[InlineData("\t", false)]
public void GenerateContent_ReturnsContentIfTagNameIsNullOrWhitespace(string tagName, bool selfClosing)
{
// Arrange
var expectedContent = "Hello World";
var tagHelperOutput = new TagHelperOutput(tagName)
{
SelfClosing = selfClosing,
Content = expectedContent
};
// Act
var output = tagHelperOutput.GenerateContent();
// Assert
Assert.Same(expectedContent, output);
}
[Fact]
public void GeneratePostContent_ReturnsPostContent()
{
@ -258,7 +304,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Fact]
public void GeneratePostContent_ReturnsNothingIfSelfClosing()
public void GeneratePostContent_ReturnsNothingIfSelfClosingWhenTagNameIsNotNullOrWhitespace()
{
// Arrange
var tagHelperOutput = new TagHelperOutput("p")
@ -287,6 +333,29 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
Assert.Equal("</p>", output);
}
[Theory]
[InlineData(null, true)]
[InlineData("\t", true )]
[InlineData(null, false)]
[InlineData("\t", false)]
public void GeneratePostContent_ReturnsPostContentIfTagNameIsNullOrWhitespace(string tagName, bool selfClosing)
{
// Arrange
var expectedContent = "Hello World";
var tagHelperOutput = new TagHelperOutput(tagName)
{
SelfClosing = selfClosing,
PostContent = expectedContent
};
// Act
var output = tagHelperOutput.GeneratePostContent();
// Assert
Assert.Equal(expectedContent, output);
}
[Fact]
public void GenerateEndTag_ReturnsNothingIfSelfClosing()
{

View File

@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var processOrder = new List<int>();
foreach (var order in tagHelperOrders)
@ -81,12 +81,32 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
Assert.Equal(expectedTagHelperOrders, processOrder);
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task RunAsync_SetTagHelperOutputSelfClosing(bool selfClosing)
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p", selfClosing);
var tagHelper = new TagHelperContextTouchingTagHelper();
executionContext.Add(tagHelper);
executionContext.AddTagHelperAttribute("foo", true);
// Act
var output = await runner.RunAsync(executionContext);
// Assert
Assert.Equal(selfClosing, output.SelfClosing);
}
[Fact]
public async Task RunAsync_ProcessesAllTagHelpers()
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executableTagHelper1 = new ExecutableTagHelper();
var executableTagHelper2 = new ExecutableTagHelper();
@ -105,7 +125,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executableTagHelper = new ExecutableTagHelper();
// Act
@ -125,7 +145,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p");
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var tagHelper = new TagHelperContextTouchingTagHelper();
// Act

View File

@ -23,11 +23,13 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers
var scopeManager = new TagHelperScopeManager();
// Act
var executionContext = scopeManager.Begin("p",
string.Empty,
DefaultExecuteChildContentAsync,
DefaultStartWritingScope,
DefaultEndWritingScope);
var executionContext = scopeManager.Begin(
"p",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
// Assert
Assert.Equal("p", executionContext.TagName);
@ -40,38 +42,70 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers
var scopeManager = new TagHelperScopeManager();
// Act
var executionContext = scopeManager.Begin("p",
string.Empty,
DefaultExecuteChildContentAsync,
DefaultStartWritingScope,
DefaultEndWritingScope);
executionContext = scopeManager.Begin("div",
string.Empty,
DefaultExecuteChildContentAsync,
DefaultStartWritingScope,
DefaultEndWritingScope);
var executionContext = scopeManager.Begin(
"p",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
executionContext = scopeManager.Begin(
"div",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
// Assert
Assert.Equal("div", executionContext.TagName);
}
[Fact]
[Theory]
[InlineData("true")]
[InlineData("false")]
public void Begin_SetExecutionContextSelfClosing(bool selfClosing)
{
// Arrange
var scopeManager = new TagHelperScopeManager();
// Act
var executionContext = scopeManager.Begin(
"p",
selfClosing: selfClosing,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
// Assert
Assert.Equal(selfClosing, executionContext.SelfClosing);
}
[Fact]
public void End_ReturnsParentExecutionContext()
{
// Arrange
var scopeManager = new TagHelperScopeManager();
// Act
var executionContext = scopeManager.Begin("p",
string.Empty,
DefaultExecuteChildContentAsync,
DefaultStartWritingScope,
DefaultEndWritingScope);
executionContext = scopeManager.Begin("div",
string.Empty,
DefaultExecuteChildContentAsync,
DefaultStartWritingScope,
DefaultEndWritingScope);
var executionContext = scopeManager.Begin(
"p",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
executionContext = scopeManager.Begin(
"div",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
executionContext = scopeManager.End();
// Assert
@ -85,16 +119,22 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers
var scopeManager = new TagHelperScopeManager();
// Act
var executionContext = scopeManager.Begin("p",
string.Empty,
DefaultExecuteChildContentAsync,
DefaultStartWritingScope,
DefaultEndWritingScope);
executionContext = scopeManager.Begin("div",
string.Empty,
DefaultExecuteChildContentAsync,
DefaultStartWritingScope,
DefaultEndWritingScope);
var executionContext = scopeManager.Begin(
"p",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
executionContext = scopeManager.Begin(
"div",
selfClosing: false,
uniqueId: string.Empty,
executeChildContentAsync: DefaultExecuteChildContentAsync,
startWritingScope: DefaultStartWritingScope,
endWritingScope: DefaultEndWritingScope);
executionContext = scopeManager.End();
executionContext = scopeManager.End();

View File

@ -178,26 +178,54 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public class MarkupTagHelperBlock : TagHelperBlock
{
public MarkupTagHelperBlock(string tagName)
: this(tagName, new Dictionary<string, SyntaxTreeNode>())
: this(tagName, selfClosing: false, attributes: new Dictionary<string, SyntaxTreeNode>())
{
}
public MarkupTagHelperBlock(string tagName, bool selfClosing)
: this(tagName, selfClosing, new Dictionary<string, SyntaxTreeNode>())
{
}
public MarkupTagHelperBlock(string tagName,
IDictionary<string, SyntaxTreeNode> attributes)
: this(tagName, attributes, new SyntaxTreeNode[0])
: this(tagName, selfClosing: false, attributes: attributes, children: new SyntaxTreeNode[0])
{
}
public MarkupTagHelperBlock(string tagName,
params SyntaxTreeNode[] children)
: this(tagName, new Dictionary<string, SyntaxTreeNode>(), children)
bool selfClosing,
IDictionary<string, SyntaxTreeNode> attributes)
: this(tagName, selfClosing, attributes, new SyntaxTreeNode[0])
{
}
public MarkupTagHelperBlock(string tagName, params SyntaxTreeNode[] children)
: this(
tagName,
selfClosing: false,
attributes: new Dictionary<string, SyntaxTreeNode>(),
children: children)
{
}
public MarkupTagHelperBlock(string tagName, bool selfClosing, params SyntaxTreeNode[] children)
: this(tagName, selfClosing, new Dictionary<string, SyntaxTreeNode>(), children)
{
}
public MarkupTagHelperBlock(string tagName,
IDictionary<string, SyntaxTreeNode> attributes,
params SyntaxTreeNode[] children)
: base(new TagHelperBlockBuilder(tagName, attributes, children))
: base(new TagHelperBlockBuilder(tagName, selfClosing: false, attributes: attributes, children: children))
{
}
public MarkupTagHelperBlock(string tagName,
bool selfClosing,
IDictionary<string, SyntaxTreeNode> attributes,
params SyntaxTreeNode[] children)
: base(new TagHelperBlockBuilder(tagName, selfClosing, attributes, children))
{
}
}

View File

@ -398,6 +398,23 @@ namespace Microsoft.AspNet.Razor.Test.Framework
}
else
{
if (!string.Equals(expected.TagName, actual.TagName, StringComparison.Ordinal))
{
collector.AddError(
"{0} - FAILED :: TagName mismatch for TagHelperBlock :: ACTUAL: {1}",
expected.TagName,
actual.TagName);
}
if (expected.SelfClosing != actual.SelfClosing)
{
collector.AddError(
"{0} - FAILED :: SelfClosing for TagHelperBlock {1} :: ACTUAL: {2}",
expected.SelfClosing,
actual.TagName,
actual.SelfClosing);
}
var expectedAttributes = expected.Attributes.GetEnumerator();
var actualAttributes = actual.Attributes.GetEnumerator();

View File

@ -131,12 +131,13 @@ namespace Microsoft.AspNet.Razor.Test.Generator
private static TagHelperChunk CreateTagHelperChunk(string tagName, IEnumerable<TagHelperDescriptor> tagHelperDescriptors)
{
return new TagHelperChunk
return new TagHelperChunk(
tagName,
selfClosing: false,
attributes: new Dictionary<string, Chunk>(),
descriptors: tagHelperDescriptors)
{
TagName = tagName,
Descriptors = tagHelperDescriptors,
Children = new List<Chunk>(),
Attributes = new Dictionary<string, Chunk>()
};
}

View File

@ -37,7 +37,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", new MarkupBlock() }
})),
@ -53,7 +54,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", factory.CodeMarkup(" true") }
})),
@ -64,7 +66,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", factory.CodeMarkup(" ") }
})),
@ -80,7 +83,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", new MarkupBlock() }
})),
@ -99,7 +103,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", factory.CodeMarkup(" ") }
})),
@ -118,7 +123,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", factory.CodeMarkup(string.Empty).With(SpanCodeGenerator.Null) }
})),
@ -134,7 +140,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", factory.CodeMarkup(string.Empty).With(SpanCodeGenerator.Null) },
{ "name", new MarkupBlock() }
@ -151,7 +158,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", factory.CodeMarkup(string.Empty).With(SpanCodeGenerator.Null) },
{ "name", factory.Markup(" ") }
@ -168,7 +176,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "bound", factory.CodeMarkup(string.Empty).With(SpanCodeGenerator.Null) },
{ "name", factory.Markup(string.Empty).With(SpanCodeGenerator.Null) }
@ -185,7 +194,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "BouND", new MarkupBlock() }
})),
@ -201,7 +211,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "BOUND", new MarkupBlock() }
})),
@ -237,7 +248,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{
"bound",
@ -259,7 +271,8 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{
"bound",
@ -1990,23 +2003,25 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
"<p class1='' class2= class3=\"\" />",
new MarkupBlock(
new MarkupTagHelperBlock("p",
new Dictionary<string, SyntaxTreeNode>
{
{ "class1", new MarkupBlock() },
{ "class2", factory.Markup("").With(SpanCodeGenerator.Null) },
{ "class3", new MarkupBlock() },
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "class1", new MarkupBlock() },
{ "class2", factory.Markup("").With(SpanCodeGenerator.Null) },
{ "class3", new MarkupBlock() },
}))
},
{
"<p class1=''class2=\"\"class3= />",
new MarkupBlock(
new MarkupTagHelperBlock("p",
new Dictionary<string, SyntaxTreeNode>
{
{ "class1", new MarkupBlock() },
{ "class2", new MarkupBlock() },
{ "class3", factory.Markup("").With(SpanCodeGenerator.Null) },
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "class1", new MarkupBlock() },
{ "class2", new MarkupBlock() },
{ "class3", factory.Markup("").With(SpanCodeGenerator.Null) },
}))
},
};
}
@ -2462,48 +2477,53 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
"<person age=\"12\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
new Dictionary<string, SyntaxTreeNode>
{
{ "age", factory.CodeMarkup("12") }
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "age", factory.CodeMarkup("12") }
}))
},
{
"<person birthday=\"DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
new Dictionary<string, SyntaxTreeNode>
{
{ "birthday", factory.CodeMarkup("DateTime.Now") }
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "birthday", factory.CodeMarkup("DateTime.Now") }
}))
},
{
"<person name=\"John\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
new Dictionary<string, SyntaxTreeNode>
{
{ "name", factory.Markup("John") }
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "name", factory.Markup("John") }
}))
},
{
"<person name=\"Time: @DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
new Dictionary<string, SyntaxTreeNode>
{
{ "name", new MarkupBlock(factory.Markup("Time:"), dateTimeNow) }
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "name", new MarkupBlock(factory.Markup("Time:"), dateTimeNow) }
}))
},
{
"<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
new Dictionary<string, SyntaxTreeNode>
{
{ "age", factory.CodeMarkup("12") },
{ "birthday", factory.CodeMarkup("DateTime.Now") },
{ "name", new MarkupBlock(factory.Markup("Time:"), dateTimeNow) }
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "age", factory.CodeMarkup("12") },
{ "birthday", factory.CodeMarkup("DateTime.Now") },
{ "name", new MarkupBlock(factory.Markup("Time:"), dateTimeNow) }
}))
},
};
}
@ -2668,7 +2688,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
"<<p />",
new MarkupBlock(
blockFactory.MarkupTagBlock("<"),
new MarkupTagHelperBlock("p"))
new MarkupTagHelperBlock("p", selfClosing: true))
},
{
"< p />",
@ -2679,7 +2699,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
"<input <p />",
new MarkupBlock(
blockFactory.MarkupTagBlock("<input "),
new MarkupTagHelperBlock("p"))
new MarkupTagHelperBlock("p", selfClosing: true))
},
{
"< class=\"foo\" <p />",
@ -2697,7 +2717,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
value: new LocationTagged<string>("foo", 9, 0, 9))),
factory.Markup("\"").With(SpanCodeGenerator.Null)),
factory.Markup(" ")),
new MarkupTagHelperBlock("p"))
new MarkupTagHelperBlock("p", selfClosing: true))
},
{
"</<<p>/></p>>",
@ -3319,11 +3339,12 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
"<script class=\"foo\" style=\"color:red;\" />",
new MarkupBlock(
new MarkupTagHelperBlock("script",
new Dictionary<string, SyntaxTreeNode>
{
{ "class", factory.Markup("foo") },
{ "style", factory.Markup("color:red;") }
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "class", factory.Markup("foo") },
{ "style", factory.Markup("color:red;") }
}))
};
yield return new object[] {
"<p>Hello <script class=\"foo\" style=\"color:red;\"></script> World</p>",
@ -3360,37 +3381,45 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
"<p class=\"foo\" style=\"color:red;\" />",
new MarkupBlock(
new MarkupTagHelperBlock("p",
new Dictionary<string, SyntaxTreeNode>
{
{ "class", factory.Markup("foo") },
{ "style", factory.Markup("color:red;") }
}))
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "class", factory.Markup("foo") },
{ "style", factory.Markup("color:red;") }
}))
};
yield return new object[] {
"<p>Hello <p class=\"foo\" style=\"color:red;\" /> World</p>",
new MarkupBlock(
new MarkupTagHelperBlock("p",
factory.Markup("Hello "),
new MarkupTagHelperBlock("p",
new Dictionary<string, SyntaxTreeNode>
{
{ "class", factory.Markup("foo") },
{ "style", factory.Markup("color:red;") }
}),
factory.Markup(" World")))
new MarkupTagHelperBlock(
"p",
selfClosing: false,
children: new SyntaxTreeNode[] {
factory.Markup("Hello "),
new MarkupTagHelperBlock(
"p",
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "class", factory.Markup("foo") },
{ "style", factory.Markup("color:red;") }
}),
factory.Markup(" World")}))
};
yield return new object[] {
"Hello<p class=\"foo\" /> <p style=\"color:red;\" />World",
new MarkupBlock(
factory.Markup("Hello"),
new MarkupTagHelperBlock("p",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "class", factory.Markup("foo") }
}),
factory.Markup(" "),
new MarkupTagHelperBlock("p",
new Dictionary<string, SyntaxTreeNode>
selfClosing: true,
attributes: new Dictionary<string, SyntaxTreeNode>
{
{ "style", factory.Markup("color:red;") }
}),

View File

@ -27,9 +27,9 @@ namespace TestOutput
Instrumentation.BeginContext(33, 49, true);
WriteLiteral("\r\n<div class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__PTagHelper = CreateTagHelper<PTagHelper>();
@ -53,7 +53,7 @@ namespace TestOutput
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -82,7 +82,7 @@ namespace TestOutput
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -28,9 +28,9 @@ namespace TestOutput
Instrumentation.BeginContext(33, 49, true);
WriteLiteral("\r\n<div class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__PTagHelper = CreateTagHelper<PTagHelper>();
@ -54,7 +54,7 @@ namespace TestOutput
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -83,7 +83,7 @@ namespace TestOutput
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -40,7 +40,7 @@ namespace TestOutput
Instrumentation.BeginContext(84, 55, true);
WriteLiteral(" <div class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n <h1>Set Time:</h1>\r\n");
#line 10 "ComplexTagHelpers.cshtml"
@ -56,9 +56,9 @@ namespace TestOutput
#line hidden
WriteLiteral(" ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("New Time: ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -120,9 +120,9 @@ namespace TestOutput
#line hidden
WriteLiteral(" ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("Current Time: ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -186,7 +186,7 @@ Write(checkbox);
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -222,7 +222,7 @@ Write(true ? "checkbox" : "anything");
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -314,7 +314,7 @@ Write(DateTime.Now);
Instrumentation.BeginContext(672, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n");
#line 22 "ComplexTagHelpers.cshtml"
@ -329,7 +329,7 @@ Write(DateTime.Now);
#line hidden
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -392,9 +392,9 @@ __PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
Instrumentation.BeginContext(819, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -457,9 +457,9 @@ __PTagHelper.Age = -1970 + DateTimeOffset.Now.Year;
Instrumentation.BeginContext(952, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -522,9 +522,9 @@ __PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
Instrumentation.BeginContext(1080, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -28,7 +28,7 @@ namespace TestOutput
Instrumentation.BeginContext(27, 13, true);
WriteLiteral("\r\n<div>\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -66,9 +66,9 @@ __InputTagHelper2.Checked = ;
Instrumentation.BeginContext(74, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -37,7 +37,7 @@ namespace TestOutput
Instrumentation.BeginContext(114, 69, true);
WriteLiteral(">\r\n <input type=\"text\" />\r\n <em>Not a TagHelper: </em> ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
}
, StartWritingScope, EndWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -26,7 +26,7 @@ namespace TestOutput
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
WriteLiteral("Body of Tag");
}
, StartWritingScope, EndWritingScope);

View File

@ -24,9 +24,9 @@ MyHelper(string val)
Instrumentation.BeginContext(68, 19, true);
WriteLiteralTo(__razor_helper_writer, " <div>\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", false, "test", async() => {
WriteLiteral("\r\n In None ContentBehavior.\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", false, "test", async() => {
WriteLiteral("Some buffered values with a value of ");
#line 8 "TagHelpersInHelper.cshtml"
Write(val);
@ -135,10 +135,10 @@ Write(DateTime.Now);
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", false, "test", async() => {
#line 12 "TagHelpersInHelper.cshtml"
Write(MyHelper(item => new Template((__razor_template_writer) => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", false, "test", async() => {
WriteLiteral("Custom Value");
}
, StartWritingScope, EndWritingScope);

View File

@ -40,9 +40,9 @@ namespace TestOutput
Instrumentation.BeginContext(93, 21, true);
WriteLiteralTo(__razor_template_writer, "\r\n <div>\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", false, "test", async() => {
WriteLiteral("\r\n In None ContentBehavior.\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", false, "test", async() => {
WriteLiteral("Some buffered values with ");
#line 11 "TagHelpersInSection.cshtml"
Write(code);