U4-6674 - Kill ToContentSet, becomes ToIndexedArray
This commit is contained in:
@@ -16,21 +16,6 @@ namespace Umbraco.Core.Models
|
||||
/// </remarks>
|
||||
public interface IPublishedContent
|
||||
{
|
||||
#region ContentSet
|
||||
|
||||
// Because of http://issues.umbraco.org/issue/U4-1797 and in order to implement
|
||||
// Index() and methods that derive from it such as IsFirst(), IsLast(), etc... all
|
||||
// content items must know about their containing content set.
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content set to which the content belongs.
|
||||
/// </summary>
|
||||
/// <remarks>The default set consists in the siblings of the content (including the content
|
||||
/// itself) ordered by <c>sortOrder</c>.</remarks>
|
||||
IEnumerable<IPublishedContent> ContentSet { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentType
|
||||
|
||||
/// <summary>
|
||||
@@ -73,12 +58,6 @@ namespace Umbraco.Core.Models
|
||||
/// have a published version, or not.</remarks>
|
||||
bool IsDraft { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the published content within its current owning content set.
|
||||
/// </summary>
|
||||
/// <returns>The index of the published content within its current owning content set.</returns>
|
||||
int GetIndex();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tree
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods to handle extended content.
|
||||
@@ -20,27 +15,5 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// Gets a value indicating whether properties were added to the extended content.
|
||||
/// </summary>
|
||||
bool HasAddedProperties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the content set of the extended content.
|
||||
/// </summary>
|
||||
/// <param name="contentSet"></param>
|
||||
void SetContentSet(IEnumerable<IPublishedContent> contentSet);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the content set of the extended content.
|
||||
/// </summary>
|
||||
void ClearContentSet();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the index of the extended content.
|
||||
/// </summary>
|
||||
/// <param name="value">The index value.</param>
|
||||
void SetIndex(int value);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the index of the extended content.
|
||||
/// </summary>
|
||||
void ClearIndex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
public class IndexedArrayItem<TContent>
|
||||
{
|
||||
public IndexedArrayItem(TContent content, int index)
|
||||
{
|
||||
Content = content;
|
||||
Index = index;
|
||||
}
|
||||
|
||||
public TContent Content { get; }
|
||||
|
||||
public int Index { get; }
|
||||
|
||||
public int TotalCount { get; internal set; }
|
||||
|
||||
public bool IsFirst()
|
||||
{
|
||||
return Index == 0;
|
||||
}
|
||||
|
||||
public HtmlString IsFirst(string valueIfTrue)
|
||||
{
|
||||
return IsFirst(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsFirst() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotFirst()
|
||||
{
|
||||
return IsFirst() == false;
|
||||
}
|
||||
|
||||
public HtmlString IsNotFirst(string valueIfTrue)
|
||||
{
|
||||
return IsNotFirst(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotFirst() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsIndex(int index)
|
||||
{
|
||||
return Index == index;
|
||||
}
|
||||
|
||||
public HtmlString IsIndex(int index, string valueIfTrue)
|
||||
{
|
||||
return IsIndex(index, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsIndex(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsIndex(index) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsModZero(int modulus)
|
||||
{
|
||||
return Index % modulus == 0;
|
||||
}
|
||||
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
return IsModZero(modulus, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsModZero(modulus) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotModZero(int modulus)
|
||||
{
|
||||
return IsModZero(modulus) == false;
|
||||
}
|
||||
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
return IsNotModZero(modulus, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotIndex(int index)
|
||||
{
|
||||
return IsIndex(index) == false;
|
||||
}
|
||||
|
||||
public HtmlString IsNotIndex(int index, string valueIfTrue)
|
||||
{
|
||||
return IsNotIndex(index, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsNotIndex(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotIndex(index) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsLast()
|
||||
{
|
||||
return Index == TotalCount - 1;
|
||||
}
|
||||
|
||||
public HtmlString IsLast(string valueIfTrue)
|
||||
{
|
||||
return IsLast(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsLast() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotLast()
|
||||
{
|
||||
return IsLast() == false;
|
||||
}
|
||||
|
||||
public HtmlString IsNotLast(string valueIfTrue)
|
||||
{
|
||||
return IsNotLast(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotLast() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsEven()
|
||||
{
|
||||
return Index % 2 == 0;
|
||||
}
|
||||
|
||||
public HtmlString IsEven(string valueIfTrue)
|
||||
{
|
||||
return IsEven(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsEven(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsEven() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsOdd()
|
||||
{
|
||||
return Index % 2 == 1;
|
||||
}
|
||||
|
||||
public HtmlString IsOdd(string valueIfTrue)
|
||||
{
|
||||
return IsOdd(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public HtmlString IsOdd(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsOdd() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,31 +17,9 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
#endregion
|
||||
|
||||
#region Index
|
||||
|
||||
private int? _index;
|
||||
|
||||
public override int GetIndex()
|
||||
{
|
||||
// fast
|
||||
if (_index.HasValue) return _index.Value;
|
||||
|
||||
// slow -- and don't cache, not in a set
|
||||
if (_contentSet == null) return Content.GetIndex();
|
||||
|
||||
// slow -- but cache for next time
|
||||
var index = _contentSet.FindIndex(x => x.Id == Id);
|
||||
if (index < 0)
|
||||
throw new IndexOutOfRangeException("Could not find content in the content set.");
|
||||
_index = index;
|
||||
return index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Extend
|
||||
|
||||
internal static IPublishedContentExtended Extend(IPublishedContent content, IEnumerable<IPublishedContent> contentSet)
|
||||
internal static IPublishedContentExtended Extend(IPublishedContent content)
|
||||
{
|
||||
// first unwrap content down to the lowest possible level, ie either the deepest inner
|
||||
// IPublishedContent or the first extended that has added properties. this is to avoid
|
||||
@@ -95,7 +73,6 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
var extended2 = extended as IPublishedContentExtended;
|
||||
if (extended2 == null)
|
||||
throw new Exception("Extended does not implement IPublishedContentExtended.");
|
||||
extended2.SetContentSet(contentSet);
|
||||
return extended2;
|
||||
}
|
||||
|
||||
@@ -115,37 +92,6 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
get { return _properties != null; }
|
||||
}
|
||||
|
||||
void IPublishedContentExtended.SetContentSet(IEnumerable<IPublishedContent> contentSet)
|
||||
{
|
||||
_contentSet = contentSet;
|
||||
}
|
||||
|
||||
void IPublishedContentExtended.ClearContentSet()
|
||||
{
|
||||
_contentSet = null;
|
||||
}
|
||||
|
||||
void IPublishedContentExtended.SetIndex(int value)
|
||||
{
|
||||
_index = value;
|
||||
}
|
||||
|
||||
void IPublishedContentExtended.ClearIndex()
|
||||
{
|
||||
_index = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content set
|
||||
|
||||
private IEnumerable<IPublishedContent> _contentSet;
|
||||
|
||||
public override IEnumerable<IPublishedContent> ContentSet
|
||||
{
|
||||
get { return _contentSet ?? Content.ContentSet; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an ordered set of <see cref="IPublishedContent"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content.</typeparam>
|
||||
public class PublishedContentOrderedSet<T> : PublishedContentSet<T>, IOrderedEnumerable<T>
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
// ReSharper disable ParameterTypeCanBeEnumerable.Local
|
||||
internal PublishedContentOrderedSet(IOrderedEnumerable<T> content)
|
||||
// ReSharper restore ParameterTypeCanBeEnumerable.Local
|
||||
: base(content)
|
||||
{ }
|
||||
|
||||
// note: because we implement IOrderedEnumerable, we don't need to implement the ThenBy nor
|
||||
// ThenByDescending methods here, only CreateOrderedEnumerable and that does it.
|
||||
|
||||
#region IOrderedEnumerable<T>
|
||||
|
||||
public IOrderedEnumerable<T> CreateOrderedEnumerable<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer, bool descending)
|
||||
{
|
||||
return new PublishedContentOrderedSet<T>(((IOrderedEnumerable<T>)Source).CreateOrderedEnumerable(keySelector, comparer, descending));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a set of <see cref="IPublishedContent"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of content.</typeparam>
|
||||
/// <remarks>
|
||||
/// <para>A <c>ContentSet{T}</c> is created from an <c>IEnumerable{T}</c> using the <c>ToContentSet</c>
|
||||
/// extension method.</para>
|
||||
/// <para>The content set source is enumerated only once. Same as what you get
|
||||
/// when you call ToList on an IEnumerable. Only, ToList enumerates its source when
|
||||
/// created, whereas a content set enumerates its source only when the content set itself
|
||||
/// is enumerated.</para>
|
||||
/// </remarks>
|
||||
public class PublishedContentSet<T> : IEnumerable<T>
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
// used by <c>ToContentSet</c> extension method to initialize a new set from an IEnumerable.
|
||||
internal PublishedContentSet(IEnumerable<T> source)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException("source");
|
||||
Source = source;
|
||||
}
|
||||
|
||||
#region Source
|
||||
|
||||
protected readonly IEnumerable<T> Source;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Enumerated
|
||||
|
||||
// cache the enumeration so we don't enumerate more than once. Same as what you get
|
||||
// when you call ToList on an IEnumerable. Only, ToList enumerates its source when
|
||||
// created, whereas a content set enumerates its source only when the content set itself
|
||||
// is enumerated.
|
||||
|
||||
// cache the wrapped items so if we reset the enumeration, we do not re-wrap everything (only new items).
|
||||
|
||||
private T[] _enumerated;
|
||||
private readonly Dictionary<T, IPublishedContentExtended> _xContent = new Dictionary<T, IPublishedContentExtended>();
|
||||
|
||||
// wrap an item, ie create the actual clone for this set
|
||||
private T MapContentAsT(T t)
|
||||
{
|
||||
return MapContent(t) as T;
|
||||
}
|
||||
|
||||
internal IPublishedContentExtended MapContent(T t)
|
||||
{
|
||||
IPublishedContentExtended extend;
|
||||
if (_xContent.TryGetValue(t, out extend)) return extend;
|
||||
|
||||
extend = PublishedContentExtended.Extend(t, this);
|
||||
var asT = extend as T;
|
||||
if (asT == null)
|
||||
throw new InvalidOperationException(string.Format("Failed extend a published content of type {0}."
|
||||
+ "Got {1} when expecting {2}.", t.GetType().FullName, extend.GetType().FullName, typeof(T).FullName));
|
||||
_xContent[t] = extend;
|
||||
return extend;
|
||||
}
|
||||
|
||||
private T[] Enumerated
|
||||
{
|
||||
get
|
||||
{
|
||||
// enumerate the source and cache the result
|
||||
// tell clones about their index within the set (for perfs purposes)
|
||||
var index = 0;
|
||||
return _enumerated ?? (_enumerated = Source.Select(t =>
|
||||
{
|
||||
var extend = MapContent(t);
|
||||
extend.SetIndex(index++);
|
||||
return extend as T;
|
||||
}).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
// indicates that the source has changed
|
||||
// so the set can clear its inner caches
|
||||
// should only be used by DynamicPublishedContentList
|
||||
internal void SourceChanged()
|
||||
{
|
||||
// reset the cached enumeration so it's enumerated again
|
||||
if (_enumerated == null) return;
|
||||
_enumerated = null;
|
||||
|
||||
foreach (var item in _xContent.Values)
|
||||
item.ClearIndex();
|
||||
|
||||
var removed = _xContent.Keys.Except(Source);
|
||||
foreach (var content in removed)
|
||||
{
|
||||
_xContent[content].ClearContentSet();
|
||||
_xContent.Remove(content);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of items in the set.
|
||||
/// </summary>
|
||||
/// <returns>The number of items in the set.</returns>
|
||||
/// <remarks>Will cause the set to be enumerated if it hasn't been already.</remarks>
|
||||
public virtual int Count
|
||||
{
|
||||
get { return Enumerated.Length; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<T>
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<T>)Enumerated).GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wrap methods returning T
|
||||
|
||||
public T ElementAt(int index)
|
||||
{
|
||||
return MapContentAsT(Source.ElementAt(index));
|
||||
}
|
||||
|
||||
public T ElementAtOrDefault(int index)
|
||||
{
|
||||
var element = Source.ElementAtOrDefault(index);
|
||||
return element == null ? null : MapContentAsT(element);
|
||||
}
|
||||
|
||||
public T First()
|
||||
{
|
||||
return MapContentAsT(Source.First());
|
||||
}
|
||||
|
||||
public T First(Func<T, bool> predicate)
|
||||
{
|
||||
return MapContentAsT(Source.First(predicate));
|
||||
}
|
||||
|
||||
public T FirstOrDefault()
|
||||
{
|
||||
var first = Source.FirstOrDefault();
|
||||
return first == null ? null : MapContentAsT(first);
|
||||
}
|
||||
|
||||
public T FirstOrDefault(Func<T, bool> predicate)
|
||||
{
|
||||
var first = Source.FirstOrDefault(predicate);
|
||||
return first == null ? null : MapContentAsT(first);
|
||||
}
|
||||
|
||||
public T Last()
|
||||
{
|
||||
return MapContentAsT(Source.Last());
|
||||
}
|
||||
|
||||
public T Last(Func<T, bool> predicate)
|
||||
{
|
||||
return MapContentAsT(Source.Last(predicate));
|
||||
}
|
||||
|
||||
public T LastOrDefault()
|
||||
{
|
||||
var last = Source.LastOrDefault();
|
||||
return last == null ? null : MapContentAsT(last);
|
||||
}
|
||||
|
||||
public T LastOrDefault(Func<T, bool> predicate)
|
||||
{
|
||||
var last = Source.LastOrDefault(predicate);
|
||||
return last == null ? null : MapContentAsT(last);
|
||||
}
|
||||
|
||||
public T Single()
|
||||
{
|
||||
return MapContentAsT(Source.Single());
|
||||
}
|
||||
|
||||
public T Single(Func<T, bool> predicate)
|
||||
{
|
||||
return MapContentAsT(Source.Single(predicate));
|
||||
}
|
||||
|
||||
public T SingleOrDefault()
|
||||
{
|
||||
var single = Source.SingleOrDefault();
|
||||
return single == null ? null : MapContentAsT(single);
|
||||
}
|
||||
|
||||
public T SingleOrDefault(Func<T, bool> predicate)
|
||||
{
|
||||
var single = Source.SingleOrDefault(predicate);
|
||||
return single == null ? null : MapContentAsT(single);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wrap methods returning IOrderedEnumerable<T>
|
||||
|
||||
public PublishedContentOrderedSet<T> OrderBy<TKey>(Func<T, TKey> keySelector)
|
||||
{
|
||||
return new PublishedContentOrderedSet<T>(Source.OrderBy(keySelector));
|
||||
}
|
||||
|
||||
public PublishedContentOrderedSet<T> OrderBy<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
|
||||
{
|
||||
return new PublishedContentOrderedSet<T>(Source.OrderBy(keySelector, comparer));
|
||||
}
|
||||
|
||||
public PublishedContentOrderedSet<T> OrderByDescending<TKey>(Func<T, TKey> keySelector)
|
||||
{
|
||||
return new PublishedContentOrderedSet<T>(Source.OrderByDescending(keySelector));
|
||||
}
|
||||
|
||||
public PublishedContentOrderedSet<T> OrderByDescending<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
|
||||
{
|
||||
return new PublishedContentOrderedSet<T>(Source.OrderByDescending(keySelector, comparer));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -48,12 +48,6 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
return Content;
|
||||
}
|
||||
|
||||
#region ContentSet
|
||||
|
||||
public virtual IEnumerable<IPublishedContent> ContentSet => Content.ContentSet;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentType
|
||||
|
||||
public virtual PublishedContentType ContentType => Content.ContentType;
|
||||
@@ -102,11 +96,6 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
public virtual bool IsDraft => Content.IsDraft;
|
||||
|
||||
public virtual int GetIndex()
|
||||
{
|
||||
return Content.GetIndex();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tree
|
||||
|
||||
@@ -627,8 +627,7 @@
|
||||
<Compile Include="PropertyEditors\ValueConverters\TextStringValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\TinyMceValueConverter.cs" />
|
||||
<Compile Include="PropertyEditors\IPropertyValueConverter.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentOrderedSet.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentSet.cs" />
|
||||
<Compile Include="Models\PublishedContent\IndexedArrayItem.cs" />
|
||||
<Compile Include="Strings\Css\StylesheetRule.cs" />
|
||||
<Compile Include="Models\DictionaryItem.cs" />
|
||||
<Compile Include="Models\DictionaryTranslation.cs" />
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -91,75 +91,39 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Assert.AreEqual("Content 1", content.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultContentSetIsSiblings()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
Assert.AreEqual(0, content.Index());
|
||||
Assert.IsTrue(content.IsFirst());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RunOnLatestContentSet()
|
||||
{
|
||||
// get first content
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var id = content.Id;
|
||||
Assert.IsTrue(content.IsFirst());
|
||||
|
||||
// reverse => should be last, but set has not changed => still first
|
||||
content = UmbracoContext.Current.ContentCache.GetAtRoot().Reverse().First(x => x.Id == id);
|
||||
Assert.IsTrue(content.IsFirst());
|
||||
Assert.IsFalse(content.IsLast());
|
||||
|
||||
// reverse + new set => now it's last
|
||||
content = UmbracoContext.Current.ContentCache.GetAtRoot().Reverse().ToContentSet().First(x => x.Id == id);
|
||||
Assert.IsFalse(content.IsFirst());
|
||||
Assert.IsTrue(content.IsLast());
|
||||
|
||||
// reverse that set => should be first, but no new set => still last
|
||||
content = UmbracoContext.Current.ContentCache.GetAtRoot().Reverse().ToContentSet().Reverse().First(x => x.Id == id);
|
||||
Assert.IsFalse(content.IsFirst());
|
||||
Assert.IsTrue(content.IsLast());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Distinct()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var items = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
.Distinct()
|
||||
.Distinct()
|
||||
.ToContentSet()
|
||||
.First();
|
||||
.ToIndexedArray();
|
||||
|
||||
Assert.AreEqual("Content 1", content.Name);
|
||||
Assert.IsTrue(content.IsFirst());
|
||||
Assert.IsFalse(content.IsLast());
|
||||
var item = items[0];
|
||||
Assert.AreEqual("Content 1", item.Content.Name);
|
||||
Assert.IsTrue(item.IsFirst());
|
||||
Assert.IsFalse(item.IsLast());
|
||||
|
||||
content = content.Next();
|
||||
Assert.AreEqual("Content 2", content.Name);
|
||||
Assert.IsFalse(content.IsFirst());
|
||||
Assert.IsFalse(content.IsLast());
|
||||
item = items[1];
|
||||
Assert.AreEqual("Content 2", item.Content.Name);
|
||||
Assert.IsFalse(item.IsFirst());
|
||||
Assert.IsFalse(item.IsLast());
|
||||
|
||||
content = content.Next();
|
||||
Assert.AreEqual("Content 2Sub", content.Name);
|
||||
Assert.IsFalse(content.IsFirst());
|
||||
Assert.IsTrue(content.IsLast());
|
||||
item = items[2];
|
||||
Assert.AreEqual("Content 2Sub", item.Content.Name);
|
||||
Assert.IsFalse(item.IsFirst());
|
||||
Assert.IsTrue(item.IsLast());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OfType1()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var items = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
.OfType<ContentType2>()
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
Assert.AreEqual(2, content.Count());
|
||||
Assert.IsInstanceOf<ContentType2>(content.First());
|
||||
var set = content.ToContentSet();
|
||||
Assert.IsInstanceOf<ContentType2>(set.First());
|
||||
Assert.AreSame(set, set.First().ContentSet);
|
||||
Assert.IsInstanceOf<ContentType2Sub>(set.First().Next());
|
||||
.ToIndexedArray();
|
||||
Assert.AreEqual(2, items.Length);
|
||||
Assert.IsInstanceOf<ContentType2>(items.First().Content);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -168,11 +132,9 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
.OfType<ContentType2Sub>()
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
Assert.AreEqual(1, content.Count());
|
||||
Assert.IsInstanceOf<ContentType2Sub>(content.First());
|
||||
var set = content.ToContentSet();
|
||||
Assert.IsInstanceOf<ContentType2Sub>(set.First());
|
||||
.ToIndexedArray();
|
||||
Assert.AreEqual(1, content.Length);
|
||||
Assert.IsInstanceOf<ContentType2Sub>(content.First().Content);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -188,17 +150,16 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Position()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var items = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
.Where(x => x.GetPropertyValue<int>("prop1") == 1234)
|
||||
.ToContentSet()
|
||||
.ToArray();
|
||||
.ToIndexedArray();
|
||||
|
||||
Assert.IsTrue(content.First().IsFirst());
|
||||
Assert.IsFalse(content.First().IsLast());
|
||||
Assert.IsFalse(content.First().Next().IsFirst());
|
||||
Assert.IsFalse(content.First().Next().IsLast());
|
||||
Assert.IsFalse(content.First().Next().Next().IsFirst());
|
||||
Assert.IsTrue(content.First().Next().Next().IsLast());
|
||||
Assert.IsTrue(items.First().IsFirst());
|
||||
Assert.IsFalse(items.First().IsLast());
|
||||
Assert.IsFalse(items.Skip(1).First().IsFirst());
|
||||
Assert.IsFalse(items.Skip(1).First().IsLast());
|
||||
Assert.IsFalse(items.Skip(2).First().IsFirst());
|
||||
Assert.IsTrue(items.Skip(2).First().IsLast());
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -199,14 +199,6 @@ namespace Umbraco.Tests.PublishedContent
|
||||
public PublishedItemType ItemType { get { return PublishedItemType.Content; } }
|
||||
public bool IsDraft { get; set; }
|
||||
|
||||
public int GetIndex()
|
||||
{
|
||||
var index = this.Siblings().FindIndex(x => x.Id == Id);
|
||||
if (index < 0)
|
||||
throw new IndexOutOfRangeException("Failed to find content in its siblings collection?!");
|
||||
return index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tree
|
||||
@@ -219,12 +211,6 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentSet
|
||||
|
||||
public IEnumerable<IPublishedContent> ContentSet { get { return this.Siblings(); } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentType
|
||||
|
||||
public PublishedContentType ContentType { get; private set; }
|
||||
|
||||
@@ -118,49 +118,16 @@ namespace Umbraco.Tests.PublishedContent
|
||||
return doc;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("IPublishedContent currently (6.1 as of april 25, 2013) has bugs")]
|
||||
public void Fails()
|
||||
{
|
||||
var content = GetNode(1173);
|
||||
|
||||
var c1 = content.Children.First(x => x.Id == 1177);
|
||||
Assert.IsFalse(c1.IsFirst());
|
||||
|
||||
var c2 = content.Children.Where(x => x.DocumentTypeAlias == "CustomDocument").First(x => x.Id == 1177);
|
||||
Assert.IsTrue(c2.IsFirst());
|
||||
|
||||
// First is not implemented
|
||||
var c2a = content.Children.First(x => x.DocumentTypeAlias == "CustomDocument" && x.Id == 1177);
|
||||
Assert.IsTrue(c2a.IsFirst()); // so here it's luck
|
||||
|
||||
c1 = content.Children.First(x => x.Id == 1177);
|
||||
Assert.IsFalse(c1.IsFirst()); // and here it fails
|
||||
|
||||
// but even using supported (where) method...
|
||||
// do not replace by First(x => ...) here since it's not supported at the moment
|
||||
c1 = content.Children.Where(x => x.Id == 1177).First();
|
||||
c2 = content.Children.Where(x => x.DocumentTypeAlias == "CustomDocument" && x.Id == 1177).First();
|
||||
|
||||
Assert.IsFalse(c1.IsFirst()); // here it fails because c2 has corrupted it
|
||||
|
||||
// so there's only 1 IPublishedContent instance
|
||||
// which keeps changing collection, ie being modified
|
||||
// which is *bad* from a cache point of vue
|
||||
// and from a consistency point of vue...
|
||||
// => we want clones!
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Last_From_Where_Filter_Dynamic_Linq()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
var items = doc.Children.Where("Visible").ToContentSet();
|
||||
var items = doc.Children.Where("Visible").ToIndexedArray();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.Id != 1178)
|
||||
if (item.Content.Id != 1178)
|
||||
{
|
||||
Assert.IsFalse(item.IsLast());
|
||||
}
|
||||
@@ -179,13 +146,13 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var items = doc
|
||||
.Children
|
||||
.Where(x => x.IsVisible())
|
||||
.ToContentSet();
|
||||
.ToIndexedArray();
|
||||
|
||||
Assert.AreEqual(3, items.Count());
|
||||
Assert.AreEqual(3, items.Length);
|
||||
|
||||
foreach (var d in items)
|
||||
{
|
||||
switch (d.Id)
|
||||
switch (d.Content.Id)
|
||||
{
|
||||
case 1174:
|
||||
Assert.IsTrue(d.IsFirst());
|
||||
@@ -228,14 +195,13 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
.OfType<Home>() // ours, return IEnumerable<Home> (actually a PublishedContentSet<Home>)
|
||||
.Where(x => x.IsVisible()) // so, here it's linq again :-(
|
||||
.ToContentSet() // so, we need that one for the test to pass
|
||||
.ToArray();
|
||||
.ToIndexedArray(); // so, we need that one for the test to pass
|
||||
|
||||
Assert.AreEqual(1, items.Count());
|
||||
|
||||
foreach (var d in items)
|
||||
{
|
||||
switch (d.Id)
|
||||
switch (d.Content.Id)
|
||||
{
|
||||
case 1174:
|
||||
Assert.IsTrue(d.IsFirst());
|
||||
@@ -253,11 +219,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
var items = doc.Children.Take(3).ToContentSet();
|
||||
var items = doc.Children.Take(3).ToIndexedArray();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.Id != 1178)
|
||||
if (item.Content.Id != 1178)
|
||||
{
|
||||
Assert.IsFalse(item.IsLast());
|
||||
}
|
||||
@@ -273,9 +239,9 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
foreach (var d in doc.Children.Skip(1))
|
||||
foreach (var d in doc.Children.Skip(1).ToIndexedArray())
|
||||
{
|
||||
if (d.Id != 1176)
|
||||
if (d.Content.Id != 1176)
|
||||
{
|
||||
Assert.IsFalse(d.IsLast());
|
||||
}
|
||||
@@ -293,11 +259,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var items = doc.Children
|
||||
.Concat(new[] { GetNode(1175), GetNode(4444) })
|
||||
.ToContentSet();
|
||||
.ToIndexedArray();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.Id != 4444)
|
||||
if (item.Content.Id != 4444)
|
||||
{
|
||||
Assert.IsFalse(item.IsLast());
|
||||
}
|
||||
@@ -362,58 +328,6 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Assert.IsNotNull(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Index()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
Assert.AreEqual(0, doc.Index());
|
||||
doc = GetNode(1176);
|
||||
Assert.AreEqual(3, doc.Index());
|
||||
doc = GetNode(1177);
|
||||
Assert.AreEqual(1, doc.Index());
|
||||
doc = GetNode(1178);
|
||||
Assert.AreEqual(2, doc.Index());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_First()
|
||||
{
|
||||
var doc = GetNode(1046); //test root nodes
|
||||
Assert.IsTrue(doc.IsFirst());
|
||||
doc = GetNode(1172);
|
||||
Assert.IsFalse(doc.IsFirst());
|
||||
doc = GetNode(1173); //test normal nodes
|
||||
Assert.IsTrue(doc.IsFirst());
|
||||
doc = GetNode(1175);
|
||||
Assert.IsFalse(doc.IsFirst());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Not_First()
|
||||
{
|
||||
var doc = GetNode(1046); //test root nodes
|
||||
Assert.IsFalse(doc.IsNotFirst());
|
||||
doc = GetNode(1172);
|
||||
Assert.IsTrue(doc.IsNotFirst());
|
||||
doc = GetNode(1173); //test normal nodes
|
||||
Assert.IsFalse(doc.IsNotFirst());
|
||||
doc = GetNode(1175);
|
||||
Assert.IsTrue(doc.IsNotFirst());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Position()
|
||||
{
|
||||
var doc = GetNode(1046); //test root nodes
|
||||
Assert.IsTrue(doc.IsPosition(0));
|
||||
doc = GetNode(1172);
|
||||
Assert.IsTrue(doc.IsPosition(1));
|
||||
doc = GetNode(1173); //test normal nodes
|
||||
Assert.IsTrue(doc.IsPosition(0));
|
||||
doc = GetNode(1175);
|
||||
Assert.IsTrue(doc.IsPosition(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Children_GroupBy_DocumentTypeAlias()
|
||||
{
|
||||
@@ -617,46 +531,6 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Assert.AreEqual((int)1174, (int)result.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Next()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
var result = doc.Next();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual((int)1175, (int)result.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Next_Without_Sibling()
|
||||
{
|
||||
var doc = GetNode(1176);
|
||||
|
||||
Assert.IsNull(doc.Next());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Previous_Without_Sibling()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
|
||||
Assert.IsNull(doc.Previous());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Previous()
|
||||
{
|
||||
var doc = GetNode(1176);
|
||||
|
||||
var result = doc.Previous();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual((int)1178, (int)result.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DetachedProperty1()
|
||||
{
|
||||
|
||||
@@ -22,10 +22,6 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Assert.AreEqual(1, content.Level);
|
||||
Assert.IsNull(content.Parent);
|
||||
|
||||
// and yet is has siblings, etc.
|
||||
var siblings = content.Siblings();
|
||||
Assert.AreEqual(2, siblings.Count());
|
||||
|
||||
// non-existing content is null
|
||||
content = ctx.ContentCache.GetById(666);
|
||||
Assert.IsNull(content);
|
||||
|
||||
@@ -14,14 +14,13 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
internal static class ExamineExtensions
|
||||
{
|
||||
internal static PublishedContentSet<IPublishedContent> ConvertSearchResultToPublishedContent(this IEnumerable<SearchResult> results, IPublishedCache cache)
|
||||
internal static IEnumerable<IPublishedContent> ConvertSearchResultToPublishedContent(this IEnumerable<SearchResult> results, IPublishedCache cache)
|
||||
{
|
||||
//TODO: The search result has already returned a result which SHOULD include all of the data to create an IPublishedContent,
|
||||
// however this is currently not the case:
|
||||
// http://examine.codeplex.com/workitem/10350
|
||||
|
||||
var list = new List<IPublishedContent>();
|
||||
var set = new PublishedContentSet<IPublishedContent>(list);
|
||||
|
||||
foreach (var result in results.OrderByDescending(x => x.Score))
|
||||
{
|
||||
@@ -36,16 +35,17 @@ namespace Umbraco.Web
|
||||
// returned by the cache, in case the cache can create real types.
|
||||
// so we have to ask it to please extend itself.
|
||||
|
||||
list.Add(content);
|
||||
var extend = set.MapContent(content);
|
||||
//var extend = set.MapContent(content);
|
||||
var extend = PublishedContentExtended.Extend(content);
|
||||
list.Add(extend);
|
||||
|
||||
var property = new PropertyResult("examineScore",
|
||||
var property = new PropertyResult("examineScore",
|
||||
result.Score,
|
||||
PropertyResultType.CustomProperty);
|
||||
extend.AddProperty(property);
|
||||
}
|
||||
|
||||
return set;
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,13 +28,6 @@ namespace Umbraco.Web.Models
|
||||
protected internal IPublishedContent PublishedContent { get; private set; }
|
||||
private DynamicPublishedContentList _contentList;
|
||||
|
||||
// must implement that one if we implement IPublishedContent
|
||||
public IEnumerable<IPublishedContent> ContentSet
|
||||
{
|
||||
// that is a definitively non-efficient way of doing it, though it should work
|
||||
get { return _contentList ?? (_contentList = new DynamicPublishedContentList(PublishedContent.ContentSet)); }
|
||||
}
|
||||
|
||||
public PublishedContentType ContentType { get { return PublishedContent.ContentType; } }
|
||||
|
||||
#region Constructors
|
||||
@@ -435,11 +428,6 @@ namespace Umbraco.Web.Models
|
||||
get { return PublishedContent.IsDraft; }
|
||||
}
|
||||
|
||||
int IPublishedContent.GetIndex()
|
||||
{
|
||||
return PublishedContent.GetIndex();
|
||||
}
|
||||
|
||||
ICollection<IPublishedProperty> IPublishedContent.Properties
|
||||
{
|
||||
get { return PublishedContent.Properties; }
|
||||
@@ -775,20 +763,6 @@ namespace Umbraco.Web.Models
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPublishedContente extension methods - ContentSet
|
||||
|
||||
public int Position()
|
||||
{
|
||||
return Index();
|
||||
}
|
||||
|
||||
public int Index()
|
||||
{
|
||||
return PublishedContent.GetIndex();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPublishedContent extension methods - IsSomething: misc
|
||||
|
||||
public bool Visible
|
||||
@@ -818,160 +792,6 @@ namespace Umbraco.Web.Models
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPublishedContent extension methods - IsSomething: position in set
|
||||
|
||||
public bool IsFirst()
|
||||
{
|
||||
return PublishedContent.IsFirst();
|
||||
}
|
||||
|
||||
public HtmlString IsFirst(string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsFirst(valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsFirst(valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotFirst()
|
||||
{
|
||||
return PublishedContent.IsNotFirst();
|
||||
}
|
||||
|
||||
public HtmlString IsNotFirst(string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsNotFirst(valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsNotFirst(valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsPosition(int index)
|
||||
{
|
||||
return PublishedContent.IsPosition(index);
|
||||
}
|
||||
|
||||
public HtmlString IsPosition(int index, string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsPosition(index, valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsPosition(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsPosition(index, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsModZero(int modulus)
|
||||
{
|
||||
return PublishedContent.IsModZero(modulus);
|
||||
}
|
||||
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsModZero(modulus, valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsModZero(modulus, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotModZero(int modulus)
|
||||
{
|
||||
return PublishedContent.IsNotModZero(modulus);
|
||||
}
|
||||
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsNotModZero(modulus, valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsNotModZero(modulus, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotPosition(int index)
|
||||
{
|
||||
return PublishedContent.IsNotPosition(index);
|
||||
}
|
||||
|
||||
public HtmlString IsNotPosition(int index, string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsNotPosition(index, valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsNotPosition(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsNotPosition(index, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsLast()
|
||||
{
|
||||
return PublishedContent.IsLast();
|
||||
}
|
||||
|
||||
public HtmlString IsLast(string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsLast(valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsLast(valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotLast()
|
||||
{
|
||||
return PublishedContent.IsNotLast();
|
||||
}
|
||||
|
||||
public HtmlString IsNotLast(string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsNotLast(valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsNotLast(valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsEven()
|
||||
{
|
||||
return PublishedContent.IsEven();
|
||||
}
|
||||
|
||||
public HtmlString IsEven(string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsEven(valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsEven(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsEven(valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsOdd()
|
||||
{
|
||||
return PublishedContent.IsOdd();
|
||||
}
|
||||
|
||||
public HtmlString IsOdd(string valueIfTrue)
|
||||
{
|
||||
return PublishedContent.IsOdd(valueIfTrue);
|
||||
}
|
||||
|
||||
public HtmlString IsOdd(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return PublishedContent.IsOdd(valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPublishedContent extension methods - IsSomething: equality
|
||||
|
||||
public bool IsEqual(DynamicPublishedContent other)
|
||||
@@ -1209,46 +1029,6 @@ namespace Umbraco.Web.Models
|
||||
return PublishedContent.Down(contentTypeAlias).AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Next()
|
||||
{
|
||||
return PublishedContent.Next().AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Next(int number)
|
||||
{
|
||||
return PublishedContent.Next(number).AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Next(string contentTypeAlias)
|
||||
{
|
||||
return PublishedContent.Next(contentTypeAlias).AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Previous()
|
||||
{
|
||||
return PublishedContent.Previous().AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Previous(int number)
|
||||
{
|
||||
return PublishedContent.Previous(number).AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Previous(string contentTypeAlias)
|
||||
{
|
||||
return PublishedContent.Previous(contentTypeAlias).AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Sibling(int number)
|
||||
{
|
||||
return PublishedContent.Previous(number).AsDynamicOrNull();
|
||||
}
|
||||
|
||||
public DynamicPublishedContent Sibling(string contentTypeAlias)
|
||||
{
|
||||
return PublishedContent.Previous(contentTypeAlias).AsDynamicOrNull();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Parent
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace Umbraco.Web.Models
|
||||
public class DynamicPublishedContentList : DynamicObject, IEnumerable<DynamicPublishedContent>
|
||||
{
|
||||
private readonly List<IPublishedContent> _content;
|
||||
private readonly PublishedContentSet<IPublishedContent> _contentSet;
|
||||
internal readonly List<DynamicPublishedContent> Items;
|
||||
|
||||
#region Constructor
|
||||
@@ -27,22 +26,19 @@ namespace Umbraco.Web.Models
|
||||
public DynamicPublishedContentList()
|
||||
{
|
||||
_content = new List<IPublishedContent>();
|
||||
_contentSet = new PublishedContentSet<IPublishedContent>(_content);
|
||||
Items = new List<DynamicPublishedContent>();
|
||||
}
|
||||
|
||||
public DynamicPublishedContentList(IEnumerable<IPublishedContent> items)
|
||||
{
|
||||
_content = items.ToList();
|
||||
_contentSet = new PublishedContentSet<IPublishedContent>(_content);
|
||||
Items = _contentSet.Select(x => new DynamicPublishedContent(x, this)).ToList();
|
||||
Items = _content.Select(x => new DynamicPublishedContent(x, this)).ToList();
|
||||
}
|
||||
|
||||
public DynamicPublishedContentList(IEnumerable<DynamicPublishedContent> items)
|
||||
{
|
||||
_content = items.Select(x => x.PublishedContent).ToList();
|
||||
_contentSet = new PublishedContentSet<IPublishedContent>(_content);
|
||||
Items = _contentSet.Select(x => new DynamicPublishedContent(x, this)).ToList();
|
||||
Items = _content.Select(x => new DynamicPublishedContent(x, this)).ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -67,10 +63,7 @@ namespace Umbraco.Web.Models
|
||||
{
|
||||
var content = dynamicContent.PublishedContent;
|
||||
_content.Add(content);
|
||||
_contentSet.SourceChanged();
|
||||
|
||||
var setContent = _contentSet.MapContent(content);
|
||||
Items.Add(new DynamicPublishedContent(setContent, this));
|
||||
Items.Add(new DynamicPublishedContent(content, this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -82,7 +75,6 @@ namespace Umbraco.Web.Models
|
||||
if (Items.Contains(dynamicContent) == false) return;
|
||||
Items.Remove(dynamicContent);
|
||||
_content.Remove(dynamicContent.PublishedContent);
|
||||
_contentSet.SourceChanged();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -115,14 +115,6 @@ namespace Umbraco.Web.Models
|
||||
|
||||
public abstract bool IsDraft { get; }
|
||||
|
||||
public int GetIndex()
|
||||
{
|
||||
var index = this.Siblings().FindIndex(x => x.Id == Id);
|
||||
if (index < 0)
|
||||
throw new IndexOutOfRangeException("Could not find content in the content set.");
|
||||
return index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tree
|
||||
@@ -140,16 +132,6 @@ namespace Umbraco.Web.Models
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentSet
|
||||
|
||||
public virtual IEnumerable<IPublishedContent> ContentSet
|
||||
{
|
||||
// the default content set of a content is its siblings
|
||||
get { return this.Siblings(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentType
|
||||
|
||||
public abstract PublishedContentType ContentType { get; }
|
||||
|
||||
@@ -452,28 +452,14 @@ namespace Umbraco.Web
|
||||
|
||||
#endregion
|
||||
|
||||
#region ToContentSet
|
||||
#region ToIndexedArray
|
||||
|
||||
/// <summary>
|
||||
/// Returns the content enumerable as a content set.
|
||||
/// </summary>
|
||||
/// <param name="source">The content enumerable.</param>
|
||||
/// <returns>A content set wrapping the content enumerable.</returns>
|
||||
public static PublishedContentSet<T> ToContentSet<T>(this IEnumerable<T> source)
|
||||
where T : class, IPublishedContent
|
||||
public static IndexedArrayItem<TContent>[] ToIndexedArray<TContent>(this IEnumerable<TContent> source)
|
||||
where TContent : class, IPublishedContent
|
||||
{
|
||||
return new PublishedContentSet<T>(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ordered content enumerable as an ordered content set.
|
||||
/// </summary>
|
||||
/// <param name="source">The ordered content enumerable.</param>
|
||||
/// <returns>A ordered content set wrapping the ordered content enumerable.</returns>
|
||||
public static PublishedContentOrderedSet<T> ToContentSet<T>(this IOrderedEnumerable<T> source)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return new PublishedContentOrderedSet<T>(source);
|
||||
var set = source.Select((content, index) => new IndexedArrayItem<TContent>(content, index)).ToArray();
|
||||
foreach (var setItem in set) setItem.TotalCount = set.Length;
|
||||
return set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -552,28 +538,6 @@ namespace Umbraco.Web
|
||||
|
||||
#endregion
|
||||
|
||||
#region ContentSet
|
||||
|
||||
public static int Position(this IPublishedContent content)
|
||||
{
|
||||
return content.GetIndex();
|
||||
}
|
||||
|
||||
public static int Index(this IPublishedContent content)
|
||||
{
|
||||
return content.GetIndex();
|
||||
}
|
||||
|
||||
private static int GetIndex(this IPublishedContent content, IEnumerable<IPublishedContent> set)
|
||||
{
|
||||
var index = set.FindIndex(n => n.Id == content.Id);
|
||||
if (index < 0)
|
||||
throw new IndexOutOfRangeException("Could not find content in the content set.");
|
||||
return index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsSomething: misc.
|
||||
|
||||
/// <summary>
|
||||
@@ -646,160 +610,6 @@ namespace Umbraco.Web
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsSomething: position in set
|
||||
|
||||
public static bool IsFirst(this IPublishedContent content)
|
||||
{
|
||||
return content.GetIndex() == 0;
|
||||
}
|
||||
|
||||
public static HtmlString IsFirst(this IPublishedContent content, string valueIfTrue)
|
||||
{
|
||||
return content.IsFirst(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsFirst(this IPublishedContent content, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsFirst() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsNotFirst(this IPublishedContent content)
|
||||
{
|
||||
return content.IsFirst() == false;
|
||||
}
|
||||
|
||||
public static HtmlString IsNotFirst(this IPublishedContent content, string valueIfTrue)
|
||||
{
|
||||
return content.IsNotFirst(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsNotFirst(this IPublishedContent content, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsNotFirst() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsPosition(this IPublishedContent content, int index)
|
||||
{
|
||||
return content.GetIndex() == index;
|
||||
}
|
||||
|
||||
public static HtmlString IsPosition(this IPublishedContent content, int index, string valueIfTrue)
|
||||
{
|
||||
return content.IsPosition(index, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsPosition(this IPublishedContent content, int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsPosition(index) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsModZero(this IPublishedContent content, int modulus)
|
||||
{
|
||||
return content.GetIndex() % modulus == 0;
|
||||
}
|
||||
|
||||
public static HtmlString IsModZero(this IPublishedContent content, int modulus, string valueIfTrue)
|
||||
{
|
||||
return content.IsModZero(modulus, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsModZero(this IPublishedContent content, int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsModZero(modulus) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsNotModZero(this IPublishedContent content, int modulus)
|
||||
{
|
||||
return content.IsModZero(modulus) == false;
|
||||
}
|
||||
|
||||
public static HtmlString IsNotModZero(this IPublishedContent content, int modulus, string valueIfTrue)
|
||||
{
|
||||
return content.IsNotModZero(modulus, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsNotModZero(this IPublishedContent content, int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsNotModZero(modulus) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsNotPosition(this IPublishedContent content, int index)
|
||||
{
|
||||
return content.IsPosition(index) == false;
|
||||
}
|
||||
|
||||
public static HtmlString IsNotPosition(this IPublishedContent content, int index, string valueIfTrue)
|
||||
{
|
||||
return content.IsNotPosition(index, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsNotPosition(this IPublishedContent content, int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsNotPosition(index) ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsLast(this IPublishedContent content)
|
||||
{
|
||||
return content.GetIndex() == content.ContentSet.Count() - 1;
|
||||
}
|
||||
|
||||
public static HtmlString IsLast(this IPublishedContent content, string valueIfTrue)
|
||||
{
|
||||
return content.IsLast(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsLast(this IPublishedContent content, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsLast() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsNotLast(this IPublishedContent content)
|
||||
{
|
||||
return content.IsLast() == false;
|
||||
}
|
||||
|
||||
public static HtmlString IsNotLast(this IPublishedContent content, string valueIfTrue)
|
||||
{
|
||||
return content.IsNotLast(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsNotLast(this IPublishedContent content, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsNotLast() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsEven(this IPublishedContent content)
|
||||
{
|
||||
return content.GetIndex() % 2 == 0;
|
||||
}
|
||||
|
||||
public static HtmlString IsEven(this IPublishedContent content, string valueIfTrue)
|
||||
{
|
||||
return content.IsEven(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsEven(this IPublishedContent content, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsEven() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
public static bool IsOdd(this IPublishedContent content)
|
||||
{
|
||||
return content.GetIndex() % 2 == 1;
|
||||
}
|
||||
|
||||
public static HtmlString IsOdd(this IPublishedContent content, string valueIfTrue)
|
||||
{
|
||||
return content.IsOdd(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
public static HtmlString IsOdd(this IPublishedContent content, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsOdd() ? valueIfTrue : valueIfFalse);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsSomething: equality
|
||||
|
||||
public static bool IsEqual(this IPublishedContent content, IPublishedContent other)
|
||||
@@ -1440,250 +1250,6 @@ namespace Umbraco.Web
|
||||
return content.Descendant(contentTypeAlias);
|
||||
}
|
||||
|
||||
// next pseudo-axe ~ following within the content set
|
||||
// bogus, kept for backward compatibility but we should get rid of it
|
||||
|
||||
public static IPublishedContent Next(this IPublishedContent content)
|
||||
{
|
||||
return content.ContentSet.ElementAtOrDefault(content.GetIndex() + 1);
|
||||
}
|
||||
|
||||
public static IPublishedContent Next(this IPublishedContent current, Func<IPublishedContent, bool> func) {
|
||||
IPublishedContent next = current.Next();
|
||||
while (next != null) {
|
||||
if (func(next)) return next;
|
||||
next = next.Next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IPublishedContent Next(this IPublishedContent content, int number)
|
||||
{
|
||||
if (number < 0)
|
||||
throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero.");
|
||||
return number == 0 ? content : content.ContentSet.ElementAtOrDefault(content.GetIndex() + number);
|
||||
}
|
||||
|
||||
public static IPublishedContent Next(this IPublishedContent content, string contentTypeAlias)
|
||||
{
|
||||
return content.Next(contentTypeAlias, false);
|
||||
}
|
||||
|
||||
public static IPublishedContent Next(this IPublishedContent content, string contentTypeAlias, bool wrap)
|
||||
{
|
||||
return content.Next(content.ContentSet, x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap);
|
||||
}
|
||||
|
||||
public static T Next<T>(this IPublishedContent content)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.Next<T>(false);
|
||||
}
|
||||
|
||||
public static T Next<T>(this IPublishedContent content, bool wrap)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.Next(content.ContentSet, x => x is T, wrap) as T;
|
||||
}
|
||||
|
||||
static IPublishedContent Next(this IPublishedContent content, IEnumerable<IPublishedContent> axis, Func<IPublishedContent, bool> predicate, bool wrap)
|
||||
{
|
||||
var b4 = true;
|
||||
IPublishedContent wrapped = null;
|
||||
foreach (var c in axis)
|
||||
{
|
||||
if (b4)
|
||||
{
|
||||
if (c.Id == content.Id)
|
||||
b4 = false;
|
||||
else if (wrap && wrapped == null && predicate(c))
|
||||
wrapped = c;
|
||||
continue;
|
||||
}
|
||||
if (predicate(c))
|
||||
return c;
|
||||
}
|
||||
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
// previous pseudo-axe ~ preceding within the content set
|
||||
// bogus, kept for backward compatibility but we should get rid of it
|
||||
|
||||
public static IPublishedContent Previous(this IPublishedContent content)
|
||||
{
|
||||
return content.ContentSet.ElementAtOrDefault(content.GetIndex() - 1);
|
||||
}
|
||||
|
||||
public static IPublishedContent Previous(this IPublishedContent current, Func<IPublishedContent, bool> func) {
|
||||
IPublishedContent prev = current.Previous();
|
||||
while (prev != null) {
|
||||
if (func(prev)) return prev;
|
||||
prev = prev.Previous();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IPublishedContent Previous(this IPublishedContent content, int number)
|
||||
{
|
||||
if (number < 0)
|
||||
throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero.");
|
||||
return number == 0 ? content : content.ContentSet.ElementAtOrDefault(content.GetIndex() - number);
|
||||
}
|
||||
|
||||
public static IPublishedContent Previous(this IPublishedContent content, string contentTypeAlias)
|
||||
{
|
||||
return content.Previous(contentTypeAlias, false);
|
||||
}
|
||||
|
||||
public static IPublishedContent Previous(this IPublishedContent content, string contentTypeAlias, bool wrap)
|
||||
{
|
||||
return content.Next(content.ContentSet.Reverse(), x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap);
|
||||
}
|
||||
|
||||
public static T Previous<T>(this IPublishedContent content)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.Previous<T>(false);
|
||||
}
|
||||
|
||||
public static T Previous<T>(this IPublishedContent content, bool wrap)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.Next(content.ContentSet.Reverse(), x => x is T, wrap) as T;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
[Obsolete("Obsolete, use FollowingSibling or PrecedingSibling instead.")]
|
||||
public static IPublishedContent Sibling(this IPublishedContent content, int number)
|
||||
{
|
||||
if (number < 0)
|
||||
throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero.");
|
||||
number += 1; // legacy is zero-based
|
||||
return content.FollowingSibling(number);
|
||||
}
|
||||
|
||||
// contentTypeAlias is case-insensitive
|
||||
[Obsolete("Obsolete, use FollowingSibling or PrecedingSibling instead.")]
|
||||
public static IPublishedContent Sibling(this IPublishedContent content, string contentTypeAlias)
|
||||
{
|
||||
// note: the original implementation seems to loop on all siblings
|
||||
// ie if it reaches the end of the set, it starts again at the beginning.
|
||||
// so here we wrap, although it's not consistent... but anyway those
|
||||
// methods should be obsoleted.
|
||||
|
||||
return content.FollowingSibling(contentTypeAlias, true);
|
||||
}
|
||||
|
||||
// following-sibling, preceding-sibling axes
|
||||
|
||||
public static IPublishedContent FollowingSibling(this IPublishedContent content)
|
||||
{
|
||||
return content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) + 1);
|
||||
}
|
||||
|
||||
public static IPublishedContent FollowingSibling(this IPublishedContent content, int number)
|
||||
{
|
||||
if (number < 0)
|
||||
throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero.");
|
||||
return number == 0 ? content : content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) + number);
|
||||
}
|
||||
|
||||
// contentTypeAlias is case-insensitive
|
||||
public static IPublishedContent FollowingSibling(this IPublishedContent content, string contentTypeAlias)
|
||||
{
|
||||
return content.FollowingSibling(contentTypeAlias, false);
|
||||
}
|
||||
|
||||
// contentTypeAlias is case-insensitive
|
||||
// note: not sure that one makes a lot of sense but it is here for backward compatibility
|
||||
public static IPublishedContent FollowingSibling(this IPublishedContent content, string contentTypeAlias, bool wrap)
|
||||
{
|
||||
return content.Next(content.Siblings(), x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap);
|
||||
}
|
||||
|
||||
public static T FollowingSibling<T>(this IPublishedContent content)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.FollowingSibling<T>(false);
|
||||
}
|
||||
|
||||
public static T FollowingSibling<T>(this IPublishedContent content, bool wrap)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.Next(content.Siblings(), x => x is T, wrap) as T;
|
||||
}
|
||||
|
||||
public static IPublishedContent PrecedingSibling(this IPublishedContent content)
|
||||
{
|
||||
return content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) - 1);
|
||||
}
|
||||
|
||||
public static IPublishedContent PrecedingSibling(this IPublishedContent content, int number)
|
||||
{
|
||||
if (number < 0)
|
||||
throw new ArgumentOutOfRangeException("number", "Must be greater than, or equal to, zero.");
|
||||
return number == 0 ? content : content.Siblings().ElementAtOrDefault(content.GetIndex(content.Siblings()) - number);
|
||||
}
|
||||
|
||||
// contentTypeAlias is case-insensitive
|
||||
public static IPublishedContent PrecedingSibling(this IPublishedContent content, string contentTypeAlias)
|
||||
{
|
||||
return content.PrecedingSibling(contentTypeAlias, false);
|
||||
}
|
||||
|
||||
// contentTypeAlias is case-insensitive
|
||||
// note: not sure that one makes a lot of sense but it is here for backward compatibility
|
||||
public static IPublishedContent PrecedingSibling(this IPublishedContent content, string contentTypeAlias, bool wrap)
|
||||
{
|
||||
return content.Next(content.Siblings().Reverse(), x => x.DocumentTypeAlias.InvariantEquals(contentTypeAlias), wrap);
|
||||
}
|
||||
|
||||
public static T PrecedingSibling<T>(this IPublishedContent content)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.PrecedingSibling<T>(false);
|
||||
}
|
||||
|
||||
public static T PrecedingSibling<T>(this IPublishedContent content, bool wrap)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.Next(content.Siblings().Reverse(), x => x is T, wrap) as T;
|
||||
}
|
||||
|
||||
// following, preceding axes - NOT IMPLEMENTED
|
||||
|
||||
// utilities
|
||||
|
||||
public static IEnumerable<IPublishedContent> Siblings(this IPublishedContent content)
|
||||
{
|
||||
// content.Parent, content.Children and cache.GetAtRoot() should be fast enough,
|
||||
// or cached by the content cache, so that we don't have to implement cache here.
|
||||
|
||||
// returns the true tree siblings, even if the content is in a set
|
||||
// get the root docs if parent is null
|
||||
|
||||
// note: I don't like having to refer to the "current" content cache here, but
|
||||
// what else? would need root content to have a special, non-null but hidden,
|
||||
// parent...
|
||||
|
||||
|
||||
|
||||
var siblings = content.Parent == null
|
||||
? content.ItemType == PublishedItemType.Media ? UmbracoContext.Current.MediaCache.GetAtRoot() : UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
: content.Parent.Children;
|
||||
|
||||
// make sure we run it once
|
||||
return siblings.ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<T> Siblings<T>(this IPublishedContent content)
|
||||
where T : class, IPublishedContent
|
||||
{
|
||||
return content.Siblings().OfType<T>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Axes: parent
|
||||
|
||||
Reference in New Issue
Block a user