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, markupnode, parentNode) 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, IXmlLineInfo xmlLineInfo, INode node,
78 if (expression.StartsWith("{}", StringComparison.Ordinal))
79 return new ValueNode(expression.Substring(2), null);
81 if (expression[expression.Length - 1] != '}')
82 throw new Exception("Expression must end with '}'");
86 if (!MarkupExpressionParser.MatchMarkup(out match, expression, out len))
87 throw new Exception();
88 expression = expression.Substring(len).TrimStart();
89 if (expression.Length == 0)
90 throw new Exception("Expression did not end in '}'");
92 var serviceProvider = new XamlServiceProvider(node, Context);
93 serviceProvider.Add(typeof(IXmlNamespaceResolver), nsResolver);
95 return new MarkupExpansionParser().Parse(match, ref expression, serviceProvider);
98 public class MarkupExpansionParser : MarkupExpressionParser, IExpressionParser<INode>
102 object IExpressionParser.Parse(string match, ref string remaining, IServiceProvider serviceProvider)
104 return Parse(match, ref remaining, serviceProvider);
107 public INode Parse(string match, ref string remaining, IServiceProvider serviceProvider)
109 var nsResolver = serviceProvider.GetService(typeof(IXmlNamespaceResolver)) as IXmlNamespaceResolver;
110 if (nsResolver == null)
111 throw new ArgumentException(nameof(nsResolver));
112 IXmlLineInfo xmlLineInfo = null;
113 var xmlLineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
114 if (xmlLineInfoProvider != null)
115 xmlLineInfo = xmlLineInfoProvider.XmlLineInfo;
117 var split = match.Split(':');
118 if (split.Length > 2)
119 throw new ArgumentException(nameof(split.Length));
121 string prefix; //, name;
122 if (split.Length == 2)
134 var typeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
135 if (typeResolver == null)
137 // Add Binding and StaticResource support, The ordinal code can't find BindingExtension for Binding
138 //else if (match == "Binding")
140 // type = typeof(BindingExtension);
142 //else if (match == "StaticResource")
144 // type = typeof(StaticResourceExtension);
148 //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.
149 if (!typeResolver.TryResolve(match + "Extension", out type) && !typeResolver.TryResolve(match, out type))
151 var lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
152 var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
153 throw new XamlParseException(String.Format("MarkupExtension not found for {0}", match), lineInfo);
157 var namespaceuri = nsResolver.LookupNamespace(prefix) ?? "";
158 var xmltype = new XmlType(namespaceuri, type?.Name, null);
161 throw new NotSupportedException();
163 node = xmlLineInfo == null
164 ? new ElementNode(xmltype, null, nsResolver)
165 : new ElementNode(xmltype, null, nsResolver, xmlLineInfo.LineNumber, xmlLineInfo.LinePosition);
167 if (remaining.StartsWith("}", StringComparison.Ordinal))
169 remaining = remaining.Substring(1);
175 while ((piece = GetNextPiece(ref remaining, out next)) != null)
176 HandleProperty(piece, serviceProvider, ref remaining, next != '=');
181 protected override void SetPropertyValue(string prop, string strValue, object value, IServiceProvider serviceProvider)
183 var nsResolver = serviceProvider.GetService(typeof(IXmlNamespaceResolver)) as IXmlNamespaceResolver;
185 var childnode = value as INode ?? new ValueNode(strValue, nsResolver);
186 childnode.Parent = node;
189 var name = new XmlName(node.NamespaceURI, prop);
190 node.Properties[name] = childnode;
192 else //ContentProperty
193 node.CollectionItems.Add(childnode);