Add TagHelperPrefix directive.
- Updated TagHelperDescriptor to have a Prefix property. This enables new tooling scenarios such as refactoring prefixes or even giving them their own classification. - Added invalid prefix cases. - Added TagHelperPrefix chunks, codegenerator, parsing logic to flow the directive through the Razor pipeline. #309
This commit is contained in:
parent
677df32160
commit
4d97a544f1
|
|
@ -138,6 +138,38 @@ namespace Microsoft.AspNet.Razor.Runtime
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("HtmlElementNameAttribute_InvalidElementName"), p0, p1);
|
return string.Format(CultureInfo.CurrentCulture, GetString("HtmlElementNameAttribute_InvalidElementName"), p0, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid tag helper directive '{0}'. Cannot have multiple '{0}' directives on a page.
|
||||||
|
/// </summary>
|
||||||
|
internal static string TagHelperDescriptorResolver_InvalidTagHelperDirective
|
||||||
|
{
|
||||||
|
get { return GetString("TagHelperDescriptorResolver_InvalidTagHelperDirective"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid tag helper directive '{0}'. Cannot have multiple '{0}' directives on a page.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatTagHelperDescriptorResolver_InvalidTagHelperDirective(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorResolver_InvalidTagHelperDirective"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid tag helper directive '{0}' value. '{1} is not allowed in prefix '{2}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string TagHelperDescriptorResolver_InvalidTagHelperPrefixValue
|
||||||
|
{
|
||||||
|
get { return GetString("TagHelperDescriptorResolver_InvalidTagHelperPrefixValue"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid tag helper directive '{0}' value. '{1} is not allowed in prefix '{2}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatTagHelperDescriptorResolver_InvalidTagHelperPrefixValue(object p0, object p1, object p2)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperDescriptorResolver_InvalidTagHelperPrefixValue"), p0, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetString(string name, params string[] formatterNames)
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
{
|
{
|
||||||
var value = _resourceManager.GetString(name);
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
|
||||||
|
|
@ -141,4 +141,10 @@
|
||||||
<data name="HtmlElementNameAttribute_InvalidElementName" xml:space="preserve">
|
<data name="HtmlElementNameAttribute_InvalidElementName" xml:space="preserve">
|
||||||
<value>Tag helpers cannot target element name '{0}' because it contains a '{1}' character.</value>
|
<value>Tag helpers cannot target element name '{0}' because it contains a '{1}' character.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TagHelperDescriptorResolver_InvalidTagHelperDirective" xml:space="preserve">
|
||||||
|
<value>Invalid tag helper directive '{0}'. Cannot have multiple '{0}' directives on a page.</value>
|
||||||
|
</data>
|
||||||
|
<data name="TagHelperDescriptorResolver_InvalidTagHelperPrefixValue" xml:space="preserve">
|
||||||
|
<value>Invalid tag helper directive '{0}' value. '{1} is not allowed in prefix '{2}'.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -23,7 +23,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
{
|
{
|
||||||
{ TagHelperDirectiveType.AddTagHelper, SyntaxConstants.CSharp.AddTagHelperKeyword },
|
{ TagHelperDirectiveType.AddTagHelper, SyntaxConstants.CSharp.AddTagHelperKeyword },
|
||||||
{ TagHelperDirectiveType.RemoveTagHelper, SyntaxConstants.CSharp.RemoveTagHelperKeyword },
|
{ TagHelperDirectiveType.RemoveTagHelper, SyntaxConstants.CSharp.RemoveTagHelperKeyword },
|
||||||
|
{ TagHelperDirectiveType.TagHelperPrefix, SyntaxConstants.CSharp.TagHelperPrefixKeyword },
|
||||||
};
|
};
|
||||||
|
private static readonly HashSet<char> InvalidNonWhitespacePrefixCharacters =
|
||||||
|
new HashSet<char>(new[] { '@', '!', '<', '!', '/', '?', '[', '>', ']', '=', '"', '\'' });
|
||||||
|
|
||||||
private readonly TagHelperTypeResolver _typeResolver;
|
private readonly TagHelperTypeResolver _typeResolver;
|
||||||
|
|
||||||
|
|
@ -51,7 +54,12 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
{
|
{
|
||||||
var resolvedDescriptors = new HashSet<TagHelperDescriptor>(TagHelperDescriptorComparer.Default);
|
var resolvedDescriptors = new HashSet<TagHelperDescriptor>(TagHelperDescriptorComparer.Default);
|
||||||
|
|
||||||
foreach (var directiveDescriptor in context.DirectiveDescriptors)
|
// tagHelperPrefix directives do not affect which TagHelperDescriptors are added or removed from the final
|
||||||
|
// list, need to remove them.
|
||||||
|
var actionableDirectiveDescriptors = context.DirectiveDescriptors.Where(
|
||||||
|
directive => directive.DirectiveType != TagHelperDirectiveType.TagHelperPrefix);
|
||||||
|
|
||||||
|
foreach (var directiveDescriptor in actionableDirectiveDescriptors)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -69,9 +77,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
}
|
}
|
||||||
else if (directiveDescriptor.DirectiveType == TagHelperDirectiveType.AddTagHelper)
|
else if (directiveDescriptor.DirectiveType == TagHelperDirectiveType.AddTagHelper)
|
||||||
{
|
{
|
||||||
var descriptors = ResolveDescriptorsInAssembly(lookupInfo.AssemblyName,
|
var descriptors = ResolveDescriptorsInAssembly(
|
||||||
directiveDescriptor.Location,
|
lookupInfo.AssemblyName,
|
||||||
context.ErrorSink);
|
directiveDescriptor.Location,
|
||||||
|
context.ErrorSink);
|
||||||
|
|
||||||
// Only use descriptors that match our lookup info
|
// Only use descriptors that match our lookup info
|
||||||
descriptors = descriptors.Where(descriptor => MatchesLookupInfo(descriptor, lookupInfo));
|
descriptors = descriptors.Where(descriptor => MatchesLookupInfo(descriptor, lookupInfo));
|
||||||
|
|
@ -89,12 +98,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
directiveDescriptor.Location,
|
directiveDescriptor.Location,
|
||||||
Resources.FormatTagHelperDescriptorResolver_EncounteredUnexpectedError(
|
Resources.FormatTagHelperDescriptorResolver_EncounteredUnexpectedError(
|
||||||
"@" + directiveName,
|
"@" + directiveName,
|
||||||
directiveDescriptor.LookupText,
|
directiveDescriptor.DirectiveText,
|
||||||
ex.Message));
|
ex.Message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolvedDescriptors;
|
var prefixedDescriptors = PrefixDescriptors(context, resolvedDescriptors);
|
||||||
|
|
||||||
|
return prefixedDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -110,9 +121,10 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
/// <returns><see cref="TagHelperDescriptor"/>s for <see cref="ITagHelper"/>s from the given
|
/// <returns><see cref="TagHelperDescriptor"/>s for <see cref="ITagHelper"/>s from the given
|
||||||
/// <paramref name="assemblyName"/>.</returns>
|
/// <paramref name="assemblyName"/>.</returns>
|
||||||
// This is meant to be overridden by tooling to enable assembly level caching.
|
// This is meant to be overridden by tooling to enable assembly level caching.
|
||||||
protected virtual IEnumerable<TagHelperDescriptor> ResolveDescriptorsInAssembly(string assemblyName,
|
protected virtual IEnumerable<TagHelperDescriptor> ResolveDescriptorsInAssembly(
|
||||||
SourceLocation documentLocation,
|
string assemblyName,
|
||||||
ParserErrorSink errorSink)
|
SourceLocation documentLocation,
|
||||||
|
ParserErrorSink errorSink)
|
||||||
{
|
{
|
||||||
// Resolve valid tag helper types from the assembly.
|
// Resolve valid tag helper types from the assembly.
|
||||||
var tagHelperTypes = _typeResolver.Resolve(assemblyName, documentLocation, errorSink);
|
var tagHelperTypes = _typeResolver.Resolve(assemblyName, documentLocation, errorSink);
|
||||||
|
|
@ -124,6 +136,84 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
return descriptors;
|
return descriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<TagHelperDescriptor> PrefixDescriptors(
|
||||||
|
TagHelperDescriptorResolutionContext context,
|
||||||
|
IEnumerable<TagHelperDescriptor> descriptors)
|
||||||
|
{
|
||||||
|
var tagHelperPrefix = ResolveTagHelperPrefix(context);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(tagHelperPrefix))
|
||||||
|
{
|
||||||
|
return descriptors.Select(descriptor =>
|
||||||
|
new TagHelperDescriptor(
|
||||||
|
tagHelperPrefix,
|
||||||
|
descriptor.TagName,
|
||||||
|
descriptor.TypeName,
|
||||||
|
descriptor.AssemblyName,
|
||||||
|
descriptor.Attributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ResolveTagHelperPrefix(TagHelperDescriptorResolutionContext context)
|
||||||
|
{
|
||||||
|
var prefixDirectiveDescriptors = context.DirectiveDescriptors.Where(
|
||||||
|
descriptor => descriptor.DirectiveType == TagHelperDirectiveType.TagHelperPrefix);
|
||||||
|
|
||||||
|
TagHelperDirectiveDescriptor prefixDirective = null;
|
||||||
|
|
||||||
|
foreach (var directive in prefixDirectiveDescriptors)
|
||||||
|
{
|
||||||
|
if (prefixDirective == null)
|
||||||
|
{
|
||||||
|
prefixDirective = directive;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For each invalid @tagHelperPrefix we need to create an error.
|
||||||
|
context.ErrorSink.OnError(
|
||||||
|
directive.Location,
|
||||||
|
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperDirective(
|
||||||
|
SyntaxConstants.CSharp.TagHelperPrefixKeyword));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var prefix = prefixDirective?.DirectiveText;
|
||||||
|
|
||||||
|
if (prefix != null && !EnsureValidPrefix(prefix, prefixDirective.Location, context.ErrorSink))
|
||||||
|
{
|
||||||
|
prefix = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool EnsureValidPrefix(
|
||||||
|
string prefix,
|
||||||
|
SourceLocation directiveLocation,
|
||||||
|
ParserErrorSink errorSink)
|
||||||
|
{
|
||||||
|
foreach (var character in prefix)
|
||||||
|
{
|
||||||
|
// Prefixes are correlated with tag names, tag names cannot have whitespace.
|
||||||
|
if (char.IsWhiteSpace(character) ||
|
||||||
|
InvalidNonWhitespacePrefixCharacters.Contains(character))
|
||||||
|
{
|
||||||
|
errorSink.OnError(
|
||||||
|
directiveLocation,
|
||||||
|
Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperPrefixValue(
|
||||||
|
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
|
||||||
|
character,
|
||||||
|
prefix));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool MatchesLookupInfo(TagHelperDescriptor descriptor, LookupInfo lookupInfo)
|
private static bool MatchesLookupInfo(TagHelperDescriptor descriptor, LookupInfo lookupInfo)
|
||||||
{
|
{
|
||||||
if (!string.Equals(descriptor.AssemblyName, lookupInfo.AssemblyName, StringComparison.Ordinal))
|
if (!string.Equals(descriptor.AssemblyName, lookupInfo.AssemblyName, StringComparison.Ordinal))
|
||||||
|
|
@ -146,7 +236,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
private static LookupInfo GetLookupInfo(TagHelperDirectiveDescriptor directiveDescriptor,
|
private static LookupInfo GetLookupInfo(TagHelperDirectiveDescriptor directiveDescriptor,
|
||||||
ParserErrorSink errorSink)
|
ParserErrorSink errorSink)
|
||||||
{
|
{
|
||||||
var lookupText = directiveDescriptor.LookupText;
|
var lookupText = directiveDescriptor.DirectiveText;
|
||||||
var lookupStrings = lookupText?.Split(new[] { ',' });
|
var lookupStrings = lookupText?.Split(new[] { ',' });
|
||||||
|
|
||||||
// Ensure that we have valid lookupStrings to work with. Valid formats are:
|
// Ensure that we have valid lookupStrings to work with. Valid formats are:
|
||||||
|
|
|
||||||
|
|
@ -58,17 +58,22 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Visit(TagHelperPrefixDirectiveChunk chunk)
|
||||||
|
{
|
||||||
|
VisitTagHelperDirectiveChunk(chunk.Prefix, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Visit(AddTagHelperChunk chunk)
|
protected override void Visit(AddTagHelperChunk chunk)
|
||||||
{
|
{
|
||||||
VisitAddOrRemoveTagHelperChunk(chunk.LookupText, chunk);
|
VisitTagHelperDirectiveChunk(chunk.LookupText, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Visit(RemoveTagHelperChunk chunk)
|
protected override void Visit(RemoveTagHelperChunk chunk)
|
||||||
{
|
{
|
||||||
VisitAddOrRemoveTagHelperChunk(chunk.LookupText, chunk);
|
VisitTagHelperDirectiveChunk(chunk.LookupText, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VisitAddOrRemoveTagHelperChunk(string lookupText, Chunk chunk)
|
private void VisitTagHelperDirectiveChunk(string text, Chunk chunk)
|
||||||
{
|
{
|
||||||
// We should always be in design time mode because of the calling AcceptTree method verification.
|
// We should always be in design time mode because of the calling AcceptTree method verification.
|
||||||
Debug.Assert(Context.Host.DesignTimeMode);
|
Debug.Assert(Context.Host.DesignTimeMode);
|
||||||
|
|
@ -81,12 +86,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
||||||
|
|
||||||
Writer.WriteStartAssignment(TagHelperDirectiveSyntaxHelper);
|
Writer.WriteStartAssignment(TagHelperDirectiveSyntaxHelper);
|
||||||
|
|
||||||
// The parsing mechanism for the add/remove TagHelper chunk (CSharpCodeParser.TagHelperDirective())
|
// The parsing mechanism for a TagHelper directive chunk (CSharpCodeParser.TagHelperDirective())
|
||||||
// removes quotes that surround the lookupText.
|
// removes quotes that surround the text.
|
||||||
_csharpCodeVisitor.CreateExpressionCodeMapping(
|
_csharpCodeVisitor.CreateExpressionCodeMapping(
|
||||||
string.Format(
|
string.Format(CultureInfo.InvariantCulture, "\"{0}\"", text),
|
||||||
CultureInfo.InvariantCulture,
|
|
||||||
"\"{0}\"", lookupText),
|
|
||||||
chunk);
|
chunk);
|
||||||
|
|
||||||
Writer.WriteLine(";");
|
Writer.WriteLine(";");
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
|
||||||
{
|
{
|
||||||
Visit((TagHelperChunk)chunk);
|
Visit((TagHelperChunk)chunk);
|
||||||
}
|
}
|
||||||
|
else if (chunk is TagHelperPrefixDirectiveChunk)
|
||||||
|
{
|
||||||
|
Visit((TagHelperPrefixDirectiveChunk)chunk);
|
||||||
|
}
|
||||||
else if (chunk is AddTagHelperChunk)
|
else if (chunk is AddTagHelperChunk)
|
||||||
{
|
{
|
||||||
Visit((AddTagHelperChunk)chunk);
|
Visit((AddTagHelperChunk)chunk);
|
||||||
|
|
@ -119,6 +123,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
|
||||||
protected abstract void Visit(ExpressionChunk chunk);
|
protected abstract void Visit(ExpressionChunk chunk);
|
||||||
protected abstract void Visit(StatementChunk chunk);
|
protected abstract void Visit(StatementChunk chunk);
|
||||||
protected abstract void Visit(TagHelperChunk chunk);
|
protected abstract void Visit(TagHelperChunk chunk);
|
||||||
|
protected abstract void Visit(TagHelperPrefixDirectiveChunk chunk);
|
||||||
protected abstract void Visit(AddTagHelperChunk chunk);
|
protected abstract void Visit(AddTagHelperChunk chunk);
|
||||||
protected abstract void Visit(RemoveTagHelperChunk chunk);
|
protected abstract void Visit(RemoveTagHelperChunk chunk);
|
||||||
protected abstract void Visit(UsingChunk chunk);
|
protected abstract void Visit(UsingChunk chunk);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
|
||||||
protected override void Visit(TagHelperChunk chunk)
|
protected override void Visit(TagHelperChunk chunk)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
protected override void Visit(TagHelperPrefixDirectiveChunk chunk)
|
||||||
|
{
|
||||||
|
}
|
||||||
protected override void Visit(AddTagHelperChunk chunk)
|
protected override void Visit(AddTagHelperChunk chunk)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Generator.Compiler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="Chunk"/> for the <c>@tagHelperPrefix</c> directive.
|
||||||
|
/// </summary>
|
||||||
|
public class TagHelperPrefixDirectiveChunk : Chunk
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Text used as a required prefix when matching HTML start and end tags in the Razor source to available
|
||||||
|
/// tag helpers.
|
||||||
|
/// </summary>
|
||||||
|
public string Prefix { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,6 +37,17 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddTagHelperPrefixDirectiveChunk(string prefix, SyntaxTreeNode association)
|
||||||
|
{
|
||||||
|
AddChunk(
|
||||||
|
new TagHelperPrefixDirectiveChunk
|
||||||
|
{
|
||||||
|
Prefix = prefix
|
||||||
|
},
|
||||||
|
association,
|
||||||
|
topLevel: true);
|
||||||
|
}
|
||||||
|
|
||||||
public void AddAddTagHelperChunk(string lookupText, SyntaxTreeNode association)
|
public void AddAddTagHelperChunk(string lookupText, SyntaxTreeNode association)
|
||||||
{
|
{
|
||||||
AddChunk(new AddTagHelperChunk
|
AddChunk(new AddTagHelperChunk
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,11 @@ namespace Microsoft.AspNet.Razor.Generator
|
||||||
codeGenerator.Context.CodeTreeBuilder = new CodeTreeBuilder();
|
codeGenerator.Context.CodeTreeBuilder = new CodeTreeBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var unprefixedTagName = tagHelperBlock.TagName.Substring(_tagHelperDescriptors.First().Prefix.Length);
|
||||||
|
|
||||||
context.CodeTreeBuilder.StartChunkBlock(
|
context.CodeTreeBuilder.StartChunkBlock(
|
||||||
new TagHelperChunk(
|
new TagHelperChunk(
|
||||||
tagHelperBlock.TagName,
|
unprefixedTagName,
|
||||||
tagHelperBlock.SelfClosing,
|
tagHelperBlock.SelfClosing,
|
||||||
attributes,
|
attributes,
|
||||||
_tagHelperDescriptors),
|
_tagHelperDescriptors),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Generator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="SpanCodeGenerator"/> responsible for generating
|
||||||
|
/// <see cref="Compiler.TagHelperPrefixDirectiveChunk"/>s.
|
||||||
|
/// </summary>
|
||||||
|
public class TagHelperPrefixDirectiveCodeGenerator : SpanCodeGenerator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new <see cref="TagHelperPrefixDirectiveCodeGenerator"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prefix">
|
||||||
|
/// Text used as a required prefix when matching HTML.
|
||||||
|
/// </param>
|
||||||
|
public TagHelperPrefixDirectiveCodeGenerator(string prefix)
|
||||||
|
{
|
||||||
|
Prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Text used as a required prefix when matching HTML.
|
||||||
|
/// </summary>
|
||||||
|
public string Prefix { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates <see cref="Compiler.TagHelperPrefixDirectiveChunk"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">
|
||||||
|
/// The <see cref="Span"/> responsible for this <see cref="TagHelperPrefixDirectiveCodeGenerator"/>.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="context">A <see cref="CodeGeneratorContext"/> instance that contains information about
|
||||||
|
/// the current code generation process.</param>
|
||||||
|
public override void GenerateCode(Span target, CodeGeneratorContext context)
|
||||||
|
{
|
||||||
|
context.CodeTreeBuilder.AddTagHelperPrefixDirectiveChunk(Prefix, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
{
|
{
|
||||||
private void SetupDirectives()
|
private void SetupDirectives()
|
||||||
{
|
{
|
||||||
|
MapDirectives(TagHelperPrefixDirective, SyntaxConstants.CSharp.TagHelperPrefixKeyword);
|
||||||
MapDirectives(AddTagHelperDirective, SyntaxConstants.CSharp.AddTagHelperKeyword);
|
MapDirectives(AddTagHelperDirective, SyntaxConstants.CSharp.AddTagHelperKeyword);
|
||||||
MapDirectives(RemoveTagHelperDirective, SyntaxConstants.CSharp.RemoveTagHelperKeyword);
|
MapDirectives(RemoveTagHelperDirective, SyntaxConstants.CSharp.RemoveTagHelperKeyword);
|
||||||
MapDirectives(InheritsDirective, SyntaxConstants.CSharp.InheritsKeyword);
|
MapDirectives(InheritsDirective, SyntaxConstants.CSharp.InheritsKeyword);
|
||||||
|
|
@ -27,14 +28,27 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
MapDirectives(LayoutDirective, SyntaxConstants.CSharp.LayoutKeyword);
|
MapDirectives(LayoutDirective, SyntaxConstants.CSharp.LayoutKeyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void TagHelperPrefixDirective()
|
||||||
|
{
|
||||||
|
TagHelperDirective(
|
||||||
|
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
|
||||||
|
prefix => new TagHelperPrefixDirectiveCodeGenerator(prefix));
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void AddTagHelperDirective()
|
protected virtual void AddTagHelperDirective()
|
||||||
{
|
{
|
||||||
TagHelperDirective(SyntaxConstants.CSharp.AddTagHelperKeyword, removeTagHelperDescriptors: false);
|
TagHelperDirective(
|
||||||
|
SyntaxConstants.CSharp.AddTagHelperKeyword,
|
||||||
|
lookupText =>
|
||||||
|
new AddOrRemoveTagHelperCodeGenerator(removeTagHelperDescriptors: false, lookupText: lookupText));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void RemoveTagHelperDirective()
|
protected virtual void RemoveTagHelperDirective()
|
||||||
{
|
{
|
||||||
TagHelperDirective(SyntaxConstants.CSharp.RemoveTagHelperKeyword, removeTagHelperDescriptors: true);
|
TagHelperDirective(
|
||||||
|
SyntaxConstants.CSharp.RemoveTagHelperKeyword,
|
||||||
|
lookupText =>
|
||||||
|
new AddOrRemoveTagHelperCodeGenerator(removeTagHelperDescriptors: true, lookupText: lookupText));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void LayoutDirective()
|
protected virtual void LayoutDirective()
|
||||||
|
|
@ -450,7 +464,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
Output(SpanKind.Code);
|
Output(SpanKind.Code);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TagHelperDirective(string keyword, bool removeTagHelperDescriptors)
|
private void TagHelperDirective(string keyword, Func<string, ISpanCodeGenerator> buildCodeGenerator)
|
||||||
{
|
{
|
||||||
AssertDirective(keyword);
|
AssertDirective(keyword);
|
||||||
|
|
||||||
|
|
@ -492,8 +506,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
// renders the C# to colorize the user provided value. We trim the quotes around the user's value
|
// renders the C# to colorize the user provided value. We trim the quotes around the user's value
|
||||||
// so when we render the code we can project the users value into double quotes to not invoke C#
|
// so when we render the code we can project the users value into double quotes to not invoke C#
|
||||||
// IntelliSense.
|
// IntelliSense.
|
||||||
Span.CodeGenerator =
|
Span.CodeGenerator = buildCodeGenerator(rawValue.Trim('"'));
|
||||||
new AddOrRemoveTagHelperCodeGenerator(removeTagHelperDescriptors, rawValue.Trim('"'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We expect the directive to be surrounded in quotes.
|
// We expect the directive to be surrounded in quotes.
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
|
|
||||||
internal static ISet<string> DefaultKeywords = new HashSet<string>()
|
internal static ISet<string> DefaultKeywords = new HashSet<string>()
|
||||||
{
|
{
|
||||||
|
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
|
||||||
SyntaxConstants.CSharp.AddTagHelperKeyword,
|
SyntaxConstants.CSharp.AddTagHelperKeyword,
|
||||||
SyntaxConstants.CSharp.RemoveTagHelperKeyword,
|
SyntaxConstants.CSharp.RemoveTagHelperKeyword,
|
||||||
"if",
|
"if",
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
[NotNull] ParserErrorSink errorSink)
|
[NotNull] ParserErrorSink errorSink)
|
||||||
{
|
{
|
||||||
var addOrRemoveTagHelperSpanVisitor =
|
var addOrRemoveTagHelperSpanVisitor =
|
||||||
new AddOrRemoveTagHelperSpanVisitor(TagHelperDescriptorResolver, errorSink);
|
new TagHelperDirectiveSpanVisitor(TagHelperDescriptorResolver, errorSink);
|
||||||
return addOrRemoveTagHelperSpanVisitor.GetDescriptors(documentRoot);
|
return addOrRemoveTagHelperSpanVisitor.GetDescriptors(documentRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ namespace Microsoft.AspNet.Razor.Parser
|
||||||
public static class CSharp
|
public static class CSharp
|
||||||
{
|
{
|
||||||
public static readonly int UsingKeywordLength = 5;
|
public static readonly int UsingKeywordLength = 5;
|
||||||
|
public static readonly string TagHelperPrefixKeyword = "tagHelperPrefix";
|
||||||
public static readonly string AddTagHelperKeyword = "addTagHelper";
|
public static readonly string AddTagHelperKeyword = "addTagHelper";
|
||||||
public static readonly string RemoveTagHelperKeyword = "removeTagHelper";
|
public static readonly string RemoveTagHelperKeyword = "removeTagHelper";
|
||||||
public static readonly string InheritsKeyword = "inherits";
|
public static readonly string InheritsKeyword = "inherits";
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
/// A <see cref="ParserVisitor"/> that generates <see cref="TagHelperDescriptor"/>s from
|
/// A <see cref="ParserVisitor"/> that generates <see cref="TagHelperDescriptor"/>s from
|
||||||
/// tag helper code generators in a Razor document.
|
/// tag helper code generators in a Razor document.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AddOrRemoveTagHelperSpanVisitor : ParserVisitor
|
public class TagHelperDirectiveSpanVisitor : ParserVisitor
|
||||||
{
|
{
|
||||||
private readonly ITagHelperDescriptorResolver _descriptorResolver;
|
private readonly ITagHelperDescriptorResolver _descriptorResolver;
|
||||||
private readonly ParserErrorSink _errorSink;
|
private readonly ParserErrorSink _errorSink;
|
||||||
|
|
@ -20,12 +20,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
private List<TagHelperDirectiveDescriptor> _directiveDescriptors;
|
private List<TagHelperDirectiveDescriptor> _directiveDescriptors;
|
||||||
|
|
||||||
// Internal for testing use
|
// Internal for testing use
|
||||||
internal AddOrRemoveTagHelperSpanVisitor(ITagHelperDescriptorResolver descriptorResolver)
|
internal TagHelperDirectiveSpanVisitor(ITagHelperDescriptorResolver descriptorResolver)
|
||||||
: this(descriptorResolver, new ParserErrorSink())
|
: this(descriptorResolver, new ParserErrorSink())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddOrRemoveTagHelperSpanVisitor([NotNull] ITagHelperDescriptorResolver descriptorResolver,
|
public TagHelperDirectiveSpanVisitor([NotNull] ITagHelperDescriptorResolver descriptorResolver,
|
||||||
[NotNull] ParserErrorSink errorSink)
|
[NotNull] ParserErrorSink errorSink)
|
||||||
{
|
{
|
||||||
_descriptorResolver = descriptorResolver;
|
_descriptorResolver = descriptorResolver;
|
||||||
|
|
@ -61,13 +61,26 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
||||||
{
|
{
|
||||||
var codeGenerator = (AddOrRemoveTagHelperCodeGenerator)span.CodeGenerator;
|
var codeGenerator = (AddOrRemoveTagHelperCodeGenerator)span.CodeGenerator;
|
||||||
|
|
||||||
var directive = codeGenerator.RemoveTagHelperDescriptors ?
|
var directive =
|
||||||
TagHelperDirectiveType.RemoveTagHelper :
|
codeGenerator.RemoveTagHelperDescriptors ?
|
||||||
TagHelperDirectiveType.AddTagHelper;
|
TagHelperDirectiveType.RemoveTagHelper :
|
||||||
|
TagHelperDirectiveType.AddTagHelper;
|
||||||
|
|
||||||
var directiveDescriptor = new TagHelperDirectiveDescriptor(codeGenerator.LookupText,
|
var directiveDescriptor = new TagHelperDirectiveDescriptor(
|
||||||
span.Start,
|
codeGenerator.LookupText,
|
||||||
directive);
|
span.Start,
|
||||||
|
directive);
|
||||||
|
|
||||||
|
_directiveDescriptors.Add(directiveDescriptor);
|
||||||
|
}
|
||||||
|
else if (span.CodeGenerator is TagHelperPrefixDirectiveCodeGenerator)
|
||||||
|
{
|
||||||
|
var codeGenerator = (TagHelperPrefixDirectiveCodeGenerator)span.CodeGenerator;
|
||||||
|
|
||||||
|
var directiveDescriptor = new TagHelperDirectiveDescriptor(
|
||||||
|
codeGenerator.Prefix,
|
||||||
|
span.Start,
|
||||||
|
TagHelperDirectiveType.TagHelperPrefix);
|
||||||
|
|
||||||
_directiveDescriptors.Add(directiveDescriptor);
|
_directiveDescriptors.Add(directiveDescriptor);
|
||||||
}
|
}
|
||||||
|
|
@ -54,6 +54,7 @@ namespace Microsoft.AspNet.Razor
|
||||||
TagHelperDescriptors = tagHelperDescriptors;
|
TagHelperDescriptors = tagHelperDescriptors;
|
||||||
ErrorSink = errorSink;
|
ErrorSink = errorSink;
|
||||||
ParserErrors = errorSink.Errors;
|
ParserErrors = errorSink.Errors;
|
||||||
|
Prefix = tagHelperDescriptors.FirstOrDefault()?.Prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -81,5 +82,10 @@ namespace Microsoft.AspNet.Razor
|
||||||
/// The <see cref="TagHelperDescriptor"/>s found for the current Razor document.
|
/// The <see cref="TagHelperDescriptor"/>s found for the current Razor document.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<TagHelperDescriptor> TagHelperDescriptors { get; }
|
public IEnumerable<TagHelperDescriptor> TagHelperDescriptors { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Text used as a required prefix when matching HTML.
|
||||||
|
/// </summary>
|
||||||
|
public string Prefix { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,11 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
internal TagHelperDescriptor([NotNull] string tagName,
|
internal TagHelperDescriptor([NotNull] string tagName,
|
||||||
[NotNull] string typeName,
|
[NotNull] string typeName,
|
||||||
[NotNull] string assemblyName)
|
[NotNull] string assemblyName)
|
||||||
: this(tagName,
|
: this(
|
||||||
typeName,
|
tagName,
|
||||||
assemblyName,
|
typeName,
|
||||||
Enumerable.Empty<TagHelperAttributeDescriptor>())
|
assemblyName,
|
||||||
|
attributes: Enumerable.Empty<TagHelperAttributeDescriptor>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,22 +36,67 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// <param name="attributes">
|
/// <param name="attributes">
|
||||||
/// The <see cref="TagHelperAttributeDescriptor"/>s to request from the HTML tag.
|
/// The <see cref="TagHelperAttributeDescriptor"/>s to request from the HTML tag.
|
||||||
/// </param>
|
/// </param>
|
||||||
public TagHelperDescriptor([NotNull] string tagName,
|
public TagHelperDescriptor(
|
||||||
[NotNull] string typeName,
|
[NotNull] string tagName,
|
||||||
[NotNull] string assemblyName,
|
[NotNull] string typeName,
|
||||||
[NotNull] IEnumerable<TagHelperAttributeDescriptor> attributes)
|
[NotNull] string assemblyName,
|
||||||
|
[NotNull] IEnumerable<TagHelperAttributeDescriptor> attributes)
|
||||||
|
: this(
|
||||||
|
prefix: string.Empty,
|
||||||
|
tagName: tagName,
|
||||||
|
typeName: typeName,
|
||||||
|
assemblyName: assemblyName,
|
||||||
|
attributes: attributes)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiates a new instance of the <see cref="TagHelperDescriptor"/> class with the given
|
||||||
|
/// <paramref name="attributes"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="prefix">
|
||||||
|
/// Text used as a required prefix when matching HTML start and end tags in the Razor source to available
|
||||||
|
/// tag helpers.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="tagName">The tag name that the tag helper targets. '*' indicates a catch-all
|
||||||
|
/// <see cref="TagHelperDescriptor"/> which applies to every HTML tag.</param>
|
||||||
|
/// <param name="typeName">The full name of the tag helper class.</param>
|
||||||
|
/// <param name="assemblyName">The name of the assembly containing the tag helper class.</param>
|
||||||
|
/// <param name="attributes">
|
||||||
|
/// The <see cref="TagHelperAttributeDescriptor"/>s to request from the HTML tag.
|
||||||
|
/// </param>
|
||||||
|
public TagHelperDescriptor(
|
||||||
|
string prefix,
|
||||||
|
[NotNull] string tagName,
|
||||||
|
[NotNull] string typeName,
|
||||||
|
[NotNull] string assemblyName,
|
||||||
|
[NotNull] IEnumerable<TagHelperAttributeDescriptor> attributes)
|
||||||
|
{
|
||||||
|
Prefix = prefix ?? string.Empty;
|
||||||
TagName = tagName;
|
TagName = tagName;
|
||||||
|
FullTagName = Prefix + TagName;
|
||||||
TypeName = typeName;
|
TypeName = typeName;
|
||||||
AssemblyName = assemblyName;
|
AssemblyName = assemblyName;
|
||||||
Attributes = new List<TagHelperAttributeDescriptor>(attributes);
|
Attributes = new List<TagHelperAttributeDescriptor>(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Text used as a required prefix when matching HTML start and end tags in the Razor source to available
|
||||||
|
/// tag helpers.
|
||||||
|
/// </summary>
|
||||||
|
public string Prefix { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The tag name that the tag helper should target.
|
/// The tag name that the tag helper should target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string TagName { get; private set; }
|
public string TagName { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The full tag name that is required for the tag helper to target an HTML element.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>This is equivalent to <see cref="Prefix"/> and <see cref="TagName"/> concatenated.</remarks>
|
||||||
|
public string FullTagName { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The full name of the tag helper class.
|
/// The full name of the tag helper class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// <c>false</c> otherwise.</returns>
|
/// <c>false</c> otherwise.</returns>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Determines equality based on <see cref="TagHelperDescriptor.TypeName"/>,
|
/// Determines equality based on <see cref="TagHelperDescriptor.TypeName"/>,
|
||||||
/// <see cref="TagHelperDescriptor.AssemblyName"/> and <see cref="TagHelperDescriptor.TagName"/>.
|
/// <see cref="TagHelperDescriptor.AssemblyName"/>, <see cref="TagHelperDescriptor.TagName"/> and
|
||||||
|
/// <see cref="TagHelperDescriptor.Prefix"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
public bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
||||||
{
|
{
|
||||||
return string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal) &&
|
return string.Equals(descriptorX.TypeName, descriptorY.TypeName, StringComparison.Ordinal) &&
|
||||||
string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.OrdinalIgnoreCase) &&
|
string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
string.Equals(descriptorX.Prefix, descriptorY.Prefix, StringComparison.OrdinalIgnoreCase) &&
|
||||||
string.Equals(descriptorX.AssemblyName, descriptorY.AssemblyName, StringComparison.Ordinal);
|
string.Equals(descriptorX.AssemblyName, descriptorY.AssemblyName, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
private const string CatchAllDescriptorTarget = "*";
|
private const string CatchAllDescriptorTarget = "*";
|
||||||
|
|
||||||
private IDictionary<string, HashSet<TagHelperDescriptor>> _registrations;
|
private IDictionary<string, HashSet<TagHelperDescriptor>> _registrations;
|
||||||
|
private string _tagHelperPrefix;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates a new instance of the <see cref="TagHelperDescriptorProvider"/>.
|
/// Instantiates a new instance of the <see cref="TagHelperDescriptorProvider"/>.
|
||||||
|
|
@ -43,10 +44,18 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
{
|
{
|
||||||
HashSet<TagHelperDescriptor> descriptors;
|
HashSet<TagHelperDescriptor> descriptors;
|
||||||
|
|
||||||
// Ensure there's an ISet to use.
|
if (!string.IsNullOrEmpty(_tagHelperPrefix) &&
|
||||||
|
(tagName.Length <= _tagHelperPrefix.Length ||
|
||||||
|
!tagName.StartsWith(_tagHelperPrefix, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
// The tagName doesn't have the tag helper prefix, we can short circuit.
|
||||||
|
return Enumerable.Empty<TagHelperDescriptor>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure there's a HashSet to use.
|
||||||
if (!_registrations.TryGetValue(CatchAllDescriptorTarget, out descriptors))
|
if (!_registrations.TryGetValue(CatchAllDescriptorTarget, out descriptors))
|
||||||
{
|
{
|
||||||
descriptors = new HashSet<TagHelperDescriptor>();
|
descriptors = new HashSet<TagHelperDescriptor>(TagHelperDescriptorComparer.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the requested tag name is the catch-all target, we should short circuit.
|
// If the requested tag name is the catch-all target, we should short circuit.
|
||||||
|
|
@ -72,11 +81,21 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
{
|
{
|
||||||
HashSet<TagHelperDescriptor> descriptorSet;
|
HashSet<TagHelperDescriptor> descriptorSet;
|
||||||
|
|
||||||
// Ensure there's a List to add the descriptor to.
|
if (_tagHelperPrefix == null)
|
||||||
if (!_registrations.TryGetValue(descriptor.TagName, out descriptorSet))
|
{
|
||||||
|
_tagHelperPrefix = descriptor.Prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
var registrationKey =
|
||||||
|
string.Equals(descriptor.TagName, CatchAllDescriptorTarget, StringComparison.Ordinal) ?
|
||||||
|
CatchAllDescriptorTarget :
|
||||||
|
descriptor.FullTagName;
|
||||||
|
|
||||||
|
// Ensure there's a HashSet to add the descriptor to.
|
||||||
|
if (!_registrations.TryGetValue(registrationKey, out descriptorSet))
|
||||||
{
|
{
|
||||||
descriptorSet = new HashSet<TagHelperDescriptor>(TagHelperDescriptorComparer.Default);
|
descriptorSet = new HashSet<TagHelperDescriptor>(TagHelperDescriptorComparer.Default);
|
||||||
_registrations[descriptor.TagName] = descriptorSet;
|
_registrations[registrationKey] = descriptorSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptorSet.Add(descriptor);
|
descriptorSet.Add(descriptor);
|
||||||
|
|
|
||||||
|
|
@ -11,23 +11,24 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
public class TagHelperDirectiveDescriptor
|
public class TagHelperDirectiveDescriptor
|
||||||
{
|
{
|
||||||
// Internal for testing purposes.
|
// Internal for testing purposes.
|
||||||
internal TagHelperDirectiveDescriptor(string lookupText,
|
internal TagHelperDirectiveDescriptor(string directiveText,
|
||||||
TagHelperDirectiveType directiveType)
|
TagHelperDirectiveType directiveType)
|
||||||
: this(lookupText, SourceLocation.Zero, directiveType)
|
: this(directiveText, SourceLocation.Zero, directiveType)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates a new instance of <see cref="TagHelperDirectiveDescriptor"/>.
|
/// Instantiates a new instance of <see cref="TagHelperDirectiveDescriptor"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="lookupText">A <see cref="string"/> used to find tag helper <see cref="System.Type"/>s.</param>
|
/// <param name="directiveText">A <see cref="string"/> used to understand tag helper
|
||||||
|
/// <see cref="System.Type"/>s.</param>
|
||||||
/// <param name="location">The <see cref="SourceLocation"/> of the directive.</param>
|
/// <param name="location">The <see cref="SourceLocation"/> of the directive.</param>
|
||||||
/// <param name="directiveType">The <see cref="TagHelperDirectiveType"/> of this directive.</param>
|
/// <param name="directiveType">The <see cref="TagHelperDirectiveType"/> of this directive.</param>
|
||||||
public TagHelperDirectiveDescriptor([NotNull] string lookupText,
|
public TagHelperDirectiveDescriptor([NotNull] string directiveText,
|
||||||
SourceLocation location,
|
SourceLocation location,
|
||||||
TagHelperDirectiveType directiveType)
|
TagHelperDirectiveType directiveType)
|
||||||
{
|
{
|
||||||
LookupText = lookupText;
|
DirectiveText = directiveText;
|
||||||
Location = location;
|
Location = location;
|
||||||
DirectiveType = directiveType;
|
DirectiveType = directiveType;
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +36,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A <see cref="string"/> used to find tag helper <see cref="System.Type"/>s.
|
/// A <see cref="string"/> used to find tag helper <see cref="System.Type"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string LookupText { get; private set; }
|
public string DirectiveText { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="TagHelperDirectiveType"/> of this directive.
|
/// The <see cref="TagHelperDirectiveType"/> of this directive.
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,18 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
||||||
public enum TagHelperDirectiveType
|
public enum TagHelperDirectiveType
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An @addTagHelper directive.
|
/// An <c>@addTagHelper</c> directive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
AddTagHelper,
|
AddTagHelper,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A @removeTagHelper directive.
|
/// A <c>@removeTagHelper</c> directive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RemoveTagHelper
|
RemoveTagHelper,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A <c>@tagHelperPrefix</c> directive.
|
||||||
|
/// </summary>
|
||||||
|
TagHelperPrefix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue