1 using System.Collections.Generic;
2 using System.Diagnostics;
5 using Tizen.NUI.Binding;
6 using Tizen.NUI.Binding.Internals;
8 namespace Tizen.NUI.Xaml
10 internal interface INode
12 List<string> IgnorablePrefixes { get; set; }
14 IXmlNamespaceResolver NamespaceResolver { get; }
16 INode Parent { get; set; }
18 void Accept(IXamlNodeVisitor visitor, INode parentNode);
22 internal interface IValueNode : INode
26 internal interface IElementNode : INode, IListNode
28 Dictionary<XmlName, INode> Properties { get; }
29 List<XmlName> SkipProperties { get; }
30 INameScope Namescope { get; }
31 XmlType XmlType { get; }
32 string NamespaceURI { get; }
35 internal interface IListNode : INode
37 List<INode> CollectionItems { get; }
40 [DebuggerDisplay("{NamespaceUri}:{Name}")]
41 internal class XmlType
43 public XmlType(string namespaceUri, string name, IList<XmlType> typeArguments)
45 NamespaceUri = namespaceUri;
47 TypeArguments = typeArguments;
50 public string NamespaceUri { get; }
51 public string Name { get; }
52 public IList<XmlType> TypeArguments { get; }
55 internal abstract class BaseNode : IXmlLineInfo, INode
57 protected BaseNode(IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1)
59 NamespaceResolver = namespaceResolver;
60 LineNumber = linenumber;
61 LinePosition = lineposition;
64 public IXmlNamespaceResolver NamespaceResolver { get; }
65 public INode Parent { get; set; }
66 public List<string> IgnorablePrefixes { get; set; }
67 public int LineNumber { get; set; }
68 public int LinePosition { get; set; }
70 public bool HasLineInfo() => LineNumber >= 0 && LinePosition >= 0;
72 public abstract void Accept(IXamlNodeVisitor visitor, INode parentNode);
73 public abstract INode Clone();
76 [DebuggerDisplay("{Value}")]
77 internal class ValueNode : BaseNode, IValueNode
79 public ValueNode(object value, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1)
80 : base(namespaceResolver, linenumber, lineposition)
85 public object Value { get; set; }
87 public override void Accept(IXamlNodeVisitor visitor, INode parentNode)
89 visitor.Visit(this, parentNode);
92 public override INode Clone() => new ValueNode(Value, NamespaceResolver, LineNumber, LinePosition)
94 IgnorablePrefixes = IgnorablePrefixes
98 [DebuggerDisplay("{MarkupString}")]
99 internal class MarkupNode : BaseNode, IValueNode
101 public MarkupNode(string markupString, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1)
102 : base(namespaceResolver, linenumber, lineposition)
104 MarkupString = markupString;
107 public string MarkupString { get; }
109 public override void Accept(IXamlNodeVisitor visitor, INode parentNode)
111 visitor.Visit(this, parentNode);
114 public override INode Clone() => new MarkupNode(MarkupString, NamespaceResolver, LineNumber, LinePosition)
116 IgnorablePrefixes = IgnorablePrefixes
120 [DebuggerDisplay("{XmlType.Name}")]
121 internal class ElementNode : BaseNode, IValueNode, IElementNode
123 public ElementNode(XmlType type, string namespaceURI, IXmlNamespaceResolver namespaceResolver, int linenumber = -1,
124 int lineposition = -1)
125 : base(namespaceResolver, linenumber, lineposition)
127 Properties = new Dictionary<XmlName, INode>();
128 SkipProperties = new List<XmlName>();
129 CollectionItems = new List<INode>();
131 NamespaceURI = namespaceURI;
134 public Dictionary<XmlName, INode> Properties { get; }
135 public List<XmlName> SkipProperties { get; }
136 public List<INode> CollectionItems { get; }
137 public XmlType XmlType { get; }
138 public string NamespaceURI { get; }
139 public INameScope Namescope { get; set; }
141 public override void Accept(IXamlNodeVisitor visitor, INode parentNode)
143 if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.TopDown)
144 visitor.Visit(this, parentNode);
146 if (!SkipChildren(visitor, this, parentNode))
148 foreach (var node in Properties.Values.ToList())
149 node.Accept(visitor, this);
150 foreach (var node in CollectionItems)
151 node.Accept(visitor, this);
154 if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.BottomUp)
155 visitor.Visit(this, parentNode);
159 bool IsDataTemplate(INode parentNode)
161 var parentElement = parentNode as IElementNode;
163 if (parentElement != null &&
164 parentElement.Properties.TryGetValue(XmlName._CreateContent, out createContent) &&
165 createContent == this)
170 protected bool SkipChildren(IXamlNodeVisitor visitor, INode node, INode parentNode) =>
171 (visitor.StopOnDataTemplate && IsDataTemplate(parentNode))
172 || (visitor.StopOnResourceDictionary && visitor.IsResourceDictionary(this))
173 || visitor.SkipChildren(node, parentNode);
175 protected bool SkipVisitNode(IXamlNodeVisitor visitor, INode parentNode) =>
176 !visitor.VisitNodeOnDataTemplate && IsDataTemplate(parentNode);
178 public override INode Clone()
180 var clone = new ElementNode(XmlType, NamespaceURI, NamespaceResolver, LineNumber, LinePosition)
182 IgnorablePrefixes = IgnorablePrefixes
184 foreach (var kvp in Properties)
185 clone.Properties.Add(kvp.Key, kvp.Value.Clone());
186 foreach (var p in SkipProperties)
187 clone.SkipProperties.Add(p);
188 foreach (var p in CollectionItems)
189 clone.CollectionItems.Add(p.Clone());
194 internal abstract class RootNode : ElementNode
196 protected RootNode(XmlType xmlType, IXmlNamespaceResolver nsResolver) : base(xmlType, xmlType.NamespaceUri, nsResolver)
200 public override void Accept(IXamlNodeVisitor visitor, INode parentNode)
202 if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.TopDown)
203 visitor.Visit(this, parentNode);
205 if (!SkipChildren(visitor, this, parentNode))
207 foreach (var node in Properties.Values.ToList())
208 node.Accept(visitor, this);
209 foreach (var node in CollectionItems)
210 node.Accept(visitor, this);
213 if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.BottomUp)
214 visitor.Visit(this, parentNode);
218 internal class ListNode : BaseNode, IListNode, IValueNode
220 public ListNode(IList<INode> nodes, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1)
221 : base(namespaceResolver, linenumber, lineposition)
223 CollectionItems = nodes.ToList();
226 public XmlName XmlName { get; set; }
227 public List<INode> CollectionItems { get; set; }
229 public override void Accept(IXamlNodeVisitor visitor, INode parentNode)
231 if (visitor.VisitingMode == TreeVisitingMode.TopDown)
232 visitor.Visit(this, parentNode);
233 foreach (var node in CollectionItems)
234 node.Accept(visitor, this);
235 if (visitor.VisitingMode == TreeVisitingMode.BottomUp)
236 visitor.Visit(this, parentNode);
239 public override INode Clone()
241 var items = new List<INode>();
242 foreach (var p in CollectionItems)
243 items.Add(p.Clone());
244 return new ListNode(items, NamespaceResolver, LineNumber, LinePosition)
246 IgnorablePrefixes = IgnorablePrefixes
251 internal static class INodeExtensions
253 public static bool SkipPrefix(this INode node, string prefix)
257 if (node.IgnorablePrefixes != null && node.IgnorablePrefixes.Contains(prefix))
260 } while (node != null);