Resvolution - ShortStringHelperResolver
This commit is contained in:
@@ -457,8 +457,8 @@ namespace Umbraco.Core
|
||||
.Append(PluginManager.ResolveTypes<IPropertyValueConverter>());
|
||||
|
||||
// use the new DefaultShortStringHelper
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(Container,
|
||||
factory => new DefaultShortStringHelper(factory.GetInstance<IUmbracoSettingsSection>()).WithDefaultConfig());
|
||||
Container.RegisterSingleton<IShortStringHelper>(factory
|
||||
=> new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(factory.GetInstance<IUmbracoSettingsSection>())));
|
||||
|
||||
UrlSegmentProviderCollectionBuilder.Register(Container)
|
||||
.Append<DefaultUrlSegmentProvider>();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using LightInject;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
@@ -38,6 +40,7 @@ namespace Umbraco.Core.DependencyInjection
|
||||
internal static void Reset()
|
||||
{
|
||||
_container = null;
|
||||
_shortStringHelper = null;
|
||||
Resetted?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
@@ -78,6 +81,26 @@ namespace Umbraco.Core.DependencyInjection
|
||||
public static ICultureDictionaryFactory CultureDictionaryFactory
|
||||
=> Container.GetInstance<ICultureDictionaryFactory>();
|
||||
|
||||
private static IShortStringHelper _shortStringHelper;
|
||||
|
||||
public static IShortStringHelper ShortStringHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
// fixme - refactor
|
||||
// we don't want Umbraco to die because the resolver hasn't been initialized
|
||||
// as the ShortStringHelper is too important, so as long as it's not there
|
||||
// already, we use a default one. That should never happen, but... in can, in
|
||||
// some tests - we should really cleanup our tests and get rid of this!
|
||||
|
||||
if (_shortStringHelper != null) return _shortStringHelper;
|
||||
var reg = HasContainer ? Container.GetAvailableService<IShortStringHelper>() : null;
|
||||
return _shortStringHelper = reg == null
|
||||
? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(UmbracoConfig.For.UmbracoSettings()))
|
||||
: Container.GetInstance<IShortStringHelper>();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ using Umbraco.Core.Configuration;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -998,32 +999,6 @@ namespace Umbraco.Core
|
||||
: input.Substring(0, 1).ToLowerInvariant() + input.Substring(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the short string helper.
|
||||
/// </summary>
|
||||
/// <remarks>This is so that unit tests that do not initialize the resolver do not
|
||||
/// fail and fall back to defaults. When running the whole Umbraco, CoreBootManager
|
||||
/// does initialise the resolver.</remarks>
|
||||
private static IShortStringHelper ShortStringHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ShortStringHelperResolver.HasCurrent)
|
||||
return ShortStringHelperResolver.Current.Helper;
|
||||
if (_helper != null)
|
||||
return _helper;
|
||||
|
||||
// we don't want Umbraco to die because the resolver hasn't been initialized
|
||||
// as the ShortStringHelper is too important, so as long as it's not there
|
||||
// already, we use a default one. That should never happen, but...
|
||||
Logging.LogHelper.Warn<IShortStringHelper>("ShortStringHelperResolver.HasCurrent == false, fallback to default.");
|
||||
_helper = new DefaultShortStringHelper(UmbracoConfig.For.UmbracoSettings()).WithDefaultConfig();
|
||||
_helper.Freeze();
|
||||
return _helper;
|
||||
}
|
||||
}
|
||||
private static IShortStringHelper _helper;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new string in which all occurences of specified strings are replaced by other specified strings.
|
||||
/// </summary>
|
||||
@@ -1032,7 +1007,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The filtered string.</returns>
|
||||
public static string ReplaceMany(this string text, IDictionary<string, string> replacements)
|
||||
{
|
||||
return ShortStringHelper.ReplaceMany(text, replacements);
|
||||
return Current.ShortStringHelper.ReplaceMany(text, replacements);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1044,7 +1019,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The filtered string.</returns>
|
||||
public static string ReplaceMany(this string text, char[] chars, char replacement)
|
||||
{
|
||||
return ShortStringHelper.ReplaceMany(text, chars, replacement);
|
||||
return Current.ShortStringHelper.ReplaceMany(text, chars, replacement);
|
||||
}
|
||||
|
||||
// FORMAT STRINGS
|
||||
@@ -1056,7 +1031,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The safe alias.</returns>
|
||||
public static string ToSafeAlias(this string alias)
|
||||
{
|
||||
return ShortStringHelper.CleanStringForSafeAlias(alias);
|
||||
return Current.ShortStringHelper.CleanStringForSafeAlias(alias);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1067,7 +1042,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The safe alias.</returns>
|
||||
public static string ToSafeAlias(this string alias, bool camel)
|
||||
{
|
||||
var a = ShortStringHelper.CleanStringForSafeAlias(alias);
|
||||
var a = Current.ShortStringHelper.CleanStringForSafeAlias(alias);
|
||||
if (string.IsNullOrWhiteSpace(a) || camel == false) return a;
|
||||
return char.ToLowerInvariant(a[0]) + a.Substring(1);
|
||||
}
|
||||
@@ -1080,7 +1055,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The safe alias.</returns>
|
||||
public static string ToSafeAlias(this string alias, CultureInfo culture)
|
||||
{
|
||||
return ShortStringHelper.CleanStringForSafeAlias(alias, culture);
|
||||
return Current.ShortStringHelper.CleanStringForSafeAlias(alias, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1115,7 +1090,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The safe url segment.</returns>
|
||||
public static string ToUrlSegment(this string text)
|
||||
{
|
||||
return ShortStringHelper.CleanStringForUrlSegment(text);
|
||||
return Current.ShortStringHelper.CleanStringForUrlSegment(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1126,7 +1101,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The safe url segment.</returns>
|
||||
public static string ToUrlSegment(this string text, CultureInfo culture)
|
||||
{
|
||||
return ShortStringHelper.CleanStringForUrlSegment(text, culture);
|
||||
return Current.ShortStringHelper.CleanStringForUrlSegment(text, culture);
|
||||
}
|
||||
|
||||
// the new methods to clean a string (to alias, url segment...)
|
||||
@@ -1138,10 +1113,10 @@ namespace Umbraco.Core
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// strings are cleaned up to camelCase and Ascii.</param>
|
||||
/// <returns>The clean string.</returns>
|
||||
/// <remarks>The string is cleaned in the context of the IShortStringHelper default culture.</remarks>
|
||||
/// <remarks>The string is cleaned in the context of the ICurrent.ShortStringHelper default culture.</remarks>
|
||||
public static string ToCleanString(this string text, CleanStringType stringType)
|
||||
{
|
||||
return ShortStringHelper.CleanString(text, stringType);
|
||||
return Current.ShortStringHelper.CleanString(text, stringType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1152,10 +1127,10 @@ namespace Umbraco.Core
|
||||
/// strings are cleaned up to camelCase and Ascii.</param>
|
||||
/// <param name="separator">The separator.</param>
|
||||
/// <returns>The clean string.</returns>
|
||||
/// <remarks>The string is cleaned in the context of the IShortStringHelper default culture.</remarks>
|
||||
/// <remarks>The string is cleaned in the context of the ICurrent.ShortStringHelper default culture.</remarks>
|
||||
public static string ToCleanString(this string text, CleanStringType stringType, char separator)
|
||||
{
|
||||
return ShortStringHelper.CleanString(text, stringType, separator);
|
||||
return Current.ShortStringHelper.CleanString(text, stringType, separator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1168,7 +1143,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The clean string.</returns>
|
||||
public static string ToCleanString(this string text, CleanStringType stringType, CultureInfo culture)
|
||||
{
|
||||
return ShortStringHelper.CleanString(text, stringType, culture);
|
||||
return Current.ShortStringHelper.CleanString(text, stringType, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1182,11 +1157,11 @@ namespace Umbraco.Core
|
||||
/// <returns>The clean string.</returns>
|
||||
public static string ToCleanString(this string text, CleanStringType stringType, char separator, CultureInfo culture)
|
||||
{
|
||||
return ShortStringHelper.CleanString(text, stringType, separator, culture);
|
||||
return Current.ShortStringHelper.CleanString(text, stringType, separator, culture);
|
||||
}
|
||||
|
||||
// note: LegacyShortStringHelper will produce 100% backward-compatible output for SplitPascalCasing.
|
||||
// other helpers may not. DefaultShortStringHelper produces better, but non-compatible, results.
|
||||
// note: LegacyCurrent.ShortStringHelper will produce 100% backward-compatible output for SplitPascalCasing.
|
||||
// other helpers may not. DefaultCurrent.ShortStringHelper produces better, but non-compatible, results.
|
||||
|
||||
/// <summary>
|
||||
/// Splits a Pascal cased string into a phrase separated by spaces.
|
||||
@@ -1195,7 +1170,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The splitted text.</returns>
|
||||
public static string SplitPascalCasing(this string phrase)
|
||||
{
|
||||
return ShortStringHelper.SplitPascalCasing(phrase, ' ');
|
||||
return Current.ShortStringHelper.SplitPascalCasing(phrase, ' ');
|
||||
}
|
||||
|
||||
//NOTE: Not sure what this actually does but is used a few places, need to figure it out and then move to StringExtensions and obsolete.
|
||||
@@ -1216,7 +1191,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The safe filename.</returns>
|
||||
public static string ToSafeFileName(this string text)
|
||||
{
|
||||
return ShortStringHelper.CleanStringForSafeFileName(text);
|
||||
return Current.ShortStringHelper.CleanStringForSafeFileName(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1228,7 +1203,7 @@ namespace Umbraco.Core
|
||||
/// <returns>The safe filename.</returns>
|
||||
public static string ToSafeFileName(this string text, CultureInfo culture)
|
||||
{
|
||||
return ShortStringHelper.CleanStringForSafeFileName(text, culture);
|
||||
return Current.ShortStringHelper.CleanStringForSafeFileName(text, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
|
||||
namespace Umbraco.Core.Strings
|
||||
@@ -19,30 +18,17 @@ namespace Umbraco.Core.Strings
|
||||
/// </remarks>
|
||||
public class DefaultShortStringHelper : IShortStringHelper
|
||||
{
|
||||
private readonly IUmbracoSettingsSection _umbracoSettings;
|
||||
|
||||
#region Ctor and vars
|
||||
|
||||
[Obsolete("Use the other ctor that specifies all dependencies")]
|
||||
public DefaultShortStringHelper()
|
||||
public DefaultShortStringHelper(IUmbracoSettingsSection settings)
|
||||
{
|
||||
_umbracoSettings = _umbracoSettings;
|
||||
InitializeLegacyUrlReplaceCharacters();
|
||||
_config = new DefaultShortStringHelperConfig().WithDefault(settings);
|
||||
}
|
||||
|
||||
public DefaultShortStringHelper(IUmbracoSettingsSection umbracoSettings)
|
||||
// clones the config so it cannot be changed at runtime
|
||||
public DefaultShortStringHelper(DefaultShortStringHelperConfig config)
|
||||
{
|
||||
_umbracoSettings = umbracoSettings;
|
||||
InitializeLegacyUrlReplaceCharacters();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Freezes the helper so it can prevents its configuration from being modified.
|
||||
/// </summary>
|
||||
/// <remarks>Will be called by <c>ShortStringHelperResolver</c> when resolution freezes.</remarks>
|
||||
public void Freeze()
|
||||
{
|
||||
_frozen = true;
|
||||
_config = config.Clone();
|
||||
}
|
||||
|
||||
// see notes for CleanAsciiString
|
||||
@@ -50,9 +36,7 @@ namespace Umbraco.Core.Strings
|
||||
//const string ValidStringCharactersSource = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
//readonly static char[] ValidStringCharacters;
|
||||
|
||||
private CultureInfo _defaultCulture = CultureInfo.InvariantCulture;
|
||||
private bool _frozen;
|
||||
private readonly Dictionary<CultureInfo, Dictionary<CleanStringType, Config>> _configs = new Dictionary<CultureInfo, Dictionary<CleanStringType, Config>>();
|
||||
private readonly DefaultShortStringHelperConfig _config;
|
||||
|
||||
// see notes for CleanAsciiString
|
||||
//static DefaultShortStringHelper()
|
||||
@@ -64,27 +48,6 @@ namespace Umbraco.Core.Strings
|
||||
|
||||
#region Filters
|
||||
|
||||
private readonly Dictionary<string, string> _urlReplaceCharacters = new Dictionary<string, string>();
|
||||
|
||||
private void InitializeLegacyUrlReplaceCharacters()
|
||||
{
|
||||
foreach (var node in _umbracoSettings.RequestHandler.CharCollection)
|
||||
{
|
||||
if(string.IsNullOrEmpty(node.Char) == false)
|
||||
_urlReplaceCharacters[node.Char] = node.Replacement;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new string in which characters have been replaced according to the Umbraco settings UrlReplaceCharacters.
|
||||
/// </summary>
|
||||
/// <param name="s">The string to filter.</param>
|
||||
/// <returns>The filtered string.</returns>
|
||||
public string ApplyUrlReplaceCharacters(string s)
|
||||
{
|
||||
return s.ReplaceMany(_urlReplaceCharacters);
|
||||
}
|
||||
|
||||
// ok to be static here because it's not configureable in any way
|
||||
private static readonly char[] InvalidFileNameChars =
|
||||
Path.GetInvalidFileNameChars()
|
||||
@@ -97,194 +60,6 @@ namespace Umbraco.Core.Strings
|
||||
return InvalidFileNameChars.Contains(c) == false;
|
||||
}
|
||||
|
||||
public static string CutMaxLength(string text, int length)
|
||||
{
|
||||
return text.Length <= length ? text : text.Substring(0, length);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configuration
|
||||
|
||||
private void EnsureNotFrozen()
|
||||
{
|
||||
if (_frozen)
|
||||
throw new InvalidOperationException("Cannot configure the helper once it is frozen.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a default culture.
|
||||
/// </summary>
|
||||
/// <param name="culture">The default culture.</param>
|
||||
/// <returns>The short string helper.</returns>
|
||||
public DefaultShortStringHelper WithDefaultCulture(CultureInfo culture)
|
||||
{
|
||||
EnsureNotFrozen();
|
||||
_defaultCulture = culture;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultShortStringHelper WithConfig(Config config)
|
||||
{
|
||||
return WithConfig(_defaultCulture, CleanStringType.RoleMask, config);
|
||||
}
|
||||
|
||||
public DefaultShortStringHelper WithConfig(CleanStringType stringRole, Config config)
|
||||
{
|
||||
return WithConfig(_defaultCulture, stringRole, config);
|
||||
}
|
||||
|
||||
public DefaultShortStringHelper WithConfig(CultureInfo culture, CleanStringType stringRole, Config config)
|
||||
{
|
||||
if (config == null)
|
||||
throw new ArgumentNullException("config");
|
||||
|
||||
EnsureNotFrozen();
|
||||
if (_configs.ContainsKey(culture) == false)
|
||||
_configs[culture] = new Dictionary<CleanStringType, Config>();
|
||||
_configs[culture][stringRole] = config.Clone(); // clone so it can't be changed
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default configuration.
|
||||
/// </summary>
|
||||
/// <returns>The short string helper.</returns>
|
||||
public DefaultShortStringHelper WithDefaultConfig()
|
||||
{
|
||||
return WithConfig(CleanStringType.UrlSegment, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
PostFilter = x => CutMaxLength(x, 240),
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = (_umbracoSettings.RequestHandler.ConvertUrlsToAscii ? CleanStringType.Ascii : CleanStringType.Utf8) | CleanStringType.LowerCase,
|
||||
BreakTermsOnUpper = false,
|
||||
Separator = '-'
|
||||
}).WithConfig(CleanStringType.FileName, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.LowerCase,
|
||||
BreakTermsOnUpper = false,
|
||||
Separator = '-'
|
||||
}).WithConfig(CleanStringType.Alias, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
IsTerm = (c, leading) => leading
|
||||
? char.IsLetter(c) // only letters
|
||||
: (char.IsLetterOrDigit(c) || c == '_'), // letter, digit or underscore
|
||||
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
|
||||
BreakTermsOnUpper = false
|
||||
}).WithConfig(CleanStringType.UnderscoreAlias, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
IsTerm = (c, leading) => 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
|
||||
});
|
||||
}
|
||||
|
||||
public sealed class Config
|
||||
{
|
||||
public Config()
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged;
|
||||
PreFilter = null;
|
||||
PostFilter = null;
|
||||
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c);
|
||||
BreakTermsOnUpper = false;
|
||||
CutAcronymOnNonUpper = false;
|
||||
GreedyAcronyms = false;
|
||||
Separator = Char.MinValue;
|
||||
}
|
||||
|
||||
public Config Clone()
|
||||
{
|
||||
return new Config
|
||||
{
|
||||
PreFilter = PreFilter,
|
||||
PostFilter = PostFilter,
|
||||
IsTerm = IsTerm,
|
||||
StringType = StringType,
|
||||
BreakTermsOnUpper = BreakTermsOnUpper,
|
||||
CutAcronymOnNonUpper = CutAcronymOnNonUpper,
|
||||
GreedyAcronyms = GreedyAcronyms,
|
||||
Separator = Separator
|
||||
};
|
||||
}
|
||||
|
||||
public Func<string, string> PreFilter { get; set; }
|
||||
public Func<string, string> PostFilter { get; set; }
|
||||
public Func<char, bool, bool> IsTerm { get; set; }
|
||||
|
||||
public CleanStringType StringType { get; set; }
|
||||
|
||||
// indicate whether an uppercase within a term eg "fooBar" is to break
|
||||
// into a new term, or to be considered as part of the current term
|
||||
public bool BreakTermsOnUpper { get; set; }
|
||||
|
||||
// indicate whether a non-uppercase within an acronym eg "FOOBar" is to cut
|
||||
// the acronym (at "B" or "a" depending on GreedyAcronyms) or to give
|
||||
// up the acronym and treat the term as a word
|
||||
public bool CutAcronymOnNonUpper { get; set; }
|
||||
|
||||
// indicates whether acronyms parsing is greedy ie whether "FOObar" is
|
||||
// "FOO" + "bar" (greedy) or "FO" + "Obar" (non-greedy)
|
||||
public bool GreedyAcronyms { get; set; }
|
||||
|
||||
// the separator char
|
||||
// but then how can we tell we dont want any?
|
||||
public char Separator { get; set; }
|
||||
|
||||
// extends the config
|
||||
public CleanStringType StringTypeExtend(CleanStringType stringType)
|
||||
{
|
||||
var st = StringType;
|
||||
foreach (var mask in new[] { CleanStringType.CaseMask, CleanStringType.CodeMask })
|
||||
{
|
||||
var a = stringType & mask;
|
||||
if (a == 0) continue;
|
||||
|
||||
st = st & ~mask; // clear what we have
|
||||
st = st | a; // set the new value
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
internal static readonly Config NotConfigured = new Config();
|
||||
}
|
||||
|
||||
private Config GetConfig(CleanStringType stringType, CultureInfo culture)
|
||||
{
|
||||
stringType = stringType & CleanStringType.RoleMask;
|
||||
|
||||
Dictionary<CleanStringType, Config> config;
|
||||
if (_configs.ContainsKey(culture))
|
||||
{
|
||||
config = _configs[culture];
|
||||
if (config.ContainsKey(stringType)) // have we got a config for _that_ role?
|
||||
return config[stringType];
|
||||
if (config.ContainsKey(CleanStringType.RoleMask)) // have we got a generic config for _all_ roles?
|
||||
return config[CleanStringType.RoleMask];
|
||||
}
|
||||
else if (_configs.ContainsKey(_defaultCulture))
|
||||
{
|
||||
config = _configs[_defaultCulture];
|
||||
if (config.ContainsKey(stringType)) // have we got a config for _that_ role?
|
||||
return config[stringType];
|
||||
if (config.ContainsKey(CleanStringType.RoleMask)) // have we got a generic config for _all_ roles?
|
||||
return config[CleanStringType.RoleMask];
|
||||
}
|
||||
|
||||
return Config.NotConfigured;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region JavaScript
|
||||
@@ -333,8 +108,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
/// </summary>
|
||||
public string GetShortStringServicesJavaScript(string controllerPath)
|
||||
{
|
||||
return string.Format(SssjsFormat,
|
||||
_umbracoSettings.Content.ForceSafeAliases ? "true" : "false", controllerPath);
|
||||
return string.Format(SssjsFormat, _config.ForceSafeAliases ? "true" : "false", controllerPath);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -352,7 +126,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
/// </remarks>
|
||||
public virtual string CleanStringForSafeAlias(string text)
|
||||
{
|
||||
return CleanStringForSafeAlias(text, _defaultCulture);
|
||||
return CleanStringForSafeAlias(text, _config.DefaultCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -380,7 +154,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
/// </remarks>
|
||||
public virtual string CleanStringForUrlSegment(string text)
|
||||
{
|
||||
return CleanStringForUrlSegment(text, _defaultCulture);
|
||||
return CleanStringForUrlSegment(text, _config.DefaultCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -406,7 +180,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
/// <remarks>Legacy says this was used to "overcome an issue when Umbraco is used in IE in an intranet environment" but that issue is not documented.</remarks>
|
||||
public virtual string CleanStringForSafeFileName(string text)
|
||||
{
|
||||
return CleanStringForSafeFileName(text, _defaultCulture);
|
||||
return CleanStringForSafeFileName(text, _config.DefaultCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -452,43 +226,43 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
// - Leading digits are removed.
|
||||
// - Many consecutive separators are folded into one unique separator.
|
||||
|
||||
const byte StateBreak = 1;
|
||||
const byte StateUp = 2;
|
||||
const byte StateWord = 3;
|
||||
const byte StateAcronym = 4;
|
||||
private const byte StateBreak = 1;
|
||||
private const byte StateUp = 2;
|
||||
private const byte StateWord = 3;
|
||||
private const byte StateAcronym = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Cleans a string.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to clean.</param>
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// strings are cleaned up to camelCase and Ascii.</param>
|
||||
/// <returns>The clean string.</returns>
|
||||
/// <remarks>The string is cleaned in the context of the default culture.</remarks>
|
||||
public string CleanString(string text, CleanStringType stringType)
|
||||
{
|
||||
return CleanString(text, stringType, _defaultCulture, null);
|
||||
return CleanString(text, stringType, _config.DefaultCulture, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans a string, using a specified separator.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to clean.</param>
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// strings are cleaned up to camelCase and Ascii.</param>
|
||||
/// <param name="separator">The separator.</param>
|
||||
/// <returns>The clean string.</returns>
|
||||
/// <remarks>The string is cleaned in the context of the default culture.</remarks>
|
||||
public string CleanString(string text, CleanStringType stringType, char separator)
|
||||
{
|
||||
return CleanString(text, stringType, _defaultCulture, separator);
|
||||
return CleanString(text, stringType, _config.DefaultCulture, separator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans a string in the context of a specified culture.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to clean.</param>
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// strings are cleaned up to camelCase and Ascii.</param>
|
||||
/// <param name="culture">The culture.</param>
|
||||
/// <returns>The clean string.</returns>
|
||||
@@ -501,7 +275,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
/// Cleans a string in the context of a specified culture, using a specified separator.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to clean.</param>
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// <param name="stringType">A flag indicating the target casing and encoding of the string. By default,
|
||||
/// strings are cleaned up to camelCase and Ascii.</param>
|
||||
/// <param name="separator">The separator.</param>
|
||||
/// <param name="culture">The culture.</param>
|
||||
@@ -514,13 +288,11 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
protected virtual string CleanString(string text, CleanStringType stringType, CultureInfo culture, char? separator)
|
||||
{
|
||||
// be safe
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
if (culture == null)
|
||||
throw new ArgumentNullException("culture");
|
||||
if (text == null) throw new ArgumentNullException(nameof(text));
|
||||
if (culture == null) throw new ArgumentNullException(nameof(culture));
|
||||
|
||||
// get config
|
||||
var config = GetConfig(stringType, culture);
|
||||
var config = _config.For(stringType, culture);
|
||||
stringType = config.StringTypeExtend(stringType);
|
||||
|
||||
// apply defaults
|
||||
@@ -542,8 +314,8 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
|
||||
// recode
|
||||
var codeType = stringType & CleanStringType.CodeMask;
|
||||
text = codeType == CleanStringType.Ascii
|
||||
? Utf8ToAsciiConverter.ToAsciiString(text)
|
||||
text = codeType == CleanStringType.Ascii
|
||||
? Utf8ToAsciiConverter.ToAsciiString(text)
|
||||
: RemoveSurrogatePairs(text);
|
||||
|
||||
// clean
|
||||
@@ -552,7 +324,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
// apply post-filter
|
||||
if (config.PostFilter != null)
|
||||
text = config.PostFilter(text);
|
||||
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -584,7 +356,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
// that the utf8 version. Micro-optimizing sometimes isn't such a good idea.
|
||||
|
||||
// note: does NOT support surrogate pairs in text
|
||||
internal string CleanCodeString(string text, CleanStringType caseType, char separator, CultureInfo culture, Config config)
|
||||
internal string CleanCodeString(string text, CleanStringType caseType, char separator, CultureInfo culture, DefaultShortStringHelperConfig.Config config)
|
||||
{
|
||||
int opos = 0, ipos = 0;
|
||||
var state = StateBreak;
|
||||
@@ -822,12 +594,12 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
{
|
||||
term = term.Substring(i);
|
||||
term.CopyTo(0, output, opos, term.Length);
|
||||
opos += term.Length;
|
||||
opos += term.Length;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("caseType");
|
||||
throw new ArgumentOutOfRangeException(nameof(caseType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,7 +619,7 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
{
|
||||
// be safe
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
throw new ArgumentNullException(nameof(text));
|
||||
|
||||
var input = text.ToCharArray();
|
||||
var output = new char[input.Length * 2];
|
||||
@@ -898,12 +670,10 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
public virtual string ReplaceMany(string text, IDictionary<string, string> replacements)
|
||||
{
|
||||
// be safe
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
if (replacements == null)
|
||||
throw new ArgumentNullException("replacements");
|
||||
if (text == null) throw new ArgumentNullException(nameof(text));
|
||||
if (replacements == null) throw new ArgumentNullException(nameof(replacements));
|
||||
|
||||
// Have done various tests, implementing my own "super fast" state machine to handle
|
||||
// Have done various tests, implementing my own "super fast" state machine to handle
|
||||
// replacement of many items, or via regexes, but on short strings and not too
|
||||
// many replacements (which prob. is going to be our case) nothing can beat this...
|
||||
// (at least with safe and checked code -- we don't want unsafe/unchecked here)
|
||||
@@ -924,10 +694,8 @@ function validateSafeAlias(input, value, immediate, callback) {{
|
||||
public virtual string ReplaceMany(string text, char[] chars, char replacement)
|
||||
{
|
||||
// be safe
|
||||
if (text == null)
|
||||
throw new ArgumentNullException("text");
|
||||
if (chars == null)
|
||||
throw new ArgumentNullException("chars");
|
||||
if (text == null) throw new ArgumentNullException(nameof(text));
|
||||
if (chars == null) throw new ArgumentNullException(nameof(chars));
|
||||
|
||||
// see note above
|
||||
|
||||
|
||||
218
src/Umbraco.Core/Strings/DefaultShortStringHelperConfig.cs
Normal file
218
src/Umbraco.Core/Strings/DefaultShortStringHelperConfig.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
|
||||
namespace Umbraco.Core.Strings
|
||||
{
|
||||
public class DefaultShortStringHelperConfig
|
||||
{
|
||||
private readonly Dictionary<CultureInfo, Dictionary<CleanStringType, Config>> _configs = new Dictionary<CultureInfo, Dictionary<CleanStringType, Config>>();
|
||||
|
||||
public DefaultShortStringHelperConfig Clone()
|
||||
{
|
||||
var config = new DefaultShortStringHelperConfig();
|
||||
config.DefaultCulture = DefaultCulture;
|
||||
config.ForceSafeAliases = ForceSafeAliases;
|
||||
config.UrlReplaceCharacters = UrlReplaceCharacters;
|
||||
|
||||
foreach (var kvp1 in _configs)
|
||||
{
|
||||
var c = config._configs[kvp1.Key] = new Dictionary<CleanStringType, Config>();
|
||||
foreach (var kvp2 in _configs[kvp1.Key])
|
||||
c[kvp2.Key] = kvp2.Value.Clone();
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
public CultureInfo DefaultCulture { get; set; } = CultureInfo.InvariantCulture;
|
||||
|
||||
public Dictionary<string, string> UrlReplaceCharacters { get; set; }
|
||||
|
||||
public bool ForceSafeAliases { get; set; }
|
||||
|
||||
public DefaultShortStringHelperConfig WithConfig(Config config)
|
||||
{
|
||||
return WithConfig(DefaultCulture, CleanStringType.RoleMask, config);
|
||||
}
|
||||
|
||||
public DefaultShortStringHelperConfig WithConfig(CleanStringType stringRole, Config config)
|
||||
{
|
||||
return WithConfig(DefaultCulture, stringRole, config);
|
||||
}
|
||||
|
||||
public DefaultShortStringHelperConfig WithConfig(CultureInfo culture, CleanStringType stringRole, Config config)
|
||||
{
|
||||
if (config == null) throw new ArgumentNullException(nameof(config));
|
||||
|
||||
if (_configs.ContainsKey(culture) == false)
|
||||
_configs[culture] = new Dictionary<CleanStringType, Config>();
|
||||
_configs[culture][stringRole] = config;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default configuration.
|
||||
/// </summary>
|
||||
/// <returns>The short string helper.</returns>
|
||||
public DefaultShortStringHelperConfig WithDefault(IUmbracoSettingsSection umbracoSettings)
|
||||
{
|
||||
ForceSafeAliases = umbracoSettings.Content.ForceSafeAliases;
|
||||
UrlReplaceCharacters = umbracoSettings.RequestHandler.CharCollection
|
||||
.Where(x => string.IsNullOrEmpty(x.Char) == false)
|
||||
.ToDictionary(x => x.Char, x => x.Replacement);
|
||||
var convertUrlsToAscii = umbracoSettings.RequestHandler.ConvertUrlsToAscii;
|
||||
|
||||
return WithConfig(CleanStringType.UrlSegment, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
PostFilter = x => CutMaxLength(x, 240),
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = (convertUrlsToAscii ? CleanStringType.Ascii : CleanStringType.Utf8) | CleanStringType.LowerCase,
|
||||
BreakTermsOnUpper = false,
|
||||
Separator = '-'
|
||||
}).WithConfig(CleanStringType.FileName, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.LowerCase,
|
||||
BreakTermsOnUpper = false,
|
||||
Separator = '-'
|
||||
}).WithConfig(CleanStringType.Alias, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
IsTerm = (c, leading) => leading
|
||||
? char.IsLetter(c) // only letters
|
||||
: (char.IsLetterOrDigit(c) || c == '_'), // letter, digit or underscore
|
||||
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
|
||||
BreakTermsOnUpper = false
|
||||
}).WithConfig(CleanStringType.UnderscoreAlias, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
IsTerm = (c, leading) => 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
|
||||
});
|
||||
}
|
||||
|
||||
// internal: we don't want ppl to retrieve a config and modify it
|
||||
// (the helper uses a private clone to prevent modifications)
|
||||
internal Config For(CleanStringType stringType, CultureInfo culture)
|
||||
{
|
||||
stringType = stringType & CleanStringType.RoleMask;
|
||||
|
||||
Dictionary<CleanStringType, Config> config;
|
||||
if (_configs.ContainsKey(culture))
|
||||
{
|
||||
config = _configs[culture];
|
||||
if (config.ContainsKey(stringType)) // have we got a config for _that_ role?
|
||||
return config[stringType];
|
||||
if (config.ContainsKey(CleanStringType.RoleMask)) // have we got a generic config for _all_ roles?
|
||||
return config[CleanStringType.RoleMask];
|
||||
}
|
||||
else if (_configs.ContainsKey(DefaultCulture))
|
||||
{
|
||||
config = _configs[DefaultCulture];
|
||||
if (config.ContainsKey(stringType)) // have we got a config for _that_ role?
|
||||
return config[stringType];
|
||||
if (config.ContainsKey(CleanStringType.RoleMask)) // have we got a generic config for _all_ roles?
|
||||
return config[CleanStringType.RoleMask];
|
||||
}
|
||||
|
||||
return Config.NotConfigured;
|
||||
}
|
||||
|
||||
public sealed class Config
|
||||
{
|
||||
public Config()
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged;
|
||||
PreFilter = null;
|
||||
PostFilter = null;
|
||||
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c);
|
||||
BreakTermsOnUpper = false;
|
||||
CutAcronymOnNonUpper = false;
|
||||
GreedyAcronyms = false;
|
||||
Separator = char.MinValue;
|
||||
}
|
||||
|
||||
public Config Clone()
|
||||
{
|
||||
return new Config
|
||||
{
|
||||
PreFilter = PreFilter,
|
||||
PostFilter = PostFilter,
|
||||
IsTerm = IsTerm,
|
||||
StringType = StringType,
|
||||
BreakTermsOnUpper = BreakTermsOnUpper,
|
||||
CutAcronymOnNonUpper = CutAcronymOnNonUpper,
|
||||
GreedyAcronyms = GreedyAcronyms,
|
||||
Separator = Separator
|
||||
};
|
||||
}
|
||||
|
||||
public Func<string, string> PreFilter { get; set; }
|
||||
public Func<string, string> PostFilter { get; set; }
|
||||
public Func<char, bool, bool> IsTerm { get; set; }
|
||||
|
||||
public CleanStringType StringType { get; set; }
|
||||
|
||||
// indicate whether an uppercase within a term eg "fooBar" is to break
|
||||
// into a new term, or to be considered as part of the current term
|
||||
public bool BreakTermsOnUpper { get; set; }
|
||||
|
||||
// indicate whether a non-uppercase within an acronym eg "FOOBar" is to cut
|
||||
// the acronym (at "B" or "a" depending on GreedyAcronyms) or to give
|
||||
// up the acronym and treat the term as a word
|
||||
public bool CutAcronymOnNonUpper { get; set; }
|
||||
|
||||
// indicates whether acronyms parsing is greedy ie whether "FOObar" is
|
||||
// "FOO" + "bar" (greedy) or "FO" + "Obar" (non-greedy)
|
||||
public bool GreedyAcronyms { get; set; }
|
||||
|
||||
// the separator char
|
||||
// but then how can we tell we dont want any?
|
||||
public char Separator { get; set; }
|
||||
|
||||
// extends the config
|
||||
public CleanStringType StringTypeExtend(CleanStringType stringType)
|
||||
{
|
||||
var st = StringType;
|
||||
foreach (var mask in new[] { CleanStringType.CaseMask, CleanStringType.CodeMask })
|
||||
{
|
||||
var a = stringType & mask;
|
||||
if (a == 0) continue;
|
||||
|
||||
st = st & ~mask; // clear what we have
|
||||
st = st | a; // set the new value
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
internal static readonly Config NotConfigured = new Config();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new string in which characters have been replaced according to the Umbraco settings UrlReplaceCharacters.
|
||||
/// </summary>
|
||||
/// <param name="s">The string to filter.</param>
|
||||
/// <returns>The filtered string.</returns>
|
||||
public string ApplyUrlReplaceCharacters(string s)
|
||||
{
|
||||
return UrlReplaceCharacters == null ? s : s.ReplaceMany(UrlReplaceCharacters);
|
||||
}
|
||||
|
||||
public static string CutMaxLength(string text, int length)
|
||||
{
|
||||
return text.Length <= length ? text : text.Substring(0, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,6 @@ namespace Umbraco.Core.Strings
|
||||
/// <remarks>Not necessarily optimized to work on large bodies of text.</remarks>
|
||||
public interface IShortStringHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Freezes the helper so it can prevents its configuration from being modified.
|
||||
/// </summary>
|
||||
/// <remarks>Will be called by <c>ShortStringHelperResolver</c> when resolution freezes.</remarks>
|
||||
void Freeze();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the JavaScript code defining client-side short string services.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using LightInject;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Strings
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves the IShortStringHelper object
|
||||
/// </summary>
|
||||
public sealed class ShortStringHelperResolver : ContainerSingleObjectResolver<ShortStringHelperResolver, IShortStringHelper>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the resolver to use IoC
|
||||
/// </summary>
|
||||
/// <param name="container"></param>
|
||||
internal ShortStringHelperResolver(IServiceContainer container)
|
||||
: base(container)
|
||||
{
|
||||
Resolution.Frozen += (sender, args) => Value.Freeze();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the resolver to use IoC
|
||||
/// </summary>
|
||||
/// <param name="container"></param>
|
||||
/// <param name="implementationType"></param>
|
||||
internal ShortStringHelperResolver(IServiceContainer container, Func<IServiceFactory, IShortStringHelper> implementationType)
|
||||
: base(container, implementationType)
|
||||
{
|
||||
Resolution.Frozen += (sender, args) => Value.Freeze();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ShortStringHelperResolver"/> class with an instance of a helper.
|
||||
/// </summary>
|
||||
/// <param name="helper">A instance of a helper.</param>
|
||||
/// <remarks>The resolver is created by the <c>CoreBootManager</c> and thus the constructor remains internal.</remarks>
|
||||
internal ShortStringHelperResolver(IShortStringHelper helper)
|
||||
: base(helper)
|
||||
{
|
||||
Resolution.Frozen += (sender, args) => Value.Freeze();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the helper.
|
||||
/// </summary>
|
||||
/// <param name="helper">The helper.</param>
|
||||
/// <remarks>For developers, at application startup.</remarks>
|
||||
public void SetHelper(IShortStringHelper helper)
|
||||
{
|
||||
Value = helper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the helper.
|
||||
/// </summary>
|
||||
public IShortStringHelper Helper
|
||||
{
|
||||
get { return Value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1128,6 +1128,7 @@
|
||||
<Compile Include="IBootManager.cs" />
|
||||
<Compile Include="IntExtensions.cs" />
|
||||
<Compile Include="LambdaExpressionCacheKey.cs" />
|
||||
<Compile Include="Strings\DefaultShortStringHelperConfig.cs" />
|
||||
<Compile Include="Strings\UrlSegmentProviderCollection.cs" />
|
||||
<Compile Include="Strings\UrlSegmentProviderCollectionBuilder.cs" />
|
||||
<Compile Include="Xml\XPath\RenamedRootNavigator.cs" />
|
||||
@@ -1250,7 +1251,6 @@
|
||||
<Compile Include="Sync\ConfigServerRegistrar.cs" />
|
||||
<Compile Include="Strings\Utf8ToAsciiConverter.cs" />
|
||||
<Compile Include="Strings\CleanStringType.cs" />
|
||||
<Compile Include="Strings\ShortStringHelperResolver.cs" />
|
||||
<Compile Include="Strings\IShortStringHelper.cs" />
|
||||
<Compile Include="Strings\StringAliasCaseTypeExtensions.cs" />
|
||||
<Compile Include="Strings\DefaultShortStringHelper.cs" />
|
||||
|
||||
@@ -30,8 +30,6 @@ namespace Umbraco.Tests.Cache.DistributedCache
|
||||
|
||||
CacheRefresherCollectionBuilder.Register(container)
|
||||
.Add<TestCacheRefresher>();
|
||||
|
||||
Resolution.Freeze();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using LightInject;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
@@ -20,15 +22,17 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
{
|
||||
//normalize culture
|
||||
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(SettingsForTests.GetDefault()));
|
||||
Resolution.Freeze();
|
||||
|
||||
var container = new ServiceContainer();
|
||||
container.ConfigureUmbracoCore();
|
||||
container.Register<IShortStringHelper>(_
|
||||
=> new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public virtual void TestTearDown()
|
||||
{
|
||||
ResolverCollection.ResetAll();
|
||||
Resolution.Reset();
|
||||
Current.Reset();
|
||||
}
|
||||
|
||||
[TestCase("{prop1: 'val1', prop2: 'val2'}", true)]
|
||||
|
||||
@@ -12,10 +12,10 @@ using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.WebApi;
|
||||
using umbraco.BusinessLogic;
|
||||
using Umbraco.Core.Plugins;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
using Current = Umbraco.Web.Current;
|
||||
|
||||
namespace Umbraco.Tests.Routing
|
||||
{
|
||||
@@ -47,7 +47,7 @@ namespace Umbraco.Tests.Routing
|
||||
var umbracoApiControllerTypes = new UmbracoApiControllerTypeCollection(PluginManager.Current.ResolveUmbracoApiControllers());
|
||||
Container.RegisterInstance(umbracoApiControllerTypes);
|
||||
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(SettingsForTests.GetDefault()));
|
||||
Container.RegisterSingleton<IShortStringHelper>(_ => new DefaultShortStringHelper(SettingsForTests.GetDefault()));
|
||||
|
||||
base.FreezeResolution();
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using LightInject;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
@@ -32,57 +34,57 @@ namespace Umbraco.Tests.Strings
|
||||
// NOTE pre-filters runs _before_ Recode takes place
|
||||
// so there still may be utf8 chars even though you want ascii
|
||||
|
||||
_helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.FileName, new DefaultShortStringHelper.Config
|
||||
_helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.FileName, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
//PreFilter = ClearFileChars, // done in IsTerm
|
||||
IsTerm = (c, leading) => (char.IsLetterOrDigit(c) || c == '_') && DefaultShortStringHelper.IsValidFileNameChar(c),
|
||||
StringType = CleanStringType.LowerCase | CleanStringType.Ascii,
|
||||
Separator = '-'
|
||||
})
|
||||
.WithConfig(CleanStringType.UrlSegment, new DefaultShortStringHelper.Config
|
||||
.WithConfig(CleanStringType.UrlSegment, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
PreFilter = StripQuotes,
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_',
|
||||
StringType = CleanStringType.LowerCase | CleanStringType.Ascii,
|
||||
Separator = '-'
|
||||
})
|
||||
.WithConfig(new CultureInfo("fr-FR"), CleanStringType.UrlSegment, new DefaultShortStringHelper.Config
|
||||
.WithConfig(new CultureInfo("fr-FR"), CleanStringType.UrlSegment, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
PreFilter = FilterFrenchElisions,
|
||||
IsTerm = (c, leading) => leading ? char.IsLetter(c) : (char.IsLetterOrDigit(c) || c == '_'),
|
||||
StringType = CleanStringType.LowerCase | CleanStringType.Ascii,
|
||||
Separator = '-'
|
||||
})
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
PreFilter = StripQuotes,
|
||||
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c),
|
||||
StringType = CleanStringType.UmbracoCase | CleanStringType.Ascii
|
||||
})
|
||||
.WithConfig(new CultureInfo("fr-FR"), CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
.WithConfig(new CultureInfo("fr-FR"), CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
PreFilter = WhiteQuotes,
|
||||
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c),
|
||||
StringType = CleanStringType.UmbracoCase | CleanStringType.Ascii
|
||||
})
|
||||
.WithConfig(CleanStringType.ConvertCase, new DefaultShortStringHelper.Config
|
||||
.WithConfig(CleanStringType.ConvertCase, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
PreFilter = null,
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = CleanStringType.Ascii,
|
||||
BreakTermsOnUpper = true
|
||||
});
|
||||
}));
|
||||
|
||||
ShortStringHelperResolver.Reset();
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(_helper);
|
||||
Resolution.Freeze();
|
||||
var container = new ServiceContainer();
|
||||
container.ConfigureUmbracoCore();
|
||||
container.Register<IShortStringHelper>(_ => _helper);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
ShortStringHelperResolver.Reset();
|
||||
Current.Reset();
|
||||
}
|
||||
|
||||
static readonly Regex FrenchElisionsRegex = new Regex("\\b(c|d|j|l|m|n|qu|s|t)('|\u8217)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
@@ -114,17 +116,17 @@ namespace Umbraco.Tests.Strings
|
||||
|
||||
const string input = "ÆØÅ and æøå and 中文测试 and אודות האתר and größer БбДдЖж page";
|
||||
|
||||
var helper = new DefaultShortStringHelper(settings).WithDefaultConfig(); // unicode
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(settings)); // unicode
|
||||
var output = helper.CleanStringForUrlSegment(input);
|
||||
Assert.AreEqual("æøå-and-æøå-and-中文测试-and-אודות-האתר-and-größer-ббдджж-page", output);
|
||||
|
||||
helper = new DefaultShortStringHelper(settings)
|
||||
.WithConfig(CleanStringType.UrlSegment, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(settings)
|
||||
.WithConfig(CleanStringType.UrlSegment, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_',
|
||||
StringType = CleanStringType.LowerCase | CleanStringType.Ascii, // ascii
|
||||
Separator = '-'
|
||||
});
|
||||
}));
|
||||
output = helper.CleanStringForUrlSegment(input);
|
||||
Assert.AreEqual("aeoa-and-aeoa-and-and-and-grosser-bbddzhzh-page", output);
|
||||
}
|
||||
@@ -132,103 +134,103 @@ namespace Umbraco.Tests.Strings
|
||||
[Test]
|
||||
public void CleanStringUnderscoreInTerm()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
// underscore is accepted within terms
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_',
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo_bar*nil", helper.CleanString("foo_bar nil", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
// underscore is not accepted within terms
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c),
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*bar*nil", helper.CleanString("foo_bar nil", CleanStringType.Alias));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanStringLeadingChars()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
// letters and digits are valid leading chars
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c),
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("0123foo*bar*543*nil*321", helper.CleanString("0123foo_bar 543 nil 321", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
// only letters are valid leading chars
|
||||
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c),
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*bar*543*nil*321", helper.CleanString("0123foo_bar 543 nil 321", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*bar*543*nil*321", helper.CleanString("0123 foo_bar 543 nil 321", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault()).WithDefaultConfig();
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault()));
|
||||
Assert.AreEqual("child2", helper.CleanStringForSafeAlias("1child2"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanStringTermOnUpper()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
// uppercase letter means new term
|
||||
BreakTermsOnUpper = true,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*Bar", helper.CleanString("fooBar", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
// uppercase letter is part of term
|
||||
BreakTermsOnUpper = false,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("fooBar", helper.CleanString("fooBar", CleanStringType.Alias));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanStringAcronymOnNonUpper()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
// non-uppercase letter means cut acronym
|
||||
CutAcronymOnNonUpper = true,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*BAR*Rnil", helper.CleanString("foo BARRnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BA*Rnil", helper.CleanString("foo BARnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BAnil", helper.CleanString("foo BAnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*Bnil", helper.CleanString("foo Bnil", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
// non-uppercase letter means word
|
||||
CutAcronymOnNonUpper = false,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*BARRnil", helper.CleanString("foo BARRnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BARnil", helper.CleanString("foo BARnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BAnil", helper.CleanString("foo BAnil", CleanStringType.Alias));
|
||||
@@ -238,27 +240,27 @@ namespace Umbraco.Tests.Strings
|
||||
[Test]
|
||||
public void CleanStringGreedyAcronyms()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
CutAcronymOnNonUpper = true,
|
||||
GreedyAcronyms = true,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*BARR*nil", helper.CleanString("foo BARRnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BAR*nil", helper.CleanString("foo BARnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BA*nil", helper.CleanString("foo BAnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*Bnil", helper.CleanString("foo Bnil", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
CutAcronymOnNonUpper = true,
|
||||
GreedyAcronyms = false,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*BAR*Rnil", helper.CleanString("foo BARRnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BA*Rnil", helper.CleanString("foo BARnil", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*BAnil", helper.CleanString("foo BAnil", CleanStringType.Alias));
|
||||
@@ -268,12 +270,12 @@ namespace Umbraco.Tests.Strings
|
||||
[Test]
|
||||
public void CleanStringWhiteSpace()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo", helper.CleanString(" foo ", CleanStringType.Alias));
|
||||
Assert.AreEqual("foo*bar", helper.CleanString(" foo bar ", CleanStringType.Alias));
|
||||
}
|
||||
@@ -281,47 +283,47 @@ namespace Umbraco.Tests.Strings
|
||||
[Test]
|
||||
public void CleanStringSeparator()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo*bar", helper.CleanString("foo bar", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = ' '
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo bar", helper.CleanString("foo bar", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foobar", helper.CleanString("foo bar", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '文'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("foo文bar", helper.CleanString("foo bar", CleanStringType.Alias));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanStringSymbols()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("house*2", helper.CleanString("house (2)", CleanStringType.Alias));
|
||||
|
||||
// FIXME but for a filename we want to keep them!
|
||||
@@ -370,21 +372,21 @@ namespace Umbraco.Tests.Strings
|
||||
[Test]
|
||||
public void CleanStringEncoding()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("中文测试", helper.CleanString("中文测试", CleanStringType.Alias));
|
||||
Assert.AreEqual("léger*中文测试*ZÔRG", helper.CleanString("léger 中文测试 ZÔRG", CleanStringType.Alias));
|
||||
|
||||
helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Ascii | CleanStringType.Unchanged,
|
||||
Separator = '*'
|
||||
});
|
||||
}));
|
||||
Assert.AreEqual("", helper.CleanString("中文测试", CleanStringType.Alias));
|
||||
Assert.AreEqual("leger*ZORG", helper.CleanString("léger 中文测试 ZÔRG", CleanStringType.Alias));
|
||||
}
|
||||
@@ -397,7 +399,7 @@ namespace Umbraco.Tests.Strings
|
||||
contentMock.Setup(x => x.CharCollection).Returns(Enumerable.Empty<IChar>());
|
||||
contentMock.Setup(x => x.ConvertUrlsToAscii).Returns(false);
|
||||
|
||||
var helper = new DefaultShortStringHelper(settings).WithDefaultConfig();
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(settings));
|
||||
|
||||
const string input = "0123 中文测试 中文测试 léger ZÔRG (2) a?? *x";
|
||||
|
||||
@@ -418,12 +420,12 @@ namespace Umbraco.Tests.Strings
|
||||
[Test]
|
||||
public void CleanStringCasing()
|
||||
{
|
||||
var helper = new DefaultShortStringHelper(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelper.Config
|
||||
var helper = new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(SettingsForTests.GetDefault())
|
||||
.WithConfig(CleanStringType.Alias, new DefaultShortStringHelperConfig.Config
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged,
|
||||
Separator = ' '
|
||||
});
|
||||
}));
|
||||
|
||||
// BBB is an acronym
|
||||
// E is a word (too short to be an acronym)
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
namespace Umbraco.Tests.Strings
|
||||
{
|
||||
[TestFixture]
|
||||
public class ShortStringHelperResolverTest
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
ShortStringHelperResolver.Reset();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
ShortStringHelperResolver.Reset();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FreezesHelperWhenResolutionFreezes()
|
||||
{
|
||||
var helper = new MockShortStringHelper();
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(helper);
|
||||
Assert.IsFalse(helper.IsFrozen);
|
||||
Resolution.Freeze();
|
||||
Assert.AreSame(helper, ShortStringHelperResolver.Current.Helper);
|
||||
Assert.IsTrue(helper.IsFrozen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using LightInject;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
@@ -14,15 +16,22 @@ namespace Umbraco.Tests.Strings
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
ShortStringHelperResolver.Reset();
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(new MockShortStringHelper());
|
||||
Resolution.Freeze();
|
||||
var container = new ServiceContainer();
|
||||
container.ConfigureUmbracoCore();
|
||||
container.RegisterSingleton<IShortStringHelper>(_ => new MockShortStringHelper());
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
ShortStringHelperResolver.Reset();
|
||||
Current.Reset();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CurrentHelper()
|
||||
{
|
||||
var helper = Current.ShortStringHelper;
|
||||
Assert.IsInstanceOf<MockShortStringHelper>(helper);
|
||||
}
|
||||
|
||||
[TestCase("hello", "world", false)]
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using LightInject;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
@@ -14,14 +16,15 @@ namespace Umbraco.Tests
|
||||
public void SetUp()
|
||||
{
|
||||
var settings = SettingsForTests.GetDefault();
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(settings).WithDefaultConfig());
|
||||
Resolution.Freeze();
|
||||
var container = new ServiceContainer();
|
||||
container.ConfigureUmbracoCore();
|
||||
container.RegisterSingleton<IShortStringHelper>(_ => new DefaultShortStringHelper(settings));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
ShortStringHelperResolver.Reset();
|
||||
Current.Reset();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -406,7 +406,6 @@
|
||||
<Compile Include="CoreXml\NavigableNavigatorTests.cs" />
|
||||
<Compile Include="Cache\PublishedCache\PublishedMediaCacheTests.cs" />
|
||||
<Compile Include="Strings\CmsHelperCasingTests.cs" />
|
||||
<Compile Include="Strings\ShortStringHelperResolverTest.cs" />
|
||||
<Compile Include="Strings\DefaultShortStringHelperTests.cs" />
|
||||
<Compile Include="Strings\MockShortStringHelper.cs" />
|
||||
<Compile Include="Macros\MacroTests.cs" />
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Moq;
|
||||
using System.IO;
|
||||
using LightInject;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
@@ -29,12 +31,9 @@ namespace Umbraco.Tests.UmbracoExamine
|
||||
/// </summary>
|
||||
protected override void FreezeResolution()
|
||||
{
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(new DefaultShortStringHelper(SettingsForTests.GetDefault()));
|
||||
Container.RegisterSingleton<IShortStringHelper>(_ => new DefaultShortStringHelper(SettingsForTests.GetDefault()));
|
||||
|
||||
base.FreezeResolution();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -232,6 +232,9 @@ namespace Umbraco.Web
|
||||
public static ICultureDictionaryFactory CultureDictionaryFactory
|
||||
=> Container.GetInstance<ICultureDictionaryFactory>();
|
||||
|
||||
public static IShortStringHelper ShortStringHelper
|
||||
=> Container.GetInstance<IShortStringHelper>();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Web.WebServices
|
||||
public JavaScriptResult ServicesJavaScript()
|
||||
{
|
||||
var controllerPath = Url.GetCoreStringsControllerPath();
|
||||
var js = ShortStringHelperResolver.Current.Helper.GetShortStringServicesJavaScript(controllerPath);
|
||||
var js = Current.ShortStringHelper.GetShortStringServicesJavaScript(controllerPath);
|
||||
return JavaScript(js);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user