Added new BlockType - HtmlComment

Updated the HtmlMarkupParser to understand the HtmlCOmments, and treat those as blocks.
This commit is contained in:
Artak Mkrtchyan 2018-02-15 18:15:34 -08:00
parent b2ae175d39
commit 696a65c780
6 changed files with 165 additions and 34 deletions

View File

@ -18,6 +18,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
// Special
Comment = 8,
Tag = 9
Tag = 9,
HtmlComment = 10
}
}

View File

@ -207,6 +207,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (last != null)
{
Accept(last);
if (At(HtmlSymbolType.OpenAngle) && last.Type == HtmlSymbolType.Text)
{
Output(SpanKindInternal.Markup);
}
}
}
@ -494,26 +498,34 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
if (CurrentSymbol.Type == HtmlSymbolType.DoubleHyphen)
{
AcceptAndMoveNext();
Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any;
while (!EndOfFile)
using (Context.Builder.StartBlock(BlockKindInternal.HtmlComment))
{
SkipToAndParseCode(HtmlSymbolType.DoubleHyphen);
if (At(HtmlSymbolType.DoubleHyphen))
AcceptAndMoveNext();
Span.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any;
while (!EndOfFile)
{
AcceptWhile(HtmlSymbolType.DoubleHyphen);
if (At(HtmlSymbolType.Text) &&
string.Equals(CurrentSymbol.Content, "-", StringComparison.Ordinal))
SkipToAndParseCode(HtmlSymbolType.DoubleHyphen);
if (At(HtmlSymbolType.DoubleHyphen))
{
AcceptAndMoveNext();
}
AcceptWhile(HtmlSymbolType.DoubleHyphen);
if (At(HtmlSymbolType.CloseAngle))
{
AcceptAndMoveNext();
return true;
if (At(HtmlSymbolType.Text) &&
string.Equals(CurrentSymbol.Content, "-", StringComparison.Ordinal))
{
AcceptAndMoveNext();
}
if (At(HtmlSymbolType.CloseAngle))
{
// This is the end of a comment block
Accept(this.CurrentSymbol);
Output(SpanKindInternal.Markup);
NextToken();
//AcceptAndMoveNext();
return true;
}
}
}
}
@ -1476,6 +1488,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
AcceptAndMoveNext(); // Accept '<'
BangTag();
return;
}

View File

@ -488,7 +488,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
private void ValidateParentAllowsContent(Span child, ErrorSink errorSink)
{
if (HasAllowedChildren() && !IsComment(child))
if (HasAllowedChildren() && !IsComment(child) && child.Kind != SpanKindInternal.Transition && child.Kind != SpanKindInternal.Code)
{
var content = child.Content;
if (!string.IsNullOrWhiteSpace(content))
@ -817,14 +817,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
return relevantSymbol.Type == HtmlSymbolType.ForwardSlash;
}
private static bool IsComment(Span span)
internal static bool IsComment(Span span)
{
bool isHtmlComment = span.Content?.StartsWith("<!--") == true;
bool isRazorComment = span.Parent?.Type == BlockKindInternal.Comment;
Block currentBlock = span.Parent;
while (currentBlock != null && currentBlock.Type != BlockKindInternal.Comment && currentBlock.Type != BlockKindInternal.HtmlComment)
{
currentBlock = currentBlock.Parent;
}
return isHtmlComment || isRazorComment;
return currentBlock != null;
}
private static void EnsureTagBlock(Block tagBlock)
{
Debug.Assert(tagBlock.Type == BlockKindInternal.Tag);

View File

@ -19,6 +19,8 @@ namespace Microsoft.VisualStudio.Editor.Razor
// Special
Comment,
Tag
Tag,
HtmlComment
}
}

View File

@ -1109,12 +1109,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
}
[Fact]
public void Rewrite_AllowsHtmlCommentsAsChildren()
public void Rewrite_AllowsSimpleHtmlCommentsAsChildren()
{
// Arrangestring documentContent,
IEnumerable<string> allowedChildren = new List<string> { "b" };
string literal = "asdf";
string commentOutput = $"<!--Hello World-->";
string commentOutput = "<!--Hello World-->";
string expectedOutput = $"<p><b>{literal}</b>{commentOutput}</p>";
var pTagHelperBuilder = TagHelperDescriptorBuilder
@ -1138,7 +1138,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
blockFactory.MarkupTagBlock("<b>"),
factory.Markup(literal),
blockFactory.MarkupTagBlock("</b>"),
factory.Markup(commentOutput)));
new HtmlCommentBlock(factory.Markup(commentOutput))));
// Act & Assert
EvaluateData(
@ -1148,6 +1148,58 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
Array.Empty<RazorDiagnostic>());
}
[Fact]
public void Rewrite_FailsForContentWithCommentsAsChildren()
{
// Arrangestring documentContent,
Func<string, string, string, int, int, RazorDiagnostic> nestedTagError =
(childName, parentName, allowed, location, length) =>
RazorDiagnosticFactory.CreateTagHelper_InvalidNestedTag(
new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), childName, parentName, allowed);
Func<string, string, int, int, RazorDiagnostic> nestedContentError =
(parentName, allowed, location, length) =>
RazorDiagnosticFactory.CreateTagHelper_CannotHaveNonTagContent(
new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), parentName, allowed);
IEnumerable<string> allowedChildren = new List<string> { "b" };
string comment1 = "Hello";
string literal = "asdf";
string comment2 = "World";
string expectedOutput = $"<p><!--{comment1}-->{literal}<!--{comment2}--></p>";
var pTagHelperBuilder = TagHelperDescriptorBuilder
.Create("PTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
foreach (var childTag in allowedChildren)
{
pTagHelperBuilder.AllowChildTag(childTag);
}
var descriptors = new TagHelperDescriptor[]
{
pTagHelperBuilder.Build()
};
var factory = new SpanFactory();
var blockFactory = new BlockFactory(factory);
var expectedMarkup = new MarkupBlock(
new MarkupTagHelperBlock("p",
new HtmlCommentBlock(factory.Markup($"<!--{comment1}-->")),
factory.Markup(literal),
new HtmlCommentBlock(factory.Markup($"<!--{comment2}-->"))));
// Act & Assert
EvaluateData(
descriptors,
expectedOutput,
expectedMarkup,
new[]
{
nestedContentError("p", "b", 15, 4),
});
}
[Fact]
public void Rewrite_AllowsRazorCommentsAsChildren()
{
@ -1193,6 +1245,54 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
Array.Empty<RazorDiagnostic>());
}
[Fact]
public void Rewrite_AllowsRazorMarkupInHtmlComment()
{
// Arrangestring documentContent,
IEnumerable<string> allowedChildren = new List<string> { "b" };
string literal = "asdf";
string part1 = "<!--Hello ";
string part2 = "World";
string part3 = "-->";
string expectedOutput = $"<p><b>{literal}</b>{part1}@{part2}{part3}</p>";
var pTagHelperBuilder = TagHelperDescriptorBuilder
.Create("PTagHelper", "SomeAssembly")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
foreach (var childTag in allowedChildren)
{
pTagHelperBuilder.AllowChildTag(childTag);
}
var descriptors = new TagHelperDescriptor[]
{
pTagHelperBuilder.Build()
};
var factory = new SpanFactory();
var blockFactory = new BlockFactory(factory);
var expectedMarkup = new MarkupBlock(
new MarkupTagHelperBlock("p",
blockFactory.MarkupTagBlock("<b>"),
factory.Markup(literal),
blockFactory.MarkupTagBlock("</b>"),
new HtmlCommentBlock(factory.Markup(part1),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code(part2)
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
factory.Markup(part3))));
// Act & Assert
EvaluateData(
descriptors,
expectedOutput,
expectedMarkup,
Array.Empty<RazorDiagnostic>());
}
[Fact]
public void Rewrite_UnderstandsNullTagNameWithAllowedChildrenForCatchAll()
{
@ -3993,7 +4093,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupBlock(
new MarkupTagBlock(
factory.Markup("<foo>")),
factory.Markup("<!-- Hello World -->"),
new HtmlCommentBlock( factory.Markup("<!-- Hello World -->")),
new MarkupTagBlock(
factory.Markup("</foo>")))
};
@ -4003,13 +4103,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupBlock(
new MarkupTagBlock(
factory.Markup("<foo>")),
factory.Markup("<!-- "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
factory.Markup(" -->"),
new HtmlCommentBlock(factory.Markup("<!-- "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
factory.Markup(" -->")),
new MarkupTagBlock(
factory.Markup("</foo>")))
};

View File

@ -217,4 +217,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
}
}
internal class HtmlCommentBlock : Block
{
private const BlockKindInternal ThisBlockKind = BlockKindInternal.HtmlComment;
public HtmlCommentBlock(params SyntaxTreeNode[] children)
: base(ThisBlockKind, children, ParentChunkGenerator.Null)
{
}
}
}