From 03441fab21bd9a22fd3d2cac715ed507c07c1f7d Mon Sep 17 00:00:00 2001 From: "agrath@gmail.com" Date: Sun, 20 Feb 2011 19:55:06 -1300 Subject: [PATCH] Added umbraco.Settings entry for controlling what document element types are parsed as DynamicXml Added documentElement checking to DynamicXml convert for DynamicNode property get to solve a potential issue with XHTML RTEs Fixed issue with calling @Model.Children.First() in testing (null Children in testing) Put some commented placeholder code in .XPath->DynamicNodeList inside DynamicNode.cs for future return of DynamicXml if not valid List --- .../config/umbracoSettings.config | 10 +++++ umbraco.MacroEngines.Juno/DynamicNode.cs | 43 +++++++++++++++++-- umbraco/businesslogic/UmbracoSettings.cs | 25 +++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/config templates/config/umbracoSettings.config b/config templates/config/umbracoSettings.config index 61409e1a08..5c75d74fa7 100644 --- a/config templates/config/umbracoSettings.config +++ b/config templates/config/umbracoSettings.config @@ -103,6 +103,16 @@ true + + + + + + p + div + + + diff --git a/umbraco.MacroEngines.Juno/DynamicNode.cs b/umbraco.MacroEngines.Juno/DynamicNode.cs index bcd0b5d1e6..73eac7074e 100644 --- a/umbraco.MacroEngines.Juno/DynamicNode.cs +++ b/umbraco.MacroEngines.Juno/DynamicNode.cs @@ -62,6 +62,12 @@ namespace umbraco.MacroEngines { get { + List children = n.ChildrenAsList; + //testing + if (children.Count == 0 && n.Id == 0) + { + return new DynamicNodeList(new List { this.n }); + } return new DynamicNodeList(n.ChildrenAsList); } } @@ -102,6 +108,16 @@ namespace umbraco.MacroEngines } catch (Exception) { } //swallow the exceptions - the returned nodes might not be full nodes, e.g. property } + //Wanted to do this, but because we return DynamicNodeList here, the only + //common parent class is DynamicObject + //maybe some future refactoring will solve this? + //if (nodeFactoryNodeList.Count == 0) + //{ + // //if the xpath resulted in a node set, but none of them could be converted to NodeFactory.Node + // XElement xElement = XElement.Parse(node.OuterXml); + // //return + // return new DynamicXml(xElement); + //} //convert the NodeFactory nodelist to IEnumerable and return it as a DynamicNodeList return new DynamicNodeList(nodeFactoryNodeList.ConvertAll(nfNode => new DynamicNode(nfNode))); } @@ -245,12 +261,33 @@ namespace umbraco.MacroEngines //a really rough check to see if this may be valid xml if (sResult.StartsWith("<") && sResult.EndsWith(">") && sResult.Contains("/")) { - XElement e = XElement.Parse(sResult, LoadOptions.None); - if (e != null) + try { - result = new DynamicXml(e); + XElement e = XElement.Parse(sResult, LoadOptions.None); + if (e != null) + { + //check that the document element is not one of the disallowed elements + //allows RTE to still return as html if it's valid xhtml + string documentElement = e.Name.LocalName; + if (!UmbracoSettings.NotDynamicXmlDocumentElements.Any(tag => + string.Equals(tag, documentElement, StringComparison.CurrentCultureIgnoreCase))) + { + result = new DynamicXml(e); + return true; + } + else + { + //we will just return this as a string + return true; + } + } + } + catch (Exception) + { + //we will just return this as a string return true; } + } } diff --git a/umbraco/businesslogic/UmbracoSettings.cs b/umbraco/businesslogic/UmbracoSettings.cs index ca66c7f588..81a79bc676 100644 --- a/umbraco/businesslogic/UmbracoSettings.cs +++ b/umbraco/businesslogic/UmbracoSettings.cs @@ -4,6 +4,7 @@ using System.Web; using System.Web.Caching; using System.Xml; using umbraco.BusinessLogic; +using System.Collections.Generic; namespace umbraco { @@ -353,6 +354,30 @@ namespace umbraco } } + /// + /// razor DynamicNode typecasting detects XML and returns DynamicXml - Root elements that won't convert to DynamicXml + /// + public static List NotDynamicXmlDocumentElements + { + get + { + try + { + List items = new List(); + XmlNode root = GetKeyAsNode("/settings/scripting/razor/notDynamicXmlDocumentElements"); + foreach (XmlNode element in root.SelectNodes(".//element")) + { + items.Add(element.InnerText); + } + return items; + } + catch + { + return new List() { "p", "div" }; + } + } + } + /// /// Gets a value indicating whether umbraco will clone XML cache on publish. ///