Esempio n. 1
0
        public void WriteTagHelperHtmlAttribute_DesignTime_WritesNothing()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension()
            {
                DesignTime = true
            };
            var context = TestCodeRenderingContext.CreateDesignTime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperHtmlAttributeIntermediateNode()
            {
                AttributeName      = "name",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                Children           =
                {
                    new HtmlAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.Html, Content = "Blah-"
                      } }
                    },
                    new CSharpCodeAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "\"Foo\"",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperHtmlAttribute(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"Render Children
Render Children
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public void WriteTagHelperHtmlAttribute_Runtime_DynamicAttribute_RendersCorrectly()
        {
            // Arrange
            var extension = new DefaultTagHelperTargetExtension();
            var context   = TestCodeRenderingContext.CreateRuntime();

            var tagHelperNode = new TagHelperIntermediateNode();
            var node          = new DefaultTagHelperHtmlAttributeIntermediateNode()
            {
                AttributeName      = "name",
                AttributeStructure = AttributeStructure.DoubleQuotes,
                Children           =
                {
                    new HtmlAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.Html, Content = "Blah-"
                      } }
                    },
                    new CSharpCodeAttributeValueIntermediateNode()
                    {
                        Children ={ new IntermediateToken                {
                          Kind = TokenKind.CSharp, Content = "\"Foo\"",
                      } },
                    }
                }
            };

            tagHelperNode.Children.Add(node);
            Push(context, tagHelperNode);

            // Act
            extension.WriteTagHelperHtmlAttribute(context, node);

            // Assert
            var csharp = context.CodeWriter.GenerateCode();

            Assert.Equal(
                @"BeginAddHtmlAttributeValues(__tagHelperExecutionContext, ""name"", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
Render Children
Render Children
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
",
                csharp,
                ignoreLineEndingDifferences: true);
        }
        public PreallocatedTagHelperHtmlAttributeValueIntermediateNode(DefaultTagHelperHtmlAttributeIntermediateNode htmlAttributeNode)
        {
            if (htmlAttributeNode == null)
            {
                throw new ArgumentNullException(nameof(htmlAttributeNode));
            }

            Source = htmlAttributeNode.Source;

            for (var i = 0; i < htmlAttributeNode.Children.Count; i++)
            {
                Children.Add(htmlAttributeNode.Children[i]);
            }

            for (var i = 0; i < htmlAttributeNode.Diagnostics.Count; i++)
            {
                Diagnostics.Add(htmlAttributeNode.Diagnostics[i]);
            }
        }
        public void WriteTagHelperHtmlAttribute(CodeRenderingContext context, DefaultTagHelperHtmlAttributeIntermediateNode node)
        {
            if (context.Parent as TagHelperIntermediateNode == null)
            {
                var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode));
                throw new InvalidOperationException(message);
            }

            if (context.Options.DesignTime)
            {
                context.RenderChildren(node);
            }
            else
            {
                var attributeValueStyleParameter = $"{HtmlAttributeValueStyleTypeName}.{node.AttributeStructure}";
                var isConditionalAttributeValue  = node.Children.Any(
                    child => child is CSharpExpressionAttributeValueIntermediateNode || child is CSharpCodeAttributeValueIntermediateNode);

                // All simple text and minimized attributes will be pre-allocated.
                if (isConditionalAttributeValue)
                {
                    // Dynamic attribute value should be run through the conditional attribute removal system. It's
                    // unbound and contains C#.

                    // TagHelper attribute rendering is buffered by default. We do not want to write to the current
                    // writer.
                    var valuePieceCount = node.Children.Count(
                        child =>
                        child is HtmlAttributeValueIntermediateNode ||
                        child is CSharpExpressionAttributeValueIntermediateNode ||
                        child is CSharpCodeAttributeValueIntermediateNode ||
                        child is ExtensionIntermediateNode);

                    context.CodeWriter
                    .WriteStartMethodInvocation(BeginAddHtmlAttributeValuesMethodName)
                    .Write(ExecutionContextVariableName)
                    .WriteParameterSeparator()
                    .WriteStringLiteral(node.AttributeName)
                    .WriteParameterSeparator()
                    .Write(valuePieceCount.ToString(CultureInfo.InvariantCulture))
                    .WriteParameterSeparator()
                    .Write(attributeValueStyleParameter)
                    .WriteEndMethodInvocation();

                    context.RenderChildren(node, new TagHelperHtmlAttributeRuntimeNodeWriter());

                    context.CodeWriter
                    .WriteMethodInvocation(
                        EndAddHtmlAttributeValuesMethodName,
                        ExecutionContextVariableName);
                }
                else
                {
                    // This is a data-* attribute which includes C#. Do not perform the conditional attribute removal or
                    // other special cases used when IsDynamicAttributeValue(). But the attribute must still be buffered to
                    // determine its final value.

                    // Attribute value is not plain text, must be buffered to determine its final value.
                    context.CodeWriter.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName);

                    // We're building a writing scope around the provided chunks which captures everything written from the
                    // page. Therefore, we do not want to write to any other buffer since we're using the pages buffer to
                    // ensure we capture all content that's written, directly or indirectly.
                    context.RenderChildren(node, new RuntimeNodeWriter());

                    context.CodeWriter
                    .WriteStartAssignment(StringValueBufferVariableName)
                    .WriteMethodInvocation(EndWriteTagHelperAttributeMethodName)
                    .WriteStartInstanceMethodInvocation(
                        ExecutionContextVariableName,
                        ExecutionContextAddHtmlAttributeMethodName)
                    .WriteStringLiteral(node.AttributeName)
                    .WriteParameterSeparator()
                    .WriteStartMethodInvocation(MarkAsHtmlEncodedMethodName)
                    .Write(StringValueBufferVariableName)
                    .WriteEndMethodInvocation(endLine: false)
                    .WriteParameterSeparator()
                    .Write(attributeValueStyleParameter)
                    .WriteEndMethodInvocation();
                }
            }
        }