コード例 #1
0
            // Internal for testing
            internal IReadOnlyList <KeyValuePair <string, string> > GetAttributeNameValuePairs(MarkupTagBlockSyntax tagBlock)
            {
                // Need to calculate how many children we should take that represent the attributes.
                var childrenOffset = IsPartialTag(tagBlock) ? 0 : 1;
                var childCount     = tagBlock.Children.Count - childrenOffset;

                if (childCount <= 1)
                {
                    return(Array.Empty <KeyValuePair <string, string> >());
                }

                _htmlAttributeTracker.Clear();

                var attributes = _htmlAttributeTracker;

                for (var i = 1; i < childCount; i++)
                {
                    if (tagBlock.Children[i] is CSharpCodeBlockSyntax)
                    {
                        // Code blocks in the attribute area of tags mangles following attributes.
                        // It's also not supported by TagHelpers, bail early to avoid creating bad attribute value pairs.
                        break;
                    }

                    if (tagBlock.Children[i] is MarkupMinimizedAttributeBlockSyntax minimizedAttributeBlock)
                    {
                        if (minimizedAttributeBlock.Name == null)
                        {
                            _attributeValueBuilder.Append(InvalidAttributeValueMarker);
                            continue;
                        }

                        var minimizedAttribute = new KeyValuePair <string, string>(minimizedAttributeBlock.Name.GetContent(), string.Empty);
                        attributes.Add(minimizedAttribute);
                        continue;
                    }

                    if (!(tagBlock.Children[i] is MarkupAttributeBlockSyntax attributeBlock))
                    {
                        // If the parser thought these aren't attributes, we don't care about them. Move on.
                        continue;
                    }

                    if (attributeBlock.Name == null)
                    {
                        _attributeValueBuilder.Append(InvalidAttributeValueMarker);
                        continue;
                    }

                    if (attributeBlock.Value != null)
                    {
                        for (var j = 0; j < attributeBlock.Value.Children.Count; j++)
                        {
                            var child = attributeBlock.Value.Children[j];
                            if (child is MarkupLiteralAttributeValueSyntax literalValue)
                            {
                                _attributeValueBuilder.Append(literalValue.GetContent());
                            }
                            else
                            {
                                _attributeValueBuilder.Append(InvalidAttributeValueMarker);
                            }
                        }
                    }

                    var attributeName  = attributeBlock.Name.GetContent();
                    var attributeValue = _attributeValueBuilder.ToString();
                    var attribute      = new KeyValuePair <string, string>(attributeName, attributeValue);
                    attributes.Add(attribute);

                    _attributeValueBuilder.Clear();
                }

                return(attributes);
            }
コード例 #2
0
            private SourceLocation GetTagDeclarationErrorStart(MarkupTagBlockSyntax tagBlock)
            {
                var advanceBy = IsEndTag(tagBlock) ? "</" : "<";

                return(SourceLocationTracker.Advance(tagBlock.GetSourceLocation(_source), advanceBy));
            }
コード例 #3
0
            private bool TryRewriteTagHelperEnd(MarkupTagBlockSyntax tagBlock, out MarkupTagHelperEndTagSyntax rewritten)
            {
                rewritten = null;
                var tagName = tagBlock.GetTagName();

                // Could not determine tag name, it can't be a TagHelper, continue on and track the element.
                if (tagName == null)
                {
                    return(false);
                }

                var tracker      = CurrentTagHelperTracker;
                var tagNameScope = tracker?.TagName ?? string.Empty;

                if (!IsPotentialTagHelper(tagName, tagBlock))
                {
                    return(false);
                }

                // Validate that our end tag matches the currently scoped tag, if not we may need to error.
                if (tagNameScope.Equals(tagName, StringComparison.OrdinalIgnoreCase))
                {
                    // If there are additional end tags required before we can build our block it means we're in a
                    // situation like this: <myth req="..."><myth></myth></myth> where we're at the inside </myth>.
                    if (tracker.OpenMatchingTags > 0)
                    {
                        tracker.OpenMatchingTags--;

                        return(false);
                    }

                    ValidateTagSyntax(tagName, tagBlock);

                    _trackerStack.Pop();
                }
                else
                {
                    var tagHelperBinding = _tagHelperBinder.GetBinding(
                        tagName,
                        attributes: Array.Empty <KeyValuePair <string, string> >(),
                        parentTagName: CurrentParentTagName,
                        parentIsTagHelper: CurrentParentIsTagHelper);

                    // If there are not TagHelperDescriptors associated with the end tag block that also have no
                    // required attributes then it means we can't be a TagHelper, bail out.
                    if (tagHelperBinding == null)
                    {
                        return(false);
                    }

                    foreach (var descriptor in tagHelperBinding.Descriptors)
                    {
                        var boundRules  = tagHelperBinding.GetBoundRules(descriptor);
                        var invalidRule = boundRules.FirstOrDefault(rule => rule.TagStructure == TagStructure.WithoutEndTag);

                        if (invalidRule != null)
                        {
                            // End tag TagHelper that states it shouldn't have an end tag.
                            _errorSink.OnError(
                                RazorDiagnosticFactory.CreateParsing_TagHelperMustNotHaveAnEndTag(
                                    new SourceSpan(SourceLocationTracker.Advance(tagBlock.GetSourceLocation(_source), "</"), tagName.Length),
                                    tagName,
                                    descriptor.DisplayName,
                                    invalidRule.TagStructure));

                            return(false);
                        }
                    }
                }

                rewritten = SyntaxFactory.MarkupTagHelperEndTag(tagBlock.Children);

                return(true);
            }
コード例 #4
0
            private bool TryRewriteTagHelperStart(MarkupTagBlockSyntax tagBlock, out MarkupTagHelperStartTagSyntax rewritten, out TagHelperInfo tagHelperInfo)
            {
                rewritten     = null;
                tagHelperInfo = null;

                // Get tag name of the current block
                var tagName = tagBlock.GetTagName();

                // Could not determine tag name, it can't be a TagHelper, continue on and track the element.
                if (tagName == null)
                {
                    return(false);
                }

                TagHelperBinding tagHelperBinding;

                if (!IsPotentialTagHelper(tagName, tagBlock))
                {
                    return(false);
                }

                var tracker      = CurrentTagHelperTracker;
                var tagNameScope = tracker?.TagName ?? string.Empty;

                // We're now in a start tag block, we first need to see if the tag block is a tag helper.
                var elementAttributes = GetAttributeNameValuePairs(tagBlock);

                tagHelperBinding = _tagHelperBinder.GetBinding(
                    tagName,
                    elementAttributes,
                    CurrentParentTagName,
                    CurrentParentIsTagHelper);

                // If there aren't any TagHelperDescriptors registered then we aren't a TagHelper
                if (tagHelperBinding == null)
                {
                    // If the current tag matches the current TagHelper scope it means the parent TagHelper matched
                    // all the required attributes but the current one did not; therefore, we need to increment the
                    // OpenMatchingTags counter for current the TagHelperBlock so we don't end it too early.
                    // ex: <myth req="..."><myth></myth></myth> We don't want the first myth to close on the inside
                    // tag.
                    if (string.Equals(tagNameScope, tagName, StringComparison.OrdinalIgnoreCase))
                    {
                        tracker.OpenMatchingTags++;
                    }

                    return(false);
                }

                ValidateParentAllowsTagHelper(tagName, tagBlock);
                ValidateBinding(tagHelperBinding, tagName, tagBlock);

                // We're in a start TagHelper block.
                var validTagStructure = ValidateTagSyntax(tagName, tagBlock);

                var startTag = TagHelperBlockRewriter.Rewrite(
                    tagName,
                    validTagStructure,
                    _featureFlags,
                    tagBlock,
                    tagHelperBinding,
                    _errorSink,
                    _source);

                var tagMode = TagHelperBlockRewriter.GetTagMode(tagBlock, tagHelperBinding, _errorSink);

                tagHelperInfo = new TagHelperInfo(tagName, tagMode, tagHelperBinding);
                rewritten     = startTag;

                return(true);
            }
コード例 #5
0
 public override void VisitMarkupTagBlock(MarkupTagBlockSyntax node)
 {
     WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupTagBlock);
 }
コード例 #6
0
 public static bool IsSelfClosing(this MarkupTagBlockSyntax tagBlock)
 {
     return(IsSelfClosingCore(tagBlock));
 }
コード例 #7
0
 public static string GetTagName(this MarkupTagBlockSyntax tagBlock)
 {
     return(GetTagNameCore(tagBlock));
 }