From a02aca0f628bda00d721552d74a6e92a8e61b9d3 Mon Sep 17 00:00:00 2001 From: "agrath@gmail.com" Date: Tue, 8 Mar 2011 19:42:59 -1300 Subject: [PATCH] Added support to DynamicNodeWalker for finding nodes that are Up/Down/Previous/Next by NodeTypeAlias Up and down are similar to Ancestors(string nodeTypeAlias)/Descendants(string nodeTypeAlias) but return the first match --- .../RazorDynamicNode/DynamicNode.cs | 18 +++- .../RazorDynamicNode/DynamicNodeWalker.cs | 87 +++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs index 1002bbc40a..4f61ce4484 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs @@ -69,6 +69,10 @@ namespace umbraco.MacroEngines { return DynamicNodeWalker.Up(this, number); } + public DynamicNode Up(string nodeTypeAlias) + { + return DynamicNodeWalker.Up(this, nodeTypeAlias); + } public DynamicNode Down() { return DynamicNodeWalker.Down(this); @@ -77,6 +81,10 @@ namespace umbraco.MacroEngines { return DynamicNodeWalker.Down(this, number); } + public DynamicNode Down(string nodeTypeAlias) + { + return DynamicNodeWalker.Down(this, nodeTypeAlias); + } public DynamicNode Next() { return DynamicNodeWalker.Next(this); @@ -85,6 +93,11 @@ namespace umbraco.MacroEngines { return DynamicNodeWalker.Next(this, number); } + public DynamicNode Next(string nodeTypeAlias) + { + return DynamicNodeWalker.Next(this, nodeTypeAlias); + } + public DynamicNode Previous() { return DynamicNodeWalker.Previous(this); @@ -93,7 +106,10 @@ namespace umbraco.MacroEngines { return DynamicNodeWalker.Previous(this, number); } - + public DynamicNode Previous(string nodeTypeAlias) + { + return DynamicNodeWalker.Previous(this, nodeTypeAlias); + } public DynamicNodeList GetChildrenAsList { get diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeWalker.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeWalker.cs index b3bff4e7db..c8a557e7b5 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeWalker.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeWalker.cs @@ -24,6 +24,19 @@ namespace umbraco.MacroEngines return context; } } + public static DynamicNode Up(this DynamicNode context, string nodeTypeAlias) + { + if (string.IsNullOrEmpty(nodeTypeAlias)) + { + return context.Parent; + } + else + { + while ((context = context.Parent) != null && context.NodeTypeAlias != nodeTypeAlias) ; + return context; + } + } + public static DynamicNode Down(this DynamicNode context) { return context.Down(0); @@ -46,6 +59,19 @@ namespace umbraco.MacroEngines return working; } } + public static DynamicNode Down(this DynamicNode context, string nodeTypeAlias) + { + + if (string.IsNullOrEmpty(nodeTypeAlias)) + { + DynamicNodeList children = new DynamicNodeList(context.ChildrenAsList); + return children.Items.First(); + } + else + { + return context.Descendants(nodeTypeAlias).Items.FirstOrDefault(); + } + } public static DynamicNode Next(this DynamicNode context) { return context.Next(0); @@ -75,6 +101,36 @@ namespace umbraco.MacroEngines throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id)); } } + public static DynamicNode Next(this DynamicNode context, string nodeTypeAlias) + { + if (context.ownerList == null && context.Parent != null) + { + var list = context.Parent.ChildrenAsList.ConvertAll(n => new DynamicNode(n)); + context.ownerList = new DynamicNodeList(list); + } + if (context.ownerList != null) + { + List container = context.ownerList.Items.ToList(); + int currentIndex = container.FindIndex(n => n.Id == context.Id); + if (currentIndex != -1) + { + int newIndex = container.FindIndex(currentIndex, n => n.NodeTypeAlias == nodeTypeAlias); + if (newIndex != -1) + { + return container.ElementAt(newIndex); + } + return null; + } + 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); @@ -104,5 +160,36 @@ namespace umbraco.MacroEngines 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, string nodeTypeAlias) + { + if (context.ownerList == null && context.Parent != null) + { + var list = context.Parent.ChildrenAsList.ConvertAll(n => new DynamicNode(n)); + context.ownerList = new DynamicNodeList(list); + } + if (context.ownerList != null) + { + List container = context.ownerList.Items.ToList(); + int currentIndex = container.FindIndex(n => n.Id == context.Id); + if (currentIndex != -1) + { + var previousNodes = container.Take(currentIndex).ToList(); + int newIndex = previousNodes.FindIndex(n => n.NodeTypeAlias == nodeTypeAlias); + if (newIndex != -1) + { + return container.ElementAt(newIndex); + } + return null; + } + 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)); + } + } } }