Fix: Nested tag helpers do not work when tag helper prefix is set
This commit is contained in:
parent
db805eb3e3
commit
45732a5dd3
|
|
@ -44,7 +44,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
private readonly Stack<BlockBuilder> _blockStack;
|
||||
private TagHelperBlockTracker _currentTagHelperTracker;
|
||||
private BlockBuilder _currentBlock;
|
||||
private string _currentParentTagName;
|
||||
|
||||
public TagHelperParseTreeRewriter(string tagHelperPrefix, IEnumerable<TagHelperDescriptor> descriptors)
|
||||
{
|
||||
|
|
@ -56,6 +55,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
_htmlAttributeTracker = new List<KeyValuePair<string, string>>();
|
||||
}
|
||||
|
||||
private TagBlockTracker CurrentTracker => _trackerStack.Count > 0 ? _trackerStack.Peek() : null;
|
||||
|
||||
private string CurrentParentTagName => CurrentTracker?.TagName;
|
||||
|
||||
private bool CurrentParentIsTagHelper => CurrentTracker?.IsTagHelper ?? false;
|
||||
|
||||
public Block Rewrite(Block syntaxTree, ErrorSink errorSink)
|
||||
{
|
||||
RewriteTags(syntaxTree, errorSink, depth: 0);
|
||||
|
|
@ -189,7 +194,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
// 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);
|
||||
tagHelperBinding = _tagHelperBinder.GetBinding(
|
||||
tagName,
|
||||
elementAttributes,
|
||||
CurrentParentTagName,
|
||||
CurrentParentIsTagHelper);
|
||||
|
||||
// If there aren't any TagHelperDescriptors registered then we aren't a TagHelper
|
||||
if (tagHelperBinding == null)
|
||||
|
|
@ -257,7 +266,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
tagHelperBinding = _tagHelperBinder.GetBinding(
|
||||
tagName,
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: _currentParentTagName);
|
||||
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.
|
||||
|
|
@ -508,10 +518,20 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return;
|
||||
}
|
||||
|
||||
var currentTracker = _trackerStack.Count > 0 ? _trackerStack.Peek() : null;
|
||||
if (!HasAllowedChildren())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasAllowedChildren() &&
|
||||
!_currentTagHelperTracker.AllowedChildren.Contains(tagName, StringComparer.OrdinalIgnoreCase))
|
||||
var tagHelperBinding = _tagHelperBinder.GetBinding(
|
||||
tagName,
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: CurrentParentTagName,
|
||||
parentIsTagHelper: CurrentParentIsTagHelper);
|
||||
|
||||
// If we found a binding for the current tag, then it is a tag helper. Use the prefixed allowed children to compare.
|
||||
var allowedChildren = tagHelperBinding != null ? _currentTagHelperTracker.PrefixedAllowedChildren : _currentTagHelperTracker.AllowedChildren;
|
||||
if (!allowedChildren.Contains(tagName, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
OnAllowedChildrenTagError(_currentTagHelperTracker, tagName, tagBlock, errorSink);
|
||||
}
|
||||
|
|
@ -812,14 +832,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
private void PushTrackerStack(TagBlockTracker tracker)
|
||||
{
|
||||
_currentParentTagName = tracker.TagName;
|
||||
_trackerStack.Push(tracker);
|
||||
}
|
||||
|
||||
private TagBlockTracker PopTrackerStack()
|
||||
{
|
||||
var poppedTracker = _trackerStack.Pop();
|
||||
_currentParentTagName = _trackerStack.Count > 0 ? _trackerStack.Peek().TagName : null;
|
||||
|
||||
return poppedTracker;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,12 +39,14 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
/// retrieves catch-all <see cref="TagHelperDescriptor"/>s (descriptors that target every tag).</param>
|
||||
/// <param name="attributes">Attributes on the HTML tag.</param>
|
||||
/// <param name="parentTagName">The parent tag name of the given <paramref name="tagName"/> tag.</param>
|
||||
/// <param name="parentIsTagHelper">Is the parent tag of the given <paramref name="tagName"/> tag a tag helper.</param>
|
||||
/// <returns><see cref="TagHelperDescriptor"/>s that apply to the given HTML tag criteria.
|
||||
/// Will return <c>null</c> if no <see cref="TagHelperDescriptor"/>s are a match.</returns>
|
||||
public TagHelperBinding GetBinding(
|
||||
string tagName,
|
||||
IReadOnlyList<KeyValuePair<string, string>> attributes,
|
||||
string parentTagName)
|
||||
string parentTagName,
|
||||
bool parentIsTagHelper)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_tagHelperPrefix) &&
|
||||
(tagName.Length <= _tagHelperPrefix.Length ||
|
||||
|
|
@ -74,11 +76,17 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
}
|
||||
|
||||
var tagNameWithoutPrefix = _tagHelperPrefix != null ? tagName.Substring(_tagHelperPrefix.Length) : tagName;
|
||||
var parentTagNameWithoutPrefix = parentTagName;
|
||||
if (_tagHelperPrefix != null && parentIsTagHelper)
|
||||
{
|
||||
parentTagNameWithoutPrefix = parentTagName.Substring(_tagHelperPrefix.Length);
|
||||
}
|
||||
|
||||
Dictionary<TagHelperDescriptor, IReadOnlyList<TagMatchingRuleDescriptor>> applicableDescriptorMappings = null;
|
||||
foreach (var descriptor in descriptors)
|
||||
{
|
||||
var applicableRules = descriptor.TagMatchingRules.Where(
|
||||
rule => TagHelperMatchingConventions.SatisfiesRule(tagNameWithoutPrefix, parentTagName, attributes, rule));
|
||||
rule => TagHelperMatchingConventions.SatisfiesRule(tagNameWithoutPrefix, parentTagNameWithoutPrefix, attributes, rule));
|
||||
|
||||
if (applicableRules.Any())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
|
||||
public static bool SatisfiesRule(
|
||||
string tagNameWithoutPrefix,
|
||||
string parentTagName,
|
||||
string parentTagNameWithoutPrefix,
|
||||
IEnumerable<KeyValuePair<string, string>> tagAttributes,
|
||||
TagMatchingRuleDescriptor rule)
|
||||
{
|
||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return false;
|
||||
}
|
||||
|
||||
var satisfiesParentTag = SatisfiesParentTag(parentTagName, rule);
|
||||
var satisfiesParentTag = SatisfiesParentTag(parentTagNameWithoutPrefix, rule);
|
||||
if (!satisfiesParentTag)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -89,14 +89,14 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return true;
|
||||
}
|
||||
|
||||
public static bool SatisfiesParentTag(string parentTagName, TagMatchingRuleDescriptor rule)
|
||||
public static bool SatisfiesParentTag(string parentTagNameWithoutPrefix, TagMatchingRuleDescriptor rule)
|
||||
{
|
||||
if (rule == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(rule));
|
||||
}
|
||||
|
||||
if (rule.ParentTag != null && !string.Equals(parentTagName, rule.ParentTag, StringComparison.OrdinalIgnoreCase))
|
||||
if (rule.ParentTag != null && !string.Equals(parentTagNameWithoutPrefix, rule.ParentTag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,13 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
var prefix = documentContext.Prefix ?? string.Empty;
|
||||
Debug.Assert(completionContext.CurrentTagName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
var applicableTagHelperBinding = _tagHelperFactsService.GetTagHelperBinding(documentContext, completionContext.CurrentTagName, completionContext.Attributes, completionContext.CurrentParentTagName);
|
||||
var applicableTagHelperBinding = _tagHelperFactsService.GetTagHelperBinding(
|
||||
documentContext,
|
||||
completionContext.CurrentTagName,
|
||||
completionContext.Attributes,
|
||||
completionContext.CurrentParentTagName,
|
||||
parentIsTagHelper: false);
|
||||
|
||||
var applicableDescriptors = applicableTagHelperBinding?.Descriptors ?? Enumerable.Empty<TagHelperDescriptor>();
|
||||
var unprefixedTagName = completionContext.CurrentTagName.Substring(prefix.Length);
|
||||
|
||||
|
|
@ -227,11 +233,13 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
}
|
||||
|
||||
var prefix = completionContext.DocumentContext.Prefix ?? string.Empty;
|
||||
|
||||
var binding = _tagHelperFactsService.GetTagHelperBinding(
|
||||
completionContext.DocumentContext,
|
||||
completionContext.ContainingTagName,
|
||||
completionContext.Attributes,
|
||||
completionContext.ContainingParentTagName);
|
||||
completionContext.ContainingParentTagName,
|
||||
completionContext.ContainingParentIsTagHelper);
|
||||
|
||||
if (binding == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
TagHelperDocumentContext documentContext,
|
||||
string tagName,
|
||||
IEnumerable<KeyValuePair<string, string>> attributes,
|
||||
string parentTag)
|
||||
string parentTag,
|
||||
bool parentIsTagHelper)
|
||||
{
|
||||
if (documentContext == null)
|
||||
{
|
||||
|
|
@ -39,7 +40,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
|
||||
var prefix = documentContext.Prefix;
|
||||
var tagHelperBinder = new TagHelperBinder(prefix, descriptors);
|
||||
var binding = tagHelperBinder.GetBinding(tagName, attributes.ToList(), parentTag);
|
||||
var binding = tagHelperBinder.GetBinding(tagName, attributes.ToList(), parentTag, parentIsTagHelper);
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
string containingTagName,
|
||||
IEnumerable<KeyValuePair<string, string>> attributes,
|
||||
string containingParentTagName,
|
||||
bool containingParentIsTagHelper,
|
||||
Func<string, bool> inHTMLSchema)
|
||||
{
|
||||
if (documentContext == null)
|
||||
|
|
@ -37,6 +38,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
ContainingTagName = containingTagName;
|
||||
Attributes = attributes;
|
||||
ContainingParentTagName = containingParentTagName;
|
||||
ContainingParentIsTagHelper = containingParentIsTagHelper;
|
||||
InHTMLSchema = inHTMLSchema;
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +52,8 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
|
||||
public string ContainingParentTagName { get; }
|
||||
|
||||
public bool ContainingParentIsTagHelper { get; }
|
||||
|
||||
public Func<string, bool> InHTMLSchema { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
{
|
||||
public abstract class TagHelperFactsService : ILanguageService
|
||||
{
|
||||
public abstract TagHelperBinding GetTagHelperBinding(TagHelperDocumentContext documentContext, string tagName, IEnumerable<KeyValuePair<string, string>> attributes, string parentTag);
|
||||
public abstract TagHelperBinding GetTagHelperBinding(TagHelperDocumentContext documentContext, string tagName, IEnumerable<KeyValuePair<string, string>> attributes, string parentTag, bool parentIsTagHelper);
|
||||
|
||||
public abstract IEnumerable<BoundAttributeDescriptor> GetBoundTagHelperAttributes(TagHelperDocumentContext documentContext, string attributeName, TagHelperBinding binding);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
|
|||
var prefix = documentContext.Prefix ?? string.Empty;
|
||||
Debug.Assert(completionContext.CurrentTagName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
var applicableTagHelperBinding = _tagHelperFactsService.GetTagHelperBinding(documentContext, completionContext.CurrentTagName, completionContext.Attributes, completionContext.CurrentParentTagName);
|
||||
var applicableTagHelperBinding = _tagHelperFactsService.GetTagHelperBinding(
|
||||
documentContext,
|
||||
completionContext.CurrentTagName,
|
||||
completionContext.Attributes,
|
||||
completionContext.CurrentParentTagName);
|
||||
|
||||
var applicableDescriptors = applicableTagHelperBinding?.Descriptors ?? Enumerable.Empty<TagHelperDescriptor>();
|
||||
var unprefixedTagName = completionContext.CurrentTagName.Substring(prefix.Length);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
|
|||
|
||||
var prefix = documentContext.Prefix;
|
||||
var tagHelperBinder = new TagHelperBinder(prefix, descriptors);
|
||||
var binding = tagHelperBinder.GetBinding(tagName, attributes.ToList(), parentTag);
|
||||
var binding = tagHelperBinder.GetBinding(tagName, attributes.ToList(), parentTag, parentIsTagHelper: false);
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,6 +385,99 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
tagHelperPrefix: "th:");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Rewrite_UnderstandsTagHelperPrefixAndAllowedChildrenAndRequireParent()
|
||||
{
|
||||
// Arrange
|
||||
var documentContent = "<th:p><th:strong></th:strong></th:p>";
|
||||
var expectedOutput = new MarkupBlock(
|
||||
new MarkupTagHelperBlock("th:p",
|
||||
new MarkupTagHelperBlock("th:strong")));
|
||||
var descriptors = new TagHelperDescriptor[]
|
||||
{
|
||||
TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
|
||||
.AllowChildTag("strong")
|
||||
.Build(),
|
||||
TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong").RequireParentTag("p"))
|
||||
.Build(),
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
EvaluateData(
|
||||
descriptors,
|
||||
documentContent,
|
||||
expectedOutput,
|
||||
expectedErrors: Enumerable.Empty<RazorError>(),
|
||||
tagHelperPrefix: "th:");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Rewrite_InvalidStructure_UnderstandsTagHelperPrefixAndAllowedChildrenAndRequireParent()
|
||||
{
|
||||
// Arrange
|
||||
var documentContent = "<th:p></th:strong></th:p>";
|
||||
var expectedOutput = new MarkupBlock(
|
||||
new MarkupTagHelperBlock("th:p",
|
||||
new MarkupTagBlock(
|
||||
Factory.Markup("</th:strong>"))));
|
||||
var descriptors = new TagHelperDescriptor[]
|
||||
{
|
||||
TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
|
||||
.AllowChildTag("strong")
|
||||
.Build(),
|
||||
TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong").RequireParentTag("p"))
|
||||
.Build(),
|
||||
};
|
||||
var expectedErrors = new[] {
|
||||
new RazorError(
|
||||
LegacyResources.FormatTagHelpersParseTreeRewriter_FoundMalformedTagHelper("th:strong"),
|
||||
absoluteIndex: 8,
|
||||
lineIndex: 0,
|
||||
columnIndex: 8,
|
||||
length: 9),
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
EvaluateData(
|
||||
descriptors,
|
||||
documentContent,
|
||||
expectedOutput,
|
||||
expectedErrors: expectedErrors,
|
||||
tagHelperPrefix: "th:");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Rewrite_NonTagHelperChild_UnderstandsTagHelperPrefixAndAllowedChildren()
|
||||
{
|
||||
// Arrange
|
||||
var documentContent = "<th:p><strong></strong></th:p>";
|
||||
var expectedOutput = new MarkupBlock(
|
||||
new MarkupTagHelperBlock("th:p",
|
||||
new MarkupTagBlock(
|
||||
Factory.Markup("<strong>")),
|
||||
new MarkupTagBlock(
|
||||
Factory.Markup("</strong>"))));
|
||||
var descriptors = new TagHelperDescriptor[]
|
||||
{
|
||||
TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
|
||||
.AllowChildTag("strong")
|
||||
.Build(),
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
EvaluateData(
|
||||
descriptors,
|
||||
documentContent,
|
||||
expectedOutput,
|
||||
expectedErrors: Enumerable.Empty<RazorError>(),
|
||||
tagHelperPrefix: "th:");
|
||||
}
|
||||
|
||||
public static TheoryData InvalidHtmlScriptBlockData
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var bindingResult = tagHelperBinder.GetBinding(
|
||||
tagName: "th:div",
|
||||
attributes: expectedAttributes,
|
||||
parentTagName: "body");
|
||||
parentTagName: "body",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, bindingResult.Descriptors, TagHelperDescriptorComparer.CaseSensitive);
|
||||
|
|
@ -109,7 +110,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var bindingResult = tagHelperBinder.GetBinding(
|
||||
tagName,
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: parentTagName);
|
||||
parentTagName: parentTagName,
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
Assert.Equal((IEnumerable<TagHelperDescriptor>)expectedDescriptors, bindingResult.Descriptors, TagHelperDescriptorComparer.CaseSensitive);
|
||||
|
|
@ -272,7 +274,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var tagHelperBinder = new TagHelperBinder(null, (IReadOnlyList<TagHelperDescriptor>)availableDescriptors);
|
||||
|
||||
// Act
|
||||
var bindingResult = tagHelperBinder.GetBinding(tagName, providedAttributes, parentTagName: "p");
|
||||
var bindingResult = tagHelperBinder.GetBinding(tagName, providedAttributes, parentTagName: "p", parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
Assert.Equal((IEnumerable<TagHelperDescriptor>)expectedDescriptors, bindingResult?.Descriptors, TagHelperDescriptorComparer.CaseSensitive);
|
||||
|
|
@ -292,7 +294,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var bindingResult = tagHelperBinder.GetBinding(
|
||||
tagName: "th",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
Assert.Null(bindingResult);
|
||||
|
|
@ -312,11 +315,13 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var bindingResultDiv = tagHelperBinder.GetBinding(
|
||||
tagName: "th:div",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
var bindingResultSpan = tagHelperBinder.GetBinding(
|
||||
tagName: "th:span",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(bindingResultDiv.Descriptors);
|
||||
|
|
@ -339,7 +344,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var bindingResult = tagHelperBinder.GetBinding(
|
||||
tagName: "th:div",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(bindingResult.Descriptors);
|
||||
|
|
@ -362,7 +368,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var bindingResult = tagHelperBinder.GetBinding(
|
||||
tagName: "div",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
Assert.Null(bindingResult);
|
||||
|
|
@ -385,7 +392,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var tagHelperBinding = tagHelperBinder.GetBinding(
|
||||
tagName: "foo",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
Assert.Null(tagHelperBinding);
|
||||
|
|
@ -411,11 +419,13 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var divBinding = tagHelperBinder.GetBinding(
|
||||
tagName: "div",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
var spanBinding = tagHelperBinder.GetBinding(
|
||||
tagName: "span",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
// For divs
|
||||
|
|
@ -443,7 +453,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var bindingResult = tagHelperBinder.GetBinding(
|
||||
tagName: "div",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(bindingResult.Descriptors);
|
||||
|
|
@ -470,7 +481,8 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var binding = tagHelperBinder.GetBinding(
|
||||
tagName: "div",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "p");
|
||||
parentTagName: "p",
|
||||
parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
var boundDescriptor = Assert.Single(binding.Descriptors);
|
||||
|
|
@ -479,5 +491,34 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var boundRule = Assert.Single(boundRules);
|
||||
Assert.Equal("div", boundRule.TagName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetBinding_PrefixedParent_ReturnsBinding()
|
||||
{
|
||||
// Arrange
|
||||
var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("div").RequireParentTag("p"))
|
||||
.Build();
|
||||
var pDescriptor = TagHelperDescriptorBuilder.Create("foo2", "SomeAssembly")
|
||||
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
|
||||
.Build();
|
||||
var descriptors = new[] { divDescriptor, pDescriptor };
|
||||
var tagHelperBinder = new TagHelperBinder("th:", descriptors);
|
||||
|
||||
// Act
|
||||
var bindingResult = tagHelperBinder.GetBinding(
|
||||
tagName: "th:div",
|
||||
attributes: Array.Empty<KeyValuePair<string, string>>(),
|
||||
parentTagName: "th:p",
|
||||
parentIsTagHelper: true);
|
||||
|
||||
// Assert
|
||||
var boundDescriptor = Assert.Single(bindingResult.Descriptors);
|
||||
Assert.Same(divDescriptor, boundDescriptor);
|
||||
var boundRules = bindingResult.GetBoundRules(boundDescriptor);
|
||||
var boundRule = Assert.Single(boundRules);
|
||||
Assert.Equal("div", boundRule.TagName);
|
||||
Assert.Equal("p", boundRule.ParentTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -927,6 +927,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
IEnumerable<string> existingCompletions,
|
||||
string containingTagName,
|
||||
string containingParentTagName = "body",
|
||||
bool containingParentIsTagHelper = false,
|
||||
string tagHelperPrefix = "")
|
||||
{
|
||||
var documentContext = TagHelperDocumentContext.Create(tagHelperPrefix, descriptors);
|
||||
|
|
@ -936,6 +937,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
containingTagName,
|
||||
attributes: Enumerable.Empty<KeyValuePair<string, string>>(),
|
||||
containingParentTagName: containingParentTagName,
|
||||
containingParentIsTagHelper: containingParentIsTagHelper,
|
||||
inHTMLSchema: (tag) => tag == "strong" || tag == "b" || tag == "bold" || tag == "li" || tag == "div");
|
||||
|
||||
return completionContext;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
var service = new DefaultTagHelperFactsService();
|
||||
|
||||
// Act
|
||||
var binding = service.GetTagHelperBinding(documentContext, "!a", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null);
|
||||
var binding = service.GetTagHelperBinding(documentContext, "!a", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null, parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
Assert.Null(binding);
|
||||
|
|
@ -73,7 +73,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
};
|
||||
|
||||
// Act
|
||||
var binding = service.GetTagHelperBinding(documentContext, "a", attributes, parentTag: "p");
|
||||
var binding = service.GetTagHelperBinding(documentContext, "a", attributes, parentTag: "p", parentIsTagHelper: false);
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(binding.Descriptors);
|
||||
|
|
@ -109,7 +109,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
};
|
||||
var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
|
||||
var service = new DefaultTagHelperFactsService();
|
||||
var binding = service.GetTagHelperBinding(documentContext, "a", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null);
|
||||
var binding = service.GetTagHelperBinding(documentContext, "a", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null, parentIsTagHelper: false);
|
||||
|
||||
// Act
|
||||
var descriptors = service.GetBoundTagHelperAttributes(documentContext, "asp-route-something", binding);
|
||||
|
|
@ -144,7 +144,7 @@ namespace Microsoft.CodeAnalysis.Razor
|
|||
};
|
||||
var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
|
||||
var service = new DefaultTagHelperFactsService();
|
||||
var binding = service.GetTagHelperBinding(documentContext, "input", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null);
|
||||
var binding = service.GetTagHelperBinding(documentContext, "input", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null, parentIsTagHelper: false);
|
||||
|
||||
// Act
|
||||
var descriptors = service.GetBoundTagHelperAttributes(documentContext, "asp-for", binding);
|
||||
|
|
|
|||
Loading…
Reference in New Issue