From fb6a08d5de3d11933c7d5884a7d5760646bdd249 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Mon, 14 Sep 2015 20:46:25 -0700 Subject: [PATCH] Allow `TagHelper`s inside of text/html typed script tags. - To limit the impact of the change ensured that we only do extra work in the case that we detect a script tag with a `type` attribute. - The parsing changes include normal HTML parsing behaviors when we detect that a script tag has a `type` attribute with value `text/html`. - Added unit and code generation tests to validate `text/html` script tag behavior. #502 --- .../Parser/HtmlMarkupParser.Block.cs | 14 +- .../Parser/HtmlMarkupParser.Document.cs | 61 +++- .../CSharpTagHelperRenderingTest.cs | 55 +++- .../TagHelperParseTreeRewriterTest.cs | 267 ++++++++++++++++++ .../NestedScriptTagTagHelpers.DesignTime.cs | 71 +++++ ...ptTagTagHelpers.DesignTime.lineMappings.cs | 49 ++++ .../Output/NestedScriptTagTagHelpers.cs | 114 ++++++++ .../Source/NestedScriptTagTagHelpers.cshtml | 16 ++ 8 files changed, 641 insertions(+), 6 deletions(-) create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.cs create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.lineMappings.cs create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.cs create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Source/NestedScriptTagTagHelpers.cshtml diff --git a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs index 09e7f06b40..31a778fd5e 100644 --- a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs +++ b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Block.cs @@ -5,8 +5,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using Microsoft.AspNet.Razor.Editor; using Microsoft.AspNet.Razor.Chunks.Generators; +using Microsoft.AspNet.Razor.Editor; using Microsoft.AspNet.Razor.Parser.SyntaxTree; using Microsoft.AspNet.Razor.Text; using Microsoft.AspNet.Razor.Tokenizer.Symbols; @@ -937,9 +937,17 @@ namespace Microsoft.AspNet.Razor.Parser } else if (string.Equals(tagName, ScriptTagName, StringComparison.OrdinalIgnoreCase)) { - CompleteTagBlockWithSpan(tagBlockWrapper, AcceptedCharacters.None, SpanKind.Markup); + if (!CurrentScriptTagExpectsHtml()) + { + CompleteTagBlockWithSpan(tagBlockWrapper, AcceptedCharacters.None, SpanKind.Markup); - SkipToEndScriptAndParseCode(endTagAcceptedCharacters: AcceptedCharacters.None); + SkipToEndScriptAndParseCode(endTagAcceptedCharacters: AcceptedCharacters.None); + } + else + { + // Push the script tag onto the tag stack, it should be treated like all other HTML tags. + tags.Push(tag); + } } else { diff --git a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Document.cs b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Document.cs index 88647b0087..8173ce1b12 100644 --- a/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Document.cs +++ b/src/Microsoft.AspNet.Razor/Parser/HtmlMarkupParser.Document.cs @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Diagnostics; +using System.Linq; +using Microsoft.AspNet.Razor.Chunks.Generators; using Microsoft.AspNet.Razor.Parser.SyntaxTree; using Microsoft.AspNet.Razor.Tokenizer.Symbols; @@ -9,6 +12,9 @@ namespace Microsoft.AspNet.Razor.Parser { public partial class HtmlMarkupParser { + private static readonly char[] ValidAfterTypeAttributeNameCharacters = + new[] { ' ', '\t', '\r', '\n', '\f', '=' }; + public override void ParseDocument() { if (Context == null) @@ -50,7 +56,7 @@ namespace Microsoft.AspNet.Razor.Parser return; } - // We should behave like a normal tag that has a parser escape, fall through to the normal + // We should behave like a normal tag that has a parser escape, fall through to the normal // tag logic. } else if (NextIs(HtmlSymbolType.QuestionMark)) @@ -79,7 +85,9 @@ namespace Microsoft.AspNet.Razor.Parser Optional(HtmlSymbolType.ForwardSlash); Optional(HtmlSymbolType.CloseAngle); - if (scriptTag) + // If the script tag expects javascript content then we should do minimal parsing until we reach + // the end script tag. Don't want to incorrectly parse a "var tag = '';" as an HTML tag. + if (scriptTag && !CurrentScriptTagExpectsHtml()) { Output(SpanKind.Markup); tagBlock.Dispose(); @@ -107,5 +115,54 @@ namespace Microsoft.AspNet.Razor.Parser tagBlock.Dispose(); } } + + private bool CurrentScriptTagExpectsHtml() + { + var blockBuilder = Context.CurrentBlock; + + Debug.Assert(blockBuilder != null); + + var typeAttribute = blockBuilder.Children + .OfType() + .Where(block => + block.ChunkGenerator is AttributeBlockChunkGenerator && + block.Children.Count() >= 2) + .FirstOrDefault(IsTypeAttribute); + + if (typeAttribute != null) + { + var contentValues = typeAttribute.Children + .OfType() + .Where(childSpan => childSpan.ChunkGenerator is LiteralAttributeChunkGenerator) + .Select(childSpan => childSpan.Content); + + var scriptType = string.Concat(contentValues).Trim(); + + // Does not allow charset parameter (or any other parameters). + return string.Equals(scriptType, "text/html", StringComparison.OrdinalIgnoreCase); + } + + return false; + } + + private static bool IsTypeAttribute(Block block) + { + var span = block.Children.First() as Span; + + if (span == null) + { + return false; + } + + var trimmedStartContent = span.Content.TrimStart(); + if (trimmedStartContent.StartsWith("type", StringComparison.OrdinalIgnoreCase) && + (trimmedStartContent.Length == 4 || + ValidAfterTypeAttributeNameCharacters.Contains(trimmedStartContent[4]))) + { + return true; + } + + return false; + } } } diff --git a/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs b/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs index 90f4b3a627..42739d0399 100644 --- a/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/CodeGenerators/CSharpTagHelperRenderingTest.cs @@ -1459,6 +1459,58 @@ namespace Microsoft.AspNet.Razor.Test.Generator contentLength: 1), } }, + { + "NestedScriptTagTagHelpers", + "NestedScriptTagTagHelpers.DesignTime", + DefaultPAndInputTagHelperDescriptors, + new[] + { + BuildLineMapping( + documentAbsoluteIndex: 14, + documentLineIndex: 0, + generatedAbsoluteIndex: 495, + generatedLineIndex: 15, + characterOffsetIndex: 14, + contentLength: 17), + BuildLineMapping( + documentAbsoluteIndex: 182, + documentLineIndex: 5, + generatedAbsoluteIndex: 1033, + generatedLineIndex: 35, + characterOffsetIndex: 0, + contentLength: 12), + BuildLineMapping( + documentAbsoluteIndex: 195, + documentLineIndex: 5, + documentCharacterOffsetIndex: 13, + generatedAbsoluteIndex: 1136, + generatedLineIndex: 41, + generatedCharacterOffsetIndex: 12, + contentLength: 30), + BuildLineMapping( + documentAbsoluteIndex: 339, + documentLineIndex: 7, + documentCharacterOffsetIndex: 50, + generatedAbsoluteIndex: 1385, + generatedLineIndex: 49, + generatedCharacterOffsetIndex: 6, + contentLength: 23), + BuildLineMapping( + documentAbsoluteIndex: 389, + documentLineIndex: 7, + generatedAbsoluteIndex: 1692, + generatedLineIndex: 56, + characterOffsetIndex: 100, + contentLength: 4), + BuildLineMapping( + documentAbsoluteIndex: 424, + documentLineIndex: 9, + generatedAbsoluteIndex: 1775, + generatedLineIndex: 61, + characterOffsetIndex: 0, + contentLength: 15), + } + }, }; } } @@ -1505,7 +1557,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator }, { "DuplicateAttributeTagHelpers", null, DefaultPAndInputTagHelperDescriptors }, { "DynamicAttributeTagHelpers", null, DynamicAttributeTagHelpers_Descriptors }, - { "TransitionsInTagHelperAttributes", null, DefaultPAndInputTagHelperDescriptors } + { "TransitionsInTagHelperAttributes", null, DefaultPAndInputTagHelperDescriptors }, + { "NestedScriptTagTagHelpers", null, DefaultPAndInputTagHelperDescriptors }, }; } } diff --git a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs index 931f129c83..43b90ab7a8 100644 --- a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperParseTreeRewriterTest.cs @@ -18,6 +18,273 @@ namespace Microsoft.AspNet.Razor.Test.TagHelpers { public class TagHelperParseTreeRewriterTest : TagHelperRewritingTestBase { + public static TheoryData InvalidHtmlScriptBlockData + { + get + { + var factory = CreateDefaultSpanFactory(); + var blockFactory = new BlockFactory(factory); + + return new TheoryData + { + { + "", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("")), + factory.Markup(""), + blockFactory.MarkupTagBlock("")) + }, + { + "", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("(" types='", 7, 0, 7), + suffix: new LocationTagged("'", 24, 0, 24)), + factory.Markup(" types='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 15, 0, 15), + value: new LocationTagged("text/html", 15, 0, 15))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + factory.Markup(""), + blockFactory.MarkupTagBlock("")) + }, + { + "", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("(" type='", 7, 0, 7), + suffix: new LocationTagged("'", 31, 0, 31)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 14, 0, 14), + value: new LocationTagged("text/html", 14, 0, 14))), + factory.Markup(" invalid").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(" ", 23, 0, 23), + value: new LocationTagged("invalid", 24, 0, 24))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + factory.Markup(""), + blockFactory.MarkupTagBlock("")) + }, + { + "", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("(" type='", 7, 0, 7), + suffix: new LocationTagged("'", 23, 0, 23)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/ng-*").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 14, 0, 14), + value: new LocationTagged("text/ng-*", 14, 0, 14))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + new MarkupBlock( + new AttributeBlockChunkGenerator( + name: "type", + prefix: new LocationTagged(" type='", 24, 0, 24), + suffix: new LocationTagged("'", 40, 0, 40)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 31, 0, 31), + value: new LocationTagged("text/html", 31, 0, 31))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + factory.Markup(""), + blockFactory.MarkupTagBlock("")) + }, + }; + } + } + + [Theory] + [MemberData(nameof(InvalidHtmlScriptBlockData))] + public void TagHelperParseTreeRewriter_DoesNotUnderstandTagHelpersInInvalidHtmlTypedScriptTags( + string documentContent, + MarkupBlock expectedOutput) + { + RunParseTreeRewriterTest(documentContent, expectedOutput, "input"); + } + + public static TheoryData HtmlScriptBlockData + { + get + { + var factory = CreateDefaultSpanFactory(); + var blockFactory = new BlockFactory(factory); + + return new TheoryData + { + { + "", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("(" type='", 7, 0, 7), + suffix: new LocationTagged("'", 23, 0, 23)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 14, 0, 14), + value: new LocationTagged("text/html", 14, 0, 14))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + new MarkupTagHelperBlock("input", TagMode.SelfClosing), + blockFactory.MarkupTagBlock("")) + }, + { + "", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("(" id='", 7, 0, 7), + suffix: new LocationTagged("'", 21, 0, 21)), + factory.Markup(" id='").With(SpanChunkGenerator.Null), + factory.Markup("scriptTag").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 12, 0, 12), + value: new LocationTagged("scriptTag", 12, 0, 12))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + new MarkupBlock( + new AttributeBlockChunkGenerator( + name: "type", + prefix: new LocationTagged(" type='", 22, 0, 22), + suffix: new LocationTagged("'", 38, 0, 38)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 29, 0, 29), + value: new LocationTagged("text/html", 29, 0, 29))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + new MarkupBlock( + new AttributeBlockChunkGenerator( + name: "class", + prefix: new LocationTagged(" class='", 39, 0, 39), + suffix: new LocationTagged("'", 56, 0, 56)), + factory.Markup(" class='").With(SpanChunkGenerator.Null), + factory.Markup("something").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 47, 0, 47), + value: new LocationTagged("something", 47, 0, 47))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + new MarkupTagHelperBlock("input", TagMode.SelfClosing), + blockFactory.MarkupTagBlock("")) + }, + { + "

", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("(" type='", 7, 0, 7), + suffix: new LocationTagged("'", 23, 0, 23)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 14, 0, 14), + value: new LocationTagged("text/html", 14, 0, 14))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + new MarkupTagHelperBlock("p", + new MarkupTagBlock( + factory.Markup("(" type='", 35, 0, 35), + suffix: new LocationTagged("'", 51, 0, 51)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 42, 0, 42), + value: new LocationTagged("text/html", 42, 0, 42))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + new MarkupTagHelperBlock("input", TagMode.SelfClosing), + blockFactory.MarkupTagBlock("")), + blockFactory.MarkupTagBlock("")) + }, + { + "

", + new MarkupBlock( + new MarkupTagBlock( + factory.Markup("(" type='", 7, 0, 7), + suffix: new LocationTagged("'", 23, 0, 23)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 14, 0, 14), + value: new LocationTagged("text/html", 14, 0, 14))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + new MarkupTagHelperBlock("p", + new MarkupTagBlock( + factory.Markup("(" type='", 35, 0, 35), + suffix: new LocationTagged("'", 52, 0, 52)), + factory.Markup(" type='").With(SpanChunkGenerator.Null), + factory.Markup("text/").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(string.Empty, 42, 0, 42), + value: new LocationTagged("text/", 42, 0, 42))), + factory.Markup(" html").With( + new LiteralAttributeChunkGenerator( + prefix: new LocationTagged(" ", 47, 0, 47), + value: new LocationTagged("html", 48, 0, 48))), + factory.Markup("'").With(SpanChunkGenerator.Null)), + factory.Markup(">")), + factory.Markup(""), + blockFactory.MarkupTagBlock("")), + blockFactory.MarkupTagBlock("")) + }, + }; + } + } + + [Theory] + [MemberData(nameof(HtmlScriptBlockData))] + public void TagHelperParseTreeRewriter_UnderstandsTagHelpersInHtmlTypedScriptTags( + string documentContent, + MarkupBlock expectedOutput) + { + RunParseTreeRewriterTest(documentContent, expectedOutput, "p", "input"); + } + [Fact] public void Rewrite_CanHandleInvalidChildrenWithWhitespace() { diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.cs new file mode 100644 index 0000000000..de703c0dd1 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.cs @@ -0,0 +1,71 @@ +namespace TestOutput +{ + using Microsoft.AspNet.Razor.Runtime.TagHelpers; + using System; + using System.Threading.Tasks; + + public class NestedScriptTagTagHelpers + { + private static object @__o; + private void @__RazorDesignTimeHelpers__() + { + #pragma warning disable 219 + string __tagHelperDirectiveSyntaxHelper = null; + __tagHelperDirectiveSyntaxHelper = +#line 1 "NestedScriptTagTagHelpers.cshtml" + "something, nice" + +#line default +#line hidden + ; + #pragma warning restore 219 + } + #line hidden + private PTagHelper __PTagHelper = null; + private InputTagHelper __InputTagHelper = null; + private InputTagHelper2 __InputTagHelper2 = null; + #line hidden + public NestedScriptTagTagHelpers() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { +#line 6 "NestedScriptTagTagHelpers.cshtml" + + +#line default +#line hidden + +#line 6 "NestedScriptTagTagHelpers.cshtml" + for(var i = 0; i < 5; i++) { + +#line default +#line hidden + + __InputTagHelper = CreateTagHelper(); + __InputTagHelper2 = CreateTagHelper(); +#line 8 "NestedScriptTagTagHelpers.cshtml" +__o = ViewBag.DefaultInterval; + +#line default +#line hidden + __InputTagHelper.Type = "text"; + __InputTagHelper2.Type = __InputTagHelper.Type; +#line 8 "NestedScriptTagTagHelpers.cshtml" + __InputTagHelper2.Checked = true; + +#line default +#line hidden +#line 10 "NestedScriptTagTagHelpers.cshtml" + } + +#line default +#line hidden + + __PTagHelper = CreateTagHelper(); + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.lineMappings.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.lineMappings.cs new file mode 100644 index 0000000000..2d848edd17 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.DesignTime.lineMappings.cs @@ -0,0 +1,49 @@ +// !!! Do not check in. Instead paste content into test method. !!! + + var expectedLineMappings = new[] + { + BuildLineMapping( + documentAbsoluteIndex: 14, + documentLineIndex: 0, + generatedAbsoluteIndex: 495, + generatedLineIndex: 15, + characterOffsetIndex: 14, + contentLength: 17), + BuildLineMapping( + documentAbsoluteIndex: 182, + documentLineIndex: 5, + generatedAbsoluteIndex: 1033, + generatedLineIndex: 35, + characterOffsetIndex: 0, + contentLength: 12), + BuildLineMapping( + documentAbsoluteIndex: 195, + documentLineIndex: 5, + documentCharacterOffsetIndex: 13, + generatedAbsoluteIndex: 1136, + generatedLineIndex: 41, + generatedCharacterOffsetIndex: 12, + contentLength: 30), + BuildLineMapping( + documentAbsoluteIndex: 339, + documentLineIndex: 7, + documentCharacterOffsetIndex: 50, + generatedAbsoluteIndex: 1385, + generatedLineIndex: 49, + generatedCharacterOffsetIndex: 6, + contentLength: 23), + BuildLineMapping( + documentAbsoluteIndex: 389, + documentLineIndex: 7, + generatedAbsoluteIndex: 1692, + generatedLineIndex: 56, + characterOffsetIndex: 100, + contentLength: 4), + BuildLineMapping( + documentAbsoluteIndex: 424, + documentLineIndex: 9, + generatedAbsoluteIndex: 1775, + generatedLineIndex: 61, + characterOffsetIndex: 0, + contentLength: 15), + }; diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.cs new file mode 100644 index 0000000000..235f76c9d5 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/NestedScriptTagTagHelpers.cs @@ -0,0 +1,114 @@ +#pragma checksum "NestedScriptTagTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "9e6bc8d09df124eda650118b208b7c5e6e058f6b" +namespace TestOutput +{ + using Microsoft.AspNet.Razor.Runtime.TagHelpers; + using System; + using System.Threading.Tasks; + + public class NestedScriptTagTagHelpers + { + #line hidden + #pragma warning disable 0414 + private TagHelperContent __tagHelperStringValueBuffer = null; + #pragma warning restore 0414 + private TagHelperExecutionContext __tagHelperExecutionContext = null; + private TagHelperRunner __tagHelperRunner = null; + private TagHelperScopeManager __tagHelperScopeManager = new TagHelperScopeManager(); + private PTagHelper __PTagHelper = null; + private InputTagHelper __InputTagHelper = null; + private InputTagHelper2 __InputTagHelper2 = null; + #line hidden + public NestedScriptTagTagHelpers() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { + __tagHelperRunner = __tagHelperRunner ?? new TagHelperRunner(); + Instrumentation.BeginContext(33, 106, true); + WriteLiteral("\r\n\r\n"); + Instrumentation.EndContext(); +#line 10 "NestedScriptTagTagHelpers.cshtml" + } + +#line default +#line hidden + + Instrumentation.BeginContext(439, 129, true); + WriteLiteral(" \r\n "); + Instrumentation.EndContext(); + } + , StartTagHelperWritingScope, EndTagHelperWritingScope); + __PTagHelper = CreateTagHelper(); + __tagHelperExecutionContext.Add(__PTagHelper); + __tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw("Hello World")); + __tagHelperExecutionContext.AddHtmlAttribute("data-delay", Html.Raw("1000")); + __tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext); + Instrumentation.BeginContext(139, 433, false); + await WriteTagHelperAsync(__tagHelperExecutionContext); + Instrumentation.EndContext(); + __tagHelperExecutionContext = __tagHelperScopeManager.End(); + Instrumentation.BeginContext(572, 23, true); + WriteLiteral("\r\n \r\n"); + Instrumentation.EndContext(); + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Source/NestedScriptTagTagHelpers.cshtml b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Source/NestedScriptTagTagHelpers.cshtml new file mode 100644 index 0000000000..27a29b23b4 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Source/NestedScriptTagTagHelpers.cshtml @@ -0,0 +1,16 @@ +@addTagHelper "something, nice" + + + } + +

+ + \ No newline at end of file