diff options
Diffstat (limited to 'Xamarin.Forms.Xaml/XamlNode.cs')
-rw-r--r-- | Xamarin.Forms.Xaml/XamlNode.cs | 123 |
1 files changed, 73 insertions, 50 deletions
diff --git a/Xamarin.Forms.Xaml/XamlNode.cs b/Xamarin.Forms.Xaml/XamlNode.cs index eccf2075..752f3845 100644 --- a/Xamarin.Forms.Xaml/XamlNode.cs +++ b/Xamarin.Forms.Xaml/XamlNode.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -6,30 +7,36 @@ using Xamarin.Forms.Internals; namespace Xamarin.Forms.Xaml { - interface INode + internal interface INode { List<string> IgnorablePrefixes { get; set; } + IXmlNamespaceResolver NamespaceResolver { get; } + INode Parent { get; set; } void Accept(IXamlNodeVisitor visitor, INode parentNode); INode Clone(); } - interface IValueNode : INode + internal interface IValueNode : INode { } - interface IElementNode : INode, IListNode + internal interface IElementNode : INode, IListNode { Dictionary<XmlName, INode> Properties { get; } + List<XmlName> SkipProperties { get; } + INameScope Namescope { get; } + XmlType XmlType { get; } + string NamespaceURI { get; } } - interface IListNode : INode + internal interface IListNode : INode { List<INode> CollectionItems { get; } } @@ -49,7 +56,7 @@ namespace Xamarin.Forms.Xaml public IList<XmlType> TypeArguments { get; } } - abstract class BaseNode : IXmlLineInfo, INode + internal abstract class BaseNode : IXmlLineInfo, INode { protected BaseNode(IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) { @@ -59,19 +66,27 @@ namespace Xamarin.Forms.Xaml } public IXmlNamespaceResolver NamespaceResolver { get; } + + public abstract void Accept(IXamlNodeVisitor visitor, INode parentNode); + public INode Parent { get; set; } + public List<string> IgnorablePrefixes { get; set; } + + public bool HasLineInfo() + { + return LineNumber >= 0 && LinePosition >= 0; + } + public int LineNumber { get; set; } - public int LinePosition { get; set; } - public bool HasLineInfo() => LineNumber >= 0 && LinePosition >= 0; + public int LinePosition { get; set; } - public abstract void Accept(IXamlNodeVisitor visitor, INode parentNode); public abstract INode Clone(); } [DebuggerDisplay("{Value}")] - class ValueNode : BaseNode, IValueNode + internal class ValueNode : BaseNode, IValueNode { public ValueNode(object value, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) : base(namespaceResolver, linenumber, lineposition) @@ -86,15 +101,19 @@ namespace Xamarin.Forms.Xaml visitor.Visit(this, parentNode); } - public override INode Clone() => new ValueNode(Value, NamespaceResolver, LineNumber, LinePosition) { - IgnorablePrefixes = IgnorablePrefixes - }; + public override INode Clone() + { + return new ValueNode(Value, NamespaceResolver, LineNumber, LinePosition) { + IgnorablePrefixes = IgnorablePrefixes + }; + } } [DebuggerDisplay("{MarkupString}")] - class MarkupNode : BaseNode, IValueNode + internal class MarkupNode : BaseNode, IValueNode { - public MarkupNode(string markupString, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) + public MarkupNode(string markupString, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, + int lineposition = -1) : base(namespaceResolver, linenumber, lineposition) { MarkupString = markupString; @@ -107,13 +126,15 @@ namespace Xamarin.Forms.Xaml visitor.Visit(this, parentNode); } - public override INode Clone() => new MarkupNode(MarkupString, NamespaceResolver, LineNumber, LinePosition) { - IgnorablePrefixes = IgnorablePrefixes - }; + public override INode Clone() + { + return new MarkupNode(MarkupString, NamespaceResolver, LineNumber, LinePosition) { + IgnorablePrefixes = IgnorablePrefixes + }; + } } - [DebuggerDisplay("{XmlType.Name}")] - class ElementNode : BaseNode, IValueNode, IElementNode + internal class ElementNode : BaseNode, IValueNode, IElementNode { public ElementNode(XmlType type, string namespaceURI, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) @@ -127,48 +148,48 @@ namespace Xamarin.Forms.Xaml } public Dictionary<XmlName, INode> Properties { get; } + public List<XmlName> SkipProperties { get; } + public List<INode> CollectionItems { get; } + public XmlType XmlType { get; } + public string NamespaceURI { get; } + public INameScope Namescope { get; set; } public override void Accept(IXamlNodeVisitor visitor, INode parentNode) { - if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.TopDown) + if (!visitor.VisitChildrenFirst) visitor.Visit(this, parentNode); - - if (!SkipChildren(visitor, parentNode)) { + if ((!visitor.StopOnDataTemplate || !IsDataTemplate(this, parentNode)) && + (!visitor.StopOnResourceDictionary || !IsResourceDictionary(this, parentNode))) + { foreach (var node in Properties.Values.ToList()) node.Accept(visitor, this); foreach (var node in CollectionItems) node.Accept(visitor, this); } - - if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.BottomUp) + if (visitor.VisitChildrenFirst) visitor.Visit(this, parentNode); - } - bool IsDataTemplate(INode parentNode) + internal static bool IsDataTemplate(INode node, INode parentNode) { var parentElement = parentNode as IElementNode; INode createContent; - if (parentElement != null && - parentElement.Properties.TryGetValue(XmlName._CreateContent, out createContent) && - createContent == this) + if (parentElement != null && parentElement.Properties.TryGetValue(XmlName._CreateContent, out createContent) && + createContent == node) return true; return false; } - bool IsResourceDictionary() => XmlType.Name == "ResourceDictionary"; - - protected bool SkipChildren(IXamlNodeVisitor visitor, INode parentNode) => - (visitor.StopOnDataTemplate && IsDataTemplate(parentNode)) || - (visitor.StopOnResourceDictionary && IsResourceDictionary()); - - protected bool SkipVisitNode(IXamlNodeVisitor visitor, INode parentNode) => - !visitor.VisitNodeOnDataTemplate && IsDataTemplate(parentNode); + internal static bool IsResourceDictionary(INode node, INode parentNode) + { + var enode = node as ElementNode; + return enode.XmlType.Name == "ResourceDictionary"; + } public override INode Clone() { @@ -185,7 +206,7 @@ namespace Xamarin.Forms.Xaml } } - abstract class RootNode : ElementNode + internal abstract class RootNode : ElementNode { protected RootNode(XmlType xmlType, IXmlNamespaceResolver nsResolver) : base(xmlType, xmlType.NamespaceUri, nsResolver) { @@ -193,39 +214,40 @@ namespace Xamarin.Forms.Xaml public override void Accept(IXamlNodeVisitor visitor, INode parentNode) { - if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.TopDown) + if (!visitor.VisitChildrenFirst) visitor.Visit(this, parentNode); - - if (!SkipChildren(visitor, parentNode)) { + if ((!visitor.StopOnDataTemplate || !IsDataTemplate(this, parentNode)) && + (!visitor.StopOnResourceDictionary || !IsResourceDictionary(this, parentNode))) + { foreach (var node in Properties.Values.ToList()) node.Accept(visitor, this); foreach (var node in CollectionItems) node.Accept(visitor, this); } - - if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.BottomUp) + if (visitor.VisitChildrenFirst) visitor.Visit(this, parentNode); } } - class ListNode : BaseNode, IListNode, IValueNode + internal class ListNode : BaseNode, IListNode, IValueNode { - public ListNode(IList<INode> nodes, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) - : base(namespaceResolver, linenumber, lineposition) + public ListNode(IList<INode> nodes, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, + int lineposition = -1) : base(namespaceResolver, linenumber, lineposition) { CollectionItems = nodes.ToList(); } public XmlName XmlName { get; set; } + public List<INode> CollectionItems { get; set; } public override void Accept(IXamlNodeVisitor visitor, INode parentNode) { - if (visitor.VisitingMode == TreeVisitingMode.TopDown) + if (!visitor.VisitChildrenFirst) visitor.Visit(this, parentNode); foreach (var node in CollectionItems) node.Accept(visitor, this); - if (visitor.VisitingMode == TreeVisitingMode.BottomUp) + if (visitor.VisitChildrenFirst) visitor.Visit(this, parentNode); } @@ -240,11 +262,12 @@ namespace Xamarin.Forms.Xaml } } - static class INodeExtensions + internal static class INodeExtensions { public static bool SkipPrefix(this INode node, string prefix) { - do { + do + { if (node.IgnorablePrefixes != null && node.IgnorablePrefixes.Contains(prefix)) return true; node = node.Parent; |