Add Multiple attribute same name understanding to TagHelperChunk.
- This also involved adding understanding to CSharpTagHelperCodeRenderer.
- When rebasing this commit was lost as part of: 7c604d2b11 .
#279
This commit is contained in:
parent
6384977e96
commit
e3fdb8886a
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
||||||
public void RenderTagHelper(TagHelperChunk chunk)
|
public void RenderTagHelper(TagHelperChunk chunk)
|
||||||
{
|
{
|
||||||
// Remove any duplicate TagHelperDescriptors that reference the same type name. Duplicates can occur when
|
// Remove any duplicate TagHelperDescriptors that reference the same type name. Duplicates can occur when
|
||||||
// multiple TargetElement attributes are on a TagHelper type and matchs overlap for an HTML element.
|
// multiple TargetElement attributes are on a TagHelper type and matches overlap for an HTML element.
|
||||||
// Having more than one descriptor with the same TagHelper type results in generated code that runs
|
// Having more than one descriptor with the same TagHelper type results in generated code that runs
|
||||||
// the same TagHelper X many times (instead of once) over a single HTML element.
|
// the same TagHelper X many times (instead of once) over a single HTML element.
|
||||||
var tagHelperDescriptors = chunk.Descriptors.Distinct(TypeNameTagHelperDescriptorComparer.Default);
|
var tagHelperDescriptors = chunk.Descriptors.Distinct(TypeNameTagHelperDescriptorComparer.Default);
|
||||||
|
|
@ -190,20 +190,21 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RenderBoundHTMLAttributes(IDictionary<string, Chunk> chunkAttributes,
|
private void RenderBoundHTMLAttributes(IList<KeyValuePair<string, Chunk>> chunkAttributes,
|
||||||
string tagHelperVariableName,
|
string tagHelperVariableName,
|
||||||
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
IEnumerable<TagHelperAttributeDescriptor> attributeDescriptors,
|
||||||
Dictionary<string, string> htmlAttributeValues)
|
Dictionary<string, string> htmlAttributeValues)
|
||||||
{
|
{
|
||||||
foreach (var attributeDescriptor in attributeDescriptors)
|
foreach (var attributeDescriptor in attributeDescriptors)
|
||||||
{
|
{
|
||||||
Chunk attributeValueChunk;
|
var matchingAttributes = chunkAttributes.Where(
|
||||||
|
attr => string.Equals(attr.Key, attributeDescriptor.Name, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
var providedAttribute = chunkAttributes.TryGetValue(attributeDescriptor.Name,
|
if (matchingAttributes.Any())
|
||||||
out attributeValueChunk);
|
|
||||||
|
|
||||||
if (providedAttribute)
|
|
||||||
{
|
{
|
||||||
|
// First attribute wins, even if there's duplicates.
|
||||||
|
var attributeValueChunk = matchingAttributes.First().Value;
|
||||||
|
|
||||||
var attributeValueRecorded = htmlAttributeValues.ContainsKey(attributeDescriptor.Name);
|
var attributeValueRecorded = htmlAttributeValues.ContainsKey(attributeDescriptor.Name);
|
||||||
|
|
||||||
// Bufferable attributes are attributes that can have Razor code inside of them.
|
// Bufferable attributes are attributes that can have Razor code inside of them.
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
|
||||||
public TagHelperChunk(
|
public TagHelperChunk(
|
||||||
string tagName,
|
string tagName,
|
||||||
bool selfClosing,
|
bool selfClosing,
|
||||||
IDictionary<string, Chunk> attributes,
|
IList<KeyValuePair<string, Chunk>> attributes,
|
||||||
IEnumerable<TagHelperDescriptor> descriptors)
|
IEnumerable<TagHelperDescriptor> descriptors)
|
||||||
{
|
{
|
||||||
TagName = tagName;
|
TagName = tagName;
|
||||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
|
||||||
/// These attributes are <see cref="string"/> => <see cref="Chunk"/> so attribute values can consist
|
/// These attributes are <see cref="string"/> => <see cref="Chunk"/> so attribute values can consist
|
||||||
/// of all sorts of Razor specific pieces.
|
/// of all sorts of Razor specific pieces.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public IDictionary<string, Chunk> Attributes { get; set; }
|
public IList<KeyValuePair<string, Chunk>> Attributes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="TagHelperDescriptor"/>s that are associated with the tag helpers HTML element.
|
/// The <see cref="TagHelperDescriptor"/>s that are associated with the tag helpers HTML element.
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Razor.Generator
|
||||||
RazorResources.TagHelpers_TagHelperCodeGeneartorMustBeAssociatedWithATagHelperBlock);
|
RazorResources.TagHelpers_TagHelperCodeGeneartorMustBeAssociatedWithATagHelperBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
var attributes = new Dictionary<string, Chunk>(StringComparer.OrdinalIgnoreCase);
|
var attributes = new List<KeyValuePair<string, Chunk>>();
|
||||||
|
|
||||||
// We need to create a code generator to create chunks for each of the attributes.
|
// We need to create a code generator to create chunks for each of the attributes.
|
||||||
var codeGenerator = context.Host.CreateCodeGenerator(
|
var codeGenerator = context.Host.CreateCodeGenerator(
|
||||||
|
|
@ -63,12 +63,13 @@ namespace Microsoft.AspNet.Razor.Generator
|
||||||
var chunks = codeGenerator.Context.CodeTreeBuilder.CodeTree.Chunks;
|
var chunks = codeGenerator.Context.CodeTreeBuilder.CodeTree.Chunks;
|
||||||
var first = chunks.FirstOrDefault();
|
var first = chunks.FirstOrDefault();
|
||||||
|
|
||||||
attributes[attribute.Key] = new ChunkBlock
|
attributes.Add(new KeyValuePair<string, Chunk>(attribute.Key,
|
||||||
{
|
new ChunkBlock
|
||||||
Association = first?.Association,
|
{
|
||||||
Children = chunks,
|
Association = first?.Association,
|
||||||
Start = first == null ? SourceLocation.Zero : first.Start
|
Children = chunks,
|
||||||
};
|
Start = first == null ? SourceLocation.Zero : first.Start
|
||||||
|
}));
|
||||||
|
|
||||||
// Reset the code tree builder so we can build a new one for the next attribute
|
// Reset the code tree builder so we can build a new one for the next attribute
|
||||||
codeGenerator.Context.CodeTreeBuilder = new CodeTreeBuilder();
|
codeGenerator.Context.CodeTreeBuilder = new CodeTreeBuilder();
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
||||||
return new TagHelperChunk(
|
return new TagHelperChunk(
|
||||||
tagName,
|
tagName,
|
||||||
selfClosing: false,
|
selfClosing: false,
|
||||||
attributes: new Dictionary<string, Chunk>(),
|
attributes: new List<KeyValuePair<string, Chunk>>(),
|
||||||
descriptors: tagHelperDescriptors)
|
descriptors: tagHelperDescriptors)
|
||||||
{
|
{
|
||||||
Children = new List<Chunk>(),
|
Children = new List<Chunk>(),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue