From 8de111fb96b268842f6de128c96d81f63f49cb2f Mon Sep 17 00:00:00 2001 From: Xianbing Teng Date: Wed, 23 Feb 2022 18:34:53 +0800 Subject: [PATCH] [NUI] Add Tizen.NUI.XamlBuild module --- build.sh | 21 + pkg/Tizen.NET.API10/Tizen.NET.API10.nuspec | 1 + pkg/Tizen.NET.API10/build/Tizen.NET.API10.props | 14 + .../build/{tizen10.0 => }/Tizen.NET.API10.targets | 5 +- .../build/tizen10.0/Tizen.NET.API10.props | 11 - pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Mdb.dll | Bin 0 -> 39424 bytes pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Pdb.dll | Bin 0 -> 87552 bytes pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Rocks.dll | Bin 0 -> 24576 bytes pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.dll | Bin 0 -> 342016 bytes pkg/Tizen.NET.API10/xamlbuild/System.CodeDom.dll | Bin 0 -> 32952 bytes .../xamlbuild/Tizen.NUI.XamlBuild.dll | Bin 0 -> 506880 bytes .../xamlbuild/Tizen.NUI.XamlBuild.props | 13 + .../xamlbuild/Tizen.NUI.XamlBuild.targets | 58 + src/Tizen.NUI.XamlBuild/README.md | 1 + src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.csproj | 28 + src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.sln | 25 + .../src/internal/Xaml/ApplyPropertiesVisitor.cs | 712 +++++++++ .../src/internal/Xaml/CreateValuesVisitor.cs | 429 ++++++ .../src/internal/Xaml/DesignMode.cs | 7 + .../src/internal/Xaml/ExpandMarkupsVisitor.cs | 197 +++ .../Xaml/FillResourceDictionariesVisitor.cs | 87 ++ .../src/internal/Xaml/HydrationContext.cs | 20 + .../src/internal/Xaml/IConverterOptions.cs | 7 + .../src/internal/Xaml/IDictionaryExtensions.cs | 14 + .../src/internal/Xaml/IExpressionParser.cs | 15 + .../src/internal/Xaml/IMarkupExtension.cs | 19 + .../internal/Xaml/INativeValueConverterService.cs | 9 + .../src/internal/Xaml/IProvideParentValues.cs | 9 + .../src/internal/Xaml/IProvideValueTarget.cs | 8 + .../src/internal/Xaml/IReferenceProvider.cs | 7 + .../src/internal/Xaml/IResourcesLoader.cs | 13 + .../src/internal/Xaml/IRootObjectProvider.cs | 7 + .../src/internal/Xaml/IValueConverterProvider.cs | 10 + .../src/internal/Xaml/IValueProvider.cs | 9 + .../src/internal/Xaml/IXamlTypeResolver.cs | 10 + .../src/internal/Xaml/IXmlLineInfoProvider.cs | 9 + .../src/internal/Xaml/MarkupExpressionParser.cs | 229 +++ .../src/internal/Xaml/MarkupExtensionParser.cs | 81 ++ .../Xaml/MarkupExtensions/ArrayExtension.cs | 41 + .../Xaml/MarkupExtensions/BindingExtension.cs | 83 ++ .../MarkupExtensions/DynamicResourceExtension.cs | 41 + .../Xaml/MarkupExtensions/NullExtension.cs | 14 + .../Xaml/MarkupExtensions/ReferenceExtension.cs | 48 + .../Xaml/MarkupExtensions/StaticExtension.cs | 52 + .../MarkupExtensions/StaticResourceExtension.cs | 111 ++ .../MarkupExtensions/TemplateBindingExtension.cs | 36 + .../Xaml/MarkupExtensions/TypeExtension.cs | 30 + .../src/internal/Xaml/NamescopingVisitor.cs | 76 + .../src/internal/Xaml/ProvideCompiledAttribute.cs | 15 + .../src/internal/Xaml/PruneIgnoredNodesVisitor.cs | 79 + .../src/internal/Xaml/ReflectionExtensions.cs | 70 + .../src/internal/Xaml/RegisterXNamesVisitor.cs | 68 + .../src/internal/Xaml/ResourcesLoader.cs | 55 + .../internal/Xaml/RuntimeNamePropertyAttribute.cs | 15 + .../src/internal/Xaml/TypeArgumentsParser.cs | 71 + .../src/internal/Xaml/TypeConversionAttribute.cs | 15 + .../src/internal/Xaml/TypeConversionExtensions.cs | 231 +++ .../src/internal/Xaml/ValueConverterProvider.cs | 17 + .../src/internal/Xaml/ViewExtensions.cs | 67 + .../src/internal/Xaml/VisualStateManager.cs | 362 +++++ .../src/internal/Xaml/XamlCompilationAttribute.cs | 42 + .../src/internal/Xaml/XamlLoader.cs | 308 ++++ .../src/internal/Xaml/XamlNode.cs | 257 ++++ .../src/internal/Xaml/XamlNodeVisitor.cs | 51 + .../src/internal/Xaml/XamlParseException.cs | 47 + .../src/internal/Xaml/XamlParser.cs | 418 ++++++ .../src/internal/Xaml/XamlResourceIdAttribute.cs | 67 + .../src/internal/Xaml/XamlServiceProvider.cs | 321 ++++ .../src/internal/Xaml/XmlLineInfo.cs | 31 + .../src/internal/Xaml/XmlName.cs | 58 + .../src/internal/Xaml/XmlnsHelper.cs | 75 + .../src/internal/XamlBinding/BindableObject.cs | 913 ++++++++++++ .../src/internal/XamlBinding/BindableProperty.cs | 550 +++++++ .../internal/XamlBinding/BindablePropertyKey.cs | 25 + .../src/internal/XamlBinding/Binding.cs | 254 ++++ .../src/internal/XamlBinding/BindingBase.cs | 154 ++ .../internal/XamlBinding/BindingBaseExtensions.cs | 12 + .../src/internal/XamlBinding/BindingExpression.cs | 644 ++++++++ .../src/internal/XamlBinding/BindingMode.cs | 36 + .../CollectionSynchronizationCallback.cs | 7 + .../CollectionSynchronizationContext.cs | 22 + .../XamlBinding/ContentPropertyAttribute.cs | 26 + .../src/internal/XamlBinding/ControlTemplate.cs | 27 + .../src/internal/XamlBinding/DataTemplate.cs | 80 + .../internal/XamlBinding/DataTemplateExtensions.cs | 22 + .../internal/XamlBinding/DataTemplateSelector.cs | 41 + .../internal/XamlBinding/DependencyAttribute.cs | 15 + .../internal/XamlBinding/DependencyFetchTarget.cs | 8 + .../src/internal/XamlBinding/DependencyResolver.cs | 57 + .../src/internal/XamlBinding/DependencyService.cs | 137 ++ .../src/internal/XamlBinding/Device.cs | 197 +++ .../src/internal/XamlBinding/DeviceInfo.cs | 45 + .../src/internal/XamlBinding/DeviceOrientation.cs | 16 + .../src/internal/XamlBinding/Effect.cs | 91 ++ .../src/internal/XamlBinding/Element.cs | 771 ++++++++++ .../src/internal/XamlBinding/ElementEventArgs.cs | 17 + .../src/internal/XamlBinding/ElementTemplate.cs | 108 ++ .../internal/XamlBinding/EnumerableExtensions.cs | 83 ++ .../internal/XamlBinding/ExportEffectAttribute.cs | 20 + .../src/internal/XamlBinding/FlowDirection.cs | 32 + .../src/internal/XamlBinding/GestureRecognizer.cs | 9 + .../src/internal/XamlBinding/HandlerAttribute.cs | 23 + .../src/internal/XamlBinding/IControlTemplated.cs | 13 + .../XamlBinding/IDynamicResourceHandler.cs | 11 + .../internal/XamlBinding/IEffectControlProvider.cs | 17 + .../src/internal/XamlBinding/IElement.cs | 14 + .../src/internal/XamlBinding/IElementController.cs | 22 + .../internal/XamlBinding/IExtendedTypeConverter.cs | 13 + .../src/internal/XamlBinding/IGestureRecognizer.cs | 8 + .../internal/XamlBinding/INativeBindingService.cs | 10 + .../src/internal/XamlBinding/IPlatform.cs | 20 + .../src/internal/XamlBinding/IPlatformServices.cs | 38 + .../src/internal/XamlBinding/IRegisterable.cs | 6 + .../internal/XamlBinding/IResourceDictionary.cs | 14 + .../src/internal/XamlBinding/IResourcesProvider.cs | 13 + .../XamlBinding/ISystemResourcesProvider.cs | 10 + .../src/internal/XamlBinding/IValueConverter.cs | 14 + .../Interactivity/AttachedCollection.cs | 127 ++ .../internal/XamlBinding/Interactivity/Behavior.cs | 66 + .../XamlBinding/Interactivity/BindingCondition.cs | 98 ++ .../XamlBinding/Interactivity/Condition.cs | 51 + .../XamlBinding/Interactivity/IAttachedObject.cs | 8 + .../XamlBinding/Interactivity/MultiCondition.cs | 65 + .../XamlBinding/Interactivity/PropertyCondition.cs | 112 ++ .../XamlBinding/Interactivity/TriggerAction.cs | 37 + .../XamlBinding/Interactivity/TriggerBase.cs | 213 +++ .../Interactivity/XamlPropertyCondition.cs | 112 ++ .../XamlBinding/Internals/DynamicResource.cs | 15 + .../XamlBinding/Internals/IDataTemplate.cs | 11 + .../internal/XamlBinding/Internals/INameScope.cs | 15 + .../XamlBinding/Internals/INamescopeProvider.cs | 9 + .../internal/XamlBinding/Internals/NameScope.cs | 60 + .../XamlBinding/Internals/PreserveAttribute.cs | 23 + .../XamlBinding/Internals/ResourceLoader.cs | 42 + .../src/internal/XamlBinding/Internals/Ticker.cs | 99 ++ .../internal/XamlBinding/Internals/TypedBinding.cs | 301 ++++ .../XamlBinding/ListStringTypeConverter.cs | 19 + .../internal/XamlBinding/NameScopeExtensions.cs | 41 + .../src/internal/XamlBinding/NullEffect.cs | 13 + .../src/internal/XamlBinding/OnIdiom.cs | 35 + .../src/internal/XamlBinding/OnPlatform.cs | 91 ++ .../src/internal/XamlBinding/ParameterAttribute.cs | 15 + .../src/internal/XamlBinding/Performance.cs | 15 + .../src/internal/XamlBinding/Registrar.cs | 284 ++++ .../internal/XamlBinding/RenderWithAttribute.cs | 15 + .../XamlBinding/ResolutionGroupNameAttribute.cs | 15 + .../src/internal/XamlBinding/ResourceDictionary.cs | 403 ++++++ .../XamlBinding/ResourcesChangedEventArgs.cs | 19 + .../internal/XamlBinding/ResourcesExtensions.cs | 170 +++ .../src/internal/XamlBinding/RoutingEffect.cs | 42 + .../src/internal/XamlBinding/Setter.cs | 95 ++ .../src/internal/XamlBinding/Style.cs | 185 +++ .../XamlBinding/StyleSheets/CharExtensions.cs | 41 + .../internal/XamlBinding/StyleSheets/CssReader.cs | 97 ++ .../src/internal/XamlBinding/StyleSheets/IStyle.cs | 13 + .../XamlBinding/StyleSheets/IStyleSelectable.cs | 20 + .../internal/XamlBinding/StyleSheets/Selector.cs | 305 ++++ .../src/internal/XamlBinding/StyleSheets/Style.cs | 98 ++ .../StyleSheets/StylePropertyAttribute.cs | 24 + .../internal/XamlBinding/StyleSheets/StyleSheet.cs | 124 ++ .../StyleSheets/StyleSheetExtensions.cs | 19 + .../StyleSheets/StyleSheetServiceProvider.cs | 39 + .../StyleSheets/TextReaderExtensions.cs | 76 + .../src/internal/XamlBinding/TargetIdiom.cs | 12 + .../src/internal/XamlBinding/TargetPlatform.cs | 14 + .../src/internal/XamlBinding/TemplateBinding.cs | 132 ++ .../src/internal/XamlBinding/TemplateUtilities.cs | 130 ++ .../internal/XamlBinding/TrackableCollection.cs | 16 + .../src/internal/XamlBinding/TypeConverter.cs | 35 + .../internal/XamlBinding/TypeConverterAttribute.cs | 74 + .../src/internal/XamlBinding/TypeTypeConverter.cs | 33 + .../XamlBinding/XmlnsDefinitionAttribute.cs | 43 + .../src/public/EXamlBuild/EXaml/EXamlAddEvent.cs | 98 ++ .../src/public/EXamlBuild/EXaml/EXamlAddObject.cs | 72 + .../EXaml/EXamlAddToCollectionInstance.cs | 52 + .../EXaml/EXamlAddToCollectionProperty.cs | 52 + .../EXaml/EXamlAddToResourceDictionary.cs | 73 + .../EXamlCreateObject/EXamlCreateArrayObject.cs | 46 + .../EXaml/EXamlCreateObject/EXamlCreateDPObject.cs | 35 + .../EXamlCreateObject/EXamlCreateDataTemplate.cs | 34 + .../EXaml/EXamlCreateObject/EXamlCreateObject.cs | 359 +++++ .../EXamlBuild/EXaml/EXamlGetObjectByProperty.cs | 59 + .../src/public/EXamlBuild/EXaml/EXamlOperation.cs | 69 + .../public/EXamlBuild/EXaml/EXamlRegisterXName.cs | 60 + .../EXamlBuild/EXaml/EXamlSetBindalbeProperty.cs | 78 + .../src/public/EXamlBuild/EXaml/EXamlSetBinding.cs | 79 + .../EXamlBuild/EXaml/EXamlSetDynamicResource.cs | 63 + .../public/EXamlBuild/EXaml/EXamlSetProperty.cs | 112 ++ .../EXaml/EXamlValueConverterFromString.cs | 68 + .../src/public/EXamlBuild/EXamlContext.cs | 848 +++++++++++ .../public/EXamlBuild/EXamlCreateObjectVisitor.cs | 708 +++++++++ .../public/EXamlBuild/EXamlExpandMarkupsVisitor.cs | 226 +++ .../src/public/EXamlBuild/EXamlSetFieldVisitor.cs | 84 ++ .../EXamlSetNamescopesAndRegisterNamesVisitor.cs | 184 +++ .../public/EXamlBuild/EXamlSetPropertiesVisitor.cs | 1139 +++++++++++++++ .../public/EXamlBuild/EXamlSetResourcesVisitor.cs | 131 ++ .../EXamlBuild/MethodDefinitionExtensions.cs | 105 ++ .../EXamlBuild/Utility/EXamlDefinitionList.cs | 67 + .../EXamlBuild/Utility/EXamlOperationType.cs | 53 + .../src/public/EXamlBuild/Utility/EXamlUtility.cs | 72 + .../BindablePropertyReferenceExtensions.cs | 61 + .../BindablePropertyConverter.cs | 108 ++ .../CompiledConverters/BindingTypeConverter.cs | 36 + .../CompiledConverters/BoundsTypeConverter.cs | 84 ++ .../CompiledConverters/ColorTypeConverter.cs | 222 +++ .../CompiledConverters/ConstraintTypeConverter.cs | 33 + .../CompiledConverters/ExtentsTypeConverter.cs | 64 + .../CompiledConverters/ICompiledTypeConverter.cs | 29 + .../CompiledConverters/LayoutOptionsConverter.cs | 42 + .../CompiledConverters/ListStringTypeConverter.cs | 41 + .../CompiledConverters/PositionTypeConverter.cs | 151 ++ .../CompiledConverters/RDSourceTypeConverter.cs | 78 + .../CompiledConverters/RectangleTypeConverter.cs | 60 + .../CompiledConverters/SizeTypeConverter.cs | 99 ++ .../CompiledConverters/ThicknessTypeConverter.cs | 61 + .../CompiledConverters/TypeTypeConverter.cs | 50 + .../CompiledConverters/UriTypeConverter.cs | 34 + .../CompiledMarkupExtensions/ArrayExtension.cs | 80 + .../ICompiledMarkupExtension.cs | 16 + .../CompiledMarkupExtensions/NullExtension.cs | 24 + .../CompiledMarkupExtensions/StaticExtension.cs | 139 ++ .../CompiledMarkupExtensions/TypeExtension.cs | 76 + .../ICompiledValueProvider.cs | 13 + .../PassthroughValueProvider.cs | 18 + .../CompiledValueProviders/SetterValueProvider.cs | 71 + .../CompiledValueProviders/StyleSheetProvider.cs | 88 ++ .../src/public/XamlBuild/CreateObjectVisitor.cs | 728 ++++++++++ .../src/public/XamlBuild/CssGTask.cs | 63 + .../src/public/XamlBuild/CssGenerator.cs | 97 ++ .../src/public/XamlBuild/DebugXamlCTask.cs | 150 ++ .../src/public/XamlBuild/ExpandMarkupsVisitor.cs | 209 +++ .../public/XamlBuild/FieldReferenceExtensions.cs | 22 + .../src/public/XamlBuild/GetTasksAbi.cs | 16 + .../src/public/XamlBuild/ILContext.cs | 46 + .../src/public/XamlBuild/ILProcessorExtensions.cs | 14 + .../src/public/XamlBuild/ILRootNode.cs | 16 + .../src/public/XamlBuild/Logger.cs | 81 ++ .../src/public/XamlBuild/MethodBodyExtensions.cs | 93 ++ .../public/XamlBuild/MethodDefinitionExtensions.cs | 78 + .../public/XamlBuild/MethodReferenceExtensions.cs | 62 + .../public/XamlBuild/ModuleDefinitionExtensions.cs | 335 +++++ .../src/public/XamlBuild/NodeILExtensions.cs | 1026 +++++++++++++ .../src/public/XamlBuild/PerformanceProvider.cs | 94 ++ .../XamlBuild/PropertyDefinitionExtensions.cs | 21 + .../src/public/XamlBuild/SetFieldVisitor.cs | 66 + .../SetNamescopesAndRegisterNamesVisitor.cs | 167 +++ .../src/public/XamlBuild/SetPropertiesVisitor.cs | 1530 ++++++++++++++++++++ .../src/public/XamlBuild/SetResourcesVisitor.cs | 93 ++ .../public/XamlBuild/TypeDefinitionExtensions.cs | 85 ++ .../public/XamlBuild/TypeReferenceExtensions.cs | 426 ++++++ .../XamlBuild/VariableDefinitionReference.cs | 22 + .../src/public/XamlBuild/XamlCAssemblyResolver.cs | 47 + .../src/public/XamlBuild/XamlCTask.cs | 889 ++++++++++++ .../src/public/XamlBuild/XamlGTask.cs | 96 ++ .../src/public/XamlBuild/XamlGenerator.cs | 576 ++++++++ .../src/public/XamlBuild/XamlTask.cs | 186 +++ .../src/public/XamlBuild/XmlTypeExtensions.cs | 243 ++++ 257 files changed, 28657 insertions(+), 12 deletions(-) mode change 100644 => 100755 pkg/Tizen.NET.API10/Tizen.NET.API10.nuspec create mode 100755 pkg/Tizen.NET.API10/build/Tizen.NET.API10.props rename pkg/Tizen.NET.API10/build/{tizen10.0 => }/Tizen.NET.API10.targets (60%) mode change 100644 => 100755 delete mode 100644 pkg/Tizen.NET.API10/build/tizen10.0/Tizen.NET.API10.props create mode 100755 pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Mdb.dll create mode 100755 pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Pdb.dll create mode 100755 pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Rocks.dll create mode 100755 pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.dll create mode 100755 pkg/Tizen.NET.API10/xamlbuild/System.CodeDom.dll create mode 100644 pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.dll create mode 100755 pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.props create mode 100755 pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.targets create mode 100644 src/Tizen.NUI.XamlBuild/README.md create mode 100755 src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.csproj create mode 100755 src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.sln create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/ApplyPropertiesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/CreateValuesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/DesignMode.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/ExpandMarkupsVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/FillResourceDictionariesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/HydrationContext.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IConverterOptions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IDictionaryExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IExpressionParser.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IMarkupExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/INativeValueConverterService.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideParentValues.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideValueTarget.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IReferenceProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IResourcesLoader.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IRootObjectProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueConverterProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXamlTypeResolver.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXmlLineInfoProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExpressionParser.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensionParser.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ArrayExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/BindingExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/DynamicResourceExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/NullExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ReferenceExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticResourceExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TemplateBindingExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TypeExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/NamescopingVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/ProvideCompiledAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/PruneIgnoredNodesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/ReflectionExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/RegisterXNamesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/ResourcesLoader.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/RuntimeNamePropertyAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeArgumentsParser.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/ValueConverterProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/ViewExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/VisualStateManager.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlCompilationAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlLoader.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNode.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNodeVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParseException.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParser.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlResourceIdAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlServiceProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlLineInfo.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlName.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlnsHelper.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableObject.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableProperty.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindablePropertyKey.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Binding.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBase.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBaseExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingExpression.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingMode.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationCallback.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationContext.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ContentPropertyAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ControlTemplate.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplate.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateSelector.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyFetchTarget.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyResolver.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyService.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Device.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceInfo.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceOrientation.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Effect.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Element.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementEventArgs.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementTemplate.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/EnumerableExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ExportEffectAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/FlowDirection.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/GestureRecognizer.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/HandlerAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IControlTemplated.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IDynamicResourceHandler.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IEffectControlProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElement.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElementController.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IExtendedTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IGestureRecognizer.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/INativeBindingService.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatform.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatformServices.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IRegisterable.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourceDictionary.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourcesProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ISystemResourcesProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IValueConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/AttachedCollection.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Behavior.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/BindingCondition.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Condition.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/IAttachedObject.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/MultiCondition.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/PropertyCondition.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerAction.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerBase.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/XamlPropertyCondition.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/DynamicResource.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/IDataTemplate.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INameScope.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INamescopeProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/NameScope.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/PreserveAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/ResourceLoader.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/Ticker.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/TypedBinding.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ListStringTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NameScopeExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NullEffect.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnIdiom.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnPlatform.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ParameterAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Performance.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Registrar.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/RenderWithAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResolutionGroupNameAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResourceDictionary.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResourcesChangedEventArgs.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResourcesExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/RoutingEffect.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Setter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Style.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/CharExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/CssReader.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/IStyle.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/IStyleSelectable.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/Selector.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/Style.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/StylePropertyAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/StyleSheet.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/StyleSheetExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/StyleSheetServiceProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/StyleSheets/TextReaderExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TargetIdiom.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TargetPlatform.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TemplateBinding.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TemplateUtilities.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TrackableCollection.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TypeConverterAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/TypeTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/XmlnsDefinitionAttribute.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlAddEvent.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlAddObject.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlAddToCollectionInstance.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlAddToCollectionProperty.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlAddToResourceDictionary.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlCreateObject/EXamlCreateArrayObject.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlCreateObject/EXamlCreateDPObject.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlCreateObject/EXamlCreateDataTemplate.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlCreateObject/EXamlCreateObject.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlGetObjectByProperty.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlOperation.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlRegisterXName.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlSetBindalbeProperty.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlSetBinding.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlSetDynamicResource.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlSetProperty.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXaml/EXamlValueConverterFromString.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXamlContext.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXamlCreateObjectVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXamlExpandMarkupsVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXamlSetFieldVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXamlSetNamescopesAndRegisterNamesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXamlSetPropertiesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/EXamlSetResourcesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/MethodDefinitionExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/Utility/EXamlDefinitionList.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/Utility/EXamlOperationType.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/EXamlBuild/Utility/EXamlUtility.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/BindablePropertyReferenceExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/BindablePropertyConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/BindingTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/BoundsTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/ColorTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/ConstraintTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/ExtentsTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/ICompiledTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/LayoutOptionsConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/ListStringTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/PositionTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/RDSourceTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/RectangleTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/SizeTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/ThicknessTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/TypeTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledConverters/UriTypeConverter.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledMarkupExtensions/ArrayExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledMarkupExtensions/ICompiledMarkupExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledMarkupExtensions/NullExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledMarkupExtensions/StaticExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledMarkupExtensions/TypeExtension.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledValueProviders/ICompiledValueProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledValueProviders/PassthroughValueProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledValueProviders/SetterValueProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CompiledValueProviders/StyleSheetProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CreateObjectVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CssGTask.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/CssGenerator.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/DebugXamlCTask.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/ExpandMarkupsVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/FieldReferenceExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/GetTasksAbi.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/ILContext.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/ILProcessorExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/ILRootNode.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/Logger.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/MethodBodyExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/MethodDefinitionExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/MethodReferenceExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/ModuleDefinitionExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/NodeILExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/PerformanceProvider.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/PropertyDefinitionExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/SetFieldVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/SetNamescopesAndRegisterNamesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/SetPropertiesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/SetResourcesVisitor.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/TypeDefinitionExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/TypeReferenceExtensions.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/VariableDefinitionReference.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/XamlCAssemblyResolver.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/XamlCTask.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/XamlGTask.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/XamlGenerator.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/XamlTask.cs create mode 100755 src/Tizen.NUI.XamlBuild/src/public/XamlBuild/XmlTypeExtensions.cs diff --git a/build.sh b/build.sh index 99f4f0d..bce3bbd 100755 --- a/build.sh +++ b/build.sh @@ -19,6 +19,8 @@ usage() { echo "Commands:" echo " build [module] Build a specific module" echo " full Build all modules in src/ directory" + echo " design Build NUI Design module" + echo " xamlbuild Build NUI XamlBuild module" echo " dummy Generate dummy assemblies of all modules" echo " pack [version] Make a NuGet package with build artifacts" echo " install [target] Install assemblies to the target device" @@ -40,6 +42,11 @@ prepare_solution() { else dotnet sln $SLN_FILE remove $SCRIPT_DIR/src/*/*.Design.csproj fi + if [ "$target" == "xamlbuild" ]; then + dotnet sln $SLN_FILE add $SCRIPT_DIR/src/*/*.XamlBuild.csproj + else + dotnet sln $SLN_FILE remove $SCRIPT_DIR/src/*/*.XamlBuild.csproj + fi } cleanup_solution() { @@ -146,6 +153,19 @@ cmd_design_build() { cleanup_solution } +cmd_xamlbuild_build() { + prepare_solution xamlbuild + restore $SLN_FILE + build $SLN_FILE $@ + projects=$(dirname $(ls -1 $SCRIPT_DIR/src/*/*.XamlBuild.csproj)) + for proj in $projects; do + if [ -d $proj/bin/$CONFIGURATION ]; then + cp -f $proj/bin/$CONFIGURATION/*/*.XamlBuild.dll $SCRIPT_DIR/pkg/Tizen.NET.API*/xamlbuild/ + fi + done + cleanup_solution +} + cmd_dummy_build() { if [ ! -d $OUTDIR/bin/public/ref ]; then echo "No assemblies to read. Build TizenFX first." @@ -216,6 +236,7 @@ case "$cmd" in build|--build|-b) cmd_module_build $@ ;; full |--full |-f) cmd_full_build $@ ;; design|--design) cmd_design_build $@ ;; + xamlbuild|--xamlbuild) cmd_xamlbuild_build $@ ;; dummy|--dummy|-d) cmd_dummy_build $@ ;; pack |--pack |-p) cmd_pack $@ ;; install |--install |-i) cmd_install $@ ;; diff --git a/pkg/Tizen.NET.API10/Tizen.NET.API10.nuspec b/pkg/Tizen.NET.API10/Tizen.NET.API10.nuspec old mode 100644 new mode 100755 index 9106a8d..9ceb71a --- a/pkg/Tizen.NET.API10/Tizen.NET.API10.nuspec +++ b/pkg/Tizen.NET.API10/Tizen.NET.API10.nuspec @@ -15,6 +15,7 @@ + diff --git a/pkg/Tizen.NET.API10/build/Tizen.NET.API10.props b/pkg/Tizen.NET.API10/build/Tizen.NET.API10.props new file mode 100755 index 0000000..66436a9 --- /dev/null +++ b/pkg/Tizen.NET.API10/build/Tizen.NET.API10.props @@ -0,0 +1,14 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + + + + + + + + diff --git a/pkg/Tizen.NET.API10/build/tizen10.0/Tizen.NET.API10.targets b/pkg/Tizen.NET.API10/build/Tizen.NET.API10.targets old mode 100644 new mode 100755 similarity index 60% rename from pkg/Tizen.NET.API10/build/tizen10.0/Tizen.NET.API10.targets rename to pkg/Tizen.NET.API10/build/Tizen.NET.API10.targets index 78ae156..8ef2043 --- a/pkg/Tizen.NET.API10/build/tizen10.0/Tizen.NET.API10.targets +++ b/pkg/Tizen.NET.API10/build/Tizen.NET.API10.targets @@ -9,7 +9,7 @@ - + false false Microsoft.NETCore.App.Ref @@ -17,4 +17,7 @@ + + + \ No newline at end of file diff --git a/pkg/Tizen.NET.API10/build/tizen10.0/Tizen.NET.API10.props b/pkg/Tizen.NET.API10/build/tizen10.0/Tizen.NET.API10.props deleted file mode 100644 index 581cd5d..0000000 --- a/pkg/Tizen.NET.API10/build/tizen10.0/Tizen.NET.API10.props +++ /dev/null @@ -1,11 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - - - - diff --git a/pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Mdb.dll b/pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Mdb.dll new file mode 100755 index 0000000000000000000000000000000000000000..5c52451e24b104143b6633f28e2f3c30bf2e5d46 GIT binary patch literal 39424 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 z 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 NX8-%||93U;e*!m6>Bj&7 literal 0 HcmV?d00001 diff --git a/pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Rocks.dll b/pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.Rocks.dll new file mode 100755 index 0000000000000000000000000000000000000000..213ba96847cb024b925ff85b802cfd9357b83c06 GIT binary patch literal 24576 zcmeHvdw5jU)%QAQX3m*RE@UQG1WC9$CS)WDVo*eGp+*THK_Ci-AsJv`GAGPTfPkdI zTeVtktk9}d@!DFg+Ip#YsaTa(E52H_)r$SVOW*R=YiqTwT)y90`^=e1u)bfP=lh=L z{o@#W;ed+oLNUVEQ2XVQG$x5-6BZj_@(i5|g~Khp$$HRyx5pyJU2dN612$Vap} zdq*x@9ZgntC9GA6aA#$EI3BlBl`A5ZiSBr1G+sGtUQ1=C)e#Bh=ljOkrsp>j&Cy(B zK6~h+bZh%*RAsI;?q?;I)K)O}ms;`G4kW zlgz?r6YS1oq>m`Zff)SRNt6fP&hUf6!cz>D?aR- zP9D1ObfViEh;oFR0hQ=~Uxxgb*jak8oXDpqhXQWV;BQrxUNPGh#26TiHrnVWeKSid z7Fx$av*J{_jMH7EK|gC2O>j}zZbh$XR+U`VFzAjSZ&zKes;bL4#dKN2p<*4+U8kn>qXdFv zkX7JOwXJZXQm7)1OFabm?{`@zLd|DX3~6mdKj;rA^(aT|(upe?rR69_#jw^!UQ2Z- zZ`mb*>%Ay9qcpq@pu19toE99y&Ve`sgjL19aBpm1rrEwgj#z8K0$Uj)t_2Y+)Ko(| za9~nc>6%pyV`^XqYE}Gq%C6Kj)UOyB%(t7H&g6v-IhCyscD2fJ)t**}pPSA_Px<3g z`s3l!cq3VZ%O;Et+bEMsXm?|CdT^`|L>M8CMe-!zK`gTL2yID^5Xl(T!ak(_QeX9G zqqMfbwl!X9xm|{Z{N}Tu<}=Ec_zahYf$`P7T6F_lz#wKv-0e6pF)gTiUKvcBhN)4Q=y9>lyVTz zx-aN*f{hT2wJiID~y*x%T&oQ{Z@x$OV zBVShAWnrrNg3|zMD$^}9%Z`njkaklpS=T=I_)-JY4)e&DYnImL7^S9#{OI$k`i81n zb*F8vB2+QjnhANul#0y?nOd<$5L>fOXf=BaGleb6sLs=^ufc&N_5j}|L%BZ*!Nx?e(-`-~ zO+D}rru{>-;8_s)0u($OR}74VH;X+7Y_-ajC_VmAY0j=$RXT%d}Cc(7O}Q!=K{2Yyy{P`KzmrCTM%kD+etchjLpmgYpcW3EsV2oyjQoD z;96rOTXDgjf=%1UKDNVH@_Z0HOx5G0EuG*wpBMaa4BbO(Y{kemt!2>6^A2sx&nXWX zIYUGF)yH|u+l?S{kx^Y@mRRu8X9SVGjA}cHnTCZn4XX_jH4oi{26<1%4kmu|VrIC< z)|8Fw#iVc_F;+r9xg7dq`&eQjywwP)g>>P|O#&KY4epOI)?@>qHX|rLYboO{3pKH5 zd2Fz}$tUfw|32e5S5vxGX8Q;W;{2}niP#DM95U;8OxPFR~4;~^TGM2AHIRga~lu{@!qAUSD z4y9oYDti4MPHaZQG7yIJzsT?#-@?SyipFop~7zY?%1QT|hVO;0;P!JYRCO#k;4ZlpY z#0)llqv63c%VMn&%(^Ab>S9&}v#w6F)-kJ+S-kq$yc%CC!GdutSTRt5W#h9(vY^Qk zh(`#Zj}J{o!vsgr&Ag1DObM`Wa*ZH%U&9*1HF(I;I0RfHOYj~9SP4Aktn~m0idPbD zQ9+rnbF|)b~9C!>(3pZ$I@ISsDOa$73KN! zlps%;Fp?Y4FJx?94LN6gdg$oUs!2Kr2*-(y;9>C(!&jBuvCUjHL!n>tSn3R%ph5LmW=zG zZF6Xr>?)C6{H5)64U%QIw{VawyS;`%vh4PTi;QDuT>{XMC-kKbeF$T0_Fm@D?+eZG zQ2P6X{)R)pAT;~0iLfhg+7#-Q;k~v$!1&cW4%OuERYp zi`(FEhh=d`Io#n{+&qVSd=~dJ%r&!@dod!5yWioO))kQ5fm4Z=CEqRbZ#uEKU+60x zdZ*A=IrO)M{+2`c34L{%u1=c0*EqyVvlsd*%GIrAZ@)v#F?+9dh%?OI?>I!A*?XNs zj5T|=IYhbHyWJtM_kTA{Al-Zq_^FqEarEdP3IcSbvK11~!@2>` z&V2a+SCF$@#mM@z?C|3ZqUCujj~+ex^))A*?5%`>zBRSu)xde9nUS&0l`R?T>%9>+ zf;#}L?*qtPo)TL(fv&r>Y8VbVdypK^uVZra%}_yNa8h(`!xm@;G)d8UUP;kKM!*nH zi#&c$MdfL6tT4Z)@|W;V-Rtuq=2=WTPH#T}J`@V4fo`Y;!z(i@Rf?`zJJDKxPDy=0 zF?H(}FzVf<`PDdU-3olXJEv?(eoiAsL7pt}QD_uO9ZK~yZ|`l;34$;hev3A|y|+8` z9-;4W=!b>A)1mJKom0urGp5`qq8~t{+)yj}QsydOL+tAhA^!?b?s6>85pzFs=qW_CVcDMeMf78cvOVE**1zG&y^dwx*1WyAV)04B+JJKw5|);ou=L<0&MxHSt&y918XN4^oJFs!z$NNa? zRCLCA5}0no3xVgNXS;D-a@>+uJWcGY^B5IhuhmPdbV)NT=6smvtvIE%5s6cdeU-RQ zK$(Uz9|fmQT7$9yWafp?AFEU_y`_g-Vkzqm?~7@otO{pqT^^|W5#Q1Q$-27S$<&7RAE;t@t(S0F;D&P-Cu^a8ePW_{RY^0!CnCtJPlLCS6z(BG6h(!IbJub48=8S z4(ez|o=a8o^;o;X$z0vg>tWC+r0NfgFlWo5TP(VIF&cao&G?KO;D+@YaK7jGEv~NM z@0j}MU{_xUw-@<9J#T;^Ja53nHj-~ZFt(2+{20DE=mn@6r&~M0FI%FXb$<{%Im zEa4~Ow!MGD$Dsplc4cg`MEQ92;J)sczS_@`f(N+EBlP6ke3h|01^q!3{VvQAEW57c zI}mMB8osjJ>T<)vy7vY2BPF9S%e>aRpvAfM}kf-W7 z)}O)lmMzKinpa2b{wQ9(&uzmi>@<9pFP1RbHh&1(WqrilmG;+7t}P#f)PtV@ZutvK z;481sVYuq-^JZ2+b~_w$8|C#r`h%$l{|Xk)nrhwoNiX8ZeX8D%amBQ;>*bn_$m1gA zO-%yfd+SP|dWmXT-~1^z{Wk!;Oju>UKXhiKpFv<@?)$cU&MFm$MW-6yS}|=Qh4}Jx zuc}|3u3wYZv$YDLRkK(5trv@>QXhBZ?-1xwa*2K^)S} z>~Ga^>bnm-zGm{O;fMg9!Rf^71XJCPLB)~!a(y$$R-#;=tCy;-`>M^-91s9CkbWgP*nZ$?gZOCoadS6S7lyoM`t z)^aMZNUj18&x%?3h_M<(@+eyiB|BM}^M#{4!e!xbi=MkIjjvUTE|8} zEAq2|V;*pQnN;j6FO=g^xIXidyQLs#_^jf`rT7?hVlHk{=<5Ox3%t>HufK>w*whTV zId^!0L5~Q$&-b5xgQf`HD)4C^OJB*oG~b}V`|i&(Xm&BLX}*s>5corZ zNr8s}4LnJD%H^XsgmZ$yn!hs{nqHQEU%M3e>%e`qB!^+2z+Z~~eZv2FK5O>*jDU~+ zB={w$WzcCl!)svQpi6TY|2=dJ3Ym=GS=dr!(1Ri!Wisy1z1Q!f-x$qk<&px1aUZw% znTMfAeEVVu^WPuBoSH(0pPS72fwm8=w4+5I%_wcof0F{7Dd=pm^QzeVuK3(2c9u&o zD#ZU{!M~9H9z+b$3yHu@B0V3i7_@W<^G`-ygWk(ye2Lg`iOsjA*HzF#zobW32|l#& zJ>5q};qL%L;>ox`GjtA1d=g@_-piaC*fi)u@xMg8-6rjhHh(+BN6%~b4>4$(*nAcv z%QNN$o=lik{I8IvyB`Tm7Q7EhdSX6PI`Z-@(7D+E2~hyqgT}3UZAsq$jX*OeQ~dh-{L`ifC1qteB!%R4LZIMvL7)^cZ+du?CB9x$j}O zMn5ch0QiY+#-AvDK*PEL)aYX4N5FdlHTsSA45Z(3zX5ogXeQl5b&Y=OzQ==F?uTLX zPXEK6Nq8dqsHc=}rJsXyZ{A+vyakR%2LyNH3to-9fM*N53~+uWoTshjGyFU{?TVt+ z?tr0D+@>BXDK~WLNz1$=3>SURrmpskG2G-CN%-{B@%}2qLo&tz%TZpB1bz{PaDWy2V^)6wxT&>CwUiW+6^jbA;MMZ{%Hww7FEM z?KIWB5fLgMr!@bJQ7EIJO+8PS80B=oP}`~Bb)_+s{$x{Sp8JgB=%`TrROi3Xz@{so zJ)S-0aMuWj8k_gDQQ=Ti@_ubd7{J-%`J48NA>9!wrN3#2TSB#&?-(aI^%~7T8z(x{ z^Lc+Yur>gD1Bv)-Y$<&>ExJJeL~Nb?kjI?r8Y z$|eTR9?v|_MDsK%7k9Q(i*KrVI$a`EKV9URYMw#w+Ei)jY;!uz39_Mny2mrmoJrT& z)DGiZa~8cMj`vf(xzwCZ`-R$0mlZ|KGwHzzs@_9GVrCOPV^dEJ*_ zx%9CuyD1Pc=h21I#qG2KR_0SoI@M37Lv{}BvnhZ6R&xPOkuLUAVR6K4p&dePrzk)NfO3jC;)UXopQv@dM`h z^s!AX^*?DYrD+n7Qsjotg8R zxq@};sxaq0vxA1))aTxh%#{?hDVO&j=4!g$rrtGO-ZgZKP2J$l^{%D6 zgt|;JLyUeR)Wyhm-CB&EbYvdtqDQm8B}~4dv-wkv}7cx{X%V}w~)!=bV$i^ zrkB)!a!*m3&G;%QPPvN8*-}yms@#_Sv~Vh@RW|i;;hCWLeG{U~yx%m6ym8uKQ{OR$ zg6gxW!Xc~4qRVaS_#qxp{Wf)*tJ2#=*W1+nu5qAlwW+xQziS=+$flMCYP{>{0h_wo zKiQk0$872b|5Q-VC`zJ~q!$KIuL^ZBZ&E9VMC`+@OKDRaRrgI=W znkCynSXlU6Of$5l-VIbKl(Mps#tWs!Xd_LuHGQ<&yOEl+G<&EuOS6ZhPQ{J zHnkAcCR%4x*MQ&8SXA&_)VNYHG0;=@NOI$)A-1#>gInz2y^CQ&KsRXA} z#n-V5rt!2Ub98zS=YHlC7V31dSbNH3j^e*0($8_8(6F~Lyx8DcPv8_k5Pt)FjTq{* zTr~gh;+IQ{%4S6tK2*F_{3{DHK5X!1a1|4!qoS&C6;Fmb_Hx$$SNIr-%r^8(CxtWA zX_D~Oh%835b%}tBF!5n6!%2^t(p0cj>avbT3eT1*pBd@{#ywl-t8kr8l2IG1qtl5p zmzX~gpCVDs)_=^!zAcwXsxkdna2wjv={us&P^WP+7OEF&=BQ}%TQVHye4M@W>BlGr z${i@T;H?@y5BUK-xPxMRB%qIK0Sj^RV>lhK1kdsqKSyAzz_9S6g6C*lcQW8{G+jFz z`LRjzVjk^425iz|$b3!O4rIJy8seWyt=bU(nG}{&bhNy*9v|>Ve#QPI-&T-cteXdC(?!aFXD}$PmDKdmbCr` zajiG#kFd<19K`!I+{yuI(xFX_HDABfc`Gp?_oc; zl?Jrw`ptP|fbZuG2YlT#N?RwVv|F@C^XoKCyW877ubu3ftu3UM zypeb&-;`Ga&N$(Gx44FuqFoJ;&)-XBAL|fLV(3e^mICgHm-1}-lP9n zTMg+8;`y(KoS57YfW1>DdDFq>mNCUn;Oz_$>m9Md}jx zPvM*-I!_U|GFfn!@Mj3TLg2Lm?+|#ez$XD;))K|5DXMMGV}E+ZW>8?Az>NZj3%pq1 zD1lc9Tqf{rfhz?r6le)N4e(`cOR)!$yae{Ir!(?L0=|UUUN0-LpU##wn9TEP{q&T7 zr|UWWG0%@&2egfWU9Q_@R==!YQ2L3hpY~!c-$PSME8P#;{A+ST?w9quiksd2bQLVO z>U@Gd2x-)PKvwAE)Z%`VK0#)Sy8j_i1AnVKN8m2vZ1$Y!KO>q$!H>E}3VcDw+OsV z;8Ow*2z*DNOXpgn1AV4uL90xM1CPZPLP;BJBY z1(H`R2%IKxxxhYwI|c3*xL+XUh`zvS0+$Qio$~-%*)MRKkMZRK`vmS3xLe?U-&#m1 zmtm#AX#$rE>=U?C;BJBY1yUaCkI8=w@cZ;M-tr7;r)!I}pJ{*6KGR0%XXuaVLDx)I z#I@el=eowV-F2hOa$n(o!u^svA18tWe*cu-F8&rCe;!wIE#RxhcEFKCb^t!;+6fpB z+zEJ-|0iCZ7C>Lee&YdLjAy7Ce)eMmZ^bD>!_RthfS-@?=DjBu_%fU@H2jPwA9x$S zH^#XJFdtv6RsinANh2Tc+KmRh6W_My;|_2Iq z7S=A*F4Jz)exV)Keyaao|3H7*Rqh_^-sry0y~BNn`#$$x_d9NPA36pf_@kk?J?d$j zFa-R?{Q}O5{83trec@h;GZjD0cEJM|;^Tq89y|;4;DqGGH<@0n4IItzDW}))WQwmJ z$uqy9bPWd+&-2#fJdW?+ZTU&Iyw>K|<62JNL%pA)=vp1!r0t@&QF8SVz2|yJ^ShtW z&U8PCGJ*bp`vsaZb#hzVgtiGZTDIi7=x@OrLJ>2!iiO&?be!W(^%~>abpozsLTECRHtG2Yz?siLO0r=nJz*)y$JEaFhM5=^jcPBfXqwXw4+ z)r0Glsi(BHZAgT>80~Cpn;ngZW3irES`Z0$G{sZ(bu=&D6puyY5k=X3s=9nJ2Jx8q`0ueYn$+tr!o>h(&mKHdDJiP_DAQuWhj(sbL&=?b-z(lQ4* zg)j-$w>34SB@H}{X-c!z(H)CS#Vtj%6}Lh&Bkj>x2*09i=}D#{ouQ_ANHVs&EkH0z z;WkF#r$Tt#TI>$A(2P|PP%~lz6Dz~9q{6To7?~3Zua~RzQ>mXDw`(XQ9%)m^s+5hy z(nw?-YbF>#$jvZZh;-LxyJkB^t0Jj3tch?(I2ER3Hi3aj_boF)lA*6f;*mrYd!+=y znK>B&TWm_IC8`=zeU_$Xb|(^%c&a%Z53h=JEL@F6*U{900LR+eqVZ@d8jd+kq>Nb> zR(WS9YCwsn7)|f!plF9P%Cn=9SO>}CROpm+XQr-gYnu^nUyJYTY{^Xg0`^$$d@G4& zt@yE$MNvqwkd865D4dA$B1#@3S}E>u1m<;Np~X8Sq-or;dG<=B>0P{FB`)UzP0X;m zZE}vaA)8c5%jvXDB0lpH(N(+xXM~fH3^$9CtYb?gN*S%@aH@SZqGNMJb9OkDr68%2 zI@Ki}NhMS0Q8>XPf!y345zpr$;U&A6n%=QK9LH6{y&$qOf{_NP3})zb^fDaIs2Qp` z(zzm%$k1?1<ehS)tx}YQ>NCpwIvnKL&D=P;~|LjS1>hP zj&xp^p!4F989k|pO)cDDF_pAQtE-)jVGTp6^`*x31>F; z1R-QfaQFvuu!nStJkB-J4$QUUsyaqg@ <=J49c{AfIm)y$*{rp$duY^RJSZ1p@r z9R7^V0A|(Y=nI){*OBqO7GgmpX~ot@9NOuIG(RiS9z%TNt3(%J=N;|bct<1=>q&Fj z>lUOH>{D_mk%|j3c5$b*1rcoUiWK`6~Fy`uvhX z8l=Hy2eG6R%Bew;FL7~@hT~j@KSS+<>1`)#L4?%Wh>$E>QinCH@LH^J90nu2x@O`e z(t=YOwWks69bM5_Bq4o+R>$-dUgB8M4V_t$72T^=@mkC9pw2me0B?FSiF_36Sr|=a ztENv`yv;?L!<4s;c z1B-B={8C|4e5IA>#9^3c)G=DB`yyQsiG?=`mOQqJ`3W3t+Ed30W?Ef6*kM*@iDu4e zVY9JlIG)9o=_&)7F|wc=%c~P7>dr1SydoNlrh2lZoW?k%X6B<%oZbeoh2Y7(C>-l{ z(yb!a3u{J#&rIsXgv2SSLDq9ibdyXBx$?T}WCmyMwj^V7!pT$<^1{Y>E3q%cR;K5j z?Rm%!C~`)|NqGr~7Fz0UAf9$M*3!KKcQULiM?Rc+FbSM`GjJGaUrlKz(xiPj^}BqKiygDrEIIvlJiDM^F3 zpOw*enST_P)aArFveLfyp!DuIE3#6Kf>u0p?!?Zj?h`T7DVl}LVIxz6)M+D&ajaFu zi%;@dI_zW?Dd|3oZc;~*ERK_&vv`f`k$SUetSULAWU+V}r_Y;m5^;#RR;s1DtIJ9t zNi}Y4kH{v0xURwtTRb(dJ2h|Rf^d9Q4ZjL5q5$jyny@x4a^=R-cPap2`pzzY~8 z@8UK(11Ho(50*(J+&O?{6X0_VMA<%8@O(q`)<>DGme-8#XiSvm$Oe$W!jsz&XCP$8 z@?XKpaIiKrL|6J0ndPWt3N)O#<4yN1Gx41JnowE|+rt$5h&dH^Lvp%Mx7=S=JFC_p z<)$RxXR6Gu#tT2-9dr{NeS$OpJp2M;at<}=_ih`q?O9*j^^(;WLgMucgc z@AT66dUcRb)TudS=4FD|sA`C}IBa?;p1N{=n3upXg}cF-9Ze*0Go2>o&M~46)6^JWA5BNCnwY959GwNC@<>y8pWdpe%igp3F?dcAKR1Z+@8-&Q=WC-z+K6im?~Jyiq#S+| z-mV(J&p(}J<5&4}@l6w6y7HXQ?|HkXNomPq-JAseUPheO;+63*=vAo4w&L)FUrPVZYv&FrTe@xTy;lzT@W$~4myoNH zG}su0)2PDM&NXp zPq=SrfvqK8hy_6{ZXs~GSJeTt6}$p`)1nukK?*E0N&-=EJ(apPyxi>r>NYih7&3p@ zLz*5~=2W$Hm$B9|m#KMC_grlRp@ky62+M|q00mdKo~)?A=>=)m{C!tI5Y=$?_!zPW zO>R>!@Ve0yN5JcXCk0-3trxglIi@S%^>6X_ZADK3*{dyHQ!DZJeM|Ft(PKdjb@4$E zn4piK5gH<(5Fgy?>&I_ciZq0_h@&SARw@(BAsqz$8$qZy5f|>31l?s|Bup(ZMPmL* zF4%9m0?mQGy*hpsqK|;Cuts1+_KwgzK0VN^=a}w5L!j?Dj~7w*7^V)~o1du)(qu(e zLEi(-ZUeQwqQ~7e0PyXXjtl;KF_K#wfs8SSpawJpgFaA4(odJ{#_P0)`Qy0$g~?w6e>FNML!ZJ*E0~6`5{C z`#n@Ri2pF;@B1JzW5>@Z9P};54@xYS_6Ftycr9-cm=>LuZH11 z(~T}2^nvygHwnbRO!XE~nP~=^)0VkmFC3A2gfL=WwHBJLEICA&O;CCWdIi9;WIQlU zsDz1p_Il%@Nx& z#xhXT1vUy)L)R=RxLG*oUC1_MF3Q}r=QQU>hh22c1ROy;gLt{wSC4)5+E<@_&9krh_O-yP z>K%_ANem#aHY?ETu%1Y>uo7*pryT5AlhDm(&k`nYB@CxSfUzVnI>^nC&$a?s!K`hns>LsgSY zHx>@6;o>zpL;ZtkTn}U41b?fnGQm8&-WZDnmSM%Q*4BLc>JKbKLd0C+LBU0cy^7eI z3m%%5DaeVfP{yy&TdB*=u@`Gn^HuWJ0`L1+J?(tc2*I=FCL~!D48epu$mfe74fh1u z1z=vm_WFXHPE@-P72@YJSpN9^3oeBDfhD?7FI|i;obm00^XLL!5n3CP8uWNcn2QSsI0-IwxRN@6_t(a!+2^%_+<`0_{E%eLa4SDKLNy# z6H4≀MqPx(B048VwE2ZCr>uZutgmy!~kK^!0V232?EX*m>A%zqlY@pWv_5)DJcm zNz0?EzUOeud~?k7iEqDnVIq8}RzDn8m) z%|4t;!PiM^p3hNkL-}+)$`Y2S566#xzsNr#Y1x3%s`zP$mwE?$7PQQ2$$RgF?^Ya| zKYQ!pkCt9`xc5(NW9F$#)%SGCrS1H+`qBhH#$0NxShExlt|R!`XKB{gj|lnFW1`yC zv4UF8oL+bGB(hsDrrRx`7fT);Q~&G84}M$z#fJ^9Tj6Q?^El&`X=>m#{TF%_7hfMH zX2oL7Jaame?N%ZZk>{*RdUPzT4DRkgb6-jEZ|>x`o_zz=cmWV$ULM0|y)#jkKvE#@ z?=Xk)iGYi!1tYcy_bdy5HQ_HU&jsBCI9vVIW&9@XBmD4IbKW7!mD=iWhA@f^(q3J* z0GC-P8m#jD$86l0#Bl%7ggcOxxMShZ7^$@oQod73LLSE5Nfc77Hu>D|=D(Gr!KW0o zqTsLk5=&=^&II&Z{hNsUCB%Tv!n;hGqdyC+CvoS*cDe?%(=07o6v7=C9{7u=Aw2c}u-u6e{det# za9%zO)+?!Rn2gLm)ydTV~q`NTD>Le}=z-nx&mY6yV zajL|auZKmBEq@k>&+}}%%w?a`{bq{qBL6+#Ct=oT_~Ro9_}78^&~|v6iNcrLVqYdn z%m>yR9QiMc`>9fII>v|Z$@%U%hDcRnCJr36FRRP#{*U~0so$QzB)?w!AL-%$ck2IP G1pYTyP`K*= literal 0 HcmV?d00001 diff --git a/pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.dll b/pkg/Tizen.NET.API10/xamlbuild/Mono.Cecil.dll new file mode 100755 index 0000000000000000000000000000000000000000..8a53cddcd75b517ec50b435101dcb441e37fece1 GIT binary patch literal 342016 zcmce<31A$>vG_fjnVsF8m29sh@9MC%0!Q+&D+yb|AW*^;%oT13ks)AiumKOz0tqbZ zm?I<*utO4Z5Rwoe_no|#`-0pD3FJ;lOb&A2FL^oNbG~0y_w0^jnY{P^{@*8icDk#( ztE;Q4tE;PfW{yAOMULk%thGJJgMym&fdd?jx~<6CgV7PfgXGm;bFq(aCe+#8g>oc0ucK3?;g^DfBdZ( z+I8sjB&+;y-)+?7c7Aze#yL^K;5}LxvG8wO#_0sMf_$efOnajEu;b)X={e#@r{WV= zUih3ViGOcj+b(G1^4T4D`_H6-k9-xM7vFu!>ax9X%@a<^~tq8W)C>}KjumP~&16p5eix?0E} z0D7=Mot`y;Lwg*mFD~&j8~XO`sB)j}I}@~CCeUnzf+ePe>-iZ8AEKolEx(cSbZs#c zF7XSQ&e}<2*mqraNoL;_ZbK;Zg8QVcURH1Mp@2$jdi|UijFe|X1>P?iYTdxHzzS_x zt~}eBTauZ4YxP>!>z}=&(s!Qg^>JTz-Z`#Up1os8?suH?uabW|aQlTcbEM=BqXwLf zU%h*z><*pZiuAdaW$jqMTj^`Xs^srMekZsygo>rGwznJHG1d>agAIzd;0D=Jmi{=5 zwq>gU%?e1J{B|#e2jOua3_`Sv-OjG%%b^33S5A#;1Nx?hv_<1(ZQ%Ga*BhFRmY^Dj zPdW9l$%(?;zQ{%$(GFojrE@mwBF!|X6Tq_BTxmcn&P7ipQ@4|g&?(N(Xo0r>i=4rsC`Q9vj zw`Ne7B%n5vB&G#-F6{~Co=UPg*q(jqjenWgv(vc&XGDrjBIN!DT ze!+d5cp13J+aC#|`HINdivN+Et=)s1B?8;+^cztSsR|nMTSEA{XYaV%#E{-fu@&o6 z!Mx*ck-tL!`JD)5O8T-^`f>|}ueVFt*p;_zTrs*E4_j$YzQ?B@GNvCgrXPxa)#+Fv zoO!pi^b^hs;fKV2_(Nx@@DjBh^}<4iC1cuiM0df@qB~xgtIIGug@#@0$=EH-H3e|0 z0AOPnjD^99iGg6{#8B-?G_P|O)(&bQ>K2r)*SZ%aK6hVh+^YWg2z6zpu2RfY8^T2y zg4;J0D!tiR6h)BdNQ?guIQsz6Id}*-Z0XWx#R9)rnKhq zO0U3$mJu=sBc);xJ)KyILIe*ZC;>|6szYw$bmG-H&jcoeI>P`4HD}@ng!>&2k?9z6BgDbfeUA1mD<#qnORd+o?w>#*_=q#LoKOtz4#o^w2RPIDOrlo<(K(cBHK4L zmBC=?S>rpX4xO6~CzC8wS+^XYCxtA##5A&e1&<&InS&Hl;3=O0UjP`O+^Pq`tP2S& z-_=pt)loggVD?I;a0Fj!RT&?sO8rZCtGIV3gPy$@Y|LlTC2}{?V0w5#&1T#k0#$FK>uzbobF&YC?GFYr+x%weD-rOQJY4@c9 zDJkC;kbSyoQ_1r!i!LLp*iRW}Z|cuW{mLBeUdw?}kRX=aLG_eWbJto4H#QjKP5=DT zz8TNou&g5)2P-Wv6PC`JTD%RBptPOso35sCkI82;`4>jgplZC z-kOeT66`x;Ai7+L)?fO;jKlX>x~4j+35Cf>wG>9oP&G4NsArJ+Mw0qGGcLCX;mWJ> zh6Mvu^|I05%w^?dj1nGbjnP<|G{ImRAh3LwTa`Nc7t|rL9q!DT!M~jLOS;Yr%$-Zy zc$an?yicS@t^n8nMvn+R%r*Mw+BQE69HTn}Ll49}5iNTo$aCb!W;gm_zRV4|b!I9t z_w{}oGuGhz$mv_JB*Vyf=V<*Z32c*SH7wiz=((!}u-V+b@u2=};!JX~qIixZ-MU+n z8PVEnCd+o$PiZpbTveHG#L_oPY@mLPApRfRCfqR$W>H0DmM&w+$F-C+@hbflc}SI8 zeb626F5k{z85}8j_se~m<5pd!>+)>mlZB{6Hkd>g9cFZ>bcWj-T?f*!U~3n~c-4)W z-^1loy>7gffEzzoYAn^aaU=11P3%u6ni5G4)sKgRS9Fi(#>W<%pcLOgvG`k|6P#QQ zYl8+Fw4vTf6X+(hKF|{JjTD&tRvDQXM3*q+oDh8ec+T6374M&1_2W+jP7sy~L3c-V z6Up95Td^1tcrwe?aMm;$ar~lYni~VU>oGrpGWqQZITja;LgcAdo0$S zVRkGCqMJ$oo{kOba-Cl1g!80&$N7wBFt7I9t^M;6UoVKCuZSfj#(b((OCS+l$lB8> z2>n`oyx`SeAUVU6gQ^dzf%&Lz5LCA)DoKg4j%uP0T}No@6rCEM=WF9@y+Jm|(&@SNBdM;%loj)F-6XiSD=tZi znObV|>RvfN|MMjO4$UtqG5sfXf5CQv+pC-(nqTNQdSHkNjI)k%NM zcfE6%LND5=KwnIR45JbNBg~g1f1^#55(oKX8A?2&MIOPX^EPhww@~Wr%ouCbi#9%@ z#Ux$IJ%YgzUk49B8E@q-16{gM`<_ASEYUvvNsIYze1l{^(~WQB&S0n=Mc3Uy13DM> zX)exX>C6LjIJ#h{sdmp8|v$%+hPyF=#`3~km1%ZFH1?#3B6O$%kV)~Z!iP3HUMoe723R9#B3LgW&GU9Es4ETs{6j*donE+8*5+68~bGn zv3AGBc)^deeUqpPoDEBGHh94uZNl5)#j01vxC!D%02kC6$~Imh{6I{zo_46>83GTBDtLN1r9#aa zG+t?QLgii3v`IJK2qGi3+x@Yn?uY@L6XQ!{MP{QHJ+jdNXyi8JXAp5SvUVW#^q9T_ zKJG3jMD&9-dzPx`yHf#x2Npo&|w@{aJ<5zQM5%U*DhFJ+q;%nw7KDDEjsC1|B z4=jrRYz|TShT$K+5GW2_&?0Ia?kmET}SpJ3(;$79~p<=!+caO*Y6=3 zy^fy(6Y#y5LjlmoSoH-}v&|3^vDB+pbo(_+Wz7Wop;Yaw_G1XO@-o+mx@7WZ z%y!T1pf_+m=gA9c5Fgtseh zYa6Ljd z4Ca1D2Pl`vM}xV)wIcn&T-i-hI)l0ONd(M$yL}N;O@K*LS!P1C#dFR8H@dvo?e1FM zi&@Z3a`V-J!)`YPI%M@bYp#V}ZD$_IB9vhfc9H-rEt_+$gZVwYWrNq6onY1aE8 zP9hge1ioV)uYGC#>aTEx@A7Ht(N@!Rws+EYdp6hvBk9FYfaUJIv zt~YW$!u1cX5mu-da=nP_QLYTSbox1z^!hFcz5b1zx%EI56+BdD{`3Zthl#j_Y4%?= z*io3CvBAN@G}`is%Jad0a2z!d`KhsPL;h4*ltTmg}orj4kKqT+_GNYJGRRcEITbN#IgT=zMZ-WDc>A%70 zVQ7MbzqP^P!t{@Aa8+TN*+Dam7N#Gv!PSN72W>DaOuyd-tA**e+2B}V`gJx~D@?zP zpjU>oWf(h_&y^>ZP2XyhY4)>ikOp2RIrl6BPq#VY%HcK$2M@48$R3mO{nWHlx{z*O zv@;CeY1#;Jpzb+B_Bw7K(fE*Xno;rbTWV_ZMu`W@HwU-=p4 zf|Q@wARX{s8>A^xYM2YMKV^f6EE9l28IxFE8ia%Q5rjQ=TL@$F4jV)|ZnnYRLT&3X z;bNh7wcG~^wJmZVEYvQN`*5Llw%k`0YNyM6v`{-i?yC#6Bjp|yY6r``TBz+W_pw54 zLhiLfZB*`S3bi4*PZnw=xla{pOXR*^p%%z}9X_G@YsCiGI_%-)10?$VKLf{k5>%DK zr5(|$NFH~Ym0QaFP_i|+$mwk4x{FIj(LM~SS+3`EiFWt{*P+Nx%r*U5a9V84FNE#} zZy`Gjo{oury}J`#dLNwVn!bYULFpWve_Va%RQFKSpIEL%auY?pmnph#@uGtZYVAGz z9_rRo!MY>#-m$KfJ@CK|3+rf94;pvNOLXIQ@wvSGaCebLVCr zPqO4^MC~gyocX5YesPj}$;_9Nq~gpYNw9b30m*e)l55qvW3=?ZxhZws^sM-l%In9bjnYc{49~5rSh{(ev0zbEk8Z- z(E#UrrdF^qVW7Bs;Y?O#xnyUs{f$HauT-ksQc zS}YZf1QUDdeZb-$oLD~nF%lDUL}C-xSo{lH(ra5%rX@F~itZtMV6%s0KkZ*9>sNq*!VMF62|1un$WS+w?uu)Uj?^c5H8DUdP1f^evRI zoHPS?6*XVEpl0FZ9@vto3~A?6QpIfcg=2o;@J}W~BDd~Dt=L_+SN6brl7ZbZbA1wY zXRakU%`(VP=+B&&1cRAVlVEOUR&vQH6h*hh4*&ej5eX=qc}fyoGJ{vtnSMzU@3jNE zID=QjAn2VLmMk(CD#G$iAqfu5ES03EC-LgK%QVX>Tj$`+pOV%M&-^wCu9{JUvyzlr zZR;GJ`9_ju^~_fYPXAXDk7hoV1gkS2lcXOe@in%t+6?{yL*baJAf;r@%xfh#YkiY6 zW$T)pxvd47xmmJ^k*r1bo7k%NbrX%+*0j7Ou0L>PC^^VA!8Ls-KYd~U?Z3xr7ihVFXFX7Ma1Qy87U|1>HBL8To{2k=wu+Jov1~`*9bT^hN&~^>~-Om0+68ghI zi{~%xg!jzDQ|Sd!r3|LK=D}A8I0Ss-Jg`)|;_gE2igum<)k0l6qrXL8QoeR%UpQci zz_76GudQjfq|c&UNwX7jceQf{re8{(rLJ19m(AZ1e;f|xbgR8HU!LvC;|rMlX|7yZ z7HnYYcHX2rfZGqM#rJR)_fhG`_zdxsbeemFzfc?v&lFhR+zYinH$EFcw}b2Qelp;Z zFd5V5sz$QSPf-6zU-JQOdQ#2QOlqS83xNm%Smyta-|7#ml1cQv4+fL8i7xw$j2<)$X}- zis@-srLK@27>5s_Qx<>>U#_J-`W?Q!Q}`0heGnd0>kkR?VD976d+5Ay6i4ei*>nq1 z8>t*2k%nfKluo>2C26U$GPSLmqJQ$E!Q3ZXCnhS{m4F z0Ez3~#Nt0vRdsThx`){cfHFNyB7W@6z{a%SSAs|SUG8+s3U0bNFg9r-?sbylZe5i) zH1{U3E4WP@n#@x;G$kcQ_G|11)E^d*Me~S+!={uEWHbnF9C)UV+Zoy%9@mH$Z6C&=bCY6BO+eF=|UZzV8TmmWhguv-CIYSyW zC6-FuR}w{;Yk;Q9y&Rn*tvUr6)u)~#LnGFFCMh*Ku1l0lox7;G;ry9yO`l&EZvozOAvgMHI)QkfU0|>$)-FGVlY!VD@$d-m=Upxo-RgI5-rL%O*`1qMk)b3age<=fA z5dqP6a!)1*BPd4M2Xh@>GFt?5*>>1%h&&9$-=WsUvi7I5id>l;w4B?JNG&s0YiF2O z$4m?EM!$ofg{<;=d@Q?tEGl)@*vrf9xDZQa?o4t<-)+^e&zFd`wX?>Ac5VvIFF-Ta zH@_*Dw$sg&HPWTyAD-%e(ukKFiCDnu#0RzRwH>M|5Vw|x7vA!?*l z8GCj7J@OPvozv_PIoaG@ayldI%8hph`FJOprzzp&TLqqC3iS9zfBU9BPVaxQg}dmN z?vf&5Pf!dF#8h*N!Q3xMHk)625yL}nW2=ef{Ur9}={w0D@chSJ^~b;v|43@SK7lF! z4HnHqkF2I_`~z~;&X!U=nPNuSXmTAJ6f@fRzB5(8Oc{1RVErhRZS%T4FFK}ChA55 zoNAO=$<_0JMl%i5vQ_ohFs+*`JMF=3IU&i0Qd4!FpHgKddDzQW9hxqOX8t23s#|Rp zUj4-=>?YMQFUqgqd|3z7p3bRRiN-9Y0#tV7az}W?-g^qPfV}9%tfbhlWYe3%$lQ6dEfACLqr& z)S9mZ)_+yfkpQRXB<1ZA^dc6F!ASg1 z2qxka31YM}$99C6@>C&c+)2iGA2w|R&hL884bV#;(e^2F(Do%>jMoz@wEj%2BsL+B za)ai}Ddfd#fsZc@TsOXwP&`X|t&7gmgm?qdLY61*I8Jncq<@j0o%vCt-gXVRjh9N* z|Demqy3yqlbL+2Q`!xOnIq3`0e-0<#mu_(KC8E+d#{j_wgT5IujpulV<6_C}#+P!# zJl;o!0fQxMrv-CIB|whS^w|PsbHCOrPXr!Y798)YXW3YZ-D|mV&Eg}`(KhJ`0=59eZTF^~x z&@BSu%wBw}z(Vb{7usyMCD{<%Wtt*J550v69w>wx9-TnX3t$w=lq}E7A%}sUrHF9- z1Zs+V@q1~+6sZlwdp;XD?3`^BZ1-8tKU(WruYpBaM z>a_xwqD3wG>Ll8&(fg7pUJ01;x+Kc%h72k7+@y7ex1OxE9lC(Nzl+Rbs}_0OFMb^I zHJ>$Be`1@X{c$K|=m^TN>nZ&4;)@7K;k_w~%^-(Vo&*R=a}jR%fSc56vHeW2eM9*u z^)sh~i#^bG{Xbt&Kl7EcQ|o^+Ww5&`b0suu{Z|R``uL|$972{u$S)}r-$07;&er`k z!So|ta|xb<6wf(HJ2nat3-SC)@I0BbHfcOxZR5EXJpGC%IjeIawZD@Lu;Bs9jTLh7 zCzJBI__a`D3`CheFWjXq1F)G)_g8<>kxLryK(AgTakX zS!-1ahhJ1Xbg|GE?ci(fY^>ux=Vtw=kJ4$K1EJzadm6aF2c1?HYWpXGkc&4-C+(fP zt^;y(!*FbQu5qH!)|K;f@iUlZni91`MmlZs0hV5VLW^5=RwK{d{1FSGFtexffiaapK55zayFCIg+DPO0)FI4hL;eR=3Z(EaL{ zNm*Fh6!c9&KUFZ(q~m;9k_u`s{*(ASj`aq3;4J!@gx%;7xhenFK;NP8&tz_3SaUFK zyq7uk2!egHO}Ux16Aq{+(cbv!kfrToE?uN-U~_vWBY9-Z$~>~L9yb{G`f5SY_`2|9 zFJU!#Gve2C4%>~UE)H8~miVQS!fDylssYciFY)8kg_hS?;?DpLgiEU%5^m#-?~;6H zFP_*ce^#ozgj3~TAmvZ6<-Pci@Xru@isv%Z3`4udqkCk!hkj}EICo?q;jMI_7rz=z zJTi3OLa((&dz_ zg@!?}3KzPb0Z^OX<)EohXb5C|;>S$YXfqya%_zM!9{MJTh6*IJ&|dUyd;SVAOZvU) zmfsR=o_uN2N6haI`V)WYzJgv!Q;O^Vfi{3v8JF^iO)y43N+iC7mIm>Q;DgGmtLJd> zYua=()=#Cgh1cDVDb)NS15PZ zE-@Wv`k>1U%F*!?>Q8|#JdQ$RL)IzrXbK=!cf4O45N{5i{y!I?f+cT{{!>;A2E^s zmt^gK^pZ$beWwy-q+p;W1>Ypw{62h`0Uhnv?lnPFN1Ek0q{{xj+>aGHEb~xoa?%u| z$<0R76m0y3++{f~t1|$CvGynGC-HUHjJbufk)b-MBSj(npZ+jtO&7p?QK&u0nNZ%7 zaVz<#Dxsj8bHgN!FJ)=$=iT~AOqr~huLdqBOoqX+YHC;#>)%GWMqD1!KADnN%BYCH z35eWBr*e-@9qwABN_$UE3x6I%ZlsuN{0-vb&q~B4_IF~@D$q5t>HMB7Yw-9Vz_eF` zgAc|q;ozpspCbQa-y3}|a^^*26ij@eX<0L(R{t*$v5u38L2zXBR3&JTbWy$L_c~78 z_zg}=`rg)&#AE&>^_cHq+O7XLNJh3vO5Dp5sO=AX5QQSs)9%0ZZIn@823dsfV!a2| zixO=l{*@&B14$A6cRh3+C+&+4rd3uVnbn!)wr{dg40k_fofd8=7_rXQ|BekJ8+(-? zf0t;a_;#_G4iU!Wc%oib#i1$_@oGG3nmic)L3(_NiS=uY2O=Z3*@IjnlVVpLul&}r zp_E_@;@Y}vM32C$X{yFd$_f|Pmf`jDD32|fj4dfIx-~jnS{I$Ezt5K6zWIagLuRl^ zejRMfv-!KmJF|J0Rz&M5(AJGVF-$N@Z?M$k*Oq3B{$0^Ev<~kOuMjBuqC%aPP`7&Oh%*n6m)aL@}BZ%y*h?j zSjA{WXv4b856-sQ3Kw(VBN9E0mUQLEve~?Lk&$=JEWIQw$Du&ga%@@YJCFM*ZGMU< z=v=kWJoeRbe}qj*G)RIv&XKUmTEUlf87gH34Bv;!JMF#8&GRM~0LHdl`vc}tQ-4b6 z@YpX$_+#FIWJMG54kTj6<^Z&vDzpj1aQ=i0N@hzuzdW4CT_z40e{Un-X_Bwcj$L^I zLPtnw6jQ<6I8^sDk?Y(r1=!k<6Lw9pjd9J2HgA55UAiRvZNi4sTs$W9<(jN9NX8rx z6&D@LPy8bA7u2T8?&_Nr~`U6B5C%E&$}v$E@El^lk# zyoWLV4Ws%*2Yg9)*Y2Q+SAK%t5V9gAQw$An98hwciP>yVR(Q%ZRXI$|dv*;Ju zKuSxor@E>74%>Wqq{CBLXnLp|{|Du6m)e_>to(QN1pEf2;drV_72m!oWVjxP1;EOW zu@K9Xq`p2DIbQMX6J5D#E?x`T_&FplcxFhfga_o6P}p@XL%x%uESP z2GMiDFR$rQ9$Zbko=Lkn-6pmTPw*&OIUFZ(qi+T#hE(sYni|{9*6zxODA0wroItI$ znH;m*P{@`J$Yr-M>u#2(O_?>7248%8a;ApyX8Kz!5hEI*5e~7Omt}M14K!7H{$69@ z(wV=M$w2gx_$9P2D}(J0a*fp!okp4X+se%LU>+~3B{!Jr7kmIb8~!jERmY*{-7bc*qED2a5WD z$7?0GpJ%?^U4bNtA3u!Bkd@W3dp`7FDFNR0gdK92Dxz^=(*R z0qAlC_MU_#9@HvQSM zhZoQ)S(Mggi_$8||2tZ-_vDl+@^}%n8bU-L9?sy<^?;5>dBRy_BdfmtOZJo>b%58f ztq%4kV(lw0ekvHP+Fn>O;3bniloCZDiFKCQVbqVn zSRVSi9^Rxhr*%czZY~7b`o%3}(VJ2hX$66|)%r4g2YX7+swFan;xqlyJ-=T@DAJTf zbn-|`Cub|&m0mT;*^QQ=oXf{Nn$cFvW{;}fH=F16%^^?FHk$=2jOKRVh^=zjZhfPU z?E-3CW_fHvQKln98xv<&WmsOR(v^$91$>m5RqTNJnGAKY%-|&<_rBbYQ-?JO<1B_&JK&jd{L~b{u&Y9q z(fXeR2Ypfl(3u-rw-=VudLL$8$%SF%U`IGFV{MY5K;VEPTafhPsL18}!3 zM5hShs_W;uj!N}O3NkNAvg-PMTkFIXc3yHS^F@@W)HCY`GL{&7+03@~)nyz>UWx z{tb4)t_vMNhZra*EC49A2Ukm z0iUaGapPyv&Fo6VJf0oQotPZ|;?)nya=8<3NRO%tHWu0nV?o|37NjH_{`k(nL({XM zss35IA=w*hK8+mK6C0mRLK1$a38UbH_&=##S3yBa_XRE07wFisma^-u7*gHE&X=xW zTpnfMG>Y!F#M2yY9+AN z9ZE+zH4(B9FrZ-8iyGio*7}CEk7FzN(X~Jm-psW7Ydpc->aQW&UqiOPII^@G$}gC8 z6@Er%PUuV45Mmx!-&|*QY?-fbRLYh&=(&Je!PoN#@z3DN$S`Gdmch%A;E`M$Fqne) zhnS)ICQzBW{P@up-5KX9%G9;Ktw2+XKk-3f^Q#Z)K%}efc55g&J_sOsYlfQ<9oCcUVmWpcG;nf<5RStqtRDbjhIbh~6UG#h=omq*I%dWExem{|=om@P70O+; z<6Amr$f%Z#8(}rDu_Bu}GD3Q?-I zIPir&xB(>AIAJ0@0w$~d8NC^}9JV()5`8M~vRFJnHjcamu4Uu!U_UmFVyJU$ED+x` zYtGz#H#6M4Y;--SjjF(*|Ff38D89mHOC6P}ml9l+)DsLNM$N6@Ryvg*#AWdLbzZk% zmz=h2V0TT`ubYjBNzdfs!{LNEJz<3W&Ad9*ECN{0rF2B4irV@TnCtki!{|mrP069_ zj9a1eIYOsrIxnanL8bzH%bEwZJG;GdDS8rID6?yDvLCM}T{dgWQ^jJ2)ayjcjyz3X z05V?8A@4a^hhcn zFL8?Fc47ZW$-iIjF;fIqsfW*R2&Eh|br`$M$cFLNJRfS>vTPJK9%h>cls5kMVVS-Vy-4xAUjjFtoE(S;5iDV#WPo(2WlCx(~T zDsNsmkC(@{c!^`OweRE0d?*j^GtL&tAJmzMEL4qyG6k!dnjdO?h5}#QS2? zx_F_Gs-%2$Tf)L%?Z*}}P%y(l{2jIU1YsZtcbIY533`JZI%&n;C^6MxYoQx^27Mte zS3O2BMg^+DbtMzlS7Tbq_Y8D$)MAMkVPdoJ}^Vr3hi4XOrakUz$P zRPMYrkQM-xU1faLGB&!bv7C6n{dFtNBCBKKL=$i)o@@gC#L2a1n_#%E*93xzqby|N z=-L@3I5<%;f!f5uwIl7$lJshzKH&oI8w#RRp`?JDCx~9GpQ`t61_}A z(v+OBO!7LU#b4+;!?byu@Hn;a?8W=izpXuxmr!2wGGt^;XvZq&rZkr@DQIsATXm!; zbc~rguHUVWwdp!Ip}lw=r>E+WlXJS+oYWyGv<}}9JNyQzqf$%z#EtZ~2OJJjycLKX z_T0+}sJ&848HCbC8FQ<--zfOfe#=Uj$e3SWj*bi2efS1gRNl?`nwzwpuLhV9IhAhb zD@lN{y@9@2R(3mNEf&Q4kx80D-M+qch5d8d!f}<>h#Ay@+}k@0+Q+Pv6lp93;;(hGzRGl#Nu zV&;d!{Q2QzbRM>=B&+Re*T-LFBemQzUPY>8BNbza_3gl%zZc*O77GR2UPrU+|MXVDzNTBbfwuWm%NH^*6(@7m= zo8)xvL4!T3FuGT;-|AJCOmyT=F<>uDr24#Y%lcr)&#_43>BUch)byy579_dx9ykP1!$6+oqk^rVo*xvP~t2 z+NN#0{`KUrIzo&uhA!Cc=5A=oCRcpzg0fl18GoXznpN-xmjgpTV z$?>0`+uCA2Q$@`ppJqd6DjT0k*{)i#o9|r^>hZB~qdSpS0A~Rh|LM*p-QKR!%f)Mh zYD~XR?*eD&2Hn+AeIR2S%Ld)mx!W3HKa7$p6!9EzCDc$`F|)i>h34n7^`|nr=j_EDn-;$WCz4ocWp{|dthr`GwE%gg@#N2}KK1mO`R&TXgO%qp zPW6~_rL%p+A`I%vK(`#!Wo2NPmz77p^n{wqt?%G3m$zdfHx0VQNCQgm4#=Uu}v zP5fc#1|Ip1d9@lU${g|U3cReYoa674dqJ7boD|P_*Rf}V@AD3R zy;kBXUGv8{`#dtnC0Tu7k=t*EHisp2XlJ_Z3GX*B>6n@svZb*sMw*MLUukGM&n;eUartc#RXqFNj%p z8gv!1I(25v)LEIB$ny=8=zXMAv-2j=tlGq#x%x%a)Fo%-y7N4cL&o@GAj!P4Ik#o< zXI{Q}8g)p2XT&e#yp(#&S~5MY&7F%UZ|;@y)Y%4^*RG=>g>1Qg3HX{PfFRqD-#HF@ z@^XvTY#47LGh^!0)LrLwgF$^?8Sa~e16d`;4_fv6&X1}8PUY=tBk6MDb2FK%LH$y0 za?tfd@>Tk$ilW+}K2E>OB`-INCVYMDl*Rg1GWOme+Zd;mqtjcjSlehAoVqHyT<1M63K57m}cQS3Vs}sthQt^MVed4@A+ot-ZVh4R?%{(1; z`#!fyl(w~O`Y zNHK_W8qdbA+=Y#6^5$gWzw@q~)~V99JiI02P3Eyz3a!zHKdK)aX_+Y8xj zseT3RW@fP7uoSvN)Ua7@|||eE*JlvSfa;d9=of>4=+B6?lX%{IZXIPayH)w zZ8m@C+(-UbwemOEUstOmdbUzHndV~sS=b{HO>2fcSI z4?ijtMxT^lMI_q#WJ<_9(JT6P3Y#Ua3${;?i3idBe4#dwZM>EC=cA7U;}CHCE4nTp zUr9FWGr5Z3+Jm!}> zcV6tpkCP((`$z6PahZxuPI&Q8Q*oZDOvTn<*$ZVn{zw(z8l<-85FEb+tBFrJ+|#m} zN>v#P=A8#cr*T_iH~9_{F7y}czX#KZJ}n*A|4g{~CRktr`mA&~Yv6AdIJ|cz^>Jx) zc&aJF%v0CbQGIFua>8zn$EU*a=3B_%HJYTW!BpD+L>{+pMeAEhXugd+m{zMXax^7F zw`XUg2j~XQ+H?jD$&ibmOJ42s6oLc3=ry*rk)HzcRu+18n-yI)2Hk(`@Ri`Iam$@RhCShGH)TPU;CUmfIWvp z89`gj@^*93I7DI_Hf)L?W;W^Zb%DW46y(hcy2$99mT}(OInB^&S8bz`f zov!;U>(W{)xE;9Lltk3lS*}%AqxB)`F>~O$teHin^U|GxAA^%>WTWoS(kt=vM0ku{ z{?k;Y>{{jSRiO>mzE&!zk(uvj`kb$})yV`S6V7NcGd7$m%CiL~#-t)cDPBo+iRBbb zenR$&qnoKV`V6HtHrtAcEj0`eZWSIZy5{s-t4x`HSl2rDlD9YPE%bKwc6n;Ru~rv< z!1_FxGF+Vd)2|>M#a%qpS8-uIIPc;50oU~J_`#Vk=Ru-RK~-V;`vNgaSix#Eg!A)! zkUU=e9rAZgV;#@KAW!S3(6O$XpIm!xI)im^nIfjD+S&6nq|wz5pP%-`bk=(3<+c=a zZlYhrGS~bfGBT2HeqL_b=I7)VG{3+N9V|NJRA^_cB{GRoVPtauc`|7pp^!vW;@(ys zBx+|>d(-1?MzAKoYv#XU@SC;L=U}B}Iy2vCcIIP}f2l}{(6WuZ_qSBjg)WV7S=8});L$blCgYj_OoxT(Y+ zA5Iq+*8RPt?gQTfV|T9}^F62amN)d|>-f*Zp3vM1dWNQ_vvyE1w0U&Cjd6pA#lr3& z94!Gw_9RqQH;O&&w_2^5;&HG$6NquPir(}?33@(G`mfj@3F z;5}joRHuNm(?I{+Qj`tLo6qo4~Q>q^(Bou3n;?mOE<67`KvKJPY z>YH+Ux{KW!@98O(>vsw}dW*fqp7>=1cXk$g$Fjv<rgM0Jjb4T)ZTAOM$UkWb|fs4ny5jFs~S)gM~blgStQYAr%d^7I`GT1FF^Jhm2unRd?W*qVuH~E1fZaKBN2zV! zv~QuCCxU~QMt75~7*N5!lf`UL9v8x$Jz;k~`W!4C@9ZwvGCc4C@YRwzoGovtOR*ld zFQqEpVU?@DRqFf#g^DE4}Z@{see6bD;wiAI=JA#)hHMDG z;^M+@sa2J#97z0K6-^U`O;L zsRB#?$1NTYQ5V80=OmZ&hDG4i=K7iF2L#P&CSELRY)%;`Z)^958~uztsHNX>>kKNV zPGp11X`-dQ=!by1YD;|^NcLuV%Z!rQ_M0a9Q^p@UqUfG9=D8>Fj<46zkP-PDs;T=l z(%+$Vi*H9hU7hoK)dyR}z2a@Xm+UqwU)yzgqt~%yl+zO^Fc!+vWck3iJdE9y7nS>S zFKbGO-aQoj^0z3*JkKnXSKy=eqQ}9+V|}LiidVj|?zV9;(djqHOewa^Va}4N$S|tv znPoB0`q^bM^TE$SDgE*by$6ws0%O2+9#^WMi^p|jV$X1mbMQMk>7TM34cSvH=6KwBz%(ze^<%t zw6}|UhO5Z6l4~EXbzFyW9nZCa3%XTbH@V-!g}>cV?}ODs=TISZszy3D6+SN&K0g({ zAQiqa6}~7HzBm=WBo*G23U5w@FHMEFNO;k+Z=M-Mz!mCDZ|G|Whv?r!ep$udVX^jI=tu( z6gsY=@1xmTFRKWm7XsB$V8`YJbiY&Smb!H_B{Z6o-BLAL9to~H9zRoXo$RVakCDsN zO$2Lstrsf|Pf&FO_*na}cR_i|kFOLfwyg4`ejo|$|X}N0sXQI}V zG&H;7|F0A-U`hwu0e-$(|0Vh5k#9xTl~`@f|0b0OeCv;qY`UQ*gV*0YAD!KLKVzcC zTvUHOf##pdJYsS+|6;4Rw2VMc!{94P*YX-{>^CgIQB{`=+%PZdN}jgn>E(ExN!Qg;81YbiBTMVg2F! zn)OZUVk)o6@d~?OEXTV%-vAF-s|Z27d!h&5zD(r#SR6y<1-Y^yGAthdT-LlMUE7>d z|MYvPv;IbqB$DZk_ZS=oX)IeE%Q{L_TarU87|zpTf0$J4)J$pZiefO%E7PUod4;C` zjf_0MKWj~NnbvucrJCF|dRB;L(ViVYpqLw<3OKd;9dVQo|MqvgocJs4;MXKriXSnz zZ*Ys>Br-6IXL*@HLkpD!cnl5x*-o)6s9+Wcr$wAINb?3070K9$)oCUL)F| zp>yIZNcQ7%BvZlF!K?4RIGhgC*#zh_KBXFJna;~21$kC61Y%*2i1&h zlazQB9=Or!i}ej$IF+T{OE{gTp?DLSt2hJVOC)fR8~>TM4gd3>j>D;cRMY-YCSNg7 z{q%Rz05;wUa>Pval&q(Xp5oj?D6bKc)G0>OyScj!fuc18D5npa5(qpo@OTZ0MI?6J z71>l1J)0Va>7nx5Ospvr`a^_MoQo*CNGc72zob~ktQ7EdK0{x zWgXwcmhZvRviAsvA98}A=nW@ed7ZJD~0$x#h6ZD*F32x4gOF9R*T+ke3WK3W7?)PnC;D0g{j=1SRDKS;8H?%D*J=L2jX)~b5ih60$-tU zOE~I2Jmh>dmC*iaB1T?3c^6BMpzVw__;Ug_U6KZWUchHVh^_Do z#3$b&wSAG0>6iOjb?GCLRQDy)f*tH=3^pDT1eQ-J@RtQ_L?WI0D~p347O*8Qh2#+d z3vu(SWWgQ|rMZO9EIi~w%O(6_mhJ^SVgV1){X+CN2`1E~z&KeJ1LK)8)L9;}*S!GjZ*L6=8Gj4vVtq{;P$q*7EZ7!fQs5r|E+-_U;H-w{2^GumaPsZE zFSH>geEpS$WGL0MytF(#qutiyc5iE6Qqh98a*B6%y`TzUVQb$i6o@ME^;cG%N&#yG zC=fkto)NV=XlnO<>`$s%(2wa6q}})_sYf*s6^gAI)KR{bgPe+bx) z^As41C^XV-rI<oezcXvJy zx9ef+t??H!1$U@L+o|FVg4CvhaL~ z@cbVHlRi&@|4YDDEvCT#4S1gB*ad*`MH~J}=>JU{%Kxej3v?>>6>S)hHgph7+K>Xf z0=8{Pf%%}rJhAnOn|UWgXi;b(&;Z zYuCVJ-VZ`uOQkN}*wLyh1>SFQ@Hzoo5>mPMUmSb@;7UHNsiuJ((y**JkcgFoE86s( z2Ym;T66`1meKQ0TUZlWJUL4GqWLxy5avuzMJ|TwynY>e^@lZlKUjNT*-g(x7PLrQ} zB4demif&lY-ov0F*uf^sVB>ItiO{FOPhA{*1YjN|u@+-0|9Z(U9c5+kNaCiwM-kHY zKC#Wx()$aHmb9d4b3Y|av?ji`?TPJ;O7(xdcvxU>$TT?x=*_LR>4&Lk z-icHi?C6!|okXx@2c+O91Fx)0s!S!EA_-HAB%CS<`z?~dQx~mKmO}LO1Z;V7I`Km` z+Tr^QA`D;c^98zWmZV_Eav^?$ps-3j1wLbO@RM+TvAh5=N!u zGv%jAgT<8Itp`5c5?dLM|Ds=8Oiop{DAtAj`owr!ow@++JfDfxDeXZf^!^LqQdgo8 zQbwCDr0r-(fyI_fGv~v^jV-ySrKQyW9M_Te;qac;CT1m1aW>C1w`ZCgdzk_}+uSyq z+d1ZTuH4KQ%Dm=!iMY`woR-a_CG0nkkz1yDtlXCPO&1*8tIEhByzq+2BJ}k zT%eH^5&qa(lO0RS3`LPdF471O`0OLGi%pE@3ng}miSZGh2gJWhfZjLjpH?Zf9=C$@PAJR>!*rDSP@j2tN))$RQ+Z_h5PCMcb?fku3xYy)2yzR zd0+lG>vxpU*pT1xwQfVkqWPZhlT1Xv$kFe)Ld$3?a^hHDtVb@l)vG>e`H=h_4xL5xYZtduD+4lId8(ksWE?Sep8(&L-=3Tm5D)q+~6E_*+ z^92|47hi>eY-GF0TV2>6tc|GOpA8Cam^^J3T`C$%CYX6iS4q-kk|fiC&2K&yC*L)A zmJ*{#^h0%k>TS@Cvgrco$~H*9T?go@Ht2;m7b=&8YxxbvhJyG3w!`>zR}j5XAn_-Y z=$qOlpD!glZ7VdNCGd7hD7#7fBpN+HxhB(!jIB<2R?d7A$8bPeG-7t+a2e81rqZ4p{IpCDo3FX6|MaQ#A&VOgTa z9|abFgW~12aA1y%(C9jcLL>TMl)(5PAUOE4tXSQ2eJ>X-3f(42=5XWa4LtM(={>VVUh# zjhT^PIu)%J#)v>zJ=SfAo#Vx)@L+FzxoR%4y|d0X>iAHbkGB~sviQB zXw#6bbYrV3-JX6P@L!Uw@_904P_OjYJ=72y%7XY^G)uqLLAz^c(03A-R$W|s{QBT|Fy->Lyiq$g5sCJ?)Xutg8xB}V@<=% z>WGyb`yJzeMF*Ou>P0VNpmKi4i>?>uaKF(oN%|H$-TAomE#MCWRX2`L}l zBx9Z0Zvs0ri`e1WZa(o#X7j|v3rOgs`WwlZ*b^Qhj}C!4 z27~cYxO!&d0pt*?wU!l%JH##9)i=XgzjysvOc2Ga{E<;ATp@@^*zbcaG)p5X|(mR z-PdTe^|9U8Y4nZB;C-V;U!O$9RP)S7J*E0PBpO6b$WdJ?e0!tzqdW{F;~7g^R$>gu zpE3&C53<-NWqv6A6^QgoKsoQN_3_c;?SM$YgHv)KbfzcFiL(^jx8X1^Jz)ysL*PFIqNZaMlGha&> zb1O@uqv;(lzLS!Vn2$lHsH&su_`oqgqbS7HBGD0=5I*x9u`OFF@1X$oh&{a@_s`H~ zS0|rwKKbXGSpmu8W&Sz|#NTELm*rSm+yA(%^2#dC`K9Ws{I(~dGgOmndpT^ zhg_gKtX*F5^|W-0P&i3ZWFGRPlvD=VX8VUgQl9!9lEWpRvYw>VF#FLNu)A~Y;w zARmn0L#~8ZpI2Tb-~3hcMdsP)<&a=`rIV@QRZgFs`hxQ61%_7$Aw#b@%nkdYq%zcSKooJD~;(^nXyFgO70MXykHd_!k!qDJNFN2Y~4uhi6w zl2pUc3zDeOm(NO~cS+_TdcLqy*6^1ge_zx#e}^oMOVAcPyiwvUfMgt7;+9zUUj#wX z-CE1TWRgd7^u1Ujq$50bc!vmS-jpc1Xog4l%2cb6YKp8r)-(B4>dff3mA|BQ$_KLb zSs%BuBEp@8V3E{0v{!;W&?+hZL`T zi<`03A02PU(m|Z@ls5>bM$k%IM=r*g4RtBMQfEIk3u2k7lL5u(3nxFy+ppq`(DN$V zJ63UH9+(cs%dUP?dwi)IKQ8gC8~>a;MBum~hz>{n zVQA+Yc-r}D{)!Y>^LH8A&sVIB7+=+|ua#k@kdPCaWW@O9>)w(_MojfydEy+0WX($45%N3Y z82B=;qQIQ5fYWVUA;{u`!MsrRKh&a$IWCMbAy6X26vW%2Rq~puS#^tN+m^EzA0b4_ z?AV7u-vi8<%R#}JBGGm!6a0m|4hgGE1Ju6fRuJi<%ElZ>+$WOP8k zzTADl!%9#w3df|NO+hLAB*K7 zvpYOI4K+58hhDrHP7 zcjui)l#geL9mD4yUk`7v{Wl5q=EVkO9j>mt8}=h48nI?l3uC4nP>D`oN9TQ2@Qm}0 z$*TDdR2Zz6ZVkEa=6ccp^4iCi!+)pc1;@0#W>T;OucXU0X7fm1DJxe{Ic(yZ=@%1n z^}!=vcq9)Vjdf-9i6c*2U4`<>5|l1eXBfSKrV7Npl8$tFuh+5Ya`V*F#XMbLUOUs1 zi_7q>6yHiaEf)962gENU+4l%Z*I~ziEANDMFadcc6~mpQ=lvVjFB6Kna$EtI&n5iq zxt%TJ|p<3yzR=T9cZp^eB zn&%}bAo>K;(fPW{#YT|}G|(wnS-+z8&Rq0Lnud9~8G5`vqw;e4N=Mc1yu*?igVk~_ z`e;jBWC>_>eLi{x#SJ5|8=K<9DOR3XsTuNoUT8RX2z-rlC z^syFxrtUCih7Lz9Vi+0n?irEIwc!1x;EgzSiN5usw@?llXVzMCS_ zSbGld&dQ=WizDdP*MT_swn?6zYjtxk5!1cua0fG0z=ef(fjEJ7@HgQbHl@C;c$}$R zM1HuZA!a(}jZ{8sz1_RQ^lZ z7z-Gl%badVD))D_xecxh$SP68?dZ8OJd=3;-7Uj9?hbF%z!R0~ot#*nfBX@U-D-S)i zJPz^Tp)2g$H+`D(PoLPFHCJ)^c>6}vN7}bCy{Wm`Ts0qObov12pI+N^IBTXy4bqr) zroNif!_5Oq>;mq%ouq7RlIJDzuz+V*5yQv&=G);$vZX)7GrEb%WM2g*Odc<<$z*cH z|8Br1ra1qGm%-w(3i_OAYCP4%%5Ds@=H=GE6>3%>D;W5b7056VfgVs!nuSKWz^GpM zmeIJZmqxnkD7Iyh&#mp8JN}X~)7}Pt&_0`AgmaF2hcHqt(}YDcJ}BSs@lEj>kBkwf zp-slhpF*%V&XyK?VwD7ux>B*F!HhqaGBavLD{?XUIdtGyG5!o0C?>y5z5jt18vvY* z6uk*Xq~40L&* z>W2FAbMG1HUvX$YS$9r zTA%7eNOhznL$`FRN^+kfH#prk!wn9{1momK7GnJU82R|Fm9I|5Z7Dylf>s9)e-%Mg z@vAuXLaN*!s0@7^R{|_iZ<_ziG4@~Ln?^@TM$Ikd9TS)Vq_1K~FgbvDb_^Ha3CCn0 zuDoMC!SNmPZjd*Y_dn%5KweZ*xM?QuN_iXdenH--g*;Tb+zU>KK$WA;&>^8@nSUka z`&5n{SCPHsA}0T|vUt^uJje>h1)L=_^01$&6UP~qC|VI&uQc8QJTwJb=UkD8sPpos zwRO+*jnp0*Ta1Wxsd9qYQ<-@QU9J>=k<7dHTr}PC?~zY83sj=wPL6xIL=5fPW{Y2J z%g$JQBAlGsj^Oar$U#a8LRKXmCk&MknIc;}gsl-melCe4Z~4}yX=9-yn=l(yW?oH3 zqco#-R~de?JDcXS*yjDO;>1+6evZ{=Ww6-35C7z`Q3C3lhp!mbQNxw>UkU@G+UQ!-`_@_QBb&x^isoA zE-ZPk>g8*?6aCKw4(gc?9b6)1GrC|DFicF!#$j_=V}%LV4-MK3-K;<)T*o?O_V@!P zQm4r9GAzu(1Y`^h_q0DN{z-syPIjD}kxDSk%*sZ-tN?5{em-AqbzK`0RM4Vnx7>DZz2kjk%YNhgJ zm}U)xCiORP#~->1XOm@Sya0Q$)RteT7FG}RO_tR zAH>RFw>_ic43Q5&L(NbY;uO>+lr9)#w(So0_7NHZnu&(P>d8ES1<6UyRP?9>`_Kmj z<>ZZk>IZEw>7uzT1)Q^F<)J2hOC(rupW^fuS`yhw zT6gkrb9@`@jo-@;BgrWQ*}W>nDY>iu=}Wnhky$1B0o6iFK2!^w$P7C)j>LNE=b?of zB->X-v*D%XAnnDSp?_F>ZkkavcVCK7xCs9dah+CsM zJpkKT_$G)(-nXsiFv9-Kc;wf3sllxJ%7-2tJ$#1XsJ?8ANnNj`9q9i-0QLW&xWC1J z^@GC^lfYcF<+unR3){i~0R3Nv`&R#7+lv=P_2Z_We)wMjg*&#vJvi_Ua%G3qgQb-l z()R{RE}x;>SCqoE(C9`7!lbEUeFf*e+lX;iI#_9YE1~T%ipdstz@dp-jc~`A zB#ucSw5=_Wna=hxLVNcfE6#8<{*FUkB2)||>ikqjF^8jgk3w|#=OXiHpK@TN8SWOz zW7y3e>(KbS#83B!)X(}0lW+@p2|cq>N7UI*Gn%1UZ$$6v^VGRs@K#HaogA5sJX$&X z0s%Z0%DXdUaiqMW9DfeTq?xyrOxUav#*mZ?D+-?4fGo{?xO@$BcOOb(?%QAG;fhnD z;Q>dxg5BJK6>RvXG+u+~a}$8x1bH~j&@w1ne-`zIEw#-z4U^=^!0^Dp%$t03ua4-{ zhDd`qSfPdo!Qd5*^2|?tPpD!|7mWVlp&R1wQ|#d(FouSQ2C&$v{(2Bi=@-^t&!LCF zqZjw^NM}N2+jurky7Rx8pEY(<308NUfh}XZq+2}zmJ48&>GpzFlExaPVT&2g2&J{` zT2-y_f^d>aXfy2aGpY?G`7vjI()x)SjK5Ze@}4Tc3&Nf-Fe=*s4xJ6Y{tk4R1w=>WhEuBax}TSnG75 zv2EQKf7g4SFV9cpafQvFe5lVonA~p`PaeQNUC~#V@DuQVBYbBKbFDLm$veM({4BZQ zQx)Gx``F~th$q+%4eBRZKV4XT13~>n7ZlW=;)l%GRi*2iZXc6=YwN8r{srWj^Y1pU znf_=P|58a>Js<4xs+Ax)gr-RPL2{_NB*%G`%|K^T=tH~EsPO^x@hl*ypB!3*_*W1O zJ$g_-B}^2-pw>rM^dj5I7}|8hRRnOryf74I`fweg_SvrpwqYHZFO7L{rPSK4p?e)jka;JJ_j)wwe^g z5vLdxl$doF1-wS9d?Pm-zP}gUqkwTQ2LfGiX!&4G;7oL46E`}O_U}x zgm}<>fXdD&%^tlyIYqtO*Q(uOJAc(GNy|xb+8(Bgk%tibM;icDH`*T2SZZegoGOIX zct3dLh9B{1J7dWotsdHRhhqFEN*9`QsEpmkrDg0cB4rowOz&uvvAKAa`5My$Wo$0q zg9pi_&Cs!ApiQGF*3X|F3Y^o34YaA|;>tq=l*>3i(57xYP%aOIVIC-#0U_RjxOUpw zh-ljE_pbQQWR+kBtU!wT?Y~=W!kyEi29OFEw{SS-9yRzm=(_~8_ zK&olOnxffl)8Rp7s$@$u9?#mTfW6g+(UHxppljx(_Meo1HThEe&vL8xL+39kysYhr%@LW7+zUf$vewCf2L)>w&g8TAvMWFrYDAwvJM{y7jcZOl!1g%lPx?p zlfKS!))XwKAL6S;Sax-5`b_IKt6Z!*&;i3$yXfUE(7qcl`9G+6DxX(O#Qfts%FWg zsHl3-TBV}c79@{iI=pphShU5^)6kOh`iSfuS)4)Jb#&!Pm`Ex|eQB>52y0XAMIEnk zR>Z*7F)xQyy9B02M&p3)!YSiy6csKp)w)VC{!hsrfNgJXed0L~vO$S~W@z?>hi*sCtkNQlFP$T&4v3blD(*?~|L3GeFJy>>K(I*9B%TRV=Yr`(Rrf@+e=LlqfF{5#zR>Y$CgRVbBYm68h@i%dupvd&@T7< z&@Q}<(+R6cQX6f|QT@f_^Ay&l$LmoVbQfoiEuM`lL2IDzjHXV2$>s zDwE6T7up|EOZ_SzYpAl(f2Y`JZ)ssozEIo0(7z0?_MYDYoRJGzMP-^A8?)9lQJuX3 zvTS=8`J0>741QA{UNNhYmBHqTJeo*?L$W^3^FZ28Vz6*bVP*LtdP&T&WhW4GzR6s`~Kp4!yv!0xF{aZ`aYzQUkj_tdI;`!Jh$L{LkHshvQ>X$AX>x6SfO z*CkpKS4Ooos_eRgiXGh>Edi^=W@)9x`lzx?)!mp0+DMGWK@BCRVHY3ALnl(bxS|Ht}ZVB$V~Y1r)LR^Xmd`y=a6XAze*;&vKQ<0sT zdb%SfxvY;WJ@O`1a zr-m_;DdRv#U~b|Yl+YJ>tbg%XmpLqf!7?aV$WgY7)-eZlr>`mZD21ynZV*3)lmjz= zACt4DS`a0Wd{gJk6wkR$7iVH>+4`WxehJ3p&3eA+nz-AkB zZP1#7cBABQiOIZ;5nst3taHBi>s|F?M%Su2VYiCuRE!r$Uun1i5+4Q9*MS^o_7vyl@QDNN`pVmsK8T z69B!KO6PiF*&65J;C1J+psfIOS7@WmAKwR66B!Gi3Is^C8_XC$sEy@ne@KXKKBDLF zh?DO*p6LLliQA}hS#*^cqu~+TSf)X}NDhXQ;yaPEHCG6r*5+8w%`QVzSC}Y>J^aWHGVNEH6!3Upp6V1UnVo%q>r{6E7Mb z^mCQx;Z(gtbYrCYa$wsTIrx1@AB`%nWH_YJ_(Jb_&mjZc!+6tr#^< z^DV^Z333klGZ`q1;eX_KnV}XJq5{gJGUrNLbjL?%x^`moXAQITiYtSVvvO5I(TE1) z1&(-IH!%~ZbFSpG7ErE{(RMUGvp3M!h?3h8j@g{#8fMH`LoZj|O)YnIClljVJHehu zawn8bPX&8sqF`<^9aEb&roLKZDw{-%sR~J+N=@vkl##Y%IG`f?-PV^!3#VM*`?5@F zw_i_M)?my*Q_we&6fpZs2B9D>GG)i_gG7VZ3*!)95%u2=8KI~aX&qMC)v=&z{^bM0|TJH@z778grE$ik0KnHRF za{!=YI)FJ?fGN@as_{8$52w-|oIi}uRb#LmrAW1TNVUa~#^xc7Erzse9@47CkXFw_ zTD=(3nt4cT7DHM)4{7aUNc+u0+AoiEq~l9{%rojV&nN(kqOEhpx@hb2Xh)~ixI1Qi zKPw~0?S~xa(`3izCp+GgY)Wq&Lm<8MfaK}XtyQDryXbTAHr2RBfD9DIXJ?h3qH3>o z9;!f#q81mT0$LQ6jyInwphZ!~7oq~nqn_Z)0JPvab$(hdgXMXEkZ1)~0Cf5aj%AnS zBN+SvA_e=16p*cMzsXq0g@yTr1(YvAhFV@&SU`)SaxG#3)#5%-#}}fG_n^08hej^j>TrXX4SmhXc^I2D)?mBFzR9~8k!F9(FzH7~&0O(e8pFem=rBTR z+>`91K?{lLjeHm=W5v|!PyQf&AHL)b+AR60%YaMH2itJiI+m$q!lmn z)T%SOk{iFDyn4XiqLxoLr@>6-E`>bKLA-6?;SwbbVJ2t?+>YGwIX{bb7^GH_Cf%!WML6C_*MW(gK?{IC(vmnHzPk23icYR|Gaxffhv_UqH10Xi?PSLR3JDqLSHp zc`X3Sqas2tE?d7dsPDB=L*Lug4(EpXwZ0*l`?u=QMc2?OCei*o!PY{}fkdnC;u7s? zKClm|mg~l`zKt4!ZXDnWC^=h&H)S&XO_=~ZmrQQ1U$^_n2!0xk zKn-k2)ol0KgTlGc3!&%A>>>=ZIc^-w%4MrCE0uqVv>Q?>`SO;`4oX(^)79d7Hg6fP z<0VR(g58lXSZ}!$)Ke}2tT57_afMl(UOBRQd(gaki#G|8eK?FQM6ojBw~wjy92-ss z3pT(l5oVh*bQR>3&*B&$N^`D8m|O288`h)E0pRlj@cn}SeodLX(rO`vr4{q>=>Jq9`_43u^ zjHkI%z+i5sm+~#5jJ^QEl|m9Y(`3SJJ%zSM`%xU*^|%X%a;@(^r*j4RiCIoRG23*$ zH)x9&PFRpDc{(Z7rpdH?J8q{5yW;^5psE6^SO@ielz~X-mkK@Y>nThzwE2ww8Mzo* z?@*Jckxo~iVn5phe=zmv#>ij)&U3@H^sdXRD=h#{pSh#_&3qVH-q zpKYQ*=Jj(~9%WrG3X5Ws2MopMCoePzo(T<}&fG0D+%P^mOX#z&H zn4{OM zZTV6k>{FZa;9{jY%H2d_M7z;CvTT|55f@Vc&U{Y?^q#^i5XO~=aV0Dot_O8FL;@=R z!+kp8sKa&~4XegQ4m5j`-Lgosw92ojK$4Knac9u}DgbqAeY>5y&8DWaEE|~9EeULA zvzwPemDyn~3tBINd5jjKqit+`C#J@<`zdFhj130l<;%b=FXrHyv|pSmYqS%C?sm|S z#%QvN%eYnLq-!CDMvbA*q#FC0h^ofWSjqf{!BPcuRIJ7W`SypohC~s51o9}0p38Jx zxSFBB9~X{x6vDLdGPQv>I>f2bpw{BnZ)Jiz`+N+?6LAo|KWP!|H$m;Ef`-ap`1tyL zGWFYUW4O>fLWTEmEkcz171Z?U@3kSym#-jw)0CQ8QcAwYl+K+~YJt1XTPmobeAb-| zyucX|uxHGjq$ynqZ%4rPPDxki5|8H_ElmHAeERXLNE1zbP4r=wHWzB=rTuw-Dlu|! zpS|gfuIF%Y>Fso0j&;y|dkireL0Xz2FFqJFcb?H_mz2tiJH_SRy(=$;0P$Mai}Ra& z+eo|rk5#!1x>hZ|QQ?{wUq+djDbeM4BcQ1Pgz}qkpfy1ce7&&TU?oM2O3)Swv@%{p z0453mwT>gByuKK}8IX-mVf;D~z+h6C`~wW$6IW^`Lvu|%O!fk_8+95Vll8>smJTqU z%ElaH$Tae9@J;n3LFJ9?B2An1?gp^yAmqqp{(6 zeDxP5k+4R{TnPt?R}gP)=R^#36;25k1U}A8=B?|{h{L0GTpJjI|El;Yx79j6bo`l&i+V4 zXCUk#=yrwlIhT>0V$~|Q61CQmAea7Bf3#K^U0JdWDN;j#)KF@?!;T_~<9D(fHl!*h z(uujRG}6DPyex=s0R7(K{`9igAy;}$=R$AL)s1yLYujYn+J?AB zbBy1?cX?l0HLc&U<|F^=-L{s(IEWUz6V&e-68H7>ORxsJ6@=!GJCAA>rnk8IIUz{a zf*&ON@tdsUhYiv^s4kH585NF07#K1>zlWr3%z3SHXT9e(T#Qj}=vcG_?*wCcpDhP_ zavril^IpPC{RcA{8=X(fY!$~?;+m@!aS+ouLZ4h(nn<+#Ub8jPx;u2^$q<^y4Hn{7005KbSl@vrx)2Ve()A z%tczo>qb@7+@BZ02Zp2F$pIN^i-m2J+@vmoR3t4eX<>bxNkKJJLPM+DQ=ASKjVLJG zR(R17?mb_PFKW|oQrogSVQN-m7-HG&hVhnU(yj&2P(4un$OcmCPy?y&N9yy)r-db| zFDrc|8jUAF$cC&aK_N&Z!MmV3SZb~0L)#VemXwoa_(qB;19iMUW<~Dr84LO;D7w8W z=y%H_QLcpa7T4B}DLmvN*Vb6A9SHGoYjtnfxH#22D#rgxQf85&&rfih!g!7@sHse0 z@!R=Pgy-adX#`~+rfD7eINGQF>ML3?=}dI%xRyM`08n+6KIQ?i$N^S)07*E&Y7b!f z-~ekpU{?xQ>j77!fc-px8No$a=K&Kbfaj=OMy|{t6%ToC1{w4arani8x1L5 z9&&L8S?VDO20m8RL)sZ6Ej6Q*$4QI5EQ7dG?b6V@KoI$CHf^uEIn!`vU_)_j5+ zo<=geCHK$d{y9I4^S|QbY{QrA(4&dzBEhcR?(|hk*G^JKLAbJvqKY0UK*`wVFqfm= zSxV!`;pBU{@kVz`85{J`WvsQ_#d4N}wX6@iLyEr;hKMe!Dk}St@N-x+Y|TG1GCZQ2 zoh!sx{vXGG6mjkU)A_!L-dFbi6rO&W@(hnnLe4G^~818rv zAzbD}%U8Q$KGxMP>`aCAw+3O*1Sup`WZj+J5pFRo$(KU1>Bv%G5=%#x4KH<$<<*f|bHCx`!SJ%-T5=UMJ=aY< ztwFvvTpM0y*E(muF^uKG9otmA;o)H$XV|(ip?z840k-PHEwk70EBQ%dtQcOAOycjx zAdUmsA{DpAG2uSksZE}})$fy*sqdzS|0Lr*iI(qWyzWp}nJ>=S-uoX&FelFaf`;PD zw@{q(b8NLReXN^fHSaUr6joT@mrXf0Hh)T`>KSJ%sU+4-G&Fr|FNY;M^+-$#^Ri`V z;+6?ptQed*U#>xDfKKHEY?9hmy3eo^p6-GW1`9@td$u{lyF(>zrP4MltpXixVx+%w zHfPbp{dPHdLMx8w0Xl{kt{jD#yG6GvSZRK8a!0H1te-iaNH#bJo{VHXNsoY1JA09t z?JLH&QxubfP~4ON#EM8CQ^;RqE1?C=%`4oOU2FShse$maleV4-FPhT??2%|b>4ABP z#!}Y~D|3Twv@<=peI#>Ks&0EtTA)4ZpB75A-=yf~VCU#CILywGc?th*8g32%ze@q; z0Py=1U=9GxUM>gb*e$#9UnJ*2{rrxIu=lB`d=!C?p%IT3=;E0Jz@JipIRN}Q1(*ZC zUs8ZM*2^-zk`h1ung*HUXx#y|TvR&-0OM~dhB*LmtmQIbj^l&+x-8=<%0E&Rb3nD` zP*!#f0RJv?{Nv7K#dhABIN+!Gb+|LBfQ1hBoTn7RnyJt3nvc@%>?$T2!9&On2N7y0 zxS6UeQ$O3Ylue-OCYD)FFF2K*ONCYAg{3rIWG-i4Q0`@Yd#g_t?xm`Ww(_%~uh9dY z9GpcV@e(u6cRAY;hU8;iCbk~AtT3AQ!?XLv5L9VQnPL=SNdR|YG2P_|JB9=@8^eyl z<^X_#r309Q4MM4xj3VfBgkgFo9NL=pW~z76X9iX`*jmTyWon6UZ;|P!LxkOtid^n| zlRn@>q`YWwJI<`qOsu)<6xlWVY^Ta)`JJ912S`=~A6wgfvpUlArF|b&4y`0&$kJEg zYJwaY>a45JY>=*0eH!S}+bNXW__OOD4r-GOHaH`aqi!qmp_km3YIV0mnnBO>rLG60EITwX_BY=`430!5tYMPfS@HLa*>m(%kYWY^F%8ppJ3Dr<56)gGU?iT*kgmB z6SY4M&QP@DHIQLY?dP>DHQxVXw9zLxUG zSMviIqa#V$==k};#Tl_;SRDT@1A0hAuZg)<=0k|Li}af$^EzgPVmy`=-MxomMR(3b z^r+>jFDv^N{}{ew@C{pJXiSg++^ihLzt_||4n)BCjC`bp2I(e zlOi!KE>ff;b`x4M;l+tC8~-H(OpdwJ2D8Ky+QEZ4H*9zM0Zz1ujSZ)k;uZxB?RUdt zoo`aNLih7rDkYM8Li^otpz}?!+B0bgF1p<$ClJMJeI(D?Uy%2s4#!rYudmQ_^jOTW zFLXU&Y~0&-S|g?&?O>m1f~C=QgqfueZ1-kv%W(Jkj+w8gcA{n}xfWr8?Q0o9mmPD? zKs$_gs5ZOdN{}XVkOSqUG#4=k$Wrx1($<-y`)@A&pzzP6uRm|o+a&)iT97=Fj)R>P zGw0(L2=Rj;(g>1Asmqmvl{Po_w13t zk5?MC+$3+bwK#DDmt%yKE;+l?xg|$vPG58zOwnI`MSPA9M>a4qP0ZfLj8m(&uzyjJ z^$H*#12R_2L%slHRS)EAKvwra?gO%>2l8_uYkMGn2C`odBq|p!S=R$u0i-_A0~!~o z(gT_lXs`!F+qtAZ)B}2~KudZ+rwX*Rr@ZG0RP6y>DNrvDcx&;JdM^`RC(znl#9aqC zUI&E};PYzDZB|`oCg0UoA0iglh4tDAk1T4+*5x$JO2kw+H(W4ka2U1V6c0*mECp2( zsrcCZ71-J38t8^q_K(#Da-`J|5KTpBvJyr{XA@&gYpOq;Gs2TEXs=CSM+qih(B3bFS-SEC?R6>4_#$60_i)u{ z-JD0r`5?m_Pca`Mn0!Hd{}g7NmalPnSbNx#kjp=uSr@O}e&Hde+$>L6+p@bG%rRj% zSRM;T?lyP#@r&A)@aAqT4&b`6m1jBbFaq~6O3+|K?${GOjAEf-i3Gx+oo8WAVBTAhX9pr1T3JK9OVhj z!%L`tM?jsShrmXk0}Ci7-2Js2%)?8#!3zP@ozx1+=`kM9yxoEplVcYTNZ3ht1k|*1 z1kAe_fq4O*z>{3db{1=k$?+Jr%zI#cLmyX-7V+P`-;L+fE z@dU`>S@<7=y(8_%5TJ`Fk5vqJc?Zpu_*|Hi0;?Sb2DQB-9btR0RL(3?y3O%fgf3J5 z(x!*xx}wSMtdEAXgqWReP3*6tJ`=H1cT$77houUvhvC>8y-^CRPoUx_b}1w|Lkg_d z2kjFeE!{SKlP@Fl=dbCqp0S%G3iJxAa(ac;s}u@}$9WR^cGcrN5(`ozp+HYUP9I9M zuv&OLAe-}_Ks(W&tC(?ajTN>|Ju>x;%Qx*RV_bR@Tc^gIueNon>RhY0Vt~)8YZZsX zeTW+A86#sM{o_d_<(KubJx!;n%c&L9bd`~=DzI>axx;%o`6hAliN;BVBxib6;7hPy zG%?swoDzC6LE+JqgB>j7Ex#wlo3a+X$dzFi5TesE+ChjY_TKzW_o3Gm)*R;U{;E$M z3Vp^L_5&}ZZN)Ewmps#{0?_*OMXb|jVrn@mhOH-)Z8?w6q0OJN}1j_O|ZalN!=T5%A#*t z7BmS|J;6=^gSkiaQhuu_pJt63LNpzi{5 z`Yu58kqxSR9iB*Nd^Rbm{krk<0LsAV-CNhfbL##lDTkGg05$?^)XLxKa(=H+Z9^Ju z-GDiTYUf`JDW_0vNU1_~52f6lE<;N1boC(R?sOSadZ()gDR-yKkkUI{JxIAbU51q2 z>B=MJ)w2c9)U$h#a(B86Y1}J%_aNo&bQ#jdJQAHq!0}zwl2aPjovsX&M?E1O%UIla zjd$JtHQa(=dH$c43m8|ZyT_*6zgYx>=Od+=k@~{C%m|dvOoqxZJ0BI$qNwGCsDKtl z9bbqFD36LVz6z4lv^Q@aCCekj{ro%vS`>BTLR3I`RGRbu*R>MaVm&kt}k195=Up>$+nD{`JX}@Fv!PJ2)l+=-G|}0N!Qx~ zx(IVl_tN4gbW8Hv3MqEfJAxp7K0f9KJ6&IZ?=DfE3#Q4A=0JcwF9nzbz|&HIIgaF! zAOJEiVAIaU&W|h=wC+c!v}1J#V@hJq?klY3%X)zVi4m3PQl{O&omJVbFfP;uDj1~C z7wL07X~`~i;VtH2+0mbWIP+`dBPgtZRz4iv zd4KTaev)t^iV*GW;+EJQaeCuA=bGB2m+i=^dm-IHAgbSs8BD6+S z4o5^Mh%$hsuZdKCi(Xr;+O?Jv<|@>!vJLel#q@S)uSWu(*;8#?>u<0It-le?GH(@~ zzs-6dhg8m-%My3-Badta=dJ^>7eqWq3I%FW^RKsB(@DNZ2xp@v7UgcZ-a;$Tis|X% zDBtZVXU*{e-cSTEwJzAHuM2j_t-ld-RGq!K-eKu_<&Q`u;kZ=#c;-P}UcNL)FA8^q zc!H-Jq?d=gL6Ll?Il?;1Rr2oLVHs0%>HI{|=i~fIz-pJ!pBF>YL&kZeAIP7Q{h>Tr z_J6ck{J+eL|JTKke(I1?vOkkIBl~mtx+)kc`)9>|R*L$%Yjxebe+IMb#PeWgBXJ(g zZY0lxIopL!wJA+QojiA!(9)3PoMl3%QJKdsDW_4@$h9KZ_?D{Pc0|CMW-~X~r7^y% z7&Nk$N~!K^juV3T@$4@L@k)4N=iZ#b*p<~h=&ISzF}Aw66H~?Yqs@NPp_=_&fkD`g z+B#ckA3sJYOs5`#?a;x=k9ak??|1R1E*Kn#@AJ8qE>JdE62z7n|G(P>G^Dja{y`JU&S!w>wL5*CQ z0?Yy6*(tyr04`4f<^a%60p_U=9FR zr2umPcyS6a2ff6UPO2T{B8X2^LphqCV4T%*p<@YMco%Kbsa@OksALoCKiM9$K67W<2O$smvfNN8LIRLyQ1(;(NTY>;E*4lolz7{iov@yDA#HcK$1%HntNhQ&U0vgLsfbc&k`Nt^_T%nWOjuB6oym7JhkK zj-Y#UF_CwiE@ZW^`e3&QbyLvZO$2N%?bJ7j=V+#_6^z`YGCZs73a;$FT6mO5UtTM* zTD#Dp2-NsQ(0(^xZK3F!pyciMeYBw|llo#_{lUp^h{|-#*zESGC?hhY#YKkHw-Lk^ zXNp_3@&|Khb~B9D*3Uf>$KL22+R{12wsaH{{}cJ(y5v*b7K)-o%FlanC_nlp7qj2v z_Mv+6vwA^(9&Gze7MJ|!o6nE@!Q7F(`FW@E!@Kj9iCqebFLL>Ls>_d}m>gWRJ#?y+ zJ+j*XDsTEGyw{h{+u@#9vE^;*z#y1AsyD%RDZ%%{;fY-ei5W|pbnI-u>}1k7z{+9i zP!4_b<&Zy^+t^F?-6Ff$%At@Ll??H9iz|nsaFH}yxubjYbDQ#W zy5&b9apL%Tq1%E~6u)QtWXgMm^@q0u)S61)Jbn3txnp|izgP6nF!~CKFERR~6jkVM ztJnygAGF^u!jxIx#(j?H)cof9n z(iGR)%;3>^xd7FgGfDk5Jbtak+Q|Nb_&Onnog0K0wi&;Q9ZeXxIq9MYS#X*i<=uxf!nAYp9$lc2j^~q6=D2xa*i?n_*t}h zH;$Rw4$HMy5u(ZC2#<<3t#EZFbO2mAje75i*59v7q5WFvDe6S!B#Zt50Ijn~bMDyQ zR`5Qxg00pH6r$~pX5(u<57FEH8JyY>TB3?TqAOo#SI2-y7=#igm8V zQi$~4^0ChIu^!VK>w}8*G>fGWsgpGun>adT8T=aYA_!~oh~|fPhQ>f%Gfd70zj}yJ zUT-Kd=J}%?sE(pm7zp>OqI9!ib~hkX_bn!&P*|2JFn*mV99iGn`Y<_}2s%$B7c@_>E@W>mXMQ3j#ny|ORs-4ev5M2<0?9szbQ$7yA_lm-l>#|$+cR> z8U8zb%wn9nMxBe8x^*x==1a1e@5y4OuF=?B{<7u#m@my@^8BWyUW`-MsB`U3HH+YIQ!@*)iuF8mfJR_32Mq_h9M7pRCK;*?DqL(sW zLz9U=DMDBqn|o|;8~%{m@YAggD@2cHG$r|I3`AxN?a8j##?bjl{tLI54oCfwSG_@GY>WbSgtS5ihg#Tj1|ff_wmfL zkQrzaOpHWVi0Uv;==9_es{^T=J5WfTX+ zBVIwKOz;nr$0-ShZSq3V?#oPCyVB(CUdi>hPin0* z>4}WZEdCUjoQ1a*f1a#p9P}>Qg7#3(=Bqzluh>f#y@{K!qlw*3??L<-mFrZfpocJO zAv{emJ2U|L=|C?}#jw>_vL{+?1I=Bnsa4X`2T6fnhL5q9wkYiF9o_jU77)e?Q!2x% zFnKsZQ(>*yx2hK3iJPiCkk919P=tpCddUw10dK;&z4c~(2Vs86JwYxz;yhjo@ZM7O z!i4#+QqprvOnpt}#=9Z2WY56*D7gqu?_E96=%a1|UNjik==wmR@RY*xrxgaObdRHv z3g9x5M1PB#l=$NFeHV13O!I67$8GxswHd_E#qH8z%C?qIvco*3T#Q3k^ssdfvEwg` zg!o=8tfTDHl-=QnV`;H5DWZI1Z%i>~0vGYCinu!!SiC6}$K##oTNT?#ZAe&O7n;Ut zOU-;&hL+(lzMM>EnNz-f5)9B^rK)T{z#MEE0yEK6dj#g-_~tN}VLO_u-HxWg*}44| zX@X`^Q(AmWC^{KUa{%DVbCFrYzEfs)R}d}DW$dKARKf03+l+18VCMi3bOZUd&HDJM z;&@xo#qH55L}vW7scrWr4A=5tL2nG&6;L$N>6=@gxQDjY zQBQS}Kc~U}P8-0;%i!E_h`|(85wwB8A?=Lf*4KIS=OuHqJai-lA$=zFMzlsimX}8768r>QC zywM$XX|A+1Q^Rd3(Jcn;B})HUqB5vMngf94m#=z=1(*YXm0y_VxRdLqLUlbDgVD2> zY24mKZZ8kQY&l?LVP;CiQki#>;Ot=fYrFO1vTgK^UpM(1?1*VB#MF&z+Dmd!yPu;VPtI?h3mwXSOp z#)!VcF^m!V3wBNu7+=Cj!?~~XJOdA+7F!s4va)>$2<~CHAZDwc3;zPn8cK)a@@V!SL0nFZud3*yN3?Dv?_izegZr}l2IH~qwQOBz?P;X zlmEhk^fV5lEC#CtUX?$)>4_+9b5y54Th2dGSH%^>aX)q z0p(HIidsbJ2ys+(e>MD~dvx_$&Y~E0M(tEsqWXBkqOh_)$}6@+_1HnN(k+*haO{o#oz+*XMXQ?Fr4SbN`+8UD3ESLS z$0<-flr(JMF~?afSDdcRQm1QE>=>MT{pV67H5wc7Ua?@r>p~uI#9N+?ct@lOn*+(< z5h=hNM>xQKx%Z6(-w%2CTus(JNV)fo42fyKi_|>`S4z~1MJ2%}qzRhiNc5!vbYDtT zTU$jvy~EBL6z2B&IifYCXaHuY{7F5r-1yXur_i2w0^}84EOF!6?<9zkuam*BDlrGy zf00^~y|%3toL85&aj;JQ4$(N6!*QwYP*bRMPO;ROFHgdu5l&xcFru0oKcL$yB{=hB zefm4X$>|SRV6C%B(C&O_(5gX+d7=VUcHVp@Paig(38=x}0$ChWj7gfaQc2CpFjy$H zVD6N(IiGCJ`Lk-yms)dHNWz-6NpVCeT{j;~I{FLR%9+&Blz{e%J;|r^lKh-VUS=c} zlCW-Xq84GrdcZdO=&a4YhJ<)R&Dr}{9^TEa3Xt6O7(<{6ZxW)$Q*)pP@L=t*U*EM9 zVu1OVb!1H3-GAX&qA+9g+v}lJ-@Bp0`M$ZjFXb#loL49x1uOli8LI0S}%d7>u5N0x=R^6*QHN9SA z0W;LJ9L&ObbX(vXT>LNxF^qy@xUBma26Zp-7+f*Tp?#7kT5YSoZy^-Zw+sqdqzs2z8H_e%(04%@1Pta* z@1^`DQQm1~P>3Eewleg&u}*QK#;4H+!J%C1n-kP5*UQjW0c`iyWUkVkm%8@|oUCTC z$(Ozh@+Dv}hsfs+-dy9oOZn{Y~)%5`O;mxMe_w6 zHYhDN`OB&g{+C-OAUTF|yPymL26J0`DSug%pJQcENOGkw!-HHI6lak#ycw{{psx%pF535y ztny{}O1BIOS)>dPvoaWM%AoIpG6)#VAz0-pe^r!sSs4_PJlB^2{R7Q@iend--ikxH z)_0%R{}kxgJ92tq`YJ8jSu(xFlhAjcOC|++5_0C3Opy4dC!y~?uTLq^laSMsI8(Vm zCej3xe;CsFy|`nuPl}WioD3-yoO+OQf|DVof>RGt?qNtnN*{*oLCQT0X-I6Um0Fk}x>?qNtnN*{(aBt$uVdme`LfPAhpwA{mx4voFgZsw0p zsj+==j;i6TpbN<(ru6a;LmIv8VMzHfMCWqX^Dv~t%N~X_MAlaNjx*@xUJA@W{{6uo zRNH3Src7!XW~c%!idtMiRo74#Mb(OJ9#vbholQ!e-VBT{L_EG!ptk93xRbpH<0vz(dZ zPSjKZXnN7NJ2$l7hS&Ix&Z|NspF0IW)z8Dp$Dpl~46plcil}JcNMC<)Bxjxo@~Y`T zza6;c#2np~t}@1|%%B_=>clRrFH7G|u~6}A!12q_I3u}&i4=+ZT_UP8k}Gq5y_BMW zjxuZSrtHh7cT)`Ma#m!H!n>87)~h%NZ9NZ2=RKlvB`G{V7hZG-FUSy({$tFM+7a0z z4lKZ%e4;z(I!`%VGDQ4BqF0*BXpb+#h4JH9czFK>@6?Z-*~s6^6y$+0h3BTdu12Y_ z_Q9#$$gsc;n*BLVm`P5hZEe+7L8b?1KSVEah9cpLVD_p|>XwZmlw$eKTevfIv@p4f zY&33zMS6#b&jTPQF9vtL_2m(A^KiAvv{ z#MMxc&FxWLy|#1PuydQT7bf4N_?`FSc59Q6lkY;|2-0YM4WX(+$Ec7@=V^#lxR=O% zzT7c(qogXq67uQz<6(thJ6c%F<-P!Sh<-&7V^1pTT&N(IMo>7KG#)`3*vDv#GW9Y5 z64&DJ43?y+-JBX@Pi|?cyxRx5jkjyJ&-^@yI!cl|fr0hqu&_V$nBTC;bV^X)mRv(| zE78ggGRMTRS#mA@FfNmVI!XKzyjov}c9%}^G;Wm$rvHcG3DM?LjBbB{y@A3b#fvY( zrAm{b*|^qzAN)$*2&{g_hNaA~^7E{dJ`}=m9B`0v!@wm&_gjyKk3KBu2l0gOJeu(! zIhnk{-@Q9w_WQK5AeL(1N_TT$PjgN^{8y%$%uu zbzh(v)SK~AG2tgsZ&^rFqo+fSQ9Jh!$f}%}=IvjYGd(Q7BtjP(RZk>zkUR#_8u0V zP5zEFKICzxS1!mUOc0^^>5eM1&|#?u`?o zS-8(fv4FCD;VANvMwoJ{NKAT)=kiuz#XrAEQctH(Kd4kcb9!wrkMhNt`J9XA=|oOd z$;Pd5(%ne9p;Jpj3p8vMNs$exTB0Hq<57OWEfyG$O~2P(qgexVY80&sVgz*E)%fEv ze)Is-N=31L{958XTICAkDnMkfwuYZd6l2q+IT>&~GuV7~RJwsy@Q*F_+Ch~lL;Mf; z-&_~8xEw*e=81tljfCs?z|804dZcp=mCbOwH`-oou5o_7f&w8~roV#`A${bB#Af!C zmlvGiz_4`%gO$p6ED0VhUbHn@lEtfh7E!TAFyNr4#z)6It1#54`6e3JT{ZsLD?$Uc z%}WM&;b7*wCF9pL^lS{PPiF()U}!34Cl!N};9E6HzC+INrGugCpT)uj#63oQ^P{kz zRH71U)5pTdp|U+UQI1#PaijB+0UMnsgEEHsi_HTpp#dH`3P;_W-(`D-f|!bvazoFY ze6>t|gM#vVi^g2L#@QWssiBoYqIbiB)}twP_qCP?iOcP$OJ+OPc&F*aHKw5;*@cEk zawahwVcPrFpTnR!E|W0h%YITl*ik)M!uX6I^Fe-2hO z!TF_>k+X#zpQ1N}@q@q(`s4liAUMtTh3RXzA+|;Vx>Gv!iJ)*4d3vnnNyeZn&MG5! z>!Z@x^wQ@3-efZCjnqJL?)edeI(2X>A3Ah;&xZ2pTD~*v={@&zRnfJWm3?wwUP;F#cKbP!+;YDKyclKVJkV*HXAturQlIRbGe8uYB7xP#oAt|tEjHX9jRO|p*TaZgTt z*t5|to3?xApQ|k~`U(|&eRFmj-2L=8OUb6vjPv;q~T{d@!E-s9HfPYkpp8aqe1?ZW`GqseL zt|;?VSYOeo44o@e%FllM|s&wX$$&92FDjM1@Q*v1vTA!l@)TW?|d5s29q_|^rn4^XHB4MZ@}=Z zO{NHDC_nX>=>U?lQePR2j>fjP5q1sOF`@F zEabSFc&|PXU>-aHLMLd9Yzx;k4sv&7!xMRH^28;39^$rsipdtrHB|1m^Utt6F;YBf zxVR*LlVAY4?!N5O!of#&?>e0Lze?wz#nLIqH<0~(q?V?2*s(4xn!HW_8WYqHAFr}q z`b3NtFrU+sjU!RAM;y33Xz!uW6H}wQbSdYovmzXyrs|_1e%pda6fCE+&zyyRryDA# zv(+4*?&E&98!G4Q7qGXyDhs`@8!G3l*>KK6zt;_wbM`*jbIwA)-wl;>_UE$goQ3|N z8!G4QpJnGc3;kg?RL)tm`Rqbr$B!)3*dgbvv;Uk0|F|10=PZ*qwxF}%pLB!eoSjtg zU>5w-Zm^uQM<{qG3;tO*Sk75zFFFhUc{f?=$#TO^=zb-`AF;Db+qIf)(o8i1v%6Ior*&n6xtmb znr6n%kVDfD(OKf$8X7uFU6f_LQBG&D>nwL@XUaY7+(wFLJe8RdMd{}AliX|XjJlwe z3hHhHRvok^DD&n(;rSAI_?ue;Xfm=-qjfzK_QdRk%n`F!>*q^c$Z+1jAOK*V`@8g? z3mlyu!kcc@FFM!eW`_f6QCO+e>Sc5H8Ao%zO0$tY0WM-w>ANYp+}j^R;$K z4=wX9q&3}(W!{BYj}=xoMe{C9@%#+y2D!{DS8o}At+3Ih>5q9Arg(-BF3LDz-i27R zy;$a5h;_BFy1Bnm-i5h;x4>V~PjMMP4gD;{I$Gc^);Wt~T`X`n#Va$cTE0!}7WnOk zsvq+P%jfee1~R)*Kjzky;#3q9Bb)t53K{_T}bQ1UaYeg$GTi#l=$>{aD~XXFuj$ z*m4dZ0qgke$Gi)%W`*#)?8m$dv2GW_SM)P9%8z*`arO3&GZfavGVemHOAJeG)p&2- zg1V*Rog%e)J*4qMriFY_+U*U`eVdbA(&E*#~aB&=?mFz>!NIwGw(uLM`W~Y zyf^Q{cK-xnS${MvB>itL9zE)ysOZ%)1cl1-)42U4XSq)32KnCV~#TLNH z`7B`ugXBvHER+9Ss%_xN^>U;SEJJgY5Vf9xJMQqqGV&$h43#I@Rk{MeWO1z0Tv4lV z5;KPOVcZrhSY3%$Pjk&_1JBv~8~9TP2ChP1L9ydk3TI_hU%oAiw$q}mBE2QO>A8J9 zt&5S?hvUn@OE(6S8+2^JenZs0gx$WWa80vsErpN>6}A6a8-Q*XtwgRJ@S+UZU#gF9 z<4i*IgTiIdf0EV&CbHEJ+*)(*!Kkd{X(jKHBBSa0@r@842fI%Qk&!id!zHyLGI0?0 zJfuAPLzPuIm|9(){cGk~Ql7QbbC);mmh5)Pj+fA@*g7ul3YWTsx!H9!c8p$5Ny#dC z4P`gJ@MQ8D>M*J;QL+-%mu=-FX$yCr-Lqm`SGBtj=ketpK;g~&Kb!;$!Gx7?yuiw9 zTXHSMJDknCF8I+I_;~{RjNSjY`|sacbNIlre8t*1w9_+tDZP2Jk5J!BG1x8hF=iW- z!9}y{FAkaIljC*|a&uW1Z26;^Y~`&YpYL7d%27pqe=BF{4o-rGjGX;L%4B;fGoXIj z_K~$aV)r|fAE-WqQA6TjQlhzw7qumtTgJ2o7N3tH{)zM2T%WbM$y%wcmgHKMtNG%p zN)uywyJ#M1Bc8<_KbN1zZ}ShqSiQ%di&?X9<}r=4S-Y7G#%Q5xpN}LjkFm0(FB$Z- zLr<(5k%p`W-)))yCpxAfV%c1rPAI!Ng_E*2sI`fjU+u7{v}(HEM5oA&Di<)Sm@Jaq zKyGZas(DZ?0E6Z8B_ko^d;bdr4+3{fXVsXX6jt0hutJLM#hN>b@bzNGv z7wRVE-d?tGZnD3AaHV-hxjU$iZQ%Ujxe%EW+R?SavJIe11||<1ut8;{xT4q{RW^(d zSR2y*ZEdX6dX+K}It898dr#cc9odN_ojJ zQHD!X{q;jF2Ll}1zW_Sh(x%?R6TgrjD#Y!*yt{Dh@1356^e&zS=T0%61_@$pl$?&@ z4tps5ye+!}YQ#TF0DG_3#}Tycmsbt3d2bh)unf za`2AlE3h_$K1%H#kLL0+mbVI zPORRF)>Due_|Hte8X7HN-TZ*HK0ssGQpPGR)mLpx&f=rtOT(H#ey|jnhJ6kn8-rZC zzGL1Pb~eFk*FvLRYZJgy$E{5OBaT~}06pW`sg(68z7Bo@zd1-|{r>5R9drF6=#lwZts`@ymcGiePQ^yKwtxJ@PYn2O)+nVN{3ZA{c z<@WhqZ-`bz*3s0r#zE?v9(0a1(^2!0(O~n4$X>=Xk;0CG?1TtD9S!aJiVf9LFCj;y zsGEJLq=3Vrtc`B&xyKcZSM;mNddV6#PqlQ#k3l`)@(hNwO|>PZvdt0$jVm1wwTV>Q zkZ*{v?jKZ@I|~!;U|yDqp1cMhgrN!!~hP=30LzbCp?bnsohxvs(6a z{X?@_NOb*6X0>GK`bXG#WKEX?^ar{W5=}ma)9FCB6nHN?N`A?g2UGRoNO!n@ZZ-Lz z7%95|Hn&U8Rhoy~JkH3V>TYCy?a1ik$iOQjV*y6STt+5`y!M(AiDT91=80PA=83WL z%@eBzZk|{@T)cT=&2azCvV#)X9Tx^p+Q6$}VWqi_K5-*1+UmDRv3nplSu73hIe^gD z5IXf=POa@v*~mD158b?V6JeK^slH6dtvQp9lY!ZdQGH@d#8=;#s;_J*g>GEtus^HD z`&zFRJ(Ho>qAxHeOYhw&O$G2of7&r0V`c%qBi{q{sxbds_v2jTA(pkpG z%jr2oD^TtvXdGxD5j;#Dra{R`|M}30lm0cjP!P?v`A}OM_Q)0J=7mssmigD`BU zE;p0fR?EYi5i)FMtTd;nvTSA~3Gu)$XI3~mp7X`p(4I9Q+st=|tKaU-S8bI2+&5G> z;`p>qi-pgU<~GuF1CI86mkh9cVC7-@E@i$;{r~0)2}1g<4K{~r`t`=uct1j$C6vu~$T1HBg(C8oKtjXEh^J(r@k z4pPW=rg{!Hufoca#*L!sC7vxlwgq$cT;yV0G^|B3q6MAu5w*1gzG!9=&S5aUw0Cut z9jRR`cXnyGTzAdW$j!uEe~DORenL=nZ!576xjzfh_#vY$bzz|NRoI&OV9@+{{RPOO2~8HU`aSy{b-veAZ}H9iG-j%1?QPe%%A#|` z{z3wcb5tksEeuQOGOgq@SRX1~yM41UYN%8#n>T(mTrAh>2i#a*z52%TnsIntxUswr z%zJJu*9Z8nJ6Em>uKIFw4$3(uCx?v@hSi*|E{Bay-YXT(IM<#3sXVJ77*ZY%W9Tou zKoQ07;Ac=8vTqmDPYc2etH~`CWqnYr@(5h=7V>0v=rpIDn=41_4PZ^o{tyNvx8e+w zHwqB5W~>b6^HS>OW&FVO+%qcN3BB{w|JvMLEfW1`be;#Jb_d@OcFgcC8E7Amj|;FU z2VzmZeBnSF#WXC3UC!^8i#KmS#bJyTTW=!q5oDV2LczE?63x9C5KD;GTNG3Zs#(c~ zOIQbp-$j9gau2Y0LV1gW4;L@2c|Hg`NZv#aiYE*gH($7AyP@nE8s-spMzjM7xfdOi zw~`EX?)ZK|Vbe!UcaDD9Z~A&n>BG%&$JPG$Z6GIaC1xcoqI)JT_eWcnhyB%qQMA^* z_bK@EG~+jC^cA!aKLAc6SXHZ;i7gt^dsKDvIGv_HRv36t%IjibBec$kmT{@lWzwMW zC~_>~-Mx}4r!Qd6L|EiX=gPLOFnmx-yWeyoo}SUp6O_S#HSm3Rn{ljImE#y3R#?*v z^Khha;1Oxt?Z@(%yDME^ZuMJ1Wv|LLBlVeRzi7Yf*#D_-+;-26 z(Yk2eb@ijRTJMp+^>$UvVL|c^@%$s;Z|8cL`9f#-EDKa6Z#VttkBZqxr&zuzWPpo( zAECN!j$gx9^~*bn%lm@(eN+qrX1F;#e`~ZQ{*Zds2|@BPXu99luLL4X@9fEvd})@X zg#9jM97po*)bXCwaa-zmZ|Zno>Ue+Z_<$VeW1?1lMz75?Sy+cMH^xFkS23ZhmJbS@ zBD-9qMW%d#je|kAd>>Q!(&DL>2ZL(-Nq|n@Z{|08gW)ih)*5X`)sGECe{l7!DN&kDJ?K7LMg@iyr> zeN~9yXkGXuzU+@O7l|{K$ok0EDb%T>`o^tO!_oM2n4Pz-JI5hxYeeHm2|yMc#Ik3R zDSnFNXg?9!7ihf7G4?vL^L0|1sGU2=dyLXC9lssCt?UjjE7vzpSIU-!=~8n^slIVb zqhw=~ebF`C()i`vhiH{kqrvLl*JVx2 z+SudCt7~J&T03y9azlydrG83wd=6aQbempyqk{z2uMXk8Bx^ISF(csI6MvJ)u1<=D z3wzQS+w6#5yZw+7FIGKJD)*3#HO~dTYY~X^E4=aJI6cjkmu@WT|V#Y{(s8*;x$qqf1pyw4-|Ot0|g%bKlAIm zIezJmh5kb8b%zdQZ802|jBsc@uz+ygdD~ng4MICo+v=Na5Z1@evmTs zye}Px)UWgxR%e)#YUjk?Qzpau?T0WZgqxT5H4h+1-?{((nL!&63^WX=Q25TwfIi~_ zDQaz-i%frY_Egkg!)v!!TnC8qZ6dNZ5por@JFG|fkw0?X{{i}r8|#iH2l{h}VLpw} zwYxOL8(!XLixxe%M##~#aidFgh>2RA!R6la-ctl0nxDZOh5s>e&F$J#{IGZyf0S{s z;s#s{G)s=huIdlmIFZNu*aP787bc;nHHKsI1T}%A5RILt*B>f2_YPJ|RnPX4lLIt2 zJ%V^FXju=atVR2^4G1f6rDz`s8%v||b*1uk3Nv}bMVR?X&7JEi{R^Qp{+ZXTy`tho z97SWpt$f|t<1gzg^quA|CisXylH#h#CWu5PE9rR~Ej-*c-XmFJOM*h3OhAq*>r1bp zC-rr<3F@SpU~lwWIMw<%yy;;6zQ|3lFcwHR@K|1+1uRVdKi1wmKB_AHAHTVG=1xgM zDw7b(1Tc7+NdieI5osb=5S1n-hyoTAL@s6!m0?0eY^W%%qS93C9UJy8c3ou^TnqMI z)~>s&?C<@4&bgDD=m6u0HHF>a6z^<8OJ0??k>^F!na1PU_FB%b@Dh_lb_&x9+*)os zKQjf#SOFPXH3ihzNzJ3OPc&cJ>`9QxISw_i#anIye>SgGs^S=ZyH4)0wlKQ*Q)GWs;gQAgf;1*$-xH#+9*(wpX3`pWteN1VPgOCB(@B#)%r^a2O*M z`Md#k>M?i<5s%|lc_0n~;0h)M#fQnr1nU$Wm^h4JWvrYy&c`NdnT~;+n>m2Gi6~@F zQCi$)rV__~SB`X)eXdz-V&c(+D^wyuz8qVgA$f-R6cL#E&jFFyKO62yW&*>Fi`1wz zwyR4UAjc}K^4g#kk2GLa7{y)E>N$j6)n#=sW&Kos zWeyh3LgBO&HbsYcii!2hxPv30jebGSgG|6_;;#IU7Ke(3c3~>!qlhi#)Ac23%+7(Ul-)1)Hp(ZNV z)RT-jC1(KSEcDC4c=9QVNfw0d)mVhp!Xgy*b-QEMEA!x%^@DZ(c2r8N9}Y_Gi^R$c zo4uR>Q;ih`I_FGyEX6V-WjHtEnOXilGbeWVEmiWOF5V=wK)wgo|y;| z2UY}53!?ORUwzGqhRfC)WGf zaCWfW%|<_Qg`c<*L{T6woTi~V5>AsfHh}H7Oeds1L^w9#(67w1CG*A^;YC5QXS?UN-wOQ&&^gfu6a923OlwlUc1p~)O zR?-%i(_*?GnM&j^KXMk4!~MvWL}vJrl|-2BnYS7Djd(9&+_%r)p{dsyn59ScYgGCN zBctu`%-C{?z7C{b?CpLnGLt)jx)F%~f_}n|lRa zmMNDJq!S!S3>(((N(3QtqL z8hDC5ompBKaP_7D)Yi{HS{QJxqA)NYvP?{)gg!9R5r2KNJ6T z_~ZT><0<@cWYNG;Bcm0ADeu1vG&bxRW%!T6AL9`Nof`u&V=TbG5zVnt9%>4Ao8D9s zZafi`iE~C>5DlSnfe>Xz1u;|^UCU>CF9;xDx5 zCV()WE>0_a947+lp?#$ivq4vQ0R}w@bOi7H@%EI9muACKPgv97>I)JP;ZwiJ@2)KC z?q5iCGp=a3V_tsJo|uAxy} zry;CbVdW1ZMg>MM;8^`JD)7cizY#BtH0kVsO|$~zu)7h@gFSBGfFXhmqB&~FVaEGr zL&v?hakOvkNR%u(hwMUW=_UCq9?6F8a{-}eJB0pZHoz*}OrXbr!m~UtWPolZqlyYi zah#e-;# zY(})>!$yt9He)r$P9a1mx3^hrETVS$b-Yq9vL|VW;-xMp#WUN1;hqD|`)772^LCow zpgBJ5{3=vn8MZTMn|g(}<=YX}CUvn@>!X}*^qQY{)czW_zo*cDEA>01Rk{DcQ|jI5 z&Jxt&H(~REb2{p`Q0h6fic8oTW#5Uvu3e3iBS3Z^7?S&ePHmTi=726`J@o`E_p%}{ zli@{GOvV;fu?$BFRiO+A51^JPDvj4B86?=TkSw5O*tfP_4k(qJyqzUz8nTK-lwx{} zPrc^MQF^goaSZ|daQay}c?99ZRL>j;#Z=EczJlrfuzMnN9L+c+Jy)>Iv3PX}Rmp3O}hjV5!-GAX*%D2^Qf%`771l(J%Ty2^7npJtjCYBSHP znNwg!o2&LaEs^{{|I?TTL4Lqh644O&AY-vRQ z(+ZRcizO-HP6l7JO63zqPTtb%))S4z__9QLom7I~9*IOF;$6`!Wr zG9I$cG!s^2mO9-aS%jEsKSK3Da7_~~%8}_vTX8K04T*%Ez2VGE6G6six^Y`<%aL#w z&(rKD1Jz+$1l{;k0kCBBTotSd$plBTEGT1&V449E$f9YqhZeU=R5GIp zLoz=oec+&)Zd1hv0z7+(r$oJ4oR&pt+)ZBD20dgtw(1oF$s=2M+$~5hBu|>TwK`OZ zO?gH#Sot1aud2La8kc}r%Df`eM9vc|H9D`cFudwKrVvKBXO9b0i z4#Aep7cX=VK;XIm--ajXgvXMo%!2e#Vpe4XF-oFfDOATE0zTRhrevNe#60IIM!nC8 z$^+uMLIoi9XD?lrZ}0_E!i|214!8Ex=>=tRX^`a8Q0IK=#fU@^>+lZYHJ#pGGJE;u z#PlpC{Oac>+4;m#i$UN4|S7^oZ3ZJ;n0f z1F4v3Y)S?0zKt0W?EC65{l6>WSI8gEm@k-qysR^hZ5JKNsVe_DayJ!vnV4(Jmc*!? z-8P9L#KT*xd+@QmZdlb&3lXf_ExFeV790UHlT=os@H%~&2r9-|7+G8@MoQ)Bw{w!vS~$?8r-rh7X|lV8j!>IxFx+-_L!h(x z933Aj2jDxJOz(bpVE2wH82nr@GXT0A3nYuPj~Fmo5&n5h3+1&_1vi$|HFBI{a4%Re zJW|g~Dt-_bOP)RdZ1@l-2PxV=P-0Q$i1aS#Xk&qg?CE z=)#!?u+3T8%r<8eBF;l8q?<3RE5*9|kUth2g_JwHQ*ARXjoCyBeug=zTL*k{7FT?e zKug~tR#%RZr(XoEl!zV*cdF@u)4->SFRw1>!l8z^bq0&A^bpZQi+9oR5W=X}6jLLp z#Dc64<|jp{_-j^WIbb}2^lD@Nk!fxfM`bD@^h;;>G`qtNZpC0zwQ8>7)I~{`0@JC1 zwQ?-l_ms5i;4fB%a(b${%3A7FoYPCqPHHNyryxBts^%v>GFMGrdSsrOp(Kd_v5$=9 zE%~7zA*qCWS_AHhu$SI+3`^<)PyKUv+MmOiBnnjXBdf6{c7j-saW8Bi_E9CE0jaUE z=*khn0bblleI1lIlPbru4&bG!*m=kkqh(FqxMqX7HPacuc&le9K#8rQ=vTnN=*>6{ zX{7h9VGX9h4w)fcxyf|4a#a7BtOroP6IC=|;H*Q8#o&N52ws@jI4yB7C5y!I{gP~K zDW*6&UD=q@5c)R)F_tuhi8_H8Ljolh1ggU-#$|Yr)F?I+g@^t0mn@Dtp(*`IxZDRoyFV8CQAfqKjr1 zDI#&FNoAUB>!RCwU!586qIs0dn6Dnh4Arv?w3eysSP_AHtffN87SW;1YSI9z4Vz}m zLJU=$Iv>oIE%CIkb+7K`Bf8;+w6i@YiIyv~#_u(g42U_vZP*QG@{xH}jZn$ns$X{% zoP?S)VFSo^Uo{$fXvNx9mp9IZ%wc&`y#U>|Nc0p+OyCY?)g2M<+54!)%(5A;M5|S4 ze2XoNyxv;HNuGN9_(k19^d<*lVB8dH76z>v%3zMMmzQo%ca|Zir#$2G>?6+vpQ;lB z`#pq`o(rg9q}&%cw1OO#=~5_oI?I66A5q(@uh^7 z?Sz)tc0AWT2+oS^COMQF!%^HRz9LYB({enK%Mx6YTbv7{l(cG0(xYC@up|~mi*nuf z!GH-eZ9Ny$YS?{`DZNk;mODx!MX0JcgP}XX_3Mkk-IQy`^Fv;!rDfa`h$vK&XUDq~ z<;7CF;iRZLo}rBwbfOD8(AWv9oZ{Zgfw)CBUeFZ(c4mGg+#K)TR1yf|1OSS>FY`!d z%PlVoN`>B(#PptWg9XTV7w~uRJJLaw!lIz*jD%M0Jm}X3jjz1?Ci$a^7Ya+a=y>*T zMuFem505H;?JikDMM9Ooj`!moYI@Z!7VAvGmQq-e99l|;MxcWje^by=3>$}zVlY+Q z-bhq?-m%5#$cJ0He32?8((KV*22BH^{pWvWG>;YF=kdkwK=960eElyiwhG>a z_3}VP0|(=hzfDW;qo0gy_XltqYVEZYeTkXA1aD^slVlk8F0AQDUYaH6(3a{3L|tb+ zoG5n^*Z#esjD+^Rp+dnegWSG16kAtuE9`6vIgFmO?0EGk2H*??#vk)&&m#$d$-nXs^XCRvcvh zIR~@2m{t&jD1fyu_TI>Zp7N`rBloOn_qZH9>%Ks{58<5JuMpJH>2{SLhr{hz^m`r$ z5sq@s@k4caSb1L9*B9Wf?xNRn8Avj4-|npFQ+uO7e}nqi}E;x|AXc?o@}OGLN7hDj?OTd!umzR&N`0mp_!%? z&d$0ogO9a@LfpTCL_UUJi*;Zss@GImRP8a#gYuso^nY8{ey5P7~GyK=}J2%P5ny6rz#gU zGSrp@;;0>qZEQv7Bbw`O2b`BoVWDXUOuRtg4ZLx_-E#g;1Ny&=*%BMOY%1J00aXvw zOfi|4aF)WCnjSV+x*ZhcsJ3~1y1psyJEXg z7pwEN-u*QLjke9|4F7mD^$u98QlDU*(cK9ns`^UfZQSxv`5y~uY%zN0;FccvZ@G7P z@vkd6cF;N`L+Wc}qSU*Pli7g4bxsCpGuqREEKG;@z_0QFV}u#tG|2#Bk1IxCZOchZ z`Xwh-!15{cFUwTBJW00>>8j;P^q8H}m2Qtmx}L{$Ro^EnpI+7^^5v?6v6h-3!kJz< z>1CJI)`a7g^}%qwwXQE71ABza>I30kb*15W7sBznXgI!mElf2HxZFnSA|<*0F7#&D z2Jo1~DF_`KZI&`A9v%7`(hr4BR&_DDJm`XFI~?=sa5vGeu0zq+3MH~fc%@4qoYUJ6 z^Q!Z@?N@cP+aMif>Czm8`|AOe&9hi{&y3B(ZSFjw@d08Qoq!MV;wkpbM~eQKuVCgA z!Z;0)`BcH5Dfn}~u(1CHt=Gc(OJ)6)vi@3Ie4$ox~@!OXwpZD;;1?@;D9d51H< z%R7?Ug?D13l|}}~i5NcB#Tvy{8p|$#`1EepP;D{$40|w5gdKwdvgD$o=1QZR10p2m zkeFvDTCMcmC@}$fHWXOtdxYW>0~9Iya(?%T2^!*r~> z4jC4=mvGJ%_bMu9wi|#eG<@v8)-YY9jkR(^x{n)PUCra1a!e@smDC`r`-+bxG$Sk= zqHqtUYD_HFCEVRaBKU6+L&IIJy`7$MmSq7X3K)WigBCGXVpHkisDaS;{JbPYfK~w!} z;ZzWTM+jv5w3#jn;wlA}jdUZL>h?o5>U@foDTICEP2}8S7|b+DD}zoJ1{*x*j;5TD zIJVs5IL*StDYDs`=c#B}s`xDhB8)5(%$FQ5AquWx8eyN&Ld^bTO6ZMqBOp{e*YcGn zB=u#ivm57zc0S$zVtQV{dQtZ7M(u967P7pSxANJ^V!Qk(T%n-%_VTnsLR~E(I#~t> z=@)izn-_-LaJSmsl66WCNXQ&a6-BFF?orU$bZ&tf_%u&fCE2-&q`tL6$Il*!vGipa zzo8$DJ~1ORjoo*F8cfTPz_5!i_fT%;p@ol!+x;JcNQnc^z{&m#@0@`|m=KwRvWn@m z810%WKyD|=Ov(-%Do_u2wX$Q1>h+Zf9I;S`g3u8rcNoQLY~LwkCc3M}(5&#@EJbRJJU0wSLhq#^9gLKs?~Vn9|Q5-~CncjsZiKnG92!Fk8D zJN5*HA^W@)3XjlyhB7}({^ep;j-5Lg;aC~tk*zF2vCd|{jV7E20Xlao8%5kMgycJ% z9s=Pav)Oubaj~xgOV2>1i_ZEwV{=AD0|2M z!gNhX5hAp;xp-keLgQ&j3Ol?uKhmDy-0)eQhfSZ++BlvC4KpHG&tj&#mQn584euon zCihnGqHvDUotbvk-19MpF}dMAl#HPt9YQy{D0Hzn*;ItC8|KT=HOFxJgGfXFSwNNKBm{5=Tau(hfvmA=zC|(RkE>3CZTOqrwd2M=MxU0iC%~&4D z{A67i^Wx=)q2+;hSPCl&3P*`;71<3|Q80n`09cVX$h?&oj?}$SiZhTE&I5>JmB3ZJ zdm?N)_d*kHsKF;g_01F=>z1HV2mO$rb$N^D9Tvr=X*m^UW8&v|xJ%_hW0+s?%+CEV zsqh8m+hF2eSJaZ5dmR-ohalUm+7)8%RwDd_Pe#DF96DTrIEqCZSHc)@^WkI9nW+lI zCMM4mElJ_#1L9I`9^UR4Jc7d9q-+bs*3Vy}`HTOQzbjBIVm*NH=mb2T{B9TcFEb(5 zD3{3#r8qvo&Q)U#^P*c0Hn|(B3>VW5#3T`Ot*;;~dW=;>8MycXL5UNkVG$uD6=N8O zSmo@Av>?il_VspOTb2G4YdK7}$3)L;JD2{9IOkG2Le3NId=t^^q54oP&ciCbdF@$4Zj{sIvEAGu01lDh5zb`2F zzd-`(;5WDq`~$+;wXO%IqT6YSh15^5$&klN|DBwes7%)Eg{iFp3gBiUTG%d*ZbW&X z8fCS+bqlfyBz!Ku1{|$_(n`PSla@zm1Tc@N-v3LQY-v(_T3P~QeM`=;TrTnSE@fW` zO|cGdrAfJkP$Qb0h(2WzOvtLCrSFidqqZ4hu-e(dDlZhqb#@XJ$w;xat7|vJZzMw| z$Sa1tn(NiYd)PhM`Fp_?#^EQcF+0<80@89Vbo6BeCTNWW^aB>b~SfB9Ews zBPtm#f`=+Ch1)$H%t%n?_c-LTY$IXNr?lNGIpAmJQf0%vin0EQ8jn2+-gVT$azBDM zytptM3*1y~+2Wo1F)YFJNoSs1D^!EI3Kb35`5#j3pMuXy-@=$fFD+R!4s%`&3W&Iy z;6HlknDF=y*rXj}g<0JNb$2lJE3nM{a4C~s%8h$1Resb;-%N?UDUnw}2=%xW4(8)| z2+Mj2i|R+Go=0iLt<7v8^TOS*bcr5pq+4yjWFxl3aU9Ar2L5V z;%d7{r!69#HhkMsS(XH(Z&wshFtj@h3CD$L>AfWpC*R}G_egCX0LlE5z7KzNB#cSg zj=bgi&mJBBbnBTL6I4rSsxP*Z4xNVdy;F^Wb}oHGRO5G$qPg^)MvXfOxvwFJB|&Xf z6s(x8=2{ycgDtW;=Vzsgci3q{L*8-euM%7f?KD?gaY5{sK zbpE{lKgxi(R(%p=R+b1G-4ra_20}6CIS7(|;_lGvYW8FN{g5b}vzXY@ArU8K%89h+ zE8*r!_=WndwF{3KNOPPQ?m06T*9dbdhZh8}kDMPN7SZLg3wEdXz*d;T_976fss2MJ z0Jj;VYpEhNSRC}FW**8khsxrIRHngEX?8Tc3mWidWrHjJ)zm!dD0DsoWwHY!Q_9YU zm0>|NQ!`PcWnyA%pKdJ!t?K2$2xA|_i{<+hcaKnj3p6q#h zjPiYf#^lFn6|m|?_4aw}iv)$rl!HV^$QK*v&9iJ*>AYg5nSZi#@xg#SwG8nrVBi3m zfzPfnFM*q@C5;&u(Qdi6dko_PXXy%OZ388-6AbkNfv&a`W}GCHx1Hwf%5lz4)){u1 z^AfV|gh|x-kWmwoMiplmwK zoLmmXN`lF5rit))}xMf-e$~c*Wse@A6$o(>xfwt>FBzmN$HU=!;6NXQ|$a5zIfNA0lSht zn>T%!k4X39D~?0NnpDNF@=%mIH{00!cse}r1E9|!jkR<8<`eVf%sIU z5p(#K9JA$yaC>+eM2bO|HMS|piKy45%-b&OxcKM+eN@@6snF%O zSe5=7EEXIIj$T+J<`qK-UqHrHH$Vnw9J9ewB{o-rhHnC3F0GU+qqJA`NZ3R>`VJx! z7ZW6txJ7s^=Vj~+!)v4eBjJx0g^Gj47G@yd1*dlsI9&gVl7zWna4U0BKqh!~xMn~% z9MIC?ayb{kanu-$fJ+g}xSXEjehi-MNLg)RvR~Ncw1VaAgf~fSg(%EYej7bd?g|O@ z_h9uD%lp>Envj)>0hwe?G|Tt_Zf;~{9lRHGKp8H=*KiA9hvk@ZSXNu8gM;XzkC!{& zreX`qhw#*oSg?B!7_2_POU1J#_m|&(RXx>HnFs_C^0hJyxTL+fo zR%}BuZf1Ndz0P2K+xXm%-LtuDuw})j>NvR>e7AJuD{ok$HN?CjKDX-}huOgDu3FLx zNQ$@A+LkrGta+;KE@ua&5R~nn4x@|yOtg8bpV?{1GOqxKdCN9A*#vAEsgne(C`7hA#&UVB*|G8e1P~qaMym=~L z-S|R$ZNudX>dW$ezi9UV#XZ77_jn=SnKF-eE8|#qy;Px-B4E4ByYa5LFUa{6fy2b2 z?R+ko1lK=GXqk6SS!+}Cc*&_~vsq^FkpWKCVM+~8=QA+#lT;xoI4D&eL6)wvhOQwg zNQx)xM0&}lXi|T540RW7eUgS0m0TIBCpK}o-5*cvRX}(L;*;K_yv-@X<~soNj_r%*UDm9;lez(Wg!DXVGJ}F7@rzMCqs^^=mM~}MMFj|A zrc@%H?X=Ib*<;U6i)Ps+Nfdk5Qn91=_7%kFxgTbUQ75a(QRekA(CrU%qZLWC#M0DR zZj4&CH+AT5v$~Wtl3qswLmdWM%DicGg}gqDTkZT#G?Iu^=O2uG*fGEL!uwGl&s{zq z%zC(0_y~hHw}Qn&^{uls$4czmwqW4IW$t355_VaSu&c#(I082nr|qV|Xeahjopx-$ zV4r*5l%B~{tWnQ&!nmi)xeFzBs~FzMb5c9qvd8*atOh@l><-T<7f zh#D-7SkBWhWC)?v7AxTu0K9|9`;5o?EO`l$SKgE>2Jj9h?{gmS^W-H&UU`#O4B#C? z-WNRH7s*SAyz(Zm2MnbJ0WpB1(F4S=&2)CbJ?t4keS0}swUJCF6JVhF!u&lLsnMU2 zo)j?v807(C05IAE!~kF~4-f-@F&-cW0DF6Y7yyj*05P<0kP#C0<7hw6yHY(v5*e4P zJehrH)yr}wF`D{d3S+WonBp0xdWJ(h!!*xuC=Dz(`y=T5VT5rOFnkZH9IY`uk}*%f zU5mELnMrn!rKF)mvjk)f&6!18XwbwrWc``k{Qp~Sm;WZWnQ|G#>7L;*&oIL?9PSy8 z@C>3eU5R?bOyuUCuyaO{0TmiPHMvN8%k7T(HEMTl(40L$ zqQ^r!JK**NCH16QlluQbW?7S#x`4|4Q5~+>C+_^8iX%NoBD_fEz3@tG`g1|OAjtDU z0>#2E!xh#cVgSH#v{Wi$0Ko340Ac_z-UGw{-~bO0L;F|gDH6NGL{K|Q5~xU%v{{3+ zxvjmA$)R#ock5U#bJcjAJy!3}o*2#j^xvb2nc9wKwo?3~HIqLv&z#)N#%2}id$XsF z@7G}VIAQm~zXJbq{4w}qp=O!>3@&enj;WW}na1?kL}-TVh+GU5qy6yhKW)%@FM}5gNRpRgEVLpO>_Y3e`(Ke3a!@W*WF(!BA!+L&j| z?dZ-@?j)=4^1G8Ug#+erMb;C|{3bp5&GrhkmR#|F`614VDNX7D?X2woawe+v>g)`u z)*<{_wI{q_7S@)VYPRD7#7lKYUfEcp0^aVRAzwRK^(PKEIieh_)IOAV@?SQkbY$U4 zS6>oYvL{8ctn&0M>deFWm5yS1c4pzMi(=W{v4+w@tFwt+(8;NCB{7=#LySiMlv#4r zus<*twcc|JpLBnd2v!zlAiU9y8GH5Z;vk(ISZY&c{F|h84 zqwd(u`Yp|Qq^g>({m?U~;M6Hd-m0i<>tef{o&wOh7?b?m>@D?9H@KCtq1aW`6!bGw zy-@<;ip=6_DqV4DKwPQ%itaG(g`c!l?pl;@1hRbFmUEOJ~Q1?@S^*cgvy*rp{!nV5?rG)I%Tz>u;_m2M?=R3Fw zbO<=nmg!VW^?+JPB&QEzjA`QZ6@wMXe9yivbYuGT$6MNQ1qbkrLNmP^IPJA)0)$l! zfz#M66RrP{{V`7f-E$5`+;GZ?od2-Q5i(88&K5?#Dr5hmpcBv9ls$A3U7`VL)`dQ+FyArT; zP1!0eVuTubSQ??n;vVVMiUhQjG`xJe90+;X*p2+n2$aPo2u04=AJeM{zS@7m3|5JK z0?V1JUZO1N?=V>XQp0weey{Vo2*I2s0hFH)}cSTnkdB3Towwc9d=+EcWa8 zUgPJ0DzwDchQxB#ahS&wE^x2ct~TiRM*Y4*zpvEqtN4~Y`5?l_pXq(FBtzl&9*H+~ zk)dpS!6ZAEk)bF2q)C>8zL`q@ncFh-(+sq`r{5+H3}@M?1b}w;)W#RWhBDbhph9Jy z7{cWVdRFejPFPtPta{}~)D?1}T(lA!?~U`h ztkA}s5@Y__(+*>|dfsZ;!Y&)wi}2l84Q}wZpmIUyGs#||h-_I`7sd+$s|QtGWEzb{ zlI%w1`}B!1)W+Sm@whTy12Z#Zure4lN>VGKciXjs<>ch}uCf<+>J>^8xoQDQkd9JdRWo9o9m z3znDX$L7V$bas!HSCo z({Aq-tfYjP=k`9qN=qd@DwH4h3)ZzO_=1LZ`+#7vm>+vku(C2g_K;xZ<$mm8!Mb(x zV~+?{QQ^lP6|8%AKlYelJ$m@D#|7)z(~mtNSg&4w41ECPwRjv@p%;#)1goq>cuf!6 zDp>E{z$~Lo#lh2p_2~nw$S7CXGlKQ)3oK-GQ`obDRqX~WnA25Z&k5GAN-&)_o)>KQ zer9Db;N|-l1ao#L*1d;v`=Vg|9bjP(dr7cF{}BA>uI0TfSTbQ$<`j7H{wi2?(gJ2_ zzE=dRsrF;93RYV~%+!3_1RGH6$NnbRzyW^jHNolz`mxsqtFQB8+XZW=_hUN*8`R*( z-Vki?AV2nZ!G;X>V{ZyJbci2&OR&bFMr9D~yNbWJ1>2+10_MfRJAw_{!;kG0Y|mkk zXLxb&u3*FW^keS{He$FRdtb1TBmCG0f{hyK$37Hn^e8{}kzjj`_G2FlHfAqB_K9G7 zkMU!l3O06cKlYhm&LzlZ2$fI*w=!M z-`|gYBiI4s{n$SQn{a?&x*UBg*nt!LeBTLn(1C*Kvh}@S2OlJuE?YkcHt}G=blvo$ zV3Q^i3+gogNwCS2{MgTeO_}V+ei3Zy6hHQ>V24a4W@~x>6l~fd#KIc;mtcoZBNoxv zzXfYLlo;j=q%HeRu;wN|_Pb!yoBh}>!48}5$NnSOjKlmG&aJCY%JcGCsbD8ABxdRGb``AUL|_p^=hK*AsTPr^u`F)%x`m zZ0V_jX}7%u%Pb+5tKG&0YfTgL`Vp0aEn6y>cH3L9whS?^AJIp!(^`S$1+=`rf-PU> zkNe#OJH5@1RSCA@G(Xl)urrnmrqg_P!OlG0&*uns)(St?U$C>!@M8(V&N+*)73}<#46miJ0fMbM7g*3sBlO5oelIwWe7N^Y>WDhQ zEQ#QML9mN1@MD7n`^$xXY_MP#ul8d@1iR!SKQ>gbHGdII$7!QrmtO4W z+e5I+E)h(Ztzm*)zD6)zw)PZk?WKb0I2bP2y32^=>wGXmu=SVwv5|spSnJ0|3AS;a z9~&*$73+z0(em~Z?8*(q3N$uGu&Xu_E7aKDf^E8jSdqrY3U>9C!1D5R`4}hIHCGYy z`1TR(+D*i~a;S>;z21*a5bVAi{Mdnl z-G8HCI^7Nu?17v7*ujE5aWk;I9G%xD3ijkJ!l%=1l3-8YN;$Bq!}?FZPW_WF)91$*Z~_9u&VewiiM&WG5~_ORK4 zz56ibdF{fHg1z?$F)!|qBDTwTl$aN%M+=tonCPP8^cca+$NktG!K^3z*s+2Ip7dkK z2^M_HkIfa#-U=+>`8!Xr(9^`cy6JeqBF_Np;??)_1&cl_nAQ)MI3gUm&k^(L`vrpK zJr6A3bBpVK!I%GnVA}0M!MeOi%yWx-#=%$c60mIlv_-I@mzf@3KQ<*;@m~X#fkH2h z7714J3b1Utog`T4tA1>;U|qMd{Ce{69R>Is`&+Owkmt!eMX<8hs7pwv`Kf}HzwXDD z2-a;o+-7x23s$j%?XM?qsbD?cfZIGT?lXe*{5$1&d81XZUT;EP*6lK2Sl188IcDr( z!M^)>*qIh^PL}67JRJv zL8llSV64<-X+t7Y3N=(>)_5mazLm&qlWa#e(N)@{(Qn8M=Wl%5f@= z6So<WkQ?w`!XdSASJ0B9V} zSO+nclc$WG!Vk;p8%pv*72y~z0@@3Thvi-pGfm0zUA{D~$qB@=_Qh7%xdq1{BFi@farVxo|FpkG$zuV#WOpYYeha1lPP6xDQ0d8ZvN;2-ZP90G7hBWZd;5--MM@W&Pxtx&bK@jg_UalMmbX zY!|z_qC2A@?C9@!Z&1>R3^Jk+iT<*z(RkVM2$kt@vq%aV7;CXsW(9*@k$RY_;KVmc z%U#=n+CU0>k7(y^A|Z3oTwVV!<*2{E967hq$-F-+LCOkpxK6^=cWja`vdq-6+%9IJ zY?h%&<>I==)SZ;!1p`TN7Ifi(7ICZA4`9SHxGq#@z#fI_OnId-WgEzxO>>%0s}{5I z!XacP#U0oI_gVOgd+brV?|^T(u!f!>ZkTxRi2DlPgdfObIAgULAUkXZ{;B&tp@hNLjcp(EUlK^_7L$WnA-VBM=BV>R>J$$yGZavYc(D;)H8-;n zLhP`7H!}4u!*UR=p1@nhkL5nWI8o^{7GZygVV9_ryW!$>?j@)Q_3db}IxMWH7*1ou zHWrl5&&QosnYWNl@tqI8;N#nPA(mAHqBJ@8(Obyo-NQUDdl%Owo%^YT^MI%#A>~cI zD&1YVI$pAXtL~2%h8IvDDTXw^UBts4kMg7z>-=XS7vHM$bZ>%oSQl)MXkPo3jb|?m zL5F`sn9TNjn%mPuC(RTpz69}=;gyWO^m31t zNMzQR^mC5_t>WI2b`jNNhjuZw8JRCCtq!WMTag-z3Xsw9J+9OvOtwz-OZzUKbKnKa z-%7l|bRBuSqx`&!bifH3qyuf-dx7(0u@oL$?x{)%HXUY5kv6jwg`=WPF1$vhRmBf< zAC>n+{T{2|W8`h7se*iYYpyHzrwb69Cm)gym8n`33)*Ch=&F?G2UJyBY=o3sDIw+Z zeb}m)R{L(KEw?hq)^4gQL+y)g@KN>cRr$KA_nqx?j4qd|dKfh;18lkXFecb;n8t1h zB!8&{YRk5BVVz3SbRJACv$!4MS`?MG^GV*6C0CLBF-u-Ra%6Xp`9hLsXUWwd%UZU1 zwDS~vFK_A5L$eFrtz}LJx}s%s2fBO9zdF!8TE_PDyYJbussr7t<&6$BK6B8gm)}7= z+A_Z*klV7QBaqjET@fn$qGMuCE8_=eGpi9pt&AaT_N;*!%doACA?JL=6*sWQByM@T z%wx=FWev92V=u9~kj+j!Vzx38vo6e5MxrLm6J{$TQIp-YJjXAOt`lZCB-0_TSb~Xe ze15P!D}fuFv@R0Wd0eCx`bvLHwV&N#{{-zNIItf;d*97*+}Yg9B+RO+&-R%{hwzcb z=QlpUei0q9Bb`=$^N(Ey*I-E~N3sSB z{=azqV%VfwVeXzB&t#N6RJif#XDF1RYN#0gC*x0@8AqDwYvGQ4TG_<{FG=HCOx@mB z)!6-7pGIw;5xm|M!g+^Lu#Z`$i?6jwA#i@3r?D6STu)$$CoeF!b;Q^;e?i`?(CRou~5xvN+12=IbYwHdq;jP<_#-cR7rEFzJcw`Ta$ zQj&;qz&lI=aw9}WVnF#f3t~{c72#H7Q|^f1)*)&r*F3Ng;AA(tl%llU79kf!SaSTW zp)0bN&&I$oU{V?PTe8j0O2Mat6EBDyszWhhj!?dm!geHmQxR;oZNh4a$U3?)#DyYQwKe5*5j=F+=i z&T1iqPYdy@eX|;hC!H!sKEDLieo+Jq^gVpDK#Ku6YzsY_?WMSv-j$Nxv{UIl3B?2X zi$Hr<8kNQUbo~oU3S{34LS%~pz*mpRzD#j8FwX*t++XlH~4rGFQMvGgD3 z&oTc5D3^Yq^oww|f%_nz@Tc4``rD)A4-$UuBtZ@*H25+r)P2BHR}26i^Z+pcc*q09 z@I|}Ner+>!4n^q*0|By%Z-YAe_N*sM3=saD2Z#Z{^By1u055oe7yvxu0b*$1q$cD@ zGyM|m`4LO0_`I}zTGEzQDs3B7StcOK_@XCN4F1ABxMK*mlM&S(lMFeEqy%(mN46cF zJTXLLyoJ>1i*kuL5(oi#!{ZS{d%g3F==yiqDqV3G9P=T8Y~Pdhlj3``GarEte5hE^ ze|#&;hmZDB9s%6eT9G)?Y<(MMrJineM5Rs^Qic7|qN{4B#9~ZKi`NfnqfC~Nclc)M z69a&q9w3HRuL)6N$b|Y)nm(~-yqIzi=d%olZogCos+e)v4*Dv*a|pN5=&Dsa&DQ0Z zwLl!a3*jnGaW4nsfB@p445Rhd_h6PdNQ`NDEE@`<48{9=GZbO~@PP-2A=({hYg#|_ zL})%Fw%Cqo=~Ah?XKm!6z>hrlVu<#@K(h5?pL>DFw9Lplq$M4G!uLp1t~lbfNr!y? zyoB>pu&8ieufj<{^7&_U%wUKC(mwY9F-Uw3L*Bw26o_kPa@H}wWjBPwCHO}ui3N(QnuAzXJMr`RP(#X+|bj;jl855|3wdjRpqv|)D`sQTyZ z#41y6K*I&Ldjd(6onMaJ%;6K0X_GSr6-Q!Zd{^pI7^=+7DflF-ng`=K?-vmt=r_co zExQMdg}J6P8C))Qm*Sf4-NWtx7_4H;{T_)~U4|*PvS=hX*(DTVpC?+4djbPHyMtXjIwbBP4w+RXp)^M3MBa5X45D$8pf-!8M2QvoNCg5>)>f9a}KAD?X~e& zP#gng-aB?9bbJXq;?8?aZ*a!6 zRudb5fQ?g3VEYT%jF@vIJjaAo6JF7sBm3<{NnW3ITGFkfeJ|LXX)0J<)N&KbSHRf- zFH+OtdP%7qQ899QKxw1dD4c6pG0DcK8inU5GsA@RF<$?)XyEV1A-lf+q`@L_!&&D;B zW+PAY_Gyp3t}W%gq0Cy;LC#2I2rmY4wWEr^Ek@BZUi^Jv6#bygoEJP6vHMrVAIF>O z@U!V0&D49P9y#B6g5k@7K5j7{xv5c*UKMgnK(u_AgG;8IyU8(H!KGx}OPR;uA`Te_%91&N#@+3zs_k z;9VUJTkgIvUdW@uKiufiWLSGk{(<>0!$LPOhkX*x+x2AK$nY~W z%lKH$`LHr`dG&VKZ-sAWE^YzJ3`MN|6&S>lYxa}kC4$xa(hRXyFq_=Dr z14imCJ89C_c}V*(7`jV&cCj?&o3vNu8+Sc)Ea$d+2tt6;c^qDyC%`bI`2hvd9fe9k z>XQ_iq9z+US`f>K0l@bJrkUzkfY%dHwriAatUlKA3G_9WlGphj=__%CJ9ZIcNEh}c zs-ge+jQi@{E4OawaT+hiDAnIgv}af1iq@Rz`l}!6yRaWh(>Z}Lb*AYYh&K+f;29g3 zy~UZ9=N-%e&jL)(VF2G9dLK+qD~&XdW+uWc{s-k7E2>@eiQ+nwl4_>uE297#td(w~BVV z`Ryh{6W&J}2uMXLRivo*6pA!lTtpYU`(5<0To+UJmd+bvkvCpt9pUyx*Cw9loXM4y zfSibN zmK;ex2P5@FWx0WtHJvSI(~?|=E3T`^HLx=mK4PS}&Qx62l50q3t`?8$e9wR@o0PkA zJi|&FYE!pRz;M3+BnVa_P(}joVErDV-$V6#xPD{#RrpW|VdVsIz>gHDj}ExFa!u?e z>-R?e#@dh4WHk+QvgLk%=zzWsa&G1Ts)N3UX>g8E%2t}zQ9J&7Ek1M85H)s&a7#K= zf7_dDF2Y7zeA*sAw&!JVw2keNxWf@y3l_9J0RK(+$D;52gcpjL_>0m7`Hhbg!kI0q zk|yHbfpU{Mm^8{0UYYSUmx-&g=sU2^$`E^Z9gbX8&)3}UdQi@ls8-!11x=*m`0wI6 z*$?Fuw2SjqyaQE9F4vNGPWSjUm-OdeQh`P(7D*_~6eybFQZ3daSz3j{#bQ!)RDWEC z5sNa)9$=KAi?tW}LjmZ{Ul+s`{}Oqi7kH5(>Q&>qby0J7NMbe42xzbN6)E-bP`LeD zHqPU_8gS1XQ&Q5jA=iwlsE#H>vDE$0gOgbY!al?3W|izb1{7KHNxa%7(HpPGu~;l* zcBxH0P0J~MOP0NZO+@6~Ue3Z=I$575>oh+rZvE zxafN)Wo@7tvR{*QqI~yUNK*$Fg*=aa0JNY3u&gs5qfJ~b)q=}P0_xKvUBm7|P?n-_ zOzdt@34M>$iD-f9F|b4Yc!8Hdz6VWoTX`D%j*8#MLnmAsnC2TTCH*#+lHiq&yiQQt zr2Y*uYPWovgX7jaVYW@@T?lkPpjmwjzUq}<**$m!vfXb9XDCR=)^Y?$33Iz4nzUT# z!MNs_7BwR32?_jM2EOC>?eoBa5rdKJRThiIQf({+SASe%`V|FO&g z51{Wbp9%#sC-4=_EZ_^DqH*ON%q*0*ojDP2WZVzow5^3^FE=5NOXDY3E=pWl#>vp? zb?A=EH~7V-Xn`qjTx`hUL|Jnlt~V7!ev)HAjvqo1c@02&))A@0%260jBDlOg9NQJZ zd~ig)X4X8Z>hP0cHq%7hL)fM)A#JAl%A7=VS%$9K>u`}F_U;$xz)KxYZud)2GGv!A zcqUE9sKd$6I-Il&%2|ht-p)!|C6aCvn&1C2UdB$X=7L{n9VQ)i_)K7dT&)1bev z4*!f%_Ww|aw|mSwTomx?aH{F6!-dS&;XAT%uIg~6WqTbiQl$>(`-`9X}p4dV^S52P_GrK&YnHhbZtc{O=Srj(4D0F#W8wQtndin#89xSnewYk{rFZe5+JUtV0~_l0AQCj@`M*=edR*X zW9GXYfAVLdi*o1{TapnTNS1FUN}t8J0wkIZ1GTS#%Gl@{m2rxJeqE+eq`eBl+BP1d*PCKa)pf zaKm2nY~#U2eC~ZGpS81zZ`q$Qb5%ag#UgFP0W`lni<(c0)BJTFL-(@Cc{f7j(aH4v zp(DB;3-cHvixYg_zaO8sT*v3F&3vx8lu!3W>hp%kUm{^QCVaNiHog+c;~E+Bho$)J zw;!MT+{foJf_$-v=GE)?yn7I}U3mu0qa=L~A5Zz8Cn$fx6@31*H=i#et!?AID`@*! z1;bJ}lh1Awhy<6AXYF!%O59p4G(QLPvYgVhnL~Cc-9+bd(K#rgxKAVuZWTEjDf8e< z`5eE5&#xs-?~&)vhmz;Cvu~Sh8&6K7*=(XO&#q@E-f1B6tvvHjXNu&>^Ns?_iAMMg zo~t7En5hu#MceQC@wr8` zI`SC0%2`4E50zZhL(JcbxmS{S<>};)3xAnt(qEnn9VZ+ zR)uk^P~nB-?2eo6b5IHOTC;h^R-@8*U8tvLk=k9TLgU^3n`dk`lbW*K%`+xo-sVlw zW#8Q?rP_E0wO^re-KnI87`ssE6&f2rO*DoYAw))@agtDtMukv=L5;Q=xmOl;cL_BT zvycpJ*>XzR%lJNrGV^K`^|Mfc=;j&6!S3HeeG(xx#@Hp)&!83?V-3rs%vEsL3MwR2 z@qo=UmV=52^)u|w1eGgPBdC?2@`XAW)GAN~LalJm`o>?hPHxVsHhf1y6qz9)rR z0M0vMS0mJS+HQbQKfrDa?CONd1@!=^2BD4yCu3rWP?q+gQK$s8rhmhP+77!%Kn)k_ zml~znD536!%qNU-#u%Y$!TB_(u|lnYl;=V1Bh+6(y$otUp$-GJ4b*s{Dj{VPs0l)y z1u5G>VLXWRs{rR3P?Ll@6`Z7|2sI1To1hL6Y9rjy?ogp_gS(xenuR(M)CZsr6Y4-M z<#3@M(LUg+d-%7vre+KE0Ay~2yQ73UI>S6T&X^-q0{L^a)oSc8S#r)^wt2?y_~!1v zKouHiUAlQjBxf1ETT80GW%G=DR*fl zL1A7%%JikiRI&Tj-8^GP&N@)kWvPR@z`V+sCw9yCq|8mmLUH%gUs(EYGVT$(Ll$hF zF+b;FQgCOWya&vu4191CK1{oqoLh~bg|l=o)-TU$D%f}PjN#^UMwb9XJ7_rVo;PAb z#ZNXJ zMx4=Zfw0kh58viR@z-B)W3}Pgt}0ue;XePHBhMEjn5>-W}p_1p_czL zz`WFqyfni2kMW~~;YQ?0WcZwLknwqfrlLXmFbw6P8Fu+WhUhZbjW7Z^ML~vk6zZ38 zMlff$AoIk>Gievfse(K7`!8n9SLHMdb=yKxBZMk6UPAsHXpYl%Hw)*aoae=d0?Dnj zNkL}aD9SuG=OdBwhUBGrIll!NhPGoVr3DnVz7Cw&+nQ5g)7_V#0#+)gNT}^XEz0Q* z3O%nRbvY@gO6*ED(uY$t_0a}WD{@AO-ELxcUd|+;zJu0_%!_l55-Hd8rj+|~-VkcJ zP!DVB$$e?}xTcPg@I9-kM^@7AWl{)39YQ+-vkFSeLnCOnBj-Jld9j4{ccBW6Cy=kt zHbdrn==u~Ib5X|rW#pOvu^AI{B{lQSV2EKq88t(|Dl!W|8AhG>USyVt-If&ntI|{t zDgBPwD4a)1-Q$=eg|j>9Hc6n&^bZVi}&%_GEaKa{F~HN-qx+|7_OHpHAKoLv(1 zVHha-zIGl%G~8SiVj4XmC2j&J>N#fuIVYHlh5CFhse{dBLftTuJ{)46BT|wmw_DM2 zoF8Hh_Wli|rfX`dP{(NML80bpYLiecnmS&nlQgwLs8c{u&&3i;twI$V7qAYoHfSn> zFpMy6HowH+vC#PU{LM3V8Mm81K$k*eBGSRk*=+t(?9OZ>=ba|10?7P&81=lz>>FlE zzbpCrbx@4YZ;^Km>uqzqP(#pn8)3X-9xCn*MXGEyzBLzy>BFnX(=KEw>PGmEex!Ax z*xfI7c~*;1tHiF*N(r?{s8VZ@P-BIPStkh!xrU>=vR<9$}0D#jt;W>WY#Ra>iKrzz?Ximaix|5!6FMy_Z>0LQZ@j3+@hTBQ?(Y zGR%5n=L0KB#)0}q>~2ibZeQzLq2@wnqjjY9yHL51Ioz6Kl|(4zj^oLBsAD=|K3pLfSxPR<2Yqd31?8;jE#}4I%~dA4`^yZqzz%H z11Iekid|UTt+P@QhA%19dh2Ad`zPEjvNl+)LhTN_rPfAkxlmt<-A3ySP?+DmtAA{( zvC%q9sJtV|w$ zZ(HXJ6)GV0uC+?2$A$XPx_59UZFYe6a=&m-fUfeYaXI)@}Q1d}OWDN>j8DTE}D6t;-Wl&&~*d1}|`WcN@ zVNg-V^7ZI-l?GoF&hjzj>=yh`CfaP4z#A)KX9^M=v8L#u;ltwL!{ttLfjS z;OgjUup4y&sjGt*i7vk_A=PI8MW_jgGg6ld^`qFWu&)+stk|uvuNUgJG&#?(ZxQO7 z(-gH?sO!Y;9Q#3`J`uZf>_D9}TYW33i|m&~>%0f4^=0;3urrL~MlwWK z2~}uZe+oIT)zn+y9AR8%zb8_zI*zGwgZ+_6dG1cYSddpDs{LcL)-LdAyBhj;9Hp)P@D z7Y5$78-GzdABbTM|b_v7R_N?4CXuVYO#P^^W+Gdn0%y8Pr2=%P^@V$MU zNGV*(Fnn*%6CZY>1iT&i-abKMBEGw_TPQxfg&B|$#*g;m+$enDjMO+ICv?@e7ALf820hIF8Yhi(@C_Q1sL2xI@y{XWh~p(lLQl+acmH7)d9 zu7#L?bPU}c8QLyV3TI)K+B!b8L#Tn8dOJ54A$nyIV`+ZqeV>$;&<7%ApUsrADD<(o z!)`vIKFuvb7{)`hamLcnw?fS?@Kd9~*={!n!?kwmiVhS6`RsU$tKw`=Bl<9{ZCqnf zXjP4>R)FWX6Mw?kBmdZ+ z0!79z56uq7j4S3095St~-?ESz_FD;NT%8MoG`Xz>g}UF9+V(~)P7J!szd3_b@;akHG8_ecS$?#X8~l7gJE{ZGd8PQ*ZtQM@0Y`Ns|fa@U&q zc+TB&EwuXeXg=SbMgIE^y%u55JthtFD!AIsm?pZNw8jkdHEvI~4e2XLU*qc78PNRX z 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 z%0A+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

UfALfYK^{$~MG?_O^!p<8kkAx>KOFA^aK& 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
  • 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 RlL7Z6wx3`B{QslC{{cK6b0Yu% literal 0 HcmV?d00001 diff --git a/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.props b/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.props new file mode 100755 index 0000000..22b69ae --- /dev/null +++ b/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.props @@ -0,0 +1,13 @@ + + + + diff --git a/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.targets b/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.targets new file mode 100755 index 0000000..4091eef --- /dev/null +++ b/pkg/Tizen.NET.API10/xamlbuild/Tizen.NUI.XamlBuild.targets @@ -0,0 +1,58 @@ + + + + + + + + + + XamlG; + $(CoreCompileDependsOn); + + + + + + <_XamlGInputs Include="@(EmbeddedResource)" Condition="'%(Extension)' == '.xaml' AND '$(DefaultLanguageSourceExtension)' == '.cs' AND '%(TargetPath)' != ''" /> + <_XamlGOutputs Include="@(_XamlGInputs->'$(IntermediateOutputPath)%(TargetPath).g.cs')" /> + + + + + + + + + + + + + + + $(CompileDependsOn); + XamlC; + + + + + + + + + + + diff --git a/src/Tizen.NUI.XamlBuild/README.md b/src/Tizen.NUI.XamlBuild/README.md new file mode 100644 index 0000000..96dc594 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/README.md @@ -0,0 +1 @@ +# Tizen.NUI.XamlBuild \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.csproj b/src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.csproj new file mode 100755 index 0000000..16003e2 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.csproj @@ -0,0 +1,28 @@ + + + + netstandard2.0 + + + + 1.0.6 + true + false + .nuspec\Tizen.NUI.XamlBuild.nuspec + configuration=$(Configuration);version=$(Version) + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.sln b/src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.sln new file mode 100755 index 0000000..0148831 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/Tizen.NUI.XamlBuild.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.NUI.XamlBuild", "Tizen.NUI.XamlBuild.csproj", "{473C3BEC-2F67-4285-85FC-BF4E96BFFF1C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {473C3BEC-2F67-4285-85FC-BF4E96BFFF1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {473C3BEC-2F67-4285-85FC-BF4E96BFFF1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {473C3BEC-2F67-4285-85FC-BF4E96BFFF1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {473C3BEC-2F67-4285-85FC-BF4E96BFFF1C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B7C41CDB-2CC7-4005-8E06-61BCAB3482A7} + EndGlobalSection +EndGlobal diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ApplyPropertiesVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ApplyPropertiesVisitor.cs new file mode 100755 index 0000000..8c5f198 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ApplyPropertiesVisitor.cs @@ -0,0 +1,712 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Xml; +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.Binding; +using Tizen.NUI.StyleSheets; + +using static System.String; + +namespace Tizen.NUI.Xaml +{ + internal class ApplyPropertiesVisitor : IXamlNodeVisitor + { + public static readonly IList Skips = new List { + XmlName.xKey, + XmlName.xTypeArguments, + XmlName.xArguments, + XmlName.xFactoryMethod, + XmlName.xName, + XmlName.xDataType + }; + + public ApplyPropertiesVisitor(HydrationContext context, bool stopOnResourceDictionary = false) + { + Context = context; + StopOnResourceDictionary = stopOnResourceDictionary; + } + + Dictionary Values => Context.Values; + HydrationContext Context { get; } + + public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp; + public bool StopOnDataTemplate => true; + public bool StopOnResourceDictionary { get; } + public bool VisitNodeOnDataTemplate => true; + public bool SkipChildren(INode node, INode parentNode) => false; + public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]); + + public void Visit(ValueNode node, INode parentNode) + { + var parentElement = parentNode as IElementNode; + var value = Values [node]; + var source = Values [parentNode]; + XmlName propertyName; + + if (TryGetPropertyName(node, parentNode, out propertyName)) { + if (TrySetRuntimeName(propertyName, source, value, node)) + return; + if (Skips.Contains(propertyName)) + return; + if (parentElement.SkipProperties.Contains(propertyName)) + return; + if (propertyName.Equals(XamlParser.McUri, "Ignorable")) + return; + 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. + var contentProperty = GetContentPropertyName(Context.Types[parentElement].GetTypeInfo()); + if (contentProperty != null) { + var name = new XmlName(((ElementNode)parentNode).NamespaceURI, contentProperty); + if (Skips.Contains(name)) + return; + if (parentElement.SkipProperties.Contains(propertyName)) + return; + SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); + } + } + } + + public void Visit(MarkupNode node, INode parentNode) + { + } + + public void Visit(ElementNode node, INode parentNode) + { + XmlName propertyName; + if (TryGetPropertyName(node, parentNode, out propertyName) && propertyName == XmlName._CreateContent) { + var s0 = Values[parentNode]; + if (s0 is ElementTemplate) { + SetTemplate(s0 as ElementTemplate, node); + return; + } + } + + var parentElement = parentNode as IElementNode; + propertyName = XmlName.Empty; + + //Simplify ListNodes with single elements + var pList = parentNode as ListNode; + if (pList != null && pList.CollectionItems.Count == 1) { + propertyName = pList.XmlName; + parentNode = parentNode.Parent; + parentElement = parentNode as IElementNode; + } + + var value = Values[node]; + + if (propertyName != XmlName.Empty || TryGetPropertyName(node, parentNode, out propertyName)) { + if (Skips.Contains(propertyName)) + return; + if (parentElement == null) + return; + if (parentElement.SkipProperties.Contains(propertyName)) + return; + + var source = Values[parentNode]; + ProvideValue(ref value, node, source, propertyName); + SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); + } + else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { + var source = Values[parentNode]; + ProvideValue(ref value, node, source, XmlName.Empty); + string contentProperty; + Exception xpe = null; + var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null; + + //ResourceDictionary + if (xpe == null && TryAddToResourceDictionary(source as ResourceDictionary, value, xKey, node, out xpe)) + return; + + // Collection element, implicit content, or implicit collection element. + if (xpe == null && typeof(IEnumerable).IsAssignableFrom(Context.Types[parentElement]) && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) { + var addMethod = + Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); + + addMethod.Invoke(source, new[] { value }); + return; + } + if (xpe == null && (contentProperty = GetContentPropertyName(Context.Types[parentElement].GetTypeInfo())) != null) { + var name = new XmlName(node.NamespaceURI, contentProperty); + if (Skips.Contains(name)) + return; + if (parentElement.SkipProperties.Contains(propertyName)) + return; + + SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); + return; + } + if (xpe == null && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) + { + //if there are similar parameters in the function, this will exist issue. + var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); + if(addMethod != null) addMethod.Invoke(source, new[] { value }); + return; + } + xpe = xpe ?? new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node); + if (Context.ExceptionHandler != null) + Context.ExceptionHandler(xpe); + throw xpe; + } + else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { + var source = Values[parentNode.Parent]; + ProvideValue(ref value, node, source, XmlName.Empty); + var parentList = (ListNode)parentNode; + if (Skips.Contains(parentList.XmlName)) + return; + Exception xpe = null; + var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null; + + object _; + var collection = GetPropertyValue(source, parentList.XmlName, Context, parentList, out _) as IEnumerable; + if (collection == null) + xpe = new XamlParseException($"Property {parentList.XmlName.LocalName} is null or is not IEnumerable", node); + + if (xpe == null && TryAddToResourceDictionary(collection as ResourceDictionary, value, xKey, node, out xpe)) + return; + + MethodInfo addMethod; + if (xpe == null && (addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) != null) { + addMethod.Invoke(collection, new[] { Values[node] }); + return; + } + xpe = xpe ?? new XamlParseException($"Value of {parentList.XmlName.LocalName} does not have a Add() method", node); + if (Context.ExceptionHandler != null) + Context.ExceptionHandler(xpe); + else + throw xpe; + } + } + + + + public void Visit(RootNode node, INode parentNode) + { + } + + public void Visit(ListNode node, INode parentNode) + { + } + + public static bool TryGetPropertyName(INode node, INode parentNode, out XmlName name) + { + name = default(XmlName); + var parentElement = parentNode as IElementNode; + if (parentElement == null) + return false; + foreach (var kvp in parentElement.Properties) { + if (kvp.Value != node) + continue; + name = kvp.Key; + return true; + } + return false; + } + + internal static bool IsCollectionItem(INode node, INode parentNode) + { + var parentList = parentNode as IListNode; + if (parentList == null) + return false; + return parentList.CollectionItems.Contains(node); + } + + internal static string GetContentPropertyName(System.Reflection.TypeInfo typeInfo) + { + while (typeInfo != null) { + var propName = GetContentPropertyName(typeInfo.CustomAttributes); + if (propName != null) + return propName; + typeInfo = typeInfo?.BaseType?.GetTypeInfo(); + } + return null; + } + + void ProvideValue(ref object value, ElementNode node, object source, XmlName propertyName) + { + var markupExtension = value as IMarkupExtension; + var valueProvider = value as IValueProvider; + + if (markupExtension == null && valueProvider == null) + return; + + XamlServiceProvider serviceProvider = null; + if (value.GetType().GetTypeInfo().GetCustomAttribute() == null) + serviceProvider = new XamlServiceProvider(node, Context); + + if (serviceProvider != null && serviceProvider.IProvideValueTarget != null && propertyName != XmlName.Empty) + ((XamlValueTargetProvider)serviceProvider.IProvideValueTarget).TargetProperty = GetTargetProperty(source, propertyName, Context, node); + + if (markupExtension != null) + value = markupExtension.ProvideValue(serviceProvider); + else if (valueProvider != null) + value = valueProvider.ProvideValue(serviceProvider); + } + + static string GetContentPropertyName(IEnumerable attributes) + { + var contentAttribute = + attributes.FirstOrDefault(cad => ContentPropertyAttribute.ContentPropertyTypes.Contains(cad.AttributeType.FullName)); + if (contentAttribute == null || contentAttribute.ConstructorArguments.Count != 1) + return null; + if (contentAttribute.ConstructorArguments [0].ArgumentType == typeof(string)) + return (string)contentAttribute.ConstructorArguments [0].Value; + return null; + } + + static bool GetRealNameAndType(ref Type elementType, string namespaceURI, ref string localname, + HydrationContext context, IXmlLineInfo lineInfo) + { + var dotIdx = localname.IndexOf('.'); + if (dotIdx > 0) { + var typename = localname.Substring(0, dotIdx); + localname = localname.Substring(dotIdx + 1); + XamlParseException xpe; + elementType = XamlParser.GetElementType(new XmlType(namespaceURI, typename, null), lineInfo, + context.RootElement.GetType().GetTypeInfo().Assembly, out xpe); + + if (xpe != null) + throw xpe; + return true; + } + return false; + } + + static BindableProperty GetBindableProperty(Type elementType, string localName, IXmlLineInfo lineInfo, + bool throwOnError = false) + { +#if NETSTANDARD1_0 + var bindableFieldInfo = elementType.GetFields().FirstOrDefault(fi => fi.Name == localName + "Property"); +#else + var bindableFieldInfo = elementType.GetFields(BindingFlags.Static | BindingFlags.NonPublic|BindingFlags.FlattenHierarchy).FirstOrDefault(fi => fi.Name == localName + "Property"); + + if (null == bindableFieldInfo) + { + bindableFieldInfo = elementType.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy).FirstOrDefault(fi => fi.Name == localName + "Property"); + } +#endif + Exception exception = null; + if (exception == null && bindableFieldInfo == null) { + exception = + new XamlParseException( + Format("BindableProperty {0} not found on {1}", localName + "Property", elementType.Name), lineInfo); + } + + if (exception == null) + return bindableFieldInfo.GetValue(null) as BindableProperty; + if (throwOnError) + throw exception; + return null; + } + + static object GetTargetProperty(object xamlelement, XmlName propertyName, HydrationContext context, IXmlLineInfo lineInfo) + { + var localName = propertyName.LocalName; + //If it's an attached BP, update elementType and propertyName + var bpOwnerType = xamlelement.GetType(); + GetRealNameAndType(ref bpOwnerType, propertyName.NamespaceURI, ref localName, context, lineInfo); + var property = GetBindableProperty(bpOwnerType, localName, lineInfo, false); + + if (property != null) + return property; + + var elementType = xamlelement.GetType(); + var propertyInfo = elementType.GetRuntimeProperties().FirstOrDefault(p => p.Name == localName); + return propertyInfo; + } + + public static void SetPropertyValue(object xamlelement, XmlName propertyName, object value, object rootElement, INode node, HydrationContext context, IXmlLineInfo lineInfo) + { + var localName = propertyName.LocalName; + var serviceProvider = new XamlServiceProvider(node, context); + Exception xpe = null; + var xKey = node is IElementNode && ((IElementNode)node).Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)((IElementNode)node).Properties[XmlName.xKey]).Value as string : null; + + //If it's an attached BP, update elementType and propertyName + var bpOwnerType = xamlelement.GetType(); + var attached = GetRealNameAndType(ref bpOwnerType, propertyName.NamespaceURI, ref localName, context, lineInfo); + var property = GetBindableProperty(bpOwnerType, localName, lineInfo, false); + + //If the target is an event, connect + if (xpe == null && TryConnectEvent(xamlelement, localName, attached, value, rootElement, lineInfo, out xpe)) + return; + + //If Value is DynamicResource and it's a BP, SetDynamicResource + if (xpe == null && TrySetDynamicResource(xamlelement, property, value, lineInfo, out xpe)) + return; + + //If value is BindingBase, SetBinding + if (xpe == null && TrySetBinding(xamlelement, property, localName, value, lineInfo, out xpe)) + return; + + //If it's a BindableProberty, SetValue + if (xpe == null && TrySetValue(xamlelement, property, attached, value, lineInfo, serviceProvider, out xpe)) + 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)) + return; + + //If it's an already initialized property, add to it + if (xpe == null && TryAddToProperty(xamlelement, propertyName, value, xKey, lineInfo, serviceProvider, context, out xpe)) + return; + + xpe = xpe ?? new XamlParseException($"Cannot assign property \"{localName}\": Property does not exist, or is not assignable, or mismatching type between value and property", lineInfo); + if (context.ExceptionHandler != null) + context.ExceptionHandler(xpe); + else + throw xpe; + } + + public static object GetPropertyValue(object xamlElement, XmlName propertyName, HydrationContext context, IXmlLineInfo lineInfo, out object targetProperty) + { + var localName = propertyName.LocalName; + Exception xpe = null; + object value; + targetProperty = null; + + //If it's an attached BP, update elementType and propertyName + var bpOwnerType = xamlElement.GetType(); + var attached = GetRealNameAndType(ref bpOwnerType, propertyName.NamespaceURI, ref localName, context, lineInfo); + var property = GetBindableProperty(bpOwnerType, localName, lineInfo, false); + + //If it's a BindableProberty, GetValue + if (xpe == null && TryGetValue(xamlElement, property, attached, out value, lineInfo, out xpe, out targetProperty)) + return value; + + //If it's a normal property, get it + if (xpe == null && TryGetProperty(xamlElement, localName, out value, lineInfo, context, out xpe, out targetProperty)) + return value; + + xpe = xpe ?? new XamlParseException($"Property {localName} is not found or does not have an accessible getter", lineInfo); + if (context.ExceptionHandler != null) + context.ExceptionHandler(xpe); + else + throw xpe; + + return null; + } + + static bool TryConnectEvent(object element, string localName, bool attached, object value, object rootElement, IXmlLineInfo lineInfo, out Exception exception) + { + exception = null; + + if (attached) + return false; + + var elementType = element.GetType(); + var eventInfo = elementType.GetRuntimeEvent(localName); + var stringValue = value as string; + + if (eventInfo == null || IsNullOrEmpty(stringValue)) + return false; + + var methodInfo = rootElement.GetType().GetRuntimeMethods().FirstOrDefault(mi => mi.Name == (string)value); + if (methodInfo == null) { + exception = new XamlParseException($"No method {value} found on type {rootElement.GetType()}", lineInfo); + return false; + } + + try { + eventInfo.AddEventHandler(element, methodInfo.CreateDelegate(eventInfo.EventHandlerType, rootElement)); + return true; + } catch (ArgumentException ae) { + exception = new XamlParseException($"Method {stringValue} does not have the correct signature", lineInfo, ae); + } + return false; + } + + static bool TrySetDynamicResource(object element, BindableProperty property, object value, IXmlLineInfo lineInfo, out Exception exception) + { + exception = null; + + var elementType = element.GetType(); + var dynamicResource = value as DynamicResource; + var bindable = element as BindableObject; + + if (dynamicResource == null || property == null) + return false; + + if (bindable == null) { + exception = new XamlParseException($"{elementType.Name} is not a BindableObject", lineInfo); + return false; + } + + bindable.SetDynamicResource(property, dynamicResource.Key); + return true; + } + + static bool TrySetBinding(object element, BindableProperty property, string localName, object value, IXmlLineInfo lineInfo, out Exception exception) + { + exception = null; + + var elementType = element.GetType(); + var binding = value.ConvertTo(typeof(BindingBase),pinfoRetriever:null,serviceProvider:null) as BindingBase; + var bindable = element as BindableObject; + var nativeBindingService = DependencyService.Get(); + + if (binding == null) + return false; + + if (bindable != null && property != null) { + bindable.SetBinding(property, binding); + return true; + } + + if (nativeBindingService != null && property != null && nativeBindingService.TrySetBinding(element, property, binding)) + return true; + + if (nativeBindingService != null && nativeBindingService.TrySetBinding(element, localName, binding)) + return true; + + if (property != null) + exception = new XamlParseException($"{elementType.Name} is not a BindableObject or does not support native bindings", lineInfo); + + return false; + } + + static bool TrySetValue(object element, BindableProperty property, bool attached, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, out Exception exception) + { + exception = null; + + var elementType = element.GetType(); + var bindable = element as BindableObject; + var nativeBindingService = DependencyService.Get(); + + if (property == null) + return false; + + if (serviceProvider != null && serviceProvider.IProvideValueTarget != null) + ((XamlValueTargetProvider)serviceProvider.IProvideValueTarget).TargetProperty = property; + + Func minforetriever; + if (attached) + minforetriever = () => property.DeclaringType.GetRuntimeMethod("Get" + property.PropertyName, new [] { typeof(BindableObject) }); + else + { + minforetriever = () => property.DeclaringType.GetRuntimeProperties().LastOrDefault(p => p.Name == property.PropertyName); + } + //minforetriever = () => property.DeclaringType.GetRuntimeProperty(property.PropertyName); + var convertedValue = value.ConvertTo(property.ReturnType, minforetriever, serviceProvider); + + if (bindable != null) { + //SetValue doesn't throw on mismatching type, so check before to get a chance to try the property setting or the collection adding + var nullable = property.ReturnTypeInfo.IsGenericType && + property.ReturnTypeInfo.GetGenericTypeDefinition() == typeof(Nullable<>); + if ((convertedValue == null && (!property.ReturnTypeInfo.IsValueType || nullable)) || + (property.ReturnType.IsInstanceOfType(convertedValue))) { + bindable.SetValue(property, convertedValue); + return true; + } + + // This might be a collection; see if we can add to it + return TryAddValue(bindable, property, value, serviceProvider); + } + + if (nativeBindingService != null && nativeBindingService.TrySetValue(element, property, convertedValue)) + return true; + + exception = new XamlParseException($"{elementType.Name} is not a BindableObject or does not support setting native BindableProperties", lineInfo); + return false; + } + + static bool TryGetValue(object element, BindableProperty property, bool attached, out object value, IXmlLineInfo lineInfo, out Exception exception, out object targetProperty) + { + exception = null; + value = null; + targetProperty = property; + var elementType = element.GetType(); + var bindable = element as BindableObject; + + if (property == null) + return false; + + if (bindable == null) + return false; + + value = bindable.GetValue(property); + return true; + } + + static bool TrySetProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, HydrationContext context, out Exception exception) + { + exception = null; + + var elementType = element.GetType(); + var propertyInfo = elementType.GetRuntimeProperties().FirstOrDefault(p => p.Name == localName); + MethodInfo setter; + if (propertyInfo == null || !propertyInfo.CanWrite || (setter = propertyInfo.SetMethod) == null) + return false; + + if (!IsVisibleFrom(setter, context.RootElement)) + return false; + + if (serviceProvider != null && serviceProvider.IProvideValueTarget != null) + ((XamlValueTargetProvider)serviceProvider.IProvideValueTarget).TargetProperty = propertyInfo; + + object convertedValue = value.ConvertTo(propertyInfo.PropertyType, () => propertyInfo, serviceProvider); + if (convertedValue != null && !propertyInfo.PropertyType.IsInstanceOfType(convertedValue)) + return false; + + setter.Invoke(element, new object [] { convertedValue }); + return true; + } + + static bool TryGetProperty(object element, string localName, out object value, IXmlLineInfo lineInfo, HydrationContext context, out Exception exception, out object targetProperty) + { + exception = null; + value = null; + var elementType = element.GetType(); + PropertyInfo propertyInfo = null; + try { + propertyInfo = elementType.GetRuntimeProperty(localName); + } catch (AmbiguousMatchException) { + // Get most derived instance of property + foreach (var property in elementType.GetRuntimeProperties().Where(prop => prop.Name == localName)) { + if (propertyInfo == null || propertyInfo.DeclaringType.IsAssignableFrom(property.DeclaringType)) + propertyInfo = property; + } + } + MethodInfo getter; + targetProperty = propertyInfo; + if (propertyInfo == null || !propertyInfo.CanRead || (getter = propertyInfo.GetMethod) == null) + return false; + + if (!IsVisibleFrom(getter, context.RootElement)) + return false; + + value = getter.Invoke(element, new object[] { }); + return true; + } + + static bool IsVisibleFrom(MethodInfo method, object rootElement) + { + if (method.IsPublic) + return true; + if (method.IsPrivate && method.DeclaringType == rootElement.GetType()) + return true; + if ((method.IsAssembly || method.IsFamilyOrAssembly) && method.DeclaringType.AssemblyQualifiedName == rootElement.GetType().AssemblyQualifiedName) + return true; + if (method.IsFamily && method.DeclaringType.IsAssignableFrom(rootElement.GetType())) + return true; + return false; + } + + static bool TryAddToProperty(object element, XmlName propertyName, object value, string xKey, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, HydrationContext context, out Exception exception) + { + exception = null; + + object targetProperty; + var collection = GetPropertyValue(element, propertyName, context, lineInfo, out targetProperty) as IEnumerable; + + if (collection == null) + return false; + + if (exception == null && TryAddToResourceDictionary(collection as ResourceDictionary, value, xKey, lineInfo, out exception)) + return true; + + if (exception != null) + return false; + + var addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); + if (addMethod == null) + return false; + + if (serviceProvider != null && serviceProvider.IProvideValueTarget != null) + ((XamlValueTargetProvider)serviceProvider.IProvideValueTarget).TargetProperty = targetProperty; + + addMethod.Invoke(collection, new [] { value.ConvertTo(addMethod.GetParameters() [0].ParameterType, (Func)null, serviceProvider) }); + return true; + } + + static bool TryAddToResourceDictionary(ResourceDictionary resourceDictionary, object value, string xKey, IXmlLineInfo lineInfo, out Exception exception) + { + exception = null; + + if (resourceDictionary == null) + return false; + + if (xKey != null) + resourceDictionary.Add(xKey, value); + else if (value is Tizen.NUI.Binding.Style) + resourceDictionary.Add((Tizen.NUI.Binding.Style)value); + else if (value is ResourceDictionary) + resourceDictionary.Add((ResourceDictionary)value); + else if (value is StyleSheets.StyleSheet) + resourceDictionary.Add((StyleSheets.StyleSheet)value); + else { + exception = new XamlParseException("resources in ResourceDictionary require a x:Key attribute", lineInfo); + return false; + } + return true; + } + + void SetTemplate(ElementTemplate dt, INode node) + { +#pragma warning disable 0612 + ((IDataTemplate)dt).LoadTemplate = () => { +#pragma warning restore 0612 + var cnode = node.Clone(); + var context = new HydrationContext { ParentContext = Context, RootElement = Context.RootElement }; + cnode.Accept(new XamlNodeVisitor((n, parent) => n.Parent = parent), node.Parent); //set parents for {StaticResource} + cnode.Accept(new ExpandMarkupsVisitor(context), null); + cnode.Accept(new NamescopingVisitor(context), null); + cnode.Accept(new CreateValuesVisitor(context), null); + cnode.Accept(new RegisterXNamesVisitor(context), null); + cnode.Accept(new FillResourceDictionariesVisitor(context), null); + cnode.Accept(new ApplyPropertiesVisitor(context, true), null); + return context.Values [cnode]; + }; + } + + static bool TryAddValue(BindableObject bindable, BindableProperty property, object value, XamlServiceProvider serviceProvider) + { + if(property?.ReturnTypeInfo?.GenericTypeArguments == null){ + return false; + } + + if(property.ReturnType == null){ + return false; + } + + if (property.ReturnTypeInfo.GenericTypeArguments.Length != 1 || + !property.ReturnTypeInfo.GenericTypeArguments[0].IsInstanceOfType(value)) + return false; + + // This might be a collection we can add to; see if we can find an Add method + var addMethod = GetAllRuntimeMethods(property.ReturnType) + .FirstOrDefault(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); + if (addMethod == null) + return false; + + // If there's an add method, get the collection + var collection = bindable.GetValue(property); + + // And add the new value to it + addMethod.Invoke(collection, new[] { value.ConvertTo(addMethod.GetParameters()[0].ParameterType, (Func)null, serviceProvider) }); + return true; + } + + static IEnumerable GetAllRuntimeMethods(Type type) + { + return type.GetRuntimeMethods() + .Concat(type.GetTypeInfo().ImplementedInterfaces.SelectMany(t => t.GetRuntimeMethods())); + } + + bool TrySetRuntimeName(XmlName propertyName, object source, object value, ValueNode node) + { + if (propertyName != XmlName.xName) + return false; + + var runTimeName = source.GetType().GetTypeInfo().GetCustomAttribute(); + if (runTimeName == null) + return false; + + SetPropertyValue(source, new XmlName("", runTimeName.Name), value, Context.RootElement, node, Context, node); + return true; + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/CreateValuesVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/CreateValuesVisitor.cs new file mode 100755 index 0000000..581c3b1 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/CreateValuesVisitor.cs @@ -0,0 +1,429 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Xml; +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.Binding; + + +namespace Tizen.NUI.Xaml +{ + internal class CreateValuesVisitor : IXamlNodeVisitor + { + public CreateValuesVisitor(HydrationContext context) + { + Context = context; + } + + Dictionary Values + { + get { return Context.Values; } + } + + HydrationContext Context { get; } + + public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp; + public bool StopOnDataTemplate => true; + public bool StopOnResourceDictionary => false; + public bool VisitNodeOnDataTemplate => false; + public bool SkipChildren(INode node, INode parentNode) => false; + public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]); + + public void Visit(ValueNode node, INode parentNode) + { + Values[node] = node.Value; + } + + public void Visit(MarkupNode node, INode parentNode) + { + } + + public void Visit(ElementNode node, INode parentNode) + { + object value = null; + + XamlParseException xpe; + var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly, + out xpe); + if (xpe != null) + throw xpe; + + Context.Types[node] = type; + string ctorargname; + if (IsXaml2009LanguagePrimitive(node)) + value = CreateLanguagePrimitive(type, node); + else if (node.Properties.ContainsKey(XmlName.xArguments) || node.Properties.ContainsKey(XmlName.xFactoryMethod)) + value = CreateFromFactory(type, node); + else if ( + type.GetTypeInfo() + .DeclaredConstructors.Any( + ci => + ci.IsPublic && ci.GetParameters().Length != 0 && + ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof (ParameterAttribute)))) && + ValidateCtorArguments(type, node, out ctorargname)) + value = CreateFromParameterizedConstructor(type, node); + else if (!type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0) && + !ValidateCtorArguments(type, node, out ctorargname)) + { + throw new XamlParseException($"The Property {ctorargname} is required to create a {type?.FullName} object.", node); + } + else + { + //this is a trick as the DataTemplate parameterless ctor is internal, and we can't CreateInstance(..., false) on WP7 + try + { + if (type == typeof (DataTemplate)) + value = new DataTemplate(); + if (type == typeof (ControlTemplate)) + value = new ControlTemplate(); + if (value == null && node.CollectionItems.Any() && node.CollectionItems.First() is ValueNode) + { + var serviceProvider = new XamlServiceProvider(node, Context); + var converted = ((ValueNode)node.CollectionItems.First()).Value.ConvertTo(type, () => type.GetTypeInfo(), + serviceProvider); + if (converted != null && converted.GetType() == type) + value = converted; + } + if (value == null) + { + value = Activator.CreateInstance(type); + if (value is Element) + { + if (null != Application.Current) + { + Application.AddResourceChangedCallback(value, (value as Element).OnResourcesChanged); + } + + if (value is BindableObject) + { + ((BindableObject)value).IsCreateByXaml = true; + } + } + } + } + catch (TargetInvocationException e) + { + if (e.InnerException is XamlParseException || e.InnerException is XmlException) + throw e.InnerException; + throw; + } + } + + Values[node] = value; + + var markup = value as IMarkupExtension; + if (markup != null && (value is TypeExtension || value is StaticExtension || value is ArrayExtension)) + { + var serviceProvider = new XamlServiceProvider(node, Context); + + var visitor = new ApplyPropertiesVisitor(Context); + foreach (var cnode in node.Properties.Values.ToList()) + cnode.Accept(visitor, node); + foreach (var cnode in node.CollectionItems) + cnode.Accept(visitor, node); + + value = markup.ProvideValue(serviceProvider); + + INode xKey; + if (!node.Properties.TryGetValue(XmlName.xKey, out xKey)) + xKey = null; + + node.Properties.Clear(); + node.CollectionItems.Clear(); + + if (xKey != null) + node.Properties.Add(XmlName.xKey, xKey); + + Values[node] = value; + } + + if (value is BindableObject) + NameScope.SetNameScope(value as BindableObject, node.Namescope); + } + + public void Visit(RootNode node, INode parentNode) + { + var rnode = (XamlLoader.RuntimeRootNode)node; + Values[node] = rnode.Root; + Context.Types[node] = rnode.Root.GetType(); + var bindableRoot = rnode.Root as BindableObject; + if (bindableRoot != null) + NameScope.SetNameScope(bindableRoot, node.Namescope); + } + + public void Visit(ListNode node, INode parentNode) + { + //this is a gross hack to keep ListNode alive. ListNode must go in favor of Properties + XmlName name; + if (ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out name)) + node.XmlName = name; + } + + bool ValidateCtorArguments(Type nodeType, IElementNode node, out string missingArgName) + { + missingArgName = null; + var ctorInfo = + nodeType.GetTypeInfo() + .DeclaredConstructors.FirstOrDefault( + ci => + ci.GetParameters().Length != 0 && ci.IsPublic && + ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof (ParameterAttribute)))); + if (ctorInfo == null) + return true; + foreach (var parameter in ctorInfo.GetParameters()) + { + // Modify the namespace + var propname = + parameter.CustomAttributes.First(ca => ca.AttributeType.FullName == "Tizen.NUI.Binding.ParameterAttribute") + .ConstructorArguments.First() + .Value as string; + if (!node.Properties.ContainsKey(new XmlName("", propname))) + { + missingArgName = propname; + return false; + } + } + + return true; + } + + public object CreateFromParameterizedConstructor(Type nodeType, IElementNode node) + { + var ctorInfo = + nodeType.GetTypeInfo() + .DeclaredConstructors.FirstOrDefault( + ci => + ci.GetParameters().Length != 0 && ci.IsPublic && + ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof (ParameterAttribute)))); + object[] arguments = CreateArgumentsArray(node, ctorInfo); + return ctorInfo.Invoke(arguments); + } + + public object CreateFromFactory(Type nodeType, IElementNode node) + { + object[] arguments = CreateArgumentsArray(node); + + if (!node.Properties.ContainsKey(XmlName.xFactoryMethod)) + { + //non-default ctor + object ret = Activator.CreateInstance(nodeType, arguments); + if (ret is Element) + { + if (null != Application.Current) + { + Application.AddResourceChangedCallback(ret, (ret as Element).OnResourcesChanged); + } + + if (ret is BindableObject) + { + ((BindableObject)ret).IsCreateByXaml = true; + } + } + return ret; + } + + var factoryMethod = ((string)((ValueNode)node.Properties[XmlName.xFactoryMethod]).Value); + Type[] types = arguments == null ? new Type[0] : arguments.Select(a => a.GetType()).ToArray(); + Func isMatch = m => { + if (m.Name != factoryMethod) + return false; + var p = m.GetParameters(); + if (p.Length != types.Length) + return false; + if (!m.IsStatic) + return false; + for (var i = 0; i < p.Length; i++) { + if ((p [i].ParameterType.IsAssignableFrom(types [i]))) + continue; + var op_impl = p[i].ParameterType.GetImplicitConversionOperator(fromType: types[i], toType: p[i].ParameterType) + ?? types[i].GetImplicitConversionOperator(fromType: types[i], toType: p[i].ParameterType); + + if (op_impl == null) + return false; + arguments [i] = op_impl.Invoke(null, new [] { arguments [i]}); + } + return true; + }; + var mi = nodeType.GetRuntimeMethods().FirstOrDefault(isMatch); + if (mi == null) + throw new MissingMemberException($"No static method found for {nodeType.FullName}::{factoryMethod} ({string.Join(", ", types.Select(t => t.FullName))})"); + return mi.Invoke(null, arguments); + } + + public object[] CreateArgumentsArray(IElementNode enode) + { + if (!enode.Properties.ContainsKey(XmlName.xArguments)) + return null; + var node = enode.Properties[XmlName.xArguments]; + var elementNode = node as ElementNode; + if (elementNode != null) + { + var array = new object[1]; + array[0] = Values[elementNode]; + return array; + } + + var listnode = node as ListNode; + if (listnode != null) + { + var array = new object[listnode.CollectionItems.Count]; + for (var i = 0; i < listnode.CollectionItems.Count; i++) + array[i] = Values[(ElementNode)listnode.CollectionItems[i]]; + return array; + } + return null; + } + + public object[] CreateArgumentsArray(IElementNode enode, ConstructorInfo ctorInfo) + { + var n = ctorInfo.GetParameters().Length; + var array = new object[n]; + for (var i = 0; i < n; i++) + { + var parameter = ctorInfo.GetParameters()[i]; + var propname = + parameter.CustomAttributes.First(attr => attr.AttributeType == typeof (ParameterAttribute)) + .ConstructorArguments.First() + .Value as string; + var name = new XmlName("", propname); + INode node; + if (!enode.Properties.TryGetValue(name, out node)) + { + throw new XamlParseException( + String.Format("The Property {0} is required to create a {1} object.", propname, ctorInfo.DeclaringType.FullName), + enode as IXmlLineInfo); + } + if (!enode.SkipProperties.Contains(name)) + enode.SkipProperties.Add(name); + var value = Context.Values[node]; + var serviceProvider = new XamlServiceProvider(enode, Context); + var convertedValue = value.ConvertTo(parameter.ParameterType, () => parameter, serviceProvider); + array[i] = convertedValue; + } + + return array; + } + + static bool IsXaml2009LanguagePrimitive(IElementNode node) + { + return node.NamespaceURI == XamlParser.X2009Uri; + } + + static object CreateLanguagePrimitive(Type nodeType, IElementNode node) + { + object value = null; + if (nodeType == typeof(string)) + value = String.Empty; + else if (nodeType == typeof(Uri)) + value = null; + else + { + value = Activator.CreateInstance(nodeType); + if (value is Element) + { + if (null != Application.Current) + { + Application.AddResourceChangedCallback(value, (value as Element).OnResourcesChanged); + } + + if (value is BindableObject) + { + ((BindableObject)value).IsCreateByXaml = true; + } + } + } + + if (node.CollectionItems.Count == 1 && node.CollectionItems[0] is ValueNode && + ((ValueNode)node.CollectionItems[0]).Value is string) + { + var valuestring = ((ValueNode)node.CollectionItems[0]).Value as string; + + if (nodeType == typeof(SByte)) { + sbyte retval; + if (sbyte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(Int16)) { + short retval; + if (short.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(Int32)) { + int retval; + if (int.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(Int64)) { + long retval; + if (long.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(Byte)) { + byte retval; + if (byte.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(UInt16)) { + ushort retval; + if (ushort.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(UInt32)) { + uint retval; + if (uint.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(UInt64)) { + ulong retval; + if (ulong.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(Single)) { + float retval; + if (float.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof(Double)) { + double retval; + if (double.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof (Boolean)) + { + bool outbool; + if (bool.TryParse(valuestring, out outbool)) + return outbool; + } + if (nodeType == typeof(TimeSpan)) { + TimeSpan retval; + if (TimeSpan.TryParse(valuestring, CultureInfo.InvariantCulture, out retval)) + return retval; + } + if (nodeType == typeof (char)) + { + char retval; + if (char.TryParse(valuestring, out retval)) + return retval; + } + if (nodeType == typeof (string)) + return valuestring; + if (nodeType == typeof (decimal)) + { + decimal retval; + if (decimal.TryParse(valuestring, NumberStyles.Number, CultureInfo.InvariantCulture, out retval)) + return retval; + } + + else if (nodeType == typeof (Uri)) + { + Uri retval; + if (Uri.TryCreate(valuestring, UriKind.RelativeOrAbsolute, out retval)) + return retval; + } + } + return value; + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/DesignMode.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/DesignMode.cs new file mode 100755 index 0000000..b01f972 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/DesignMode.cs @@ -0,0 +1,7 @@ +namespace Tizen.NUI.Xaml +{ + internal static class DesignMode + { + public static bool IsDesignModeEnabled { get; internal set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ExpandMarkupsVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ExpandMarkupsVisitor.cs new file mode 100755 index 0000000..a3a680a --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ExpandMarkupsVisitor.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using System.Xml; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Xaml +{ + internal class ExpandMarkupsVisitor : IXamlNodeVisitor + { + public ExpandMarkupsVisitor(HydrationContext context) + { + Context = context; + } + + public static readonly IList Skips = new List + { + XmlName.xKey, + XmlName.xTypeArguments, + XmlName.xFactoryMethod, + XmlName.xName, + XmlName.xDataType + }; + + Dictionary Values + { + get { return Context.Values; } + } + + HydrationContext Context { get; } + + public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp; + public bool StopOnDataTemplate => false; + public bool StopOnResourceDictionary => false; + public bool VisitNodeOnDataTemplate => true; + public bool SkipChildren(INode node, INode parentNode) => false; + public bool IsResourceDictionary(ElementNode node) => false; + + public void Visit(ValueNode node, INode parentNode) + { + } + + public void Visit(MarkupNode markupnode, INode parentNode) + { + var parentElement = parentNode as IElementNode; + XmlName propertyName; + if (!ApplyPropertiesVisitor.TryGetPropertyName(markupnode, parentNode, out propertyName)) + return; + if (Skips.Contains(propertyName)) + return; + if (parentElement.SkipProperties.Contains(propertyName)) + return; + + var markupString = markupnode.MarkupString; + var node = + ParseExpression(ref markupString, markupnode.NamespaceResolver, markupnode, markupnode, parentNode) as IElementNode; + if (node != null) + { + ((IElementNode)parentNode).Properties[propertyName] = node; + node.Parent = parentNode; + } + } + + public void Visit(ElementNode node, INode parentNode) + { + } + + public void Visit(RootNode node, INode parentNode) + { + } + + public void Visit(ListNode node, INode parentNode) + { + } + + INode ParseExpression(ref string expression, IXmlNamespaceResolver nsResolver, IXmlLineInfo xmlLineInfo, INode node, + INode parentNode) + { + if (expression.StartsWith("{}", StringComparison.Ordinal)) + return new ValueNode(expression.Substring(2), null); + + if (expression[expression.Length - 1] != '}') + throw new Exception("Expression must end with '}'"); + + int len; + string match; + if (!MarkupExpressionParser.MatchMarkup(out match, expression, out len)) + throw new Exception(); + expression = expression.Substring(len).TrimStart(); + if (expression.Length == 0) + throw new Exception("Expression did not end in '}'"); + + var serviceProvider = new XamlServiceProvider(node, Context); + serviceProvider.Add(typeof (IXmlNamespaceResolver), nsResolver); + + return new MarkupExpansionParser().Parse(match, ref expression, serviceProvider); + } + + public class MarkupExpansionParser : MarkupExpressionParser, IExpressionParser + { + IElementNode node; + + object IExpressionParser.Parse(string match, ref string remaining, IServiceProvider serviceProvider) + { + return Parse(match, ref remaining, serviceProvider); + } + + public INode Parse(string match, ref string remaining, IServiceProvider serviceProvider) + { + var nsResolver = serviceProvider.GetService(typeof (IXmlNamespaceResolver)) as IXmlNamespaceResolver; + if (nsResolver == null) + throw new ArgumentException(); + IXmlLineInfo xmlLineInfo = null; + var xmlLineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + if (xmlLineInfoProvider != null) + xmlLineInfo = xmlLineInfoProvider.XmlLineInfo; + + var split = match.Split(':'); + if (split.Length > 2) + throw new ArgumentException(); + + string prefix; //, name; + if (split.Length == 2) + { + prefix = split[0]; + //name = split [1]; + } + else + { + prefix = ""; + //name = split [0]; + } + + Type type; + var typeResolver = serviceProvider.GetService(typeof (IXamlTypeResolver)) as IXamlTypeResolver; + if (typeResolver == null) + type = null; + // Add Binding and StaticResource support, The ordinal code can't find BindingExtension for Binding + //else if (match == "Binding") + //{ + // type = typeof(BindingExtension); + //} + //else if (match == "StaticResource") + //{ + // type = typeof(StaticResourceExtension); + //} + else + { + //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. + if (!typeResolver.TryResolve(match + "Extension", out type) && !typeResolver.TryResolve(match, out type)) + { + var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException(String.Format("MarkupExtension not found for {0}", match), lineInfo); + } + } + + var namespaceuri = nsResolver.LookupNamespace(prefix) ?? ""; + var xmltype = new XmlType(namespaceuri, type?.Name, null); + + if (type == null) + throw new NotSupportedException(); + + node = xmlLineInfo == null + ? new ElementNode(xmltype, null, nsResolver) + : new ElementNode(xmltype, null, nsResolver, xmlLineInfo.LineNumber, xmlLineInfo.LinePosition); + + if (remaining.StartsWith("}", StringComparison.Ordinal)) + { + remaining = remaining.Substring(1); + return node; + } + + char next; + string piece; + while ((piece = GetNextPiece(ref remaining, out next)) != null) + HandleProperty(piece, serviceProvider, ref remaining, next != '='); + + return node; + } + + protected override void SetPropertyValue(string prop, string strValue, object value, IServiceProvider serviceProvider) + { + var nsResolver = serviceProvider.GetService(typeof (IXmlNamespaceResolver)) as IXmlNamespaceResolver; + + var childnode = value as INode ?? new ValueNode(strValue, nsResolver); + childnode.Parent = node; + if (prop != null) + { + var name = new XmlName(node.NamespaceURI, prop); + node.Properties[name] = childnode; + } + else //ContentProperty + node.CollectionItems.Add(childnode); + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/FillResourceDictionariesVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/FillResourceDictionariesVisitor.cs new file mode 100755 index 0000000..2be8e7b --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/FillResourceDictionariesVisitor.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + internal class FillResourceDictionariesVisitor : IXamlNodeVisitor + { + public FillResourceDictionariesVisitor(HydrationContext context) + { + Context = context; + } + + HydrationContext Context { get; } + Dictionary Values => Context.Values; + + public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown; + public bool StopOnDataTemplate => true; + public bool StopOnResourceDictionary => false; + public bool VisitNodeOnDataTemplate => false; + + public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]); + + public void Visit(ValueNode node, INode parentNode) + { + if (!typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)])) + return; + + node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); + } + + public void Visit(MarkupNode node, INode parentNode) + { + } + + public void Visit(ElementNode node, INode parentNode) + { + var value = Values[node]; + XmlName propertyName; + //Set RD to VE + if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]) && ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName)) { + if ((propertyName.LocalName == "Resources" || + propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal)) && value is ResourceDictionary) { + var source = Values[parentNode]; + ApplyPropertiesVisitor.SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); + return; + } + } + + //Only proceed further if the node is a keyless RD + if ( parentNode is IElementNode + && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]) + && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey)) + node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); + else if ( parentNode is ListNode + && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode.Parent)]) + && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey)) + node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); + } + + public void Visit(RootNode node, INode parentNode) + { + } + + public void Visit(ListNode node, INode parentNode) + { + } + + public bool SkipChildren(INode node, INode parentNode) + { + var enode = node as ElementNode; + if (enode is null) + return false; + if ( parentNode is IElementNode + && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]) + && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey)) + return true; + if ( parentNode is ListNode + && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode.Parent)]) + && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey)) + return true; + return false; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/HydrationContext.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/HydrationContext.cs new file mode 100755 index 0000000..0285f07 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/HydrationContext.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace Tizen.NUI.Xaml +{ + internal class HydrationContext + { + public HydrationContext() + { + Values = new Dictionary(); + Types = new Dictionary(); + } + + public Dictionary Values { get; } + public Dictionary Types { get; } + public HydrationContext ParentContext { get; set; } + public Action ExceptionHandler { get; set; } + public object RootElement { get; set; } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IConverterOptions.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IConverterOptions.cs new file mode 100755 index 0000000..722707a --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IConverterOptions.cs @@ -0,0 +1,7 @@ +namespace Tizen.NUI.Xaml +{ + internal interface IConverterOptions + { + bool IgnoreCase { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IDictionaryExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IDictionaryExtensions.cs new file mode 100755 index 0000000..eb8a897 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IDictionaryExtensions.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Tizen.NUI.Xaml +{ + internal static class IDictionaryExtensions + { + public static void AddRange(this IDictionary dictionary, + IEnumerable> collection) + { + foreach (var kvp in collection) + dictionary.Add(kvp); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IExpressionParser.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IExpressionParser.cs new file mode 100755 index 0000000..7d52405 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IExpressionParser.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + internal interface IExpressionParser + { + object Parse(string match, ref string expression, IServiceProvider serviceProvider); + } + + internal interface IExpressionParser : IExpressionParser + where T : class + { + new T Parse(string match, ref string expression, IServiceProvider serviceProvider); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IMarkupExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IMarkupExtension.cs new file mode 100755 index 0000000..a6f26a5 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IMarkupExtension.cs @@ -0,0 +1,19 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + internal interface IMarkupExtension : IMarkupExtension + { + new T ProvideValue(IServiceProvider serviceProvider); + } + + internal interface IMarkupExtension + { + object ProvideValue(IServiceProvider serviceProvider); + } + + [AttributeUsage(AttributeTargets.Class, Inherited = false)] + internal sealed class AcceptEmptyServiceProviderAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/INativeValueConverterService.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/INativeValueConverterService.cs new file mode 100755 index 0000000..a5a60f2 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/INativeValueConverterService.cs @@ -0,0 +1,9 @@ +using System; + +namespace Tizen.NUI.Xaml.Internals +{ + internal interface INativeValueConverterService + { + bool ConvertTo(object value, Type toType, out object nativeValue); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideParentValues.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideParentValues.cs new file mode 100755 index 0000000..d7de36a --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideParentValues.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Tizen.NUI.Xaml +{ + internal interface IProvideParentValues : IProvideValueTarget + { + IEnumerable ParentObjects { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideValueTarget.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideValueTarget.cs new file mode 100755 index 0000000..cdf7b79 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IProvideValueTarget.cs @@ -0,0 +1,8 @@ +namespace Tizen.NUI.Xaml +{ + internal interface IProvideValueTarget + { + object TargetObject { get; } + object TargetProperty { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IReferenceProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IReferenceProvider.cs new file mode 100755 index 0000000..249932e --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IReferenceProvider.cs @@ -0,0 +1,7 @@ +namespace Tizen.NUI.Xaml +{ + internal interface IReferenceProvider + { + object FindByName(string name); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IResourcesLoader.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IResourcesLoader.cs new file mode 100755 index 0000000..820289d --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IResourcesLoader.cs @@ -0,0 +1,13 @@ +using System; +using System.Reflection; +using System.Xml; +using System.IO; + +namespace Tizen.NUI +{ + internal interface IResourcesLoader + { + T CreateFromResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) where T : new(); + string GetResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IRootObjectProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IRootObjectProvider.cs new file mode 100755 index 0000000..057ae54 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IRootObjectProvider.cs @@ -0,0 +1,7 @@ +namespace Tizen.NUI.Xaml +{ + internal interface IRootObjectProvider + { + object RootObject { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueConverterProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueConverterProvider.cs new file mode 100755 index 0000000..72942e8 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueConverterProvider.cs @@ -0,0 +1,10 @@ +using System; +using System.Reflection; + +namespace Tizen.NUI.Xaml +{ + internal interface IValueConverterProvider + { + object Convert(object value, Type toType, Func minfoRetriever, IServiceProvider serviceProvider); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueProvider.cs new file mode 100755 index 0000000..a93a3e5 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IValueProvider.cs @@ -0,0 +1,9 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + internal interface IValueProvider + { + object ProvideValue(IServiceProvider serviceProvider); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXamlTypeResolver.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXamlTypeResolver.cs new file mode 100755 index 0000000..fbf2d37 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXamlTypeResolver.cs @@ -0,0 +1,10 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + internal interface IXamlTypeResolver + { + Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider = null); + bool TryResolve(string qualifiedTypeName, out Type type); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXmlLineInfoProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXmlLineInfoProvider.cs new file mode 100755 index 0000000..da9ac5a --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/IXmlLineInfoProvider.cs @@ -0,0 +1,9 @@ +using System.Xml; + +namespace Tizen.NUI.Xaml +{ + internal interface IXmlLineInfoProvider + { + IXmlLineInfo XmlLineInfo { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExpressionParser.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExpressionParser.cs new file mode 100755 index 0000000..6dbc21a --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExpressionParser.cs @@ -0,0 +1,229 @@ +// +// MarkupExpressionParser.cs +// +// This code is partly salvaged from moonlight. Following licence apply. +// +// +// Author(s): +// Moonlight List (moonlight-list@lists.ximian.com) +// Stephane Delcroix (stephane@mi8.be) +// +// Copyright 2009 Novell, Inc. +// Copyright 2013 Xamarin, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +namespace Tizen.NUI.Xaml +{ + internal abstract class MarkupExpressionParser + { + public object ParseExpression(ref string expression, IServiceProvider serviceProvider) + { + if (serviceProvider == null) + throw new ArgumentNullException(nameof(serviceProvider)); + if (expression.StartsWith("{}", StringComparison.Ordinal)) + return expression.Substring(2); + + if (expression[expression.Length - 1] != '}') + throw new Exception("Expression must end with '}'"); + + int len; + string match; + if (!MatchMarkup(out match, expression, out len)) + return false; + expression = expression.Substring(len).TrimStart(); + if (expression.Length == 0) + throw new Exception("Expression did not end in '}'"); + + var parser = Activator.CreateInstance(GetType()) as IExpressionParser; + return parser.Parse(match, ref expression, serviceProvider); + } + + internal static bool MatchMarkup(out string match, string expression, out int end) + { + if (expression.Length < 2) + { + end = 1; + match = null; + return false; + } + + if (expression[0] != '{') + { + end = 2; + match = null; + return false; + } + + int i; + bool found = false; + for (i = 1; i < expression.Length; i++) + { + if (expression[i] == ' ') + continue; + found = true; + break; + } + + if (!found) + { + end = 3; + match = null; + return false; + } + + int c; + for (c = 0; c + i < expression.Length; c++) + { + if (expression[i + c] == ' ' || expression[i + c] == '}') + break; + } + + if (i + c == expression.Length) + { + end = 6; + match = null; + return false; + } + + end = i + c; + match = expression.Substring(i, c); + return true; + } + + protected void HandleProperty(string prop, IServiceProvider serviceProvider, ref string remaining, bool isImplicit) + { + char next; + object value = null; + string str_value; + + if (isImplicit) + { + SetPropertyValue(null, prop, null, serviceProvider); + return; + } + remaining = remaining.TrimStart(); + if (remaining.StartsWith("{", StringComparison.Ordinal)) + { + value = ParseExpression(ref remaining, serviceProvider); + remaining = remaining.TrimStart(); + + if (remaining.Length > 0 && remaining[0] == ',') + remaining = remaining.Substring(1); + else if (remaining.Length > 0 && remaining[0] == '}') + remaining = remaining.Substring(1); + + str_value = value as string; + } + else + str_value = GetNextPiece(ref remaining, out next); + + SetPropertyValue(prop, str_value, value, serviceProvider); + } + + protected abstract void SetPropertyValue(string prop, string strValue, object value, IServiceProvider serviceProvider); + + protected string GetNextPiece(ref string remaining, out char next) + { + bool inString = false; + int end = 0; + char stringTerminator = '\0'; + remaining = remaining.TrimStart(); + if (remaining.Length == 0) + { + next = Char.MaxValue; + return null; + } + + var piece = new StringBuilder(); + // If we're inside a quoted string we append all chars to our piece until we hit the ending quote. + while (end < remaining.Length && + (inString || (remaining[end] != '}' && remaining[end] != ',' && remaining[end] != '='))) + { + if (inString) + { + if (remaining[end] == stringTerminator) + { + inString = false; + end ++; + break; + } + } + else + { + if (remaining[end] == '\'' || remaining[end] == '"') + { + inString = true; + stringTerminator = remaining[end]; + end ++; + continue; + } + } + + // If this is an escape char, consume it and append the next char to our piece. + if (remaining[end] == '\\') + { + end ++; + if (end == remaining.Length) + break; + } + piece.Append(remaining[end]); + end++; + } + + if (inString && end == remaining.Length) + throw new Exception("Unterminated quoted string"); + + if (end == remaining.Length && !remaining.EndsWith("}", StringComparison.Ordinal)) + throw new Exception("Expression did not end with '}'"); + + if (end == 0) + { + next = Char.MaxValue; + return null; + } + + next = remaining[end]; + remaining = remaining.Substring(end + 1); + + // Whitespace is trimmed from the end of the piece before stripping + // quote chars from the start/end of the string. + while (piece.Length > 0 && char.IsWhiteSpace(piece[piece.Length - 1])) + piece.Length --; + + if (piece.Length >= 2) + { + char first = piece[0]; + char last = piece[piece.Length - 1]; + if ((first == '\'' && last == '\'') || (first == '"' && last == '"')) + { + piece.Remove(piece.Length - 1, 1); + piece.Remove(0, 1); + } + } + + return piece.ToString(); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensionParser.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensionParser.cs new file mode 100755 index 0000000..ec76d26 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensionParser.cs @@ -0,0 +1,81 @@ +using System; +using System.Reflection; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + internal sealed class MarkupExtensionParser : MarkupExpressionParser, IExpressionParser + { + IMarkupExtension markupExtension; + + public object Parse(string match, ref string remaining, IServiceProvider serviceProvider) + { + var typeResolver = serviceProvider.GetService(typeof (IXamlTypeResolver)) as IXamlTypeResolver; + + //shortcut for Binding and StaticResource, to avoid too many reflection calls. + if (match == "Binding") + markupExtension = new BindingExtension(); + else if (match == "TemplateBinding") + markupExtension = new TemplateBindingExtension(); + else if (match == "StaticResource") + markupExtension = new StaticResourceExtension(); + else + { + if (typeResolver == null) + return null; + Type type; + + //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. + if (!typeResolver.TryResolve(match + "Extension", out type) && !typeResolver.TryResolve(match, out type)) + { + var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException(String.Format("MarkupExtension not found for {0}", match), lineInfo); + } + markupExtension = Activator.CreateInstance(type) as IMarkupExtension; + } + + if (markupExtension == null) + { + var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException(String.Format("Missing public default constructor for MarkupExtension {0}", match), + lineInfo); + } + + char next; + if (remaining == "}") + return markupExtension.ProvideValue(serviceProvider); + + string piece; + while ((piece = GetNextPiece(ref remaining, out next)) != null) + HandleProperty(piece, serviceProvider, ref remaining, next != '='); + + return markupExtension.ProvideValue(serviceProvider); + } + + protected override void SetPropertyValue(string prop, string strValue, object value, IServiceProvider serviceProvider) + { + MethodInfo setter; + if (prop == null) + { + //implicit property + var t = markupExtension.GetType(); + prop = ApplyPropertiesVisitor.GetContentPropertyName(t.GetTypeInfo()); + if (prop == null) + return; + setter = t.GetRuntimeProperty(prop).SetMethod; + } + else + setter = markupExtension.GetType().GetRuntimeProperty(prop).SetMethod; + + if (value == null && strValue != null) + { + value = strValue.ConvertTo(markupExtension.GetType().GetRuntimeProperty(prop).PropertyType, + (Func)null, serviceProvider); + } + + setter?.Invoke(markupExtension, new[] { value }); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ArrayExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ArrayExtension.cs new file mode 100755 index 0000000..ce20e18 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ArrayExtension.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty("Items")] + [AcceptEmptyServiceProvider] + internal class ArrayExtension : IMarkupExtension + { + public ArrayExtension() + { + Items = new List(); + } + + public IList Items { get; } + + public Type Type { get; set; } + + public Array ProvideValue(IServiceProvider serviceProvider) + { + if (Type == null) + throw new InvalidOperationException("Type argument mandatory for x:Array extension"); + + if (Items == null) + return null; + + var array = Array.CreateInstance(Type, Items.Count); + for (var i = 0; i < Items.Count; i++) + ((IList)array)[i] = Items[i]; + + return array; + } + + object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) + { + return (this as IMarkupExtension).ProvideValue(serviceProvider); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/BindingExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/BindingExtension.cs new file mode 100755 index 0000000..50fd16c --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/BindingExtension.cs @@ -0,0 +1,83 @@ +using System; +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.Binding; +using Tizen.NUI.EXaml; +using Mono.Cecil; +using Tizen.NUI.EXaml.Build.Tasks; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty("Path")] + [AcceptEmptyServiceProvider] + internal sealed class BindingExtension : IMarkupExtension + { + public string Path { get; set; } = Tizen.NUI.Binding.Binding.SelfPath; + public BindingMode Mode { get; set; } = BindingMode.Default; + + public EXamlCreateObject ModeInEXaml { get; set; } = null; + + public object Converter { get; set; } + + public object ConverterParameter { get; set; } + + public string StringFormat { get; set; } + + public object Source { get; set; } + + public string UpdateSourceEventName { get; set; } + + public object TargetNullValue { get; set; } + + public object FallbackValue { get; set; } + + public TypedBindingBase TypedBinding { get; set; } + + public EXamlCreateObject ProvideValue(EXamlContext context, ModuleDefinition module) + { + if (TypedBinding == null) + { + var newTypeRef = module.ImportReference(typeof(Tizen.NUI.Binding.Binding)); + return new EXamlCreateObject(context, null, newTypeRef, new object[] { Path, ModeInEXaml, Converter, ConverterParameter, StringFormat, Source }); + } + else + { + throw new Exception("TypedBinding should not be not null"); + //TypedBinding.Mode = Mode; + //TypedBinding.Converter = Converter; + //TypedBinding.ConverterParameter = ConverterParameter; + //TypedBinding.StringFormat = StringFormat; + //TypedBinding.Source = Source; + //TypedBinding.UpdateSourceEventName = UpdateSourceEventName; + //TypedBinding.FallbackValue = FallbackValue; + //TypedBinding.TargetNullValue = TargetNullValue; + //return TypedBinding; + } + } + + BindingBase IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) + { + if (TypedBinding == null) + return new Tizen.NUI.Binding.Binding(Path, Mode, Converter as IValueConverter, ConverterParameter, StringFormat, Source) + { + UpdateSourceEventName = UpdateSourceEventName, + FallbackValue = FallbackValue, + TargetNullValue = TargetNullValue, + }; + + TypedBinding.Mode = Mode; + TypedBinding.Converter = Converter as IValueConverter; + TypedBinding.ConverterParameter = ConverterParameter; + TypedBinding.StringFormat = StringFormat; + TypedBinding.Source = Source; + TypedBinding.UpdateSourceEventName = UpdateSourceEventName; + TypedBinding.FallbackValue = FallbackValue; + TypedBinding.TargetNullValue = TargetNullValue; + return TypedBinding; + } + + object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) + { + return (this as IMarkupExtension).ProvideValue(serviceProvider); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/DynamicResourceExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/DynamicResourceExtension.cs new file mode 100755 index 0000000..a883738 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/DynamicResourceExtension.cs @@ -0,0 +1,41 @@ +using System; +using Tizen.NUI.Binding; +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.EXaml; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty("Key")] + internal sealed class DynamicResourceExtension : IMarkupExtension + { + public string Key { get; set; } + + public object ProvideValue() + { + if (null == Key) + { + return null; + } + else + { + return new DynamicResource(Key); + } + } + + public object ProvideValue(IServiceProvider serviceProvider) + { + return ((IMarkupExtension)this).ProvideValue(serviceProvider); + } + + DynamicResource IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) + { + if (Key == null) + { + var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException("DynamicResource markup require a Key", lineInfo); + } + return new DynamicResource(Key); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/NullExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/NullExtension.cs new file mode 100755 index 0000000..b5a310c --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/NullExtension.cs @@ -0,0 +1,14 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + [ProvideCompiled("Tizen.NUI.Xaml.Build.Tasks.NullExtension")] + [AcceptEmptyServiceProvider] + internal class NullExtension : IMarkupExtension + { + public object ProvideValue(IServiceProvider serviceProvider) + { + return null; + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ReferenceExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ReferenceExtension.cs new file mode 100755 index 0000000..4972d84 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/ReferenceExtension.cs @@ -0,0 +1,48 @@ +using System; +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.Binding; +using Tizen.NUI.EXaml; +using Tizen.NUI.EXaml.Build.Tasks; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty("Name")] + internal class ReferenceExtension : IMarkupExtension + { + public string Name { get; set; } + + public object ProvideValue(EXamlContext context) + { + return context.GetObjectByXName(Name); + } + + public object ProvideValue(IServiceProvider serviceProvider) + { + if (serviceProvider == null) + throw new ArgumentNullException(nameof(serviceProvider)); + var valueProvider = serviceProvider.GetService(typeof (IProvideValueTarget)) as IProvideParentValues; + if (valueProvider == null) + throw new ArgumentException("serviceProvider does not provide an IProvideValueTarget"); + var namescopeprovider = serviceProvider.GetService(typeof (INameScopeProvider)) as INameScopeProvider; + if (namescopeprovider != null && namescopeprovider.NameScope != null) + { + var value = namescopeprovider.NameScope.FindByName(Name); + if (value != null) + return value; + } + + foreach (var target in valueProvider.ParentObjects) + { + var ns = target as INameScope; + if (ns == null) + continue; + var value = ns.FindByName(Name); + if (value != null) + return value; + } + + var lineInfo = (serviceProvider?.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider)?.XmlLineInfo ?? new XmlLineInfo(); + throw new XamlParseException($"Can not find the object referenced by `{Name}`", lineInfo); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticExtension.cs new file mode 100755 index 0000000..2423ed0 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticExtension.cs @@ -0,0 +1,52 @@ +using System; +using System.Linq; +using System.Reflection; +using System.Xml; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty(nameof(Member))] + [ProvideCompiled("Tizen.NUI.Xaml.Build.Tasks.StaticExtension")] + internal class StaticExtension : IMarkupExtension + { + public string Member { get; set; } + + public object ProvideValue(IServiceProvider serviceProvider) + { + IXmlLineInfoProvider lineInfoProvider; + IXmlLineInfo lineInfo; + + if (serviceProvider == null) + throw new ArgumentNullException(nameof(serviceProvider)); + var typeResolver = serviceProvider.GetService(typeof (IXamlTypeResolver)) as IXamlTypeResolver; + if (typeResolver == null) + throw new ArgumentException("No IXamlTypeResolver in IServiceProvider"); + + if (string.IsNullOrEmpty(Member) || !Member.Contains(".")) + { + lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException("Syntax for x:Static is [Member=][prefix:]typeName.staticMemberName", lineInfo); + } + + var dotIdx = Member.LastIndexOf('.'); + var typename = Member.Substring(0, dotIdx); + var membername = Member.Substring(dotIdx + 1); + + var type = typeResolver.Resolve(typename, serviceProvider); + + var pinfo = type.GetRuntimeProperties().FirstOrDefault(pi => pi.Name == membername && pi.GetMethod.IsStatic); + if (pinfo != null) + return pinfo.GetMethod.Invoke(null, new object[] { }); + + var finfo = type.GetRuntimeFields().FirstOrDefault(fi => fi.Name == membername && fi.IsStatic); + if (finfo != null) + return finfo.GetValue(null); + + lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException($"No static member found for {Member}", lineInfo); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticResourceExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticResourceExtension.cs new file mode 100755 index 0000000..0ad0840 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/StaticResourceExtension.cs @@ -0,0 +1,111 @@ +using System; +using System.Xml; +using System.Reflection; +using System.Linq; +using Tizen.NUI.Binding; +using Tizen.NUI.Binding; +using Tizen.NUI.EXaml; +using Tizen.NUI.EXaml.Build.Tasks; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty("Key")] + internal sealed class StaticResourceExtension : IMarkupExtension + { + public string Key { get; set; } + + public object ProvideValue(EXamlContext context) + { + object ret = null; + context.resourceDictionary.TryGetValue(Key, out ret); + + if (null == ret) + { + throw new Exception(String.Format("Key {0} can't be found in Resource", Key)); + } + + return ret; + } + + public object ProvideValue(IServiceProvider serviceProvider) + { + if (serviceProvider == null) + throw new ArgumentNullException(nameof(serviceProvider)); + if (Key == null) { + var lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException("you must specify a key in {StaticResource}", lineInfo); + } + var valueProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideParentValues; + if (valueProvider == null) + throw new ArgumentException(); + var xmlLineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var xmlLineInfo = xmlLineInfoProvider != null ? xmlLineInfoProvider.XmlLineInfo : null; + object resource = null; + + foreach (var p in valueProvider.ParentObjects) { + var irp = p as IResourcesProvider; + var resDict = irp != null && irp.IsResourcesCreated ? irp.Resources : p as ResourceDictionary; + if (resDict == null) + continue; + if (resDict.TryGetValue(Key, out resource)) + break; + } + resource = resource ?? GetApplicationLevelResource(Key, xmlLineInfo); + + var bp = valueProvider.TargetProperty as BindableProperty; + var pi = valueProvider.TargetProperty as PropertyInfo; + var propertyType = bp?.ReturnType ?? pi?.PropertyType; + if (propertyType == null) { + if (resource != null) { + if (resource.GetType().GetTypeInfo().IsGenericType && (resource.GetType().GetGenericTypeDefinition() == typeof(OnPlatform<>) || resource.GetType().GetGenericTypeDefinition() == typeof(OnIdiom<>))) { + // This is only there to support our backward compat story with pre 2.3.3 compiled Xaml project who was not providing TargetProperty + var method = resource.GetType().GetRuntimeMethod("op_Implicit", new[] { resource.GetType() }); + if (method != null) { + resource = method.Invoke(null, new[] { resource }); + } + } + } + return resource; + } + if (propertyType.IsAssignableFrom(resource?.GetType())) + return resource; + var implicit_op = resource?.GetType().GetImplicitConversionOperator(fromType: resource?.GetType(), toType: propertyType) + ?? propertyType.GetImplicitConversionOperator(fromType: resource?.GetType(), toType: propertyType); + if (implicit_op != null) + return implicit_op.Invoke(resource, new [] { resource }); + + if (resource != null) { + //Special case for https://bugzilla.xamarin.com/show_bug.cgi?id=59818 + //On OnPlatform, check for an opImplicit from the targetType + if ( Device.Flags != null + && Device.Flags.Contains("xamlDoubleImplicitOpHack") + && resource.GetType().GetTypeInfo().IsGenericType + && (resource.GetType().GetGenericTypeDefinition() == typeof(OnPlatform<>))) { + var tType = resource.GetType().GenericTypeArguments[0]; + var opImplicit = tType.GetImplicitConversionOperator(fromType: tType, toType: propertyType) + ?? propertyType.GetImplicitConversionOperator(fromType: tType, toType: propertyType); + + if (opImplicit != null) { + //convert the OnPlatform to T + var opPlatformImplicitConversionOperator = resource?.GetType().GetImplicitConversionOperator(fromType: resource?.GetType(), toType: tType); + resource = opPlatformImplicitConversionOperator?.Invoke(null, new[] { resource }); + + //and convert to toType + resource = opImplicit.Invoke(null, new[] { resource }); + return resource; + } + } + } + return resource; + } + + internal object GetApplicationLevelResource(string key, IXmlLineInfo xmlLineInfo) + { + object resource = null; + if (Application.Current == null || !((IResourcesProvider)Application.Current).IsResourcesCreated || !Application.Current.Resources.TryGetValue(Key, out resource)) + throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo); + return resource; + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TemplateBindingExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TemplateBindingExtension.cs new file mode 100755 index 0000000..d06f242 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TemplateBindingExtension.cs @@ -0,0 +1,36 @@ +using System; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty("Path")] + [AcceptEmptyServiceProvider] + internal sealed class TemplateBindingExtension : IMarkupExtension + { + internal TemplateBindingExtension() + { + Mode = BindingMode.Default; + Path = Tizen.NUI.Binding.Binding.SelfPath; + } + + public string Path { get; set; } + + public BindingMode Mode { get; set; } + + public IValueConverter Converter { get; set; } + + public object ConverterParameter { get; set; } + + public string StringFormat { get; set; } + + BindingBase IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) + { + return new TemplateBinding(Path, Mode, Converter, ConverterParameter, StringFormat); + } + + object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) + { + return (this as IMarkupExtension).ProvideValue(serviceProvider); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TypeExtension.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TypeExtension.cs new file mode 100755 index 0000000..9bcd36b --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/MarkupExtensions/TypeExtension.cs @@ -0,0 +1,30 @@ +using System; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + [ContentProperty(nameof(TypeName))] + [ProvideCompiled("Tizen.NUI.Xaml.Build.Tasks.TypeExtension")] + internal class TypeExtension : IMarkupExtension + { + public string TypeName { get; set; } + + public Type ProvideValue(IServiceProvider serviceProvider) + { + if (string.IsNullOrEmpty(TypeName)) + throw new InvalidOperationException("TypeName isn't set."); + if (serviceProvider == null) + throw new ArgumentNullException(nameof(serviceProvider)); + var typeResolver = serviceProvider.GetService(typeof (IXamlTypeResolver)) as IXamlTypeResolver; + if (typeResolver == null) + throw new ArgumentException("No IXamlTypeResolver in IServiceProvider"); + + return typeResolver.Resolve(TypeName, serviceProvider); + } + + object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) + { + return (this as IMarkupExtension).ProvideValue(serviceProvider); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/NamescopingVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/NamescopingVisitor.cs new file mode 100755 index 0000000..99e0f89 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/NamescopingVisitor.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Xaml +{ + internal class NamescopingVisitor : IXamlNodeVisitor + { + readonly Dictionary scopes = new Dictionary(); + + public NamescopingVisitor(HydrationContext context) + { + Values = context.Values; + } + + Dictionary Values { get; set; } + + public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown; + public bool StopOnDataTemplate => false; + public bool StopOnResourceDictionary => false; + public bool VisitNodeOnDataTemplate => true; + public bool SkipChildren(INode node, INode parentNode) => false; + public bool IsResourceDictionary(ElementNode node) => false; + + public void Visit(ValueNode node, INode parentNode) + { + scopes[node] = scopes[parentNode]; + } + + public void Visit(MarkupNode node, INode parentNode) + { + scopes[node] = scopes[parentNode]; + } + + public void Visit(ElementNode node, INode parentNode) + { + var ns = parentNode == null || IsDataTemplate(node, parentNode) || IsStyle(node, parentNode) || IsVisualStateGroupList(node) + ? new NameScope() + : scopes[parentNode]; + node.Namescope = ns; + scopes[node] = ns; + } + + public void Visit(RootNode node, INode parentNode) + { + var ns = new NameScope(); + node.Namescope = ns; + scopes[node] = ns; + } + + public void Visit(ListNode node, INode parentNode) + { + scopes[node] = scopes[parentNode]; + } + + 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 == node) + return true; + return false; + } + + static bool IsStyle(INode node, INode parentNode) + { + var pnode = parentNode as ElementNode; + return pnode != null && pnode.XmlType.Name == "Style"; + } + + static bool IsVisualStateGroupList(ElementNode node) + { + return node != null && node.XmlType.Name == "VisualStateGroup" && node.Parent is IListNode; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ProvideCompiledAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ProvideCompiledAttribute.cs new file mode 100755 index 0000000..33cb1cb --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ProvideCompiledAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] + internal sealed class ProvideCompiledAttribute : Attribute + { + public string CompiledVersion { get; } + + public ProvideCompiledAttribute (string compiledVersion) + { + CompiledVersion = compiledVersion; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/PruneIgnoredNodesVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/PruneIgnoredNodesVisitor.cs new file mode 100755 index 0000000..8c025e5 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/PruneIgnoredNodesVisitor.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Tizen.NUI.Xaml +{ + internal class PruneIgnoredNodesVisitor : IXamlNodeVisitor + { + public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown; + public bool StopOnDataTemplate => false; + public bool StopOnResourceDictionary => false; + public bool VisitNodeOnDataTemplate => true; + public bool SkipChildren(INode node, INode parentNode) => false; + public bool IsResourceDictionary(ElementNode node) => false; + + public void Visit(ElementNode node, INode parentNode) + { + foreach (var propertyKvp in node.Properties) + { + var propertyName = propertyKvp.Key; + var propertyValue = (propertyKvp.Value as ValueNode)?.Value as string; + if (propertyValue == null) + continue; + if (!propertyName.Equals(XamlParser.McUri, "Ignorable")) + continue; + (parentNode.IgnorablePrefixes ?? (parentNode.IgnorablePrefixes = new List())).AddRange(propertyValue.Split(',')); + } + + foreach (var propertyKvp in node.Properties.ToList()) + { + // skip d:foo="bar" + var prefix = node.NamespaceResolver.LookupPrefix(propertyKvp.Key.NamespaceURI); + if (node.SkipPrefix(prefix)) + node.Properties.Remove(propertyKvp.Key); + var propNs = (propertyKvp.Value as IElementNode)?.NamespaceURI ?? ""; + var propPrefix = node.NamespaceResolver.LookupPrefix(propNs); + if (node.SkipPrefix(propPrefix)) + node.Properties.Remove(propertyKvp.Key); + } + + foreach (var prop in node.CollectionItems.ToList()) + { + var propNs = (prop as IElementNode)?.NamespaceURI ?? ""; + var propPrefix = node.NamespaceResolver.LookupPrefix(propNs); + if (node.SkipPrefix(propPrefix)) + node.CollectionItems.Remove(prop); + } + + if (node.SkipPrefix(node.NamespaceResolver.LookupPrefix(node.NamespaceURI))) + { + node.Properties.Clear(); + node.CollectionItems.Clear(); + } + } + + public void Visit(RootNode node, INode parentNode) + { + Visit((ElementNode)node, node); + } + + public void Visit(MarkupNode node, INode parentNode) + { + } + + public void Visit(ListNode node, INode parentNode) + { + foreach (var prop in node.CollectionItems.ToList()) + { + var propNs = (prop as IElementNode)?.NamespaceURI ?? ""; + var propPrefix = node.NamespaceResolver.LookupPrefix(propNs); + if (node.SkipPrefix(propPrefix)) + node.CollectionItems.Remove(prop); + } + } + + public void Visit(ValueNode node, INode parentNode) + { + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ReflectionExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ReflectionExtensions.cs new file mode 100755 index 0000000..c356b05 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ReflectionExtensions.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; + +namespace Tizen.NUI.Binding.Internals +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class ReflectionExtensions + { + public static FieldInfo GetField(this Type type, Func predicate) + { + return GetFields(type).FirstOrDefault(predicate); + } + + public static FieldInfo GetField(this Type type, string name) + { + return type.GetField(fi => fi.Name == name); + } + + public static IEnumerable GetFields(this Type type) + { + return GetParts(type, i => i.DeclaredFields); + } + + public static IEnumerable GetProperties(this Type type) + { + return GetParts(type, ti => ti.DeclaredProperties); + } + + public static PropertyInfo GetProperty(this Type type, string name) + { + Type t = type; + while (t != null) + { + System.Reflection.TypeInfo ti = t.GetTypeInfo(); + PropertyInfo property = ti.GetDeclaredProperty(name); + if (property != null) + return property; + + t = ti.BaseType; + } + + return null; + } + + public static bool IsAssignableFrom(this Type self, Type c) + { + return self.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo()); + } + + public static bool IsInstanceOfType(this Type self, object o) + { + return self.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()); + } + + static IEnumerable GetParts(Type type, Func> selector) + { + Type t = type; + while (t != null) + { + System.Reflection.TypeInfo ti = t.GetTypeInfo(); + foreach (T f in selector(ti)) + yield return f; + t = ti.BaseType; + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/RegisterXNamesVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/RegisterXNamesVisitor.cs new file mode 100755 index 0000000..8ca6dde --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/RegisterXNamesVisitor.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + internal class RegisterXNamesVisitor : IXamlNodeVisitor + { + public RegisterXNamesVisitor(HydrationContext context) + { + Context = context; + Values = context.Values; + } + + Dictionary Values { get; } + HydrationContext Context { get; } + public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown; + public bool StopOnDataTemplate => true; + public bool StopOnResourceDictionary => false; + public bool VisitNodeOnDataTemplate => false; + public bool SkipChildren(INode node, INode parentNode) => false; + public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]); + + public void Visit(ValueNode node, INode parentNode) + { + if (!IsXNameProperty(node, parentNode)) + return; + try + { + ((IElementNode)parentNode).Namescope.RegisterName((string)node.Value, Values[parentNode]); + } + catch (ArgumentException ae) + { + if (ae.ParamName != "name") + throw ae; + throw new XamlParseException($"An element with the name \"{(string)node.Value}\" already exists in this NameScope", node); + } + var element = Values[parentNode] as Element; + if (element != null) + element.StyleId = element.StyleId ?? (string)node.Value; + } + + public void Visit(MarkupNode node, INode parentNode) + { + } + + public void Visit(ElementNode node, INode parentNode) + { + } + + public void Visit(RootNode node, INode parentNode) + { + } + + public void Visit(ListNode node, INode parentNode) + { + } + + static bool IsXNameProperty(ValueNode node, INode parentNode) + { + var parentElement = parentNode as IElementNode; + INode xNameNode; + if (parentElement != null && parentElement.Properties.TryGetValue(XmlName.xName, out xNameNode) && xNameNode == node) + return true; + return false; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ResourcesLoader.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ResourcesLoader.cs new file mode 100755 index 0000000..6b25652 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ResourcesLoader.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; +using System.Reflection; +using Tizen.NUI; +using System.Xml; +using Tizen.NUI.Binding.Internals; + +// [assembly:Dependency(typeof(Tizen.NUI.Xaml.ResourcesLoader))] +namespace Tizen.NUI.Xaml +{ + internal class ResourcesLoader : IResourcesLoader + { + public T CreateFromResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) where T: new() + { + var alternateResource = ResourceLoader.ResourceProvider?.Invoke(assembly.GetName(), resourcePath); + if (alternateResource != null) { + var rd = new T(); + rd.LoadFromXaml(alternateResource); + return rd; + } + + var resourceId = XamlResourceIdAttribute.GetResourceIdForPath(assembly, resourcePath); + if (resourceId == null) + throw new XamlParseException($"Resource '{resourcePath}' not found.", lineInfo); + + using (var stream = assembly.GetManifestResourceStream(resourceId)) { + if (stream == null) + throw new XamlParseException($"No resource found for '{resourceId}'.", lineInfo); + using (var reader = new StreamReader(stream)) { + var rd = new T(); + rd.LoadFromXaml(reader.ReadToEnd()); + return rd; + } + } + } + + public string GetResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) + { + var alternateResource = ResourceLoader.ResourceProvider?.Invoke(assembly.GetName(), resourcePath); + if (alternateResource != null) + return alternateResource; + + var resourceId = XamlResourceIdAttribute.GetResourceIdForPath(assembly, resourcePath); + if (resourceId == null) + throw new XamlParseException($"Resource '{resourcePath}' not found.", lineInfo); + + using (var stream = assembly.GetManifestResourceStream(resourceId)) { + if (stream == null) + throw new XamlParseException($"No resource found for '{resourceId}'.", lineInfo); + using (var reader = new StreamReader(stream)) + return reader.ReadToEnd(); + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/RuntimeNamePropertyAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/RuntimeNamePropertyAttribute.cs new file mode 100755 index 0000000..80b8fe5 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/RuntimeNamePropertyAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + [AttributeUsage(AttributeTargets.Class)] + internal sealed class RuntimeNamePropertyAttribute : Attribute + { + public RuntimeNamePropertyAttribute(string name) + { + Name = name; + } + + public string Name { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeArgumentsParser.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeArgumentsParser.cs new file mode 100755 index 0000000..42e80ac --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeArgumentsParser.cs @@ -0,0 +1,71 @@ + +using System.Collections.Generic; +using System.Xml; + +namespace Tizen.NUI.Xaml +{ + internal static class TypeArgumentsParser + { + public static IList ParseExpression(string expression, IXmlNamespaceResolver resolver, IXmlLineInfo lineInfo) + { + var typeList = new List(); + while (!string.IsNullOrWhiteSpace(expression)) + { + var match = expression; + typeList.Add(Parse(match, ref expression, resolver, lineInfo)); + } + return typeList; + } + + static XmlType Parse(string match, ref string remaining, IXmlNamespaceResolver resolver, IXmlLineInfo lineinfo) + { + remaining = null; + int parensCount = 0; + int pos = 0; + bool isGeneric = false; + + for (pos = 0; pos < match.Length; pos++) + { + if (match[pos] == '(') + { + parensCount++; + isGeneric = true; + } + else if (match[pos] == ')') + parensCount--; + else if (match[pos] == ',' && parensCount == 0) + { + remaining = match.Substring(pos + 1); + break; + } + } + var type = match.Substring(0, pos).Trim(); + + IList typeArguments = null; + if (isGeneric) + { + typeArguments = ParseExpression( + type.Substring(type.IndexOf('(') + 1, type.LastIndexOf(')') - type.IndexOf('(') - 1), resolver, lineinfo); + type = type.Substring(0, type.IndexOf('(')); + } + + var split = type.Split(':'); + if (split.Length > 2) + return null; + + string prefix, name; + if (split.Length == 2) { + prefix = split [0]; + name = split [1]; + } else { + prefix = ""; + name = split [0]; + } + + var namespaceuri = resolver.LookupNamespace(prefix); + if (namespaceuri == null) + throw new XamlParseException($"No xmlns declaration for prefix '{prefix}'.", lineinfo, null); + return new XmlType(namespaceuri, name, typeArguments); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionAttribute.cs new file mode 100755 index 0000000..2b81846 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + [System.AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] + internal sealed class TypeConversionAttribute : Attribute + { + public Type TargetType { get; private set; } + + public TypeConversionAttribute(Type targetType) + { + TargetType = targetType; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionExtensions.cs new file mode 100755 index 0000000..ab1d84d --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/TypeConversionExtensions.cs @@ -0,0 +1,231 @@ +// +// TypeConversionExtensions.cs +// +// Author: +// Stephane Delcroix +// +// Copyright (c) 2013 Mobile Inception +// Copyright (c) 2014 Xamarin, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using Tizen.NUI.Xaml.Internals; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + internal static class TypeConversionExtensions + { + internal static object ConvertTo(this object value, Type toType, Func pinfoRetriever, + IServiceProvider serviceProvider) + { + Func getConverter = () => + { + ParameterInfo pInfo; + if (pinfoRetriever == null || (pInfo = pinfoRetriever()) == null) + return null; + + var converterTypeName = pInfo.CustomAttributes.GetTypeConverterTypeName(); + if (converterTypeName == null) + return null; + var convertertype = Type.GetType(converterTypeName); + return (TypeConverter)Activator.CreateInstance(convertertype); + }; + + return ConvertTo(value, toType, getConverter, serviceProvider); + } + + internal static object ConvertTo(this object value, Type toType, Func minfoRetriever, + IServiceProvider serviceProvider) + { + Func getConverter = () => + { + MemberInfo memberInfo; + + var converterTypeName = toType.GetTypeInfo().CustomAttributes.GetTypeConverterTypeName(); + if (minfoRetriever != null && (memberInfo = minfoRetriever()) != null) + converterTypeName = memberInfo.CustomAttributes.GetTypeConverterTypeName() ?? converterTypeName; + if (converterTypeName == null) + return null; + + var convertertype = Type.GetType(converterTypeName); + object ret = Activator.CreateInstance(convertertype); + return ret; + }; + + return ConvertTo(value, toType, getConverter, serviceProvider); + } + + static string GetTypeConverterTypeName(this IEnumerable attributes) + { + var converterAttribute = + attributes.FirstOrDefault(cad => TypeConverterAttribute.TypeConvertersType.Contains(cad.AttributeType.FullName)); + if (converterAttribute == null) + return null; + if (converterAttribute.ConstructorArguments[0].ArgumentType == typeof (string)) + return (string)converterAttribute.ConstructorArguments[0].Value; + if (converterAttribute.ConstructorArguments[0].ArgumentType == typeof (Type)) + return ((Type)converterAttribute.ConstructorArguments[0].Value).AssemblyQualifiedName; + return null; + } + + //Don't change the name or the signature of this, it's used by XamlC + public static object ConvertTo(this object value, Type toType, Type convertertype, IServiceProvider serviceProvider) + { + if (convertertype == null) + return value.ConvertTo(toType, (Func)null, serviceProvider); + Func getConverter = () => Activator.CreateInstance(convertertype); + ; + return value.ConvertTo(toType, getConverter, serviceProvider); + } + + private delegate void ParseValueFunc(string s, IFormatProvider provider); + + static private Dictionary typeToParseValueFunc = null; + + static private void BuildParseValueFunc() + { + if (null == typeToParseValueFunc) + { + typeToParseValueFunc = new Dictionary(); + + } + } + + internal static object ConvertTo(this object value, Type toType, Func getConverter, + IServiceProvider serviceProvider) + { + if (value == null) + return null; + + var str = value as string; + if (str != null) + { + //If there's a [TypeConverter], use it + object converter = getConverter?.Invoke(); + if (null != converter) + { + var xfTypeConverter = converter as TypeConverter; + var xfExtendedTypeConverter = xfTypeConverter as IExtendedTypeConverter; + if (xfExtendedTypeConverter != null) + return value = xfExtendedTypeConverter.ConvertFromInvariantString(str, serviceProvider); + if (xfTypeConverter != null) + return value = xfTypeConverter.ConvertFromInvariantString(str); + var converterType = converter?.GetType(); + if (converterType != null) + { + var convertFromStringInvariant = converterType.GetRuntimeMethod("ConvertFromInvariantString", + new[] { typeof(string) }); + if (convertFromStringInvariant != null) + return value = convertFromStringInvariant.Invoke(converter, new object[] { str }); + } + } + + var ignoreCase = (serviceProvider?.GetService(typeof(IConverterOptions)) as IConverterOptions)?.IgnoreCase ?? false; + + //If the type is nullable, as the value is not null, it's safe to assume we want the built-in conversion + if (toType.GetTypeInfo().IsGenericType && toType.GetGenericTypeDefinition() == typeof (Nullable<>)) + toType = Nullable.GetUnderlyingType(toType); + + //Obvious Built-in conversions + if (toType.GetTypeInfo().IsEnum) + return Enum.Parse(toType, str, ignoreCase); + + if (toType == typeof(SByte)) + return SByte.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(Int16)) + return Int16.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(Int32)) + return Int32.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(Int64)) + return Int64.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(Byte)) + return Byte.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(UInt16)) + return UInt16.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(UInt32)) + return UInt32.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(UInt64)) + return UInt64.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof (Single)) + return Single.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof (Double)) + return Double.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof (Boolean)) + return Boolean.Parse(str); + if (toType == typeof (TimeSpan)) + return TimeSpan.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof (DateTime)) + return DateTime.Parse(str, CultureInfo.InvariantCulture); + if (toType == typeof(Char)) { + char c = '\0'; + Char.TryParse(str, out c); + return c; + } + if (toType == typeof (String) && str.StartsWith("{}", StringComparison.Ordinal)) + return str.Substring(2); + if (toType == typeof (String)) + return value; + if (toType == typeof(Decimal)) + return Decimal.Parse(str, CultureInfo.InvariantCulture); + } + + //if the value is not assignable and there's an implicit conversion, convert + if (value != null && !toType.IsAssignableFrom(value.GetType())) { + var opImplicit = value.GetType().GetImplicitConversionOperator(fromType: value.GetType(), toType: toType) + ?? toType.GetImplicitConversionOperator(fromType: value.GetType(), toType: toType); + + if (opImplicit != null) { + value = opImplicit.Invoke(null, new[] { value }); + return value; + } + } + + var nativeValueConverterService = DependencyService.Get(); + + object nativeValue = null; + if (nativeValueConverterService != null && nativeValueConverterService.ConvertTo(value, toType, out nativeValue)) + return nativeValue; + + return value; + } + + internal static MethodInfo GetImplicitConversionOperator(this Type onType, Type fromType, Type toType) + { +#if NETSTANDARD1_0 + var mi = onType.GetRuntimeMethod("op_Implicit", new[] { fromType }); +#else + var bindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy; + var mi = onType.GetMethod("op_Implicit", bindingFlags, null, new[] { fromType }, null); +#endif + if (mi == null) return null; + if (!mi.IsSpecialName) return null; + if (!mi.IsPublic) return null; + if (!mi.IsStatic) return null; + if (!toType.IsAssignableFrom(mi.ReturnType)) return null; + + return mi; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ValueConverterProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ValueConverterProvider.cs new file mode 100755 index 0000000..d4b5e61 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ValueConverterProvider.cs @@ -0,0 +1,17 @@ +using System; +using System.Reflection; + +using Tizen.NUI; +using Tizen.NUI.Xaml; + +// [assembly:Dependency(typeof(ValueConverterProvider))] +namespace Tizen.NUI.Xaml +{ + internal class ValueConverterProvider : IValueConverterProvider + { + public object Convert(object value, Type toType, Func minfoRetriever, IServiceProvider serviceProvider) + { + return value.ConvertTo(toType, minfoRetriever, serviceProvider); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ViewExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ViewExtensions.cs new file mode 100755 index 0000000..cdef491 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/ViewExtensions.cs @@ -0,0 +1,67 @@ +// +// ViewExtensions.cs +// +// Author: +// Stephane Delcroix +// +// Copyright (c) 2013 Mobile Inception +// Copyright (c) 2013 Xamarin, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Reflection; +using System.ComponentModel; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + /// + /// Extension class for View defining Tizen.NUI.Xaml.Extensions.LoadFromXaml{TView} method. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class Extensions + { + /// + /// Returns a TXaml with the properties that are defined in the application manifest for callingType. + /// + /// The type of view to initialize with state from XAML. + /// The view on which this method operates. + /// The XAML that encodes the view state. + /// A TXaml with the properties that are defined in the application manifest for callingType. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public static TXaml LoadFromXaml(this TXaml view, string xaml) + { + if (view is Element) + { + NameScopeExtensions.PushElement(view); + } + + XamlLoader.Load(view, xaml); + + if (view is Element) + { + NameScopeExtensions.PopElement(); + } + + return view; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/VisualStateManager.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/VisualStateManager.cs new file mode 100755 index 0000000..01e42f3 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/VisualStateManager.cs @@ -0,0 +1,362 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using Tizen.NUI; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + internal static class VisualStateManager + { + internal class CommonStates + { + public const string Normal = "Normal"; + public const string Disabled = "Disabled"; + public const string Focused = "Focused"; + } + + public static readonly BindableProperty VisualStateGroupsProperty = + BindableProperty.CreateAttached("VisualStateGroups", typeof(VisualStateGroupList), typeof(Element), + defaultValue: null, propertyChanged: VisualStateGroupsPropertyChanged, + defaultValueCreator: bindable => new VisualStateGroupList()); + + static void VisualStateGroupsPropertyChanged(BindableObject bindable, object oldValue, object newValue) + { + GoToState((Element)bindable, CommonStates.Normal); + } + + public static IList GetVisualStateGroups(Element visualElement) + { + return (IList)visualElement.GetValue(VisualStateGroupsProperty); + } + + public static void SetVisualStateGroups(Element visualElement, VisualStateGroupList value) + { + visualElement.SetValue(VisualStateGroupsProperty, value); + } + + public static bool GoToState(Element visualElement, string name) + { + if (!visualElement.IsSet(VisualStateGroupsProperty)) + { + return false; + } + + var groups = (IList)visualElement.GetValue(VisualStateGroupsProperty); + + foreach (VisualStateGroup group in groups) + { + if (group.CurrentState?.Name == name) + { + // We're already in the target state; nothing else to do + return true; + } + + // See if this group contains the new state + var target = group.GetState(name); + if (target == null) + { + continue; + } + + // If we've got a new state to transition to, unapply the setters from the current state + if (group.CurrentState != null) + { + foreach (Setter setter in group.CurrentState.Setters) + { + setter.UnApply(visualElement); + } + } + + // Update the current state + group.CurrentState = target; + + // Apply the setters from the new state + foreach (Setter setter in target.Setters) + { + setter.Apply(visualElement); + } + + return true; + } + + return false; + } + + public static bool HasVisualStateGroups(this Element element) + { + return element.IsSet(VisualStateGroupsProperty); + } + } + + internal class VisualStateGroupList : IList + { + readonly IList _internalList; + + void Validate(IList groups) + { + // If we have 1 group, no need to worry about duplicate group names + if (groups.Count > 1) + { + if (groups.GroupBy(vsg => vsg.Name).Any(g => g.Count() > 1)) + { + throw new InvalidOperationException("VisualStateGroup Names must be unique"); + } + } + + // State names must be unique within this group list, so pull in all + // the states in all the groups, group them by name, and see if we have + // and duplicates + if (groups.SelectMany(group => group.States) + .GroupBy(state => state.Name) + .Any(g => g.Count() > 1)) + { + throw new InvalidOperationException("VisualState Names must be unique"); + } + } + + public VisualStateGroupList() + { + _internalList = new WatchAddList(Validate); + } + + void ValidateOnStatesChanged(object sender, EventArgs eventArgs) + { + Validate(_internalList); + } + + public IEnumerator GetEnumerator() + { + return _internalList.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)_internalList).GetEnumerator(); + } + + public void Add(VisualStateGroup item) + { + _internalList.Add(item); + item.StatesChanged += ValidateOnStatesChanged; + } + + public void Clear() + { + foreach (var group in _internalList) + { + group.StatesChanged -= ValidateOnStatesChanged; + } + + _internalList.Clear(); + } + + public bool Contains(VisualStateGroup item) + { + return _internalList.Contains(item); + } + + public void CopyTo(VisualStateGroup[] array, int arrayIndex) + { + _internalList.CopyTo(array, arrayIndex); + } + + public bool Remove(VisualStateGroup item) + { + item.StatesChanged -= ValidateOnStatesChanged; + return _internalList.Remove(item); + } + + public int Count => _internalList.Count; + + public bool IsReadOnly => false; + + public int IndexOf(VisualStateGroup item) + { + return _internalList.IndexOf(item); + } + + public void Insert(int index, VisualStateGroup item) + { + item.StatesChanged += ValidateOnStatesChanged; + _internalList.Insert(index, item); + } + + public void RemoveAt(int index) + { + _internalList[index].StatesChanged -= ValidateOnStatesChanged; + _internalList.RemoveAt(index); + } + + public VisualStateGroup this[int index] + { + get => _internalList[index]; + set => _internalList[index] = value; + } + } + + [RuntimeNameProperty(nameof(Name))] + [ContentProperty(nameof(States))] + internal sealed class VisualStateGroup + { + public VisualStateGroup() + { + States = new WatchAddList(OnStatesChanged); + } + + public Type TargetType { get; set; } + public string Name { get; set; } + public IList States { get; } + public VisualState CurrentState { get; internal set; } + + internal VisualState GetState(string name) + { + foreach (VisualState state in States) + { + if (string.CompareOrdinal(state.Name, name) == 0) + { + return state; + } + } + + return null; + } + + internal VisualStateGroup Clone() + { + var clone = new VisualStateGroup {TargetType = TargetType, Name = Name, CurrentState = CurrentState}; + foreach (VisualState state in States) + { + clone.States.Add(state.Clone()); + } + + return clone; + } + + internal event EventHandler StatesChanged; + + void OnStatesChanged(IList list) + { + if (list.Any(state => string.IsNullOrEmpty(state.Name))) + { + throw new InvalidOperationException("State names may not be null or empty"); + } + + StatesChanged?.Invoke(this, EventArgs.Empty); + } + } + + [RuntimeNameProperty(nameof(Name))] + internal sealed class VisualState + { + public VisualState() + { + Setters = new ObservableCollection(); + } + + public string Name { get; set; } + public IList Setters { get;} + public Type TargetType { get; set; } + + internal VisualState Clone() + { + var clone = new VisualState { Name = Name, TargetType = TargetType }; + foreach (var setter in Setters) + { + clone.Setters.Add(setter); + } + + return clone; + } + } + + internal static class VisualStateGroupListExtensions + { + internal static IList Clone(this IList groups) + { + var actual = new VisualStateGroupList(); + foreach (var group in groups) + { + actual.Add(group.Clone()); + } + + return actual; + } + } + + internal class WatchAddList : IList + { + readonly Action> _onAdd; + readonly List _internalList; + + public WatchAddList(Action> onAdd) + { + _onAdd = onAdd; + _internalList = new List(); + } + + public IEnumerator GetEnumerator() + { + return _internalList.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)_internalList).GetEnumerator(); + } + + public void Add(T item) + { + _internalList.Add(item); + _onAdd(_internalList); + } + + public void Clear() + { + _internalList.Clear(); + } + + public bool Contains(T item) + { + return _internalList.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + _internalList.CopyTo(array, arrayIndex); + } + + public bool Remove(T item) + { + return _internalList.Remove(item); + } + + public int Count => _internalList.Count; + + public bool IsReadOnly => false; + + public int IndexOf(T item) + { + return _internalList.IndexOf(item); + } + + public void Insert(int index, T item) + { + _internalList.Insert(index, item); + _onAdd(_internalList); + } + + public void RemoveAt(int index) + { + _internalList.RemoveAt(index); + } + + public T this[int index] + { + get => _internalList[index]; + set => _internalList[index] = value; + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlCompilationAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlCompilationAttribute.cs new file mode 100755 index 0000000..53b6263 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlCompilationAttribute.cs @@ -0,0 +1,42 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Tizen.NUI.Xaml +{ + [Flags] + internal enum XamlCompilationOptions + { + Skip = 1 << 0, + Compile = 1 << 1 + } + + //[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class, Inherited = false)] + //public sealed class XamlCompilationAttribute : Attribute + //{ + // public XamlCompilationAttribute(XamlCompilationOptions xamlCompilationOptions) + // { + // XamlCompilationOptions = xamlCompilationOptions; + // } + + // public XamlCompilationOptions XamlCompilationOptions { get; set; } + //} + + //internal static class XamlCExtensions + //{ + // public static bool IsCompiled(this Type type) + // { + // var attr = type.GetTypeInfo().GetCustomAttribute(); + // if (attr != null) + // return attr.XamlCompilationOptions == XamlCompilationOptions.Compile; + // attr = type.GetTypeInfo().Module.GetCustomAttribute(); + // if (attr != null) + // return attr.XamlCompilationOptions == XamlCompilationOptions.Compile; + // attr = type.GetTypeInfo().Assembly.GetCustomAttribute(); + // if (attr != null) + // return attr.XamlCompilationOptions == XamlCompilationOptions.Compile; + + // return false; + // } + //} +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlLoader.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlLoader.cs new file mode 100755 index 0000000..da7e05d --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlLoader.cs @@ -0,0 +1,308 @@ +// +// XamlLoader.cs +// +// Author: +// Stephane Delcroix +// +// Copyright (c) 2018 Mobile Inception +// Copyright (c) 2018-2014 Xamarin, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Xml; +using Tizen.NUI.Binding; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Xaml.Internals +{ + [Obsolete ("Replaced by ResourceLoader")] + internal static class XamlLoader + { + static Func xamlFileProvider; + + public static Func XamlFileProvider { + get { return xamlFileProvider; } + internal set { + xamlFileProvider = value; + Tizen.NUI.Xaml.DesignMode.IsDesignModeEnabled = true; + //¯\_(ツ)_/¯ the previewer forgot to set that bool + DoNotThrowOnExceptions = value != null; + } + } + + internal static bool DoNotThrowOnExceptions { get; set; } + } +} + +namespace Tizen.NUI.Xaml +{ + static internal class XamlLoader + { + public static void Load(object view, string xaml) + { + using (var textReader = new StringReader(xaml)) + using (var reader = XmlReader.Create(textReader)) + { + while (reader.Read()) + { + //Skip until element + if (reader.NodeType == XmlNodeType.Whitespace) + continue; + if (reader.NodeType == XmlNodeType.XmlDeclaration) + continue; + if (reader.NodeType != XmlNodeType.Element) { + Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value); + continue; + } + + for (int i = 0; i < 100; i++) + { + XmlType temp = new XmlType(reader.NamespaceURI, reader.Name, null); + } + + XmlType xmlType = new XmlType(reader.NamespaceURI, reader.Name, null); + + for (int i = 0; i < 100; i++) + { + new RuntimeRootNode(xmlType, view, (IXmlNamespaceResolver)reader); + } + + var rootnode = new RuntimeRootNode (xmlType, view, (IXmlNamespaceResolver)reader); + XamlParser.ParseXaml (rootnode, reader); + Visit (rootnode, new HydrationContext { + RootElement = view, +#pragma warning disable 0618 + ExceptionHandler = ResourceLoader.ExceptionHandler ?? (Internals.XamlLoader.DoNotThrowOnExceptions ? e => { }: (Action)null) +#pragma warning restore 0618 + }); + break; + } + } + } + + [Obsolete ("Use the XamlFileProvider to provide xaml files. We will remove this when Cycle 8 hits Stable.")] + public static object Create (string xaml, bool doNotThrow = false) + { + object inflatedView = null; + using (var textreader = new StringReader(xaml)) + using (var reader = XmlReader.Create (textreader)) { + while (reader.Read ()) { + //Skip until element + if (reader.NodeType == XmlNodeType.Whitespace) + continue; + if (reader.NodeType == XmlNodeType.XmlDeclaration) + continue; + if (reader.NodeType != XmlNodeType.Element) { + Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value); + continue; + } + + var rootnode = new RuntimeRootNode (new XmlType (reader.NamespaceURI, reader.Name, null), null, (IXmlNamespaceResolver)reader); + XamlParser.ParseXaml (rootnode, reader); + var visitorContext = new HydrationContext { + ExceptionHandler = doNotThrow ? e => { } : (Action)null, + }; + var cvv = new CreateValuesVisitor (visitorContext); + cvv.Visit ((ElementNode)rootnode, null); + inflatedView = rootnode.Root = visitorContext.Values [rootnode]; + visitorContext.RootElement = inflatedView as BindableObject; + + Visit (rootnode, visitorContext); + break; + } + } + return inflatedView; + } + + static void Visit (RootNode rootnode, HydrationContext visitorContext) + { + rootnode.Accept (new XamlNodeVisitor ((node, parent) => node.Parent = parent), null); //set parents for {StaticResource} + rootnode.Accept (new ExpandMarkupsVisitor (visitorContext), null); + rootnode.Accept (new PruneIgnoredNodesVisitor(), null); + rootnode.Accept (new NamescopingVisitor (visitorContext), null); //set namescopes for {x:Reference} + rootnode.Accept (new CreateValuesVisitor (visitorContext), null); + rootnode.Accept (new RegisterXNamesVisitor (visitorContext), null); + rootnode.Accept (new FillResourceDictionariesVisitor (visitorContext), null); + rootnode.Accept (new ApplyPropertiesVisitor (visitorContext, true), null); + } + + static string LoadObjectFromXaml(string animationXamlPath) + { + string xaml; + if (File.Exists(animationXamlPath)) + { + StreamReader reader = new StreamReader(animationXamlPath); + xaml = reader.ReadToEnd(); + return xaml; + } + + return null; + } + //if the assembly was generated using a version of XamlG that doesn't outputs XamlResourceIdAttributes, we still need to find the resource, and load it + + // static string GetXamlForType(Type type) + // { + // //the Previewer might want to provide it's own xaml for this... let them do that + // //the check at the end is preferred (using ResourceLoader). keep this until all the previewers are updated + + // string xaml; + //#pragma warning disable 0618 + // if (ResourceLoader.ResourceProvider == null && (xaml = Internals.XamlLoader.XamlFileProvider?.Invoke(type)) != null) + // return xaml; + //#pragma warning restore 0618 + + // var assembly = type.GetTypeInfo().Assembly; + // var resourceId = XamlResourceIdAttribute.GetResourceIdForType(type); + + // if (resourceId == null) + // return LegacyGetXamlForType(type); + + // using (var stream = assembly.GetManifestResourceStream(resourceId)) + // { + // if (stream != null) + // using (var reader = new StreamReader(stream)) + // xaml = reader.ReadToEnd(); + // else + // xaml = null; + // } + + // var alternateXaml = ResourceLoader.ResourceProvider?.Invoke(assembly.GetName(), XamlResourceIdAttribute.GetPathForType(type)); + // return alternateXaml ?? xaml; + // } + + static readonly Dictionary XamlResources = new Dictionary(); + static string LegacyGetXamlForType(Type type) + { + var assembly = type.GetTypeInfo().Assembly; + + string resourceId; + if (XamlResources.TryGetValue(type, out resourceId)) { + var result = ReadResourceAsXaml(type, assembly, resourceId); + if (result != null) + return result; + } + + var likelyResourceName = type.Name + ".xaml"; + var resourceNames = assembly.GetManifestResourceNames(); + string resourceName = null; + + // first pass, pray to find it because the user named it correctly + + foreach (var resource in resourceNames) { + if (ResourceMatchesFilename(assembly, resource, likelyResourceName)) { + resourceName = resource; + var xaml = ReadResourceAsXaml(type, assembly, resource); + if (xaml != null) + return xaml; + } + } + + // okay maybe they at least named it .xaml + + foreach (var resource in resourceNames) { + if (!resource.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase)) + continue; + + resourceName = resource; + var xaml = ReadResourceAsXaml(type, assembly, resource); + if (xaml != null) + return xaml; + } + + foreach (var resource in resourceNames) { + if (resource.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase)) + continue; + + resourceName = resource; + var xaml = ReadResourceAsXaml(type, assembly, resource, true); + if (xaml != null) + return xaml; + } + + return null; + } + + //legacy... + static bool ResourceMatchesFilename(Assembly assembly, string resource, string filename) + { + try { + var info = assembly.GetManifestResourceInfo(resource); + + if (!string.IsNullOrEmpty(info.FileName) && + string.Compare(info.FileName, filename, StringComparison.OrdinalIgnoreCase) == 0) + return true; + } + catch (PlatformNotSupportedException) { + // Because Win10 + .NET Native + } + + if (resource.EndsWith("." + filename, StringComparison.OrdinalIgnoreCase) || + string.Compare(resource, filename, StringComparison.OrdinalIgnoreCase) == 0) + return true; + + return false; + } + + //part of the legacy as well... + static string ReadResourceAsXaml(Type type, Assembly assembly, string likelyTargetName, bool validate = false) + { + using (var stream = assembly.GetManifestResourceStream(likelyTargetName)) + using (var reader = new StreamReader(stream)) { + if (validate) { + // terrible validation of XML. Unfortunately it will probably work most of the time since comments + // also start with a <. We can't bring in any real deps. + + var firstNonWhitespace = (char)reader.Read(); + while (char.IsWhiteSpace(firstNonWhitespace)) + firstNonWhitespace = (char)reader.Read(); + + if (firstNonWhitespace != '<') + return null; + + stream.Seek(0, SeekOrigin.Begin); + } + + var xaml = reader.ReadToEnd(); + + var pattern = String.Format("x:Class *= *\"{0}\"", type.FullName); + var regex = new Regex(pattern, RegexOptions.ECMAScript); + if (regex.IsMatch(xaml) || xaml.Contains(String.Format("x:Class=\"{0}\"", type.FullName))) + return xaml; + } + return null; + } + + public class RuntimeRootNode : RootNode + { + public RuntimeRootNode(XmlType xmlType, object root, IXmlNamespaceResolver resolver) : base (xmlType, resolver) + { + Root = root; + } + + public object Root { get; internal set; } + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNode.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNode.cs new file mode 100755 index 0000000..44a7df8 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNode.cs @@ -0,0 +1,257 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Xml; +using Tizen.NUI.Binding; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Xaml +{ + internal interface INode + { + List IgnorablePrefixes { get; set; } + + IXmlNamespaceResolver NamespaceResolver { get; } + + INode Parent { get; set; } + + void Accept(IXamlNodeVisitor visitor, INode parentNode); + INode Clone(); + } + + internal interface IValueNode : INode + { + } + + internal interface IElementNode : INode, IListNode + { + Dictionary Properties { get; } + List SkipProperties { get; } + INameScope Namescope { get; } + XmlType XmlType { get; } + string NamespaceURI { get; } + } + + internal interface IListNode : INode + { + List CollectionItems { get; } + } + + [DebuggerDisplay("{NamespaceUri}:{Name}")] + internal class XmlType + { + public XmlType(string namespaceUri, string name, IList typeArguments) + { + NamespaceUri = namespaceUri; + Name = name; + TypeArguments = typeArguments; + } + + public string NamespaceUri { get; } + public string Name { get; } + public IList TypeArguments { get; } + } + + internal abstract class BaseNode : IXmlLineInfo, INode + { + protected BaseNode(IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) + { + NamespaceResolver = namespaceResolver; + LineNumber = linenumber; + LinePosition = lineposition; + } + + public IXmlNamespaceResolver NamespaceResolver { get; } + public INode Parent { get; set; } + public List IgnorablePrefixes { get; set; } + public int LineNumber { get; set; } + public int LinePosition { get; set; } + + public bool HasLineInfo() => LineNumber >= 0 && LinePosition >= 0; + + public abstract void Accept(IXamlNodeVisitor visitor, INode parentNode); + public abstract INode Clone(); + } + + [DebuggerDisplay("{Value}")] + internal class ValueNode : BaseNode, IValueNode + { + public ValueNode(object value, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) + : base(namespaceResolver, linenumber, lineposition) + { + Value = value; + } + + public object Value { get; set; } + + public override void Accept(IXamlNodeVisitor visitor, INode parentNode) + { + visitor.Visit(this, parentNode); + } + + public override INode Clone() => new ValueNode(Value, NamespaceResolver, LineNumber, LinePosition) { + IgnorablePrefixes = IgnorablePrefixes + }; + } + + [DebuggerDisplay("{MarkupString}")] + internal class MarkupNode : BaseNode, IValueNode + { + public MarkupNode(string markupString, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) + : base(namespaceResolver, linenumber, lineposition) + { + MarkupString = markupString; + } + + public string MarkupString { get; } + + public override void Accept(IXamlNodeVisitor visitor, INode parentNode) + { + visitor.Visit(this, parentNode); + } + + public override INode Clone() => new MarkupNode(MarkupString, NamespaceResolver, LineNumber, LinePosition) { + IgnorablePrefixes = IgnorablePrefixes + }; + } + + [DebuggerDisplay("{XmlType.Name}")] + internal class ElementNode : BaseNode, IValueNode, IElementNode + { + public ElementNode(XmlType type, string namespaceURI, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, + int lineposition = -1) + : base(namespaceResolver, linenumber, lineposition) + { + Properties = new Dictionary(); + SkipProperties = new List(); + CollectionItems = new List(); + XmlType = type; + NamespaceURI = namespaceURI; + } + + public Dictionary Properties { get; } + public List SkipProperties { get; } + public List 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) + visitor.Visit(this, parentNode); + + if (!SkipChildren(visitor, 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) + visitor.Visit(this, parentNode); + + } + + bool IsDataTemplate(INode parentNode) + { + var parentElement = parentNode as IElementNode; + INode createContent; + if (parentElement != null && + parentElement.Properties.TryGetValue(XmlName._CreateContent, out createContent) && + createContent == this) + return true; + return false; + } + + protected bool SkipChildren(IXamlNodeVisitor visitor, INode node, INode parentNode) => + (visitor.StopOnDataTemplate && IsDataTemplate(parentNode)) + || (visitor.StopOnResourceDictionary && visitor.IsResourceDictionary(this)) + || visitor.SkipChildren(node, parentNode); + + protected bool SkipVisitNode(IXamlNodeVisitor visitor, INode parentNode) => + !visitor.VisitNodeOnDataTemplate && IsDataTemplate(parentNode); + + public override INode Clone() + { + var clone = new ElementNode(XmlType, NamespaceURI, NamespaceResolver, LineNumber, LinePosition) { + IgnorablePrefixes = IgnorablePrefixes + }; + foreach (var kvp in Properties) + clone.Properties.Add(kvp.Key, kvp.Value.Clone()); + foreach (var p in SkipProperties) + clone.SkipProperties.Add(p); + foreach (var p in CollectionItems) + clone.CollectionItems.Add(p.Clone()); + return clone; + } + } + + internal abstract class RootNode : ElementNode + { + protected RootNode(XmlType xmlType, IXmlNamespaceResolver nsResolver) : base(xmlType, xmlType.NamespaceUri, nsResolver) + { + } + + public override void Accept(IXamlNodeVisitor visitor, INode parentNode) + { + if (!SkipVisitNode(visitor, parentNode) && visitor.VisitingMode == TreeVisitingMode.TopDown) + visitor.Visit(this, parentNode); + + if (!SkipChildren(visitor, 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) + visitor.Visit(this, parentNode); + } + } + + internal class ListNode : BaseNode, IListNode, IValueNode + { + public ListNode(IList nodes, IXmlNamespaceResolver namespaceResolver, int linenumber = -1, int lineposition = -1) + : base(namespaceResolver, linenumber, lineposition) + { + CollectionItems = nodes.ToList(); + } + + public XmlName XmlName { get; set; } + public List CollectionItems { get; set; } + + public override void Accept(IXamlNodeVisitor visitor, INode parentNode) + { + if (visitor.VisitingMode == TreeVisitingMode.TopDown) + visitor.Visit(this, parentNode); + foreach (var node in CollectionItems) + node.Accept(visitor, this); + if (visitor.VisitingMode == TreeVisitingMode.BottomUp) + visitor.Visit(this, parentNode); + } + + public override INode Clone() + { + var items = new List(); + foreach (var p in CollectionItems) + items.Add(p.Clone()); + return new ListNode(items, NamespaceResolver, LineNumber, LinePosition) { + IgnorablePrefixes = IgnorablePrefixes + }; + } + } + + internal static class INodeExtensions + { + public static bool SkipPrefix(this INode node, string prefix) + { + do { + if (node.IgnorablePrefixes != null && node.IgnorablePrefixes.Contains(prefix)) + return true; + node = node.Parent; + } while (node != null); + return false; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNodeVisitor.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNodeVisitor.cs new file mode 100755 index 0000000..6868780 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlNodeVisitor.cs @@ -0,0 +1,51 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + internal interface IXamlNodeVisitor + { + TreeVisitingMode VisitingMode { get; } + bool StopOnDataTemplate { get; } + bool VisitNodeOnDataTemplate { get; } + bool StopOnResourceDictionary { get; } + + void Visit(ValueNode node, INode parentNode); + void Visit(MarkupNode node, INode parentNode); + void Visit(ElementNode node, INode parentNode); + void Visit(RootNode node, INode parentNode); + void Visit(ListNode node, INode parentNode); + bool SkipChildren(INode node, INode parentNode); + bool IsResourceDictionary(ElementNode node); + } + + internal enum TreeVisitingMode { + TopDown, + BottomUp + } + + internal class XamlNodeVisitor : IXamlNodeVisitor + { + readonly Action action; + + public XamlNodeVisitor(Action action, TreeVisitingMode visitingMode = TreeVisitingMode.TopDown, bool stopOnDataTemplate = false, bool visitNodeOnDataTemplate = true) + { + this.action = action; + VisitingMode = visitingMode; + StopOnDataTemplate = stopOnDataTemplate; + VisitNodeOnDataTemplate = visitNodeOnDataTemplate; + } + + public TreeVisitingMode VisitingMode { get; } + public bool StopOnDataTemplate { get; } + public bool StopOnResourceDictionary { get; } + public bool VisitNodeOnDataTemplate { get; } + + public void Visit(ValueNode node, INode parentNode) => action(node, parentNode); + public void Visit(MarkupNode node, INode parentNode) => action(node, parentNode); + public void Visit(ElementNode node, INode parentNode) => action(node, parentNode); + public void Visit(RootNode node, INode parentNode) => action(node, parentNode); + public void Visit(ListNode node, INode parentNode) => action(node, parentNode); + public bool SkipChildren(INode node, INode parentNode) => false; + public bool IsResourceDictionary(ElementNode node) => false; + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParseException.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParseException.cs new file mode 100755 index 0000000..27a5841 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParseException.cs @@ -0,0 +1,47 @@ +using System; +using System.Diagnostics; +using System.Text; +using System.Xml; + +namespace Tizen.NUI.Xaml +{ + internal class XamlParseException : Exception + { + readonly string _unformattedMessage; + + static private StringBuilder GetStackInfo() + { + StringBuilder ret = new StringBuilder("\nStack:\n"); + + StackTrace st = new StackTrace(); + + for (int i = 2; i < st.FrameCount; i++) + { + StackFrame sf = st.GetFrame(i); + ret.AppendFormat("File:{0}, Method:{1}, Line:{2}\n", sf.GetFileName(), sf.GetMethod().Name, sf.GetFileLineNumber()); + } + + return ret; + } + + public XamlParseException(string message, IXmlLineInfo xmlInfo, Exception innerException = null) : base(FormatMessage(message + GetStackInfo(), xmlInfo), innerException) + { + _unformattedMessage = message; + XmlInfo = xmlInfo; + } + + public IXmlLineInfo XmlInfo { get; private set; } + + internal string UnformattedMessage + { + get { return _unformattedMessage ?? Message; } + } + + static string FormatMessage(string message, IXmlLineInfo xmlinfo) + { + if (xmlinfo == null || !xmlinfo.HasLineInfo()) + return message; + return string.Format("Position {0}:{1}. {2}", xmlinfo.LineNumber, xmlinfo.LinePosition, message); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParser.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParser.cs new file mode 100755 index 0000000..dd30afa --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlParser.cs @@ -0,0 +1,418 @@ +// +// XamlParser.cs +// +// Author: +// Stephane Delcroix +// +// Copyright (c) 2013 Mobile Inception +// Copyright (c) 2013-2014 Xamarin, Inc +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Xml; +using Tizen.NUI.Binding; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Xaml +{ + internal static class XamlParser + { + //public const string XFUri = "http://xamarin.com/schemas/2014/forms"; + public const string XFUri = "http://tizen.org/Tizen.NUI/2018/XAML"; + public const string NUI2018Uri = "http://tizen.org/Tizen.NUI/2018/XAML"; + public const string X2006Uri = "http://schemas.microsoft.com/winfx/2006/xaml"; + public const string X2009Uri = "http://schemas.microsoft.com/winfx/2009/xaml"; + public const string McUri = "http://schemas.openxmlformats.org/markup-compatibility/2006"; + + public static void ParseXaml(RootNode rootNode, XmlReader reader) + { + IList> xmlns; + var attributes = ParseXamlAttributes(reader, out xmlns); + var prefixes = PrefixesToIgnore(xmlns); + (rootNode.IgnorablePrefixes ?? (rootNode.IgnorablePrefixes=new List())).AddRange(prefixes); + rootNode.Properties.AddRange(attributes); + ParseXamlElementFor(rootNode, reader); + } + + static void ParseXamlElementFor(IElementNode node, XmlReader reader) + { + Debug.Assert(reader.NodeType == XmlNodeType.Element); + + var elementName = reader.Name; + var isEmpty = reader.IsEmptyElement; + + if (isEmpty) + return; + + while (reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.EndElement: + Debug.Assert(reader.Name == elementName); //make sure we close the right element + return; + case XmlNodeType.Element: + // 1. Property Element. + if (reader.Name.Contains(".")) + { + XmlName name; + if (reader.Name.StartsWith(elementName + ".", StringComparison.Ordinal)) + name = new XmlName(reader.NamespaceURI, reader.Name.Substring(elementName.Length + 1)); + else //Attached DP + name = new XmlName(reader.NamespaceURI, reader.LocalName); + + var prop = ReadNode(reader); + if (prop != null) + node.Properties.Add(name, prop); + } + // 2. Xaml2009 primitives, x:Arguments, ... + else if (reader.NamespaceURI == X2009Uri && reader.LocalName == "Arguments") + { + var prop = ReadNode(reader); + if (prop != null) + node.Properties.Add(XmlName.xArguments, prop); + } + // 3. DataTemplate (should be handled by 4.) + else if ((node.XmlType.NamespaceUri == XFUri || node.XmlType.NamespaceUri == NUI2018Uri) && + (node.XmlType.Name == "DataTemplate" || node.XmlType.Name == "ControlTemplate")) + { + var prop = ReadNode(reader, true); + if (prop != null) + node.Properties.Add(XmlName._CreateContent, prop); + } + // 4. Implicit content, implicit collection, or collection syntax. Add to CollectionItems, resolve case later. + else + { + var item = ReadNode(reader, true); + if (item != null) + node.CollectionItems.Add(item); + } + break; + 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)); + break; + default: + Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value); + break; + } + } + } + + static INode ReadNode(XmlReader reader, bool nested = false) + { + var skipFirstRead = nested; + Debug.Assert(reader.NodeType == XmlNodeType.Element); + var name = reader.Name; + List nodes = new List(); + INode node = null; + + while (skipFirstRead || reader.Read()) + { + skipFirstRead = false; + + switch (reader.NodeType) + { + case XmlNodeType.EndElement: + Debug.Assert(reader.Name == name); + if (nodes.Count == 0) //Empty element + return null; + if (nodes.Count == 1) + return nodes[0]; + return new ListNode(nodes, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, + ((IXmlLineInfo)reader).LinePosition); + case XmlNodeType.Element: + var isEmpty = reader.IsEmptyElement && reader.Name == name; + var elementName = reader.Name; + var elementNsUri = reader.NamespaceURI; + var elementXmlInfo = (IXmlLineInfo)reader; + IList> xmlns; + + var attributes = ParseXamlAttributes(reader, out xmlns); + var prefixes = PrefixesToIgnore(xmlns); + + IList typeArguments = null; + if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments)) + { + typeArguments = + ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList; + } + + node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri, + reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition); + ((IElementNode)node).Properties.AddRange(attributes); + (node.IgnorablePrefixes ?? (node.IgnorablePrefixes = new List())).AddRange(prefixes); + + ParseXamlElementFor((IElementNode)node, reader); + nodes.Add(node); + if (isEmpty || nested) + return node; + break; + case XmlNodeType.Text: + node = new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, + ((IXmlLineInfo)reader).LinePosition); + nodes.Add(node); + break; + case XmlNodeType.Whitespace: + break; + default: + Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value); + break; + } + } + throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader); + } + + static IList> ParseXamlAttributes(XmlReader reader, out IList> xmlns) + { + Debug.Assert(reader.NodeType == XmlNodeType.Element); + var attributes = new List>(); + xmlns = new List>(); + for (var i = 0; i < reader.AttributeCount; i++) + { + reader.MoveToAttribute(i); + + //skip xmlns + if (reader.NamespaceURI == "http://www.w3.org/2000/xmlns/") { + xmlns.Add(new KeyValuePair(reader.LocalName, reader.Value)); + continue; + } + + var namespaceUri = reader.NamespaceURI; + if (reader.LocalName.Contains(".") && namespaceUri == "") + namespaceUri = ((IXmlNamespaceResolver)reader).LookupNamespace(""); + var propertyName = new XmlName(namespaceUri, reader.LocalName); + + object value = reader.Value; + + if (reader.NamespaceURI == X2006Uri) + { + switch (reader.Name) { + case "x:Key": + propertyName = XmlName.xKey; + break; + case "x:Name": + propertyName = XmlName.xName; + break; + case "x:Class": + case "x:FieldModifier": + continue; + default: + Debug.WriteLine("Unhandled attribute {0}", reader.Name); + continue; + } + } + + if (reader.NamespaceURI == X2009Uri) + { + switch (reader.Name) { + case "x:Key": + propertyName = XmlName.xKey; + break; + case "x:Name": + propertyName = XmlName.xName; + break; + case "x:TypeArguments": + propertyName = XmlName.xTypeArguments; + value = TypeArgumentsParser.ParseExpression((string)value, (IXmlNamespaceResolver)reader, (IXmlLineInfo)reader); + break; + case "x:DataType": + propertyName = XmlName.xDataType; + break; + case "x:Class": + case "x:FieldModifier": + continue; + case "x:FactoryMethod": + propertyName = XmlName.xFactoryMethod; + break; + case "x:Arguments": + propertyName = XmlName.xArguments; + break; + default: + Debug.WriteLine("Unhandled attribute {0}", reader.Name); + continue; + } + } + + var propertyNode = GetValueNode(value, reader); + attributes.Add(new KeyValuePair(propertyName, propertyNode)); + } + reader.MoveToElement(); + return attributes; + } + + static IList PrefixesToIgnore(IList> xmlns) + { + var prefixes = new List(); + foreach (var kvp in xmlns) { + var prefix = kvp.Key; + + string typeName = null, ns = null, asm = null, targetPlatform = null; + XmlnsHelper.ParseXmlns(kvp.Value, out typeName, out ns, out asm, out targetPlatform); + if (targetPlatform == null) + continue; + try { + if (targetPlatform != Device.RuntimePlatform) + { + // Special case for Windows backward compatibility + if (targetPlatform == "Windows" && Device.RuntimePlatform == Device.UWP) + continue; + + prefixes.Add(prefix); + } + } catch (InvalidOperationException) { + prefixes.Add(prefix); + } + } + return prefixes; + } + + static IValueNode GetValueNode(object value, XmlReader reader) + { + var valueString = value as string; + if (valueString != null && valueString.Trim().StartsWith("{}", StringComparison.Ordinal)) + { + return new ValueNode(valueString.Substring(2), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, + ((IXmlLineInfo)reader).LinePosition); + } + if (valueString != null && valueString.Trim().StartsWith("{", StringComparison.Ordinal)) + { + return new MarkupNode(valueString.Trim(), reader as IXmlNamespaceResolver, ((IXmlLineInfo)reader).LineNumber, + ((IXmlLineInfo)reader).LinePosition); + } + return new ValueNode(value, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, + ((IXmlLineInfo)reader).LinePosition); + } + + static IList s_xmlnsDefinitions; + public static IList s_assemblies = new List();// = new Assembly[]{}; + + static void GatherXmlnsDefinitionAttributes() + { + //this could be extended to look for [XmlnsDefinition] in all assemblies + // var assemblies = new [] { + // typeof(View).GetTypeInfo().Assembly, + // typeof(XamlLoader).GetTypeInfo().Assembly, + // }; + // s_assemblies = new Assembly[]{typeof(View).GetTypeInfo().Assembly}; + s_assemblies.Add(typeof(Element).GetTypeInfo().Assembly); + + s_xmlnsDefinitions = new List(); + + foreach (var assembly in s_assemblies) + foreach (XmlnsDefinitionAttribute attribute in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute))) { + s_xmlnsDefinitions.Add(attribute); + attribute.AssemblyName = attribute.AssemblyName ?? assembly.FullName; + } + } + + public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, + out XamlParseException exception) + { + if (s_xmlnsDefinitions == null) + GatherXmlnsDefinitionAttributes(); + + var namespaceURI = xmlType.NamespaceUri; + var elementName = xmlType.Name; + var typeArguments = xmlType.TypeArguments; + exception = null; + + if (elementName.Contains("-")) + { + elementName = elementName.Replace('-', '+'); + } + + var lookupAssemblies = new List(); + var lookupNames = new List(); + + foreach (var xmlnsDef in s_xmlnsDefinitions) { + if (xmlnsDef.XmlNamespace != namespaceURI) + continue; + lookupAssemblies.Add(xmlnsDef); + } + + if (lookupAssemblies.Count == 0) { + string ns, asmstring, _; + XmlnsHelper.ParseXmlns(namespaceURI, out _, out ns, out asmstring, out _); + lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns, 0) { + AssemblyName = asmstring ?? currentAssembly.FullName + }); + } + + lookupNames.Add(elementName); + lookupNames.Add(elementName + "Extension"); + + for (var i = 0; i < lookupNames.Count; i++) + { + var name = lookupNames[i]; + if (name.Contains(":")) + name = name.Substring(name.LastIndexOf(':') + 1); + if (typeArguments != null) + name += "`" + typeArguments.Count; //this will return an open generic Type + lookupNames[i] = name; + } + + Type type = null; + foreach (var asm in lookupAssemblies) { + foreach (var name in lookupNames) + if ((type = Type.GetType($"{asm.ClrNamespace}.{name}, {asm.AssemblyName}")) != null) + break; + if (type != null) + break; + } + + if (type != null && typeArguments != null) + { + XamlParseException innerexception = null; + var args = typeArguments.Select(delegate(XmlType xmltype) + { + XamlParseException xpe; + var t = GetElementType(xmltype, xmlInfo, currentAssembly, out xpe); + if (xpe != null) + { + innerexception = xpe; + return null; + } + return t; + }).ToArray(); + if (innerexception != null) + { + exception = innerexception; + return null; + } + type = type.MakeGenericType(args); + } + + if (type == null) + exception = new XamlParseException($"Type {elementName} not found in xmlns {namespaceURI}", xmlInfo); + + return type; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlResourceIdAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlResourceIdAttribute.cs new file mode 100755 index 0000000..b95bfcf --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlResourceIdAttribute.cs @@ -0,0 +1,67 @@ +using System; +using System.Reflection; + +namespace Tizen.NUI.Xaml +{ + [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)] + internal sealed class XamlResourceIdAttribute : Attribute + { + public string ResourceId { get; set; } + public string Path { get; set; } + public Type Type { get; set; } + + public XamlResourceIdAttribute(string resourceId, string path, Type type) + { + ResourceId = resourceId; + Path = path; + Type = type; + } + + internal static string GetResourceIdForType(Type type) + { + var assembly = type.GetTypeInfo().Assembly; + foreach (var xria in assembly.GetCustomAttributes()) { + if (xria.Type == type) + return xria.ResourceId; + } + return null; + } + + internal static string GetPathForType(Type type) + { + var assembly = type.GetTypeInfo().Assembly; + foreach (var xria in assembly.GetCustomAttributes()) { + if (xria.Type == type) + return xria.Path; + } + return null; + } + + internal static string GetResourceIdForPath(Assembly assembly, string path) + { + foreach (var xria in assembly.GetCustomAttributes()) { + if (xria.Path == path) + return xria.ResourceId; + } + return null; + } + + internal static Type GetTypeForResourceId(Assembly assembly, string resourceId) + { + foreach (var xria in assembly.GetCustomAttributes()) { + if (xria.ResourceId == resourceId) + return xria.Type; + } + return null; + } + + internal static Type GetTypeForPath(Assembly assembly, string path) + { + foreach (var xria in assembly.GetCustomAttributes()) { + if (xria.Path == path) + return xria.Type; + } + return null; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlServiceProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlServiceProvider.cs new file mode 100755 index 0000000..440319c --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XamlServiceProvider.cs @@ -0,0 +1,321 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Xml; +using Tizen.NUI.Binding; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Xaml +{ + internal class XamlServiceProvider : IServiceProvider + { + readonly Dictionary services = new Dictionary(); + + internal XamlServiceProvider(INode node, HydrationContext context) + { + object targetObject; + if (node != null && node.Parent != null && context.Values.TryGetValue(node.Parent, out targetObject)) + IProvideValueTarget = new XamlValueTargetProvider(targetObject, node, context, null); + if (context != null) + IRootObjectProvider = new XamlRootObjectProvider(context.RootElement); + if (node != null) + { + IXamlTypeResolver = new XamlTypeResolver(node.NamespaceResolver, XamlParser.GetElementType, + context?.RootElement.GetType().GetTypeInfo().Assembly); + + var enode = node; + while (enode != null && !(enode is IElementNode)) + enode = enode.Parent; + if (enode != null) + INameScopeProvider = new NameScopeProvider { NameScope = (enode as IElementNode).Namescope }; + } + + var xmlLineInfo = node as IXmlLineInfo; + if (xmlLineInfo != null) + IXmlLineInfoProvider = new XmlLineInfoProvider(xmlLineInfo); + + IValueConverterProvider = new ValueConverterProvider(); + } + + public XamlServiceProvider() + { + IValueConverterProvider = new ValueConverterProvider(); + } + + internal IProvideValueTarget IProvideValueTarget + { + get { return (IProvideValueTarget)GetService(typeof (IProvideValueTarget)); } + set { services[typeof (IProvideValueTarget)] = value; } + } + + internal IXamlTypeResolver IXamlTypeResolver + { + get { return (IXamlTypeResolver)GetService(typeof (IXamlTypeResolver)); } + set { services[typeof (IXamlTypeResolver)] = value; } + } + + internal IRootObjectProvider IRootObjectProvider + { + get { return (IRootObjectProvider)GetService(typeof (IRootObjectProvider)); } + set { services[typeof (IRootObjectProvider)] = value; } + } + + internal IXmlLineInfoProvider IXmlLineInfoProvider + { + get { return (IXmlLineInfoProvider)GetService(typeof (IXmlLineInfoProvider)); } + set { services[typeof (IXmlLineInfoProvider)] = value; } + } + + internal INameScopeProvider INameScopeProvider + { + get { return (INameScopeProvider)GetService(typeof (INameScopeProvider)); } + set { services[typeof (INameScopeProvider)] = value; } + } + + internal IValueConverterProvider IValueConverterProvider + { + get { return (IValueConverterProvider)GetService(typeof (IValueConverterProvider)); } + set { services[typeof (IValueConverterProvider)] = value; } + } + + public object GetService(Type serviceType) + { + object service; + return services.TryGetValue(serviceType, out service) ? service : null; + } + + public void Add(Type type, object service) + { + services.Add(type, service); + } + } + + internal class XamlValueTargetProvider : IProvideParentValues, IProvideValueTarget + { + public XamlValueTargetProvider(object targetObject, INode node, HydrationContext context, object targetProperty) + { + Context = context; + Node = node; + TargetObject = targetObject; + TargetProperty = targetProperty; + } + + INode Node { get; } + + HydrationContext Context { get; } + public object TargetObject { get; } + public object TargetProperty { get; internal set; } = null; + + IEnumerable IProvideParentValues.ParentObjects + { + get + { + if (Node == null || Context == null) + yield break; + var n = Node; + object obj = null; + var context = Context; + while (n.Parent != null && context != null) + { + if (n.Parent is IElementNode) + { + if (context.Values.TryGetValue(n.Parent, out obj)) + yield return obj; + else + { + context = context.ParentContext; + continue; + } + } + n = n.Parent; + } + } + } + } + + internal class SimpleValueTargetProvider : IProvideParentValues, IProvideValueTarget, IReferenceProvider + { + readonly object[] objectAndParents; + readonly object targetProperty; + + [Obsolete("SimpleValueTargetProvider(object[] objectAndParents) is obsolete as of version 2.3.4. Please use SimpleValueTargetProvider(object[] objectAndParents, object targetProperty) instead.")] + public SimpleValueTargetProvider(object[] objectAndParents) : this (objectAndParents, null) + { + } + + public SimpleValueTargetProvider(object[] objectAndParents, object targetProperty) + { + if (objectAndParents == null) + throw new ArgumentNullException(nameof(objectAndParents)); + if (objectAndParents.Length == 0) + throw new ArgumentException(); + + this.objectAndParents = objectAndParents; + this.targetProperty = targetProperty; + } + + IEnumerable IProvideParentValues.ParentObjects + { + get { return objectAndParents; } + } + + object IProvideValueTarget.TargetObject + { + get { return objectAndParents[0]; } + } + + object IProvideValueTarget.TargetProperty + { + get { return targetProperty; } + } + + public object FindByName(string name) + { + for (var i = 0; i < objectAndParents.Length; i++) + { + var bo = objectAndParents[i] as BindableObject; + if (bo == null) continue; + var ns = NameScope.GetNameScope(bo) as INameScope; + if (ns == null) continue; + var value = ns.FindByName(name); + if (value != null) + return value; + } + return null; + } + } + + internal class XamlTypeResolver : IXamlTypeResolver + { + readonly Assembly currentAssembly; + readonly GetTypeFromXmlName getTypeFromXmlName; + readonly IXmlNamespaceResolver namespaceResolver; + + public XamlTypeResolver(IXmlNamespaceResolver namespaceResolver, Assembly currentAssembly) + : this(namespaceResolver, XamlParser.GetElementType, currentAssembly) + { + } + + internal XamlTypeResolver(IXmlNamespaceResolver namespaceResolver, GetTypeFromXmlName getTypeFromXmlName, + Assembly currentAssembly) + { + this.currentAssembly = currentAssembly; + if (namespaceResolver == null) + throw new ArgumentNullException(); + if (getTypeFromXmlName == null) + throw new ArgumentNullException(); + + this.namespaceResolver = namespaceResolver; + this.getTypeFromXmlName = getTypeFromXmlName; + } + + Type IXamlTypeResolver.Resolve(string qualifiedTypeName, IServiceProvider serviceProvider) + { + XamlParseException e; + var type = Resolve(qualifiedTypeName, serviceProvider, out e); + if (e != null) + throw e; + return type; + } + + bool IXamlTypeResolver.TryResolve(string qualifiedTypeName, out Type type) + { + XamlParseException exception; + type = Resolve(qualifiedTypeName, null, out exception); + return exception == null; + } + + Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out XamlParseException exception) + { + exception = null; + var split = qualifiedTypeName.Split(':'); + if (split.Length > 2) + return null; + + string prefix, name; + if (split.Length == 2) + { + prefix = split[0]; + name = split[1]; + } + else + { + prefix = ""; + name = split[0]; + } + + IXmlLineInfo xmlLineInfo = null; + if (serviceProvider != null) + { + var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + if (lineInfoProvider != null) + xmlLineInfo = lineInfoProvider.XmlLineInfo; + } + + var namespaceuri = namespaceResolver.LookupNamespace(prefix); + if (namespaceuri == null) + { + exception = new XamlParseException(string.Format("No xmlns declaration for prefix \"{0}\"", prefix), xmlLineInfo); + return null; + } + + return getTypeFromXmlName(new XmlType(namespaceuri, name, null), xmlLineInfo, currentAssembly, out exception); + } + + internal delegate Type GetTypeFromXmlName( + XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception); + } + + internal class XamlRootObjectProvider : IRootObjectProvider + { + public XamlRootObjectProvider(object rootObject) + { + RootObject = rootObject; + } + + public object RootObject { get; } + } + + internal class XmlLineInfoProvider : IXmlLineInfoProvider + { + public XmlLineInfoProvider(IXmlLineInfo xmlLineInfo) + { + XmlLineInfo = xmlLineInfo; + } + + public IXmlLineInfo XmlLineInfo { get; } + } + + internal class NameScopeProvider : INameScopeProvider + { + public INameScope NameScope { get; set; } + } + + internal class XmlNamespaceResolver : IXmlNamespaceResolver + { + readonly Dictionary namespaces = new Dictionary(); + + public IDictionary GetNamespacesInScope(XmlNamespaceScope scope) + { + throw new NotImplementedException(); + } + + public string LookupNamespace(string prefix) + { + string result; + if (namespaces.TryGetValue(prefix, out result)) + return result; + return null; + } + + public string LookupPrefix(string namespaceName) + { + throw new NotImplementedException(); + } + + public void Add(string prefix, string ns) + { + namespaces.Add(prefix, ns); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlLineInfo.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlLineInfo.cs new file mode 100755 index 0000000..59bb074 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlLineInfo.cs @@ -0,0 +1,31 @@ +using System.Xml; + +namespace Tizen.NUI.Xaml +{ + internal class XmlLineInfo : IXmlLineInfo + { + readonly bool _hasLineInfo; + private int v1; + private int v2; + + public XmlLineInfo() + { + } + + public XmlLineInfo(int linenumber, int lineposition) + { + _hasLineInfo = true; + LineNumber = linenumber; + LinePosition = lineposition; + } + + public bool HasLineInfo() + { + return _hasLineInfo; + } + + public int LineNumber { get; } + + public int LinePosition { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlName.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlName.cs new file mode 100755 index 0000000..7cb0a26 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlName.cs @@ -0,0 +1,58 @@ +using System.Diagnostics; + +namespace Tizen.NUI.Xaml +{ + [DebuggerDisplay("{NamespaceURI}:{LocalName}")] + internal struct XmlName + { + public static readonly XmlName _CreateContent = new XmlName("_", "CreateContent"); + public static readonly XmlName xKey = new XmlName("x", "Key"); + public static readonly XmlName xName = new XmlName("x", "Name"); + public static readonly XmlName xTypeArguments = new XmlName("x", "TypeArguments"); + public static readonly XmlName xArguments = new XmlName("x", "Arguments"); + public static readonly XmlName xFactoryMethod = new XmlName("x", "FactoryMethod"); + public static readonly XmlName xDataType = new XmlName("x", "DataType"); + public static readonly XmlName Empty = new XmlName(); + + public string NamespaceURI { get; } + public string LocalName { get; } + + public XmlName(string namespaceUri, string localName) + { + NamespaceURI = namespaceUri; + LocalName = localName; + } + + public override bool Equals(object obj) + { + if (obj == null) + return false; + if (obj.GetType() != typeof (XmlName)) + return false; + var other = (XmlName)obj; + return NamespaceURI == other.NamespaceURI && LocalName == other.LocalName; + } + + public bool Equals(string namespaceUri, string localName) + => Equals(new XmlName(namespaceUri, localName)); + + public override int GetHashCode() + { + unchecked + { + int hashCode = 0; + if (NamespaceURI != null) + hashCode = NamespaceURI.GetHashCode(); + if (LocalName != null) + hashCode = (hashCode * 397) ^ LocalName.GetHashCode(); + return hashCode; + } + } + + public static bool operator ==(XmlName x1, XmlName x2) + => x1.NamespaceURI == x2.NamespaceURI && x1.LocalName == x2.LocalName; + + public static bool operator !=(XmlName x1, XmlName x2) + => !(x1 == x2); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlnsHelper.cs b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlnsHelper.cs new file mode 100755 index 0000000..8f86874 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/Xaml/XmlnsHelper.cs @@ -0,0 +1,75 @@ +using System; + +namespace Tizen.NUI.Xaml +{ + internal static class XmlnsHelper + { + public static string ParseNamespaceFromXmlns(string xmlns) + { + string typeName; + string ns; + string asm; + string targetPlatform; + + ParseXmlns(xmlns, out typeName, out ns, out asm, out targetPlatform); + + return ns; + } + + public static void ParseXmlns(string xmlns, out string typeName, out string ns, out string asm, out string targetPlatform) + { + typeName = ns = asm = targetPlatform = null; + + xmlns = xmlns.Trim(); + + if (xmlns.StartsWith("using:", StringComparison.Ordinal)) { + ParseUsing(xmlns, out typeName, out ns, out asm, out targetPlatform); + return; + } + ParseClrNamespace(xmlns, out typeName, out ns, out asm, out targetPlatform); + } + + static void ParseClrNamespace(string xmlns, out string typeName, out string ns, out string asm, out string targetPlatform) + { + typeName = ns = asm = targetPlatform = null; + + foreach (var decl in xmlns.Split(';')) + { + if (decl.StartsWith("clr-namespace:", StringComparison.Ordinal)) + { + ns = decl.Substring(14, decl.Length - 14); + continue; + } + if (decl.StartsWith("assembly=", StringComparison.Ordinal)) + { + asm = decl.Substring(9, decl.Length - 9); + continue; + } + if (decl.StartsWith("targetPlatform=", StringComparison.Ordinal)) { + targetPlatform = decl.Substring(15, decl.Length - 15); + continue; + } + var nsind = decl.LastIndexOf(".", StringComparison.Ordinal); + if (nsind > 0) + { + ns = decl.Substring(0, nsind); + typeName = decl.Substring(nsind + 1, decl.Length - nsind - 1); + } + else + typeName = decl; + } + } + + static void ParseUsing(string xmlns, out string typeName, out string ns, out string asm, out string targetPlatform) + { + typeName = ns = asm = targetPlatform = null; + + foreach (var decl in xmlns.Split(';')) { + if (decl.StartsWith("using:", StringComparison.Ordinal)) { + ns = decl.Substring(6, decl.Length - 6); + continue; + } + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableObject.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableObject.cs new file mode 100755 index 0000000..e94b836 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableObject.cs @@ -0,0 +1,913 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + /// + /// Provides a mechanism by which application developers can propagate changes that are made to data in one object to another, by enabling validation, type coercion, and an event system. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal abstract class BindableObject : INotifyPropertyChanged, IDynamicResourceHandler + { + /// + /// Implements the bound property whose interface is provided by the BindingContext property. + /// + public static readonly BindableProperty BindingContextProperty = + BindableProperty.Create("BindingContext", typeof(object), typeof(BindableObject), default(object), + BindingMode.OneWay, null, BindingContextPropertyChanged, null, null, BindingContextPropertyBindingChanging); + + readonly List _properties = new List(4); + + bool _applying; + object _inheritedContext; + + /// + /// Gets or sets object that contains the properties that will be targeted by the bound properties that belong to this BindableObject. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public object BindingContext + { + get { return _inheritedContext ?? GetValue(BindingContextProperty); } + set { SetValue(BindingContextProperty, value); } + } + + void IDynamicResourceHandler.SetDynamicResource(BindableProperty property, string key) + { + SetDynamicResource(property, key, false); + } + + /// + /// Raised when a property has changed. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raised whenever the BindingContext property changes. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler BindingContextChanged; + + internal void ClearValue(BindableProperty property, bool fromStyle) + { + ClearValue(property, fromStyle: fromStyle, checkAccess: true); + } + + /// + /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue. + /// + /// The BindableProperty to clear + internal void ClearValue(BindableProperty property) + { + ClearValue(property, fromStyle: false, checkAccess: true); + } + + /// + /// Clears any value set by Tizen.NUI.Xaml.BindableObject.SetValue for the property that is identified by propertyKey. + /// + /// The BindablePropertyKey that identifies the BindableProperty to clear. + internal void ClearValue(BindablePropertyKey propertyKey) + { + if (propertyKey == null) + throw new ArgumentNullException("propertyKey"); + + ClearValue(propertyKey.BindableProperty, fromStyle:false, checkAccess: false); + } + + /// + /// Return true if the target property exists and has been set. + /// + /// The target property + /// return true if the target property exists and has been set + internal bool IsSet(BindableProperty targetProperty) + { + if (targetProperty == null) + throw new ArgumentNullException(nameof(targetProperty)); + + var bpcontext = GetContext(targetProperty); + return bpcontext != null + && (bpcontext.Attributes & BindableContextAttributes.IsDefaultValue) == 0; + } + + /// + /// Returns the value that is contained the BindableProperty. + /// + /// The BindableProperty for which to get the value. + /// The value that is contained the BindableProperty + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public object GetValue(BindableProperty property) + { + if (property == null) + throw new ArgumentNullException("property"); + + BindablePropertyContext context = property.DefaultValueCreator != null ? GetOrCreateContext(property) : GetContext(property); + + if (context == null) + return property.DefaultValue; + + return context.Value; + } + + /// + /// Raised when a property is about to change. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public event PropertyChangingEventHandler PropertyChanging; + + /// + /// Removes a previously set binding. + /// + /// The BindableProperty from which to remove bindings. + internal void RemoveBinding(BindableProperty property) + { + if (property == null) + throw new ArgumentNullException("property"); + + BindablePropertyContext context = GetContext(property); + if (context == null || context.Binding == null) + return; + + RemoveBinding(property, context); + } + + /// + /// Assigns a binding to a property. + /// + /// The BindableProperty on which to set a binding. + /// The binding to set. + public void SetBinding(BindableProperty targetProperty, BindingBase binding) + { + SetBinding(targetProperty, binding, false); + } + + private bool isCreateByXaml = false; + internal virtual bool IsCreateByXaml + { + get + { + return isCreateByXaml; + } + set + { + isCreateByXaml = value; + } + } + + /// + /// Sets the value of the specified property. + /// + /// The BindableProperty on which to assign a value. + /// The value to set. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetValue(BindableProperty property, object value) + { + SetValue(property, value, false, true); + //if (true == isCreateByXaml) + //{ + // SetValue(property, value, false, true); + //} + //else + //{ + // property.PropertyChanged?.Invoke(this, null, value); + //} + } + + internal void SetValueAndForceSendChangeSignal(BindableProperty property, object value) + { + if (property == null) + throw new ArgumentNullException("property"); + + if (property.IsReadOnly) + throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName)); + + SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource, + SetValuePrivateFlags.ManuallySet | SetValuePrivateFlags.CheckAccess, true); + + //if (true == isCreateByXaml) + //{ + // if (property.IsReadOnly) + // throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName)); + + // SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource, + // SetValuePrivateFlags.ManuallySet | SetValuePrivateFlags.CheckAccess, true); + //} + //else + //{ + // property.PropertyChanged?.Invoke(this, null, value); + //} + } + + /// + /// Sets the value of the propertyKey. + /// + /// The BindablePropertyKey on which to assign a value. + /// The value to set. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetValue(BindablePropertyKey propertyKey, object value) + { + if (propertyKey == null) + throw new ArgumentNullException("propertyKey"); + + SetValue(propertyKey.BindableProperty, value, false, false); + } + + /// + /// Set the inherited context to a neated element. + /// + /// The object on which to set the inherited binding context. + /// The inherited context to set. + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetInheritedBindingContext(BindableObject bindable, object value) + { + BindablePropertyContext bpContext = bindable.GetContext(BindingContextProperty); + if (bpContext != null && ((bpContext.Attributes & BindableContextAttributes.IsManuallySet) != 0)) + return; + + object oldContext = bindable._inheritedContext; + + if (ReferenceEquals(oldContext, value)) + return; + + if (bpContext != null && oldContext == null) + oldContext = bpContext.Value; + + if (bpContext != null && bpContext.Binding != null) + { + bpContext.Binding.Context = value; + bindable._inheritedContext = null; + } + else + { + bindable._inheritedContext = value; + } + + bindable.ApplyBindings(skipBindingContext:false, fromBindingContextChanged:true); + bindable.OnBindingContextChanged(); + } + + /// + /// Apply the bindings to BindingContext. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected void ApplyBindings() + { + ApplyBindings(skipBindingContext: false, fromBindingContextChanged: false); + } + + /// + /// Override this method to execute an action when the BindingContext changes. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void OnBindingContextChanged() + { + BindingContextChanged?.Invoke(this, EventArgs.Empty); + } + + /// + /// Call this method from a child class to notify that a change happened on a property. + /// + /// The name of the property that changed. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + + /// + /// Call this method from a child class to notify that a change is going to happen on a property. + /// + /// The name of the property that is changing. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null) + => PropertyChanging?.Invoke(this, new PropertyChangingEventArgs(propertyName)); + + /// + /// Unapplies all previously set bindings. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected void UnapplyBindings() + { + for (int i = 0, _propertiesCount = _properties.Count; i < _propertiesCount; i++) { + BindablePropertyContext context = _properties [i]; + if (context.Binding == null) + continue; + + context.Binding.Unapply(); + } + } + + internal bool GetIsBound(BindableProperty targetProperty) + { + if (targetProperty == null) + throw new ArgumentNullException("targetProperty"); + + BindablePropertyContext bpcontext = GetContext(targetProperty); + return bpcontext != null && bpcontext.Binding != null; + } + + /// + /// Returns the value that is contained the BindableProperty. + /// + /// The BindableProperty instance. + /// The BindableProperty instance. + /// The value that is contained the BindableProperty + internal object[] GetValues(BindableProperty property0, BindableProperty property1) + { + var values = new object[2]; + + for (var i = 0; i < _properties.Count; i++) + { + BindablePropertyContext context = _properties[i]; + + if (ReferenceEquals(context.Property, property0)) + { + values[0] = context.Value; + property0 = null; + } + else if (ReferenceEquals(context.Property, property1)) + { + values[1] = context.Value; + property1 = null; + } + + if (property0 == null && property1 == null) + return values; + } + + if (!ReferenceEquals(property0, null)) + values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value; + if (!ReferenceEquals(property1, null)) + values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value; + + return values; + } + + /// + /// Returns the value that is contained the BindableProperty. + /// + /// The BindableProperty instance. + /// The BindableProperty instance. + /// The BindableProperty instance. + /// The value that is contained the BindableProperty + internal object[] GetValues(BindableProperty property0, BindableProperty property1, BindableProperty property2) + { + var values = new object[3]; + + for (var i = 0; i < _properties.Count; i++) + { + BindablePropertyContext context = _properties[i]; + + if (ReferenceEquals(context.Property, property0)) + { + values[0] = context.Value; + property0 = null; + } + else if (ReferenceEquals(context.Property, property1)) + { + values[1] = context.Value; + property1 = null; + } + else if (ReferenceEquals(context.Property, property2)) + { + values[2] = context.Value; + property2 = null; + } + + if (property0 == null && property1 == null && property2 == null) + return values; + } + + if (!ReferenceEquals(property0, null)) + values[0] = property0.DefaultValueCreator == null ? property0.DefaultValue : CreateAndAddContext(property0).Value; + if (!ReferenceEquals(property1, null)) + values[1] = property1.DefaultValueCreator == null ? property1.DefaultValue : CreateAndAddContext(property1).Value; + if (!ReferenceEquals(property2, null)) + values[2] = property2.DefaultValueCreator == null ? property2.DefaultValue : CreateAndAddContext(property2).Value; + + return values; + } + + /// + /// Returns the value that is contained the BindableProperty. + /// + /// The array of the BindableProperty instances + /// The values that is contained the BindableProperty instances. + internal object[] GetValues(params BindableProperty[] properties) + { + var values = new object[properties.Length]; + for (var i = 0; i < _properties.Count; i++) { + var context = _properties[i]; + var index = properties.IndexOf(context.Property); + if (index < 0) + continue; + values[index] = context.Value; + } + for (var i = 0; i < values.Length; i++) { + if (!ReferenceEquals(values[i], null)) + continue; + values[i] = properties[i].DefaultValueCreator == null ? properties[i].DefaultValue : CreateAndAddContext(properties[i]).Value; + } + return values; + } + + internal virtual void OnRemoveDynamicResource(BindableProperty property) + { + } + + internal virtual void OnSetDynamicResource(BindableProperty property, string key) + { + } + + internal void RemoveDynamicResource(BindableProperty property) + { + if (property == null) + throw new ArgumentNullException("property"); + + OnRemoveDynamicResource(property); + BindablePropertyContext context = GetOrCreateContext(property); + context.Attributes &= ~BindableContextAttributes.IsDynamicResource; + } + + internal void SetBinding(BindableProperty targetProperty, BindingBase binding, bool fromStyle) + { + if (targetProperty == null) + throw new ArgumentNullException("targetProperty"); + if (binding == null) + throw new ArgumentNullException("binding"); + + if (fromStyle && !CanBeSetFromStyle(targetProperty)) + return; + + var context = GetOrCreateContext(targetProperty); + if (fromStyle) + context.Attributes |= BindableContextAttributes.IsSetFromStyle; + else + context.Attributes &= ~BindableContextAttributes.IsSetFromStyle; + + if (context.Binding != null) + context.Binding.Unapply(); + + BindingBase oldBinding = context.Binding; + context.Binding = binding; + + targetProperty.BindingChanging?.Invoke(this, oldBinding, binding); + + binding.Apply(BindingContext, this, targetProperty); + } + + bool CanBeSetFromStyle(BindableProperty property) + { + var context = GetContext(property); + if (context == null) + return true; + if ((context.Attributes & BindableContextAttributes.IsSetFromStyle) == BindableContextAttributes.IsSetFromStyle) + return true; + if ((context.Attributes & BindableContextAttributes.IsDefaultValue) == BindableContextAttributes.IsDefaultValue) + return true; + if ((context.Attributes & BindableContextAttributes.IsDefaultValueCreated) == BindableContextAttributes.IsDefaultValueCreated) + return true; + return false; + } + + internal void SetDynamicResource(BindableProperty property, string key) + { + SetDynamicResource(property, key, false); + } + + internal void SetDynamicResource(BindableProperty property, string key, bool fromStyle) + { + if (property == null) + throw new ArgumentNullException(nameof(property)); + if (string.IsNullOrEmpty(key)) + throw new ArgumentNullException(nameof(key)); + if (fromStyle && !CanBeSetFromStyle(property)) + return; + + var context = GetOrCreateContext(property); + + context.Attributes |= BindableContextAttributes.IsDynamicResource; + if (fromStyle) + context.Attributes |= BindableContextAttributes.IsSetFromStyle; + else + context.Attributes &= ~BindableContextAttributes.IsSetFromStyle; + + OnSetDynamicResource(property, key); + } + + internal void SetValue(BindableProperty property, object value, bool fromStyle) + { + SetValue(property, value, fromStyle, true); + } + + internal void SetValueCore(BindablePropertyKey propertyKey, object value, SetValueFlags attributes = SetValueFlags.None) + { + SetValueCore(propertyKey.BindableProperty, value, attributes, SetValuePrivateFlags.None, false); + } + + /// + /// For internal use. + /// + /// The BindableProperty on which to assign a value. + /// The value to set + /// The set value flag + [EditorBrowsable(EditorBrowsableState.Never)] + internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes = SetValueFlags.None) + { + SetValueCore(property, value, attributes, SetValuePrivateFlags.Default, false); + } + + internal void SetValueCore(BindableProperty property, object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, bool forceSendChangeSignal) + { + bool checkAccess = (privateAttributes & SetValuePrivateFlags.CheckAccess) != 0; + bool manuallySet = (privateAttributes & SetValuePrivateFlags.ManuallySet) != 0; + bool silent = (privateAttributes & SetValuePrivateFlags.Silent) != 0; + bool fromStyle = (privateAttributes & SetValuePrivateFlags.FromStyle) != 0; + bool converted = (privateAttributes & SetValuePrivateFlags.Converted) != 0; + + if (property == null) + throw new ArgumentNullException("property"); + if (checkAccess && property.IsReadOnly) + { + Debug.WriteLine("Can not set the BindableProperty \"{0}\" because it is readonly.", property.PropertyName); + return; + } + + if (!converted && !property.TryConvert(ref value)) + { + Console.WriteLine("SetValue", "Can not convert {0} to type '{1}'", value, property.ReturnType); + return; + } + + if (property.ValidateValue != null && !property.ValidateValue(this, value)) + throw new ArgumentException("Value was an invalid value for " + property.PropertyName, "value"); + + if (property.CoerceValue != null) + value = property.CoerceValue(this, value); + + BindablePropertyContext context = GetOrCreateContext(property); + if (manuallySet) { + context.Attributes |= BindableContextAttributes.IsManuallySet; + context.Attributes &= ~BindableContextAttributes.IsSetFromStyle; + } else + context.Attributes &= ~BindableContextAttributes.IsManuallySet; + + if (fromStyle) + context.Attributes |= BindableContextAttributes.IsSetFromStyle; + // else omitted on purpose + + bool currentlyApplying = _applying; + + if ((context.Attributes & BindableContextAttributes.IsBeingSet) != 0) + { + Queue delayQueue = context.DelayedSetters; + if (delayQueue == null) + context.DelayedSetters = delayQueue = new Queue(); + + delayQueue.Enqueue(new SetValueArgs(property, context, value, currentlyApplying, attributes)); + } + else + { + context.Attributes |= BindableContextAttributes.IsBeingSet; + SetValueActual(property, context, value, currentlyApplying, forceSendChangeSignal, attributes, silent); + + Queue delayQueue = context.DelayedSetters; + if (delayQueue != null) + { + while (delayQueue.Count > 0) + { + SetValueArgs s = delayQueue.Dequeue(); + SetValueActual(s.Property, s.Context, s.Value, s.CurrentlyApplying, forceSendChangeSignal, s.Attributes); + } + + context.DelayedSetters = null; + } + + context.Attributes &= ~BindableContextAttributes.IsBeingSet; + } + } + + internal void ApplyBindings(bool skipBindingContext, bool fromBindingContextChanged) + { + var prop = _properties.ToArray(); + for (int i = 0, propLength = prop.Length; i < propLength; i++) { + BindablePropertyContext context = prop [i]; + BindingBase binding = context.Binding; + if (binding == null) + continue; + + if (skipBindingContext && ReferenceEquals(context.Property, BindingContextProperty)) + continue; + + binding.Unapply(fromBindingContextChanged: fromBindingContextChanged); + binding.Apply(BindingContext, this, context.Property, fromBindingContextChanged: fromBindingContextChanged); + } + } + + static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase) + { + object context = bindable._inheritedContext; + var oldBinding = oldBindingBase as Binding; + var newBinding = newBindingBase as Binding; + + if (context == null && oldBinding != null) + context = oldBinding.Context; + if (context != null && newBinding != null) + newBinding.Context = context; + } + + static void BindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue) + { + bindable._inheritedContext = null; + bindable.ApplyBindings(skipBindingContext: true, fromBindingContextChanged:true); + bindable.OnBindingContextChanged(); + } + + void ClearValue(BindableProperty property, bool fromStyle, bool checkAccess) + { + if (property == null) + throw new ArgumentNullException(nameof(property)); + + if (checkAccess && property.IsReadOnly) + throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName)); + + BindablePropertyContext bpcontext = GetContext(property); + if (bpcontext == null) + return; + + if (fromStyle && !CanBeSetFromStyle(property)) + return; + + object original = bpcontext.Value; + + object newValue = property.GetDefaultValue(this); + + bool same = Equals(original, newValue); + if (!same) + { + property.PropertyChanging?.Invoke(this, original, newValue); + + OnPropertyChanging(property.PropertyName); + } + + bpcontext.Attributes &= ~BindableContextAttributes.IsManuallySet; + bpcontext.Value = newValue; + if (property.DefaultValueCreator == null) + bpcontext.Attributes |= BindableContextAttributes.IsDefaultValue; + else + bpcontext.Attributes |= BindableContextAttributes.IsDefaultValueCreated; + + if (!same) + { + OnPropertyChanged(property.PropertyName); + property.PropertyChanged?.Invoke(this, original, newValue); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + BindablePropertyContext CreateAndAddContext(BindableProperty property) + { + var context = new BindablePropertyContext { Property = property, Value = property.DefaultValueCreator != null ? property.DefaultValueCreator(this) : property.DefaultValue }; + + if (property.DefaultValueCreator == null) + context.Attributes = BindableContextAttributes.IsDefaultValue; + else + context.Attributes = BindableContextAttributes.IsDefaultValueCreated; + + _properties.Add(context); + return context; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + BindablePropertyContext GetContext(BindableProperty property) + { + List properties = _properties; + + for (var i = 0; i < properties.Count; i++) + { + BindablePropertyContext context = properties[i]; + if (ReferenceEquals(context.Property, property)) + return context; + } + + return null; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + BindablePropertyContext GetOrCreateContext(BindableProperty property) + { + BindablePropertyContext context = GetContext(property); + if (context == null) + { + context = CreateAndAddContext(property); + } + else if (property.DefaultValueCreator != null ) + { + context.Value = property.DefaultValueCreator(this); //Update Value from dali + }//added by xb.teng + + return context; + } + + void RemoveBinding(BindableProperty property, BindablePropertyContext context) + { + context.Binding.Unapply(); + + property.BindingChanging?.Invoke(this, context.Binding, null); + + context.Binding = null; + } + + void SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess) + { + if (property == null) + throw new ArgumentNullException("property"); + + if (checkAccess && property.IsReadOnly) + throw new InvalidOperationException(string.Format("The BindableProperty \"{0}\" is readonly.", property.PropertyName)); + + if (fromStyle && !CanBeSetFromStyle(property)) + return; + + SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource, + (fromStyle ? SetValuePrivateFlags.FromStyle : SetValuePrivateFlags.ManuallySet) | (checkAccess ? SetValuePrivateFlags.CheckAccess : 0), + false); + } + + void SetValueActual(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, bool forceSendChangeSignal, SetValueFlags attributes, bool silent = false) + { + object original = context.Value; + bool raiseOnEqual = (attributes & SetValueFlags.RaiseOnEqual) != 0; + bool clearDynamicResources = (attributes & SetValueFlags.ClearDynamicResource) != 0; + bool clearOneWayBindings = (attributes & SetValueFlags.ClearOneWayBindings) != 0; + bool clearTwoWayBindings = (attributes & SetValueFlags.ClearTwoWayBindings) != 0; + + bool same = ReferenceEquals(context.Property, BindingContextProperty) ? ReferenceEquals(value, original) : Equals(value, original); + if (!silent && (!same || raiseOnEqual)) + { + property.PropertyChanging?.Invoke(this, original, value); + + OnPropertyChanging(property.PropertyName); + } + + if (!same || raiseOnEqual) + { + context.Value = value; + } + + context.Attributes &= ~BindableContextAttributes.IsDefaultValue; + context.Attributes &= ~BindableContextAttributes.IsDefaultValueCreated; + + if ((context.Attributes & BindableContextAttributes.IsDynamicResource) != 0 && clearDynamicResources) + RemoveDynamicResource(property); + + BindingBase binding = context.Binding; + if (binding != null) + { + if (clearOneWayBindings && binding.GetRealizedMode(property) == BindingMode.OneWay || clearTwoWayBindings && binding.GetRealizedMode(property) == BindingMode.TwoWay) + { + RemoveBinding(property, context); + binding = null; + } + } + + if (!silent) + { + if ((!same || raiseOnEqual)) + { + property.PropertyChanged?.Invoke(this, original, value); + + if (binding != null && !currentlyApplying) + { + _applying = true; + binding.Apply(true); + _applying = false; + } + + OnPropertyChanged(property.PropertyName); + } + else if (true == same && true == forceSendChangeSignal) + { + if (binding != null && !currentlyApplying) + { + _applying = true; + binding.Apply(true); + _applying = false; + } + + OnPropertyChanged(property.PropertyName); + } + } + } + + [Flags] + enum BindableContextAttributes + { + IsManuallySet = 1 << 0, + IsBeingSet = 1 << 1, + IsDynamicResource = 1 << 2, + IsSetFromStyle = 1 << 3, + IsDefaultValue = 1 << 4, + IsDefaultValueCreated = 1 << 5, + } + + class BindablePropertyContext + { + public BindableContextAttributes Attributes; + public BindingBase Binding; + public Queue DelayedSetters; + public BindableProperty Property; + public object Value; + } + + [Flags] + internal enum SetValuePrivateFlags + { + None = 0, + CheckAccess = 1 << 0, + Silent = 1 << 1, + ManuallySet = 1 << 2, + FromStyle = 1 << 3, + Converted = 1 << 4, + Default = CheckAccess + } + + class SetValueArgs + { + public readonly SetValueFlags Attributes; + public readonly BindablePropertyContext Context; + public readonly bool CurrentlyApplying; + public readonly BindableProperty Property; + public readonly object Value; + + public SetValueArgs(BindableProperty property, BindablePropertyContext context, object value, bool currentlyApplying, SetValueFlags attributes) + { + Property = property; + Context = context; + Value = value; + CurrentlyApplying = currentlyApplying; + Attributes = attributes; + } + } + } +} + +namespace Tizen.NUI.Binding.Internals +{ + /// + /// SetValueFlags. For internal use. + /// + [Flags] + [EditorBrowsable(EditorBrowsableState.Never)] + public enum SetValueFlags + { + /// + /// None. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + None = 0, + + /// + /// Clear OneWay bindings. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + ClearOneWayBindings = 1 << 0, + + /// + /// Clear TwoWay bindings. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + ClearTwoWayBindings = 1 << 1, + + /// + /// Clear dynamic resource. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + ClearDynamicResource = 1 << 2, + + /// + /// Raise or equal. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + RaiseOnEqual = 1 << 3 + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableProperty.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableProperty.cs new file mode 100755 index 0000000..4feb5be --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindableProperty.cs @@ -0,0 +1,550 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Reflection; +using System.ComponentModel; +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding +{ + /// + /// A BindableProperty is a backing store for properties allowing bindings on BindableObject. + /// + [DebuggerDisplay("{PropertyName}")] + [EditorBrowsable(EditorBrowsableState.Never)] + internal sealed class BindableProperty + { + /// + /// Delegate for BindableProperty.PropertyChanged. + /// + /// The bindable object that contains the property. + /// The old property value. + /// The new property value. + public delegate void BindingPropertyChangedDelegate(BindableObject bindable, object oldValue, object newValue); + + /// + /// Strongly-typed delegate for BindableProperty.PropertyChanged. + /// + /// The type of the bound property. + /// The bindable object that contains the property. + /// The old property value. + /// The new property value. + public delegate void BindingPropertyChangedDelegate(BindableObject bindable, TPropertyType oldValue, TPropertyType newValue); + + /// + /// Delegate for BindableProperty.PropertyChanging. + /// + /// The bindable object that contains the property. + /// The old property value. + /// The new property value. + public delegate void BindingPropertyChangingDelegate(BindableObject bindable, object oldValue, object newValue); + + /// + /// Strongly-typed delegate for BindableProperty.PropertyChanging. + /// + /// The type of the bound property. + /// The bindable object that contains the property. + /// The old property value. + /// The new property value. + public delegate void BindingPropertyChangingDelegate(BindableObject bindable, TPropertyType oldValue, TPropertyType newValue); + + /// + /// Delegate for BindableProperty.CoerceValue. + /// + /// The bindable object that contains the property. + /// The value to coerce. + /// System.Object + public delegate object CoerceValueDelegate(BindableObject bindable, object value); + + /// + /// Strongly-typed delegate for BindableProperty.CoerceValue. + /// + /// The type of the bound property. + /// The bindable object that contains the property. + /// The value to coerce. + /// TPropertyType + public delegate TPropertyType CoerceValueDelegate(BindableObject bindable, TPropertyType value); + + /// + /// Delegate for BindableProperty.DefaultValueCreator. + /// + /// The bindable object that contains the property. + /// System.Object + public delegate object CreateDefaultValueDelegate(BindableObject bindable); + + /// + /// Strongly-typed delegate for BindableProperty.DefaultValueCreator. + /// + /// The type of the object that delared the property. + /// The type of the bound property. + /// The bindable object that contains the property. + /// TPropertyType + public delegate TPropertyType CreateDefaultValueDelegate(TDeclarer bindable); + + /// + /// Delegate for BindableProperty.ValidateValue. + /// + /// The bindable object that contains the property. + /// The default value. + /// System.Boolean + public delegate bool ValidateValueDelegate(BindableObject bindable, object value); + + /// + /// Strongly-typed delegate for BindableProperty.ValidateValue. + /// + /// The type of the bound property. + /// The bindable object that contains the property. + /// The default value. + /// System.Boolean + public delegate bool ValidateValueDelegate(BindableObject bindable, TPropertyType value); + + static readonly Dictionary WellKnownConvertTypes = new Dictionary + { + //Fang: Wait for check + //{ typeof(Uri), new UriTypeConverter() }, + //{ typeof(Color), new ColorTypeConverter() }, + //{ typeof(Size2D), new Size2DTypeConverter() }, + //{ typeof(Position2D), new Position2DTypeConverter() }, + //{ typeof(Size), new SizeTypeConverter() }, + //{ typeof(Position), new PositionTypeConverter() }, + //{ typeof(Rectangle), new RectangleTypeConverter() }, + //{ typeof(Rotation), new RotationTypeConverter() }, + //{ typeof(Thickness), new ThicknessTypeConverter() }, + //{ typeof(Vector2), new Vector2TypeConverter() }, + //{ typeof(Vector3), new Vector3TypeConverter() }, + //{ typeof(Vector4), new Vector4TypeConverter() }, + //{ typeof(RelativeVector2), new RelativeVector2TypeConverter() }, + //{ typeof(RelativeVector3), new RelativeVector3TypeConverter() }, + //{ typeof(RelativeVector4), new RelativeVector4TypeConverter() }, + }; + + // more or less the encoding of this, without the need to reflect + // http://msdn.microsoft.com/en-us/library/y5b434w4.aspx + static readonly Dictionary SimpleConvertTypes = new Dictionary + { + { typeof(sbyte), new[] { typeof(string), typeof(short), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(byte), new[] { typeof(string), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(short), new[] { typeof(string), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(ushort), new[] { typeof(string), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(int), new[] { typeof(string), typeof(long), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(uint), new[] { typeof(string), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(long), new[] { typeof(string), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(char), new[] { typeof(string), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } }, + { typeof(float), new[] { typeof(string), typeof(double) } }, + { typeof(ulong), new[] { typeof(string), typeof(float), typeof(double), typeof(decimal) } } + }; + + BindableProperty(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay, + ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null, + CoerceValueDelegate coerceValue = null, BindablePropertyBindingChanging bindingChanging = null, bool isReadOnly = false, CreateDefaultValueDelegate defaultValueCreator = null) + { + if (propertyName == null) + throw new ArgumentNullException("propertyName"); + if (ReferenceEquals(returnType, null)) + throw new ArgumentNullException("returnType"); + if (ReferenceEquals(declaringType, null)) + throw new ArgumentNullException("declaringType"); + + // don't use Enum.IsDefined as its redonkulously expensive for what it does + if (defaultBindingMode != BindingMode.Default && defaultBindingMode != BindingMode.OneWay && defaultBindingMode != BindingMode.OneWayToSource && defaultBindingMode != BindingMode.TwoWay && defaultBindingMode != BindingMode.OneTime) + throw new ArgumentException("Not a valid type of BindingMode", "defaultBindingMode"); + if (defaultValue == null && Nullable.GetUnderlyingType(returnType) == null && returnType.GetTypeInfo().IsValueType) + throw new ArgumentException("Not a valid default value", "defaultValue"); + if (defaultValue != null && !returnType.IsInstanceOfType(defaultValue)) + throw new ArgumentException("Default value did not match return type", "defaultValue"); + if (defaultBindingMode == BindingMode.Default) + defaultBindingMode = BindingMode.OneWay; + + PropertyName = propertyName; + ReturnType = returnType; + ReturnTypeInfo = returnType.GetTypeInfo(); + DeclaringType = declaringType; + DefaultValue = defaultValue; + DefaultBindingMode = defaultBindingMode; + PropertyChanged = propertyChanged; + PropertyChanging = propertyChanging; + ValidateValue = validateValue; + CoerceValue = coerceValue; + BindingChanging = bindingChanging; + IsReadOnly = isReadOnly; + DefaultValueCreator = defaultValueCreator; + } + + /// + /// Gets the type declaring the BindableProperty. + /// + public Type DeclaringType { get; private set; } + + /// + /// Gets the default BindingMode. + /// + public BindingMode DefaultBindingMode { get; private set; } + + /// + /// Gets the default value for the BindableProperty. + /// + public object DefaultValue { get; } + + /// + /// Gets a value indicating if the BindableProperty is created form a BindablePropertyKey. + /// + public bool IsReadOnly { get; private set; } + + /// + /// Gets the property name. + /// + public string PropertyName { get; } + + /// + /// Gets the type of the BindableProperty. + /// + public Type ReturnType { get; } + + internal BindablePropertyBindingChanging BindingChanging { get; private set; } + + internal CoerceValueDelegate CoerceValue { get; private set; } + + internal CreateDefaultValueDelegate DefaultValueCreator { get; } + + internal BindingPropertyChangedDelegate PropertyChanged { get; private set; } + + internal BindingPropertyChangingDelegate PropertyChanging { get; private set; } + + internal System.Reflection.TypeInfo ReturnTypeInfo { get; } + + internal ValidateValueDelegate ValidateValue { get; private set; } + + /// + /// Deprecated. Do not use. + /// + /// The type of the declaring object. + /// The type of the property. + /// An expression identifying the getter for the property using this BindableProperty as backing store. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + /// A newly created BindableProperty. + [Obsolete("Create<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")] + public static BindableProperty Create(Expression> getter, TPropertyType defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay, + ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, + BindingPropertyChangingDelegate propertyChanging = null, CoerceValueDelegate coerceValue = null, + CreateDefaultValueDelegate defaultValueCreator = null) where TDeclarer : BindableObject + { + return Create(getter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, defaultValueCreator: defaultValueCreator); + } + + /// + /// Creates a new instance of the BindableProperty class. + /// + /// The name of the BindableProperty. + /// The type of the property. + /// The type of the declaring object. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + /// A newly created BindableProperty. + public static BindableProperty Create(string propertyName, Type returnType, Type declaringType, object defaultValue = null, BindingMode defaultBindingMode = BindingMode.OneWay, + ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null, + CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null) + { + return new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, + defaultValueCreator: defaultValueCreator); + } + + /// + /// Deprecated. Do not use. + /// + /// The type of the declaring object. + /// The type of the property. + /// An expression identifying a static method returning the value of the property using this BindableProperty as backing store. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + [Obsolete("CreateAttached<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")] + public static BindableProperty CreateAttached(Expression> staticgetter, TPropertyType defaultValue, + BindingMode defaultBindingMode = BindingMode.OneWay, ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, + BindingPropertyChangingDelegate propertyChanging = null, CoerceValueDelegate coerceValue = null, + CreateDefaultValueDelegate defaultValueCreator = null) + { + return CreateAttached(staticgetter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, + defaultValueCreator: defaultValueCreator); + } + + /// + /// Creates a new instance of the BindableProperty class for an attached property. + /// + /// The name of the BindableProperty. + /// The type of the property. + /// The type of the declaring object. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + /// A newly created BindableProperty. + public static BindableProperty CreateAttached(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay, + ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null, + CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null) + { + return CreateAttached(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, false, defaultValueCreator); + } + + /// + /// Deprecated. Do not use. + /// + /// The type of the declaring object. + /// The type of the property. + /// An expression identifying a static method returning the value of the property using this BindableProperty as backing store. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + /// A newly created attached read-only BindablePropertyKey. + [Obsolete("CreateAttachedReadOnly<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")] + public static BindablePropertyKey CreateAttachedReadOnly(Expression> staticgetter, TPropertyType defaultValue, + BindingMode defaultBindingMode = BindingMode.OneWayToSource, ValidateValueDelegate validateValue = null, + BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null, + CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null) + + { + return + new BindablePropertyKey(CreateAttached(staticgetter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, true, + defaultValueCreator)); + } + + /// + /// Creates a new instance of the BindableProperty class for attached read-only properties. + /// + /// The name of the BindableProperty. + /// The type of the property. + /// The type of the declaring object. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + /// A newly created attached read-only BindablePropertyKey. + public static BindablePropertyKey CreateAttachedReadOnly(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWayToSource, + ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null, + CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null) + { + return + new BindablePropertyKey(CreateAttached(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, true, + defaultValueCreator)); + } + + /// + /// Deprecated. Do not use. + /// + /// The type of the declaring object. + /// The type of the property. + /// An expression identifying the getter for the property using this BindableProperty as backing store. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + /// A newly created BindablePropertyKey. + [Obsolete("CreateReadOnly<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")] + public static BindablePropertyKey CreateReadOnly(Expression> getter, TPropertyType defaultValue, + BindingMode defaultBindingMode = BindingMode.OneWayToSource, ValidateValueDelegate validateValue = null, + BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null, + CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null) where TDeclarer : BindableObject + { + return new BindablePropertyKey(Create(getter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, true, defaultValueCreator)); + } + + /// + /// Creates a new instance of the BindablePropertyKey class. + /// + /// The name of the BindableProperty. + /// The type of the property. + /// The type of the declaring object. + /// The default value for the property. + /// The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay. + /// A delegate to be run when a value is set. This parameter is optional. Default is null. + /// A delegate to be run when the value has changed. This parameter is optional. Default is null. + /// A delegate to be run when the value will change. This parameter is optional. Default is null. + /// A delegate used to coerce the range of a value. This parameter is optional. Default is null. + /// A Func used to initialize default value for reference types. + /// A newly created BindablePropertyKey. + public static BindablePropertyKey CreateReadOnly(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWayToSource, + ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null, + CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null) + { + return + new BindablePropertyKey(new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, + isReadOnly: true, defaultValueCreator: defaultValueCreator)); + } + + [Obsolete("Create<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")] + internal static BindableProperty Create(Expression> getter, TPropertyType defaultValue, BindingMode defaultBindingMode, + ValidateValueDelegate validateValue, BindingPropertyChangedDelegate propertyChanged, BindingPropertyChangingDelegate propertyChanging, + CoerceValueDelegate coerceValue, BindablePropertyBindingChanging bindingChanging, bool isReadOnly = false, + CreateDefaultValueDelegate defaultValueCreator = null) where TDeclarer : BindableObject + { + if (getter == null) + throw new ArgumentNullException("getter"); + + Expression expr = getter.Body; + + var unary = expr as UnaryExpression; + if (unary != null) + expr = unary.Operand; + + var member = expr as MemberExpression; + if (member == null) + throw new ArgumentException("getter must be a MemberExpression", "getter"); + + var property = (PropertyInfo)member.Member; + + ValidateValueDelegate untypedValidateValue = null; + BindingPropertyChangedDelegate untypedBindingPropertyChanged = null; + BindingPropertyChangingDelegate untypedBindingPropertyChanging = null; + CoerceValueDelegate untypedCoerceValue = null; + CreateDefaultValueDelegate untypedDefaultValueCreator = null; + if (validateValue != null) + untypedValidateValue = (bindable, value) => validateValue(bindable, (TPropertyType)value); + if (propertyChanged != null) + untypedBindingPropertyChanged = (bindable, oldValue, newValue) => propertyChanged(bindable, (TPropertyType)oldValue, (TPropertyType)newValue); + if (propertyChanging != null) + untypedBindingPropertyChanging = (bindable, oldValue, newValue) => propertyChanging(bindable, (TPropertyType)oldValue, (TPropertyType)newValue); + if (coerceValue != null) + untypedCoerceValue = (bindable, value) => coerceValue(bindable, (TPropertyType)value); + if (defaultValueCreator != null) + untypedDefaultValueCreator = o => defaultValueCreator((TDeclarer)o); + + return new BindableProperty(property.Name, property.PropertyType, typeof(TDeclarer), defaultValue, defaultBindingMode, untypedValidateValue, untypedBindingPropertyChanged, + untypedBindingPropertyChanging, untypedCoerceValue, bindingChanging, isReadOnly, untypedDefaultValueCreator); + } + + internal static BindableProperty Create(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode, ValidateValueDelegate validateValue, + BindingPropertyChangedDelegate propertyChanged, BindingPropertyChangingDelegate propertyChanging, CoerceValueDelegate coerceValue, BindablePropertyBindingChanging bindingChanging, + CreateDefaultValueDelegate defaultValueCreator = null) + { + return new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, bindingChanging, + defaultValueCreator: defaultValueCreator); + } + + [Obsolete("CreateAttached<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")] + internal static BindableProperty CreateAttached(Expression> staticgetter, TPropertyType defaultValue, BindingMode defaultBindingMode, + ValidateValueDelegate validateValue, BindingPropertyChangedDelegate propertyChanged, BindingPropertyChangingDelegate propertyChanging, + CoerceValueDelegate coerceValue, BindablePropertyBindingChanging bindingChanging, bool isReadOnly = false, + CreateDefaultValueDelegate defaultValueCreator = null) + { + if (staticgetter == null) + throw new ArgumentNullException("staticgetter"); + + Expression expr = staticgetter.Body; + + var unary = expr as UnaryExpression; + if (unary != null) + expr = unary.Operand; + + var methodcall = expr as MethodCallExpression; + if (methodcall == null) + throw new ArgumentException("staticgetter must be a MethodCallExpression", "staticgetter"); + + MethodInfo method = methodcall.Method; + if (!method.Name.StartsWith("Get", StringComparison.Ordinal)) + throw new ArgumentException("staticgetter name must start with Get", "staticgetter"); + + string propertyname = method.Name.Substring(3); + + ValidateValueDelegate untypedValidateValue = null; + BindingPropertyChangedDelegate untypedBindingPropertyChanged = null; + BindingPropertyChangingDelegate untypedBindingPropertyChanging = null; + CoerceValueDelegate untypedCoerceValue = null; + CreateDefaultValueDelegate untypedDefaultValueCreator = null; + if (validateValue != null) + untypedValidateValue = (bindable, value) => validateValue(bindable, (TPropertyType)value); + if (propertyChanged != null) + untypedBindingPropertyChanged = (bindable, oldValue, newValue) => propertyChanged(bindable, (TPropertyType)oldValue, (TPropertyType)newValue); + if (propertyChanging != null) + untypedBindingPropertyChanging = (bindable, oldValue, newValue) => propertyChanging(bindable, (TPropertyType)oldValue, (TPropertyType)newValue); + if (coerceValue != null) + untypedCoerceValue = (bindable, value) => coerceValue(bindable, (TPropertyType)value); + if (defaultValueCreator != null) + untypedDefaultValueCreator = o => defaultValueCreator(o); + + return new BindableProperty(propertyname, method.ReturnType, typeof(TDeclarer), defaultValue, defaultBindingMode, untypedValidateValue, untypedBindingPropertyChanged, untypedBindingPropertyChanging, + untypedCoerceValue, bindingChanging, isReadOnly, untypedDefaultValueCreator); + } + + internal static BindableProperty CreateAttached(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode, ValidateValueDelegate validateValue, + BindingPropertyChangedDelegate propertyChanged, BindingPropertyChangingDelegate propertyChanging, CoerceValueDelegate coerceValue, BindablePropertyBindingChanging bindingChanging, + bool isReadOnly, CreateDefaultValueDelegate defaultValueCreator = null) + { + return new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, bindingChanging, isReadOnly, + defaultValueCreator); + } + + internal object GetDefaultValue(BindableObject bindable) + { + if (DefaultValueCreator != null) + return DefaultValueCreator(bindable); + + return DefaultValue; + } + + internal bool TryConvert(ref object value) + { + if (value == null) + { + return !ReturnTypeInfo.IsValueType || ReturnTypeInfo.IsGenericType && ReturnTypeInfo.GetGenericTypeDefinition() == typeof(Nullable<>); + } + + Type valueType = value.GetType(); + Type type = ReturnType; + + // Dont support arbitrary IConvertible by limiting which types can use this + Type[] convertableTo; + TypeConverter typeConverterTo; + if (SimpleConvertTypes.TryGetValue(valueType, out convertableTo) && Array.IndexOf(convertableTo, type) != -1) + { + value = Convert.ChangeType(value, type); + } + else if (WellKnownConvertTypes.TryGetValue(type, out typeConverterTo) && typeConverterTo.CanConvertFrom(valueType)) + { + value = typeConverterTo.ConvertFromInvariantString(value.ToString()); + } + else if (!ReturnTypeInfo.IsAssignableFrom(valueType.GetTypeInfo())) + { + var cast = type.GetImplicitConversionOperator(fromType: valueType, toType: type) + ?? valueType.GetImplicitConversionOperator(fromType: valueType, toType: type); + + if (cast == null) + return false; + + value = cast.Invoke(null, new[] { value }); + } + + return true; + } + + internal delegate void BindablePropertyBindingChanging(BindableObject bindable, BindingBase oldValue, BindingBase newValue); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindablePropertyKey.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindablePropertyKey.cs new file mode 100755 index 0000000..60df089 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindablePropertyKey.cs @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + /// + /// The secret key to a BindableProperty, used to implement a BindableProperty with restricted write access. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal sealed class BindablePropertyKey + { + internal BindablePropertyKey(BindableProperty property) + { + if (property == null) + throw new ArgumentNullException("property"); + + BindableProperty = property; + } + + /// + /// Gets the BindableProperty. + /// + public BindableProperty BindableProperty { get; private set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Binding.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Binding.cs new file mode 100755 index 0000000..4fe9658 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Binding.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + internal sealed class Binding : BindingBase + { + internal const string SelfPath = "."; + IValueConverter _converter; + object _converterParameter; + + BindingExpression _expression; + string _path; + object _source; + string _updateSourceEventName; + + public Binding() + { + } + + public Binding(string path, BindingMode mode = BindingMode.Default, IValueConverter converter = null, object converterParameter = null, string stringFormat = null, object source = null) + { + if (path == null) + throw new ArgumentNullException("path"); + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentException("path can not be an empty string", "path"); + + Path = path; + Converter = converter; + ConverterParameter = converterParameter; + Mode = mode; + StringFormat = stringFormat; + Source = source; + } + + public IValueConverter Converter + { + get { return _converter; } + set + { + ThrowIfApplied(); + + _converter = value; + } + } + + public object ConverterParameter + { + get { return _converterParameter; } + set + { + ThrowIfApplied(); + + _converterParameter = value; + } + } + + public string Path + { + get { return _path; } + set + { + ThrowIfApplied(); + + _path = value; + _expression = new BindingExpression(this, !string.IsNullOrWhiteSpace(value) ? value : SelfPath); + } + } + + public object Source + { + get { return _source; } + set + { + ThrowIfApplied(); + _source = value; + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public string UpdateSourceEventName { + get { return _updateSourceEventName; } + set { + ThrowIfApplied(); + _updateSourceEventName = value; + } + } + + [Obsolete] + public static Binding Create(Expression> propertyGetter, BindingMode mode = BindingMode.Default, IValueConverter converter = null, object converterParameter = null, + string stringFormat = null) + { + if (propertyGetter == null) + throw new ArgumentNullException("propertyGetter"); + + return new Binding(GetBindingPath(propertyGetter), mode, converter, converterParameter, stringFormat); + } + + internal override void Apply(bool fromTarget) + { + base.Apply(fromTarget); + + if (_expression == null) + _expression = new BindingExpression(this, SelfPath); + + _expression.Apply(fromTarget); + } + + internal override void Apply(object newContext, BindableObject bindObj, BindableProperty targetProperty, bool fromBindingContextChanged = false) + { + object src = _source; + var isApplied = IsApplied; + + base.Apply(src ?? newContext, bindObj, targetProperty, fromBindingContextChanged: fromBindingContextChanged); + + if (src != null && isApplied && fromBindingContextChanged) + return; + + object bindingContext = src ?? Context ?? newContext; + if (_expression == null && bindingContext != null) + _expression = new BindingExpression(this, SelfPath); + + _expression?.Apply(bindingContext, bindObj, targetProperty); + } + + internal override BindingBase Clone() + { + return new Binding(Path, Mode) { Converter = Converter, ConverterParameter = ConverterParameter, StringFormat = StringFormat, Source = Source, UpdateSourceEventName = UpdateSourceEventName }; + } + + internal override object GetSourceValue(object value, Type targetPropertyType) + { + if (Converter != null) + value = Converter.Convert(value, targetPropertyType, ConverterParameter, CultureInfo.CurrentUICulture); + + return base.GetSourceValue(value, targetPropertyType); + } + + internal override object GetTargetValue(object value, Type sourcePropertyType) + { + if (Converter != null) + value = Converter.ConvertBack(value, sourcePropertyType, ConverterParameter, CultureInfo.CurrentUICulture); + + return base.GetTargetValue(value, sourcePropertyType); + } + + internal override void Unapply(bool fromBindingContextChanged = false) + { + if (Source != null && fromBindingContextChanged && IsApplied) + return; + + base.Unapply(fromBindingContextChanged: fromBindingContextChanged); + + if (_expression != null) + _expression.Unapply(); + } + + [Obsolete] + static string GetBindingPath(Expression> propertyGetter) + { + Expression expr = propertyGetter.Body; + + var unary = expr as UnaryExpression; + if (unary != null) + expr = unary.Operand; + + var builder = new StringBuilder(); + + var indexed = false; + + var member = expr as MemberExpression; + if (member == null) + { + var methodCall = expr as MethodCallExpression; + if (methodCall != null) + { + if (methodCall.Arguments.Count == 0) + throw new ArgumentException("Method calls are not allowed in binding expression"); + + var arguments = new List(methodCall.Arguments.Count); + foreach (Expression arg in methodCall.Arguments) + { + if (arg.NodeType != ExpressionType.Constant) + throw new ArgumentException("Only constants can be used as indexer arguments"); + + object value = ((ConstantExpression)arg).Value; + arguments.Add(value != null ? value.ToString() : "null"); + } + + Type declarerType = methodCall.Method.DeclaringType; + DefaultMemberAttribute defaultMember = declarerType.GetTypeInfo().GetCustomAttributes(typeof(DefaultMemberAttribute), true).OfType().FirstOrDefault(); + string indexerName = defaultMember != null ? defaultMember.MemberName : "Item"; + + MethodInfo getterInfo = + declarerType.GetProperties().Where(pi => pi.Name == indexerName && pi.CanRead && pi.GetMethod.IsPublic && !pi.GetMethod.IsStatic).Select(pi => pi.GetMethod).FirstOrDefault(); + if (getterInfo != null) + { + if (getterInfo == methodCall.Method) + { + indexed = true; + builder.Append("["); + + var first = true; + foreach (string argument in arguments) + { + if (!first) + builder.Append(","); + + builder.Append(argument); + first = false; + } + + builder.Append("]"); + + member = methodCall.Object as MemberExpression; + } + else + throw new ArgumentException("Method calls are not allowed in binding expressions"); + } + else + throw new ArgumentException("Public indexer not found"); + } + else + throw new ArgumentException("Invalid expression type"); + } + + while (member != null) + { + var property = (PropertyInfo)member.Member; + if (builder.Length != 0) + { + if (!indexed) + builder.Insert(0, "."); + else + indexed = false; + } + + builder.Insert(0, property.Name); + + //member = member.Expression as MemberExpression ?? (member.Expression as UnaryExpression)?.Operand as MemberExpression; + member = member.Expression as MemberExpression ?? (member.Expression is UnaryExpression ? (member.Expression as UnaryExpression).Operand as MemberExpression : null); + } + + return builder.ToString(); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBase.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBase.cs new file mode 100755 index 0000000..e6b40b4 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBase.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections; +using System.Runtime.CompilerServices; +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + /// + /// An abstract class that provides a BindingMode and a formatting option. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal abstract class BindingBase + { + static readonly ConditionalWeakTable SynchronizedCollections = new ConditionalWeakTable(); + + BindingMode _mode = BindingMode.Default; + string _stringFormat; + object _targetNullValue; + object _fallbackValue; + + internal BindingBase() + { + } + + /// + /// Gets or sets the mode for this binding. + /// + public BindingMode Mode + { + get { return _mode; } + set + { + if ( value != BindingMode.Default + && value != BindingMode.OneWay + && value != BindingMode.OneWayToSource + && value != BindingMode.TwoWay + && value != BindingMode.OneTime) + throw new ArgumentException("mode is not a valid BindingMode", "mode"); + + ThrowIfApplied(); + + _mode = value; + } + } + + /// + /// Gets or sets the string format for this binding. + /// + public string StringFormat + { + get { return _stringFormat; } + set + { + ThrowIfApplied(); + + _stringFormat = value; + } + } + + public object TargetNullValue + { + get { return _targetNullValue; } + set { + ThrowIfApplied(); + _targetNullValue = value; + } + } + + public object FallbackValue { + get => _fallbackValue; + set { + ThrowIfApplied(); + _fallbackValue = value; + } + } + + internal bool AllowChaining { get; set; } + + internal object Context { get; set; } + + internal bool IsApplied { get; private set; } + + /// + /// Stops synchronization on the collection. + /// + /// The collection on which to stop synchronization. + public static void DisableCollectionSynchronization(IEnumerable collection) + { + if (collection == null) + throw new ArgumentNullException(nameof(collection)); + + SynchronizedCollections.Remove(collection); + } + + public static void EnableCollectionSynchronization(IEnumerable collection, object context, CollectionSynchronizationCallback callback) + { + if (collection == null) + throw new ArgumentNullException(nameof(collection)); + if (callback == null) + throw new ArgumentNullException(nameof(callback)); + + SynchronizedCollections.Add(collection, new CollectionSynchronizationContext(context, callback)); + } + + /// + /// Throws an InvalidOperationException if the binding has been applied. + /// + protected void ThrowIfApplied() + { + if (IsApplied) + throw new InvalidOperationException("Can not change a binding while it's applied"); + } + + internal virtual void Apply(bool fromTarget) + { + IsApplied = true; + } + + internal virtual void Apply(object context, BindableObject bindObj, BindableProperty targetProperty, bool fromBindingContextChanged = false) + { + IsApplied = true; + } + + internal abstract BindingBase Clone(); + + internal virtual object GetSourceValue(object value, Type targetPropertyType) + { + if (value == null && TargetNullValue != null) + return TargetNullValue; + if (StringFormat != null) + return string.Format(StringFormat, value); + + return value; + } + + internal virtual object GetTargetValue(object value, Type sourcePropertyType) + { + return value; + } + + internal static bool TryGetSynchronizedCollection(IEnumerable collection, out CollectionSynchronizationContext synchronizationContext) + { + if (collection == null) + throw new ArgumentNullException(nameof(collection)); + + return SynchronizedCollections.TryGetValue(collection, out synchronizationContext); + } + + internal virtual void Unapply(bool fromBindingContextChanged = false) + { + IsApplied = false; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBaseExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBaseExtensions.cs new file mode 100755 index 0000000..3a637fa --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingBaseExtensions.cs @@ -0,0 +1,12 @@ +using System; + +namespace Tizen.NUI.Binding +{ + internal static class BindingBaseExtensions + { + public static BindingMode GetRealizedMode(this BindingBase self, BindableProperty property) + { + return self.Mode != BindingMode.Default ? self.Mode : property.DefaultBindingMode; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingExpression.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingExpression.cs new file mode 100755 index 0000000..c4dd7f6 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingExpression.cs @@ -0,0 +1,644 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Reflection; +using Tizen.NUI.Binding.Internals; +using System.Runtime.CompilerServices; + +namespace Tizen.NUI.Binding +{ + internal class BindingExpression + { + internal const string PropertyNotFoundErrorMessage = "'{0}' property not found on '{1}', target property: '{2}.{3}'"; + + readonly List _parts = new List(); + + BindableProperty _targetProperty; + WeakReference _weakSource; + WeakReference _weakTarget; + + internal BindingExpression(BindingBase binding, string path) + { + if (binding == null) + throw new ArgumentNullException(nameof(binding)); + if (path == null) + throw new ArgumentNullException(nameof(path)); + + Binding = binding; + Path = path; + + ParsePath(); + } + + internal BindingBase Binding { get; } + + internal string Path { get; } + + /// + /// Applies the binding expression to a previously set source and target. + /// + internal void Apply(bool fromTarget = false) + { + if (_weakSource == null || _weakTarget == null) + return; + + BindableObject target; + if (!_weakTarget.TryGetTarget(out target)) + { + Unapply(); + return; + } + + object source; + if (_weakSource.TryGetTarget(out source) && _targetProperty != null) + ApplyCore(source, target, _targetProperty, fromTarget); + } + + /// + /// Applies the binding expression to a new source or target. + /// + internal void Apply(object sourceObject, BindableObject target, BindableProperty property) + { + _targetProperty = property; + + BindableObject prevTarget; + if (_weakTarget != null && _weakTarget.TryGetTarget(out prevTarget) && !ReferenceEquals(prevTarget, target)) + throw new InvalidOperationException("Binding instances can not be reused"); + + object previousSource; + if (_weakSource != null && _weakSource.TryGetTarget(out previousSource) && !ReferenceEquals(previousSource, sourceObject)) + throw new InvalidOperationException("Binding instances can not be reused"); + + _weakSource = new WeakReference(sourceObject); + _weakTarget = new WeakReference(target); + + ApplyCore(sourceObject, target, property); + } + + internal void Unapply() + { + object sourceObject; + if (_weakSource != null && _weakSource.TryGetTarget(out sourceObject)) + { + for (var i = 0; i < _parts.Count - 1; i++) + { + BindingExpressionPart part = _parts[i]; + + if (!part.IsSelf) + { + part.TryGetValue(sourceObject, out sourceObject); + } + + part.Unsubscribe(); + } + } + + _weakSource = null; + _weakTarget = null; + } + + /// + /// Applies the binding expression to a previously set source or target. + /// + void ApplyCore(object sourceObject, BindableObject target, BindableProperty property, bool fromTarget = false) + { + BindingMode mode = Binding.GetRealizedMode(_targetProperty); + if ((mode == BindingMode.OneWay || mode == BindingMode.OneTime) && fromTarget) + return; + + bool needsGetter = (mode == BindingMode.TwoWay && !fromTarget) || mode == BindingMode.OneWay || mode == BindingMode.OneTime; + bool needsSetter = !needsGetter && ((mode == BindingMode.TwoWay && fromTarget) || mode == BindingMode.OneWayToSource); + + object current = sourceObject; + object previous = null; + BindingExpressionPart part = null; + + for (var i = 0; i < _parts.Count; i++) + { + part = _parts[i]; + bool isLast = i + 1 == _parts.Count; + + if (!part.IsSelf && current != null) + { + // Allow the object instance itself to provide its own TypeInfo + var reflectable = current as IReflectableType; + System.Reflection.TypeInfo currentType = reflectable != null ? reflectable.GetTypeInfo() : current.GetType().GetTypeInfo(); + if (part.LastGetter == null || !part.LastGetter.DeclaringType.GetTypeInfo().IsAssignableFrom(currentType)) + SetupPart(currentType, part); + + if (!isLast) + part.TryGetValue(current, out current); + } + + if (!part.IsSelf && current != null) + { + if ((needsGetter && part.LastGetter == null) || (needsSetter && part.NextPart == null && part.LastSetter == null)) + { + Console.WriteLine("Binding", PropertyNotFoundErrorMessage, part.Content, current, target.GetType(), property.PropertyName); + break; + } + } + + if (mode == BindingMode.OneWay || mode == BindingMode.TwoWay) + { + var inpc = current as INotifyPropertyChanged; + if (inpc != null && !ReferenceEquals(current, previous)) + part.Subscribe(inpc); + } + + previous = current; + } + + Debug.Assert(part != null, "There should always be at least the self part in the expression."); + + if (needsGetter) + { + object value = property.DefaultValue; + if (part.TryGetValue(current, out value) || part.IsSelf) + { + value = Binding.GetSourceValue(value, property.ReturnType); + } + else + value = property.DefaultValue; + + if (!TryConvert(part, ref value, property.ReturnType, true)) + { + Console.WriteLine("Binding", "{0} can not be converted to type '{1}'", value, property.ReturnType); + return; + } + + target.SetValueCore(property, value, SetValueFlags.ClearDynamicResource, BindableObject.SetValuePrivateFlags.Default | BindableObject.SetValuePrivateFlags.Converted, false); + } + else if (needsSetter && part.LastSetter != null && current != null) + { + object value = Binding.GetTargetValue(target.GetValue(property), part.SetterType); + + if (!TryConvert(part, ref value, part.SetterType, false)) + { + Console.WriteLine("Binding", "{0} can not be converted to type '{1}'", value, part.SetterType); + return; + } + + object[] args; + if (part.IsIndexer) + { + args = new object[part.Arguments.Length + 1]; + part.Arguments.CopyTo(args, 0); + args[args.Length - 1] = value; + } + else if (part.IsBindablePropertySetter) + { + args = new[] { part.BindablePropertyField, value }; + } + else + { + args = new[] { value }; + } + + part.LastSetter.Invoke(current, args); + } + } + + IEnumerable GetPart(string part) + { + part = part.Trim(); + if (part == string.Empty) + throw new FormatException("Path contains an empty part"); + + BindingExpressionPart indexer = null; + + int lbIndex = part.IndexOf('['); + if (lbIndex != -1) + { + int rbIndex = part.LastIndexOf(']'); + if (rbIndex == -1) + throw new FormatException("Indexer did not contain closing bracket"); + + int argLength = rbIndex - lbIndex - 1; + if (argLength == 0) + throw new FormatException("Indexer did not contain arguments"); + + string argString = part.Substring(lbIndex + 1, argLength); + indexer = new BindingExpressionPart(this, argString, true); + + part = part.Substring(0, lbIndex); + part = part.Trim(); + } + + if (part.Length > 0) + yield return new BindingExpressionPart(this, part); + if (indexer != null) + yield return indexer; + } + + void ParsePath() + { + string p = Path.Trim(); + + var last = new BindingExpressionPart(this, "."); + _parts.Add(last); + + if (p[0] == '.') + { + if (p.Length == 1) + return; + + p = p.Substring(1); + } + + string[] pathParts = p.Split('.'); + for (var i = 0; i < pathParts.Length; i++) + { + foreach (BindingExpressionPart part in GetPart(pathParts[i])) + { + last.NextPart = part; + _parts.Add(part); + last = part; + } + } + } + + void SetupPart(System.Reflection.TypeInfo sourceType, BindingExpressionPart part) + { + part.Arguments = null; + part.LastGetter = null; + part.LastSetter = null; + + PropertyInfo property = null; + if (part.IsIndexer) + { + if (sourceType.IsArray) + { + int index; + if (!int.TryParse(part.Content, out index)) + Console.WriteLine("Binding", "{0} could not be parsed as an index for a {1}", part.Content, sourceType); + else + part.Arguments = new object[] { index }; + + part.LastGetter = sourceType.GetDeclaredMethod("Get"); + part.LastSetter = sourceType.GetDeclaredMethod("Set"); + part.SetterType = sourceType.GetElementType(); + } + + DefaultMemberAttribute defaultMember = sourceType.GetCustomAttributes(typeof(DefaultMemberAttribute), true).OfType().FirstOrDefault(); + string indexerName = defaultMember != null ? defaultMember.MemberName : "Item"; + + part.IndexerName = indexerName; + +#if NETSTANDARD2_0 + try { + property = sourceType.GetDeclaredProperty(indexerName); + } + catch (AmbiguousMatchException) { + // Get most derived instance of property + foreach (var p in sourceType.GetProperties().Where(prop => prop.Name == indexerName)) { + if (property == null || property.DeclaringType.IsAssignableFrom(property.DeclaringType)) + property = p; + } + } +#else + property = sourceType.GetDeclaredProperty(indexerName); +#endif + + if (property == null) //is the indexer defined on the base class? + property = sourceType.BaseType.GetProperty(indexerName); + if (property == null) //is the indexer defined on implemented interface ? + { + foreach (var implementedInterface in sourceType.ImplementedInterfaces) + { + property = implementedInterface.GetProperty(indexerName); + if (property != null) + break; + } + } + + if (property != null) + { + ParameterInfo parameter = property.GetIndexParameters().FirstOrDefault(); + if (parameter != null) + { + try + { + object arg = Convert.ChangeType(part.Content, parameter.ParameterType, CultureInfo.InvariantCulture); + part.Arguments = new[] { arg }; + } + catch (FormatException) + { + } + catch (InvalidCastException) + { + } + catch (OverflowException) + { + } + } + } + } + else + property = sourceType.GetDeclaredProperty(part.Content) ?? sourceType.BaseType?.GetProperty(part.Content); + + if (property != null) + { + if (property.CanRead && property.GetMethod.IsPublic && !property.GetMethod.IsStatic) + part.LastGetter = property.GetMethod; + if (property.CanWrite && property.SetMethod.IsPublic && !property.SetMethod.IsStatic) + { + part.LastSetter = property.SetMethod; + part.SetterType = part.LastSetter.GetParameters().Last().ParameterType; + + if (Binding.AllowChaining) + { + FieldInfo bindablePropertyField = sourceType.GetDeclaredField(part.Content + "Property"); + if (bindablePropertyField != null && bindablePropertyField.FieldType == typeof(BindableProperty) && sourceType.ImplementedInterfaces.Contains(typeof(IElementController))) + { + MethodInfo setValueMethod = null; +#if NETSTANDARD1_0 + foreach (MethodInfo m in sourceType.AsType().GetRuntimeMethods()) + { + if (m.Name.EndsWith("IElementController.SetValueFromRenderer")) + { + ParameterInfo[] parameters = m.GetParameters(); + if (parameters.Length == 2 && parameters[0].ParameterType == typeof(BindableProperty)) + { + setValueMethod = m; + break; + } + } + } +#else + setValueMethod = typeof(IElementController).GetMethod("SetValueFromRenderer", new[] { typeof(BindableProperty), typeof(object) }); +#endif + if (setValueMethod != null) + { + part.LastSetter = setValueMethod; + part.IsBindablePropertySetter = true; + part.BindablePropertyField = bindablePropertyField.GetValue(null); + } + } + } + } +#if !NETSTANDARD1_0 + //TupleElementNamesAttribute tupleEltNames; + //if (property != null + // && part.NextPart != null + // && property.PropertyType.IsGenericType + // && (property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<>) + // || property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,>) + // || property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,,>) + // || property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,,,>) + // || property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,,,,>) + // || property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,,,,,>) + // || property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,,,,,,>) + // || property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,,,,,,,>)) + // && (tupleEltNames = property.GetCustomAttribute(typeof(TupleElementNamesAttribute)) as TupleElementNamesAttribute) != null) + //{ + // // modify the nextPart to access the tuple item via the ITuple indexer + // var nextPart = part.NextPart; + // var name = nextPart.Content; + // var index = tupleEltNames.TransformNames.IndexOf(name); + // if (index >= 0) + // { + // nextPart.IsIndexer = true; + // nextPart.Content = index.ToString(); + // } + //} +#endif + } + + } + static Type[] DecimalTypes = new[] { typeof(float), typeof(decimal), typeof(double) }; + + bool TryConvert(BindingExpressionPart part, ref object value, Type convertTo, bool toTarget) + { + if (value == null) + return true; + if ((toTarget && _targetProperty.TryConvert(ref value)) || (!toTarget && convertTo.IsInstanceOfType(value))) + return true; + + object original = value; + try + { + var stringValue = value as string ?? string.Empty; + // see: https://bugzilla.xamarin.com/show_bug.cgi?id=32871 + // do not canonicalize "*.[.]"; "1." should not update bound BindableProperty + if (stringValue.EndsWith(".") && DecimalTypes.Contains(convertTo)) + throw new FormatException(); + + // do not canonicalize "-0"; user will likely enter a period after "-0" + if (stringValue == "-0" && DecimalTypes.Contains(convertTo)) + throw new FormatException(); + + value = Convert.ChangeType(value, convertTo, CultureInfo.InvariantCulture); + return true; + } + catch (InvalidCastException) + { + value = original; + return false; + } + catch (FormatException) + { + value = original; + return false; + } + catch (OverflowException) + { + value = original; + return false; + } + } + + class BindingPair + { + public BindingPair(BindingExpressionPart part, object source, bool isLast) + { + Part = part; + Source = source; + IsLast = isLast; + } + + public bool IsLast { get; set; } + + public BindingExpressionPart Part { get; private set; } + + public object Source { get; private set; } + } + + internal class WeakPropertyChangedProxy + { + readonly WeakReference _source = new WeakReference(null); + readonly WeakReference _listener = new WeakReference(null); + readonly PropertyChangedEventHandler _handler; + readonly EventHandler _bchandler; + internal WeakReference Source => _source; + + public WeakPropertyChangedProxy() + { + _handler = new PropertyChangedEventHandler(OnPropertyChanged); + _bchandler = new EventHandler(OnBCChanged); + } + + public WeakPropertyChangedProxy(INotifyPropertyChanged source, PropertyChangedEventHandler listener) : this() + { + SubscribeTo(source, listener); + } + + public void SubscribeTo(INotifyPropertyChanged source, PropertyChangedEventHandler listener) + { + source.PropertyChanged += _handler; + var bo = source as BindableObject; + if (bo != null) + bo.BindingContextChanged += _bchandler; + _source.SetTarget(source); + _listener.SetTarget(listener); + } + + public void Unsubscribe() + { + INotifyPropertyChanged source; + if (_source.TryGetTarget(out source) && source != null) + source.PropertyChanged -= _handler; + var bo = source as BindableObject; + if (bo != null) + bo.BindingContextChanged -= _bchandler; + + _source.SetTarget(null); + _listener.SetTarget(null); + } + + void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + PropertyChangedEventHandler handler; + if (_listener.TryGetTarget(out handler) && handler != null) + handler(sender, e); + else + Unsubscribe(); + } + + void OnBCChanged(object sender, EventArgs e) + { + OnPropertyChanged(sender, new PropertyChangedEventArgs("BindingContext")); + } + } + + class BindingExpressionPart + { + readonly BindingExpression _expression; + readonly PropertyChangedEventHandler _changeHandler; + WeakPropertyChangedProxy _listener; + + public BindingExpressionPart(BindingExpression expression, string content, bool isIndexer = false) + { + _expression = expression; + IsSelf = content == Tizen.NUI.Binding.Binding.SelfPath; + Content = content; + IsIndexer = isIndexer; + + _changeHandler = PropertyChanged; + } + + public void Subscribe(INotifyPropertyChanged handler) + { + INotifyPropertyChanged source; + if (_listener != null && _listener.Source.TryGetTarget(out source) && ReferenceEquals(handler, source)) + // Already subscribed + return; + + // Clear out the old subscription if necessary + Unsubscribe(); + + _listener = new WeakPropertyChangedProxy(handler, _changeHandler); + } + + public void Unsubscribe() + { + var listener = _listener; + if (listener != null) + { + listener.Unsubscribe(); + _listener = null; + } + } + + public object[] Arguments { get; set; } + + public object BindablePropertyField { get; set; } + + public string Content { get; internal set; } + + public string IndexerName { get; set; } + + public bool IsBindablePropertySetter { get; set; } + + public bool IsIndexer { get; internal set; } + + public bool IsSelf { get; } + + public MethodInfo LastGetter { get; set; } + + public MethodInfo LastSetter { get; set; } + + public BindingExpressionPart NextPart { get; set; } + + public Type SetterType { get; set; } + + public void PropertyChanged(object sender, PropertyChangedEventArgs args) + { + BindingExpressionPart part = NextPart ?? this; + + string name = args.PropertyName; + + if (!string.IsNullOrEmpty(name)) + { + if (part.IsIndexer) + { + if (name.Contains("[")) + { + if (name != string.Format("{0}[{1}]", part.IndexerName, part.Content)) + return; + } + else if (name != part.IndexerName) + return; + } + else if (name != part.Content) + { + return; + } + } + + _expression.Apply(); + // Device.BeginInvokeOnMainThread(() => _expression.Apply()); + } + + public bool TryGetValue(object source, out object value) + { + value = source; + + if (LastGetter != null && value != null) + { + if (IsIndexer) + { + try + { + value = LastGetter.Invoke(value, Arguments); + } + catch (TargetInvocationException ex) + { + if (!(ex.InnerException is KeyNotFoundException)) + throw; + value = null; + } + return true; + } + value = LastGetter.Invoke(value, Arguments); + return true; + } + + return false; + } + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingMode.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingMode.cs new file mode 100755 index 0000000..0d4fdfc --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/BindingMode.cs @@ -0,0 +1,36 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + /// + /// The direction of changes propagation for bindings. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal enum BindingMode + { + /// + /// When used in Bindings, indicates that the Binding should use the DefaultBindingMode. When used in BindableProperty declaration, defaults to BindingMode.OneWay. + /// + Default, + + /// + /// Indicates that the binding should propagates changes from source (usually the View Model) to target (the BindableObject) in both directions. + /// + TwoWay, + + /// + /// Indicates that the binding should only propagate changes from source (usually the View Model) to target (the BindableObject). This is the default mode for most BindableProperty values. + /// + OneWay, + + /// + /// Indicates that the binding should only propagate changes from target (the BindableObject) to source (usually the View Model). This is mainly used for read-only BindableProperty values. + /// + OneWayToSource, + + /// + /// Indicates that the binding will be applied only when the binding context changes and the value will not be monitored for changes with INotifyPropertyChanged. + /// + OneTime, + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationCallback.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationCallback.cs new file mode 100755 index 0000000..cae30f5 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationCallback.cs @@ -0,0 +1,7 @@ +using System; +using System.Collections; + +namespace Tizen.NUI.Binding +{ + public delegate void CollectionSynchronizationCallback(IEnumerable collection, object context, Action accessMethod, bool writeAccess); +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationContext.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationContext.cs new file mode 100755 index 0000000..b2c36a7 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/CollectionSynchronizationContext.cs @@ -0,0 +1,22 @@ +using System; + +namespace Tizen.NUI.Binding +{ + internal sealed class CollectionSynchronizationContext + { + internal CollectionSynchronizationContext(object context, CollectionSynchronizationCallback callback) + { + ContextReference = new WeakReference(context); + Callback = callback; + } + + internal CollectionSynchronizationCallback Callback { get; private set; } + + internal object Context + { + get { return ContextReference != null ? ContextReference.Target : null; } + } + + internal WeakReference ContextReference { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ContentPropertyAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ContentPropertyAttribute.cs new file mode 100755 index 0000000..77faaa8 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ContentPropertyAttribute.cs @@ -0,0 +1,26 @@ +// +// ContentPropertyAttribute.cs +// +// Author: +// Stephane Delcroix +// +// Copyright (c) 2013 S. Delcroix +// + +using System; + +namespace Tizen.NUI.Binding +{ + [AttributeUsage(AttributeTargets.Class)] + internal sealed class ContentPropertyAttribute : Attribute + { + internal static string[] ContentPropertyTypes = { "Tizen.NUI.Binding.ContentPropertyAttribute", "System.Windows.Markup.ContentPropertyAttribute" }; + + public ContentPropertyAttribute(string name) + { + Name = name; + } + + public string Name { get; private set; } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ControlTemplate.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ControlTemplate.cs new file mode 100755 index 0000000..ae9c3a1 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ControlTemplate.cs @@ -0,0 +1,27 @@ +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + /// + /// Template that specifies a group of styles and effects for controls. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal class ControlTemplate : ElementTemplate + { + /// + /// For internal use only. + /// + public ControlTemplate() + { + } + + /// + /// Creates a new control template for the specified control type. + /// + /// The type of control for which to create a template. + public ControlTemplate(Type type) : base(type) + { + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplate.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplate.cs new file mode 100755 index 0000000..feb86cc --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplate.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; + +namespace Tizen.NUI.Binding +{ + internal class DataTemplate : ElementTemplate + { + public DataTemplate() + { + } + + public DataTemplate(Type type) : base(type) + { + } + + public DataTemplate(Func loadTemplate) : base(loadTemplate) + { + } + + public IDictionary Bindings { get; } = new Dictionary(); + + public IDictionary Values { get; } = new Dictionary(); + + public void SetBinding(BindableProperty property, BindingBase binding) + { + if (property == null) + throw new ArgumentNullException("property"); + if (binding == null) + throw new ArgumentNullException("binding"); + + Values.Remove(property); + Bindings[property] = binding; + } + + public void SetValue(BindableProperty property, object value) + { + if (property == null) + throw new ArgumentNullException("property"); + + Bindings.Remove(property); + Values[property] = value; + } + + internal override void SetupContent(object item) + { + ApplyBindings(item); + ApplyValues(item); + } + + void ApplyBindings(object item) + { + if (Bindings == null) + return; + + var bindable = item as BindableObject; + if (bindable == null) + return; + + foreach (KeyValuePair kvp in Bindings) + { + if (Values.ContainsKey(kvp.Key)) + throw new InvalidOperationException("Binding and Value found for " + kvp.Key.PropertyName); + + bindable.SetBinding(kvp.Key, kvp.Value.Clone()); + } + } + + void ApplyValues(object item) + { + if (Values == null) + return; + + var bindable = item as BindableObject; + if (bindable == null) + return; + foreach (KeyValuePair kvp in Values) + bindable.SetValue(kvp.Key, kvp.Value); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateExtensions.cs new file mode 100755 index 0000000..e966fda --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateExtensions.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class DataTemplateExtensions + { + public static DataTemplate SelectDataTemplate(this DataTemplate self, object item, BindableObject container) + { + var selector = self as DataTemplateSelector; + if (selector == null) + return self; + + return selector.SelectTemplate(item, container); + } + + public static object CreateContent(this DataTemplate self, object item, BindableObject container) + { + return self.SelectDataTemplate(item, container).CreateContent(); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateSelector.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateSelector.cs new file mode 100755 index 0000000..e23ba1d --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DataTemplateSelector.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; + +namespace Tizen.NUI.Binding +{ + internal abstract class DataTemplateSelector : DataTemplate + { + Dictionary _dataTemplates = new Dictionary(); + + public DataTemplate SelectTemplate(object item, BindableObject container) + { + // var listView = container as ListView; + + // var recycle = listView == null ? false : + // (listView.CachingStrategy & ListViewCachingStrategy.RecycleElementAndDataTemplate) == + // ListViewCachingStrategy.RecycleElementAndDataTemplate; + + DataTemplate dataTemplate = null; + // if (recycle && _dataTemplates.TryGetValue(item.GetType(), out dataTemplate)) + // return dataTemplate; + + dataTemplate = OnSelectTemplate(item, container); + if (dataTemplate is DataTemplateSelector) + throw new NotSupportedException( + "DataTemplateSelector.OnSelectTemplate must not return another DataTemplateSelector"); + + // if (recycle) + // { + // if (!dataTemplate.CanRecycle) + // throw new NotSupportedException( + // "RecycleElementAndDataTemplate requires DataTemplate activated with ctor taking a type."); + + // _dataTemplates[item.GetType()] = dataTemplate; + // } + + return dataTemplate; + } + + protected abstract DataTemplate OnSelectTemplate(object item, BindableObject container); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyAttribute.cs new file mode 100755 index 0000000..086b061 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Binding +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + internal class DependencyAttribute : Attribute + { + public DependencyAttribute(Type implementorType) + { + Implementor = implementorType; + } + + internal Type Implementor { get; private set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyFetchTarget.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyFetchTarget.cs new file mode 100755 index 0000000..43a96ea --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyFetchTarget.cs @@ -0,0 +1,8 @@ +namespace Tizen.NUI.Binding +{ + internal enum DependencyFetchTarget + { + GlobalInstance, + NewInstance + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyResolver.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyResolver.cs new file mode 100755 index 0000000..6bf047b --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyResolver.cs @@ -0,0 +1,57 @@ +using System; +using System.Linq; +using System.Reflection; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Binding +{ + internal static class DependencyResolver + { + static Func Resolver { get; set; } + + public static void ResolveUsing(Func resolver) + { + Resolver = resolver; + } + + public static void ResolveUsing(Func resolver) + { + Resolver = (type, objects) => resolver.Invoke(type); + } + + internal static object Resolve(Type type, params object[] args) + { + var result = Resolver?.Invoke(type, args); + + if (result != null) + { + if (!type.IsInstanceOfType(result)) + { + throw new InvalidCastException("Resolved instance is not of the correct type."); + } + } + + return result; + } + + internal static object ResolveOrCreate(Type type, params object[] args) + { + var result = Resolve(type, args); + + if (result != null) return result; + + if (args.Length > 0) + { + // This is by no means a general solution to matching with the correct constructor, but it'll + // do for finding Android renderers which need Context (vs older custom renderers which may still use + // parameterless constructors) + if (type.GetTypeInfo().DeclaredConstructors.Any(info => info.GetParameters().Length == args.Length)) + { + return Activator.CreateInstance(type, args); + } + } + + return Activator.CreateInstance(type); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyService.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyService.cs new file mode 100755 index 0000000..54e1424 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DependencyService.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding +{ + internal static class DependencyService + { + static bool s_initialized; + + static readonly List DependencyTypes = new List(); + static readonly Dictionary DependencyImplementations = new Dictionary(); + + public static T Resolve(DependencyFetchTarget fallbackFetchTarget = DependencyFetchTarget.GlobalInstance) where T : class + { + var result = DependencyResolver.Resolve(typeof(T)) as T; + + return result ?? Get(fallbackFetchTarget); + } + + public static T Get(DependencyFetchTarget fetchTarget = DependencyFetchTarget.GlobalInstance) where T : class + { + Initialize(); + + Type targetType = typeof(T); + + if (!DependencyImplementations.ContainsKey(targetType)) + { + Type implementor = FindImplementor(targetType); + DependencyImplementations[targetType] = implementor != null ? new DependencyData { ImplementorType = implementor } : null; + } + + DependencyData dependencyImplementation = DependencyImplementations[targetType]; + if (dependencyImplementation == null) + return null; + + if (fetchTarget == DependencyFetchTarget.GlobalInstance) + { + if (dependencyImplementation.GlobalInstance == null) + { + dependencyImplementation.GlobalInstance = Activator.CreateInstance(dependencyImplementation.ImplementorType); + } + return (T)dependencyImplementation.GlobalInstance; + } + return (T)Activator.CreateInstance(dependencyImplementation.ImplementorType); + } + + public static void Register() where T : class + { + Type type = typeof(T); + if (!DependencyTypes.Contains(type)) + DependencyTypes.Add(type); + } + + public static void Register() where T : class where TImpl : class, T + { + Type targetType = typeof(T); + Type implementorType = typeof(TImpl); + if (!DependencyTypes.Contains(targetType)) + DependencyTypes.Add(targetType); + + DependencyImplementations[targetType] = new DependencyData { ImplementorType = implementorType }; + } + + static Type FindImplementor(Type target) + { + return DependencyTypes.FirstOrDefault(t => target.IsAssignableFrom(t)); + } + + static void Initialize() + { + if (s_initialized) + { + return; + } + + Assembly[] assemblies = Device.GetAssemblies(); + if (Tizen.NUI.Binding.Internals.Registrar.ExtraAssemblies != null) + { + assemblies = assemblies.Union(Tizen.NUI.Binding.Internals.Registrar.ExtraAssemblies).ToArray(); + } + + Initialize(assemblies); + } + + internal static void Initialize(Assembly[] assemblies) + { + if (s_initialized || assemblies == null) + { + return; + } + DependencyService.Register(); + + Type targetAttrType = typeof(DependencyAttribute); + + // Don't use LINQ for performance reasons + // Naive implementation can easily take over a second to run + foreach (Assembly assembly in assemblies) + { + Attribute[] attributes; + try + { + attributes = assembly.GetCustomAttributes(targetAttrType).ToArray(); + } + catch (System.IO.FileNotFoundException) + { + // Sometimes the previewer doesn't actually have everything required for these loads to work + Console.WriteLine(nameof(Registrar), "Could not load assembly: {0} for Attibute {1} | Some renderers may not be loaded", assembly.FullName, targetAttrType.FullName); + continue; + } + + if (attributes.Length == 0) + continue; + + foreach (DependencyAttribute attribute in attributes) + { + if (!DependencyTypes.Contains(attribute.Implementor)) + { + DependencyTypes.Add(attribute.Implementor); + } + } + } + + s_initialized = true; + } + + class DependencyData + { + public object GlobalInstance { get; set; } + + public Type ImplementorType { get; set; } + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Device.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Device.cs new file mode 100755 index 0000000..f43cf60 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Device.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + internal static class Device + { + public const string iOS = "iOS"; + public const string Android = "Android"; + public const string UWP = "UWP"; + public const string macOS = "macOS"; + public const string GTK = "GTK"; + public const string Tizen = "Tizen"; + public const string WPF = "WPF"; + + [EditorBrowsable(EditorBrowsableState.Never)] + public static DeviceInfo info; + + static IPlatformServices s_platformServices; + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetIdiom(TargetIdiom value) => Idiom = value; + public static TargetIdiom Idiom { get; internal set; } + + //TODO: Why are there two of these? This is never used...? + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetTargetIdiom(TargetIdiom value) => Idiom = value; + + [Obsolete("TargetPlatform is obsolete as of version 2.3.4. Please use RuntimePlatform instead.")] +#pragma warning disable 0618 + public static TargetPlatform OS + { + get + { + TargetPlatform platform; + if (Enum.TryParse(RuntimePlatform, out platform)) + return platform; + + // In the old TargetPlatform, there was no distinction between WinRT/UWP + if (RuntimePlatform == UWP) + { + return TargetPlatform.Windows; + } + + return TargetPlatform.Other; + } + } +#pragma warning restore 0618 + + public static string RuntimePlatform => PlatformServices?.RuntimePlatform; + + [EditorBrowsable(EditorBrowsableState.Never)] + public static DeviceInfo Info + { + get + { + // if (info == null) + // throw new InvalidOperationException("You MUST call Tizen.NUI.Xaml.Init(); prior to using it."); + return info; + } + set { info = value; } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetFlowDirection(FlowDirection value) => FlowDirection = value; + public static FlowDirection FlowDirection { get; internal set; } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static bool IsInvokeRequired + { + get { return PlatformServices.IsInvokeRequired; } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static IPlatformServices PlatformServices + { + get + { + if (s_platformServices == null) + throw new InvalidOperationException("You MUST call Tizen.NUI.Init(); prior to using it."); + return s_platformServices; + } + set + { + s_platformServices = value; + Console.WriteLine("Device s_platformServices : " + s_platformServices ); + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static IReadOnlyList Flags { get; private set; } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetFlags(IReadOnlyList flags) + { + Flags = flags; + } + + public static void BeginInvokeOnMainThread(Action action) + { + PlatformServices?.BeginInvokeOnMainThread(action); + action(); + Console.WriteLine("Device BeginInvokeOnMainThread action called"); + } + + // public static double GetNamedSize(NamedSize size, Element targetElement) + // { + // return GetNamedSize(size, targetElement.GetType()); + // } + + // public static double GetNamedSize(NamedSize size, Type targetElementType) + // { + // return GetNamedSize(size, targetElementType, false); + // } + + [Obsolete("OnPlatform is obsolete as of version 2.3.4. Please use switch(RuntimePlatform) instead.")] + public static void OnPlatform(Action iOS = null, Action Android = null, Action WinPhone = null, Action Default = null) + { + switch (OS) + { + case TargetPlatform.iOS: + if (iOS != null) + iOS(); + else if (Default != null) + Default(); + break; + case TargetPlatform.Android: + if (Android != null) + Android(); + else if (Default != null) + Default(); + break; + case TargetPlatform.Windows: + case TargetPlatform.WinPhone: + if (WinPhone != null) + WinPhone(); + else if (Default != null) + Default(); + break; + case TargetPlatform.Other: + if (Default != null) + Default(); + break; + } + } + + [Obsolete("OnPlatform<> (generic) is obsolete as of version 2.3.4. Please use switch(RuntimePlatform) instead.")] + public static T OnPlatform(T iOS, T Android, T WinPhone) + { + switch (OS) + { + case TargetPlatform.iOS: + return iOS; + case TargetPlatform.Android: + return Android; + case TargetPlatform.Windows: + case TargetPlatform.WinPhone: + return WinPhone; + } + + return iOS; + } + + public static void OpenUri(Uri uri) + { + // PlatformServices?.OpenUriAction(uri); + } + + public static void StartTimer(TimeSpan interval, Func callback) + { + PlatformServices.StartTimer(interval, callback); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static Assembly[] GetAssemblies() + { + return PlatformServices?.GetAssemblies(); + } + + // [EditorBrowsable(EditorBrowsableState.Never)] + // public static double GetNamedSize(NamedSize size, Type targetElementType, bool useOldSizes) + // { + // return PlatformServices.GetNamedSize(size, targetElementType, useOldSizes); + // } + + internal static Task GetStreamAsync(Uri uri, CancellationToken cancellationToken) + { + return PlatformServices?.GetStreamAsync(uri, cancellationToken); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceInfo.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceInfo.cs new file mode 100755 index 0000000..3b908b2 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceInfo.cs @@ -0,0 +1,45 @@ +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal abstract class DeviceInfo : INotifyPropertyChanged, IDisposable + { + DeviceOrientation _currentOrientation; + bool _disposed; + + public DeviceOrientation CurrentOrientation + { + get { return _currentOrientation; } + set + { + if (Equals(_currentOrientation, value)) + return; + _currentOrientation = value; + OnPropertyChanged(); + } + } + + public virtual double DisplayRound(double value) => + Math.Round(value); + + public void Dispose() + { + Dispose(true); + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + _disposed = true; + } + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceOrientation.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceOrientation.cs new file mode 100755 index 0000000..8453e20 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/DeviceOrientation.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal enum DeviceOrientation + { + Portrait, + Landscape, + PortraitUp, + PortraitDown, + LandscapeLeft, + LandscapeRight, + Other + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Effect.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Effect.cs new file mode 100755 index 0000000..a70c710 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Effect.cs @@ -0,0 +1,91 @@ +using System; +using System.ComponentModel; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + /// + /// A collection of styles and properties that can be added to an element at run time. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal abstract class Effect + { + internal Effect() + { + } + + /// + /// Gets the element to which the style is attached. + /// + public Element Element { get; internal set; } + + /// + /// Gets a value that tells whether the effect is attached to an element. + /// + public bool IsAttached { get; private set; } + + /// + /// Gets the ID that is used to resolve this effect at runtime. + /// + public string ResolveId { get; internal set; } + + #region Statics + /// + /// Returns an Effect for the specified name, which is of the form ResolutionGroupName.ExportEffect. + /// + /// The name of the effect to get. + /// The uniquely identified effect. + public static Effect Resolve(string name) + { + Effect result = null; + if (Tizen.NUI.Binding.Internals.Registrar.Effects.TryGetValue(name, out Type effectType)) + { + result = (Effect)DependencyResolver.ResolveOrCreate(effectType); + } + + if (result == null) + result = new NullEffect(); + result.ResolveId = name; + return result; + } + + #endregion + + /// + /// Method that is called after the effect is attached and made valid. + /// + protected abstract void OnAttached(); + + /// + /// Method that is called after the effect is detached and invalidated. + /// + protected abstract void OnDetached(); + + internal virtual void ClearEffect() + { + if (IsAttached) + SendDetached(); + Element = null; + } + + internal virtual void SendAttached() + { + if (IsAttached) + return; + OnAttached(); + IsAttached = true; + } + + internal virtual void SendDetached() + { + if (!IsAttached) + return; + OnDetached(); + IsAttached = false; + } + + internal virtual void SendOnElementPropertyChanged(PropertyChangedEventArgs args) + { + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Element.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Element.cs new file mode 100755 index 0000000..b887142 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Element.cs @@ -0,0 +1,771 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Xml; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + /// + /// Provides the base class for all Tizen.NUI.Binding hierarchal elements. This class contains all the methods and properties required to represent an element in the Tizen.NUI.Binding hierarchy. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal abstract partial class Element : BindableObject, IElement, INameScope, IElementController + { + + // public static readonly BindableProperty MenuProperty = BindableProperty.CreateAttached(nameof(Menu), typeof(Menu), typeof(Element), null); + + // public static Menu GetMenu(BindableObject bindable) + // { + // return (Menu)bindable.GetValue(MenuProperty); + // } + + // public static void SetMenu(BindableObject bindable, Menu menu) + // { + // bindable.SetValue(MenuProperty, menu); + // } + + internal static readonly ReadOnlyCollection EmptyChildren = new ReadOnlyCollection(new Element[0]); + + /// + /// Identifies the ClassId bindable property. + /// + internal static readonly BindableProperty ClassIdProperty = BindableProperty.Create("ClassId", typeof(string), typeof(Element), null); + + string _automationId; + + IList _bindableResources; + + List> _changeHandlers; + + Dictionary _dynamicResources; + + IEffectControlProvider _effectControlProvider; + + TrackableCollection _effects; + + Guid? _id; + + Element _parentOverride; + + IPlatform _platform; + + string _styleId; + + /// + /// Gets or sets a value that allows the automation framework to find and interact with this element. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public string AutomationId + { + get { return _automationId; } + set + { + if (_automationId != null) + throw new InvalidOperationException("AutomationId may only be set one time"); + _automationId = value; + } + } + + /// + /// Gets or sets a value used to identify a collection of semantically similar elements. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public string ClassId + { + get { return (string)GetValue(ClassIdProperty); } + set { SetValue(ClassIdProperty, value); } + } + + internal IList Effects + { + get + { + if (_effects == null) + { + _effects = new TrackableCollection(); + _effects.CollectionChanged += EffectsOnCollectionChanged; + _effects.Clearing += EffectsOnClearing; + } + return _effects; + } + } + + /// + /// Gets a value that can be used to uniquely identify an element through the run of an application. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public Guid Id + { + get + { + if (!_id.HasValue) + _id = Guid.NewGuid(); + return _id.Value; + } + } + + /// + /// Gets the element which is the closest ancestor of this element that is a BaseHandle. + /// + [Obsolete("ParentView is obsolete as of version 2.1.0. Please use Parent instead.")] + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public Element ParentView + { + get + { + Element parent = Parent; + while (parent != null) + { + var parentView = parent as Element; + if (parentView != null) + return parentView; + parent = parent.RealParent; + } + return null; + } + } + + /// + /// Gets or sets a user defined value to uniquely identify the element. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public string StyleId + { + get { return _styleId; } + set + { + if (_styleId == value) + return; + + OnPropertyChanging(); + _styleId = value; + OnPropertyChanged(); + } + } + + internal virtual ReadOnlyCollection LogicalChildrenInternal => EmptyChildren; + + /// + /// For internal use. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public ReadOnlyCollection LogicalChildren => LogicalChildrenInternal; + + internal bool Owned { get; set; } + + internal Element ParentOverride + { + get { return _parentOverride; } + set + { + if (_parentOverride == value) + return; + + bool emitChange = Parent != value; + + if (emitChange) + OnPropertyChanging(nameof(Parent)); + + _parentOverride = value; + + if (emitChange) + OnPropertyChanged(nameof(Parent)); + } + } + + /// + /// For internal use. + /// + internal IPlatform Platform + { + get + { + if (_platform == null && RealParent != null) + return RealParent.Platform; + return _platform; + } + set + { + if (_platform == value) + return; + _platform = value; + PlatformSet?.Invoke(this, EventArgs.Empty); + foreach (Element descendant in Descendants()) + { + descendant._platform = _platform; + descendant.PlatformSet?.Invoke(this, EventArgs.Empty); + } + } + } + + /// + /// For internal use. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Element RealParent { get; private set; } + + Dictionary DynamicResources + { + get { return _dynamicResources ?? (_dynamicResources = new Dictionary()); } + } + + void IElement.AddResourcesChangedListener(Action onchanged) + { + _changeHandlers = _changeHandlers ?? new List>(2); + _changeHandlers.Add(onchanged); + } + + /// + /// Gets or sets the parent element of the element. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public Element Parent + { + get { return _parentOverride ?? RealParent; } + set + { + if (RealParent == value) + return; + + OnPropertyChanging(); + + if (RealParent != null) + ((IElement)RealParent).RemoveResourcesChangedListener(OnParentResourcesChanged); + RealParent = value; + if (RealParent != null) + { + OnParentResourcesChanged(RealParent?.GetMergedResources()); + ((IElement)RealParent).AddResourcesChangedListener(OnParentResourcesChanged); + } + + object context = value != null ? value.BindingContext : null; + if (value != null) + { + value.SetChildInheritedBindingContext(this, context); + } + else + { + SetInheritedBindingContext(this, null); + } + + OnParentSet(); + + if (RealParent != null) + { + IPlatform platform = RealParent.Platform; + if (platform != null) + Platform = platform; + } + + OnPropertyChanged(); + } + } + + void IElement.RemoveResourcesChangedListener(Action onchanged) + { + if (_changeHandlers == null) + return; + _changeHandlers.Remove(onchanged); + } + + /// + /// For internal use. + /// + internal IEffectControlProvider EffectControlProvider + { + get { return _effectControlProvider; } + set + { + if (_effectControlProvider == value) + return; + if (_effectControlProvider != null && _effects != null) + { + foreach (Effect effect in _effects) + effect?.SendDetached(); + } + _effectControlProvider = value; + if (_effectControlProvider != null && _effects != null) + { + foreach (Effect effect in _effects) + { + if (effect != null) + AttachEffect(effect); + } + } + } + } + + //void IElementController.SetValueFromRenderer(BindableProperty property, object value) => SetValueFromRenderer(property, value); + + /// + /// Sets the value of the specified property. + /// + /// The BindableProperty on which to assign a value. + /// The value to set. + internal void SetValueFromRenderer(BindableProperty property, object value) + { + SetValueCore(property, value); + } + + /// + /// Sets the value of the propertyKey. + /// + /// The BindablePropertyKey on which to assign a value. + /// The value to set. + internal void SetValueFromRenderer(BindablePropertyKey property, object value) + { + SetValueCore(property, value); + } + + /// + /// For internal use. + /// + /// The nameof the effect + /// true if attached + [EditorBrowsable(EditorBrowsableState.Never)] + public bool EffectIsAttached(string name) + { + foreach (var effect in Effects) + { + if (effect.ResolveId == name) + return true; + } + return false; + } + + object INameScope.FindByName(string name) + { + INameScope namescope = GetNameScope(); + if (namescope == null) + { + //throw new InvalidOperationException("this element is not in a namescope"); + return null; + } + else + { + return namescope.FindByName(name); + } + } + + void INameScope.RegisterName(string name, object scopedElement) + { + INameScope namescope = GetNameScope(); + if (namescope == null) + throw new InvalidOperationException("this element is not in a namescope"); + namescope.RegisterName(name, scopedElement); + } + + [Obsolete] + void INameScope.RegisterName(string name, object scopedElement, IXmlLineInfo xmlLineInfo) + { + INameScope namescope = GetNameScope(); + if (namescope == null) + throw new InvalidOperationException("this element is not in a namescope"); + namescope.RegisterName(name, scopedElement, xmlLineInfo); + } + + void INameScope.UnregisterName(string name) + { + INameScope namescope = GetNameScope(); + if (namescope == null) + throw new InvalidOperationException("this element is not in a namescope"); + namescope.UnregisterName(name); + } + + internal event EventHandler ChildAdded; + + internal event EventHandler ChildRemoved; + + internal event EventHandler DescendantAdded; + + internal event EventHandler DescendantRemoved; + + /// + /// Removes a previously set dynamic resource. + /// + /// The BindableProperty from which to remove the DynamicResource. + internal new void RemoveDynamicResource(BindableProperty property) + { + base.RemoveDynamicResource(property); + } + + /// + /// Sets the BindableProperty property of this element to be updated via the DynamicResource with the provided key. + /// + /// The BindableProperty. + /// The key of the DynamicResource + internal new void SetDynamicResource(BindableProperty property, string key) + { + base.SetDynamicResource(property, key); + } + + /// + /// Invoked whenever the binding context of the element changes. Implement this method to add class handling for this event. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void OnBindingContextChanged() + { + var gotBindingContext = false; + object bc = null; + + for (var index = 0; index < LogicalChildrenInternal.Count; index++) + { + Element child = LogicalChildrenInternal[index]; + + if (!gotBindingContext) + { + bc = BindingContext; + gotBindingContext = true; + } + + SetChildInheritedBindingContext(child, bc); + } + + if (_bindableResources != null) + foreach (BindableObject item in _bindableResources) + { + SetInheritedBindingContext(item, BindingContext); + } + + base.OnBindingContextChanged(); + } + + /// + /// Invoked whenever the ChildAdded event needs to be emitted.Implement this method to add class handling for this event. + /// + /// The element that was added. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void OnChildAdded(Element child) + { + child.Parent = this; + if (Platform != null) + child.Platform = Platform; + + child.ApplyBindings(skipBindingContext: false, fromBindingContextChanged:true); + + ChildAdded?.Invoke(this, new ElementEventArgs(child)); + + OnDescendantAdded(child); + foreach (Element element in child.Descendants()) + OnDescendantAdded(element); + } + + /// + /// Invoked whenever the ChildRemoved event needs to be emitted.Implement this method to add class handling for this event. + /// + /// The element that was removed. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void OnChildRemoved(Element child) + { + child.Parent = null; + + ChildRemoved?.Invoke(child, new ElementEventArgs(child)); + + OnDescendantRemoved(child); + foreach (Element element in child.Descendants()) + OnDescendantRemoved(element); + } + + /// + /// Invoked whenever the Parent of an element is set.Implement this method in order to add behavior when the element is added to a parent. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void OnParentSet() + { + ParentSet?.Invoke(this, EventArgs.Empty); + // ApplyStyleSheetsOnParentSet(); + } + + /// + /// Method that is called when a bound property is changed. + /// + /// The name of the bound property that changed. + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + base.OnPropertyChanged(propertyName); + + if (_effects == null || _effects.Count == 0) + return; + + var args = new PropertyChangedEventArgs(propertyName); + foreach (Effect effect in _effects) + { + effect?.SendOnElementPropertyChanged(args); + } + } + + /// + /// For internal use. + /// + /// the elements + [EditorBrowsable(EditorBrowsableState.Never)] + public IEnumerable Descendants() + { + var queue = new Queue(16); + queue.Enqueue(this); + + while (queue.Count > 0) + { + ReadOnlyCollection children = queue.Dequeue().LogicalChildrenInternal; + for (var i = 0; i < children.Count; i++) + { + Element child = children[i]; + yield return child; + queue.Enqueue(child); + } + } + } + + internal virtual void OnParentResourcesChanged(object sender, ResourcesChangedEventArgs e) + { + // if (e == ResourcesChangedEventArgs.StyleSheets) + // // ApplyStyleSheetsOnParentSet(); + // else + // OnParentResourcesChanged(e.Values); + } + + internal virtual void OnParentResourcesChanged(IEnumerable> values) + { + OnResourcesChanged(values); + } + + internal override void OnRemoveDynamicResource(BindableProperty property) + { + DynamicResources.Remove(property); + + if (DynamicResources.Count == 0) + _dynamicResources = null; + base.OnRemoveDynamicResource(property); + } + + internal virtual void OnResourcesChanged(object sender, ResourcesChangedEventArgs e) + { + OnResourcesChanged(e.Values); + } + + internal void OnResourcesChanged(IEnumerable> values) + { + if (values == null) + return; + if (_changeHandlers != null) + foreach (Action handler in _changeHandlers) + handler(this, new ResourcesChangedEventArgs(values)); + if (_dynamicResources == null) + return; + if (_bindableResources == null) + _bindableResources = new List(); + foreach (KeyValuePair value in values) + { + List changedResources = null; + foreach (KeyValuePair dynR in DynamicResources) + { + // when the DynamicResource bound to a BindableProperty is + // changing then the BindableProperty needs to be refreshed; + // The .Value is the name of DynamicResouce to which the BindableProperty is bound. + // The .Key is the name of the DynamicResource whose value is changing. + if (dynR.Value != value.Key) + continue; + changedResources = changedResources ?? new List(); + changedResources.Add(dynR.Key); + } + if (changedResources == null) + continue; + foreach (BindableProperty changedResource in changedResources) + OnResourceChanged(changedResource, value.Value); + + var bindableObject = value.Value as BindableObject; + if (bindableObject != null && (bindableObject as Element)?.Parent == null) + { + if (!_bindableResources.Contains(bindableObject)) + _bindableResources.Add(bindableObject); + SetInheritedBindingContext(bindableObject, BindingContext); + } + } + } + + internal override void OnSetDynamicResource(BindableProperty property, string key) + { + base.OnSetDynamicResource(property, key); + DynamicResources[property] = key; + object value; + if (this.TryGetResource(key, out value)) + OnResourceChanged(property, value); + + Application.AddResourceChangedCallback(this, (this as Element).OnResourcesChanged); + } + + internal event EventHandler ParentSet; + + internal static void SetFlowDirectionFromParent(Element child) + { + // IFlowDirectionController controller = child as IFlowDirectionController; + // if (controller == null) + // return; + + // if (controller.EffectiveFlowDirection.IsImplicit()) + // { + // var parentView = child.Parent as IFlowDirectionController; + // if (parentView == null) + // return; + + // var flowDirection = parentView.EffectiveFlowDirection.ToFlowDirection(); + + // if (flowDirection != controller.EffectiveFlowDirection.ToFlowDirection()) + // { + // controller.EffectiveFlowDirection = flowDirection.ToEffectiveFlowDirection(); + // } + // } + } + + /// + /// For internal use. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public event EventHandler PlatformSet; + + internal virtual void SetChildInheritedBindingContext(Element child, object context) + { + SetInheritedBindingContext(child, context); + } + + internal IEnumerable VisibleDescendants() + { + var queue = new Queue(16); + queue.Enqueue(this); + + while (queue.Count > 0) + { + ReadOnlyCollection children = queue.Dequeue().LogicalChildrenInternal; + for (var i = 0; i < children.Count; i++) + { + var child = children[i] as Element; + if (child == null /*|| !child.IsVisible*/) + continue; + yield return child; + queue.Enqueue(child); + } + } + } + + void AttachEffect(Effect effect) + { + if (_effectControlProvider == null) + return; + if (effect.IsAttached) + throw new InvalidOperationException("Cannot attach Effect to multiple sources"); + + Effect effectToRegister = effect; + if (effect is RoutingEffect) + effectToRegister = ((RoutingEffect)effect).Inner; + _effectControlProvider.RegisterEffect(effectToRegister); + effectToRegister.Element = this; + effect.SendAttached(); + } + + void EffectsOnClearing(object sender, EventArgs eventArgs) + { + foreach (Effect effect in _effects) + { + effect?.ClearEffect(); + } + } + + void EffectsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (Effect effect in e.NewItems) + { + AttachEffect(effect); + } + break; + case NotifyCollectionChangedAction.Move: + break; + case NotifyCollectionChangedAction.Remove: + foreach (Effect effect in e.OldItems) + { + effect.ClearEffect(); + } + break; + case NotifyCollectionChangedAction.Replace: + foreach (Effect effect in e.NewItems) + { + AttachEffect(effect); + } + foreach (Effect effect in e.OldItems) + { + effect.ClearEffect(); + } + break; + case NotifyCollectionChangedAction.Reset: + if (e.NewItems != null) + { + foreach (Effect effect in e.NewItems) + { + AttachEffect(effect); + } + } + if (e.OldItems != null) + { + foreach (Effect effect in e.OldItems) + { + effect.ClearEffect(); + } + } + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + INameScope GetNameScope() + { + INameScope namescope = NameScope.GetNameScope(this); + Element p = RealParent; + while (namescope == null && p != null) + { + namescope = NameScope.GetNameScope(p); + p = p.RealParent; + } + return namescope; + } + + void OnDescendantAdded(Element child) + { + DescendantAdded?.Invoke(this, new ElementEventArgs(child)); + + if (RealParent != null) + RealParent.OnDescendantAdded(child); + } + + void OnDescendantRemoved(Element child) + { + DescendantRemoved?.Invoke(this, new ElementEventArgs(child)); + + if (RealParent != null) + RealParent.OnDescendantRemoved(child); + } + + void OnResourceChanged(BindableProperty property, object value) + { + SetValueCore(property, value, SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearTwoWayBindings); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementEventArgs.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementEventArgs.cs new file mode 100755 index 0000000..fcdeacd --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementEventArgs.cs @@ -0,0 +1,17 @@ +using System; + +namespace Tizen.NUI.Binding +{ + internal class ElementEventArgs : EventArgs + { + public ElementEventArgs(Element element) + { + if (element == null) + throw new ArgumentNullException("element"); + + Element = element; + } + + public Element Element { get; private set; } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementTemplate.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementTemplate.cs new file mode 100755 index 0000000..34a8aa8 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ElementTemplate.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + /// + /// Base class for DataTemplate and ControlTemplate classes. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal class ElementTemplate : IElement, IDataTemplate + { + List> _changeHandlers; + Element _parent; + bool _canRecycle; // aka IsDeclarative + + internal ElementTemplate() + { + } + + internal ElementTemplate(Type type) : this() + { + if (type == null) + throw new ArgumentNullException("type"); + + _canRecycle = true; + + LoadTemplate = () => Activator.CreateInstance(type); + } + + internal ElementTemplate(Func loadTemplate) : this() + { + if (loadTemplate == null) + throw new ArgumentNullException("loadTemplate"); + + LoadTemplate = loadTemplate; + } + + Func LoadTemplate { get; set; } + +#pragma warning disable 0612 + Func IDataTemplate.LoadTemplate + { + get { return LoadTemplate; } + set { LoadTemplate = value; } + } +#pragma warning restore 0612 + + void IElement.AddResourcesChangedListener(Action onchanged) + { + _changeHandlers = _changeHandlers ?? new List>(1); + _changeHandlers.Add(onchanged); + } + + internal bool CanRecycle => _canRecycle; + Element IElement.Parent + { + get { return _parent; } + set + { + if (_parent == value) + return; + if (_parent != null) + ((IElement)_parent).RemoveResourcesChangedListener(OnResourcesChanged); + _parent = value; + if (_parent != null) + ((IElement)_parent).AddResourcesChangedListener(OnResourcesChanged); + } + } + + void IElement.RemoveResourcesChangedListener(Action onchanged) + { + if (_changeHandlers == null) + return; + _changeHandlers.Remove(onchanged); + } + + /// + /// Used by the XAML infrastructure to load data templates and set up the content of the resulting UI. + /// + /// + public object CreateContent() + { + if (LoadTemplate == null) + throw new InvalidOperationException("LoadTemplate should not be null"); + if (this is DataTemplateSelector) + throw new InvalidOperationException("Cannot call CreateContent directly on a DataTemplateSelector"); + + object item = LoadTemplate(); + SetupContent(item); + + return item; + } + + internal virtual void SetupContent(object item) + { + } + + void OnResourcesChanged(object sender, ResourcesChangedEventArgs e) + { + if (_changeHandlers == null) + return; + foreach (Action handler in _changeHandlers) + handler(this, e); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/EnumerableExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/EnumerableExtensions.cs new file mode 100755 index 0000000..dd52ab0 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/EnumerableExtensions.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class EnumerableExtensions + { + public static IEnumerable GetGesturesFor(this IEnumerable gestures, Func predicate = null) where T : GestureRecognizer + { + if (gestures == null) + yield break; + + if (predicate == null) + predicate = x => true; + + foreach (IGestureRecognizer item in gestures) + { + var gesture = item as T; + if (gesture != null && predicate(gesture)) + { + yield return gesture; + } + } + } + + internal static IEnumerable Append(this IEnumerable enumerable, T item) + { + foreach (T x in enumerable) + yield return x; + + yield return item; + } + + public static void ForEach(this IEnumerable enumeration, Action action) + { + foreach (T item in enumeration) + { + action(item); + } + } + + public static int IndexOf(this IEnumerable enumerable, T item) + { + if (enumerable == null) + throw new ArgumentNullException("enumerable"); + + var i = 0; + foreach (T element in enumerable) + { + if (Equals(element, item)) + return i; + + i++; + } + + return -1; + } + + public static int IndexOf(this IEnumerable enumerable, Func predicate) + { + var i = 0; + foreach (T element in enumerable) + { + if (predicate(element)) + return i; + + i++; + } + + return -1; + } + + public static IEnumerable Prepend(this IEnumerable enumerable, T item) + { + yield return item; + + foreach (T x in enumerable) + yield return x; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ExportEffectAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ExportEffectAttribute.cs new file mode 100755 index 0000000..a5f5aa0 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ExportEffectAttribute.cs @@ -0,0 +1,20 @@ +using System; + +namespace Tizen.NUI.Binding +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + internal class ExportEffectAttribute : Attribute + { + public ExportEffectAttribute(Type effectType, string uniqueName) + { + if (uniqueName.Contains(".")) + throw new ArgumentException("uniqueName must not contain a ."); + Type = effectType; + Id = uniqueName; + } + + internal string Id { get; private set; } + + internal Type Type { get; private set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/FlowDirection.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/FlowDirection.cs new file mode 100755 index 0000000..f30a1cd --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/FlowDirection.cs @@ -0,0 +1,32 @@ +using System; + +namespace Tizen.NUI.Binding +{ + [TypeConverter(typeof(FlowDirectionConverter))] + internal enum FlowDirection + { + MatchParent = 0, + LeftToRight = 1, + RightToLeft = 2, + } + + [Xaml.TypeConversion(typeof(FlowDirection))] + internal class FlowDirectionConverter : TypeConverter + { + public override object ConvertFromInvariantString(string value) + { + if (value != null) { + if (Enum.TryParse(value, out FlowDirection direction)) + return direction; + + if (value.Equals("ltr", StringComparison.OrdinalIgnoreCase)) + return FlowDirection.LeftToRight; + if (value.Equals("rtl", StringComparison.OrdinalIgnoreCase)) + return FlowDirection.RightToLeft; + if (value.Equals("inherit", StringComparison.OrdinalIgnoreCase)) + return FlowDirection.MatchParent; + } + throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", value, typeof(FlowDirection))); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/GestureRecognizer.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/GestureRecognizer.cs new file mode 100755 index 0000000..b490a71 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/GestureRecognizer.cs @@ -0,0 +1,9 @@ +namespace Tizen.NUI.Binding +{ + internal class GestureRecognizer : Element, IGestureRecognizer + { + internal GestureRecognizer() + { + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/HandlerAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/HandlerAttribute.cs new file mode 100755 index 0000000..f582f5a --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/HandlerAttribute.cs @@ -0,0 +1,23 @@ +using System; + +namespace Tizen.NUI.Binding +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + internal abstract class HandlerAttribute : Attribute + { + protected HandlerAttribute(Type handler, Type target) + { + TargetType = target; + HandlerType = handler; + } + + internal Type HandlerType { get; private set; } + + internal Type TargetType { get; private set; } + + public virtual bool ShouldRegister() + { + return true; + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IControlTemplated.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IControlTemplated.cs new file mode 100755 index 0000000..403ccfc --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IControlTemplated.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; + +namespace Tizen.NUI.Binding +{ + internal interface IControlTemplated + { + // ControlTemplate ControlTemplate { get; set; } + + IList InternalChildren { get; } + + void OnControlTemplateChanged(ControlTemplate oldValue, ControlTemplate newValue); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IDynamicResourceHandler.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IDynamicResourceHandler.cs new file mode 100755 index 0000000..cd6b3ba --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IDynamicResourceHandler.cs @@ -0,0 +1,11 @@ +using System.ComponentModel; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IDynamicResourceHandler + { + void SetDynamicResource(BindableProperty property, string key); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IEffectControlProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IEffectControlProvider.cs new file mode 100755 index 0000000..8f61b22 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IEffectControlProvider.cs @@ -0,0 +1,17 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + /// + /// When implemented in a renderer, registers a platform-specific effect on an element. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IEffectControlProvider + { + /// + /// Registers the effect with the element by establishing the parent-child relations needed for rendering on the specific platform. + /// + /// The effect to register. + void RegisterEffect(Effect effect); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElement.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElement.cs new file mode 100755 index 0000000..331ec27 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElement.cs @@ -0,0 +1,14 @@ +using System; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + internal interface IElement + { + Element Parent { get; set; } + + //Use these 2 instead of an event to avoid cloning way too much multicastdelegates on mono + void AddResourcesChangedListener(Action onchanged); + void RemoveResourcesChangedListener(Action onchanged); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElementController.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElementController.cs new file mode 100755 index 0000000..f652069 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IElementController.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + internal interface IElementController + { + // IEffectControlProvider EffectControlProvider { get; set; } + + // bool EffectIsAttached(string name); + + // void SetValueFromRenderer(BindableProperty property, object value); + // void SetValueFromRenderer(BindablePropertyKey propertyKey, object value); + // ReadOnlyCollection LogicalChildren { get; } + // IPlatform Platform { get; set; } + // Element RealParent { get; } + // IEnumerable Descendants(); + // event EventHandler PlatformSet; + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IExtendedTypeConverter.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IExtendedTypeConverter.cs new file mode 100755 index 0000000..13318dd --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IExtendedTypeConverter.cs @@ -0,0 +1,13 @@ +using System; +using System.Globalization; + +namespace Tizen.NUI.Binding +{ + internal interface IExtendedTypeConverter + { + [Obsolete("IExtendedTypeConverter.ConvertFrom is obsolete as of version 2.2.0. Please use ConvertFromInvariantString (string, IServiceProvider) instead.")] + object ConvertFrom(CultureInfo culture, object value, IServiceProvider serviceProvider); + + object ConvertFromInvariantString(string value, IServiceProvider serviceProvider); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IGestureRecognizer.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IGestureRecognizer.cs new file mode 100755 index 0000000..9e2b688 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IGestureRecognizer.cs @@ -0,0 +1,8 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + internal interface IGestureRecognizer : INotifyPropertyChanged + { + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/INativeBindingService.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/INativeBindingService.cs new file mode 100755 index 0000000..70845b6 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/INativeBindingService.cs @@ -0,0 +1,10 @@ +namespace Tizen.NUI.Binding +{ + + internal interface INativeBindingService + { + bool TrySetBinding(object target, string propertyName, BindingBase binding); + bool TrySetBinding(object target, BindableProperty property, BindingBase binding); + bool TrySetValue(object target, BindableProperty property, object value); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatform.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatform.cs new file mode 100755 index 0000000..3240d4c --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatform.cs @@ -0,0 +1,20 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + /// + /// For internal use. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IPlatform + { + /// + /// Returns the native size. + /// + /// The view + /// The width constraint. + /// The height constraint. + /// The native size. + //SizeRequest GetNativeSize(BaseHandle view, double widthConstraint, double heightConstraint); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatformServices.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatformServices.cs new file mode 100755 index 0000000..5e46ac0 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IPlatformServices.cs @@ -0,0 +1,38 @@ +using System; +using System.ComponentModel; +using System.IO; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IPlatformServices + { + bool IsInvokeRequired { get; } + + void BeginInvokeOnMainThread(Action action); + + Ticker CreateTicker(); + + Assembly[] GetAssemblies(); + + string GetMD5Hash(string input); + + // double GetNamedSize(NamedSize size, Type targetElementType, bool useOldSizes); + + Task GetStreamAsync(Uri uri, CancellationToken cancellationToken); + + // IIsolatedStorageFile GetUserStoreForApplication(); + + // void OpenUriAction(Uri uri); + + void StartTimer(TimeSpan interval, Func callback); + + string RuntimePlatform { get; } + + void QuitApplication(); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IRegisterable.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IRegisterable.cs new file mode 100755 index 0000000..6974fcc --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IRegisterable.cs @@ -0,0 +1,6 @@ +namespace Tizen.NUI.Binding +{ + internal interface IRegisterable + { + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourceDictionary.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourceDictionary.cs new file mode 100755 index 0000000..e1132db --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourceDictionary.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IResourceDictionary : IEnumerable> + { + bool TryGetValue(string key, out object value); + + event EventHandler ValuesChanged; + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourcesProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourcesProvider.cs new file mode 100755 index 0000000..9cbc7e2 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IResourcesProvider.cs @@ -0,0 +1,13 @@ +using System.ComponentModel; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Binding +{ + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IResourcesProvider + { + bool IsResourcesCreated { get; } + ResourceDictionary Resources { get; set; } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ISystemResourcesProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ISystemResourcesProvider.cs new file mode 100755 index 0000000..ad52cc1 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ISystemResourcesProvider.cs @@ -0,0 +1,10 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface ISystemResourcesProvider + { + IResourceDictionary GetSystemResources(); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IValueConverter.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IValueConverter.cs new file mode 100755 index 0000000..a3c37c8 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/IValueConverter.cs @@ -0,0 +1,14 @@ +using System; +using System.Globalization; +using System.ComponentModel; + +namespace Tizen.NUI.Binding +{ + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IValueConverter + { + object Convert(object value, Type targetType, object parameter, CultureInfo culture); + object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/AttachedCollection.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/AttachedCollection.cs new file mode 100755 index 0000000..d5d1fc3 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/AttachedCollection.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Tizen.NUI.Binding +{ + internal class AttachedCollection : ObservableCollection, ICollection, IAttachedObject where T : BindableObject, IAttachedObject + { + readonly List _associatedObjects = new List(); + + public AttachedCollection() + { + } + + public AttachedCollection(IEnumerable collection) : base(collection) + { + } + + public AttachedCollection(IList list) : base(list) + { + } + + public void AttachTo(BindableObject bindable) + { + if (bindable == null) + throw new ArgumentNullException("bindable"); + OnAttachedTo(bindable); + } + + public void DetachFrom(BindableObject bindable) + { + OnDetachingFrom(bindable); + } + + protected override void ClearItems() + { + foreach (WeakReference weakbindable in _associatedObjects) + { + foreach (T item in this) + { + var bindable = weakbindable.Target as BindableObject; + if (bindable == null) + continue; + item.DetachFrom(bindable); + } + } + base.ClearItems(); + } + + protected override void InsertItem(int index, T item) + { + base.InsertItem(index, item); + foreach (WeakReference weakbindable in _associatedObjects) + { + var bindable = weakbindable.Target as BindableObject; + if (bindable == null) + continue; + item.AttachTo(bindable); + } + } + + protected virtual void OnAttachedTo(BindableObject bindable) + { + lock (_associatedObjects) + { + _associatedObjects.Add(new WeakReference(bindable)); + } + foreach (T item in this) + item.AttachTo(bindable); + } + + protected virtual void OnDetachingFrom(BindableObject bindable) + { + foreach (T item in this) + item.DetachFrom(bindable); + lock (_associatedObjects) + { + for (var i = 0; i < _associatedObjects.Count; i++) + { + object target = _associatedObjects[i].Target; + + if (target == null || target == bindable) + { + _associatedObjects.RemoveAt(i); + i--; + } + } + } + } + + protected override void RemoveItem(int index) + { + T item = this[index]; + foreach (WeakReference weakbindable in _associatedObjects) + { + var bindable = weakbindable.Target as BindableObject; + if (bindable == null) + continue; + item.DetachFrom(bindable); + } + + base.RemoveItem(index); + } + + protected override void SetItem(int index, T item) + { + T old = this[index]; + foreach (WeakReference weakbindable in _associatedObjects) + { + var bindable = weakbindable.Target as BindableObject; + if (bindable == null) + continue; + old.DetachFrom(bindable); + } + + base.SetItem(index, item); + + foreach (WeakReference weakbindable in _associatedObjects) + { + var bindable = weakbindable.Target as BindableObject; + if (bindable == null) + continue; + item.AttachTo(bindable); + } + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Behavior.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Behavior.cs new file mode 100755 index 0000000..388f3a8 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Behavior.cs @@ -0,0 +1,66 @@ +using System; +using System.Reflection; + +namespace Tizen.NUI.Binding +{ + internal abstract class Behavior : BindableObject, IAttachedObject + { + internal Behavior(Type associatedType) + { + if (associatedType == null) + throw new ArgumentNullException("associatedType"); + AssociatedType = associatedType; + } + + protected Type AssociatedType { get; } + + void IAttachedObject.AttachTo(BindableObject bindable) + { + if (bindable == null) + throw new ArgumentNullException("bindable"); + if (!AssociatedType.IsInstanceOfType(bindable)) + throw new InvalidOperationException("bindable not an instance of AssociatedType"); + OnAttachedTo(bindable); + } + + void IAttachedObject.DetachFrom(BindableObject bindable) + { + OnDetachingFrom(bindable); + } + + protected virtual void OnAttachedTo(BindableObject bindable) + { + } + + protected virtual void OnDetachingFrom(BindableObject bindable) + { + } + } + + internal abstract class Behavior : Behavior where T : BindableObject + { + protected Behavior() : base(typeof(T)) + { + } + + protected override void OnAttachedTo(BindableObject bindable) + { + base.OnAttachedTo(bindable); + OnAttachedTo((T)bindable); + } + + protected virtual void OnAttachedTo(T bindable) + { + } + + protected override void OnDetachingFrom(BindableObject bindable) + { + OnDetachingFrom((T)bindable); + base.OnDetachingFrom(bindable); + } + + protected virtual void OnDetachingFrom(T bindable) + { + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/BindingCondition.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/BindingCondition.cs new file mode 100755 index 0000000..63f0319 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/BindingCondition.cs @@ -0,0 +1,98 @@ +using System; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding +{ + [ProvideCompiled("Tizen.NUI.Xaml.Core.XamlC.PassthroughValueProvider")] + [AcceptEmptyServiceProvider] + internal sealed class BindingCondition : Condition, IValueProvider + { + readonly BindableProperty _boundProperty; + + BindingBase _binding; + object _triggerValue; + + public BindingCondition() + { + _boundProperty = BindableProperty.CreateAttached("Bound", typeof(object), typeof(BindingCondition), null, propertyChanged: OnBoundPropertyChanged); + } + + public BindingBase Binding + { + get { return _binding; } + set + { + if (_binding == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Binding once the Condition has been applied."); + _binding = value; + } + } + + public object Value + { + get { return _triggerValue; } + set + { + if (_triggerValue == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Value once the Condition has been applied."); + _triggerValue = value; + } + } + + object IValueProvider.ProvideValue(IServiceProvider serviceProvider) + { + //This is no longer required + return this; + } + + internal override bool GetState(BindableObject bindable) + { + object newValue = bindable.GetValue(_boundProperty); + return EqualsToValue(newValue); + } + + internal override void SetUp(BindableObject bindable) + { + if (Binding != null) + bindable.SetBinding(_boundProperty, Binding.Clone()); + } + + internal override void TearDown(BindableObject bindable) + { + bindable.RemoveBinding(_boundProperty); + bindable.ClearValue(_boundProperty); + } + + static IValueConverterProvider s_valueConverter = DependencyService.Get(); + + bool EqualsToValue(object other) + { + if ((other == Value) || (other != null && other.Equals(Value))) + return true; + + object converted = null; + if (s_valueConverter != null) + converted = s_valueConverter.Convert(Value, other != null ? other.GetType() : typeof(object), null, null); + else + return false; + + return (other == converted) || (other != null && other.Equals(converted)); + } + + void OnBoundPropertyChanged(BindableObject bindable, object oldValue, object newValue) + { + bool oldState = EqualsToValue(oldValue); + bool newState = EqualsToValue(newValue); + + if (newState == oldState) + return; + + if (ConditionChanged != null) + ConditionChanged(bindable, oldState, newState); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Condition.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Condition.cs new file mode 100755 index 0000000..74ee0a2 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/Condition.cs @@ -0,0 +1,51 @@ +using System; + +namespace Tizen.NUI.Binding +{ + internal abstract class Condition + { + Action _conditionChanged; + + bool _isSealed; + + internal Condition() + { + } + + internal Action ConditionChanged + { + get { return _conditionChanged; } + set + { + if (_conditionChanged == value) + return; + if (_conditionChanged != null) + throw new InvalidOperationException("The same condition instance can not be reused"); + _conditionChanged = value; + } + } + + internal bool IsSealed + { + get { return _isSealed; } + set + { + if (_isSealed == value) + return; + if (!value) + throw new InvalidOperationException("What is sealed can not be unsealed."); + _isSealed = value; + OnSealed(); + } + } + + internal abstract bool GetState(BindableObject bindable); + + internal virtual void OnSealed() + { + } + + internal abstract void SetUp(BindableObject bindable); + internal abstract void TearDown(BindableObject bindable); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/IAttachedObject.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/IAttachedObject.cs new file mode 100755 index 0000000..2e7e2c8 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/IAttachedObject.cs @@ -0,0 +1,8 @@ +namespace Tizen.NUI.Binding +{ + internal interface IAttachedObject + { + void AttachTo(BindableObject bindable); + void DetachFrom(BindableObject bindable); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/MultiCondition.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/MultiCondition.cs new file mode 100755 index 0000000..e25abf6 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/MultiCondition.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; + +namespace Tizen.NUI.Binding +{ + internal sealed class MultiCondition : Condition + { + readonly BindableProperty _aggregatedStateProperty; + + public MultiCondition() + { + _aggregatedStateProperty = BindableProperty.CreateAttached("AggregatedState", typeof(bool), typeof(MultiCondition), false, propertyChanged: OnAggregatedStatePropertyChanged); + Conditions = new TriggerBase.SealedList(); + } + + public IList Conditions { get; } + + internal override bool GetState(BindableObject bindable) + { + return (bool)bindable.GetValue(_aggregatedStateProperty); + } + + internal override void OnSealed() + { + ((TriggerBase.SealedList)Conditions).IsReadOnly = true; + foreach (Condition condition in Conditions) + condition.ConditionChanged = OnConditionChanged; + } + + internal override void SetUp(BindableObject bindable) + { + foreach (Condition condition in Conditions) + condition.SetUp(bindable); + } + + internal override void TearDown(BindableObject bindable) + { + foreach (Condition condition in Conditions) + condition.TearDown(bindable); + } + + void OnAggregatedStatePropertyChanged(BindableObject bindable, object oldValue, object newValue) + { + if ((bool)oldValue == (bool)newValue) + return; + + ConditionChanged?.Invoke(bindable, (bool)oldValue, (bool)newValue); + } + + void OnConditionChanged(BindableObject bindable, bool oldValue, bool newValue) + { + var oldState = (bool)bindable.GetValue(_aggregatedStateProperty); + var newState = true; + foreach (Condition condition in Conditions) + { + if (!condition.GetState(bindable)) + { + newState = false; + break; + } + } + if (newState != oldState) + bindable.SetValue(_aggregatedStateProperty, newState); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/PropertyCondition.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/PropertyCondition.cs new file mode 100755 index 0000000..241159c --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/PropertyCondition.cs @@ -0,0 +1,112 @@ +using System; +using System.ComponentModel; +using System.Reflection; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Xaml +{ + [ProvideCompiled("Tizen.NUI.Xaml.Core.XamlC.PassthroughValueProvider")] + [AcceptEmptyServiceProvider] + internal sealed class XamlPropertyCondition : Condition, IValueProvider + { + readonly BindableProperty _stateProperty; + + BindableProperty _property; + object _triggerValue; + + public XamlPropertyCondition() + { + _stateProperty = BindableProperty.CreateAttached("State", typeof(bool), typeof(XamlPropertyCondition), false, propertyChanged: OnStatePropertyChanged); + } + + public BindableProperty Property + { + get { return _property; } + set + { + if (_property == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Property once the Trigger has been applied."); + _property = value; + + //convert the value + if (_property != null && s_valueConverter != null) + { + Func minforetriever = () => Property.DeclaringType.GetRuntimeProperty(Property.PropertyName); + Value = s_valueConverter.Convert(Value, Property.ReturnType, minforetriever, null); + } + } + } + + public object Value + { + get { return _triggerValue; } + set + { + if (_triggerValue == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Value once the Trigger has been applied."); + + //convert the value + if (_property != null && s_valueConverter != null) + { + Func minforetriever = () => Property.DeclaringType.GetRuntimeProperty(Property.PropertyName); + value = s_valueConverter.Convert(value, Property.ReturnType, minforetriever, null); + } + _triggerValue = value; + } + } + + object IValueProvider.ProvideValue(IServiceProvider serviceProvider) + { + //This is no longer required + return this; + } + + internal override bool GetState(BindableObject bindable) + { + return (bool)bindable.GetValue(_stateProperty); + } + + static IValueConverterProvider s_valueConverter = DependencyService.Get(); + + internal override void SetUp(BindableObject bindable) + { + object newvalue = bindable.GetValue(Property); + bool newState = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value)); + bindable.SetValue(_stateProperty, newState); + bindable.PropertyChanged += OnAttachedObjectPropertyChanged; + } + + internal override void TearDown(BindableObject bindable) + { + bindable.ClearValue(_stateProperty); + bindable.PropertyChanged -= OnAttachedObjectPropertyChanged; + } + + void OnAttachedObjectPropertyChanged(object sender, PropertyChangedEventArgs e) + { + var bindable = (BindableObject)sender; + var oldState = (bool)bindable.GetValue(_stateProperty); + + if (Property == null) + return; + if (e.PropertyName != Property.PropertyName) + return; + object newvalue = bindable.GetValue(Property); + bool newstate = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value)); + if (oldState != newstate) + bindable.SetValue(_stateProperty, newstate); + } + + void OnStatePropertyChanged(BindableObject bindable, object oldValue, object newValue) + { + if ((bool)oldValue == (bool)newValue) + return; + + ConditionChanged?.Invoke(bindable, (bool)oldValue, (bool)newValue); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerAction.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerAction.cs new file mode 100755 index 0000000..7aa32d7 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerAction.cs @@ -0,0 +1,37 @@ +using System; + +namespace Tizen.NUI.Binding +{ + internal abstract class TriggerAction + { + internal TriggerAction(Type associatedType) + { + if (associatedType == null) + throw new ArgumentNullException("associatedType"); + AssociatedType = associatedType; + } + + protected Type AssociatedType { get; private set; } + + protected abstract void Invoke(object sender); + + internal virtual void DoInvoke(object sender) + { + Invoke(sender); + } + } + + internal abstract class TriggerAction : TriggerAction where T : BindableObject + { + protected TriggerAction() : base(typeof(T)) + { + } + + protected override void Invoke(object sender) + { + Invoke((T)sender); + } + + protected abstract void Invoke(T sender); + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerBase.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerBase.cs new file mode 100755 index 0000000..6eef482 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/TriggerBase.cs @@ -0,0 +1,213 @@ +using System; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; + +namespace Tizen.NUI.Binding +{ + internal abstract class TriggerBase : BindableObject, IAttachedObject + { + bool _isSealed; + + internal TriggerBase(Type targetType) + { + if (targetType == null) + throw new ArgumentNullException("targetType"); + TargetType = targetType; + + EnterActions = new SealedList(); + ExitActions = new SealedList(); + } + + internal TriggerBase(Condition condition, Type targetType) : this(targetType) + { + Setters = new SealedList(); + Condition = condition; + Condition.ConditionChanged = OnConditionChanged; + } + + public IList EnterActions { get; } + + public IList ExitActions { get; } + + public bool IsSealed + { + get { return _isSealed; } + private set + { + if (_isSealed == value) + return; + if (!value) + throw new InvalidOperationException("What is sealed can not be unsealed."); + _isSealed = value; + OnSeal(); + } + } + + public Type TargetType { get; } + + internal Condition Condition { get; } + + //Setters and Condition are used by Trigger, DataTrigger and MultiTrigger + internal IList Setters { get; } + + void IAttachedObject.AttachTo(BindableObject bindable) + { + IsSealed = true; + + if (bindable == null) + throw new ArgumentNullException("bindable"); + if (!TargetType.IsInstanceOfType(bindable)) + throw new InvalidOperationException("bindable not an instance of AssociatedType"); + OnAttachedTo(bindable); + } + + void IAttachedObject.DetachFrom(BindableObject bindable) + { + if (bindable == null) + throw new ArgumentNullException("bindable"); + OnDetachingFrom(bindable); + } + + internal virtual void OnAttachedTo(BindableObject bindable) + { + if (Condition != null) + Condition.SetUp(bindable); + } + + internal virtual void OnDetachingFrom(BindableObject bindable) + { + if (Condition != null) + Condition.TearDown(bindable); + } + + internal virtual void OnSeal() + { + ((SealedList)EnterActions).IsReadOnly = true; + ((SealedList)ExitActions).IsReadOnly = true; + if (Setters != null) + ((SealedList)Setters).IsReadOnly = true; + if (Condition != null) + Condition.IsSealed = true; + } + + void OnConditionChanged(BindableObject bindable, bool oldValue, bool newValue) + { + if (newValue) + { + foreach (TriggerAction action in EnterActions) + action.DoInvoke(bindable); + foreach (Setter setter in Setters) + setter.Apply(bindable); + } + else + { + foreach (Setter setter in Setters) + setter.UnApply(bindable); + foreach (TriggerAction action in ExitActions) + action.DoInvoke(bindable); + } + } + + internal class SealedList : IList + { + readonly IList _actual; + + bool _isReadOnly; + + public SealedList() + { + _actual = new List(); + } + + public void Add(T item) + { + if (IsReadOnly) + throw new InvalidOperationException("This list is ReadOnly"); + _actual.Add(item); + } + + public void Clear() + { + if (IsReadOnly) + throw new InvalidOperationException("This list is ReadOnly"); + _actual.Clear(); + } + + public bool Contains(T item) + { + return _actual.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) + { + _actual.CopyTo(array, arrayIndex); + } + + public int Count + { + get { return _actual.Count; } + } + + public bool IsReadOnly + { + get { return _isReadOnly; } + set + { + if (_isReadOnly == value) + return; + if (!value) + throw new InvalidOperationException("Can't change this back to non readonly"); + _isReadOnly = value; + } + } + + public bool Remove(T item) + { + if (IsReadOnly) + throw new InvalidOperationException("This list is ReadOnly"); + return _actual.Remove(item); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)_actual).GetEnumerator(); + } + + public IEnumerator GetEnumerator() + { + return _actual.GetEnumerator(); + } + + public int IndexOf(T item) + { + return _actual.IndexOf(item); + } + + public void Insert(int index, T item) + { + if (IsReadOnly) + throw new InvalidOperationException("This list is ReadOnly"); + _actual.Insert(index, item); + } + + public T this[int index] + { + get { return _actual[index]; } + set + { + if (IsReadOnly) + throw new InvalidOperationException("This list is ReadOnly"); + _actual[index] = value; + } + } + + public void RemoveAt(int index) + { + if (IsReadOnly) + throw new InvalidOperationException("This list is ReadOnly"); + _actual.RemoveAt(index); + } + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/XamlPropertyCondition.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/XamlPropertyCondition.cs new file mode 100755 index 0000000..baafae3 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Interactivity/XamlPropertyCondition.cs @@ -0,0 +1,112 @@ +using System; +using System.ComponentModel; +using System.Reflection; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding +{ + [ProvideCompiled("Tizen.NUI.Core.XamlC.PassthroughValueProvider")] + [AcceptEmptyServiceProvider] + internal sealed class XamlPropertyCondition : Condition, IValueProvider + { + readonly BindableProperty _stateProperty; + + BindableProperty _property; + object _triggerValue; + + public XamlPropertyCondition() + { + _stateProperty = BindableProperty.CreateAttached("State", typeof(bool), typeof(XamlPropertyCondition), false, propertyChanged: OnStatePropertyChanged); + } + + public BindableProperty Property + { + get { return _property; } + set + { + if (_property == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Property once the Trigger has been applied."); + _property = value; + + //convert the value + if (_property != null && s_valueConverter != null) + { + Func minforetriever = () => Property.DeclaringType.GetRuntimeProperty(Property.PropertyName); + Value = s_valueConverter.Convert(Value, Property.ReturnType, minforetriever, null); + } + } + } + + public object Value + { + get { return _triggerValue; } + set + { + if (_triggerValue == value) + return; + if (IsSealed) + throw new InvalidOperationException("Can not change Value once the Trigger has been applied."); + + //convert the value + if (_property != null && s_valueConverter != null) + { + Func minforetriever = () => Property.DeclaringType.GetRuntimeProperty(Property.PropertyName); + value = s_valueConverter.Convert(value, Property.ReturnType, minforetriever, null); + } + _triggerValue = value; + } + } + + object IValueProvider.ProvideValue(IServiceProvider serviceProvider) + { + //This is no longer required + return this; + } + + internal override bool GetState(BindableObject bindable) + { + return (bool)bindable.GetValue(_stateProperty); + } + + static IValueConverterProvider s_valueConverter = DependencyService.Get(); + + internal override void SetUp(BindableObject bindable) + { + object newvalue = bindable.GetValue(Property); + bool newState = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value)); + bindable.SetValue(_stateProperty, newState); + bindable.PropertyChanged += OnAttachedObjectPropertyChanged; + } + + internal override void TearDown(BindableObject bindable) + { + bindable.ClearValue(_stateProperty); + bindable.PropertyChanged -= OnAttachedObjectPropertyChanged; + } + + void OnAttachedObjectPropertyChanged(object sender, PropertyChangedEventArgs e) + { + var bindable = (BindableObject)sender; + var oldState = (bool)bindable.GetValue(_stateProperty); + + if (Property == null) + return; + if (e.PropertyName != Property.PropertyName) + return; + object newvalue = bindable.GetValue(Property); + bool newstate = (newvalue == Value) || (newvalue != null && newvalue.Equals(Value)); + if (oldState != newstate) + bindable.SetValue(_stateProperty, newstate); + } + + void OnStatePropertyChanged(BindableObject bindable, object oldValue, object newValue) + { + if ((bool)oldValue == (bool)newValue) + return; + + ConditionChanged?.Invoke(bindable, (bool)oldValue, (bool)newValue); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/DynamicResource.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/DynamicResource.cs new file mode 100755 index 0000000..67c6ff7 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/DynamicResource.cs @@ -0,0 +1,15 @@ +using System.ComponentModel; + +namespace Tizen.NUI.Binding.Internals +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal class DynamicResource + { + public DynamicResource(string key) + { + Key = key; + } + + public string Key { get; private set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/IDataTemplate.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/IDataTemplate.cs new file mode 100755 index 0000000..727cd98 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/IDataTemplate.cs @@ -0,0 +1,11 @@ +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Binding.Internals +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IDataTemplate + { + Func LoadTemplate { get; set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INameScope.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INameScope.cs new file mode 100755 index 0000000..6da4b4c --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INameScope.cs @@ -0,0 +1,15 @@ +using System; +using System.ComponentModel; +using System.Xml; + +namespace Tizen.NUI.Binding.Internals +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface INameScope + { + object FindByName(string name); + void RegisterName(string name, object scopedElement); + void UnregisterName(string name); + [Obsolete]void RegisterName(string name, object scopedElement, IXmlLineInfo xmlLineInfo); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INamescopeProvider.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INamescopeProvider.cs new file mode 100755 index 0000000..ff4bbf1 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/INamescopeProvider.cs @@ -0,0 +1,9 @@ +using System; + +namespace Tizen.NUI.Binding.Internals +{ + interface INameScopeProvider + { + INameScope NameScope { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/NameScope.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/NameScope.cs new file mode 100755 index 0000000..9eee776 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/NameScope.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Xml; +using Tizen.NUI.Binding; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding.Internals +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal class NameScope : INameScope + { + public static readonly BindableProperty NameScopeProperty = BindableProperty.CreateAttached("NameScope", typeof(INameScope), typeof(NameScope), default(INameScope)); + + readonly Dictionary _names = new Dictionary(); + + object INameScope.FindByName(string name) + { + if (_names.ContainsKey(name)) + return _names[name]; + return null; + } + + void INameScope.RegisterName(string name, object scopedElement) + { + if (_names.ContainsKey(name)) + throw new ArgumentException("An element with the same key already exists in NameScope", "name"); + + _names[name] = scopedElement; + } + + [Obsolete] + void INameScope.RegisterName(string name, object scopedElement, IXmlLineInfo xmlLineInfo) + { + try + { + ((INameScope)this).RegisterName(name, scopedElement); + } + catch (ArgumentException) + { + throw new XamlParseException(string.Format("An element with the name \"{0}\" already exists in this NameScope", name), xmlLineInfo); + } + } + + void INameScope.UnregisterName(string name) + { + _names.Remove(name); + } + + public static INameScope GetNameScope(BindableObject bindable) + { + return (INameScope)bindable.GetValue(NameScopeProperty); + } + + public static void SetNameScope(BindableObject bindable, INameScope value) + { + bindable.SetValue(NameScopeProperty, value); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/PreserveAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/PreserveAttribute.cs new file mode 100755 index 0000000..1ff17cb --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/PreserveAttribute.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel; + +namespace Tizen.NUI.Binding.Internals +{ + [AttributeUsage(AttributeTargets.All)] + [EditorBrowsable(EditorBrowsableState.Never)] + internal class PreserveAttribute : Attribute + { + public bool AllMembers; + public bool Conditional; + + public PreserveAttribute(bool allMembers, bool conditional) + { + AllMembers = allMembers; + Conditional = conditional; + } + + public PreserveAttribute() + { + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/ResourceLoader.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/ResourceLoader.cs new file mode 100755 index 0000000..a305af3 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/ResourceLoader.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; +using System.Reflection; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding.Internals +{ + internal static class ResourceLoader + { + static Func resourceProvider = (asmName, path) => + { + return null; + //string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource; + //path = resource + path; + + //string ret = File.ReadAllText(path); + //return ret; + }; + + //takes a resource path, returns string content + public static Func ResourceProvider123 + { + get => resourceProvider; + internal set + { + DesignMode.IsDesignModeEnabled = true; + resourceProvider = value; + } + } + + //takes a resource path, returns string content + public static Func ResourceProvider { + get => resourceProvider; + internal set { + DesignMode.IsDesignModeEnabled = true; + resourceProvider = value; + } + } + + internal static Action ExceptionHandler { get; set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/Ticker.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/Ticker.cs new file mode 100755 index 0000000..f93f02b --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/Ticker.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; + +namespace Tizen.NUI.Binding.Internals +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal abstract class Ticker + { + static Ticker s_ticker; + readonly Stopwatch _stopwatch; + readonly List>> _timeouts; + + int _count; + bool _enabled; + + protected Ticker() + { + _count = 0; + _timeouts = new List>>(); + + _stopwatch = new Stopwatch(); + } + + public static void SetDefault(Ticker ticker) => Default = ticker; + public static Ticker Default + { + internal set { s_ticker = value; } + get { return s_ticker ?? (s_ticker = Device.PlatformServices.CreateTicker()); } + } + + public virtual int Insert(Func timeout) + { + _count++; + _timeouts.Add(new Tuple>(_count, timeout)); + + if (!_enabled) + { + _enabled = true; + Enable(); + } + + return _count; + } + + public virtual void Remove(int handle) + { + Device.BeginInvokeOnMainThread(() => + { + _timeouts.RemoveAll(t => t.Item1 == handle); + + if (!_timeouts.Any()) + { + _enabled = false; + Disable(); + } + }); + } + + protected abstract void DisableTimer(); + + protected abstract void EnableTimer(); + + protected void SendSignals(int timestep = -1) + { + long step = timestep >= 0 ? timestep : _stopwatch.ElapsedMilliseconds; + _stopwatch.Reset(); + _stopwatch.Start(); + + var localCopy = new List>>(_timeouts); + foreach (Tuple> timeout in localCopy) + { + bool remove = !timeout.Item2(step); + if (remove) + _timeouts.RemoveAll(t => t.Item1 == timeout.Item1); + } + + if (!_timeouts.Any()) + { + _enabled = false; + Disable(); + } + } + + void Disable() + { + _stopwatch.Reset(); + DisableTimer(); + } + + void Enable() + { + _stopwatch.Start(); + EnableTimer(); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/TypedBinding.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/TypedBinding.cs new file mode 100755 index 0000000..1605b17 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Internals/TypedBinding.cs @@ -0,0 +1,301 @@ +#define DO_NOT_CHECK_FOR_BINDING_REUSE + +using System; +using System.ComponentModel; +using System.Globalization; +using System.Collections.Generic; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Binding.Internals +{ + //FIXME: need a better name for this, and share with Binding, so we can share more unittests + [EditorBrowsable(EditorBrowsableState.Never)] + internal abstract class TypedBindingBase : BindingBase + { + IValueConverter _converter; + object _converterParameter; + object _source; + string _updateSourceEventName; + + public IValueConverter Converter { + get { return _converter; } + set { + ThrowIfApplied(); + _converter = value; + } + } + + public object ConverterParameter { + get { return _converterParameter; } + set { + ThrowIfApplied(); + _converterParameter = value; + } + } + + public object Source { + get { return _source; } + set { + ThrowIfApplied(); + _source = value; + } + } + + internal string UpdateSourceEventName { + get { return _updateSourceEventName; } + set { + ThrowIfApplied(); + _updateSourceEventName = value; + } + } + + internal TypedBindingBase() + { + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + internal sealed class TypedBinding : TypedBindingBase + { + readonly Func _getter; + readonly Action _setter; + readonly PropertyChangedProxy [] _handlers; + + public TypedBinding(Func getter, Action setter, Tuple, string> [] handlers) + { + if (getter == null) + throw new ArgumentNullException(nameof(getter)); + + _getter = getter; + _setter = setter; + + if (handlers == null) + return; + + _handlers = new PropertyChangedProxy [handlers.Length]; + for (var i = 0; i < handlers.Length; i++) + _handlers [i] = new PropertyChangedProxy(handlers [i].Item1, handlers [i].Item2, this); + } + + readonly WeakReference _weakSource = new WeakReference(null); + readonly WeakReference _weakTarget = new WeakReference(null); + BindableProperty _targetProperty; + + // Applies the binding to a previously set source and target. + internal override void Apply(bool fromTarget = false) + { + base.Apply(fromTarget); + + BindableObject target; +#if DO_NOT_CHECK_FOR_BINDING_REUSE + if (!_weakTarget.TryGetTarget(out target)) + throw new InvalidOperationException(); +#else + if (!_weakTarget.TryGetTarget(out target) || target == null) { + Unapply(); + return; + } +#endif + object source; + if (_weakSource.TryGetTarget(out source) && source != null) + ApplyCore(source, target, _targetProperty, fromTarget); + } + + // Applies the binding to a new source or target. + internal override void Apply(object context, BindableObject bindObj, BindableProperty targetProperty, bool fromBindingContextChanged = false) + { + _targetProperty = targetProperty; + var source = Source ?? Context ?? context; + var isApplied = IsApplied; + + if (Source != null && isApplied && fromBindingContextChanged) + return; + + base.Apply(source, bindObj, targetProperty, fromBindingContextChanged); + +#if (!DO_NOT_CHECK_FOR_BINDING_REUSE) + BindableObject prevTarget; + if (_weakTarget.TryGetTarget(out prevTarget) && !ReferenceEquals(prevTarget, bindObj)) + throw new InvalidOperationException("Binding instances can not be reused"); + + object previousSource; + if (_weakSource.TryGetTarget(out previousSource) && !ReferenceEquals(previousSource, source)) + throw new InvalidOperationException("Binding instances can not be reused"); +#endif + _weakSource.SetTarget(source); + _weakTarget.SetTarget(bindObj); + + ApplyCore(source, bindObj, targetProperty); + } + + internal override BindingBase Clone() + { + Tuple, string> [] handlers = _handlers == null ? null : new Tuple, string> [_handlers.Length]; + if (handlers != null) { + for (var i = 0; i < _handlers.Length; i++) + handlers [i] = new Tuple, string>(_handlers [i].PartGetter, _handlers [i].PropertyName); + } + return new TypedBinding(_getter, _setter, handlers) { + Mode = Mode, + Converter = Converter, + ConverterParameter = ConverterParameter, + StringFormat = StringFormat, + Source = Source, + UpdateSourceEventName = UpdateSourceEventName, + }; + } + + internal override object GetSourceValue(object value, Type targetPropertyType) + { + if (Converter != null) + value = Converter.Convert(value, targetPropertyType, ConverterParameter, CultureInfo.CurrentUICulture); + + //return base.GetSourceValue(value, targetPropertyType); + if (StringFormat != null) + return string.Format(StringFormat, value); + + return value; + } + + internal override object GetTargetValue(object value, Type sourcePropertyType) + { + if (Converter != null) + value = Converter.ConvertBack(value, sourcePropertyType, ConverterParameter, CultureInfo.CurrentUICulture); + + //return base.GetTargetValue(value, sourcePropertyType); + return value; + } + + internal override void Unapply(bool fromBindingContextChanged = false) + { + if (Source != null && fromBindingContextChanged && IsApplied) + return; + +#if (!DO_NOT_CHECK_FOR_BINDING_REUSE) + base.Unapply(fromBindingContextChanged:fromBindingContextChanged); +#endif + if (_handlers != null) + Unsubscribe(); + +#if (!DO_NOT_CHECK_FOR_BINDING_REUSE) + _weakSource.SetTarget(null); + _weakTarget.SetTarget(null); +#endif + } + + // ApplyCore is as slim as it should be: + // Setting 100000 values : 17ms. + // ApplyCore 100000 (w/o INPC, w/o unnapply) : 20ms. + internal void ApplyCore(object sourceObject, BindableObject target, BindableProperty property, bool fromTarget = false) + { + var isTSource = sourceObject != null && sourceObject is TSource; + var mode = this.GetRealizedMode(property); + if ((mode == BindingMode.OneWay || mode == BindingMode.OneTime) && fromTarget) + return; + + var needsGetter = (mode == BindingMode.TwoWay && !fromTarget) || mode == BindingMode.OneWay || mode == BindingMode.OneTime; + + if (isTSource && (mode == BindingMode.OneWay || mode == BindingMode.TwoWay) && _handlers != null) + Subscribe((TSource)sourceObject); + + if (needsGetter) { + var value = property.DefaultValue; + if (isTSource) { + try { + value = GetSourceValue(_getter((TSource)sourceObject), property.ReturnType); + } catch (Exception ex) when (ex is NullReferenceException || ex is KeyNotFoundException) { + } + } + if (!TryConvert(ref value, property, property.ReturnType, true)) { + // Log.Warning("Binding", "{0} can not be converted to type '{1}'", value, property.ReturnType); + return; + } + target.SetValueCore(property, value, SetValueFlags.ClearDynamicResource, BindableObject.SetValuePrivateFlags.Default | BindableObject.SetValuePrivateFlags.Converted, false); + return; + } + + var needsSetter = (mode == BindingMode.TwoWay && fromTarget) || mode == BindingMode.OneWayToSource; + if (needsSetter && _setter != null && isTSource) { + var value = GetTargetValue(target.GetValue(property), typeof(TProperty)); + if (!TryConvert(ref value, property, typeof(TProperty), false)) { + // Log.Warning("Binding", "{0} can not be converted to type '{1}'", value, typeof(TProperty)); + return; + } + _setter((TSource)sourceObject, (TProperty)value); + } + } + + static bool TryConvert(ref object value, BindableProperty targetProperty, Type convertTo, bool toTarget) + { + if (value == null) + return true; + if ((toTarget && targetProperty.TryConvert(ref value)) || (!toTarget && convertTo.IsInstanceOfType(value))) + return true; + + object original = value; + try { + value = Convert.ChangeType(value, convertTo, CultureInfo.InvariantCulture); + return true; + } catch (Exception ex ) when (ex is InvalidCastException || ex is FormatException||ex is OverflowException) { + value = original; + return false; + } + } + + class PropertyChangedProxy + { + public Func PartGetter { get; } + public string PropertyName { get; } + public BindingExpression.WeakPropertyChangedProxy Listener { get; } + WeakReference _weakPart = new WeakReference(null); + readonly BindingBase _binding; + + public INotifyPropertyChanged Part { + get { + INotifyPropertyChanged target; + if (_weakPart.TryGetTarget(out target)) + return target; + return null; + } + set { + _weakPart.SetTarget(value); + Listener.SubscribeTo(value, OnPropertyChanged); + } + } + + public PropertyChangedProxy(Func partGetter, string propertyName, BindingBase binding) + { + PartGetter = partGetter; + PropertyName = propertyName; + _binding = binding; + Listener = new BindingExpression.WeakPropertyChangedProxy(); + } + + void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (!string.IsNullOrEmpty(e.PropertyName) && string.CompareOrdinal(e.PropertyName, PropertyName) != 0) + return; + Device.BeginInvokeOnMainThread(() => _binding.Apply(false)); + } + } + + void Subscribe(TSource sourceObject) + { + for (var i = 0; i < _handlers.Length; i++) { + var part = _handlers [i].PartGetter(sourceObject); + if (part == null) + break; + var inpc = part as INotifyPropertyChanged; + if (inpc == null) + continue; + _handlers [i].Part = (inpc); + } + } + + void Unsubscribe() + { + for (var i = 0; i < _handlers.Length; i++) + _handlers [i].Listener.Unsubscribe(); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ListStringTypeConverter.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ListStringTypeConverter.cs new file mode 100755 index 0000000..e7327c3 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ListStringTypeConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Tizen.NUI.Binding +{ + [Xaml.ProvideCompiled("Tizen.NUI.Core.XamlC.ListStringTypeConverter")] + [Xaml.TypeConversion(typeof(List))] + internal class ListStringTypeConverter : TypeConverter + { + public override object ConvertFromInvariantString(string value) + { + if (value == null) + return null; + + return value.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList(); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NameScopeExtensions.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NameScopeExtensions.cs new file mode 100755 index 0000000..205df37 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NameScopeExtensions.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.ComponentModel; +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class NameScopeExtensions + { + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public static T FindByName(this Element element, string name) + { + return ((INameScope)element).FindByName(name); + } + + internal static T FindByName(this INameScope namescope, string name) + { + return (T)namescope.FindByName(name); + } + + private static Stack elementStack = new Stack(); + + internal static void PushElement(object element) + { + elementStack.Push((Element)element); + } + + internal static void PopElement() + { + elementStack.Pop(); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static T FindByNameInCurrentNameScope(string name) + { + return FindByName(elementStack.Peek(), name); + } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NullEffect.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NullEffect.cs new file mode 100755 index 0000000..2826045 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/NullEffect.cs @@ -0,0 +1,13 @@ +namespace Tizen.NUI.Binding +{ + internal class NullEffect : Effect + { + protected override void OnAttached() + { + } + + protected override void OnDetached() + { + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnIdiom.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnIdiom.cs new file mode 100755 index 0000000..172c8ee --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnIdiom.cs @@ -0,0 +1,35 @@ +using Tizen.NUI.Binding.Internals; + +namespace Tizen.NUI.Binding +{ + internal class OnIdiom + { + public T Phone { get; set; } + + public T Tablet { get; set; } + + public T Desktop { get; set; } + + public T TV { get; set; } + + public T Watch { get; set; } + + public static implicit operator T(OnIdiom onIdiom) + { + switch (Device.Idiom) + { + default: + case TargetIdiom.Phone: + return onIdiom.Phone; + case TargetIdiom.Tablet: + return onIdiom.Tablet; + case TargetIdiom.Desktop: + return onIdiom.Desktop; + case TargetIdiom.TV: + return onIdiom.TV; + case TargetIdiom.Watch: + return onIdiom.Watch; + } + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnPlatform.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnPlatform.cs new file mode 100755 index 0000000..7186a7d --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/OnPlatform.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding +{ + [ContentProperty("Platforms")] + internal class OnPlatform + { + public OnPlatform() + { + Platforms = new List(); + } + + bool useLegacyFallback; + T android; + [Obsolete] + public T Android { + get { return android; } + set { + useLegacyFallback = true; + android = value; + } + } + + T ios; + [Obsolete] + public T iOS { + get { return ios; } + set { + useLegacyFallback = true; + ios = value; + } + } + + T winPhone; + [Obsolete] + public T WinPhone { + get { return winPhone; } + set { + useLegacyFallback = true; + winPhone = value; + } + } + + bool hasDefault; + T @default; + public T Default { + get { return @default; } + set { + hasDefault = true; + @default = value; + } + } + + public IList Platforms { get; private set; } + +#pragma warning disable RECS0108 // Warns about static fields in generic types + static readonly IValueConverterProvider s_valueConverter = DependencyService.Get(); +#pragma warning restore RECS0108 // Warns about static fields in generic types + + public static implicit operator T(OnPlatform onPlatform) + { + foreach (var onPlat in onPlatform.Platforms) { + if (onPlat.Platform == null) + continue; + if (!onPlat.Platform.Contains(Device.RuntimePlatform)) + continue; + if (s_valueConverter == null) + continue; + return (T)s_valueConverter.Convert(onPlat.Value, typeof(T), null, null); + } + + if (!onPlatform.useLegacyFallback) + return onPlatform.hasDefault ? onPlatform.@default : default(T); + + //legacy fallback +#pragma warning disable 0618, 0612 + return Device.OnPlatform(iOS: onPlatform.iOS, Android: onPlatform.Android, WinPhone: onPlatform.WinPhone); +#pragma warning restore 0618, 0612 + } + } + + [ContentProperty("Value")] + internal class On + { + [TypeConverter(typeof(ListStringTypeConverter))] + public IList Platform { get; set; } + public object Value { get; set; } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ParameterAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ParameterAttribute.cs new file mode 100755 index 0000000..de2c8bd --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ParameterAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Binding +{ + [AttributeUsage(AttributeTargets.Parameter)] + internal sealed class ParameterAttribute : Attribute + { + public ParameterAttribute(string name) + { + Name = name; + } + + public string Name { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Performance.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Performance.cs new file mode 100755 index 0000000..2a2693e --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Performance.cs @@ -0,0 +1,15 @@ +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System; +using System.Threading; + +namespace Tizen.NUI +{ + [EditorBrowsable(EditorBrowsableState.Never)] + internal interface IPerformanceProvider + { + void Stop(string reference, string tag, string path, string member); + + void Start(string reference, string tag, string path, string member); + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Registrar.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Registrar.cs new file mode 100755 index 0000000..ee075dc --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/Registrar.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using Tizen.NUI.Binding; + +namespace Tizen.NUI.Binding +{ + // Previewer uses reflection to bind to this method; Removal or modification of visibility will break previewer. + internal static class Registrar + { + internal static void RegisterAll(Type[] attrTypes) => Internals.Registrar.RegisterAll(attrTypes); + } +} + +namespace Tizen.NUI.Binding.Internals +{ + /// + /// For internal use. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal class Registrar where TRegistrable : class + { + readonly Dictionary _handlers = new Dictionary(); + + /// + /// Register. + /// + /// The type of the view + /// The type of the render. + public void Register(Type tview, Type trender) + { + //avoid caching null renderers + if (trender == null) + return; + _handlers[tview] = trender; + } + + internal TRegistrable GetHandler(Type type) + { + Type handlerType = GetHandlerType(type); + if (handlerType == null) + return null; + + object handler = DependencyResolver.ResolveOrCreate(handlerType); + + return (TRegistrable)handler; + } + + internal TRegistrable GetHandler(Type type, params object[] args) + { + if (args.Length == 0) + { + return GetHandler(type); + } + + Type handlerType = GetHandlerType(type); + if (handlerType == null) + return null; + + return (TRegistrable)DependencyResolver.ResolveOrCreate(handlerType, args); + } + + /// + /// For internal use. Returns handler. + /// + /// The type of the handler + /// The type. + /// The handler instance. + public TOut GetHandler(Type type) where TOut : TRegistrable + { + return (TOut)GetHandler(type); + } + + /// + /// For internal use. Returns handler. + /// + /// The type of the handler + /// The type. + /// The args of the type + /// The handler instance. + public TOut GetHandler(Type type, params object[] args) where TOut : TRegistrable + { + return (TOut)GetHandler(type, args); + } + + /// + /// For internal use. Return the handler of the object. + /// + /// Thetype + /// The object instance. + /// The handle of the obj. + public TOut GetHandlerForObject(object obj) where TOut : TRegistrable + { + if (obj == null) + throw new ArgumentNullException(nameof(obj)); + + var reflectableType = obj as IReflectableType; + var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType(); + + return (TOut)GetHandler(type); + } + + /// + /// For inetrnal use. Return the handler of the object. + /// + /// The type + /// The object instance + /// The args of the type + /// The handler of the object. + public TOut GetHandlerForObject(object obj, params object[] args) where TOut : TRegistrable + { + if (obj == null) + throw new ArgumentNullException(nameof(obj)); + + var reflectableType = obj as IReflectableType; + var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType(); + + return (TOut)GetHandler(type, args); + } + + /// + /// For internal use. Returns the handle type. + /// + /// The view type. + /// The type of the handle. + public Type GetHandlerType(Type viewType) + { + Type type; + if (LookupHandlerType(viewType, out type)) + return type; + + // lazy load render-view association with RenderWithAttribute (as opposed to using ExportRenderer) + var attribute = viewType.GetTypeInfo().GetCustomAttribute(); + if (attribute == null) + { + Register(viewType, null); // Cache this result so we don't have to do GetCustomAttribute again + return null; + } + + type = attribute.Type; + + if (type.Name.StartsWith("_", StringComparison.Ordinal)) + { + // TODO: Remove attribute2 once renderer names have been unified across all platforms + var attribute2 = type.GetTypeInfo().GetCustomAttribute(); + if (attribute2 != null) + type = attribute2.Type; + + if (type.Name.StartsWith("_", StringComparison.Ordinal)) + { + Register(viewType, null); // Cache this result so we don't work through this chain again + return null; + } + } + + Register(viewType, type); // Register this so we don't have to look for the RenderWith Attibute again in the future + + return type; + } + + /// + /// For internal use. Return the handle type of the object + /// + /// The object instance. + /// The type of the handler. + public Type GetHandlerTypeForObject(object obj) + { + if (obj == null) + throw new ArgumentNullException(nameof(obj)); + + var reflectableType = obj as IReflectableType; + var type = reflectableType != null ? reflectableType.GetTypeInfo().AsType() : obj.GetType(); + + return GetHandlerType(type); + } + + bool LookupHandlerType(Type viewType, out Type handlerType) + { + Type type = viewType; + + while (type != null) + { + if (_handlers.ContainsKey(type)) + { + handlerType = _handlers[type]; + return true; + } + + type = type.GetTypeInfo().BaseType; + } + + handlerType = null; + return false; + } + } + + /// + /// For internal use + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class Registrar + { + static Registrar() + { + Registered = new Registrar(); + } + + internal static Dictionary Effects { get; } = new Dictionary(); + internal static Dictionary StyleProperties { get; } = new Dictionary(); + + public static IEnumerable ExtraAssemblies { get; set; } + + public static Registrar Registered { get; internal set; } + + public static void RegisterAll(Type[] attrTypes) + { + Assembly[] assemblies = Device.GetAssemblies(); + if (ExtraAssemblies != null) + assemblies = assemblies.Union(ExtraAssemblies).ToArray(); + + Assembly defaultRendererAssembly = Device.PlatformServices.GetType().GetTypeInfo().Assembly; + int indexOfExecuting = Array.IndexOf(assemblies, defaultRendererAssembly); + + if (indexOfExecuting > 0) + { + assemblies[indexOfExecuting] = assemblies[0]; + assemblies[0] = defaultRendererAssembly; + } + + // Don't use LINQ for performance reasons + // Naive implementation can easily take over a second to run + foreach (Assembly assembly in assemblies) + { + foreach (Type attrType in attrTypes) + { + Attribute[] attributes; + try + { + attributes = assembly.GetCustomAttributes(attrType).ToArray(); + } + catch (System.IO.FileNotFoundException) + { + // Sometimes the previewer doesn't actually have everything required for these loads to work + Console.WriteLine(nameof(Registrar), "Could not load assembly: {0} for Attibute {1} | Some renderers may not be loaded", assembly.FullName, attrType.FullName); + continue; + } + var length = attributes.Length; + for (var i = 0; i < length;i++) + { + var attribute = (HandlerAttribute)attributes[i]; + if (attribute.ShouldRegister()) + Registered.Register(attribute.HandlerType, attribute.TargetType); + } + } + + string resolutionName = assembly.FullName; + var resolutionNameAttribute = (ResolutionGroupNameAttribute)assembly.GetCustomAttribute(typeof(ResolutionGroupNameAttribute)); + if (resolutionNameAttribute != null) + resolutionName = resolutionNameAttribute.ShortName; + + Attribute[] effectAttributes = assembly.GetCustomAttributes(typeof(ExportEffectAttribute)).ToArray(); + var exportEffectsLength = effectAttributes.Length; + for (var i = 0; i < exportEffectsLength;i++) + { + var effect = (ExportEffectAttribute)effectAttributes[i]; + Effects [resolutionName + "." + effect.Id] = effect.Type; + } + + Attribute[] styleAttributes = assembly.GetCustomAttributes(typeof(StyleSheets.StylePropertyAttribute)).ToArray(); + var stylePropertiesLength = styleAttributes.Length; + for (var i = 0; i < stylePropertiesLength; i++) + { + var attribute = (StyleSheets.StylePropertyAttribute)styleAttributes[i]; + StyleProperties[attribute.CssPropertyName] = attribute; + } + } + + DependencyService.Initialize(assemblies); + } + } +} diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/RenderWithAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/RenderWithAttribute.cs new file mode 100755 index 0000000..57b3398 --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/RenderWithAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Binding +{ + [AttributeUsage(AttributeTargets.Class)] + internal sealed class RenderWithAttribute : Attribute + { + public RenderWithAttribute(Type type) + { + Type = type; + } + + public Type Type { get; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResolutionGroupNameAttribute.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResolutionGroupNameAttribute.cs new file mode 100755 index 0000000..4320f9a --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResolutionGroupNameAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Tizen.NUI.Binding +{ + [AttributeUsage(AttributeTargets.Assembly)] + internal class ResolutionGroupNameAttribute : Attribute + { + public ResolutionGroupNameAttribute(string name) + { + ShortName = name; + } + + internal string ShortName { get; private set; } + } +} \ No newline at end of file diff --git a/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResourceDictionary.cs b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResourceDictionary.cs new file mode 100755 index 0000000..f96404c --- /dev/null +++ b/src/Tizen.NUI.XamlBuild/src/internal/XamlBinding/ResourceDictionary.cs @@ -0,0 +1,403 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; + +using Tizen.NUI.Binding.Internals; +using Tizen.NUI.Xaml; + +namespace Tizen.NUI.Binding +{ + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + internal class ResourceDictionary : IResourceDictionary, IDictionary + { + static ConditionalWeakTable s_instances = new ConditionalWeakTable(); + readonly Dictionary _innerDictionary = new Dictionary(); + ResourceDictionary _mergedInstance; + Type _mergedWith; + Uri _source; + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public ResourceDictionary() + { + DependencyService.Register(); + } + + [TypeConverter(typeof(TypeTypeConverter))] + [Obsolete("Use Source")] + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public Type MergedWith { + get { return _mergedWith; } + set { + if (_mergedWith == value) + return; + + if (_source != null) + throw new ArgumentException("MergedWith can not be used with Source"); + + if (!typeof(ResourceDictionary).GetTypeInfo().IsAssignableFrom(value.GetTypeInfo())) + throw new ArgumentException("MergedWith should inherit from ResourceDictionary"); + + _mergedWith = value; + if (_mergedWith == null) + return; + + _mergedInstance = s_instances.GetValue(_mergedWith, (key) => (ResourceDictionary)Activator.CreateInstance(key)); + OnValuesChanged(_mergedInstance.ToArray()); + } + } + + [TypeConverter(typeof(RDSourceTypeConverter))] + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public Uri Source { + get { return _source; } + set { + if (_source == value) + return; + throw new InvalidOperationException("Source can only be set from XAML."); //through the RDSourceTypeConverter + } + } + + //Used by the XamlC compiled converter + [EditorBrowsable(EditorBrowsableState.Never)] + public void SetAndLoadSource(Uri value, string resourcePath, Assembly assembly, System.Xml.IXmlLineInfo lineInfo) + { + _source = value; + if (_mergedWith != null) + throw new ArgumentException("Source can not be used with MergedWith"); + + //this will return a type if the RD as an x:Class element, and codebehind + var type = XamlResourceIdAttribute.GetTypeForPath(assembly, resourcePath); + if (type != null) + _mergedInstance = s_instances.GetValue(type, (key) => (ResourceDictionary)Activator.CreateInstance(key)); + else + _mergedInstance = DependencyService.Get().CreateFromResource(resourcePath, assembly, lineInfo); + OnValuesChanged(_mergedInstance.ToArray()); + } + + ICollection _mergedDictionaries; + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public ICollection MergedDictionaries { + get { + if (_mergedDictionaries == null) { + var col = new ObservableCollection(); + col.CollectionChanged += MergedDictionaries_CollectionChanged; + _mergedDictionaries = col; + } + return _mergedDictionaries; + } + } + + internal IList StyleSheets { get; set; } + + void StyleSheetsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + switch (e.Action) { + case NotifyCollectionChangedAction.Add: + ValuesChanged?.Invoke(this, ResourcesChangedEventArgs.StyleSheets); + break; + } + } + IList _collectionTrack; + + void MergedDictionaries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + // Move() isn't exposed by ICollection + if (e.Action == NotifyCollectionChangedAction.Move) + return; + + _collectionTrack = _collectionTrack ?? new List(); + // Collection has been cleared + if (e.Action == NotifyCollectionChangedAction.Reset) { + foreach (var dictionary in _collectionTrack) + dictionary.ValuesChanged -= Item_ValuesChanged; + + _collectionTrack.Clear(); + return; + } + + // New Items + if (e.NewItems != null) + { + foreach (var item in e.NewItems) + { + var rd = (ResourceDictionary)item; + _collectionTrack.Add(rd); + rd.ValuesChanged += Item_ValuesChanged; + OnValuesChanged(rd.ToArray()); + } + } + + // Old Items + if (e.OldItems != null) + { + foreach (var item in e.OldItems) + { + var rd = (ResourceDictionary)item; + rd.ValuesChanged -= Item_ValuesChanged; + _collectionTrack.Remove(rd); + } + } + } + + void Item_ValuesChanged(object sender, ResourcesChangedEventArgs e) + { + OnValuesChanged(e.Values.ToArray()); + } + + void ICollection>.Add(KeyValuePair item) + { + ((ICollection>)_innerDictionary).Add(item); + OnValuesChanged(item); + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public void Clear() + { + _innerDictionary.Clear(); + } + + bool ICollection>.Contains(KeyValuePair item) + { + return ((ICollection>)_innerDictionary).Contains(item) + || (_mergedInstance != null && _mergedInstance.Contains(item)); + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + ((ICollection>)_innerDictionary).CopyTo(array, arrayIndex); + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public int Count + { + get { return _innerDictionary.Count; } + } + + bool ICollection>.IsReadOnly + { + get { return ((ICollection>)_innerDictionary).IsReadOnly; } + } + + bool ICollection>.Remove(KeyValuePair item) + { + return ((ICollection>)_innerDictionary).Remove(item); + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public void Add(string key, object value) + { + if (ContainsKey(key)) + throw new ArgumentException($"A resource with the key '{key}' is already present in the ResourceDictionary."); + _innerDictionary.Add(key, value); + OnValueChanged(key, value); + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ContainsKey(string key) + { + return _innerDictionary.ContainsKey(key); + } + + [IndexerName("Item")] + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public object this[string index] + { + get + { + if (_innerDictionary.ContainsKey(index)) + return _innerDictionary[index]; + if (_mergedInstance != null && _mergedInstance.ContainsKey(index)) + return _mergedInstance[index]; + if (MergedDictionaries != null) + foreach (var dict in MergedDictionaries.Reverse()) + if (dict.ContainsKey(index)) + return dict[index]; + throw new KeyNotFoundException($"The resource '{index}' is not present in the dictionary."); + } + set + { + _innerDictionary[index] = value; + OnValueChanged(index, value); + } + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public ICollection Keys + { + get { return _innerDictionary.Keys; } + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool Remove(string key) + { + return _innerDictionary.Remove(key); + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public ICollection Values + { + get { return _innerDictionary.Values; } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public IEnumerator> GetEnumerator() + { + return _innerDictionary.GetEnumerator(); + } + + internal IEnumerable> MergedResources { + get { + if (MergedDictionaries != null) + foreach (var r in MergedDictionaries.Reverse().SelectMany(x => x.MergedResources)) + yield return r; + if (_mergedInstance != null) + foreach (var r in _mergedInstance.MergedResources) + yield return r; + foreach (var r in _innerDictionary) + yield return r; + } + } + + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public bool TryGetValue(string key, out object value) + { + return _innerDictionary.TryGetValue(key, out value) + || (_mergedInstance != null && _mergedInstance.TryGetValue(key, out value)) + || (MergedDictionaries != null && TryGetMergedDictionaryValue(key, out value)); + } + + bool TryGetMergedDictionaryValue(string key, out object value) + { + foreach (var dictionary in MergedDictionaries.Reverse()) + if (dictionary.TryGetValue(key, out value)) + return true; + + value = null; + return false; + } + + event EventHandler IResourceDictionary.ValuesChanged + { + add { ValuesChanged += value; } + remove { ValuesChanged -= value; } + } + + public void Add(Style style) + { + if (string.IsNullOrEmpty(style.Class)) + Add(style.TargetType.FullName, style); + else + { + IList
  • b%l{0MSk*h%r}qp01B@F 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 z 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 R#&1}4*S6q)!~cT^eg}E<=Tray literal 0 HcmV?d00001 diff --git a/pkg/Tizen.NET.API10/xamlbuild/System.CodeDom.dll b/pkg/Tizen.NET.API10/xamlbuild/System.CodeDom.dll new file mode 100755 index 0000000000000000000000000000000000000000..ffb089503eb03b4ecd7d01add7c43d0327622ef3 GIT binary patch literal 32952 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 z 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