diff --git a/.gitignore b/.gitignore index 9f22544f35..6c180fa693 100644 --- a/.gitignore +++ b/.gitignore @@ -121,6 +121,9 @@ src/Umbraco.Web.UI.Client/bower_components/* /src/Umbraco.Web.UI/Umbraco/preview /src/Umbraco.Web.UI/Umbraco/preview.old +# ignore rule for clearing out Belle (avoid rebuilding all the time) +preserve.belle + #Ignore Rule for output of generated documentation files from Grunt docserve src/Umbraco.Web.UI.Client/docs/api src/*.boltdata/ diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index d06b5e7136..5e836f602b 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -43,7 +43,7 @@ - + diff --git a/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs b/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs index 6baa2cf0ed..9da202b5aa 100644 --- a/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs +++ b/src/Umbraco.Core/Cache/DictionaryCacheProviderBase.cs @@ -24,8 +24,13 @@ namespace Umbraco.Core.Cache protected abstract object GetEntry(string key); // read-write lock the underlying cache - protected abstract IDisposable ReadLock { get; } - protected abstract IDisposable WriteLock { get; } + //protected abstract IDisposable ReadLock { get; } + //protected abstract IDisposable WriteLock { get; } + + protected abstract void EnterReadLock(); + protected abstract void ExitReadLock(); + protected abstract void EnterWriteLock(); + protected abstract void ExitWriteLock(); protected string GetCacheKey(string key) { @@ -88,21 +93,31 @@ namespace Umbraco.Core.Cache public virtual void ClearAllCache() { - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheItem(string key) { var cacheKey = GetCacheKey(key); - using (WriteLock) + try { + EnterWriteLock(); RemoveEntry(cacheKey); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(string typeName) @@ -110,15 +125,16 @@ namespace Umbraco.Core.Cache var type = TypeFinder.GetTypeByName(typeName); if (type == null) return; var isInterface = type.IsInterface; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => { // entry.Value is Lazy and not null, its value may be null // remove null values as well, does not hurt // get non-created as NonCreatedValue & exceptions as null - var value = GetSafeLazyValue((Lazy)x.Value, true); + var value = GetSafeLazyValue((Lazy) x.Value, true); // if T is an interface remove anything that implements that interface // otherwise remove exact types (not inherited types) @@ -127,14 +143,19 @@ namespace Umbraco.Core.Cache .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes() { var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => { @@ -142,7 +163,7 @@ namespace Umbraco.Core.Cache // remove null values as well, does not hurt // compare on exact type, don't use "is" // get non-created as NonCreatedValue & exceptions as null - var value = GetSafeLazyValue((Lazy)x.Value, true); + var value = GetSafeLazyValue((Lazy) x.Value, true); // if T is an interface remove anything that implements that interface // otherwise remove exact types (not inherited types) @@ -151,6 +172,10 @@ namespace Umbraco.Core.Cache .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(Func predicate) @@ -158,8 +183,9 @@ namespace Umbraco.Core.Cache var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; var plen = CacheItemPrefix.Length + 1; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => { @@ -167,7 +193,7 @@ namespace Umbraco.Core.Cache // remove null values as well, does not hurt // compare on exact type, don't use "is" // get non-created as NonCreatedValue & exceptions as null - var value = GetSafeLazyValue((Lazy)x.Value, true); + var value = GetSafeLazyValue((Lazy) x.Value, true); if (value == null) return true; // if T is an interface remove anything that implements that interface @@ -178,30 +204,44 @@ namespace Umbraco.Core.Cache })) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheByKeySearch(string keyStartsWith) { var plen = CacheItemPrefix.Length + 1; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith)) .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } public virtual void ClearCacheByKeyExpression(string regexString) { var plen = CacheItemPrefix.Length + 1; - using (WriteLock) + try { + EnterWriteLock(); foreach (var entry in GetDictionaryEntries() .Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString)) .ToArray()) RemoveEntry((string) entry.Key); } + finally + { + ExitWriteLock(); + } } #endregion @@ -212,12 +252,18 @@ namespace Umbraco.Core.Cache { var plen = CacheItemPrefix.Length + 1; IEnumerable entries; - using (ReadLock) + try { + EnterReadLock(); entries = GetDictionaryEntries() .Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith)) .ToArray(); // evaluate while locked } + finally + { + ExitReadLock(); + } + return entries .Select(x => GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null); // backward compat, don't store null values in the cache @@ -228,12 +274,17 @@ namespace Umbraco.Core.Cache const string prefix = CacheItemPrefix + "-"; var plen = prefix.Length; IEnumerable entries; - using (ReadLock) + try { + EnterReadLock(); entries = GetDictionaryEntries() .Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString)) .ToArray(); // evaluate while locked } + finally + { + ExitReadLock(); + } return entries .Select(x => GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null); // backward compat, don't store null values in the cache @@ -243,10 +294,15 @@ namespace Umbraco.Core.Cache { cacheKey = GetCacheKey(cacheKey); Lazy result; - using (ReadLock) + try { + EnterReadLock(); result = GetEntry(cacheKey) as Lazy; // null if key not found } + finally + { + ExitReadLock(); + } return result == null ? null : GetSafeLazyValue(result); // return exceptions as null } diff --git a/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs b/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs index 6f97651042..5554655d83 100644 --- a/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs +++ b/src/Umbraco.Core/Cache/HttpRequestCacheProvider.cs @@ -79,24 +79,26 @@ namespace Umbraco.Core.Cache #region Lock - protected override IDisposable ReadLock + private bool _entered; + + protected override void EnterReadLock() => EnterWriteLock(); + + protected override void EnterWriteLock() { - // there's no difference between ReadLock and WriteLock here - get { return WriteLock; } + if (HasContextItems) + { + System.Threading.Monitor.Enter(ContextItems.SyncRoot, ref _entered); + } } - protected override IDisposable WriteLock - { - // NOTE - // could think about just overriding base.Locker to return a different - // object but then we'd create a ReaderWriterLockSlim per request, - // which is less efficient than just using a basic monitor lock. + protected override void ExitReadLock() => ExitWriteLock(); - get + protected override void ExitWriteLock() + { + if (_entered) { - return HasContextItems - ? (IDisposable) new MonitorLock(ContextItems.SyncRoot) - : new NoopLocker(); + _entered = false; + System.Threading.Monitor.Exit(ContextItems.SyncRoot); } } @@ -113,8 +115,9 @@ namespace Umbraco.Core.Cache Lazy result; - using (WriteLock) + try { + EnterWriteLock(); result = ContextItems[cacheKey] as Lazy; // null if key not found // cannot create value within the lock, so if result.IsValueCreated is false, just @@ -127,6 +130,10 @@ namespace Umbraco.Core.Cache ContextItems[cacheKey] = result; } } + finally + { + ExitWriteLock(); + } // using GetSafeLazy and GetSafeLazyValue ensures that we don't cache // exceptions (but try again and again) and silently eat them - however at diff --git a/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs b/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs index ad46201c0c..068bf3605e 100644 --- a/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Cache/HttpRuntimeCacheProvider.cs @@ -50,14 +50,26 @@ namespace Umbraco.Core.Cache #region Lock - protected override IDisposable ReadLock + protected override void EnterReadLock() { - get { return new ReadLock(_locker); } + _locker.EnterReadLock(); } - protected override IDisposable WriteLock + protected override void EnterWriteLock() { - get { return new WriteLock(_locker); } + _locker.EnterWriteLock();; + } + + protected override void ExitReadLock() + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } + + protected override void ExitWriteLock() + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); } #endregion @@ -118,10 +130,16 @@ namespace Umbraco.Core.Cache // reads. We first try with a normal ReadLock for maximum concurrency and take the penalty of // having to re-lock in case there's no value. Would need to benchmark to figure out whether // it's worth it, though... - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); result = _cache.Get(cacheKey) as Lazy; // null if key not found } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } var value = result == null ? null : GetSafeLazyValue(result); if (value != null) return value; @@ -195,11 +213,17 @@ namespace Umbraco.Core.Cache var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value)); var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration); - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); //NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update! _cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public void InsertCacheItem(string cacheKey, Func getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null) diff --git a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs index 70e37addb8..b3a643dbfb 100644 --- a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs @@ -37,20 +37,32 @@ namespace Umbraco.Core.Cache public virtual void ClearAllCache() { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); MemoryCache.DisposeIfDisposable(); MemoryCache = new MemoryCache("in-memory"); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheItem(string key) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); if (MemoryCache[key] == null) return; MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(string typeName) @@ -58,8 +70,9 @@ namespace Umbraco.Core.Cache var type = TypeFinder.GetTypeByName(typeName); if (type == null) return; var isInterface = type.IsInterface; - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); foreach (var key in MemoryCache .Where(x => { @@ -76,12 +89,18 @@ namespace Umbraco.Core.Cache .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes() { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); var typeOfT = typeof (T); var isInterface = typeOfT.IsInterface; foreach (var key in MemoryCache @@ -101,12 +120,18 @@ namespace Umbraco.Core.Cache .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheObjectTypes(Func predicate) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); var typeOfT = typeof(T); var isInterface = typeOfT.IsInterface; foreach (var key in MemoryCache @@ -127,30 +152,47 @@ namespace Umbraco.Core.Cache .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheByKeySearch(string keyStartsWith) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); foreach (var key in MemoryCache .Where(x => x.Key.InvariantStartsWith(keyStartsWith)) .Select(x => x.Key) .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } public virtual void ClearCacheByKeyExpression(string regexString) { - using (new WriteLock(_locker)) + try { + _locker.EnterWriteLock(); foreach (var key in MemoryCache .Where(x => Regex.IsMatch(x.Key, regexString)) .Select(x => x.Key) .ToArray()) // ToArray required to remove MemoryCache.Remove(key); } + finally + { + if (_locker.IsWriteLockHeld) + _locker.ExitWriteLock(); + } } #endregion @@ -160,12 +202,18 @@ namespace Umbraco.Core.Cache public IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) { KeyValuePair[] entries; - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); entries = MemoryCache .Where(x => x.Key.InvariantStartsWith(keyStartsWith)) .ToArray(); // evaluate while locked } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } return entries .Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null) // backward compat, don't store null values in the cache @@ -175,12 +223,18 @@ namespace Umbraco.Core.Cache public IEnumerable GetCacheItemsByKeyExpression(string regexString) { KeyValuePair[] entries; - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); entries = MemoryCache .Where(x => Regex.IsMatch(x.Key, regexString)) .ToArray(); // evaluate while locked } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } return entries .Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy)x.Value)) // return exceptions as null .Where(x => x != null) // backward compat, don't store null values in the cache @@ -190,10 +244,16 @@ namespace Umbraco.Core.Cache public object GetCacheItem(string cacheKey) { Lazy result; - using (new ReadLock(_locker)) + try { + _locker.EnterReadLock(); result = MemoryCache.Get(cacheKey) as Lazy; // null if key not found } + finally + { + if (_locker.IsReadLockHeld) + _locker.ExitReadLock(); + } return result == null ? null : DictionaryCacheProviderBase.GetSafeLazyValue(result); // return exceptions as null } diff --git a/src/Umbraco.Core/Collections/ConcurrentHashSet.cs b/src/Umbraco.Core/Collections/ConcurrentHashSet.cs index 39cb701e69..4cad6e9f15 100644 --- a/src/Umbraco.Core/Collections/ConcurrentHashSet.cs +++ b/src/Umbraco.Core/Collections/ConcurrentHashSet.cs @@ -50,10 +50,16 @@ namespace Umbraco.Core.Collections /// The object to remove from the .The is read-only. public bool Remove(T item) { - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); return _innerSet.Remove(item); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } @@ -86,10 +92,16 @@ namespace Umbraco.Core.Collections /// The object to add to the .The is read-only. public void Add(T item) { - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); _innerSet.Add(item); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } /// @@ -101,13 +113,20 @@ namespace Umbraco.Core.Collections { var clone = GetThreadSafeClone(); if (clone.Contains(item)) return false; - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); + //double check if (_innerSet.Contains(item)) return false; _innerSet.Add(item); return true; } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } /// @@ -116,10 +135,16 @@ namespace Umbraco.Core.Collections /// The is read-only. public void Clear() { - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); _innerSet.Clear(); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } } /// @@ -147,10 +172,16 @@ namespace Umbraco.Core.Collections private HashSet GetThreadSafeClone() { HashSet clone = null; - using (new WriteLock(_instanceLocker)) + try { + _instanceLocker.EnterWriteLock(); clone = new HashSet(_innerSet, _innerSet.Comparer); } + finally + { + if (_instanceLocker.IsWriteLockHeld) + _instanceLocker.ExitWriteLock(); + } return clone; } diff --git a/src/Umbraco.Core/Composing/LightInjectExtensions.cs b/src/Umbraco.Core/Composing/LightInjectExtensions.cs index c7b51404fe..68ba48c803 100644 --- a/src/Umbraco.Core/Composing/LightInjectExtensions.cs +++ b/src/Umbraco.Core/Composing/LightInjectExtensions.cs @@ -311,15 +311,15 @@ namespace Umbraco.Core.Composing // we HAVE to let LightInject throw - and catch at THE OUTERMOST if InvalidOperationException in LightInject.Anything! return factory.GetInstance(tService, serviceName, args); - try - { - return factory.GetInstance(tService, serviceName, args); - } - catch (Exception e) - { - LightInjectException.TryThrow(e, implementingType); - throw; - } + //try + //{ + // return factory.GetInstance(tService, serviceName, args); + //} + //catch (Exception e) + //{ + // LightInjectException.TryThrow(e, implementingType); + // throw; + //} } /// diff --git a/src/Umbraco.Core/EnumerableExtensions.cs b/src/Umbraco.Core/EnumerableExtensions.cs index d5d4a66122..6ae96c9d53 100644 --- a/src/Umbraco.Core/EnumerableExtensions.cs +++ b/src/Umbraco.Core/EnumerableExtensions.cs @@ -92,21 +92,6 @@ namespace Umbraco.Core } } - [EditorBrowsable(EditorBrowsableState.Never)] - [Obsolete("Use a normal foreach loop instead, this adds more allocations than necessary")] - public static IEnumerable ForEach(this IEnumerable items, Action action) - { - if (items != null) - { - foreach (TItem item in items) - { - action(item); - } - } - - return items; - } - /// The flatten list. /// The items. /// The select child. diff --git a/src/Umbraco.Core/IO/FileSystems.cs b/src/Umbraco.Core/IO/FileSystems.cs index 33989122b8..5d7088b0e1 100644 --- a/src/Umbraco.Core/IO/FileSystems.cs +++ b/src/Umbraco.Core/IO/FileSystems.cs @@ -28,7 +28,6 @@ namespace Umbraco.Core.IO private ShadowWrapper _scriptsFileSystem; private ShadowWrapper _masterPagesFileSystem; private ShadowWrapper _mvcViewsFileSystem; - private ShadowWrapper _javaScriptLibraryFileSystem; // well-known file systems lazy initialization private object _wkfsLock = new object(); diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs index 8b85d6992e..b7d869ee62 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/RefactorXmlColumns.cs @@ -67,13 +67,6 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0 .Do(); } - private bool ColumnExists(string tableName, string columnName) - { - // that's ok even on MySql - var columns = SqlSyntax.GetColumnsInSchema(Context.Database).Distinct().ToArray(); - return columns.Any(x => x.TableName.InvariantEquals(tableName) && x.ColumnName.InvariantEquals(columnName)); - } - private void RemoveDuplicates() { const string sql = @"delete from cmsPreviewXml where versionId in ( diff --git a/src/Umbraco.Core/Models/MediaType.cs b/src/Umbraco.Core/Models/MediaType.cs index bc8b7c4c89..9612fce728 100644 --- a/src/Umbraco.Core/Models/MediaType.cs +++ b/src/Umbraco.Core/Models/MediaType.cs @@ -48,7 +48,7 @@ namespace Umbraco.Core.Models /// Creates a deep clone of the current entity with its identity/alias and it's property identities reset /// /// - public IMediaType DeepCloneWithResetIdentities(string alias) + public new IMediaType DeepCloneWithResetIdentities(string alias) { var clone = (MediaType)DeepClone(); clone.Alias = alias; diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 709c37daaa..7e53eb764a 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -271,6 +271,10 @@ namespace Umbraco.Core.Models /// public void SetValue(object value, string culture = null, string segment = null) { + if (PropertyType.Variations == ContentVariation.InvariantNeutral) + { + culture = null; + } PropertyType.ValidateVariation(culture, segment, true); (var pvalue, var change) = GetPValue(culture, segment, true); diff --git a/src/Umbraco.Core/Models/PropertyGroupCollection.cs b/src/Umbraco.Core/Models/PropertyGroupCollection.cs index abec6febcb..0083bdb502 100644 --- a/src/Umbraco.Core/Models/PropertyGroupCollection.cs +++ b/src/Umbraco.Core/Models/PropertyGroupCollection.cs @@ -67,8 +67,10 @@ namespace Umbraco.Core.Models internal new void Add(PropertyGroup item) { - using (new WriteLock(_addLocker)) + try { + _addLocker.EnterWriteLock(); + //Note this is done to ensure existig groups can be renamed if (item.HasIdentity && item.Id > 0) { @@ -102,6 +104,11 @@ namespace Umbraco.Core.Models OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); } + finally + { + if (_addLocker.IsWriteLockHeld) + _addLocker.ExitWriteLock(); + } } /// diff --git a/src/Umbraco.Core/Models/PropertyTypeCollection.cs b/src/Umbraco.Core/Models/PropertyTypeCollection.cs index 4788221854..dbe97248f9 100644 --- a/src/Umbraco.Core/Models/PropertyTypeCollection.cs +++ b/src/Umbraco.Core/Models/PropertyTypeCollection.cs @@ -80,8 +80,9 @@ namespace Umbraco.Core.Models item.IsPublishing = IsPublishing; // fixme redo this entirely!!! - using (new WriteLock(_addLocker)) + try { + _addLocker.EnterWriteLock(); var key = GetKeyForItem(item); if (key != null) { @@ -105,6 +106,11 @@ namespace Umbraco.Core.Models OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item)); } + finally + { + if (_addLocker.IsWriteLockHeld) + _addLocker.ExitWriteLock(); + } } /// diff --git a/src/Umbraco.Core/Packaging/DefaultPackageContext.cs b/src/Umbraco.Core/Packaging/DefaultPackageContext.cs deleted file mode 100644 index c08418ec86..0000000000 --- a/src/Umbraco.Core/Packaging/DefaultPackageContext.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using NuGet; -using Umbraco.Core.Configuration; - -namespace Umbraco.Core.Packaging -{ - internal class DefaultPackageContext : IPackageContext - { - public DefaultPackageContext(Func mapPath) - {} - - private readonly string _localPackageRepoFolderPath; - private readonly string _pluginInstallFolderPath; - private readonly Lazy _localPackageManager; - private readonly Lazy _localPackageRepository; - private readonly Lazy _publicPackageManager; - private readonly Lazy _privatePackageManager; - private readonly Lazy _publicPackageRepository; - private readonly Lazy _sprivatePackageRepository; - - /// - /// Gets the local path resolver. - /// - public IPackagePathResolver LocalPathResolver - { - get { return ((PackageManager)LocalPackageManager).PathResolver; } - } - - /// - /// Gets the local package manager. - /// - public IPackageManager LocalPackageManager - { - get { return _localPackageManager.Value; } - } - - /// - /// Gets the public package manager. - /// - public IPackageManager PublicPackageManager - { - get { return _publicPackageManager.Value; } - } - } -} diff --git a/src/Umbraco.Core/Packaging/IPackageContext.cs b/src/Umbraco.Core/Packaging/IPackageContext.cs deleted file mode 100644 index 41cf372ce6..0000000000 --- a/src/Umbraco.Core/Packaging/IPackageContext.cs +++ /dev/null @@ -1,11 +0,0 @@ -using NuGet; - -namespace Umbraco.Core.Packaging -{ - internal interface IPackageContext - { - IPackageManager LocalPackageManager { get; } - IPackageManager PublicPackageManager { get; } - IPackagePathResolver LocalPathResolver { get; } - } -} diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs index 8a0333a965..73dcb44fef 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs @@ -139,7 +139,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement FileSystem.AddFile(filepath, content, true); } - public long GetFileSize(string filepath) + public new long GetFileSize(string filepath) { if (FileSystem.FileExists(filepath) == false) return -1; diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs b/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs index efe05e951d..2b82ec7fac 100644 --- a/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs +++ b/src/Umbraco.Core/Persistence/UmbracoDatabaseFactory.cs @@ -126,8 +126,10 @@ namespace Umbraco.Core.Persistence /// public void Configure(string connectionString, string providerName) { - using (new WriteLock(_lock)) + try { + _lock.EnterWriteLock(); + _logger.Debug("Configuring."); if (Configured) throw new InvalidOperationException("Already configured."); @@ -173,6 +175,11 @@ namespace Umbraco.Core.Persistence _logger.Debug("Configured."); Configured = true; } + finally + { + if (_lock.IsWriteLockHeld) + _lock.ExitWriteLock(); + } } /// diff --git a/src/Umbraco.Core/ReadLock.cs b/src/Umbraco.Core/ReadLock.cs index 61025721fc..6e6ecf14b8 100644 --- a/src/Umbraco.Core/ReadLock.cs +++ b/src/Umbraco.Core/ReadLock.cs @@ -10,9 +10,11 @@ namespace Umbraco.Core /// Provides a convenience methodology for implementing locked access to resources. /// /// - /// Intended as an infrastructure class. + /// Intended as an infrastructure class. + /// This is a very unefficient way to lock as it allocates one object each time we lock, + /// so it's OK to use this class for things that happen once, where it is convenient, but not + /// for performance-critical code! /// - [Obsolete("stop using, allocates")] public class ReadLock : IDisposable { private readonly ReaderWriterLockSlim _rwLock; diff --git a/src/Umbraco.Core/Security/MachineKeyGenerator.cs b/src/Umbraco.Core/Security/MachineKeyGenerator.cs index 283ca1ac3a..a20f04c919 100644 --- a/src/Umbraco.Core/Security/MachineKeyGenerator.cs +++ b/src/Umbraco.Core/Security/MachineKeyGenerator.cs @@ -26,8 +26,6 @@ namespace Umbraco.Core.Security validation=""HMACSHA256"" decryption=""AES"" />"; - var Xxx = 3; - return string.Format(c, GenerateAESDecryptionKey(), GenerateHMACSHA256ValidationKey()); } diff --git a/src/Umbraco.Core/Services/Implement/MemberService.cs b/src/Umbraco.Core/Services/Implement/MemberService.cs index f8245f18c2..ca2b39dee2 100644 --- a/src/Umbraco.Core/Services/Implement/MemberService.cs +++ b/src/Umbraco.Core/Services/Implement/MemberService.cs @@ -186,8 +186,9 @@ namespace Umbraco.Core.Services.Implement /// Email of the to create /// This value should be the encoded/encrypted/hashed value for the password that will be stored in the database /// Alias of the Type + /// /// - IMember IMembershipMemberService.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved = true) + IMember IMembershipMemberService.CreateWithIdentity(string username, string email, string passwordValue, string memberTypeAlias, bool isApproved) { return CreateMemberWithIdentity(username, email, username, passwordValue, memberTypeAlias, isApproved); } diff --git a/src/Umbraco.Core/Services/Implement/UserService.cs b/src/Umbraco.Core/Services/Implement/UserService.cs index 4b27fb5c51..96cac1d814 100644 --- a/src/Umbraco.Core/Services/Implement/UserService.cs +++ b/src/Umbraco.Core/Services/Implement/UserService.cs @@ -198,7 +198,7 @@ namespace Umbraco.Core.Services.Implement { return _userRepository.GetByUsername(username, includeSecurityData: true); } - catch (DbException ex) + catch (DbException) { // fixme - refactor users/upgrade // currently kinda accepting anything on upgrade, but that won't deal with all cases @@ -727,7 +727,7 @@ namespace Umbraco.Core.Services.Implement { return _userRepository.Get(id); } - catch (DbException ex) + catch (DbException) { // fixme - refactor users/upgrade // currently kinda accepting anything on upgrade, but that won't deal with all cases diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index a399c82f0c..4369e8faac 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -164,7 +164,7 @@ namespace Umbraco.Core var obj = JsonConvert.DeserializeObject(input); return obj; } - catch (Exception ex) + catch (Exception) { return input; } @@ -622,7 +622,7 @@ namespace Umbraco.Core byte[] decodedBytes = UrlTokenDecode(input); return decodedBytes != null ? Encoding.UTF8.GetString(decodedBytes) : null; } - catch (FormatException ex) + catch (FormatException) { return null; } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 92854ea74c..e39b6ed9c8 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -47,7 +47,6 @@ - @@ -74,7 +73,7 @@ - + @@ -395,6 +394,7 @@ + @@ -836,9 +836,7 @@ - - @@ -1265,7 +1263,6 @@ - diff --git a/src/Umbraco.Core/WriteLock.cs b/src/Umbraco.Core/WriteLock.cs index b6a957234b..6ddc7e0bb3 100644 --- a/src/Umbraco.Core/WriteLock.cs +++ b/src/Umbraco.Core/WriteLock.cs @@ -10,9 +10,11 @@ namespace Umbraco.Core /// Provides a convenience methodology for implementing locked access to resources. /// /// - /// Intended as an infrastructure class. + /// Intended as an infrastructure class. + /// This is a very unefficient way to lock as it allocates one object each time we lock, + /// so it's OK to use this class for things that happen once, where it is convenient, but not + /// for performance-critical code! /// - [Obsolete("stop using, allocates")] public class WriteLock : IDisposable { private readonly ReaderWriterLockSlim _rwLock; diff --git a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj index 5dfa0d1285..4c33b16002 100644 --- a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj +++ b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj @@ -69,7 +69,6 @@ - @@ -157,24 +156,11 @@ Umbraco.Web - - -REM if not exist "$(TargetDir)x86" md "$(TargetDir)x86" -REM xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" -REM if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" -REM xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" - - - REM xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\amd64\*.* "$(TargetDir)amd64\" /Y /F /E /I /C /D -REM xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" /Y /F /E /I /C /D - REM if not exist "$(TargetDir)x86" md "$(TargetDir)x86" -REM xcopy /s /y "$(NugetPackages)\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" -REM if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" -REM xcopy /s /y "$(NugetPackages)\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" $(NuGetPackageFolders.Split(';')[0]) + diff --git a/src/Umbraco.Tests/Composing/TypeFinderTests.cs b/src/Umbraco.Tests/Composing/TypeFinderTests.cs index 9a0d473db0..b30312647e 100644 --- a/src/Umbraco.Tests/Composing/TypeFinderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeFinderTests.cs @@ -310,7 +310,7 @@ namespace Umbraco.Tests.Composing using (new WriteLock(LocalFilteredAssemblyCacheLocker)) { var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter); - assemblies.ForEach(LocalFilteredAssemblyCache.Add); + foreach (var assembly in assemblies) LocalFilteredAssemblyCache.Add(assembly); } return LocalFilteredAssemblyCache; } diff --git a/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs b/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs index e7b7d4a9bc..4b52289e2a 100644 --- a/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs +++ b/src/Umbraco.Tests/Models/Collections/SimpleOrder.cs @@ -35,7 +35,7 @@ namespace Umbraco.Tests.Models.Collections internal void Reset(IEnumerable properties) { Clear(); - properties.ForEach(Add); + foreach (var property in properties) Add(property); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } diff --git a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs index e1c856297d..38990405c4 100644 --- a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs +++ b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs @@ -441,7 +441,7 @@ namespace Umbraco.Tests.Scheduling tManager.TaskCompleted += (sender, task) => tasks[task.Task].Set(); //execute first batch - tasks.ForEach(t => tManager.Add(t.Key)); + foreach (var t in tasks) tManager.Add(t.Key); //wait for all ITasks to complete WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); @@ -455,7 +455,7 @@ namespace Umbraco.Tests.Scheduling Thread.Sleep(2000); tasks = getTasks(); - tasks.ForEach(t => tManager.Add(t.Key)); + foreach (var t in tasks) tManager.Add(t.Key); //wait for all ITasks to complete WaitHandle.WaitAll(tasks.Values.Select(x => (WaitHandle)x).ToArray()); diff --git a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs index d5c0eac8c9..b607290c5e 100644 --- a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs @@ -108,9 +108,9 @@ namespace Umbraco.Tests.Services ServiceContext.MemberTypeService.Save(contentType1); ServiceContext.MemberTypeService.Save(contentType2); var contentItems1 = MockedMember.CreateSimpleMember(contentType1, 10).ToArray(); - contentItems1.ForEach(x => ServiceContext.MemberService.Save(x)); + foreach (var x in contentItems1) ServiceContext.MemberService.Save(x); var contentItems2 = MockedMember.CreateSimpleMember(contentType2, 5).ToArray(); - contentItems2.ForEach(x => ServiceContext.MemberService.Save(x)); + foreach (var x in contentItems2) ServiceContext.MemberService.Save(x); //only update the contentType1 alias which will force an xml rebuild for all content of that type contentType1.Alias = "newAlias"; ServiceContext.MemberTypeService.Save(contentType1); @@ -141,7 +141,7 @@ namespace Umbraco.Tests.Services var contentType1 = MockedContentTypes.CreateSimpleMemberType("test1", "Test1"); ServiceContext.MemberTypeService.Save(contentType1); var contentItems1 = MockedMember.CreateSimpleMember(contentType1, 10).ToArray(); - contentItems1.ForEach(x => ServiceContext.MemberService.Save(x)); + foreach (var x in contentItems1) ServiceContext.MemberService.Save(x); var alias = contentType1.PropertyTypes.First(x => standardProps.ContainsKey(x.Alias) == false).Alias; var elementToMatch = "<" + alias + ">"; diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 25ac6314e2..5380a747f5 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -84,8 +84,9 @@ namespace Umbraco.Tests.TestHelpers { var directoryInfo = new DirectoryInfo(IOHelper.MapPath(directory)); var preserve = preserves.ContainsKey(directory) ? preserves[directory] : null; - if (directoryInfo.Exists) - directoryInfo.GetFiles().Where(x => preserve == null || preserve.Contains(x.Name) == false).ForEach(x => x.Delete()); + if (directoryInfo.Exists) + foreach (var x in directoryInfo.GetFiles().Where(x => preserve == null || preserve.Contains(x.Name) == false)) + x.Delete(); } } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index c7db9addf8..a8f4ff0226 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -4,7 +4,7 @@ function ContentEditController($rootScope, $scope, $routeParams, $q, $timeout, $window, $location, appState, contentResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, treeService, fileManager, formHelper, umbRequestHelper, - keyboardService, umbModelMapper, editorState, $http, eventsService, relationResource, overlayService) { + keyboardService, umbModelMapper, editorState, $http, eventsService, relationResource, overlayService, localizationService) { var evts = []; @@ -320,7 +320,7 @@ //before we launch the dialog we want to execute all client side validations first if (formHelper.submitForm({ scope: $scope, action: "publish" })) { var dialog = { - title: "Ready to Publish?", //TODO: localize + title: localizationService.localize("content_readyToPublish"), view: "publish", variants: $scope.content.variants, //set a model property for the dialog skipFormValidation: true, //when submitting the overlay form, skip any client side validation @@ -416,7 +416,7 @@ var target = null; var error = { headline: "Cannot automatically restore this item", content: "Use the Move menu item to move it manually" }; - if (data.length == 0) { + if (data.length === 0) { notificationsService.error(error.headline, "There is no 'restore' relation found for this node. Use the Move menu item to move it manually."); $scope.page.buttonRestore = "error"; return; @@ -424,7 +424,7 @@ relation = data[0]; - if (relation.parentId == -1) { + if (relation.parentId === -1) { target = { id: -1, name: "Root" }; moveNode(content, target); } else { @@ -481,7 +481,6 @@ $scope.editors[editorIndex].content = angular.copy($scope.content); $scope.editors[editorIndex].content.name = "What a variant"; // set selected variant on split view content - console.log($scope.editors[editorIndex].content.variants); angular.forEach($scope.editors[editorIndex].content.variants, function (variant) { if (variant.culture === selectedVariant.culture) { variant.current = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html index c27d885483..7d435adc6d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/listview/listview.html @@ -1,19 +1,18 @@ -
- -
-
- -
- -
- - - - -
- -
+ + +
+
+
+ +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html index 7df2577871..606ae1d9b1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html @@ -1,60 +1,65 @@
-
+ + -
-
- -
-
- -
+
-
+
+
+ +
+
+ +
-
+
-
-
- -
+
-
- - +
+
+ +
- - +
+ + -
+ + -
+
-
+
-
-
Content Type Variation
- Define the rules for how this content type's properties can be varied -
-
- -
+
-
+
+
Content Type Variation
+ Define the rules for how this content type's properties can be varied +
+
+ +
+
+ + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html index 0cfe76cd7a..c3bc28a145 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/templates/templates.html @@ -1,23 +1,27 @@ -
+
+ + +
-
-
- -
- -
- - - - -
+
+
+ +
+ +
+ + +
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html index 1461341d6d..21d29b2161 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/listview/listview.html @@ -1,19 +1,18 @@ -
- -
-
- -
- -
- - - - -
- -
+ + +
+
+
+ +
+
+ + +
+
+
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html index 7c9811e37a..d34b31c8ea 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/views/permissions/permissions.html @@ -1,49 +1,51 @@
+ + +
-
- -
-
- -
-
- -
- -
- -
- -
-
- -
- -
- - - - - - - - -
- -
- +
+
+ +
+
+ +
+ +
+ +
+ +
+
+ +
+ +
+ + + + + + + + +
+ +
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html index 8f093a5924..d692c6fd9e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/partialviewmacros/edit.html @@ -19,50 +19,53 @@ + + -
+
-
- - - -
- -
- -
-
- +
+
+ + diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html b/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html index 6ecc2b2d89..3bbf735199 100644 --- a/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/partialviews/edit.html @@ -20,49 +20,54 @@ -
+ + + +
+ +
+ -
- - -
-
- -
-
- +
+
+ + + diff --git a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html index 9b03935efc..2e747fd5a5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/scripts/edit.html @@ -19,14 +19,16 @@ - -
-
- + + +
+
+
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/edit.html b/src/Umbraco.Web.UI.Client/src/views/templates/edit.html index 279cdc538d..25cfb7ea61 100644 --- a/src/Umbraco.Web.UI.Client/src/views/templates/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/templates/edit.html @@ -7,14 +7,12 @@ novalidate val-form-manager> - -
+ + -
+
-
- - +
- - - +
+ + + + + + + +
+ +
+ +
+ + + + + + +
- -
- -
- - -
- -
-
+ + diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html index 67f204aa2f..5aded20cfa 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html @@ -165,196 +165,200 @@
-
+ - -
- + - - + +
+ - - + + - + + +
+ +
+ +
- +
+ + +
-
- - -
- -
- - -
- -
- - -
- -
- - -
- - - - - - - - +
+ + +
+ label="Change password" + label-key="general_changePassword" + state="changePasswordButtonState" + ng-if="model.changePasswordModel.isChanging === false" + size="s"> -
+ + + + + + + + + + +
+


Password reset to value: {{model.user.resetPasswordValue}}

+
-
-


Password reset to value: {{model.user.resetPasswordValue}}

-
+ +
+
+ Status: +
+
+ + {{model.user.userDisplayState.name}} + +
+
- -
-
- Status: +
+
+ Last login: +
+
+ {{ model.user.formattedLastLogin }} + {{ model.user.name | umbWordLimit:1 }} has not logged in yet +
-
- - {{model.user.userDisplayState.name}} - -
-
-
-
- Last login: +
+
+ Failed login attempts: +
+
+ {{ model.user.failedPasswordAttempts }} +
-
- {{ model.user.formattedLastLogin }} - {{ model.user.name | umbWordLimit:1 }} has not logged in yet -
-
-
-
- Failed login attempts: +
+
+ Last lockout date: +
+
+ + {{ model.user.name | umbWordLimit:1 }} hasn't been locked out + + {{ model.user.formattedLastLockoutDate }} +
-
- {{ model.user.failedPasswordAttempts }} -
-
-
-
- Last lockout date: +
+
+ Password is last changed: +
+
+ + The password hasn't been changed + + {{ model.user.formattedLastPasswordChangeDate }} +
-
- - {{ model.user.name | umbWordLimit:1 }} hasn't been locked out - - {{ model.user.formattedLastLockoutDate }} -
-
-
-
- Password is last changed: +
+
+ User is created: +
+
+ {{ model.user.formattedCreateDate }} +
-
- - The password hasn't been changed - - {{ model.user.formattedLastPasswordChangeDate }} -
-
-
-
- User is created: +
+
+ User is last updated: +
+
+ {{ model.user.formattedUpdateDate }} +
-
- {{ model.user.formattedCreateDate }} -
-
-
-
- User is last updated: -
-
- {{ model.user.formattedUpdateDate }} -
-
+ -
+
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index e03c3b4b41..63348ecb9a 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -121,7 +121,7 @@ - + @@ -656,11 +656,12 @@ - + + - + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 1bf64d524c..e2649a3ab7 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -235,7 +235,7 @@ What languages would you like to publish? No languages available to be published. Published Languages. - + Ready to Publish? Create a new Content Template from '%0%' diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index f9c62eeb0e..510b4f17db 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -11,11 +11,11 @@ One can edit web.config, it will not be overritten, but it WILL be altered by this transform file everytime Umbraco builds. --> + + + - - - -