summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Xaml
diff options
context:
space:
mode:
authorKangho Hur <kangho.hur@samsung.com>2017-03-24 14:29:22 +0900
committerKangho Hur <kangho.hur@samsung.com>2017-03-24 14:47:36 +0900
commit161a8e0f544b44f848d4c68ac9637d3a8b3f2520 (patch)
tree9a61043f0e27ef4f9855fcc1fc70693b12f10f4f /Xamarin.Forms.Xaml
parent20daaa5702a27d1a9c7cf9dfacfdfa254ac0e5e3 (diff)
downloadxamarin-forms-161a8e0f544b44f848d4c68ac9637d3a8b3f2520.tar.gz
xamarin-forms-161a8e0f544b44f848d4c68ac9637d3a8b3f2520.tar.bz2
xamarin-forms-161a8e0f544b44f848d4c68ac9637d3a8b3f2520.zip
Clean sync with 2.3.4-2
Change-Id: I6a7423d2690a1c30f46e0c128d9504a2464f8f0b
Diffstat (limited to 'Xamarin.Forms.Xaml')
-rw-r--r--Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs55
-rw-r--r--Xamarin.Forms.Xaml/CreateValuesVisitor.cs18
-rw-r--r--Xamarin.Forms.Xaml/ExpandMarkupsVisitor.cs18
-rw-r--r--Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs18
-rw-r--r--Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs2
-rw-r--r--Xamarin.Forms.Xaml/NamescopingVisitor.cs18
-rw-r--r--Xamarin.Forms.Xaml/PruneIgnoredNodesVisitor.cs15
-rw-r--r--Xamarin.Forms.Xaml/RegisterXNamesVisitor.cs18
-rw-r--r--Xamarin.Forms.Xaml/TypeConversionExtensions.cs4
-rw-r--r--Xamarin.Forms.Xaml/XamlNode.cs123
-rw-r--r--Xamarin.Forms.Xaml/XamlNodeVisitor.cs24
-rw-r--r--Xamarin.Forms.Xaml/XamlParser.cs6
12 files changed, 187 insertions, 132 deletions
diff --git a/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs b/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs
index 833d5d94..154ba023 100644
--- a/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs
+++ b/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs
@@ -35,10 +35,15 @@ namespace Xamarin.Forms.Xaml
HydratationContext Context { get; }
- public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp;
- public bool StopOnDataTemplate => true;
+ public bool VisitChildrenFirst {
+ get { return true; }
+ }
+
+ public bool StopOnDataTemplate {
+ get { return true; }
+ }
+
public bool StopOnResourceDictionary { get; }
- public bool VisitNodeOnDataTemplate => true;
public void Visit(ValueNode node, INode parentNode)
{
@@ -76,15 +81,6 @@ namespace Xamarin.Forms.Xaml
public void Visit(ElementNode node, INode parentNode)
{
- var propertyName = XmlName.Empty;
- if (TryGetPropertyName(node, parentNode, out propertyName) && propertyName == XmlName._CreateContent){
- var s0 = Values[parentNode];
- if (s0 is ElementTemplate) {
- SetTemplate(s0 as ElementTemplate, node);
- return;
- }
- }
-
var value = Values [node];
var parentElement = parentNode as IElementNode;
var markupExtension = value as IMarkupExtension;
@@ -100,7 +96,7 @@ namespace Xamarin.Forms.Xaml
value = valueProvider.ProvideValue(serviceProvider);
}
- propertyName = XmlName.Empty;
+ XmlName propertyName = XmlName.Empty;
//Simplify ListNodes with single elements
var pList = parentNode as ListNode;
@@ -117,11 +113,15 @@ namespace Xamarin.Forms.Xaml
return;
var source = Values [parentNode];
- SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node);
+
+ if (propertyName == XmlName._CreateContent && source is ElementTemplate)
+ SetTemplate(source as ElementTemplate, node);
+ else
+ SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node);
} else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) {
// Collection element, implicit content, or implicit collection element.
string contentProperty;
- if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(Context.Types [parentElement].GetTypeInfo()) && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) {
+ if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(Context.Types [parentElement].GetTypeInfo())) {
var source = Values [parentNode];
if (!(typeof(ResourceDictionary).IsAssignableFrom(Context.Types [parentElement]))) {
var addMethod =
@@ -137,8 +137,7 @@ namespace Xamarin.Forms.Xaml
var source = Values [parentNode];
SetPropertyValue(source, name, value, Context.RootElement, node, Context, node);
- } else
- throw new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node);
+ }
} else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) {
var parentList = (ListNode)parentNode;
var source = Values [parentNode.Parent];
@@ -297,7 +296,7 @@ namespace Xamarin.Forms.Xaml
return;
//If we can assign that value to a normal property, let's do it
- if (xpe == null && TrySetProperty(xamlelement, localName, value, lineInfo, serviceProvider, context, out xpe))
+ if (xpe == null && TrySetProperty(xamlelement, localName, value, lineInfo, serviceProvider, out xpe))
return;
//If it's an already initialized property, add to it
@@ -362,7 +361,7 @@ namespace Xamarin.Forms.Xaml
exception = null;
var elementType = element.GetType();
- var binding = value.ConvertTo(typeof(BindingBase),pinfoRetriever:null,serviceProvider:null) as BindingBase;
+ var binding = value as BindingBase;
var bindable = element as BindableObject;
var nativeBindingService = DependencyService.Get<INativeBindingService>();
@@ -423,7 +422,7 @@ namespace Xamarin.Forms.Xaml
return false;
}
- static bool TrySetProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, HydratationContext context, out Exception exception)
+ static bool TrySetProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, out Exception exception)
{
exception = null;
@@ -433,9 +432,6 @@ namespace Xamarin.Forms.Xaml
if (propertyInfo == null || !propertyInfo.CanWrite || (setter = propertyInfo.SetMethod) == null)
return false;
- if (!IsVisibleFrom(setter, context.RootElement))
- return false;
-
object convertedValue = value.ConvertTo(propertyInfo.PropertyType, () => propertyInfo, serviceProvider);
if (convertedValue != null && !propertyInfo.PropertyType.IsInstanceOfType(convertedValue))
return false;
@@ -444,19 +440,6 @@ namespace Xamarin.Forms.Xaml
return true;
}
- static bool IsVisibleFrom(MethodInfo setter, object rootElement)
- {
- if (setter.IsPublic)
- return true;
- if (setter.IsPrivate && setter.DeclaringType == rootElement.GetType())
- return true;
- if ((setter.IsAssembly || setter.IsFamilyOrAssembly) && setter.DeclaringType.AssemblyQualifiedName == rootElement.GetType().AssemblyQualifiedName)
- return true;
- if (setter.IsFamily && setter.DeclaringType.IsAssignableFrom(rootElement.GetType()))
- return true;
- return false;
- }
-
static bool TryAddToProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, out Exception exception)
{
exception = null;
diff --git a/Xamarin.Forms.Xaml/CreateValuesVisitor.cs b/Xamarin.Forms.Xaml/CreateValuesVisitor.cs
index b4f9213a..817b62c8 100644
--- a/Xamarin.Forms.Xaml/CreateValuesVisitor.cs
+++ b/Xamarin.Forms.Xaml/CreateValuesVisitor.cs
@@ -23,10 +23,20 @@ namespace Xamarin.Forms.Xaml
HydratationContext Context { get; }
- public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp;
- public bool StopOnDataTemplate => true;
- public bool StopOnResourceDictionary => false;
- public bool VisitNodeOnDataTemplate => false;
+ public bool VisitChildrenFirst
+ {
+ get { return true; }
+ }
+
+ public bool StopOnDataTemplate
+ {
+ get { return true; }
+ }
+
+ public bool StopOnResourceDictionary
+ {
+ get { return false; }
+ }
public void Visit(ValueNode node, INode parentNode)
{
diff --git a/Xamarin.Forms.Xaml/ExpandMarkupsVisitor.cs b/Xamarin.Forms.Xaml/ExpandMarkupsVisitor.cs
index 282b7da4..81893506 100644
--- a/Xamarin.Forms.Xaml/ExpandMarkupsVisitor.cs
+++ b/Xamarin.Forms.Xaml/ExpandMarkupsVisitor.cs
@@ -28,10 +28,20 @@ namespace Xamarin.Forms.Xaml
HydratationContext Context { get; }
- public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp;
- public bool StopOnDataTemplate => false;
- public bool StopOnResourceDictionary => false;
- public bool VisitNodeOnDataTemplate => true;
+ public bool VisitChildrenFirst
+ {
+ get { return true; }
+ }
+
+ public bool StopOnDataTemplate
+ {
+ get { return false; }
+ }
+
+ public bool StopOnResourceDictionary
+ {
+ get { return false; }
+ }
public void Visit(ValueNode node, INode parentNode)
{
diff --git a/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs b/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs
index 509d54e8..a3f12109 100644
--- a/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs
+++ b/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs
@@ -20,10 +20,20 @@ namespace Xamarin.Forms.Xaml
get { return Context.Values; }
}
- public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
- public bool StopOnDataTemplate => true;
- public bool StopOnResourceDictionary => false;
- public bool VisitNodeOnDataTemplate => false;
+ public bool VisitChildrenFirst
+ {
+ get { return false; }
+ }
+
+ public bool StopOnDataTemplate
+ {
+ get { return true; }
+ }
+
+ public bool StopOnResourceDictionary
+ {
+ get { return false; }
+ }
public void Visit(ValueNode node, INode parentNode)
{
diff --git a/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs b/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs
index 34f1c569..703fc206 100644
--- a/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs
+++ b/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs
@@ -34,7 +34,7 @@ namespace Xamarin.Forms.Xaml
}
if (resource == null && (Application.Current == null || Application.Current.Resources == null ||
!Application.Current.Resources.TryGetMergedValue(Key, out resource)))
- throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo);
+ throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo);
var bp = valueProvider.TargetProperty as BindableProperty;
var pi = valueProvider.TargetProperty as PropertyInfo;
diff --git a/Xamarin.Forms.Xaml/NamescopingVisitor.cs b/Xamarin.Forms.Xaml/NamescopingVisitor.cs
index ec9b9851..0651d045 100644
--- a/Xamarin.Forms.Xaml/NamescopingVisitor.cs
+++ b/Xamarin.Forms.Xaml/NamescopingVisitor.cs
@@ -14,10 +14,20 @@ namespace Xamarin.Forms.Xaml
Dictionary<INode, object> Values { get; set; }
- public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
- public bool StopOnDataTemplate => false;
- public bool StopOnResourceDictionary => false;
- public bool VisitNodeOnDataTemplate => true;
+ public bool VisitChildrenFirst
+ {
+ get { return false; }
+ }
+
+ public bool StopOnDataTemplate
+ {
+ get { return false; }
+ }
+
+ public bool StopOnResourceDictionary
+ {
+ get { return false; }
+ }
public void Visit(ValueNode node, INode parentNode)
{
diff --git a/Xamarin.Forms.Xaml/PruneIgnoredNodesVisitor.cs b/Xamarin.Forms.Xaml/PruneIgnoredNodesVisitor.cs
index 92badecd..95ddb20f 100644
--- a/Xamarin.Forms.Xaml/PruneIgnoredNodesVisitor.cs
+++ b/Xamarin.Forms.Xaml/PruneIgnoredNodesVisitor.cs
@@ -5,10 +5,17 @@ namespace Xamarin.Forms.Xaml
{
class PruneIgnoredNodesVisitor : IXamlNodeVisitor
{
- public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
- public bool StopOnDataTemplate => false;
- public bool StopOnResourceDictionary => false;
- public bool VisitNodeOnDataTemplate => true;
+ public bool StopOnDataTemplate {
+ get { return false; }
+ }
+
+ public bool StopOnResourceDictionary {
+ get { return false; }
+ }
+
+ public bool VisitChildrenFirst {
+ get { return false; }
+ }
public void Visit(ElementNode node, INode parentNode)
{
diff --git a/Xamarin.Forms.Xaml/RegisterXNamesVisitor.cs b/Xamarin.Forms.Xaml/RegisterXNamesVisitor.cs
index 5ee3bc3e..a7da3b98 100644
--- a/Xamarin.Forms.Xaml/RegisterXNamesVisitor.cs
+++ b/Xamarin.Forms.Xaml/RegisterXNamesVisitor.cs
@@ -12,10 +12,20 @@ namespace Xamarin.Forms.Xaml
Dictionary<INode, object> Values { get; }
- public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
- public bool StopOnDataTemplate => true;
- public bool StopOnResourceDictionary => false;
- public bool VisitNodeOnDataTemplate => false;
+ public bool VisitChildrenFirst
+ {
+ get { return false; }
+ }
+
+ public bool StopOnDataTemplate
+ {
+ get { return true; }
+ }
+
+ public bool StopOnResourceDictionary
+ {
+ get { return false; }
+ }
public void Visit(ValueNode node, INode parentNode)
{
diff --git a/Xamarin.Forms.Xaml/TypeConversionExtensions.cs b/Xamarin.Forms.Xaml/TypeConversionExtensions.cs
index da8e7117..15a66f5d 100644
--- a/Xamarin.Forms.Xaml/TypeConversionExtensions.cs
+++ b/Xamarin.Forms.Xaml/TypeConversionExtensions.cs
@@ -176,7 +176,7 @@ namespace Xamarin.Forms.Xaml
if (!mi.IsSpecialName) continue;
if (mi.Name != "op_Implicit") continue;
if (!mi.IsPublic) continue;
- if (!toType.IsAssignableFrom(mi.ReturnType)) continue;
+ if (mi.ReturnType != toType) continue;
var parameters = mi.GetParameters();
if (parameters.Length != 1) continue;
if (parameters[0].ParameterType != value.GetType()) continue;
@@ -188,7 +188,7 @@ namespace Xamarin.Forms.Xaml
if (!mi.IsSpecialName) continue;
if (mi.Name != "op_Implicit") continue;
if (!mi.IsPublic) continue;
- if (!toType.IsAssignableFrom(mi.ReturnType)) continue;
+ if (mi.ReturnType != toType) continue;
var parameters = mi.GetParameters();
if (parameters.Length != 1) continue;
if (parameters[0].ParameterType != value.GetType()) continue;
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;
diff --git a/Xamarin.Forms.Xaml/XamlNodeVisitor.cs b/Xamarin.Forms.Xaml/XamlNodeVisitor.cs
index 874a5fbd..e0b1db32 100644
--- a/Xamarin.Forms.Xaml/XamlNodeVisitor.cs
+++ b/Xamarin.Forms.Xaml/XamlNodeVisitor.cs
@@ -2,11 +2,12 @@
namespace Xamarin.Forms.Xaml
{
- interface IXamlNodeVisitor
+ internal interface IXamlNodeVisitor
{
- TreeVisitingMode VisitingMode { get; }
+ bool VisitChildrenFirst { get; }
+
bool StopOnDataTemplate { get; }
- bool VisitNodeOnDataTemplate { get; }
+
bool StopOnResourceDictionary { get; }
void Visit(ValueNode node, INode parentNode);
@@ -16,27 +17,22 @@ namespace Xamarin.Forms.Xaml
void Visit(ListNode node, INode parentNode);
}
- enum TreeVisitingMode {
- TopDown,
- BottomUp
- }
-
- class XamlNodeVisitor : IXamlNodeVisitor
+ internal class XamlNodeVisitor : IXamlNodeVisitor
{
readonly Action<INode, INode> action;
- public XamlNodeVisitor(Action<INode, INode> action, TreeVisitingMode visitingMode = TreeVisitingMode.TopDown, bool stopOnDataTemplate = false, bool visitNodeOnDataTemplate = true)
+ public XamlNodeVisitor(Action<INode, INode> action, bool visitChildrenFirst = false, bool stopOnDataTemplate = false)
{
this.action = action;
- VisitingMode = visitingMode;
+ VisitChildrenFirst = visitChildrenFirst;
StopOnDataTemplate = stopOnDataTemplate;
- VisitNodeOnDataTemplate = visitNodeOnDataTemplate;
}
- public TreeVisitingMode VisitingMode { get; }
+ public bool VisitChildrenFirst { get; }
+
public bool StopOnDataTemplate { get; }
+
public bool StopOnResourceDictionary { get; private set; }
- public bool VisitNodeOnDataTemplate { get; }
public void Visit(ValueNode node, INode parentNode)
{
diff --git a/Xamarin.Forms.Xaml/XamlParser.cs b/Xamarin.Forms.Xaml/XamlParser.cs
index 456aad6a..e5c49804 100644
--- a/Xamarin.Forms.Xaml/XamlParser.cs
+++ b/Xamarin.Forms.Xaml/XamlParser.cs
@@ -104,11 +104,7 @@ namespace Xamarin.Forms.Xaml
case XmlNodeType.Whitespace:
break;
case XmlNodeType.Text:
- case XmlNodeType.CDATA:
- if (node.CollectionItems.Count == 1 && node.CollectionItems[0] is ValueNode)
- ((ValueNode)node.CollectionItems[0]).Value += reader.Value.Trim();
- else
- node.CollectionItems.Add(new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader));
+ node.CollectionItems.Add(new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader));
break;
default:
Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);