Add ability to write start tag only `TagHelper` elements.

- To write a start tag only `TagHelper` you can now utilize the `TagStructure` property on the `TargetElement` attribute. If none is specified it'll be treated as unspecified and default to old behavior of being start/end tag or self-closing.
- Added `TagMode` to showcase what the user initially wrote in their Razor document. This way `TagHelper`s can flow end-to-end in thesame format as they were written with.
- Updated code generation to specify `TagMode` instead of the boolean self-closing.
- Updated existing tests to move from `SelfClosing` => `TagMode`.
- Added `TagStructure` related tests to the set of tests that we currently have for `TagHelperBlockRewriter` and `TagHelperParseTreeRewriter`.

#450
This commit is contained in:
N. Taylor Mullen 2015-08-10 15:11:24 -07:00
parent 71c4c8dac6
commit e9292a0e30
52 changed files with 1077 additions and 390 deletions

View File

@ -118,6 +118,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName,
attributeDescriptors,
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: typeDesignTimeDescriptor)
};
}
@ -147,6 +148,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName,
attributeDescriptors,
requiredAttributes,
targetElementAttribute.TagStructure,
designTimeDescriptor);
}
@ -156,6 +158,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
string assemblyName,
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
IEnumerable<string> requiredAttributes,
TagStructure tagStructure,
TagHelperDesignTimeDescriptor designTimeDescriptor)
{
return new TagHelperDescriptor(
@ -165,6 +168,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: assemblyName,
attributes: attributeDescriptors,
requiredAttributes: requiredAttributes,
tagStructure: tagStructure,
designTimeDescriptor: designTimeDescriptor);
}

View File

@ -154,6 +154,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
descriptor.AssemblyName,
descriptor.Attributes,
descriptor.RequiredAttributes,
descriptor.TagStructure,
descriptor.DesignTimeDescriptor));
}

View File

@ -22,9 +22,9 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <summary>
/// Internal for testing purposes only.
/// </summary>
internal TagHelperExecutionContext(string tagName, bool selfClosing)
internal TagHelperExecutionContext(string tagName, TagMode tagMode)
: this(tagName,
selfClosing,
tagMode,
items: new Dictionary<object, object>(),
uniqueId: string.Empty,
executeChildContentAsync: async () => await Task.FromResult(result: true),
@ -37,8 +37,7 @@ 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="tagMode">HTML syntax of the element in the Razor source.</param>
/// <param name="items">The collection of items used to communicate with other
/// <see cref="ITagHelper"/>s</param>
/// <param name="uniqueId">An identifier unique to the HTML element this context is for.</param>
@ -47,7 +46,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <param name="endTagHelperWritingScope">A delegate used to end a writing scope in a Razor page.</param>
public TagHelperExecutionContext(
[NotNull] string tagName,
bool selfClosing,
TagMode tagMode,
[NotNull] IDictionary<object, object> items,
[NotNull] string uniqueId,
[NotNull] Func<Task> executeChildContentAsync,
@ -59,7 +58,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
_startTagHelperWritingScope = startTagHelperWritingScope;
_endTagHelperWritingScope = endTagHelperWritingScope;
SelfClosing = selfClosing;
TagMode = tagMode;
HTMLAttributes = new TagHelperAttributeList();
AllAttributes = new TagHelperAttributeList();
TagName = tagName;
@ -68,9 +67,9 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
/// <summary>
/// Gets a value indicating whether or not the tag in the Razor source was self-closing.
/// Gets the HTML syntax of the element in the Razor source.
/// </summary>
public bool SelfClosing { get; }
public TagMode TagMode { get; }
/// <summary>
/// Indicates if <see cref="GetChildContentAsync"/> has been called.

View File

@ -1,8 +1,6 @@
// 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 Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
@ -82,9 +80,9 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
/// <summary>
/// Indicates whether or not the tag is self-closing.
/// Syntax of the element in the generated HTML.
/// </summary>
public bool SelfClosing { get; set; }
public TagMode TagMode { get; set; }
/// <summary>
/// The HTML element's attributes.
@ -100,7 +98,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// Changes <see cref="TagHelperOutput"/> to generate nothing.
/// </summary>
/// <remarks>
/// Sets <see cref="TagName"/> to <c>null</c>, and clears <see cref="PreElement"/>, <see cref="PreContent"/>,
/// Sets <see cref="TagName"/> to <c>null</c>, and clears <see cref="PreElement"/>, <see cref="PreContent"/>,
/// <see cref="Content"/>, <see cref="PostContent"/>, and <see cref="PostElement"/> to suppress output.
/// </remarks>
public void SuppressOutput()

View File

@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
executionContext.TagName,
executionContext.HTMLAttributes)
{
SelfClosing = executionContext.SelfClosing,
TagMode = executionContext.TagMode,
};
var orderedTagHelpers = executionContext.TagHelpers.OrderBy(tagHelper => tagHelper.Order);

View File

@ -27,9 +27,7 @@ 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="tagMode">HTML syntax of the element in the Razor source.</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="startTagHelperWritingScope">A delegate used to start a writing scope in a Razor page.</param>
@ -37,7 +35,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <returns>A <see cref="TagHelperExecutionContext"/> to use.</returns>
public TagHelperExecutionContext Begin(
[NotNull] string tagName,
bool selfClosing,
TagMode tagMode,
[NotNull] string uniqueId,
[NotNull] Func<Task> executeChildContentAsync,
[NotNull] Action startTagHelperWritingScope,
@ -59,7 +57,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var executionContext = new TagHelperExecutionContext(
tagName,
selfClosing,
tagMode,
items,
uniqueId,
executeChildContentAsync,

View File

@ -53,5 +53,31 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
/// <c>*</c> at the end of an attribute name acts as a prefix match.
/// </remarks>
public string Attributes { get; set; }
/// <summary>
/// The expected tag structure.
/// </summary>
/// <remarks>
/// If <see cref="TagStructure.Unspecified"/> and no other tag helpers applying to the same element specify
/// their <see cref="TagStructure"/> the <see cref="TagStructure.NormalOrSelfClosing"/> behavior is used:
/// <para>
/// <code>
/// &lt;my-tag-helper&gt;&lt;/my-tag-helper&gt;
/// &lt;!-- OR --&gt;
/// &lt;my-tag-helper /&gt;
/// </code>
/// Otherwise, if another tag helper applying to the same element does specify their behavior, that behavior
/// is used.
/// </para>
/// <para>
/// If <see cref="TagStructure.WithoutEndTag"/> HTML elements can be written in the following formats:
/// <code>
/// &lt;my-tag-helper&gt;
/// &lt;!-- OR --&gt;
/// &lt;my-tag-helper /&gt;
/// </code>
/// </para>
/// </remarks>
public TagStructure TagStructure { get; set; }
}
}

View File

@ -1,7 +1,6 @@
// 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.Diagnostics;
using System.Linq;
@ -84,7 +83,7 @@ namespace Microsoft.AspNet.Razor.Chunks.Generators
context.ChunkTreeBuilder.StartParentChunk(
new TagHelperChunk(
unprefixedTagName,
tagHelperBlock.SelfClosing,
tagHelperBlock.TagMode,
attributes,
_tagHelperDescriptors),
target,

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
namespace Microsoft.AspNet.Razor.Chunks
@ -15,21 +16,19 @@ namespace Microsoft.AspNet.Razor.Chunks
/// 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="tagMode">HTML syntax of the element in the Razor source.</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,
TagMode tagMode,
IList<KeyValuePair<string, Chunk>> attributes,
IEnumerable<TagHelperDescriptor> descriptors)
{
TagName = tagName;
SelfClosing = selfClosing;
TagMode = tagMode;
Attributes = attributes;
Descriptors = descriptors;
}
@ -54,8 +53,8 @@ namespace Microsoft.AspNet.Razor.Chunks
public string TagName { get; set; }
/// <summary>
/// Gets a value indicating whether or not the tag of the tag helpers HTML element is self-closing.
/// Gets the HTML syntax of the element in the Razor source.
/// </summary>
public bool SelfClosing { get; }
public TagMode TagMode { get; }
}
}

View File

@ -7,6 +7,7 @@ using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Framework.Internal;
@ -65,7 +66,7 @@ namespace Microsoft.AspNet.Razor.CodeGenerators
// the same TagHelper X many times (instead of once) over a single HTML element.
var tagHelperDescriptors = chunk.Descriptors.Distinct(TypeBasedTagHelperDescriptorComparer.Default);
RenderBeginTagHelperScope(chunk.TagName, chunk.SelfClosing, chunk.Children);
RenderBeginTagHelperScope(chunk.TagName, chunk.TagMode, chunk.Children);
RenderTagHelpersCreation(chunk, tagHelperDescriptors);
@ -85,7 +86,7 @@ namespace Microsoft.AspNet.Razor.CodeGenerators
return "__" + descriptor.TypeName.Replace('.', '_');
}
private void RenderBeginTagHelperScope(string tagName, bool selfClosing, IList<Chunk> children)
private void RenderBeginTagHelperScope(string tagName, TagMode tagMode, IList<Chunk> children)
{
// Scopes/execution contexts are a runtime feature.
if (_designTimeMode)
@ -105,7 +106,9 @@ namespace Microsoft.AspNet.Razor.CodeGenerators
// per call site, e.g. if the tag is on the view twice, there should be two IDs.
_writer.WriteStringLiteral(tagName)
.WriteParameterSeparator()
.WriteBooleanLiteral(selfClosing)
.Write(nameof(TagMode))
.Write(".")
.Write(tagMode.ToString())
.WriteParameterSeparator()
.WriteStringLiteral(GenerateUniqueId())
.WriteParameterSeparator();

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Framework.Internal;
@ -30,7 +31,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
Descriptors = source.Descriptors;
Attributes = new List<KeyValuePair<string, SyntaxTreeNode>>(source.Attributes);
_start = source.Start;
SelfClosing = source.SelfClosing;
TagMode = source.TagMode;
SourceStartTag = source.SourceStartTag;
SourceEndTag = source.SourceEndTag;
@ -58,9 +59,9 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
public Block SourceEndTag { get; }
/// <summary>
/// Indicates whether or not the tag is self closing.
/// Gets the HTML syntax of the element in the Razor source.
/// </summary>
public bool SelfClosing { get; }
public TagMode TagMode { get; }
/// <summary>
/// <see cref="TagHelperDescriptor"/>s for the HTML element.

View File

@ -4,6 +4,7 @@
using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
namespace Microsoft.AspNet.Razor.Parser.TagHelpers
@ -32,22 +33,20 @@ 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="tagMode">HTML syntax of the element in the Razor source.</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,
TagMode tagMode,
SourceLocation start,
IList<KeyValuePair<string, SyntaxTreeNode>> attributes,
IEnumerable<TagHelperDescriptor> descriptors)
{
TagName = tagName;
SelfClosing = selfClosing;
TagMode = tagMode;
Start = start;
Descriptors = descriptors;
Attributes = new List<KeyValuePair<string, SyntaxTreeNode>>(attributes);
@ -58,12 +57,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
// Internal for testing
internal TagHelperBlockBuilder(
string tagName,
bool selfClosing,
TagMode tagMode,
IList<KeyValuePair<string, SyntaxTreeNode>> attributes,
IEnumerable<SyntaxTreeNode> children)
{
TagName = tagName;
SelfClosing = selfClosing;
TagMode = tagMode;
Attributes = attributes;
Type = BlockType.Tag;
ChunkGenerator = new TagHelperChunkGenerator(tagHelperDescriptors: null);
@ -88,9 +87,9 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
public Block SourceEndTag { get; set; }
/// <summary>
/// Gets a value indicating whether or not the tag in the Razor source was self-closing.
/// Gets the HTML syntax of the element in the Razor source.
/// </summary>
public bool SelfClosing { get; }
public TagMode TagMode { get; }
/// <summary>
/// <see cref="TagHelperDescriptor"/>s for the HTML element.

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.AspNet.Razor.Tokenizer.Symbols;
@ -25,9 +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);
var tagMode = GetTagMode(tagName, tag, descriptors, errorSink);
return new TagHelperBlockBuilder(tagName, selfClosing, start, attributes, descriptors);
return new TagHelperBlockBuilder(tagName, tagMode, start, attributes, descriptors);
}
private static IList<KeyValuePair<string, SyntaxTreeNode>> GetTagAttributes(
@ -108,11 +109,29 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
return attributes;
}
private static bool IsSelfClosing(Block beginTagBlock)
private static TagMode GetTagMode(
string tagName,
Block beginTagBlock,
IEnumerable<TagHelperDescriptor> descriptors,
ErrorSink errorSink)
{
var childSpan = beginTagBlock.FindLastDescendentSpan();
return childSpan?.Content.EndsWith("/>") ?? false;
// Self-closing tags are always valid despite descriptors[X].TagStructure.
if (childSpan?.Content.EndsWith("/>") ?? false)
{
return TagMode.SelfClosing;
}
var baseDescriptor = descriptors.FirstOrDefault(
descriptor => descriptor.TagStructure != TagStructure.Unspecified);
var resolvedTagStructure = baseDescriptor?.TagStructure ?? TagStructure.Unspecified;
if (resolvedTagStructure == TagStructure.WithoutEndTag)
{
return TagMode.StartTagOnly;
}
return TagMode.StartTagAndEndTag;
}
// This method handles cases when the attribute is a simple span attribute such as

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.AspNet.Razor.Tokenizer.Symbols;
@ -70,7 +71,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
// At this point the child is a Span or Block with Type BlockType.Tag that doesn't happen to be a
// tag helper.
// Add the child to current block.
// Add the child to current block.
_currentBlock.Children.Add(child);
}
@ -78,7 +79,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
// it means that there are malformed tag helpers at the top of our stack.
if (activeTagHelpers != _trackerStack.Count)
{
// Malformed tag helpers built here will be tag helpers that do not have end tags in the current block
// Malformed tag helpers built here will be tag helpers that do not have end tags in the current block
// scope. Block scopes are special cases in Razor such as @<p> would cause an error because there's no
// matching end </p> tag in the template block scope and therefore doesn't make sense as a tag helper.
BuildMalformedTagHelpers(_trackerStack.Count - activeTagHelpers, context);
@ -117,11 +118,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
descriptors = _provider.GetDescriptors(tagName, providedAttributes);
// If there aren't any TagHelperDescriptors registered then we aren't a TagHelper
if (!descriptors.Any())
{
// If the current tag matches the current TagHelper scope it means the parent TagHelper matched
// all the required attributes but the current one did not; therefore, we need to increment the
// all the required attributes but the current one did not; therefore, we need to increment the
// OpenMatchingTags counter for current the TagHelperBlock so we don't end it too early.
// ex: <myth req="..."><myth></myth></myth> We don't want the first myth to close on the inside
// tag.
@ -133,8 +135,10 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
return false;
}
ValidateDescriptors(descriptors, tagName, tagBlock, context.ErrorSink);
// We're in a start TagHelper block.
var validTagStructure = ValidateTagStructure(tagName, tagBlock, context);
var validTagStructure = ValidateTagSyntax(tagName, tagBlock, context);
var builder = TagHelperBlockRewriter.Rewrite(
tagName,
@ -143,16 +147,16 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
descriptors,
context.ErrorSink);
// Track the original start tag so the editor knows where each piece of the TagHelperBlock lies
// Track the original start tag so the editor knows where each piece of the TagHelperBlock lies
// for formatting.
builder.SourceStartTag = tagBlock;
// Found a new tag helper block
TrackTagHelperBlock(builder);
// If it's a self closing block then we don't have to worry about nested children
// within the tag... complete it.
if (builder.SelfClosing)
// If it's a non-content expecting block then we don't have to worry about nested children within the
// tag. Complete it.
if (builder.TagMode == TagMode.SelfClosing || builder.TagMode == TagMode.StartTagOnly)
{
BuildCurrentlyTrackedTagHelperBlock(endTag: null);
}
@ -171,25 +175,43 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
return false;
}
ValidateTagStructure(tagName, tagBlock, context);
ValidateTagSyntax(tagName, tagBlock, context);
BuildCurrentlyTrackedTagHelperBlock(tagBlock);
}
else
{
// If there are not TagHelperDescriptors associated with the end tag block that also have no
descriptors = _provider.GetDescriptors(tagName, attributeNames: Enumerable.Empty<string>());
// If there are not TagHelperDescriptors associated with the end tag block that also have no
// required attributes then it means we can't be a TagHelper, bail out.
if (!_provider.GetDescriptors(tagName, attributeNames: Enumerable.Empty<string>()).Any())
if (!descriptors.Any())
{
return false;
}
// Current tag helper scope does not match the end tag. Attempt to recover the tag
// helper by looking up the previous tag helper scopes for a matching tag. If we
var invalidDescriptor = descriptors.FirstOrDefault(
descriptor => descriptor.TagStructure == TagStructure.WithoutEndTag);
if (invalidDescriptor != null)
{
// End tag TagHelper that states it shouldn't have an end tag.
context.ErrorSink.OnError(
tagBlock.Start,
RazorResources.FormatTagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag(
tagName,
invalidDescriptor.TypeName,
invalidDescriptor.TagStructure),
tagBlock.Length);
return false;
}
// Current tag helper scope does not match the end tag. Attempt to recover the tag
// helper by looking up the previous tag helper scopes for a matching tag. If we
// can't recover it means there was no corresponding tag helper start tag.
if (TryRecoverTagHelper(tagName, tagBlock, context))
{
ValidateTagStructure(tagName, tagBlock, context);
ValidateTagSyntax(tagName, tagBlock, context);
// Successfully recovered, move onto the next element.
}
@ -245,9 +267,40 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
return attributeNames;
}
private static bool ValidateTagStructure(string tagName, Block tag, RewritingContext context)
private static void ValidateDescriptors(
IEnumerable<TagHelperDescriptor> descriptors,
string tagName,
Block tagBlock,
ErrorSink errorSink)
{
// We assume an invalid structure until we verify that the tag meets all of our "valid structure" criteria.
// Ensure that all descriptors associated with this tag have appropriate TagStructures. Cannot have
// multiple descriptors that expect different TagStructures (other than TagStructure.Unspecified).
TagHelperDescriptor baseDescriptor = null;
foreach (var descriptor in descriptors)
{
if (descriptor.TagStructure != TagStructure.Unspecified)
{
// Can't have a set of TagHelpers that expect different structures.
if (baseDescriptor != null && baseDescriptor.TagStructure != descriptor.TagStructure)
{
errorSink.OnError(
tagBlock.Start,
RazorResources.FormatTagHelperParseTreeRewriter_InconsistentTagStructure(
baseDescriptor.TypeName,
descriptor.TypeName,
tagName,
nameof(TagHelperDescriptor.TagStructure)),
tagBlock.Length);
}
baseDescriptor = descriptor;
}
}
}
private static bool ValidateTagSyntax(string tagName, Block tag, RewritingContext context)
{
// We assume an invalid syntax until we verify that the tag meets all of our "valid syntax" criteria.
if (IsPartialTag(tag))
{
context.ErrorSink.OnError(
@ -304,7 +357,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
private void BuildCurrentlyTrackedTagHelperBlock(Block endTag)
{
// Track the original end tag so the editor knows where each piece of the TagHelperBlock lies
// Track the original end tag so the editor knows where each piece of the TagHelperBlock lies
// for formatting.
_trackerStack.Pop().Builder.SourceEndTag = endTag;
@ -351,7 +404,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
malformedTagHelperCount++;
}
// If the malformedTagHelperCount == _tagStack.Count it means we couldn't find a start tag for the tag
// If the malformedTagHelperCount == _tagStack.Count it means we couldn't find a start tag for the tag
// helper, can't recover.
if (malformedTagHelperCount != _trackerStack.Count)
{

View File

@ -1482,6 +1482,38 @@ namespace Microsoft.AspNet.Razor
return string.Format(CultureInfo.CurrentCulture, GetString("SourceLocationFilePathDoesNotMatch"), p0, p1);
}
/// <summary>
/// Tag helpers '{0}' and '{1}' targeting element '{2}' must not expect different {3} values.
/// </summary>
internal static string TagHelperParseTreeRewriter_InconsistentTagStructure
{
get { return GetString("TagHelperParseTreeRewriter_InconsistentTagStructure"); }
}
/// <summary>
/// Tag helpers '{0}' and '{1}' targeting element '{2}' must not expect different {3} values.
/// </summary>
internal static string FormatTagHelperParseTreeRewriter_InconsistentTagStructure(object p0, object p1, object p2, object p3)
{
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperParseTreeRewriter_InconsistentTagStructure"), p0, p1, p2, p3);
}
/// <summary>
/// Found an end tag (&amp;lt;/{0}&amp;gt;) for tag helper '{1}' with tag structure that disallows an end tag ('{2}').
/// </summary>
internal static string TagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag
{
get { return GetString("TagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag"); }
}
/// <summary>
/// Found an end tag (&amp;lt;/{0}&amp;gt;) for tag helper '{1}' with tag structure that disallows an end tag ('{2}').
/// </summary>
internal static string FormatTagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag(object p0, object p1, object p2)
{
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag"), p0, p1, p2);
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -413,4 +413,10 @@ Instead, wrap the contents of the block in "{{}}":
<data name="SourceLocationFilePathDoesNotMatch" xml:space="preserve">
<value>Cannot perform '{1}' operations on '{0}' instances with different file paths.</value>
</data>
<data name="TagHelperParseTreeRewriter_InconsistentTagStructure" xml:space="preserve">
<value>Tag helpers '{0}' and '{1}' targeting element '{2}' must not expect different {3} values.</value>
</data>
<data name="TagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag" xml:space="preserve">
<value>Found an end tag (&amp;lt;/{0}&amp;gt;) for tag helper '{1}' with tag structure that disallows an end tag ('{2}').</value>
</data>
</root>

View File

@ -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.
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
/// <summary>
/// The mode in which an element should render.
/// </summary>
public enum TagMode
{
/// <summary>
/// Include both start and end tags.
/// </summary>
StartTagAndEndTag,
/// <summary>
/// A self-closed tag.
/// </summary>
SelfClosing,
/// <summary>
/// Only a start tag.
/// </summary>
StartTagOnly
}
}

View File

@ -0,0 +1,28 @@
// 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.
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
/// <summary>
/// The structure the element should be written in.
/// </summary>
public enum TagStructure
{
/// <summary>
/// If no other tag helper applies to the same element and specifies a <see cref="TagStructure"/>,
/// <see cref="NormalOrSelfClosing"/> will be used.
/// </summary>
Unspecified,
/// <summary>
/// Element can be written as &lt;my-tag-helper&gt;&lt;/my-tag-helper&gt; or &lt;my-tag-helper /&gt;.
/// </summary>
NormalOrSelfClosing,
/// <summary>
/// Element can be written as &lt;my-tag-helper&gt; or &lt;my-tag-helper /&gt;.
/// </summary>
/// <remarks>Elements with a <see cref="WithoutEndTag"/> structure will never have any content.</remarks>
WithoutEndTag
}
}

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Razor.TagHelpers
@ -60,6 +61,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: assemblyName,
attributes: attributes,
requiredAttributes: requiredAttributes,
tagStructure: TagStructure.Unspecified,
designTimeDescriptor: null)
{
}
@ -91,6 +93,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
[NotNull] string assemblyName,
[NotNull] IEnumerable<TagHelperAttributeDescriptor> attributes,
[NotNull] IEnumerable<string> requiredAttributes,
TagStructure tagStructure,
TagHelperDesignTimeDescriptor designTimeDescriptor)
{
Prefix = prefix ?? string.Empty;
@ -100,6 +103,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
AssemblyName = assemblyName;
Attributes = new List<TagHelperAttributeDescriptor>(attributes);
RequiredAttributes = new List<string>(requiredAttributes);
TagStructure = tagStructure;
DesignTimeDescriptor = designTimeDescriptor;
}
@ -143,6 +147,32 @@ namespace Microsoft.AspNet.Razor.TagHelpers
/// </remarks>
public IReadOnlyList<string> RequiredAttributes { get; }
/// <summary>
/// The expected tag structure.
/// </summary>
/// <remarks>
/// If <see cref="TagStructure.Unspecified"/> and no other tag helpers applying to the same element specify
/// their <see cref="TagStructure"/> the <see cref="TagStructure.NormalOrSelfClosing"/> behavior is used:
/// <para>
/// <code>
/// &lt;my-tag-helper&gt;&lt;/my-tag-helper&gt;
/// &lt;!-- OR --&gt;
/// &lt;my-tag-helper /&gt;
/// </code>
/// Otherwise, if another tag helper applying to the same element does specify their behavior, that behavior
/// is used.
/// </para>
/// <para>
/// If <see cref="TagStructure.WithoutEndTag"/> HTML elements can be written in the following formats:
/// <code>
/// &lt;my-tag-helper&gt;
/// &lt;!-- OR --&gt;
/// &lt;my-tag-helper /&gt;
/// </code>
/// </para>
/// </remarks>
public TagStructure TagStructure { get; }
/// <summary>
/// The <see cref="TagHelperDesignTimeDescriptor"/> that contains design time information about this
/// tag helper.

View File

@ -30,8 +30,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
/// <remarks>
/// Determines equality based on <see cref="TagHelperDescriptor.TypeName"/>,
/// <see cref="TagHelperDescriptor.AssemblyName"/>, <see cref="TagHelperDescriptor.TagName"/>,
/// and <see cref="TagHelperDescriptor.RequiredAttributes"/>. Ignores
/// <see cref="TagHelperDescriptor.DesignTimeDescriptor"/> because it can be inferred directly from
/// <see cref="TagHelperDescriptor.RequiredAttributes"/>, and <see cref="TagHelperDescriptor.TagStructure"/>.
/// Ignores <see cref="TagHelperDescriptor.DesignTimeDescriptor"/> because it can be inferred directly from
/// <see cref="TagHelperDescriptor.TypeName"/> and <see cref="TagHelperDescriptor.AssemblyName"/>.
/// </remarks>
public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
@ -48,7 +48,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
Enumerable.SequenceEqual(
descriptorX.RequiredAttributes.OrderBy(attribute => attribute, StringComparer.OrdinalIgnoreCase),
descriptorY.RequiredAttributes.OrderBy(attribute => attribute, StringComparer.OrdinalIgnoreCase),
StringComparer.OrdinalIgnoreCase);
StringComparer.OrdinalIgnoreCase) &&
descriptorX.TagStructure == descriptorY.TagStructure;
}
/// <inheritdoc />
@ -57,7 +58,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers
var hashCodeCombiner = HashCodeCombiner.Start()
.Add(descriptor.TypeName, StringComparer.Ordinal)
.Add(descriptor.TagName, StringComparer.OrdinalIgnoreCase)
.Add(descriptor.AssemblyName, StringComparer.Ordinal);
.Add(descriptor.AssemblyName, StringComparer.Ordinal)
.Add(descriptor.TagStructure);
var attributes = descriptor.RequiredAttributes.OrderBy(
attribute => attribute,

View File

@ -17,6 +17,106 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
private static readonly string AssemblyName =
typeof(TagHelperDescriptorFactoryTest).GetTypeInfo().Assembly.GetName().Name;
public static TheoryData TagStructureData
{
get
{
// tagHelperType, expectedDescriptors
return new TheoryData<Type, TagHelperDescriptor[]>
{
{
typeof(TagStructureTagHelper),
new[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: typeof(TagStructureTagHelper).FullName,
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null)
}
},
{
typeof(MultiSpecifiedTagStructureTagHelper),
new[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: typeof(MultiSpecifiedTagStructureTagHelper).FullName,
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "p",
typeName: typeof(MultiSpecifiedTagStructureTagHelper).FullName,
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.NormalOrSelfClosing,
designTimeDescriptor: null),
}
},
{
typeof(MultiWithUnspecifiedTagStructureTagHelper),
new[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: typeof(MultiWithUnspecifiedTagStructureTagHelper).FullName,
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "p",
typeName: typeof(MultiWithUnspecifiedTagStructureTagHelper).FullName,
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.Unspecified,
designTimeDescriptor: null),
}
},
};
}
}
[Theory]
[MemberData(nameof(TagStructureData))]
public void CreateDescriptors_CreatesDesignTimeDescriptorsWithTagStructure(
Type tagHelperType,
TagHelperDescriptor[] expectedDescriptors)
{
// Arrange
var errorSink = new ErrorSink();
// Act
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
AssemblyName,
tagHelperType,
designTime: false,
errorSink: errorSink);
// Assert
Assert.Empty(errorSink.Errors);
// We don't care about order. Mono returns reflected attributes differently so we need to ensure order
// doesn't matter by sorting.
descriptors = descriptors.OrderBy(descriptor => descriptor.TagName);
Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
}
// TagHelperDesignTimeDescriptors are not created in CoreCLR.
#if !DNXCORE50
public static TheoryData OutputElementHintData
@ -37,6 +137,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: new TagHelperDesignTimeDescriptor(
summary: null,
remarks: null,
@ -54,6 +155,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: new TagHelperDesignTimeDescriptor(
summary: null,
remarks: null,
@ -65,6 +167,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: new TagHelperDesignTimeDescriptor(
summary: null,
remarks: null,
@ -1870,6 +1973,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: assemblyName,
attributes: attributes ?? Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: requiredAttributes ?? Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
}
@ -1885,6 +1989,23 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
designTimeDescriptor: null);
}
[TargetElement("input", TagStructure = TagStructure.WithoutEndTag)]
private class TagStructureTagHelper : TagHelper
{
}
[TargetElement("p", TagStructure = TagStructure.NormalOrSelfClosing)]
[TargetElement("input", TagStructure = TagStructure.WithoutEndTag)]
private class MultiSpecifiedTagStructureTagHelper : TagHelper
{
}
[TargetElement("p")]
[TargetElement("input", TagStructure = TagStructure.WithoutEndTag)]
private class MultiWithUnspecifiedTagStructureTagHelper : TagHelper
{
}
[EditorBrowsable(EditorBrowsableState.Always)]
private class DefaultEditorBrowsableTagHelper : TagHelper
{

View File

@ -32,6 +32,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
}
}
@ -47,6 +48,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: AssemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
}
}
@ -573,6 +575,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: assemblyB,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
return new TheoryData<Dictionary<string, IEnumerable<Type>>, // descriptorAssemblyLookups
@ -1008,6 +1011,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName: assemblyB,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
return new TheoryData<Dictionary<string, IEnumerable<Type>>, // descriptorAssemblyLookups
@ -1390,6 +1394,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
assemblyName,
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
}

View File

@ -13,15 +13,16 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
[Theory]
[InlineData(true)]
[InlineData(false)]
public void SelfClosing_ReturnsTrueOrFalseAsExpected(bool selfClosing)
[InlineData(TagMode.SelfClosing)]
[InlineData(TagMode.StartTagAndEndTag)]
[InlineData(TagMode.StartTagOnly)]
public void TagMode_ReturnsExpectedValue(TagMode tagMode)
{
// Arrange & Act
var executionContext = new TagHelperExecutionContext("p", selfClosing);
var executionContext = new TagHelperExecutionContext("p", tagMode);
// Assert
Assert.Equal(selfClosing, executionContext.SelfClosing);
Assert.Equal(tagMode, executionContext.TagMode);
}
[Fact]
@ -36,7 +37,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
// Act
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: expectedItems,
uniqueId: string.Empty,
executeChildContentAsync: async () => await Task.FromResult(result: true),
@ -56,7 +57,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var expectedContent = string.Empty;
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: null,
uniqueId: string.Empty,
executeChildContentAsync: () =>
@ -89,7 +90,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var executionCount = 0;
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: null,
uniqueId: string.Empty,
executeChildContentAsync: () =>
@ -118,7 +119,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var defaultTagHelperContent = new DefaultTagHelperContent();
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: null,
uniqueId: string.Empty,
executeChildContentAsync: () => { return Task.FromResult(result: true); },
@ -143,7 +144,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var childContentExecutionCount = 0;
var executionContext = new TagHelperExecutionContext(
"p",
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
items: null,
uniqueId: string.Empty,
executeChildContentAsync: () =>
@ -182,7 +183,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void HtmlAttributes_IgnoresCase(string originalName, string updatedName)
{
// Arrange
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
executionContext.HTMLAttributes[originalName] = "hello";
// Act
@ -198,7 +199,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void AllAttributes_IgnoresCase(string originalName, string updatedName)
{
// Arrange
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", tagMode: TagMode.StartTagAndEndTag);
executionContext.AllAttributes.Add(originalName, value: false);
// Act
@ -213,7 +214,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void AddHtmlAttribute_MaintainsHTMLAttributes()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var expectedAttributes = new TagHelperAttributeList
{
{ "class", "btn" },
@ -235,7 +236,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void AddMinimizedHtmlAttribute_MaintainsHTMLAttributes()
{
// Arrange
var executionContext = new TagHelperExecutionContext("input", selfClosing: true);
var executionContext = new TagHelperExecutionContext("input", tagMode: TagMode.StartTagOnly);
var expectedAttributes = new TagHelperAttributeList
{
["checked"] = new TagHelperAttribute { Name = "checked", Minimized = true },
@ -257,7 +258,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void AddMinimizedHtmlAttribute_MaintainsHTMLAttributes_SomeMinimized()
{
// Arrange
var executionContext = new TagHelperExecutionContext("input", selfClosing: true);
var executionContext = new TagHelperExecutionContext("input", tagMode: TagMode.SelfClosing);
var expectedAttributes = new TagHelperAttributeList
{
{ "class", "btn" },
@ -283,7 +284,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void TagHelperExecutionContext_MaintainsAllAttributes()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var expectedAttributes = new TagHelperAttributeList
{
{ "class", "btn" },
@ -307,7 +308,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void Add_MaintainsTagHelpers()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var tagHelper = new PTagHelper();
// Act
@ -322,7 +323,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public void Add_MaintainsMultipleTagHelpers()
{
// Arrange
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var tagHelper1 = new PTagHelper();
var tagHelper2 = new PTagHelper();

View File

@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var processOrder = new List<int>();
foreach (var order in tagHelperOrders)
@ -82,13 +82,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public async Task RunAsync_SetTagHelperOutputSelfClosing(bool selfClosing)
[InlineData(TagMode.SelfClosing)]
[InlineData(TagMode.StartTagAndEndTag)]
[InlineData(TagMode.StartTagOnly)]
public async Task RunAsync_SetsTagHelperOutputTagMode(TagMode tagMode)
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p", selfClosing);
var executionContext = new TagHelperExecutionContext("p", tagMode);
var tagHelper = new TagHelperContextTouchingTagHelper();
executionContext.Add(tagHelper);
@ -98,7 +99,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
var output = await runner.RunAsync(executionContext);
// Assert
Assert.Equal(selfClosing, output.SelfClosing);
Assert.Equal(tagMode, output.TagMode);
}
[Fact]
@ -106,7 +107,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var executableTagHelper1 = new ExecutableTagHelper();
var executableTagHelper2 = new ExecutableTagHelper();
@ -125,7 +126,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var executableTagHelper = new ExecutableTagHelper();
// Act
@ -137,7 +138,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
Assert.Equal("foo", output.TagName);
Assert.Equal("somethingelse", output.Attributes["class"].Value);
Assert.Equal("world", output.Attributes["hello"].Value);
Assert.Equal(true, output.SelfClosing);
Assert.Equal(TagMode.SelfClosing, output.TagMode);
}
[Fact]
@ -145,7 +146,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var tagHelper = new TagHelperContextTouchingTagHelper();
// Act
@ -162,7 +163,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
{
// Arrange
var runner = new TagHelperRunner();
var executionContext = new TagHelperExecutionContext("p", selfClosing: false);
var executionContext = new TagHelperExecutionContext("p", TagMode.StartTagAndEndTag);
var tagHelper = new ContextInspectingTagHelper();
executionContext.Add(tagHelper);
@ -191,7 +192,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
output.Attributes.Add("hello", "world");
output.SelfClosing = true;
output.TagMode = TagMode.SelfClosing;
}
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;
namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers
@ -152,18 +153,19 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers
}
[Theory]
[InlineData("true")]
[InlineData("false")]
public void Begin_SetExecutionContextSelfClosing(bool selfClosing)
[InlineData(TagMode.SelfClosing)]
[InlineData(TagMode.StartTagAndEndTag)]
[InlineData(TagMode.StartTagOnly)]
public void Begin_SetsExecutionContextTagMode(TagMode tagMode)
{
// Arrange
var scopeManager = new TagHelperScopeManager();
// Act
var executionContext = BeginDefaultScope(scopeManager, "p", selfClosing);
var executionContext = BeginDefaultScope(scopeManager, "p", tagMode);
// Assert
Assert.Equal(selfClosing, executionContext.SelfClosing);
Assert.Equal(tagMode, executionContext.TagMode);
}
[Fact]
@ -218,13 +220,13 @@ namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers
}
private static TagHelperExecutionContext BeginDefaultScope(
TagHelperScopeManager scopeManager,
TagHelperScopeManager scopeManager,
string tagName,
bool selfClosing = false)
TagMode tagMode = TagMode.StartTagAndEndTag)
{
return scopeManager.Begin(
tagName,
selfClosing,
tagMode,
uniqueId: string.Empty,
executeChildContentAsync: async () => await Task.FromResult(result: true),
startTagHelperWritingScope: () => { },

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Reflection;
#endif
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;
@ -448,7 +449,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 6,
contentLength: 23),
BuildLineMapping(
documentAbsoluteIndex: 287,
documentAbsoluteIndex: 285,
documentLineIndex: 6,
generatedAbsoluteIndex: 1677,
generatedLineIndex: 49,
@ -462,24 +463,27 @@ namespace Microsoft.AspNet.Razor.Test.Generator
PrefixedPAndInputTagHelperDescriptors,
new List<LineMapping>
{
BuildLineMapping(documentAbsoluteIndex: 17,
documentLineIndex: 0,
generatedAbsoluteIndex: 496,
generatedLineIndex: 15,
characterOffsetIndex: 17,
contentLength: 5),
BuildLineMapping(documentAbsoluteIndex: 38,
documentLineIndex: 1,
generatedAbsoluteIndex: 655,
generatedLineIndex: 22,
characterOffsetIndex: 14,
contentLength: 17),
BuildLineMapping(documentAbsoluteIndex: 228,
documentLineIndex: 7,
generatedAbsoluteIndex: 1480,
generatedLineIndex: 46,
characterOffsetIndex: 43,
contentLength: 4)
BuildLineMapping(
documentAbsoluteIndex: 17,
documentLineIndex: 0,
generatedAbsoluteIndex: 496,
generatedLineIndex: 15,
characterOffsetIndex: 17,
contentLength: 5),
BuildLineMapping(
documentAbsoluteIndex: 38,
documentLineIndex: 1,
generatedAbsoluteIndex: 655,
generatedLineIndex: 22,
characterOffsetIndex: 14,
contentLength: 17),
BuildLineMapping(
documentAbsoluteIndex: 226,
documentLineIndex: 7,
generatedAbsoluteIndex: 1480,
generatedLineIndex: 46,
characterOffsetIndex: 43,
contentLength: 4),
}
},
{
@ -589,7 +593,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 0,
contentLength: 1),
BuildLineMapping(
documentAbsoluteIndex: 645,
documentAbsoluteIndex: 643,
documentLineIndex: 18,
generatedAbsoluteIndex: 3245,
generatedLineIndex: 128,
@ -604,21 +608,21 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 6,
contentLength: 12),
BuildLineMapping(
documentAbsoluteIndex: 771,
documentAbsoluteIndex: 769,
documentLineIndex: 21,
generatedAbsoluteIndex: 3477,
generatedLineIndex: 140,
characterOffsetIndex: 0,
contentLength: 12),
BuildLineMapping(
documentAbsoluteIndex: 785,
documentAbsoluteIndex: 783,
documentLineIndex: 21,
generatedAbsoluteIndex: 3575,
generatedLineIndex: 146,
characterOffsetIndex: 14,
contentLength: 21),
BuildLineMapping(
documentAbsoluteIndex: 839,
documentAbsoluteIndex: 837,
documentLineIndex: 22,
documentCharacterOffsetIndex: 30,
generatedAbsoluteIndex: 3832,
@ -626,7 +630,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 28,
contentLength: 7),
BuildLineMapping(
documentAbsoluteIndex: 713,
documentAbsoluteIndex: 711,
documentLineIndex: 20,
documentCharacterOffsetIndex: 39,
generatedAbsoluteIndex: 4007,
@ -634,7 +638,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 38,
contentLength: 23),
BuildLineMapping(
documentAbsoluteIndex: 736,
documentAbsoluteIndex: 734,
documentLineIndex: 20,
documentCharacterOffsetIndex: 62,
generatedAbsoluteIndex: 4030,
@ -642,7 +646,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 61,
contentLength: 7),
BuildLineMapping(
documentAbsoluteIndex: 981,
documentAbsoluteIndex: 977,
documentLineIndex: 25,
documentCharacterOffsetIndex: 62,
generatedAbsoluteIndex: 4304,
@ -650,7 +654,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 60,
contentLength: 30),
BuildLineMapping(
documentAbsoluteIndex: 883,
documentAbsoluteIndex: 879,
documentLineIndex: 24,
documentCharacterOffsetIndex: 16,
generatedAbsoluteIndex: 4483,
@ -658,7 +662,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 19,
contentLength: 8),
BuildLineMapping(
documentAbsoluteIndex: 892,
documentAbsoluteIndex: 888,
documentLineIndex: 24,
documentCharacterOffsetIndex: 25,
generatedAbsoluteIndex: 4491,
@ -666,14 +670,14 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 27,
contentLength: 23),
BuildLineMapping(
documentAbsoluteIndex: 1110,
documentAbsoluteIndex: 1106,
documentLineIndex: 28,
generatedAbsoluteIndex: 4749,
generatedLineIndex: 180,
characterOffsetIndex: 28,
contentLength: 30),
BuildLineMapping(
documentAbsoluteIndex: 1048,
documentAbsoluteIndex: 1044,
documentLineIndex: 27,
documentCharacterOffsetIndex: 16,
generatedAbsoluteIndex: 4928,
@ -681,14 +685,14 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 19,
contentLength: 30),
BuildLineMapping(
documentAbsoluteIndex: 1240,
documentAbsoluteIndex: 1234,
documentLineIndex: 31,
generatedAbsoluteIndex: 5193,
generatedLineIndex: 193,
characterOffsetIndex: 28,
contentLength: 3),
BuildLineMapping(
documentAbsoluteIndex: 1245,
documentAbsoluteIndex: 1239,
documentLineIndex: 31,
documentCharacterOffsetIndex: 33,
generatedAbsoluteIndex: 5196,
@ -696,7 +700,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 31,
contentLength: 27),
BuildLineMapping(
documentAbsoluteIndex: 1273,
documentAbsoluteIndex: 1267,
documentLineIndex: 31,
documentCharacterOffsetIndex: 61,
generatedAbsoluteIndex: 5223,
@ -704,7 +708,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 58,
contentLength: 10),
BuildLineMapping(
documentAbsoluteIndex: 1178,
documentAbsoluteIndex: 1172,
documentLineIndex: 30,
documentCharacterOffsetIndex: 18,
generatedAbsoluteIndex: 5382,
@ -712,7 +716,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
generatedCharacterOffsetIndex: 19,
contentLength: 29),
BuildLineMapping(
documentAbsoluteIndex: 1315,
documentAbsoluteIndex: 1309,
documentLineIndex: 34,
generatedAbsoluteIndex: 5482,
generatedLineIndex: 204,
@ -1344,6 +1348,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
new TagHelperAttributeDescriptor("age", pAgePropertyInfo)
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.NormalOrSelfClosing,
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix,
@ -1355,6 +1360,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo)
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix,
@ -1367,6 +1373,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
new TagHelperAttributeDescriptor("checked", checkedPropertyInfo)
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.Unspecified,
designTimeDescriptor: null)
};
}

View File

@ -6,6 +6,7 @@ using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Parser.TagHelpers;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;
@ -169,14 +170,14 @@ namespace Microsoft.AspNet.Razor.Test.Generator
{
return new TagHelperChunk(
tagName,
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, Chunk>>(),
descriptors: tagHelperDescriptors)
{
Association = new TagHelperBlock(
new TagHelperBlockBuilder(
tagName,
selfClosing: false,
tagMode: TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>(),
children: Enumerable.Empty<SyntaxTreeNode>())),
Children = new List<Chunk>(),

View File

@ -7,6 +7,7 @@ using System.Reflection;
#endif
using Microsoft.AspNet.Razor.CodeGenerators;
using Microsoft.AspNet.Razor.CodeGenerators.Visitors;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;
@ -23,21 +24,27 @@ namespace Microsoft.AspNet.Razor.Test.Generator
var tagHelperDescriptors = new TagHelperDescriptor[]
{
new TagHelperDescriptor("p", "PTagHelper", "SomeAssembly"),
new TagHelperDescriptor("input",
"InputTagHelper",
"SomeAssembly",
new TagHelperAttributeDescriptor[]
{
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo)
}),
new TagHelperDescriptor("input",
"InputTagHelper2",
"SomeAssembly",
new TagHelperAttributeDescriptor[]
{
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo),
new TagHelperAttributeDescriptor("checked", checkedPropertyInfo)
})
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[]
{
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo)
},
requiredAttributes: new string[0],
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null),
new TagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper2",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[]
{
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo),
new TagHelperAttributeDescriptor("checked", checkedPropertyInfo)
})
};
// Act & Assert

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Parser.TagHelpers;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
namespace Microsoft.AspNet.Razor.Test.Framework
{
@ -156,41 +157,41 @@ namespace Microsoft.AspNet.Razor.Test.Framework
public class MarkupTagHelperBlock : TagHelperBlock
{
public MarkupTagHelperBlock(string tagName)
: this(tagName, selfClosing: false, attributes: new List<KeyValuePair<string, SyntaxTreeNode>>())
: this(tagName, tagMode: TagMode.StartTagAndEndTag, attributes: new List<KeyValuePair<string, SyntaxTreeNode>>())
{
}
public MarkupTagHelperBlock(string tagName, bool selfClosing)
: this(tagName, selfClosing, new List<KeyValuePair<string, SyntaxTreeNode>>())
public MarkupTagHelperBlock(string tagName, TagMode tagMode)
: this(tagName, tagMode, new List<KeyValuePair<string, SyntaxTreeNode>>())
{
}
public MarkupTagHelperBlock(
string tagName,
IList<KeyValuePair<string, SyntaxTreeNode>> attributes)
: this(tagName, selfClosing: false, attributes: attributes, children: new SyntaxTreeNode[0])
: this(tagName, TagMode.StartTagAndEndTag, attributes, children: new SyntaxTreeNode[0])
{
}
public MarkupTagHelperBlock(
string tagName,
bool selfClosing,
TagMode tagMode,
IList<KeyValuePair<string, SyntaxTreeNode>> attributes)
: this(tagName, selfClosing, attributes, new SyntaxTreeNode[0])
: this(tagName, tagMode, attributes, new SyntaxTreeNode[0])
{
}
public MarkupTagHelperBlock(string tagName, params SyntaxTreeNode[] children)
: this(
tagName,
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>(),
children: children)
{
}
public MarkupTagHelperBlock(string tagName, bool selfClosing, params SyntaxTreeNode[] children)
: this(tagName, selfClosing, new List<KeyValuePair<string, SyntaxTreeNode>>(), children)
public MarkupTagHelperBlock(string tagName, TagMode tagMode, params SyntaxTreeNode[] children)
: this(tagName, tagMode, new List<KeyValuePair<string, SyntaxTreeNode>>(), children)
{
}
@ -198,16 +199,20 @@ namespace Microsoft.AspNet.Razor.Test.Framework
string tagName,
IList<KeyValuePair<string, SyntaxTreeNode>> attributes,
params SyntaxTreeNode[] children)
: base(new TagHelperBlockBuilder(tagName, selfClosing: false, attributes: attributes, children: children))
: base(new TagHelperBlockBuilder(
tagName,
TagMode.StartTagAndEndTag,
attributes: attributes,
children: children))
{
}
public MarkupTagHelperBlock(
string tagName,
bool selfClosing,
TagMode tagMode,
IList<KeyValuePair<string, SyntaxTreeNode>> attributes,
params SyntaxTreeNode[] children)
: base(new TagHelperBlockBuilder(tagName, selfClosing, attributes, children))
: base(new TagHelperBlockBuilder(tagName, tagMode, attributes, children))
{
}
}

View File

@ -10,6 +10,7 @@ using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Parser.TagHelpers;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.Text;
using Xunit;
@ -411,13 +412,11 @@ namespace Microsoft.AspNet.Razor.Test.Framework
actual.TagName);
}
if (expected.SelfClosing != actual.SelfClosing)
if (expected.TagMode != actual.TagMode)
{
collector.AddError(
"{0} - FAILED :: SelfClosing for TagHelperBlock {1} :: ACTUAL: {2}",
expected.SelfClosing,
actual.TagName,
actual.SelfClosing);
$"{expected.TagMode} - FAILED :: {nameof(TagMode)} for {nameof(TagHelperBlock)} " +
$"{actual.TagName} :: ACTUAL: {actual.TagMode}");
}
var expectedAttributes = expected.Attributes.GetEnumerator();

View File

@ -8,6 +8,7 @@ using System.Linq;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.Test.Framework;
using Microsoft.AspNet.Razor.Test.TagHelpers;
using Microsoft.AspNet.Razor.Text;
@ -17,6 +18,195 @@ namespace Microsoft.AspNet.Razor.TagHelpers
{
public class TagHelperBlockRewriterTest : TagHelperRewritingTestBase
{
public static TheoryData WithoutEndTagElementData
{
get
{
var factory = CreateDefaultSpanFactory();
var blockFactory = new BlockFactory(factory);
// documentContent, expectedOutput
return new TheoryData<string, MarkupBlock>
{
{
"<input>",
new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
},
{
"<input type='text'>",
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
TagMode.StartTagOnly,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("type", factory.Markup("text"))
}))
},
{
"<input><input>",
new MarkupBlock(
new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
},
{
"<input type='text'><input>",
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
TagMode.StartTagOnly,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("type", factory.Markup("text"))
}),
new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
},
{
"<div><input><input></div>",
new MarkupBlock(
blockFactory.MarkupTagBlock("<div>"),
new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
blockFactory.MarkupTagBlock("</div>"))
},
};
}
}
[Theory]
[MemberData(nameof(WithoutEndTagElementData))]
public void Rewrite_CanHandleWithoutEndTagTagStructure(string documentContent, MarkupBlock expectedOutput)
{
// Arrange
var descriptors = new TagHelperDescriptor[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[0],
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null)
};
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
// Act & Assert
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]);
}
public static TheoryData TagStructureCompatibilityData
{
get
{
var factory = CreateDefaultSpanFactory();
var blockFactory = new BlockFactory(factory);
// documentContent, structure1, structure2, expectedOutput
return new TheoryData<string, TagStructure, TagStructure, MarkupBlock>
{
{
"<input></input>",
TagStructure.Unspecified,
TagStructure.Unspecified,
new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagAndEndTag))
},
{
"<input />",
TagStructure.Unspecified,
TagStructure.Unspecified,
new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.SelfClosing))
},
{
"<input type='text'>",
TagStructure.Unspecified,
TagStructure.WithoutEndTag,
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
TagMode.StartTagOnly,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("type", factory.Markup("text"))
}))
},
{
"<input><input>",
TagStructure.WithoutEndTag,
TagStructure.WithoutEndTag,
new MarkupBlock(
new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
},
{
"<input type='text'></input>",
TagStructure.Unspecified,
TagStructure.NormalOrSelfClosing,
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("type", factory.Markup("text"))
}))
},
{
"<input />",
TagStructure.Unspecified,
TagStructure.WithoutEndTag,
new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.SelfClosing))
},
{
"<input />",
TagStructure.NormalOrSelfClosing,
TagStructure.Unspecified,
new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.SelfClosing))
},
};
}
}
[Theory]
[MemberData(nameof(TagStructureCompatibilityData))]
public void Rewrite_AllowsCompatibleTagStructures(
string documentContent,
TagStructure structure1,
TagStructure structure2,
MarkupBlock expectedOutput)
{
// Arrange
var factory = CreateDefaultSpanFactory();
var blockFactory = new BlockFactory(factory);
var descriptors = new TagHelperDescriptor[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper1",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[0],
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: structure1,
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper2",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[0],
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: structure2,
designTimeDescriptor: null)
};
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
// Act & Assert
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]);
}
public static TheoryData<string, MarkupBlock, RazorError[]> MalformedTagHelperAttributeBlockData
{
get
@ -574,7 +764,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person age=\"12\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("age", factory.CodeMarkup("12"))
@ -584,7 +774,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person birthday=\"DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -596,7 +786,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person name=\"John\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("name", factory.Markup("John"))
@ -606,7 +796,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person name=\"Time: @DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -618,7 +808,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person age=\"1 + @value + 2\" birthday='(bool)@Bag[\"val\"] ? @@DateTime : @DateTime.Now'/>",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -670,7 +860,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("age", factory.CodeMarkup("12")),
@ -686,7 +876,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @@ @DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("age", factory.CodeMarkup("12")),
@ -709,7 +899,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person age=\"12\" birthday=\"DateTime.Now\" name=\"@@BoundStringAttribute\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("age", factory.CodeMarkup("12")),
@ -731,7 +921,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<person age=\"@@@(11+1)\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />",
new MarkupBlock(
new MarkupTagHelperBlock("person",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -1324,7 +1514,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<<p />",
new MarkupBlock(
blockFactory.MarkupTagBlock("<"),
new MarkupTagHelperBlock("p", selfClosing: true))
new MarkupTagHelperBlock("p", TagMode.SelfClosing))
},
{
"< p />",
@ -1339,7 +1529,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<input <p />",
new MarkupBlock(
blockFactory.MarkupTagBlock("<input "),
new MarkupTagHelperBlock("p", selfClosing: true))
new MarkupTagHelperBlock("p", TagMode.SelfClosing))
},
{
"< class=\"foo\" <p />",
@ -1357,7 +1547,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
value: new LocationTagged<string>("foo", 9, 0, 9))),
factory.Markup("\"").With(SpanChunkGenerator.Null)),
factory.Markup(" ")),
new MarkupTagHelperBlock("p", selfClosing: true))
new MarkupTagHelperBlock("p", TagMode.SelfClosing))
},
{
"</<<p>/></p>>",
@ -1468,7 +1658,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<p class1='' class2= class3=\"\" />",
new MarkupBlock(
new MarkupTagHelperBlock("p",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class1", new MarkupBlock()),
@ -1482,7 +1672,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<p class1=''class2=\"\"class3= />",
new MarkupBlock(
new MarkupTagHelperBlock("p",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class1", new MarkupBlock()),
@ -1521,7 +1711,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("bound", new MarkupBlock())
@ -1538,7 +1728,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("bound", factory.CodeMarkup(" true"))
@ -1550,7 +1740,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("bound", factory.CodeMarkup(" "))
@ -1567,7 +1757,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("bound", new MarkupBlock()),
@ -1588,7 +1778,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("bound", factory.CodeMarkup(" ")),
@ -1609,7 +1799,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("bound", factory.CodeMarkup("true")),
@ -1629,7 +1819,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -1649,7 +1839,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -1669,7 +1859,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("bound", factory.CodeMarkup("true")),
@ -1693,7 +1883,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("BouND", new MarkupBlock())
@ -1710,7 +1900,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("BOUND", new MarkupBlock()),
@ -1750,7 +1940,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
{
@ -1774,7 +1964,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"myth",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
{
@ -1883,7 +2073,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<script class=\"foo\" style=\"color:red;\" />",
new MarkupBlock(
new MarkupTagHelperBlock("script",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("foo")),
@ -1947,7 +2137,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"<p class=\"foo\" style=\"color:red;\" />",
new MarkupBlock(
new MarkupTagHelperBlock("p",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("foo")),
@ -1960,13 +2150,13 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
children: new SyntaxTreeNode[]
{
factory.Markup("Hello "),
new MarkupTagHelperBlock(
"p",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("foo")),
@ -1983,14 +2173,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
factory.Markup("Hello"),
new MarkupTagHelperBlock("p",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("foo"))
}),
factory.Markup(" "),
new MarkupTagHelperBlock("p",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("style", factory.Markup("color:red;"))
@ -2287,7 +2477,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -2300,7 +2490,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("data-required", factory.Markup("value")),
@ -2311,7 +2501,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -2324,7 +2514,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -2337,7 +2527,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -2353,7 +2543,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("pre-attribute", value: null),
@ -2371,7 +2561,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>(
@ -2469,7 +2659,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("unbound-required", null),
@ -2481,7 +2671,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-string", null),
@ -2497,7 +2687,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-string", null),
@ -2513,7 +2703,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-int", null),
@ -2529,7 +2719,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),
@ -2541,7 +2731,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("int-dictionary", null),
@ -2561,7 +2751,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("string-dictionary", null),
@ -2581,7 +2771,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("int-prefix-", null),
@ -2607,7 +2797,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("string-prefix-", null),
@ -2633,7 +2823,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("int-prefix-value", null),
@ -2653,7 +2843,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("string-prefix-value", null),
@ -2673,7 +2863,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("int-prefix-value", new MarkupBlock()),
@ -2693,7 +2883,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("string-prefix-value", new MarkupBlock()),
@ -2705,7 +2895,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("int-prefix-value", factory.CodeMarkup("3")),
@ -2717,7 +2907,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("string-prefix-value", new MarkupBlock(
@ -2731,7 +2921,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("unbound-required", null),
@ -2752,7 +2942,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),
@ -2769,7 +2959,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-int", null),
@ -2793,7 +2983,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),
@ -2812,7 +3002,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("unbound-required", null),
@ -2825,7 +3015,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-string", null),
@ -2846,7 +3036,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn")),
@ -2859,7 +3049,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn")),
@ -2880,7 +3070,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-string", null),
@ -2901,7 +3091,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn")),
@ -2922,7 +3112,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-int", null),
@ -2939,7 +3129,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),
@ -2955,7 +3145,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn")),
@ -2971,7 +3161,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn")),
@ -2987,7 +3177,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("class", expression(14)),
@ -3004,7 +3194,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("class", expression(10)),
@ -3021,7 +3211,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: true,
TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-int", null),
@ -3048,7 +3238,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),
@ -3202,7 +3392,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("unbound-required", null),
@ -3218,7 +3408,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-string", null),
@ -3240,7 +3430,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-int", null),
@ -3262,7 +3452,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-int", null),
@ -3292,7 +3482,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-string", null),
@ -3310,7 +3500,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),
@ -3327,7 +3517,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),
@ -3347,7 +3537,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"input",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-required-int", null),
@ -3356,7 +3546,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
},
children: new MarkupTagHelperBlock(
"p",
selfClosing: false,
TagMode.StartTagAndEndTag,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()
{
new KeyValuePair<string, SyntaxTreeNode>("bound-int", null),

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Xunit;
namespace Microsoft.AspNet.Razor.TagHelpers
@ -321,6 +322,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
}
}

View File

@ -3,6 +3,7 @@
using System;
using System.Linq;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.Test.Internal;
using Newtonsoft.Json;
using Xunit;
@ -22,6 +23,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: "assembly name",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: new[] { "required attribute one", "required attribute two" },
tagStructure: TagStructure.Unspecified,
designTimeDescriptor: new TagHelperDesignTimeDescriptor("usage summary", "usage remarks", "some-tag"));
var expectedSerializedDescriptor =
@ -33,6 +35,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperDescriptor.Attributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":" +
"[\"required attribute one\",\"required attribute two\"]," +
$"\"{ nameof(TagHelperDescriptor.TagStructure) }\":0," +
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{"+
$"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," +
$"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," +
@ -70,6 +73,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.NormalOrSelfClosing,
designTimeDescriptor: null);
var expectedSerializedDescriptor =
$"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," +
@ -91,6 +95,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.TagStructure) }\":1," +
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
// Act
@ -125,6 +130,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null);
var expectedSerializedDescriptor =
$"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," +
@ -146,6 +152,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{ nameof(TagHelperDescriptor.TagStructure) }\":0," +
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
// Act
@ -168,6 +175,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{nameof(TagHelperDescriptor.Attributes)}\":[]," +
$"\"{nameof(TagHelperDescriptor.RequiredAttributes)}\":" +
"[\"required attribute one\",\"required attribute two\"]," +
$"\"{nameof(TagHelperDescriptor.TagStructure)}\":2," +
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{" +
$"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," +
$"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," +
@ -179,6 +187,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
assemblyName: "assembly name",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: new[] { "required attribute one", "required attribute two" },
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: new TagHelperDesignTimeDescriptor("usage summary", "usage remarks", "some-tag"));
// Act
@ -223,6 +232,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{nameof(TagHelperDescriptor.TagStructure)}\":0," +
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
var expectedDescriptor = new TagHelperDescriptor(
prefix: "prefix:",
@ -245,6 +255,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.Unspecified,
designTimeDescriptor: null);
// Act
@ -310,6 +321,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
$"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," +
$"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," +
$"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," +
$"\"{nameof(TagHelperDescriptor.TagStructure)}\":1," +
$"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";
var expectedDescriptor = new TagHelperDescriptor(
prefix: "prefix:",
@ -332,6 +344,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.NormalOrSelfClosing,
designTimeDescriptor: null);
// Act

View File

@ -8,6 +8,7 @@ using System.Linq;
using Microsoft.AspNet.Razor.Chunks.Generators;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.AspNet.Razor.Test.Framework;
using Microsoft.AspNet.Razor.Text;
@ -17,6 +18,110 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
{
public class TagHelperParseTreeRewriterTest : TagHelperRewritingTestBase
{
[Fact]
public void Rewrite_CanHandleStartTagOnlyTagTagMode()
{
// Arrange
var documentContent = "<input>";
var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly));
var descriptors = new TagHelperDescriptor[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[0],
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null)
};
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
// Act & Assert
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]);
}
[Fact]
public void Rewrite_CreatesErrorForWithoutEndTagTagStructureForEndTags()
{
// Arrange
var factory = CreateDefaultSpanFactory();
var blockFactory = new BlockFactory(factory);
var expectedError = new RazorError(
RazorResources.FormatTagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag(
"input",
"InputTagHelper",
TagStructure.WithoutEndTag),
absoluteIndex: 0,
lineIndex: 0,
columnIndex: 0,
length: 8);
var documentContent = "</input>";
var expectedOutput = new MarkupBlock(blockFactory.MarkupTagBlock("</input>"));
var descriptors = new TagHelperDescriptor[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[0],
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null)
};
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
// Act & Assert
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new[] { expectedError });
}
[Fact]
public void Rewrite_CreatesErrorForInconsistentTagStructures()
{
// Arrange
var factory = CreateDefaultSpanFactory();
var blockFactory = new BlockFactory(factory);
var expectedError = new RazorError(
RazorResources.FormatTagHelperParseTreeRewriter_InconsistentTagStructure(
"InputTagHelper1",
"InputTagHelper2",
"input",
nameof(TagHelperDescriptor.TagStructure)),
absoluteIndex: 0,
lineIndex: 0,
columnIndex: 0,
length: 7);
var documentContent = "<input>";
var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly));
var descriptors = new TagHelperDescriptor[]
{
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper1",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[0],
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.WithoutEndTag,
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: string.Empty,
tagName: "input",
typeName: "InputTagHelper2",
assemblyName: "SomeAssembly",
attributes: new TagHelperAttributeDescriptor[0],
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: TagStructure.NormalOrSelfClosing,
designTimeDescriptor: null)
};
var descriptorProvider = new TagHelperDescriptorProvider(descriptors);
// Act & Assert
EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new[] { expectedError });
}
public static TheoryData RequiredAttributeData
{
get
@ -65,7 +170,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn"))
@ -76,7 +181,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", dateTimeNow(10))
@ -127,7 +232,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"strong",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("catchAll", factory.Markup("hi"))
@ -138,7 +243,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"strong",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("catchAll", dateTimeNow(18))
@ -208,7 +313,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("notRequired", factory.Markup("a")),
@ -220,7 +325,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("notRequired", dateTimeNow(16)),
@ -244,7 +349,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"div",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("style", new MarkupBlock()),
@ -256,7 +361,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"div",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("style", dateTimeNow(12)),
@ -311,7 +416,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"p",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn")),
@ -335,7 +440,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"div",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("style", new MarkupBlock()),
@ -917,6 +1022,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: "th:",
@ -933,6 +1039,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null)
};
var availableDescriptorsText = new TagHelperDescriptor[]
@ -944,6 +1051,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null),
new TagHelperDescriptor(
prefix: "PREFIX",
@ -960,6 +1068,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
designTimeDescriptor: null),
},
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null)
};
var availableDescriptorsCatchAll = new TagHelperDescriptor[]
@ -971,6 +1080,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
assemblyName: "SomeAssembly",
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
requiredAttributes: Enumerable.Empty<string>(),
tagStructure: default(TagStructure),
designTimeDescriptor: null),
};
@ -993,13 +1103,13 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
{
"<th:myth />",
new MarkupBlock(
new MarkupTagHelperBlock("th:myth", selfClosing: true)),
new MarkupTagHelperBlock("th:myth", tagMode: TagMode.SelfClosing)),
availableDescriptorsColon
},
{
"<PREFIXmyth />",
new MarkupBlock(
new MarkupTagHelperBlock("PREFIXmyth", selfClosing: true)),
new MarkupTagHelperBlock("PREFIXmyth", tagMode: TagMode.SelfClosing)),
availableDescriptorsText
},
{
@ -1063,7 +1173,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"th:myth",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn"))
@ -1075,7 +1185,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"PREFIXmyth",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn"))
@ -1087,7 +1197,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"th:myth2",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn"))
@ -1099,7 +1209,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"PREFIXmyth2",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
new KeyValuePair<string, SyntaxTreeNode>("class", factory.Markup("btn"))
@ -1135,7 +1245,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"th:myth2",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
{
@ -1157,7 +1267,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"PREFIXmyth2",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
{
@ -1179,7 +1289,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupTagHelperBlock(
"PREFIXmyth2",
selfClosing: true,
tagMode: TagMode.SelfClosing,
attributes: new List<KeyValuePair<string, SyntaxTreeNode>>
{
{

View File

@ -30,11 +30,11 @@ namespace TestOutput
Instrumentation.BeginContext(30, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(47, 9, true);
WriteLiteral("\r\n <p>");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("strong", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("strong", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(78, 5, true);
WriteLiteral("Hello");
Instrumentation.EndContext();
@ -51,7 +51,7 @@ namespace TestOutput
Instrumentation.BeginContext(92, 62, true);
WriteLiteral("<strong>World</strong></p>\r\n <input checked=\"true\" />\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -75,7 +75,7 @@ namespace TestOutput
Instrumentation.BeginContext(194, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -1,4 +1,4 @@
#pragma checksum "BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d83a512ddca8f28897c27630e252991c84555533"
#pragma checksum "BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3cdbdfa1515b87565e2f00812f0093dbe8e49667"
namespace TestOutput
{
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
@ -28,11 +28,11 @@ namespace TestOutput
Instrumentation.BeginContext(33, 71, true);
WriteLiteral("\r\n<div data-animation=\"fade\" class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(145, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__PTagHelper = CreateTagHelper<PTagHelper>();
@ -45,7 +45,7 @@ namespace TestOutput
Instrumentation.BeginContext(162, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.StartTagOnly, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -66,14 +66,14 @@ Write(ViewBag.DefaultInterval);
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
__InputTagHelper2.Type = __InputTagHelper.Type;
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(172, 73, false);
Instrumentation.BeginContext(172, 71, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(245, 10, true);
Instrumentation.BeginContext(243, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -90,11 +90,11 @@ Write(ViewBag.DefaultInterval);
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(255, 39, false);
Instrumentation.BeginContext(253, 39, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(294, 6, true);
Instrumentation.BeginContext(292, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
}
@ -104,11 +104,11 @@ Write(ViewBag.DefaultInterval);
__tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw("Hello World"));
__tagHelperExecutionContext.AddHtmlAttribute("data-delay", Html.Raw("1000"));
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(104, 200, false);
Instrumentation.BeginContext(104, 198, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(304, 8, true);
Instrumentation.BeginContext(302, 8, true);
WriteLiteral("\r\n</div>");
Instrumentation.EndContext();
}

View File

@ -1,4 +1,4 @@
#pragma checksum "BasicTagHelpers.Prefixed.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "da1aeb71c15bd7443662536f58df99382b0a47f2"
#pragma checksum "BasicTagHelpers.Prefixed.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "44eafd8ba2adb5f9e260d37e87544c018e182eed"
namespace TestOutput
{
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
@ -29,11 +29,11 @@ namespace TestOutput
Instrumentation.BeginContext(57, 52, true);
WriteLiteral("\r\n<THSdiv class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
Instrumentation.BeginContext(135, 58, true);
WriteLiteral("\r\n <p></p>\r\n <input type=\"text\" />\r\n ");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(135, 56, true);
WriteLiteral("\r\n <p></p>\r\n <input type=\"text\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.StartTagOnly, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -50,11 +50,11 @@ namespace TestOutput
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(193, 43, false);
Instrumentation.BeginContext(191, 41, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(236, 6, true);
Instrumentation.BeginContext(232, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
}
@ -63,11 +63,11 @@ namespace TestOutput
__tagHelperExecutionContext.Add(__PTagHelper);
__tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw("Hello World"));
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(109, 140, false);
Instrumentation.BeginContext(109, 136, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(249, 11, true);
Instrumentation.BeginContext(245, 11, true);
WriteLiteral("\r\n</THSdiv>");
Instrumentation.EndContext();
}

View File

@ -1,4 +1,4 @@
#pragma checksum "BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d83a512ddca8f28897c27630e252991c84555533"
#pragma checksum "BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3cdbdfa1515b87565e2f00812f0093dbe8e49667"
namespace TestOutput
{
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
@ -29,11 +29,11 @@ namespace TestOutput
Instrumentation.BeginContext(33, 71, true);
WriteLiteral("\r\n<div data-animation=\"fade\" class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(145, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__PTagHelper = CreateTagHelper<PTagHelper>();
@ -46,7 +46,7 @@ namespace TestOutput
Instrumentation.BeginContext(162, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.StartTagOnly, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -67,14 +67,14 @@ Write(ViewBag.DefaultInterval);
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
__InputTagHelper2.Type = __InputTagHelper.Type;
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(172, 73, false);
Instrumentation.BeginContext(172, 71, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(245, 10, true);
Instrumentation.BeginContext(243, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -91,11 +91,11 @@ Write(ViewBag.DefaultInterval);
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(255, 39, false);
Instrumentation.BeginContext(253, 39, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(294, 6, true);
Instrumentation.BeginContext(292, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
}
@ -105,11 +105,11 @@ Write(ViewBag.DefaultInterval);
__tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw("Hello World"));
__tagHelperExecutionContext.AddHtmlAttribute("data-delay", Html.Raw("1000"));
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(104, 200, false);
Instrumentation.BeginContext(104, 198, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(304, 8, true);
Instrumentation.BeginContext(302, 8, true);
WriteLiteral("\r\n</div>");
Instrumentation.EndContext();
}

View File

@ -1,4 +1,4 @@
#pragma checksum "ComplexTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "ece1d34a29b5cfd4b3ed96c16b3546e5a44eb260"
#pragma checksum "ComplexTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "29efbebdd0277d2835528479690b48268c1dc03b"
namespace TestOutput
{
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
@ -41,7 +41,7 @@ namespace TestOutput
Instrumentation.BeginContext(84, 55, true);
WriteLiteral(" <div class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(177, 34, true);
WriteLiteral("\r\n <h1>Set Time:</h1>\r\n");
Instrumentation.EndContext();
@ -61,11 +61,11 @@ namespace TestOutput
Instrumentation.BeginContext(251, 16, true);
WriteLiteral(" ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(270, 10, true);
WriteLiteral("New Time: ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -105,11 +105,11 @@ namespace TestOutput
Instrumentation.BeginContext(400, 16, true);
WriteLiteral(" ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(419, 14, true);
WriteLiteral("Current Time: ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -149,7 +149,7 @@ WriteLiteral(checkbox);
Instrumentation.BeginContext(474, 18, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -174,7 +174,7 @@ WriteLiteral(true ? "checkbox" : "anything");
Instrumentation.BeginContext(542, 18, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.StartTagOnly, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -219,11 +219,11 @@ if(true) {
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
__InputTagHelper2.Type = __InputTagHelper.Type;
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(560, 81, false);
Instrumentation.BeginContext(560, 79, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(643, 2, true);
Instrumentation.BeginContext(641, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
#line 19 "ComplexTagHelpers.cshtml"
@ -232,7 +232,7 @@ if(true) {
#line default
#line hidden
Instrumentation.BeginContext(660, 8, true);
Instrumentation.BeginContext(658, 8, true);
WriteLiteral(" ");
Instrumentation.EndContext();
}
@ -242,15 +242,15 @@ if(true) {
AddHtmlAttributeValues("time", __tagHelperExecutionContext, Tuple.Create(Tuple.Create("", 148), Tuple.Create("Current", 148), true), Tuple.Create(Tuple.Create(" ", 155), Tuple.Create("Time:", 156), true),
Tuple.Create(Tuple.Create(" ", 161), Tuple.Create<System.Object, System.Int32>(DateTime.Now, 162), false));
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(139, 531, false);
Instrumentation.BeginContext(139, 529, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(672, 10, true);
Instrumentation.BeginContext(670, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
Instrumentation.BeginContext(769, 2, true);
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(767, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
#line 22 "ComplexTagHelpers.cshtml"
@ -265,10 +265,10 @@ if(true) {
#line default
#line hidden
Instrumentation.BeginContext(807, 14, true);
Instrumentation.BeginContext(805, 14, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.StartTagOnly, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -282,11 +282,11 @@ __InputTagHelper2.Checked = @object;
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("ChecKED", __InputTagHelper2.Checked);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(821, 30, false);
Instrumentation.BeginContext(819, 28, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(851, 10, true);
Instrumentation.BeginContext(847, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
}
@ -302,18 +302,18 @@ __InputTagHelper2.Checked = @object;
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
__tagHelperExecutionContext.AddHtmlAttribute("unbound", Html.Raw("second value"));
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(682, 183, false);
Instrumentation.BeginContext(680, 181, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(865, 10, true);
Instrumentation.BeginContext(861, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
Instrumentation.BeginContext(917, 14, true);
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(913, 14, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -329,11 +329,11 @@ __InputTagHelper2.Checked = @object;
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(931, 85, false);
Instrumentation.BeginContext(927, 85, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(1016, 10, true);
Instrumentation.BeginContext(1012, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
}
@ -347,18 +347,18 @@ __PTagHelper.Age = -1970 + DateTimeOffset.Now.Year;
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(875, 155, false);
Instrumentation.BeginContext(871, 155, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(1030, 10, true);
Instrumentation.BeginContext(1026, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
Instrumentation.BeginContext(1080, 14, true);
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(1076, 14, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.StartTagOnly, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -372,11 +372,11 @@ __InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014;
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(1094, 50, false);
Instrumentation.BeginContext(1090, 48, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(1144, 10, true);
Instrumentation.BeginContext(1138, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
}
@ -390,18 +390,18 @@ __PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(1040, 118, false);
Instrumentation.BeginContext(1036, 116, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(1158, 10, true);
Instrumentation.BeginContext(1152, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
Instrumentation.BeginContext(1210, 14, true);
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(1204, 14, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -415,11 +415,11 @@ __InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014 ;
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(1224, 63, false);
Instrumentation.BeginContext(1218, 63, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(1287, 10, true);
Instrumentation.BeginContext(1281, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
}
@ -433,11 +433,11 @@ __PTagHelper.Age = "My age is this long.".Length;
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(1168, 133, false);
Instrumentation.BeginContext(1162, 133, false);
await WriteTagHelperAsync(__tagHelperExecutionContext);
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.End();
Instrumentation.BeginContext(1301, 14, true);
Instrumentation.BeginContext(1295, 14, true);
WriteLiteral("\r\n </div>\r\n");
Instrumentation.EndContext();
#line 35 "ComplexTagHelpers.cshtml"

View File

@ -29,11 +29,11 @@ namespace TestOutput
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(65, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -52,7 +52,7 @@ namespace TestOutput
Instrumentation.BeginContext(110, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -28,7 +28,7 @@ namespace TestOutput
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -27,7 +27,7 @@ namespace TestOutput
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -42,7 +42,7 @@ namespace TestOutput
Instrumentation.BeginContext(75, 4, true);
WriteLiteral("\r\n\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -91,7 +91,7 @@ WriteTo(__razor_attribute_value_writer, false);
Instrumentation.BeginContext(150, 4, true);
WriteLiteral("\r\n\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -117,7 +117,7 @@ WriteLiteral(DateTime.Now);
Instrumentation.BeginContext(237, 4, true);
WriteLiteral("\r\n\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -212,7 +212,7 @@ WriteTo(__razor_attribute_value_writer, false);
Instrumentation.BeginContext(424, 4, true);
WriteLiteral("\r\n\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -229,7 +229,7 @@ WriteTo(__razor_attribute_value_writer, false);
Instrumentation.BeginContext(508, 4, true);
WriteLiteral("\r\n\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -29,7 +29,7 @@ namespace TestOutput
Instrumentation.BeginContext(27, 13, true);
WriteLiteral("\r\n<div>\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -54,11 +54,11 @@ __InputTagHelper2.Checked = ;
Instrumentation.BeginContext(74, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(90, 10, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -38,7 +38,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", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -28,11 +28,11 @@ namespace TestOutput
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(64, 34, true);
WriteLiteral("\r\n <input nottaghelper />\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__CatchAllTagHelper = CreateTagHelper<CatchAllTagHelper>();
@ -47,7 +47,7 @@ namespace TestOutput
Instrumentation.BeginContext(157, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -67,7 +67,7 @@ namespace TestOutput
Instrumentation.BeginContext(282, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
@ -89,7 +89,7 @@ namespace TestOutput
Instrumentation.BeginContext(464, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper = CreateTagHelper<InputTagHelper>();

View File

@ -46,7 +46,7 @@ namespace TestOutput
Instrumentation.BeginContext(280, 51, true);
WriteLiteral("\r\n\r\n<div class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
@ -76,7 +76,7 @@ namespace TestOutput
Instrumentation.BeginContext(423, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
@ -121,7 +121,7 @@ namespace TestOutput
Instrumentation.BeginContext(532, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
@ -193,7 +193,7 @@ WriteLiteral(literate);
Instrumentation.BeginContext(795, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();

View File

@ -46,7 +46,7 @@ namespace TestOutput
Instrumentation.BeginContext(280, 51, true);
WriteLiteral("\r\n\r\n<div class=\"randomNonTagHelperAttribute\">\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper1 = CreateTagHelper<InputTagHelper1>();
@ -76,7 +76,7 @@ namespace TestOutput
Instrumentation.BeginContext(423, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper1 = CreateTagHelper<InputTagHelper1>();
@ -121,7 +121,7 @@ namespace TestOutput
Instrumentation.BeginContext(532, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper1 = CreateTagHelper<InputTagHelper1>();
@ -193,7 +193,7 @@ WriteLiteral(literate);
Instrumentation.BeginContext(795, 6, true);
WriteLiteral("\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", true, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.SelfClosing, "test", async() => {
}
, StartTagHelperWritingScope, EndTagHelperWritingScope);
__InputTagHelper1 = CreateTagHelper<InputTagHelper1>();

View File

@ -27,7 +27,7 @@ namespace TestOutput
Instrumentation.BeginContext(33, 2, true);
WriteLiteral("\r\n");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(69, 11, true);
WriteLiteral("Body of Tag");
Instrumentation.EndContext();

View File

@ -42,11 +42,11 @@ namespace TestOutput
Instrumentation.BeginContext(93, 21, true);
WriteLiteralTo(__razor_template_writer, "\r\n <div>\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(217, 52, true);
WriteLiteral("\r\n In None ContentBehavior.\r\n ");
Instrumentation.EndContext();
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", false, "test", async() => {
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", TagMode.StartTagAndEndTag, "test", async() => {
Instrumentation.BeginContext(286, 26, true);
WriteLiteral("Some buffered values with ");
Instrumentation.EndContext();

View File

@ -4,7 +4,7 @@
<THSdiv class="randomNonTagHelperAttribute">
<THSp class="Hello World">
<p></p>
<input type="text" />
<THSinput type="checkbox" checked="true" />
<input type="text">
<THSinput type="checkbox" checked="true">
</THSp>
</THSdiv>

View File

@ -3,7 +3,7 @@
<div data-animation="fade" class="randomNonTagHelperAttribute">
<p class="Hello World" data-delay="1000">
<p></p>
<input data-interval="2000 + @ViewBag.DefaultInterval + 1" type="text" />
<input data-interval="2000 + @ViewBag.DefaultInterval + 1" type="text">
<input type="checkbox" checked="true"/>
</p>
</div>

View File

@ -15,18 +15,18 @@
{
<p>Current Time: <input type=@checkbox checked=true /></p>
<input tYPe='@(true ? "checkbox" : "anything")' />
<input type='@if(true) { <text>checkbox</text> } else { <text>anything</text> }' />
<input type='@if(true) { <text>checkbox</text> } else { <text>anything</text> }'>
}
</p>
<p unbound="first value" age="@DateTimeOffset.Now.Year - 1970" unbound="second value" >
@{ var @object = false;}
<input ChecKED="@(@object)" />
<input ChecKED="@(@object)">
</p>
<p age="-1970 + @DateTimeOffset.Now.Year">
<input unbound="hello" unbound="world" checked="@(DateTimeOffset.Now.Year > 2014)" />
</p>
<p age="DateTimeOffset.Now.Year - 1970">
<input checked="DateTimeOffset.Now.Year > 2014" />
<input checked="DateTimeOffset.Now.Year > 2014">
</p>
<p age="@("My age is this long.".Length)">
<input checked=" @( DateTimeOffset.Now.Year ) > 2014 " />