Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Commit 2ad828f

Browse files
author
N. Taylor Mullen
committed
Change TagHelper tag and attribute names to be lower kebab cased.
- Lower kebab casing is the HTML convention. #240
1 parent 2d2c2cd commit 2ad828f

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.Linq;
77
using System.Reflection;
8+
using System.Text.RegularExpressions;
89
using Microsoft.AspNet.Razor.TagHelpers;
910

1011
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
@@ -15,6 +16,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
1516
public static class TagHelperDescriptorFactory
1617
{
1718
private const string TagHelperNameEnding = "TagHelper";
19+
private const string HtmlCaseRegexReplacement = "-$1$2";
20+
21+
// This matches the following AFTER the start of the input string (MATCH).
22+
// Any letter/number followed by an uppercase letter then lowercase letter: 1(Aa), a(Aa), A(Aa)
23+
// Any lowercase letter followed by an uppercase letter: a(A)
24+
// Each match is then prefixed by a "-" via the ToHtmlCase method.
25+
private static readonly Regex HtmlCaseRegex =
26+
new Regex("(?<!^)((?<=[a-zA-Z0-9])[A-Z][a-z])|((?<=[a-z])[A-Z])", RegexOptions.None);
1827

1928
// TODO: Investigate if we should cache TagHelperDescriptors for types:
2029
// https://github.com/aspnet/Razor/issues/165
@@ -55,7 +64,7 @@ private static IEnumerable<string> GetTagNames(Type tagHelperType)
5564
name = name.Substring(0, name.Length - TagHelperNameEnding.Length);
5665
}
5766

58-
return new[] { name };
67+
return new[] { ToHtmlCase(name) };
5968
}
6069

6170
// Remove duplicate tag names.
@@ -75,7 +84,7 @@ private static TagHelperAttributeDescriptor ToAttributeDescriptor(PropertyInfo p
7584
var attributeNameAttribute = property.GetCustomAttribute<HtmlAttributeNameAttribute>(inherit: false);
7685
var attributeName = attributeNameAttribute != null ?
7786
attributeNameAttribute.Name :
78-
property.Name;
87+
ToHtmlCase(property.Name);
7988

8089
return new TagHelperAttributeDescriptor(attributeName, property.Name, property.PropertyType.FullName);
8190
}
@@ -97,5 +106,22 @@ private static bool IsValidProperty(PropertyInfo property)
97106
property.SetMethod != null &&
98107
property.SetMethod.IsPublic;
99108
}
109+
110+
/// <summary>
111+
/// Converts from pascal/camel case to lower kebab-case.
112+
/// </summary>
113+
/// <example>
114+
/// SomeThing => some-thing
115+
/// capsONInside => caps-on-inside
116+
/// CAPSOnOUTSIDE => caps-on-outside
117+
/// ALLCAPS => allcaps
118+
/// One1Two2Three3 => one1-two2-three3
119+
/// ONE1TWO2THREE3 => one1two2three3
120+
/// First_Second_ThirdHi => first_second_third-hi
121+
/// </example>
122+
private static string ToHtmlCase(string name)
123+
{
124+
return HtmlCaseRegex.Replace(name, HtmlCaseRegexReplacement).ToLowerInvariant();
125+
}
100126
}
101127
}

src/Microsoft.AspNet.Razor.Runtime/project.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"aspnet50": { },
1010
"aspnetcore50": {
1111
"dependencies": {
12-
"System.Reflection.Extensions": "4.0.0-beta-*"
12+
"System.Reflection.Extensions": "4.0.0-beta-*",
13+
"System.Text.RegularExpressions": "4.0.10-beta-*"
1314
}
1415
}
1516
}

0 commit comments

Comments
 (0)