Files
Umbraco-CMS/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeWalker.cs
agrath@gmail.com 71c5e35443 Added DynamicNodeWalker and implementation on DynamicNode and DynamicNodeList
DynamicNodeWalker is our secret weapon in the fight against the Rebel XSLT Alliance
Navigate nodes by calling Up(), Down(), Next() and Previous() on them
Next(1) will jump two items along within the current list, whereas Next() will walk by one within the list
Previous(1) will move two items backwards within the current list
Up() is a special wrapper around .Parent which has an overload .Up(int) to replace @Model.Parent.Parent.Parent... [.Up(2)]
Down() will take you to the first Child item and is equivilent to .Children.First(), use .Down(1) to replace .Children.First().Children
If one of the NodeWalker functions fails to find a node at the requested position, it will return null
2011-02-24 17:19:50 -13:00

99 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using umbraco.interfaces;
namespace umbraco.MacroEngines
{
public static class DynamicNodeWalker
{
public static DynamicNode Up(this DynamicNode context)
{
return context.Up(0);
}
public static DynamicNode Up(this DynamicNode context, int number)
{
if (number == 0)
{
return context.Parent;
}
else
{
while ((context = context.Parent) != null && --number >= 0) ;
return context;
}
}
public static DynamicNode Down(this DynamicNode context)
{
return context.Down(0);
}
public static DynamicNode Down(this DynamicNode context, int number)
{
DynamicNodeList children = new DynamicNodeList(context.ChildrenAsList);
if (number == 0)
{
return children.Items.First();
}
else
{
DynamicNode working = context;
while (number-- >= 0)
{
working = children.Items.First();
children = new DynamicNodeList(working.ChildrenAsList);
}
return working;
}
}
public static DynamicNode Next(this DynamicNode context)
{
return context.Next(0);
}
public static DynamicNode Next(this DynamicNode context, int number)
{
if (context.ownerList != null)
{
List<DynamicNode> container = context.ownerList.Items.ToList();
int currentIndex = container.IndexOf(context);
if (currentIndex != -1)
{
return container.ElementAtOrDefault(currentIndex + (number + 1));
}
else
{
throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", context.Id));
}
}
else
{
throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id));
}
}
public static DynamicNode Previous(this DynamicNode context)
{
return context.Previous(0);
}
public static DynamicNode Previous(this DynamicNode context, int number)
{
if (context.ownerList != null)
{
List<DynamicNode> container = context.ownerList.Items.ToList();
int currentIndex = container.IndexOf(context);
if (currentIndex != -1)
{
return container.ElementAtOrDefault(currentIndex + (number - 1));
}
else
{
throw new IndexOutOfRangeException(string.Format("Node {0} belongs to a DynamicNodeList but could not retrieve the index for it's position in the list", context.Id));
}
}
else
{
throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id));
}
}
}
}