diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs
index 4847df3fc4..0b0c76f620 100644
--- a/src/Umbraco.Core/StringExtensions.cs
+++ b/src/Umbraco.Core/StringExtensions.cs
@@ -1084,7 +1084,7 @@ namespace Umbraco.Core
var cases2 = cases.ToCleanStringType() & CleanStringType.CaseMask;
return legacy != null
? legacy.LegacyConvertStringCase(phrase, cases2)
- : helper.CleanString(phrase, CleanStringType.Ascii | CleanStringType.Alias | cases2);
+ : helper.CleanString(phrase, CleanStringType.Ascii | CleanStringType.ConvertCase | cases2);
}
// the new methods to clean a string (to alias, url segment...)
diff --git a/src/Umbraco.Core/Strings/CleanStringType.cs b/src/Umbraco.Core/Strings/CleanStringType.cs
index f681c42d4a..4c53be4cb8 100644
--- a/src/Umbraco.Core/Strings/CleanStringType.cs
+++ b/src/Umbraco.Core/Strings/CleanStringType.cs
@@ -14,25 +14,6 @@ namespace Umbraco.Core.Strings
// note: you have 32 bits at your disposal
// 0xffffffff
-
- // masks
-
- ///
- /// Flag mask for casing.
- ///
- CaseMask = 0x3f, // 0xff - 8 possible values
-
- ///
- /// Flag mask for encoding.
- ///
- CodeMask = 0x700, // 0xff00 - 8 possible values
-
- ///
- /// Flag mask for role.
- ///
- RoleMask = 0x070000, // 0xff0000 - 8 possible values
-
-
// no value
///
@@ -43,6 +24,11 @@ namespace Umbraco.Core.Strings
// casing values
+ ///
+ /// Flag mask for casing.
+ ///
+ CaseMask = PascalCase | CamelCase | Unchanged | LowerCase | UpperCase | UmbracoCase,
+
///
/// Pascal casing eg "PascalCase".
///
@@ -78,6 +64,11 @@ namespace Umbraco.Core.Strings
// encoding values
+ ///
+ /// Flag mask for encoding.
+ ///
+ CodeMask = Unicode | Utf8 | Ascii,
+
///
/// Unicode encoding.
///
@@ -97,6 +88,11 @@ namespace Umbraco.Core.Strings
// role values
+ ///
+ /// Flag mask for role.
+ ///
+ RoleMask = UrlSegment | Alias | FileName | ConvertCase,
+
///
/// Url role.
///
@@ -110,6 +106,11 @@ namespace Umbraco.Core.Strings
///
/// FileName role.
///
- FileName = 0x040000
+ FileName = 0x040000,
+
+ ///
+ /// ConvertCase role.
+ ///
+ ConvertCase = 0x080000
}
}
diff --git a/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs b/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs
index 25abba7232..92d82c9a6b 100644
--- a/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs
+++ b/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs
@@ -1,4 +1,8 @@
-using System;
+
+// debugging - define to write cleaning details & steps to console
+#define WRTCONS
+
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@@ -160,6 +164,12 @@ namespace Umbraco.Core.Strings
: (char.IsLetterOrDigit(c) || c == '_'), // letter, digit or underscore
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
BreakTermsOnUpper = false
+ }).WithConfig(CleanStringType.ConvertCase, new Config
+ {
+ PreFilter = null,
+ IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
+ StringType = CleanStringType.Ascii,
+ BreakTermsOnUpper = true
});
}
@@ -487,6 +497,10 @@ function validateSafeAlias(id, value, immediate, callback) {{
if (culture == null)
throw new ArgumentNullException("culture");
+#if WRTCONS
+ Console.WriteLine("STRING TYPE {0}", stringType);
+#endif
+
// get config
var config = GetConfig(stringType, culture);
stringType = config.StringTypeExtend(stringType);
@@ -554,6 +568,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
var state = StateBreak;
caseType &= CleanStringType.CaseMask;
+#if WRTCONS
+ Console.WriteLine("CASE {0}", caseType);
+#endif
// if we apply global ToUpper or ToLower to text here
// then we cannot break words on uppercase chars
@@ -579,13 +596,13 @@ function validateSafeAlias(id, value, immediate, callback) {{
var isPair = char.IsSurrogate(c);
if (isPair)
throw new NotSupportedException("Surrogate pairs are not supported.");
-
- //Console.WriteLine("CHAR '{0}' {1} {2} - {3} - {4}/{5} {6}",
- // c,
- // isTerm ? "term" : "!term", isUpper ? "upper" : "!upper",
- // state,
- // i, ipos, leading ? "leading" : "!leading");
-
+#if WRTCONS
+ Console.WriteLine("CHAR '{0}' {1} {2} - {3} - {4}/{5} {6}",
+ c,
+ isTerm ? "term" : "!term", isUpper ? "upper" : "!upper",
+ state,
+ i, ipos, leading ? "leading" : "!leading");
+#endif
switch (state)
{
// within a break
@@ -692,11 +709,12 @@ function validateSafeAlias(id, value, immediate, callback) {{
CleanStringType caseType, CultureInfo culture, bool isAcronym)
{
var term = input.Substring(ipos, len);
- //Console.WriteLine("TERM \"{0}\" {1} {2}",
- // term,
- // isAcronym ? "acronym" : "word",
- // caseType);
-
+#if WRTCONS
+ Console.WriteLine("TERM \"{0}\" {1} {2}",
+ term,
+ isAcronym ? "acronym" : "word",
+ caseType);
+#endif
if (isAcronym)
{
if ((caseType == CleanStringType.CamelCase && len <= 2 && opos > 0) ||
diff --git a/src/Umbraco.Tests/CoreStrings/DefaultShortStringHelperTests.cs b/src/Umbraco.Tests/CoreStrings/DefaultShortStringHelperTests.cs
index f8b5808681..64a432e815 100644
--- a/src/Umbraco.Tests/CoreStrings/DefaultShortStringHelperTests.cs
+++ b/src/Umbraco.Tests/CoreStrings/DefaultShortStringHelperTests.cs
@@ -6,8 +6,12 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+using Moq;
using NUnit.Framework;
+using umbraco;
using Umbraco.Core;
+using Umbraco.Core.Configuration;
+using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Strings;
using Umbraco.Core.ObjectResolution;
using Umbraco.Tests.TestHelpers;
@@ -65,6 +69,13 @@ namespace Umbraco.Tests.CoreStrings
PreFilter = WhiteQuotes,
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c),
StringType = CleanStringType.UmbracoCase | CleanStringType.Ascii
+ })
+ .WithConfig(CleanStringType.ConvertCase, new DefaultShortStringHelper.Config
+ {
+ PreFilter = null,
+ IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
+ StringType = CleanStringType.Ascii,
+ BreakTermsOnUpper = true
});
ShortStringHelperResolver.Reset();
@@ -98,9 +109,30 @@ namespace Umbraco.Tests.CoreStrings
return s;
}
+ [Test]
+ public void U4_4055_4056()
+ {
+ var settings = SettingsForTests.GenerateMockSettings();
+ var contentMock = Mock.Get(settings.RequestHandler);
+ contentMock.Setup(x => x.CharCollection).Returns(Enumerable.Empty());
+ contentMock.Setup(x => x.ConvertUrlsToAscii).Returns(false);
+ SettingsForTests.ConfigureSettings(settings);
+
+ const string input = "publishedVersion";
+
+ Assert.AreEqual("PublishedVersion", input.ConvertCase(StringAliasCaseType.PascalCase)); // obsolete, use the one below
+ Assert.AreEqual("PublishedVersion", input.ToCleanString(CleanStringType.ConvertCase | CleanStringType.PascalCase | CleanStringType.Ascii)); // role, case and code
+ }
+
[Test]
public void U4_4056()
{
+ var settings = SettingsForTests.GenerateMockSettings();
+ var contentMock = Mock.Get(settings.RequestHandler);
+ contentMock.Setup(x => x.CharCollection).Returns(Enumerable.Empty());
+ contentMock.Setup(x => x.ConvertUrlsToAscii).Returns(false);
+ SettingsForTests.ConfigureSettings(settings);
+
const string input = "ÆØÅ and æøå and 中文测试 and אודות האתר and größer БбДдЖж page";
var helper = new DefaultShortStringHelper().WithDefaultConfig(); // unicode
@@ -381,6 +413,12 @@ namespace Umbraco.Tests.CoreStrings
[Test]
public void CleanStringDefaultConfig()
{
+ var settings = SettingsForTests.GenerateMockSettings();
+ var contentMock = Mock.Get(settings.RequestHandler);
+ contentMock.Setup(x => x.CharCollection).Returns(Enumerable.Empty());
+ contentMock.Setup(x => x.ConvertUrlsToAscii).Returns(false);
+ SettingsForTests.ConfigureSettings(settings);
+
var helper = new DefaultShortStringHelper().WithDefaultConfig();
const string input = "0123 中文测试 中文测试 léger ZÔRG (2) a?? *x";