2 using System.Collections.Generic;
4 using Tizen.NUI.Binding.Internals;
6 namespace Tizen.NUI.Xaml
8 internal class ExpandMarkupsVisitor : IXamlNodeVisitor
10 public ExpandMarkupsVisitor(HydrationContext context)
15 public static readonly IList<XmlName> Skips = new List<XmlName>
18 XmlName.xTypeArguments,
19 XmlName.xFactoryMethod,
24 Dictionary<INode, object> Values
26 get { return Context.Values; }
29 HydrationContext Context { get; }
31 public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp;
32 public bool StopOnDataTemplate => false;
33 public bool StopOnResourceDictionary => false;
34 public bool VisitNodeOnDataTemplate => true;
35 public bool SkipChildren(INode node, INode parentNode) => false;
36 public bool IsResourceDictionary(ElementNode node) => false;
38 public void Visit(ValueNode node, INode parentNode)
42 public void Visit(MarkupNode markupnode, INode parentNode)
44 var parentElement = parentNode as IElementNode;
46 if (!ApplyPropertiesVisitor.TryGetPropertyName(markupnode, parentNode, out propertyName))
48 if (Skips.Contains(propertyName))
50 if (parentElement.SkipProperties.Contains(propertyName))
53 var markupString = markupnode.MarkupString;
55 ParseExpression(ref markupString, markupnode.NamespaceResolver, markupnode) as IElementNode;
58 ((IElementNode)parentNode).Properties[propertyName] = node;
59 node.Parent = parentNode;
63 public void Visit(ElementNode node, INode parentNode)
67 public void Visit(RootNode node, INode parentNode)
71 public void Visit(ListNode node, INode parentNode)
75 INode ParseExpression(ref string expression, IXmlNamespaceResolver nsResolver, INode node)
77 if (expression.StartsWith("{}", StringComparison.Ordinal))
78 return new ValueNode(expression.Substring(2), null);
80 if (expression[expression.Length - 1] != '}')
81 throw new Exception("Expression must end with '}'");
85 if (!MarkupExpressionParser.MatchMarkup(out match, expression, out len))
86 throw new Exception();
87 expression = expression.Substring(len).TrimStart();
88 if (expression.Length == 0)
89 throw new Exception("Expression did not end in '}'");
91 var serviceProvider = new XamlServiceProvider(node, Context);
92 serviceProvider.Add(typeof(IXmlNamespaceResolver), nsResolver);
94 return new MarkupExpansionParser().Parse(match, ref expression, serviceProvider);
97 public class MarkupExpansionParser : MarkupExpressionParser, IExpressionParser<INode>
101 object IExpressionParser.Parse(string match, ref string remaining, IServiceProvider serviceProvider)
103 return Parse(match, ref remaining, serviceProvider);
106 public INode Parse(string match, ref string remaining, IServiceProvider serviceProvider)
108 var nsResolver = serviceProvider.GetService(typeof(IXmlNamespaceResolver)) as IXmlNamespaceResolver;
109 if (nsResolver == null)
110 throw new ArgumentException(nameof(nsResolver));
111 IXmlLineInfo xmlLineInfo = null;
112 var xmlLineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
113 if (xmlLineInfoProvider != null)
114 xmlLineInfo = xmlLineInfoProvider.XmlLineInfo;
116 var split = match.Split(':');
117 if (split.Length > 2)
118 throw new ArgumentException(nameof(split.Length));
120 string prefix; //, name;
121 if (split.Length == 2)
133 var typeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
134 if (typeResolver == null)
136 // Add Binding and StaticResource support, The ordinal code can't find BindingExtension for Binding
137 //else if (match == "Binding")
139 // type = typeof(BindingExtension);
141 //else if (match == "StaticResource")
143 // type = typeof(StaticResourceExtension);
147 //The order of lookup is to look for the Extension-suffixed class name first and then look for the class name without the Extension suffix.
148 if (!typeResolver.TryResolve(match + "Extension", out type) && !typeResolver.TryResolve(match, out type))
150 var lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
151 var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
152 throw new XamlParseException(String.Format("MarkupExtension not found for {0}", match), lineInfo);
156 var namespaceuri = nsResolver.LookupNamespace(prefix) ?? "";
157 var xmltype = new XmlType(namespaceuri, type?.Name, null);
160 throw new NotSupportedException();
162 node = xmlLineInfo == null
163 ? new ElementNode(xmltype, null, nsResolver)
164 : new ElementNode(xmltype, null, nsResolver, xmlLineInfo.LineNumber, xmlLineInfo.LinePosition);
166 if (remaining.StartsWith("}", StringComparison.Ordinal))
168 remaining = remaining.Substring(1);
174 while ((piece = GetNextPiece(ref remaining, out next)) != null)
175 HandleProperty(piece, serviceProvider, ref remaining, next != '=');
180 protected override void SetPropertyValue(string prop, string strValue, object value, IServiceProvider serviceProvider)
182 var nsResolver = serviceProvider.GetService(typeof(IXmlNamespaceResolver)) as IXmlNamespaceResolver;
184 var childnode = value as INode ?? new ValueNode(strValue, nsResolver);
185 childnode.Parent = node;
188 var name = new XmlName(node.NamespaceURI, prop);
189 node.Properties[name] = childnode;
191 else //ContentProperty
192 node.CollectionItems.Add(childnode);