diff --git a/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs
index 4032206bb1..5dc2bee774 100644
--- a/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs
+++ b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/TagHelperBlockRewriter.cs
@@ -254,7 +254,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
// If we're not after an equal then we should treat the value as if it were a minimized attribute.
var attributeValueBuilder = afterEquals ? builder : null;
result.AttributeValueNode =
- CreateMarkupAttribute(name, attributeValueBuilder, result.IsBoundNonStringAttribute);
+ CreateMarkupAttribute(attributeValueBuilder, result.IsBoundNonStringAttribute);
return result;
}
@@ -337,17 +337,45 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
var spanBuilder = new SpanBuilder(child);
result.AttributeValueNode =
- CreateMarkupAttribute(name, spanBuilder, result.IsBoundNonStringAttribute);
+ CreateMarkupAttribute(spanBuilder, result.IsBoundNonStringAttribute);
return result;
}
}
- result.AttributeValueNode = block;
+ result.AttributeValueNode = ConvertToMarkupAttributeBlock(block, result.IsBoundNonStringAttribute);
return result;
}
+ private static Block ConvertToMarkupAttributeBlock(Block block, bool isBoundNonStringAttribute)
+ {
+ var blockBuilder = new BlockBuilder
+ {
+ ChunkGenerator = block.ChunkGenerator,
+ Type = block.Type
+ };
+
+ foreach (var child in block.Children)
+ {
+ SyntaxTreeNode markupAttributeChild;
+
+ if (child.IsBlock)
+ {
+ markupAttributeChild = ConvertToMarkupAttributeBlock((Block)child, isBoundNonStringAttribute);
+ }
+ else
+ {
+ var spanBuilder = new SpanBuilder((Span)child);
+ markupAttributeChild = CreateMarkupAttribute(spanBuilder, isBoundNonStringAttribute);
+ }
+
+ blockBuilder.Children.Add(markupAttributeChild);
+ }
+
+ return blockBuilder.Build();
+ }
+
private static Block RebuildChunkGenerators(Block block)
{
var builder = new BlockBuilder(block);
@@ -440,10 +468,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
return nodeStart + firstNonWhitespaceSymbol.Start;
}
- private static SyntaxTreeNode CreateMarkupAttribute(
- string name,
- SpanBuilder builder,
- bool isBoundNonStringAttribute)
+ private static SyntaxTreeNode CreateMarkupAttribute(SpanBuilder builder, bool isBoundNonStringAttribute)
{
Span value = null;
diff --git a/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs b/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs
index 258bbd2a7d..9f607c7db7 100644
--- a/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs
+++ b/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs
@@ -385,6 +385,12 @@ namespace Microsoft.AspNet.Razor.Test.Framework
return Builder.Build();
}
+ public SpanConstructor As(SpanKind spanKind)
+ {
+ Builder.Kind = spanKind;
+ return this;
+ }
+
public SpanConstructor With(ISpanChunkGenerator generator)
{
Builder.ChunkGenerator = generator;
diff --git a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs
index 0d44d5de5e..f45124d1c5 100644
--- a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs
+++ b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs
@@ -603,6 +603,58 @@ namespace Microsoft.AspNet.Razor.TagHelpers
new MarkupBlock(factory.Markup("Time:"), dateTimeNow))
}))
},
+ {
+ "",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ selfClosing: true,
+ attributes: new List>
+ {
+ new KeyValuePair(
+ "age",
+ new MarkupBlock(
+ factory.CodeMarkup("1"),
+ factory.CodeMarkup(" +"),
+ new MarkupBlock(
+ factory.CodeMarkup(" "),
+ new ExpressionBlock(
+ factory.CodeTransition().As(SpanKind.Code),
+ factory
+ .Code("value")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharacters.NonWhiteSpace))),
+ factory.CodeMarkup(" +"),
+ factory.CodeMarkup(" 2"))),
+ new KeyValuePair(
+ "birthday",
+ new MarkupBlock(
+ factory.CodeMarkup("(bool)"),
+ new MarkupBlock(
+ new ExpressionBlock(
+ factory.CodeTransition().As(SpanKind.Code),
+ factory
+ .Code("Bag[\"val\"]")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharacters.NonWhiteSpace))),
+ factory.CodeMarkup(" ?"),
+ new MarkupBlock(
+ factory.CodeMarkup(" @").Accepts(AcceptedCharacters.None),
+ factory.CodeMarkup("@")
+ .With(SpanChunkGenerator.Null)
+ .Accepts(AcceptedCharacters.None)),
+ factory.CodeMarkup("DateTime"),
+ factory.CodeMarkup(" :"),
+ new MarkupBlock(
+ factory.CodeMarkup(" "),
+ new ExpressionBlock(
+ factory.CodeTransition().As(SpanKind.Code),
+ factory
+ .Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharacters.NonWhiteSpace)))
+ ))
+ }))
+ },
{
"",
new MarkupBlock(
@@ -675,17 +727,21 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"age",
new MarkupBlock(
new MarkupBlock(
- factory.Markup("@").Accepts(AcceptedCharacters.None),
- factory.Markup("@")
+ factory.CodeMarkup("@").Accepts(AcceptedCharacters.None),
+ factory.CodeMarkup("@")
.With(SpanChunkGenerator.Null)
.Accepts(AcceptedCharacters.None)),
new MarkupBlock(
- factory.EmptyHtml(),
+ factory.EmptyHtml().As(SpanKind.Code),
new ExpressionBlock(
- factory.CodeTransition(),
- factory.MetaCode("(").Accepts(AcceptedCharacters.None),
+ factory.CodeTransition().As(SpanKind.Code),
+ factory.MetaCode("(")
+ .Accepts(AcceptedCharacters.None)
+ .As(SpanKind.Code),
factory.Code("11+1").AsExpression(),
- factory.MetaCode(")").Accepts(AcceptedCharacters.None))))),
+ factory.MetaCode(")")
+ .Accepts(AcceptedCharacters.None)
+ .As(SpanKind.Code))))),
new KeyValuePair(
"birthday",
factory.CodeMarkup("DateTime.Now")),
@@ -1653,13 +1709,13 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"bound",
new MarkupBlock(
new MarkupBlock(
- factory.Markup(" "),
+ factory.CodeMarkup(" "),
new ExpressionBlock(
- factory.CodeTransition(),
+ factory.CodeTransition().As(SpanKind.Code),
factory.Code("true")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace))),
- factory.Markup(" ")))
+ factory.CodeMarkup(" ")))
}
})),
new RazorError[0]
@@ -1677,13 +1733,17 @@ namespace Microsoft.AspNet.Razor.TagHelpers
"bound",
new MarkupBlock(
new MarkupBlock(
- factory.Markup(" "),
+ factory.CodeMarkup(" "),
new ExpressionBlock(
- factory.CodeTransition(),
- factory.MetaCode("(").Accepts(AcceptedCharacters.None),
+ factory.CodeTransition().As(SpanKind.Code),
+ factory.MetaCode("(")
+ .Accepts(AcceptedCharacters.None)
+ .As(SpanKind.Code),
factory.Code("true").AsExpression(),
- factory.MetaCode(")").Accepts(AcceptedCharacters.None))),
- factory.Markup(" ")))
+ factory.MetaCode(")")
+ .Accepts(AcceptedCharacters.None)
+ .As(SpanKind.Code))),
+ factory.CodeMarkup(" ")))
}
})),
new RazorError[0]
diff --git a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs
index 0b1172a37d..bf5b6cce8f 100644
--- a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs
+++ b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs
@@ -1131,7 +1131,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupBlock(
new ExpressionBlock(
- factory.CodeTransition(),
+ factory.CodeTransition().As(SpanKind.Code),
factory.Code("DateTime.Now")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)))))
@@ -1153,7 +1153,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
new MarkupBlock(
new MarkupBlock(
new ExpressionBlock(
- factory.CodeTransition(),
+ factory.CodeTransition().As(SpanKind.Code),
factory.Code("DateTime.Now")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)))))
@@ -1174,12 +1174,12 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
"bound",
new MarkupBlock(
new MarkupBlock(
- factory.Markup("@").Accepts(AcceptedCharacters.None),
- factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharacters.None)),
+ factory.CodeMarkup("@").Accepts(AcceptedCharacters.None),
+ factory.CodeMarkup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharacters.None)),
new MarkupBlock(
- factory.EmptyHtml(),
+ factory.EmptyHtml().As(SpanKind.Code),
new ExpressionBlock(
- factory.CodeTransition(),
+ factory.CodeTransition().As(SpanKind.Code),
factory.Code("DateTime.Now")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)))))