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
This commit is contained in:
parent
d3835455d2
commit
fb6a08d5de
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 = '<input />';" 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<Block>()
|
||||
.Where(block =>
|
||||
block.ChunkGenerator is AttributeBlockChunkGenerator &&
|
||||
block.Children.Count() >= 2)
|
||||
.FirstOrDefault(IsTypeAttribute);
|
||||
|
||||
if (typeAttribute != null)
|
||||
{
|
||||
var contentValues = typeAttribute.Children
|
||||
.OfType<Span>()
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<string, MarkupBlock>
|
||||
{
|
||||
{
|
||||
"<script type><input /></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(factory.Markup(" type")),
|
||||
factory.Markup(">")),
|
||||
factory.Markup("<input />"),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
{
|
||||
"<script types='text/html'><input /></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "types",
|
||||
prefix: new LocationTagged<string>(" types='", 7, 0, 7),
|
||||
suffix: new LocationTagged<string>("'", 24, 0, 24)),
|
||||
factory.Markup(" types='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 15, 0, 15),
|
||||
value: new LocationTagged<string>("text/html", 15, 0, 15))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
factory.Markup("<input />"),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
{
|
||||
"<script type='text/html invalid'><input /></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 7, 0, 7),
|
||||
suffix: new LocationTagged<string>("'", 31, 0, 31)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
|
||||
value: new LocationTagged<string>("text/html", 14, 0, 14))),
|
||||
factory.Markup(" invalid").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(" ", 23, 0, 23),
|
||||
value: new LocationTagged<string>("invalid", 24, 0, 24))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
factory.Markup("<input />"),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
{
|
||||
"<script type='text/ng-*' type='text/html'><input /></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 7, 0, 7),
|
||||
suffix: new LocationTagged<string>("'", 23, 0, 23)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/ng-*").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
|
||||
value: new LocationTagged<string>("text/ng-*", 14, 0, 14))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 24, 0, 24),
|
||||
suffix: new LocationTagged<string>("'", 40, 0, 40)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 31, 0, 31),
|
||||
value: new LocationTagged<string>("text/html", 31, 0, 31))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
factory.Markup("<input />"),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[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<string, MarkupBlock>
|
||||
{
|
||||
{
|
||||
"<script type='text/html'><input /></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 7, 0, 7),
|
||||
suffix: new LocationTagged<string>("'", 23, 0, 23)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
|
||||
value: new LocationTagged<string>("text/html", 14, 0, 14))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
new MarkupTagHelperBlock("input", TagMode.SelfClosing),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
{
|
||||
"<script id='scriptTag' type='text/html' class='something'><input /></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "id",
|
||||
prefix: new LocationTagged<string>(" id='", 7, 0, 7),
|
||||
suffix: new LocationTagged<string>("'", 21, 0, 21)),
|
||||
factory.Markup(" id='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("scriptTag").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 12, 0, 12),
|
||||
value: new LocationTagged<string>("scriptTag", 12, 0, 12))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 22, 0, 22),
|
||||
suffix: new LocationTagged<string>("'", 38, 0, 38)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 29, 0, 29),
|
||||
value: new LocationTagged<string>("text/html", 29, 0, 29))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "class",
|
||||
prefix: new LocationTagged<string>(" class='", 39, 0, 39),
|
||||
suffix: new LocationTagged<string>("'", 56, 0, 56)),
|
||||
factory.Markup(" class='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("something").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 47, 0, 47),
|
||||
value: new LocationTagged<string>("something", 47, 0, 47))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
new MarkupTagHelperBlock("input", TagMode.SelfClosing),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
{
|
||||
"<script type='text/html'><p><script type='text/html'><input /></script></p></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 7, 0, 7),
|
||||
suffix: new LocationTagged<string>("'", 23, 0, 23)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
|
||||
value: new LocationTagged<string>("text/html", 14, 0, 14))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
new MarkupTagHelperBlock("p",
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 35, 0, 35),
|
||||
suffix: new LocationTagged<string>("'", 51, 0, 51)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 42, 0, 42),
|
||||
value: new LocationTagged<string>("text/html", 42, 0, 42))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
new MarkupTagHelperBlock("input", TagMode.SelfClosing),
|
||||
blockFactory.MarkupTagBlock("</script>")),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
{
|
||||
"<script type='text/html'><p><script type='text/ html'><input /></script></p></script>",
|
||||
new MarkupBlock(
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 7, 0, 7),
|
||||
suffix: new LocationTagged<string>("'", 23, 0, 23)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
|
||||
value: new LocationTagged<string>("text/html", 14, 0, 14))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
new MarkupTagHelperBlock("p",
|
||||
new MarkupTagBlock(
|
||||
factory.Markup("<script"),
|
||||
new MarkupBlock(
|
||||
new AttributeBlockChunkGenerator(
|
||||
name: "type",
|
||||
prefix: new LocationTagged<string>(" type='", 35, 0, 35),
|
||||
suffix: new LocationTagged<string>("'", 52, 0, 52)),
|
||||
factory.Markup(" type='").With(SpanChunkGenerator.Null),
|
||||
factory.Markup("text/").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(string.Empty, 42, 0, 42),
|
||||
value: new LocationTagged<string>("text/", 42, 0, 42))),
|
||||
factory.Markup(" html").With(
|
||||
new LiteralAttributeChunkGenerator(
|
||||
prefix: new LocationTagged<string>(" ", 47, 0, 47),
|
||||
value: new LocationTagged<string>("html", 48, 0, 48))),
|
||||
factory.Markup("'").With(SpanChunkGenerator.Null)),
|
||||
factory.Markup(">")),
|
||||
factory.Markup("<input />"),
|
||||
blockFactory.MarkupTagBlock("</script>")),
|
||||
blockFactory.MarkupTagBlock("</script>"))
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(HtmlScriptBlockData))]
|
||||
public void TagHelperParseTreeRewriter_UnderstandsTagHelpersInHtmlTypedScriptTags(
|
||||
string documentContent,
|
||||
MarkupBlock expectedOutput)
|
||||
{
|
||||
RunParseTreeRewriterTest(documentContent, expectedOutput, "p", "input");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Rewrite_CanHandleInvalidChildrenWithWhitespace()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<InputTagHelper>();
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
#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<PTagHelper>();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
};
|
||||
|
|
@ -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<script type=\"text/html\">\r\n <div data-animation=\"fade\" class=\"randomNonTagHe" +
|
||||
"lperAttribute\">\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", TagMode.StartTagAndEndTag, "test", async() => {
|
||||
Instrumentation.BeginContext(180, 2, true);
|
||||
WriteLiteral("\r\n");
|
||||
Instrumentation.EndContext();
|
||||
#line 6 "NestedScriptTagTagHelpers.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 6 "NestedScriptTagTagHelpers.cshtml"
|
||||
for(var i = 0; i < 5; i++) {
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
Instrumentation.BeginContext(225, 84, true);
|
||||
WriteLiteral(" <script id=\"nestedScriptTag\" type=\"text/html\">\r\n " +
|
||||
" ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", TagMode.StartTagOnly, "test", async() => {
|
||||
}
|
||||
, StartTagHelperWritingScope, EndTagHelperWritingScope);
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
StartTagHelperWritingScope();
|
||||
WriteLiteral("2000 + ");
|
||||
#line 8 "NestedScriptTagTagHelpers.cshtml"
|
||||
Write(ViewBag.DefaultInterval);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
WriteLiteral(" + 1");
|
||||
__tagHelperStringValueBuffer = EndTagHelperWritingScope();
|
||||
__tagHelperExecutionContext.AddHtmlAttribute("data-interval", Html.Raw(__tagHelperStringValueBuffer.ToString()));
|
||||
__InputTagHelper.Type = "text";
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 8 "NestedScriptTagTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
|
||||
Instrumentation.BeginContext(309, 86, false);
|
||||
await WriteTagHelperAsync(__tagHelperExecutionContext);
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(395, 29, true);
|
||||
WriteLiteral("\r\n </script>\r\n");
|
||||
Instrumentation.EndContext();
|
||||
#line 10 "NestedScriptTagTagHelpers.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
Instrumentation.BeginContext(439, 129, true);
|
||||
WriteLiteral(" <script type=\"text/javascript\">\r\n var tag = \'<input ch" +
|
||||
"ecked=\"true\">\';\r\n </script>\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
}
|
||||
, StartTagHelperWritingScope, EndTagHelperWritingScope);
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__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 </div>\r\n</script>");
|
||||
Instrumentation.EndContext();
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
@addTagHelper "something, nice"
|
||||
|
||||
<script type="text/html">
|
||||
<div data-animation="fade" class="randomNonTagHelperAttribute">
|
||||
<p class="Hello World" data-delay="1000">
|
||||
@for(var i = 0; i < 5; i++) {
|
||||
<script id="nestedScriptTag" type="text/html">
|
||||
<input data-interval="2000 + @ViewBag.DefaultInterval + 1" type="text" checked="true">
|
||||
</script>
|
||||
}
|
||||
<script type="text/javascript">
|
||||
var tag = '<input checked="true">';
|
||||
</script>
|
||||
</p>
|
||||
</div>
|
||||
</script>
|
||||
Loading…
Reference in New Issue