diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs index 7c6fe4192c..0610e40ce6 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers // https://github.com/aspnet/Razor/issues/165 public static ICollection InvalidNonWhitespaceNameCharacters { get; } = new HashSet( - new[] { '@', '!', '<', '/', '?', '[', '>', ']', '=', '"', '\'' }); + new[] { '@', '!', '<', '/', '?', '[', '>', ']', '=', '"', '\'', '*' }); /// /// Creates a from the given . @@ -169,6 +169,25 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers bool targetingAttributes, ErrorSink errorSink) { + if (!targetingAttributes && + string.Equals( + name, + TagHelperDescriptorProvider.ElementCatchAllTarget, + StringComparison.OrdinalIgnoreCase)) + { + // '*' as the entire name is OK in the TargetElement catch-all case. + return true; + } + else if (targetingAttributes && + name.EndsWith( + TagHelperDescriptorProvider.RequiredAttributeWildcardSuffix, + StringComparison.OrdinalIgnoreCase)) + { + // A single '*' at the end of a required attribute is valid; everywhere else is invalid. Strip it from + // the end so we can validate the rest of the name. + name = name.Substring(0, name.Length - 1); + } + var targetName = targetingAttributes ? Resources.TagHelperDescriptorFactory_Attribute : Resources.TagHelperDescriptorFactory_Tag; diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TargetElementAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TargetElementAttribute.cs index a35f4e6b1b..116ba65a4a 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TargetElementAttribute.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TargetElementAttribute.cs @@ -12,16 +12,16 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] public sealed class TargetElementAttribute : Attribute { - public const string CatchAllDescriptorTarget = TagHelperDescriptorProvider.CatchAllDescriptorTarget; + public const string ElementCatchAllTarget = TagHelperDescriptorProvider.ElementCatchAllTarget; /// /// Instantiates a new instance of the class with /// set to *. /// - /// A * value indicates an + /// A * value indicates an /// that targets all HTML elements with the required . public TargetElementAttribute() - : this(CatchAllDescriptorTarget) + : this(ElementCatchAllTarget) { } @@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers /// /// The HTML tag the targets. /// - /// A * value indicates an + /// A * value indicates an /// that targets all HTML elements with the required . public TargetElementAttribute(string tag) { @@ -41,14 +41,17 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers /// /// The HTML tag the targets. /// - /// A * value indicates an + /// A * value indicates an /// that targets all HTML elements with the required . public string Tag { get; } /// - /// A comma-separated of attributes the HTML element must contain for the + /// A comma-separated of attribute names the HTML element must contain for the /// to run. /// + /// + /// * at the end of an attribute name acts as a prefix match. + /// public string Attributes { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptor.cs b/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptor.cs index 384d5e91b6..80d07b2028 100644 --- a/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptor.cs +++ b/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptor.cs @@ -133,6 +133,9 @@ namespace Microsoft.AspNet.Razor.TagHelpers /// /// The list of required attribute names the tag helper expects to target an element. /// + /// + /// * at the end of an attribute name acts as a prefix match. + /// public IReadOnlyList RequiredAttributes { get; private set; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorProvider.cs b/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorProvider.cs index 5d60782572..38ce94c95f 100644 --- a/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorProvider.cs +++ b/src/Microsoft.AspNet.Razor/TagHelpers/TagHelperDescriptorProvider.cs @@ -12,7 +12,9 @@ namespace Microsoft.AspNet.Razor.TagHelpers /// public class TagHelperDescriptorProvider { - public const string CatchAllDescriptorTarget = "*"; + public const string ElementCatchAllTarget = "*"; + + public static readonly string RequiredAttributeWildcardSuffix = "*"; private IDictionary> _registrations; private string _tagHelperPrefix; @@ -55,7 +57,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers IEnumerable descriptors; // Ensure there's a HashSet to use. - if (!_registrations.TryGetValue(CatchAllDescriptorTarget, out catchAllDescriptors)) + if (!_registrations.TryGetValue(ElementCatchAllTarget, out catchAllDescriptors)) { descriptors = new HashSet(TagHelperDescriptorComparer.Default); } @@ -66,9 +68,9 @@ namespace Microsoft.AspNet.Razor.TagHelpers // If the requested tag name is the catch-all target, we shouldn't do the work of concatenating extra // descriptors. - if (!tagName.Equals(CatchAllDescriptorTarget, StringComparison.OrdinalIgnoreCase)) + if (!tagName.Equals(ElementCatchAllTarget, StringComparison.OrdinalIgnoreCase)) { - // If we have a tag name associated with the requested name, we need to combine matchingDescriptors + // If we have a tag name associated with the requested name, we need to combine matchingDescriptors // with all the catch-all descriptors. HashSet matchingDescriptors; if (_registrations.TryGetValue(tagName, out matchingDescriptors)) @@ -91,7 +93,23 @@ namespace Microsoft.AspNet.Razor.TagHelpers { foreach (var requiredAttribute in descriptor.RequiredAttributes) { - if (!attributeNames.Contains(requiredAttribute, StringComparer.OrdinalIgnoreCase)) + // '*' at the end of a required attribute indicates: apply to attributes prefixed with the + // required attribute value. + if (requiredAttribute.EndsWith( + RequiredAttributeWildcardSuffix, + StringComparison.OrdinalIgnoreCase)) + { + var prefix = requiredAttribute.Substring(0, requiredAttribute.Length - 1); + + if (!attributeNames.Any( + attributeName => + attributeName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) && + !string.Equals(attributeName, prefix, StringComparison.OrdinalIgnoreCase))) + { + return false; + } + } + else if (!attributeNames.Contains(requiredAttribute, StringComparer.OrdinalIgnoreCase)) { return false; } @@ -111,8 +129,8 @@ namespace Microsoft.AspNet.Razor.TagHelpers } var registrationKey = - string.Equals(descriptor.TagName, CatchAllDescriptorTarget, StringComparison.Ordinal) ? - CatchAllDescriptorTarget : + string.Equals(descriptor.TagName, ElementCatchAllTarget, StringComparison.Ordinal) ? + ElementCatchAllTarget : descriptor.FullTagName; // Ensure there's a HashSet to add the descriptor to. diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs index 06520824a7..ea2d645178 100644 --- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Reflection; using Microsoft.AspNet.Razor.TagHelpers; @@ -29,7 +30,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers new[] { new TagHelperDescriptor( - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, typeof(AttributeTargetingTagHelper).FullName, AssemblyName, attributes, @@ -41,7 +42,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers new[] { new TagHelperDescriptor( - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, typeof(MultiAttributeTargetingTagHelper).FullName, AssemblyName, attributes, @@ -53,13 +54,13 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers new[] { new TagHelperDescriptor( - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, typeof(MultiAttributeAttributeTargetingTagHelper).FullName, AssemblyName, attributes, requiredAttributes: new[] { "custom" }), new TagHelperDescriptor( - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, typeof(MultiAttributeAttributeTargetingTagHelper).FullName, AssemblyName, attributes, @@ -71,7 +72,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers new[] { new TagHelperDescriptor( - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, typeof(InheritedAttributeTargetingTagHelper).FullName, AssemblyName, attributes, @@ -168,6 +169,30 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers requiredAttributes: new[] { "class", "style" }), } }, + { + typeof(AttributeWildcardTargetingTagHelper), + new[] + { + new TagHelperDescriptor( + TagHelperDescriptorProvider.ElementCatchAllTarget, + typeof(AttributeWildcardTargetingTagHelper).FullName, + AssemblyName, + attributes, + requiredAttributes: new[] { "class*" }) + } + }, + { + typeof(MultiAttributeWildcardTargetingTagHelper), + new[] + { + new TagHelperDescriptor( + TagHelperDescriptorProvider.ElementCatchAllTarget, + typeof(MultiAttributeWildcardTargetingTagHelper).FullName, + AssemblyName, + attributes, + requiredAttributes: new[] { "class*", "style*" }) + } + }, }; } } @@ -1381,51 +1406,65 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers onNameError("'he'lo'", "'"), } }, + { "hello*", new[] { onNameError("hello*", "*") } }, + { "*hello", new[] { onNameError("*hello", "*") } }, + { "he*lo", new[] { onNameError("he*lo", "*") } }, + { + "*he*lo*", + new[] + { + onNameError("*he*lo*", "*"), + onNameError("*he*lo*", "*"), + onNameError("*he*lo*", "*"), + } + }, { Environment.NewLine, new[] { whitespaceErrorString } }, { "\t", new[] { whitespaceErrorString } }, { " \t ", new[] { whitespaceErrorString } }, { " ", new[] { whitespaceErrorString } }, { Environment.NewLine + " ", new[] { whitespaceErrorString } }, { - "! \t\r\n@/<>?[]=\"'", + "! \t\r\n@/<>?[]=\"'*", new[] { - onNameError("! \t\r\n@/<>?[]=\"'", "!"), - onNameError("! \t\r\n@/<>?[]=\"'", " "), - onNameError("! \t\r\n@/<>?[]=\"'", "\t"), - onNameError("! \t\r\n@/<>?[]=\"'", "\r"), - onNameError("! \t\r\n@/<>?[]=\"'", "\n"), - onNameError("! \t\r\n@/<>?[]=\"'", "@"), - onNameError("! \t\r\n@/<>?[]=\"'", "/"), - onNameError("! \t\r\n@/<>?[]=\"'", "<"), - onNameError("! \t\r\n@/<>?[]=\"'", ">"), - onNameError("! \t\r\n@/<>?[]=\"'", "?"), - onNameError("! \t\r\n@/<>?[]=\"'", "["), - onNameError("! \t\r\n@/<>?[]=\"'", "]"), - onNameError("! \t\r\n@/<>?[]=\"'", "="), - onNameError("! \t\r\n@/<>?[]=\"'", "\""), - onNameError("! \t\r\n@/<>?[]=\"'", "'"), + onNameError("! \t\r\n@/<>?[]=\"'*", "!"), + onNameError("! \t\r\n@/<>?[]=\"'*", " "), + onNameError("! \t\r\n@/<>?[]=\"'*", "\t"), + onNameError("! \t\r\n@/<>?[]=\"'*", "\r"), + onNameError("! \t\r\n@/<>?[]=\"'*", "\n"), + onNameError("! \t\r\n@/<>?[]=\"'*", "@"), + onNameError("! \t\r\n@/<>?[]=\"'*", "/"), + onNameError("! \t\r\n@/<>?[]=\"'*", "<"), + onNameError("! \t\r\n@/<>?[]=\"'*", ">"), + onNameError("! \t\r\n@/<>?[]=\"'*", "?"), + onNameError("! \t\r\n@/<>?[]=\"'*", "["), + onNameError("! \t\r\n@/<>?[]=\"'*", "]"), + onNameError("! \t\r\n@/<>?[]=\"'*", "="), + onNameError("! \t\r\n@/<>?[]=\"'*", "\""), + onNameError("! \t\r\n@/<>?[]=\"'*", "'"), + onNameError("! \t\r\n@/<>?[]=\"'*", "*"), } }, { - "! \tv\ra\nl@i/d<>?[]=\"'", + "! \tv\ra\nl@i/d<>?[]=\"'*", new[] { - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "!"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", " "), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\t"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\r"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\n"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "@"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "/"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "<"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", ">"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "?"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "["), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "]"), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "="), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "\""), - onNameError("! \tv\ra\nl@i/d<>?[]=\"'", "'"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "!"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", " "), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "\t"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "\r"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "\n"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "@"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "/"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "<"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", ">"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "?"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "["), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "]"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "="), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "\""), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "'"), + onNameError("! \tv\ra\nl@i/d<>?[]=\"'*", "*"), } }, }; @@ -1441,6 +1480,16 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers return data; } + [TargetElement(Attributes = "class*")] + private class AttributeWildcardTargetingTagHelper : TagHelper + { + } + + [TargetElement(Attributes = "class*,style*")] + private class MultiAttributeWildcardTargetingTagHelper : TagHelper + { + } + [TargetElement(Attributes = "class")] private class AttributeTargetingTagHelper : TagHelper { diff --git a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperDescriptorProviderTest.cs b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperDescriptorProviderTest.cs index 7ec15fddb6..599c71e5cb 100644 --- a/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperDescriptorProviderTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperDescriptorProviderTest.cs @@ -25,20 +25,34 @@ namespace Microsoft.AspNet.Razor.TagHelpers assemblyName: "SomeAssembly", attributes: Enumerable.Empty(), requiredAttributes: new[] { "class", "style" }); + var inputWildcardPrefixDescriptor = new TagHelperDescriptor( + tagName: "input", + typeName: "InputWildCardAttribute", + assemblyName: "SomeAssembly", + attributes: Enumerable.Empty(), + requiredAttributes: new[] { "nodashprefix*" }); var catchAllDescriptor = new TagHelperDescriptor( - tagName: TagHelperDescriptorProvider.CatchAllDescriptorTarget, + tagName: TagHelperDescriptorProvider.ElementCatchAllTarget, typeName: "CatchAllTagHelper", assemblyName: "SomeAssembly", attributes: Enumerable.Empty(), requiredAttributes: new[] { "class" }); var catchAllDescriptor2 = new TagHelperDescriptor( - tagName: TagHelperDescriptorProvider.CatchAllDescriptorTarget, + tagName: TagHelperDescriptorProvider.ElementCatchAllTarget, typeName: "CatchAllTagHelper", assemblyName: "SomeAssembly", attributes: Enumerable.Empty(), requiredAttributes: new[] { "custom", "class" }); + var catchAllWildcardPrefixDescriptor = new TagHelperDescriptor( + tagName: TagHelperDescriptorProvider.ElementCatchAllTarget, + typeName: "CatchAllWildCardAttribute", + assemblyName: "SomeAssembly", + attributes: Enumerable.Empty(), + requiredAttributes: new[] { "prefix-*" }); var defaultAvailableDescriptors = new[] { divDescriptor, inputDescriptor, catchAllDescriptor, catchAllDescriptor2 }; + var defaultWildcardDescriptors = + new[] { inputWildcardPrefixDescriptor, catchAllWildcardPrefixDescriptor }; return new TheoryData< string, // tagName @@ -73,29 +87,83 @@ namespace Microsoft.AspNet.Razor.TagHelpers new[] { inputDescriptor, catchAllDescriptor } }, { - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, new[] { "custom" }, defaultAvailableDescriptors, Enumerable.Empty() }, { - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, new[] { "class" }, defaultAvailableDescriptors, new[] { catchAllDescriptor } }, { - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, new[] { "class", "style" }, defaultAvailableDescriptors, new[] { catchAllDescriptor } }, { - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, new[] { "class", "custom" }, defaultAvailableDescriptors, new[] { catchAllDescriptor, catchAllDescriptor2 } }, + { + "input", + new[] { "nodashprefixA" }, + defaultWildcardDescriptors, + new[] { inputWildcardPrefixDescriptor } + }, + { + "input", + new[] { "nodashprefix-ABC-DEF", "random" }, + defaultWildcardDescriptors, + new[] { inputWildcardPrefixDescriptor } + }, + { + "input", + new[] { "prefixABCnodashprefix" }, + defaultWildcardDescriptors, + Enumerable.Empty() + }, + { + "input", + new[] { "prefix-" }, + defaultWildcardDescriptors, + Enumerable.Empty() + }, + { + "input", + new[] { "nodashprefix" }, + defaultWildcardDescriptors, + Enumerable.Empty() + }, + { + "input", + new[] { "prefix-A" }, + defaultWildcardDescriptors, + new[] { catchAllWildcardPrefixDescriptor } + }, + { + "input", + new[] { "prefix-ABC-DEF", "random" }, + defaultWildcardDescriptors, + new[] { catchAllWildcardPrefixDescriptor } + }, + { + "input", + new[] { "prefix-abc", "nodashprefix-def" }, + defaultWildcardDescriptors, + new[] { inputWildcardPrefixDescriptor, catchAllWildcardPrefixDescriptor } + }, + { + "input", + new[] { "class", "prefix-abc", "onclick", "nodashprefix-def", "style" }, + defaultWildcardDescriptors, + new[] { inputWildcardPrefixDescriptor, catchAllWildcardPrefixDescriptor } + }, }; } } @@ -124,7 +192,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers // Arrange var catchAllDescriptor = CreatePrefixedDescriptor( "th", - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, "foo1"); var descriptors = new[] { catchAllDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); @@ -159,7 +227,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers public void GetDescriptors_ReturnsCatchAllDescriptorsForPrefixedTags() { // Arrange - var catchAllDescriptor = CreatePrefixedDescriptor("th:", TagHelperDescriptorProvider.CatchAllDescriptorTarget, "foo1"); + var catchAllDescriptor = CreatePrefixedDescriptor("th:", TagHelperDescriptorProvider.ElementCatchAllTarget, "foo1"); var descriptors = new[] { catchAllDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); @@ -230,14 +298,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers var divDescriptor = new TagHelperDescriptor("div", "foo1", "SomeAssembly"); var spanDescriptor = new TagHelperDescriptor("span", "foo2", "SomeAssembly"); var catchAllDescriptor = new TagHelperDescriptor( - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, "foo3", "SomeAssembly"); var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); // Act - var retrievedDescriptors = provider.GetDescriptors(TagHelperDescriptorProvider.CatchAllDescriptorTarget, attributeNames: Enumerable.Empty()); + var retrievedDescriptors = provider.GetDescriptors(TagHelperDescriptorProvider.ElementCatchAllTarget, attributeNames: Enumerable.Empty()); // Assert var descriptor = Assert.Single(retrievedDescriptors); @@ -251,7 +319,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers var divDescriptor = new TagHelperDescriptor("div", "foo1", "SomeAssembly"); var spanDescriptor = new TagHelperDescriptor("span", "foo2", "SomeAssembly"); var catchAllDescriptor = new TagHelperDescriptor( - TagHelperDescriptorProvider.CatchAllDescriptorTarget, + TagHelperDescriptorProvider.ElementCatchAllTarget, "foo3", "SomeAssembly"); var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor };