// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Web.Razor.Editor; using System.Web.Razor.Generator; using System.Web.Razor.Parser; using System.Web.Razor.Parser.SyntaxTree; using System.Web.Razor.Test.Framework; using System.Web.Razor.Text; using Xunit; namespace System.Web.Razor.Test.Parser.Html { public class HtmlAttributeTest : CsHtmlMarkupParserTestBase { [Fact] public void SimpleLiteralAttribute() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), suffix: new LocationTagged("'", 12, 0, 12)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("Foo").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(String.Empty, 9, 0, 9), value: new LocationTagged("Foo", 9, 0, 9))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void MultiPartLiteralAttribute() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), suffix: new LocationTagged("'", 20, 0, 20)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("Foo").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(String.Empty, 9, 0, 9), value: new LocationTagged("Foo", 9, 0, 9))), Factory.Markup(" Bar").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(" ", 12, 0, 12), value: new LocationTagged("Bar", 13, 0, 13))), Factory.Markup(" Baz").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(" ", 16, 0, 16), value: new LocationTagged("Baz", 17, 0, 17))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void DoubleQuotedLiteralAttribute() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href=\"", 2, 0, 2), suffix: new LocationTagged("\"", 20, 0, 20)), Factory.Markup(" href=\"").With(SpanCodeGenerator.Null), Factory.Markup("Foo").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(String.Empty, 9, 0, 9), value: new LocationTagged("Foo", 9, 0, 9))), Factory.Markup(" Bar").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(" ", 12, 0, 12), value: new LocationTagged("Bar", 13, 0, 13))), Factory.Markup(" Baz").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(" ", 16, 0, 16), value: new LocationTagged("Baz", 17, 0, 17))), Factory.Markup("\"").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void UnquotedLiteralAttribute() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href=", 2, 0, 2), suffix: new LocationTagged(String.Empty, 11, 0, 11)), Factory.Markup(" href=").With(SpanCodeGenerator.Null), Factory.Markup("Foo").With(new LiteralAttributeCodeGenerator(prefix: new LocationTagged(String.Empty, 8, 0, 8), value: new LocationTagged("Foo", 8, 0, 8)))), Factory.Markup(" Bar Baz />").Accepts(AcceptedCharacters.None))); } [Fact] public void SimpleExpressionAttribute() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), suffix: new LocationTagged("'", 13, 0, 13)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 9, 0, 9), 9, 0, 9), new ExpressionBlock( Factory.CodeTransition(), Factory.Code("foo") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void MultiValueExpressionAttribute() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), suffix: new LocationTagged("'", 22, 0, 22)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 9, 0, 9), 9, 0, 9), new ExpressionBlock( Factory.CodeTransition(), Factory.Code("foo") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup(" bar").With(new LiteralAttributeCodeGenerator(new LocationTagged(" ", 13, 0, 13), new LocationTagged("bar", 14, 0, 14))), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(" ", 17, 0, 17), 18, 0, 18), Factory.Markup(" ").With(SpanCodeGenerator.Null), new ExpressionBlock( Factory.CodeTransition(), Factory.Code("baz") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void VirtualPathAttributesWorkWithConditionalAttributes() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), suffix: new LocationTagged("'", 23, 0, 23)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 9, 0, 9), 9, 0, 9), new ExpressionBlock( Factory.CodeTransition(), Factory.Code("foo") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup(" ~/Foo/Bar") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(" ", 13, 0, 13), new LocationTagged(new ResolveUrlCodeGenerator(), 14, 0, 14))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void UnquotedAttributeWithCodeWithSpacesInBlock() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" value=", 6, 0, 6), suffix: new LocationTagged(String.Empty, 17, 0, 17)), Factory.Markup(" value=").With(SpanCodeGenerator.Null), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 13, 0, 13), 13, 0, 13), new ExpressionBlock( Factory.CodeTransition(), Factory.Code("foo") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace)))), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void UnquotedAttributeWithCodeWithSpacesInDocument() { ParseDocumentTest("", new MarkupBlock( Factory.Markup("(" value=", 6, 0, 6), suffix: new LocationTagged(String.Empty, 17, 0, 17)), Factory.Markup(" value=").With(SpanCodeGenerator.Null), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 13, 0, 13), 13, 0, 13), new ExpressionBlock( Factory.CodeTransition(), Factory.Code("foo") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace)))), Factory.Markup(" />"))); } [Fact] public void ConditionalAttributeCollapserDoesNotRemoveUrlAttributeValues() { // Act ParserResults results = ParseDocument(""); Block rewritten = new ConditionalAttributeCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(results.Document); rewritten = new MarkupCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritten); // Assert Assert.Equal(0, results.ParserErrors.Count); EvaluateParseTree(rewritten, new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), suffix: new LocationTagged("'", 18, 0, 18)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/Bar") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 9, 0, 9), new LocationTagged(new ResolveUrlCodeGenerator(), 9, 0, 9))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />"))); } [Fact] public void ConditionalAttributesDoNotCreateExtraDataForEntirelyLiteralAttribute() { // Arrange const string code = #region Big Block o' code @"

Title

As the author, you can edit or remove this photo.

Description
The uploader did not provide a description for this photo.
Uploaded by
user.DisplayName
Upload date
photo.UploadDate
Gallery
gallery.Name
Tags
  • This photo has no tags.
edit tags

Download full photo ((photo.FileSize / 1024) KB)

Nobody has commented on this photo

  1. comment.DisplayName commented at comment.CommentDate:

    comment.CommentText

Post new comment

"; #endregion // Act ParserResults results = ParseDocument(code); Block rewritten = new ConditionalAttributeCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(results.Document); rewritten = new MarkupCollapser(new HtmlMarkupParser().BuildSpan).Rewrite(rewritten); // Assert Assert.Equal(0, results.ParserErrors.Count); EvaluateParseTree(rewritten, new MarkupBlock(Factory.Markup(code))); } [Fact] public void ConditionalAttributesAreDisabledForDataAttributesInBlock() { ParseBlockTest("", new MarkupBlock( Factory.Markup("").Accepts(AcceptedCharacters.None))); } [Fact] public void ConditionalAttributesAreDisabledForDataAttributesInDocument() { ParseDocumentTest("", new MarkupBlock( Factory.Markup(""))); } } }