Beispiel #1
0
        public override void VisitMarkupAttributeBlock(MarkupAttributeBlockSyntax node)
        {
            Visit(node.NamePrefix);
            AddSemanticRange(node.Name, RazorSemanticTokensLegend.MarkupAttribute);
            Visit(node.NameSuffix);
            AddSemanticRange(node.EqualsToken, RazorSemanticTokensLegend.MarkupOperator);

            Visit(node.ValuePrefix);
            Visit(node.Value);
            Visit(node.ValueSuffix);
        }
Beispiel #2
0
 public override void VisitMarkupAttributeBlock(MarkupAttributeBlockSyntax node)
 {
     WriteBlock(node, FormattingBlockKind.Markup, n =>
     {
         var equalsSyntax          = SyntaxFactory.MarkupTextLiteral(new SyntaxList <SyntaxToken>(node.EqualsToken));
         var mergedAttributePrefix = SyntaxUtilities.MergeTextLiterals(node.NamePrefix, node.Name, node.NameSuffix, equalsSyntax, node.ValuePrefix);
         Visit(mergedAttributePrefix);
         Visit(node.Value);
         Visit(node.ValueSuffix);
     });
 }
Beispiel #3
0
            // Example
            // <input` checked="hello-world @false"`/>
            //  Name=checked
            //  Prefix= checked="
            //  Suffix="
            public override void VisitMarkupAttributeBlock(MarkupAttributeBlockSyntax node)
            {
                var prefixTokens = MergeLiterals(
                    node.NamePrefix?.LiteralTokens,
                    node.Name.LiteralTokens,
                    node.NameSuffix?.LiteralTokens,
                    node.EqualsToken == null ? new SyntaxList <SyntaxToken>() : new SyntaxList <SyntaxToken>(node.EqualsToken),
                    node.ValuePrefix?.LiteralTokens);
                var prefix = (MarkupTextLiteralSyntax)SyntaxFactory.MarkupTextLiteral(prefixTokens).Green.CreateRed(node, node.NamePrefix?.Position ?? node.Name.Position);

                var name = node.Name.GetContent();

                if (name.StartsWith("data-", StringComparison.OrdinalIgnoreCase) &&
                    !_featureFlags.EXPERIMENTAL_AllowConditionalDataDashAttributes)
                {
                    Visit(prefix);
                    Visit(node.Value);
                    Visit(node.ValueSuffix);
                }
                else
                {
                    if (node.Value != null && node.Value.ChildNodes().All(c => c is MarkupLiteralAttributeValueSyntax))
                    {
                        // We need to do what ConditionalAttributeCollapser used to do.
                        var literalAttributeValueNodes = node.Value.ChildNodes().Cast <MarkupLiteralAttributeValueSyntax>().ToArray();
                        var valueTokens = SyntaxListBuilder <SyntaxToken> .Create();

                        for (var i = 0; i < literalAttributeValueNodes.Length; i++)
                        {
                            var mergedValue = MergeAttributeValue(literalAttributeValueNodes[i]);
                            valueTokens.AddRange(mergedValue.LiteralTokens);
                        }
                        var rewritten = SyntaxFactory.MarkupTextLiteral(valueTokens.ToList());

                        var mergedLiterals  = MergeLiterals(prefix?.LiteralTokens, rewritten.LiteralTokens, node.ValueSuffix?.LiteralTokens);
                        var mergedAttribute = SyntaxFactory.MarkupTextLiteral(mergedLiterals).Green.CreateRed(node.Parent, node.Position);
                        Visit(mergedAttribute);
                    }
                    else
                    {
                        _builder.Push(new HtmlAttributeIntermediateNode()
                        {
                            AttributeName = node.Name.GetContent(),
                            Prefix        = prefix.GetContent(),
                            Suffix        = node.ValueSuffix?.GetContent() ?? string.Empty,
                            Source        = BuildSourceSpanFromNode(node),
                        });

                        VisitAttributeValue(node.Value);

                        _builder.Pop();
                    }
                }
            }
Beispiel #4
0
        private static TryParseResult TryParseAttribute(
            string tagName,
            MarkupAttributeBlockSyntax attributeBlock,
            IEnumerable <TagHelperDescriptor> descriptors,
            ErrorSink errorSink,
            HashSet <string> processedBoundAttributeNames)
        {
            // Have a name now. Able to determine correct isBoundNonStringAttribute value.
            var result = CreateTryParseResult(attributeBlock.Name.GetContent(), descriptors, processedBoundAttributeNames);

            if (attributeBlock.ValuePrefix == null)
            {
                // We are purposefully not persisting NoQuotes even for unbound attributes because it is still possible to
                // rewrite the values that introduces a space like in UrlResolutionTagHelper.
                // The other case is it could be an expression, treat NoQuotes and DoubleQuotes equivalently. We purposefully do not persist NoQuotes
                // ValueStyles at code generation time to protect users from rendering dynamic content with spaces
                // that can break attributes.
                // Ex: <tag my-attribute=@value /> where @value results in the test "hello world".
                // This way, the above code would render <tag my-attribute="hello world" />.
                result.AttributeStructure = AttributeStructure.DoubleQuotes;
            }
            else
            {
                var lastToken = attributeBlock.ValuePrefix.GetLastToken();
                switch (lastToken.Kind)
                {
                case SyntaxKind.DoubleQuote:
                    result.AttributeStructure = AttributeStructure.DoubleQuotes;
                    break;

                case SyntaxKind.SingleQuote:
                    result.AttributeStructure = AttributeStructure.SingleQuotes;
                    break;

                default:
                    result.AttributeStructure = AttributeStructure.Minimized;
                    break;
                }
            }

            var attributeValue = attributeBlock.Value;

            if (attributeValue == null)
            {
                var builder = SyntaxListBuilder <RazorSyntaxNode> .Create();

                // Add a marker for attribute value when there are no quotes like, <p class= >
                builder.Add(SyntaxFactory.MarkupTextLiteral(new SyntaxList <SyntaxToken>()));

                attributeValue = SyntaxFactory.GenericBlock(builder.ToList());
            }
            var rewrittenValue = RewriteAttributeValue(result, attributeValue);

            var rewritten = SyntaxFactory.MarkupTagHelperAttribute(
                attributeBlock.NamePrefix,
                attributeBlock.Name,
                attributeBlock.NameSuffix,
                attributeBlock.EqualsToken,
                attributeBlock.ValuePrefix,
                rewrittenValue,
                attributeBlock.ValueSuffix);

            rewritten = rewritten.WithTagHelperAttributeInfo(
                new TagHelperAttributeInfo(result.AttributeName, result.AttributeStructure, result.IsBoundAttribute));

            result.RewrittenAttribute = rewritten;

            return(result);
        }
        private static MarkupTagHelperDirectiveAttributeSyntax RewriteToDirectiveAttribute(
            MarkupAttributeBlockSyntax attributeBlock,
            TryParseResult result,
            MarkupTagHelperAttributeValueSyntax rewrittenValue)
        {
            //
            // Consider, <Foo @bind:param="..." />
            // We're now going to rewrite @bind:param from a regular MarkupAttributeBlock to a MarkupTagHelperDirectiveAttribute.
            // We need to split the name "@bind:param" into four parts,
            // @ - Transition (MetaCode)
            // bind - Name (Text)
            // : - Colon (MetaCode)
            // param - ParameterName (Text)
            //
            var attributeName       = result.AttributeName;
            var attributeNameSyntax = attributeBlock.Name;
            var transition          = SyntaxFactory.RazorMetaCode(
                new SyntaxList <SyntaxToken>(SyntaxFactory.MissingToken(SyntaxKind.Transition)));
            RazorMetaCodeSyntax     colon         = null;
            MarkupTextLiteralSyntax parameterName = null;

            if (attributeName.StartsWith("@", StringComparison.Ordinal))
            {
                attributeName = attributeName.Substring(1);
                var attributeNameToken = SyntaxFactory.Token(SyntaxKind.Text, attributeName);
                attributeNameSyntax = SyntaxFactory.MarkupTextLiteral().AddLiteralTokens(attributeNameToken);

                var transitionToken = SyntaxFactory.Token(SyntaxKind.Transition, "@");
                transition = SyntaxFactory.RazorMetaCode(new SyntaxList <SyntaxToken>(transitionToken));
            }

            if (attributeName.IndexOf(':') != -1)
            {
                var segments = attributeName.Split(new[] { ':' }, 2);

                var attributeNameToken = SyntaxFactory.Token(SyntaxKind.Text, segments[0]);
                attributeNameSyntax = SyntaxFactory.MarkupTextLiteral().AddLiteralTokens(attributeNameToken);

                var colonToken = SyntaxFactory.Token(SyntaxKind.Colon, ":");
                colon = SyntaxFactory.RazorMetaCode(new SyntaxList <SyntaxToken>(colonToken));

                var parameterNameToken = SyntaxFactory.Token(SyntaxKind.Text, segments[1]);
                parameterName = SyntaxFactory.MarkupTextLiteral().AddLiteralTokens(parameterNameToken);
            }

            var rewritten = SyntaxFactory.MarkupTagHelperDirectiveAttribute(
                attributeBlock.NamePrefix,
                transition,
                attributeNameSyntax,
                colon,
                parameterName,
                attributeBlock.NameSuffix,
                attributeBlock.EqualsToken,
                attributeBlock.ValuePrefix,
                rewrittenValue,
                attributeBlock.ValueSuffix);

            rewritten = rewritten.WithTagHelperAttributeInfo(
                new TagHelperAttributeInfo(result.AttributeName, parameterName?.GetContent(), result.AttributeStructure, result.IsBoundAttribute, isDirectiveAttribute: true));

            return(rewritten);
        }
Beispiel #6
0
 public override void VisitMarkupAttributeBlock(MarkupAttributeBlockSyntax node)
 {
     AddSemanticRange(node.Name, SyntaxKind.MarkupAttributeBlock);
     AddSemanticRange(node.EqualsToken);
     base.VisitMarkupAttributeBlock(node);
 }