Allow invalid HTML to be in Razor pages.
- Modified the TagHelperParseTreeRewriter to not remove invalid HTML snippets. - Added tests to validate invalid HTML is allowed. #212
This commit is contained in:
parent
39accef1ad
commit
8d4bdbdb84
|
|
@ -56,8 +56,10 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
// Get tag name of the current block (doesn't matter if it's an end or start tag)
|
||||
var tagName = GetTagName(childBlock);
|
||||
|
||||
// Could not determine tag name, it can't be a TagHelper, continue on and track the element.
|
||||
if (tagName == null)
|
||||
{
|
||||
_currentBlock.Children.Add(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -224,9 +226,14 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
}
|
||||
|
||||
var childSpan = (Span)child;
|
||||
var textSymbol = childSpan.Symbols.FirstHtmlSymbolAs(HtmlSymbolType.Text);
|
||||
var textSymbol = childSpan.Symbols.FirstHtmlSymbolAs(HtmlSymbolType.WhiteSpace | HtmlSymbolType.Text);
|
||||
|
||||
return textSymbol != null ? textSymbol.Content : null;
|
||||
if (textSymbol == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return textSymbol.Type == HtmlSymbolType.WhiteSpace ? null : textSymbol.Content;
|
||||
}
|
||||
|
||||
private static bool IsSelfClosing(Block beginTagBlock)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Tokenizer.Symbols
|
||||
{
|
||||
[Flags]
|
||||
public enum HtmlSymbolType
|
||||
{
|
||||
Unknown,
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNet.Razor.Tokenizer.Symbols
|
|||
/// <returns>The first <see cref="HtmlSymbol"/> of type <paramref name="type"/>.</returns>
|
||||
public static HtmlSymbol FirstHtmlSymbolAs(this IEnumerable<ISymbol> symbols, HtmlSymbolType type)
|
||||
{
|
||||
return symbols.OfType<HtmlSymbol>().FirstOrDefault(sym => sym.Type == type);
|
||||
return symbols.OfType<HtmlSymbol>().FirstOrDefault(sym => (type & sym.Type) == sym.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(IncompleteHelperBlockData))]
|
||||
public void TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper(
|
||||
|
|
@ -102,6 +103,128 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers
|
|||
RunParseTreeRewriterTest(documentContent, expectedOutput, new[] { expectedError }, "strong", "p");
|
||||
}
|
||||
|
||||
public static TheoryData<string, MarkupBlock> InvalidHtmlBlockData
|
||||
{
|
||||
get
|
||||
{
|
||||
var factory = CreateDefaultSpanFactory();
|
||||
var blockFactory = new BlockFactory(factory);
|
||||
var dateTimeNow = new ExpressionBlock(
|
||||
factory.CodeTransition(),
|
||||
factory.Code("DateTime.Now")
|
||||
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
||||
.Accepts(AcceptedCharacters.NonWhiteSpace));
|
||||
|
||||
return new TheoryData<string, MarkupBlock>
|
||||
{
|
||||
{
|
||||
"<<<p>>></p>",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("<"),
|
||||
blockFactory.MarkupTagBlock("<"),
|
||||
new MarkupTagHelperBlock("p",
|
||||
factory.Markup(">>")))
|
||||
},
|
||||
{
|
||||
"<<p />",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("<"),
|
||||
new MarkupTagHelperBlock("p"))
|
||||
},
|
||||
{
|
||||
"< p />",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("< p />"))
|
||||
},
|
||||
{
|
||||
"<input <p />",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("<input "),
|
||||
new MarkupTagHelperBlock("p"))
|
||||
},
|
||||
{
|
||||
"< class=\"foo\" <p />",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockCodeGenerator(
|
||||
name: "class",
|
||||
prefix: new LocationTagged<string>(" class=\"", 1, 0, 1),
|
||||
suffix: new LocationTagged<string>("\"", 12, 0, 12)),
|
||||
factory.Markup(" class=\"").With(SpanCodeGenerator.Null),
|
||||
factory.Markup("foo").With(new LiteralAttributeCodeGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 9, 0, 9),
|
||||
value: new LocationTagged<string>("foo", 9, 0, 9))),
|
||||
factory.Markup("\"").With(SpanCodeGenerator.Null)),
|
||||
factory.Markup(" ")),
|
||||
new MarkupTagHelperBlock("p"))
|
||||
},
|
||||
{
|
||||
"</<<p>/></p>>",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("</"),
|
||||
blockFactory.MarkupTagBlock("<"),
|
||||
new MarkupTagHelperBlock("p",
|
||||
factory.Markup("/>")),
|
||||
factory.Markup(">"))
|
||||
},
|
||||
{
|
||||
"</<<p>/><strong></p>>",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("</"),
|
||||
blockFactory.MarkupTagBlock("<"),
|
||||
new MarkupTagHelperBlock("p",
|
||||
factory.Markup("/>"),
|
||||
blockFactory.MarkupTagBlock("<strong>")),
|
||||
factory.Markup(">"))
|
||||
},
|
||||
{
|
||||
"</<<p>@DateTime.Now/><strong></p>>",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("</"),
|
||||
blockFactory.MarkupTagBlock("<"),
|
||||
new MarkupTagHelperBlock("p",
|
||||
dateTimeNow,
|
||||
factory.Markup("/>"),
|
||||
blockFactory.MarkupTagBlock("<strong>")),
|
||||
factory.Markup(">"))
|
||||
},
|
||||
{
|
||||
"</ /< ><p>@DateTime.Now / ><strong></p></ >",
|
||||
new MarkupBlock(
|
||||
blockFactory.MarkupTagBlock("</ "),
|
||||
factory.Markup("/"),
|
||||
blockFactory.MarkupTagBlock("< >"),
|
||||
new MarkupTagHelperBlock("p",
|
||||
dateTimeNow,
|
||||
factory.Markup(" / >"),
|
||||
blockFactory.MarkupTagBlock("<strong>")),
|
||||
blockFactory.MarkupTagBlock("</ >"))
|
||||
},
|
||||
{
|
||||
"<p>< @DateTime.Now ></ @DateTime.Now ></p>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagHelperBlock("p",
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("< "),
|
||||
dateTimeNow,
|
||||
factory.Markup(" >")),
|
||||
blockFactory.MarkupTagBlock("</ "),
|
||||
dateTimeNow,
|
||||
factory.Markup(" >")))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(InvalidHtmlBlockData))]
|
||||
public void TagHelperParseTreeRewriter_AllowsInvalidHtml(string documentContent, MarkupBlock expectedOutput)
|
||||
{
|
||||
RunParseTreeRewriterTest(documentContent, expectedOutput, "p");
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> TextTagsBlockData
|
||||
{
|
||||
get
|
||||
|
|
|
|||
Loading…
Reference in New Issue