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 fbbc25ea20..07f262c272 100644 --- a/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs +++ b/src/Umbraco.Core/Strings/DefaultShortStringHelper.cs @@ -1,9 +1,20 @@ -using System; + +// debugging +// define WRTCONS to write cleaning details & steps to console +// leave it wrapped within #if DEBUG to make sure it does leak +// into RELEASE, see http://issues.umbraco.org/issue/U4-4199 +#if DEBUG +#undef WRTCONS +#endif + +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; using Umbraco.Core.Configuration; namespace Umbraco.Core.Strings @@ -176,6 +187,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 }); } @@ -503,6 +520,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); @@ -570,6 +591,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 @@ -595,13 +619,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 @@ -708,11 +732,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) ||