From 2245c88396afe0aeef0f8b58efb6b369157c25bb Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 16 Apr 2013 12:29:58 -0200 Subject: [PATCH] U4-2117 - fix Ancestor- vs AncestorsOrSelf inconsistencies --- src/Umbraco.Web/PublishedContentExtensions.cs | 208 ++++++++---------- .../RazorDynamicNode/DynamicNode.cs | 117 +++++----- 2 files changed, 144 insertions(+), 181 deletions(-) diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 1510b33ba1..1eb4c9dfbb 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -785,128 +785,100 @@ namespace Umbraco.Web #endregion - #region Ancestors + #region Ancestors - public static IEnumerable Ancestors(this IPublishedContent content, int level) - { - return content.Ancestors(n => n.Level <= level); - } - public static IEnumerable Ancestors(this IPublishedContent content, string nodeTypeAlias) - { - return content.Ancestors(n => n.DocumentTypeAlias == nodeTypeAlias); - } - public static IEnumerable Ancestors(this IPublishedContent content) - { - return content.Ancestors(n => true); - } - internal static IEnumerable Ancestors(this IPublishedContent content, Func func) - { - var ancestorList = new List(); - var node = content; - while (node != null) - { - if (node.Level == 1) break; - var parent = node.Parent; - if (parent == null) - { - break; - } - if (content != parent) - { - node = parent; - if (func(node)) - { - ancestorList.Add(node); - } - } - else - { - break; - } - } - ancestorList.Reverse(); - return ancestorList; - } + public static IEnumerable Ancestors(this IPublishedContent content) + { + return content.AncestorsOrSelf(false, n => true); + } - public static IPublishedContent AncestorOrSelf(this IPublishedContent content) - { - //TODO: Why is this query like this?? - return content.AncestorOrSelf(node => node.Level == 1); - } - public static IPublishedContent AncestorOrSelf(this IPublishedContent content, int level) - { - return content.AncestorOrSelf(node => node.Level == level); - } - public static IPublishedContent AncestorOrSelf(this IPublishedContent content, string nodeTypeAlias) - { - return content.AncestorOrSelf(node => node.DocumentTypeAlias == nodeTypeAlias); - } - internal static IPublishedContent AncestorOrSelf(this IPublishedContent content, Func func) - { - var node = content; - while (node != null) - { - if (func(node)) return node; - var parent = node.Parent; - if (parent == null) - { - return null; - } - if (content != parent) - { - node = parent; - } - else - { - return node; - } - } - return null; - } + public static IEnumerable Ancestors(this IPublishedContent content, int level) + { + return content.AncestorsOrSelf(false, n => n.Level <= level); + } - internal static IEnumerable AncestorsOrSelf(this IPublishedContent content, Func func) - { - var ancestorList = new List(); - var node = content; - ancestorList.Add(node); - while (node != null) - { - if (node.Level == 1) break; - var parent = node.Parent; - if (parent == null) - { - break; - } - if (content != parent) - { - node = parent; - if (func(node)) - { - ancestorList.Add(node); - } - } - else - { - break; - } - } - ancestorList.Reverse(); - return ancestorList; - } - public static IEnumerable AncestorsOrSelf(this IPublishedContent content) - { - return content.AncestorsOrSelf(n => true); - } - public static IEnumerable AncestorsOrSelf(this IPublishedContent content, string nodeTypeAlias) - { - return content.AncestorsOrSelf(n => n.DocumentTypeAlias == nodeTypeAlias); - } - public static IEnumerable AncestorsOrSelf(this IPublishedContent content, int level) - { - return content.AncestorsOrSelf(n => n.Level <= level); - } + public static IEnumerable Ancestors(this IPublishedContent content, string nodeTypeAlias) + { + return content.AncestorsOrSelf(false, n => n.DocumentTypeAlias == nodeTypeAlias); + } - #endregion + public static IEnumerable Ancestors(this IPublishedContent content, Func func) + { + return content.AncestorsOrSelf(false, func); + } + + public static IPublishedContent AncestorOrSelf(this IPublishedContent content) + { + //TODO: Why is this query like this?? + return content.AncestorOrSelf(node => node.Level == 1); + } + + public static IPublishedContent AncestorOrSelf(this IPublishedContent content, int level) + { + return content.AncestorOrSelf(node => node.Level == level); + } + + public static IPublishedContent AncestorOrSelf(this IPublishedContent content, string nodeTypeAlias) + { + return content.AncestorOrSelf(node => node.DocumentTypeAlias == nodeTypeAlias); + } + + internal static IPublishedContent AncestorOrSelf(this IPublishedContent content, Func func) + { + if (func(content)) + return content; + + while (content.Level > 1) // while we have a parent, consider the parent + { + content = content.Parent; + + if (func(content)) + return content; + } + + return null; + } + + public static IEnumerable AncestorsOrSelf(this IPublishedContent content) + { + return content.AncestorsOrSelf(true, n => true); + } + + public static IEnumerable AncestorsOrSelf(this IPublishedContent content, int level) + { + return content.AncestorsOrSelf(true, n => n.Level <= level); + } + + public static IEnumerable AncestorsOrSelf(this IPublishedContent content, string nodeTypeAlias) + { + return content.AncestorsOrSelf(true, n => n.DocumentTypeAlias == nodeTypeAlias); + } + + internal static IEnumerable AncestorsOrSelf(this IPublishedContent content, Func func) + { + return content.AncestorsOrSelf(true, func); + } + + internal static IEnumerable AncestorsOrSelf(this IPublishedContent content, bool orSelf, Func func) + { + var ancestors = new List(); + + if (orSelf && func(content)) + ancestors.Add(content); + + while (content.Level > 1) // while we have a parent, consider the parent + { + content = content.Parent; + + if (func(content)) + ancestors.Add(content); + } + + ancestors.Reverse(); + return ancestors; + } + + #endregion #region Descendants public static IEnumerable Descendants(this IPublishedContent content, string nodeTypeAlias) diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs index 8419bdf93f..23385093d8 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs @@ -954,73 +954,61 @@ namespace umbraco.MacroEngines } public DynamicNode AncestorOrSelf(Func func) { - var node = this; - while (node != null) + if (func(this)) return this; + + var content = this; + while (content.Level > 1) // while we have a parent, consider the parent { - if (func(node)) return node; - DynamicNode parent = node.Parent; - if (parent != null) - { - if (this != parent) - { - node = parent; - } - else - { - return node; - } - } - else - { - return null; - } + // see note in .Parent - strange things can happen + var parent = content.Parent; + if (parent == content) return null; + content = parent; + + if (func(content)) + return content; } - return node; - } - public DynamicNodeList AncestorsOrSelf(Func func) - { - List ancestorList = new List(); - var node = this; - ancestorList.Add(node); - while (node != null) - { - if (node.Level == 1) break; - DynamicNode parent = node.Parent; - if (parent != null) - { - if (this != parent) - { - node = parent; - if (func(node)) - { - ancestorList.Add(node); - } - } - else - { - break; - } - } - else - { - break; - } - } - ancestorList.Reverse(); - return new DynamicNodeList(ancestorList); + + return null; } + public DynamicNodeList AncestorsOrSelf() { return AncestorsOrSelf(n => true); } - public DynamicNodeList AncestorsOrSelf(string nodeTypeAlias) - { - return AncestorsOrSelf(n => n.NodeTypeAlias == nodeTypeAlias); - } + public DynamicNodeList AncestorsOrSelf(int level) { return AncestorsOrSelf(n => n.Level <= level); } + + public DynamicNodeList AncestorsOrSelf(string nodeTypeAlias) + { + return AncestorsOrSelf(n => n.NodeTypeAlias == nodeTypeAlias); + } + + public DynamicNodeList AncestorsOrSelf(Func func) + { + var ancestors = new List(); + + if (func(this)) + ancestors.Add(this); + + var content = this; + while (content.Level > 1) // while we have a parent, consider the parent + { + // see note in .Parent - strange things can happen + var parent = content.Parent; + if (parent == content) break; + content = parent; + + if (func(content)) + ancestors.Add(content); + } + + ancestors.Reverse(); + return new DynamicNodeList(ancestors); + } + public DynamicNodeList Descendants(string nodeTypeAlias) { return Descendants(p => p.NodeTypeAlias == nodeTypeAlias); @@ -1109,22 +1097,25 @@ namespace umbraco.MacroEngines ancestorList.Reverse(); return new DynamicNodeList(ancestorList); } + public DynamicNode Parent { get { if (n == null) - { return null; - } + if (n.Parent != null) - { return new DynamicNode(n.Parent); - } + + // DynamicBackingItem.Id will return zero if IsNull else it should return non-zero; + // it's IsNull when it's neither content nor media - which might happen when created + // an invalid identifier. And then it's a "non-existing" node which is its own parent. + // Does not make much sense, but, hey... + if (n != null && n.Id == 0) - { - return this; - } + return this; // ouch + return null; } }