| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 | 
							- #if XFORMS
 
- namespace Caliburn.Micro.Core.Xamarin.Forms
 
- #else
 
- namespace Caliburn.Micro
 
- #endif
 
- {
 
-     using System;
 
-     using System.Collections.Generic;
 
-     using System.Linq;
 
- #if WinRT81
 
-     using System.Reflection;
 
-     using Windows.UI.Xaml;
 
-     using Microsoft.Xaml.Interactivity;
 
-     using TriggerBase = Microsoft.Xaml.Interactivity.IBehavior;
 
-     using EventTrigger = Microsoft.Xaml.Interactions.Core.EventTriggerBehavior;
 
-     using TriggerAction = Microsoft.Xaml.Interactivity.IAction;
 
-     using System.Text;
 
-     using System.Text.RegularExpressions;
 
-     using Windows.UI.Xaml.Data;
 
- #elif XFORMS
 
-     using System.Reflection;
 
-     using System.Text.RegularExpressions;
 
-     using global::Xamarin.Forms;
 
-     using DependencyObject = global::Xamarin.Forms.BindableObject;
 
-     using FrameworkElement = global::Xamarin.Forms.VisualElement;
 
- #else
 
-     using System.Reflection;
 
-     using System.Text.RegularExpressions;
 
-     using System.Windows;
 
-     using System.Windows.Data;
 
-     using EventTrigger = System.Windows.Interactivity.EventTrigger;
 
-     using TriggerBase = System.Windows.Interactivity.TriggerBase;
 
-     using TriggerAction = System.Windows.Interactivity.TriggerAction;
 
-     using System.Text;
 
-     using Caliburn.Micro.Core;
 
- #endif
 
-     /// <summary>
 
-     /// Parses text into a fully functional set of <see cref="TriggerBase"/> instances with <see cref="ActionMessage"/>.
 
-     /// </summary>
 
-     public static class Parser
 
-     {
 
-         static readonly Regex LongFormatRegularExpression = new Regex(@"^[\s]*\[[^\]]*\][\s]*=[\s]*\[[^\]]*\][\s]*$");
 
-         static readonly ILog Log = LogManager.GetLog(typeof(Parser));
 
-         /// <summary>
 
-         /// Parses the specified message text.
 
-         /// </summary>
 
-         /// <param name="target">The target.</param>
 
-         /// <param name="text">The message text.</param>
 
-         /// <returns>The triggers parsed from the text.</returns>
 
-         public static IEnumerable<TriggerBase> Parse(DependencyObject target, string text)
 
-         {
 
-             if (string.IsNullOrEmpty(text))
 
-             {
 
-                 return new TriggerBase[0];
 
-             }
 
-             var triggers = new List<TriggerBase>();
 
-             var messageTexts = StringSplitter.Split(text, ';');
 
-             foreach (var messageText in messageTexts)
 
-             {
 
-                 var triggerPlusMessage = LongFormatRegularExpression.IsMatch(messageText)
 
-                                              ? StringSplitter.Split(messageText, '=')
 
-                                              : new[] { null, messageText };
 
-                 var messageDetail = triggerPlusMessage.Last()
 
-                     .Replace("[", string.Empty)
 
-                     .Replace("]", string.Empty)
 
-                     .Trim();
 
-                 var trigger = CreateTrigger(target, triggerPlusMessage.Length == 1 ? null : triggerPlusMessage[0]);
 
-                 var message = CreateMessage(target, messageDetail);
 
- #if WinRT81 || XFORMS
 
-                 AddActionToTrigger(target, message, trigger);
 
- #else
 
-                 trigger.Actions.Add(message);
 
- #endif
 
-                 triggers.Add(trigger);
 
-             }
 
-             return triggers;
 
-         }
 
- #if XFORMS
 
-         private static void AddActionToTrigger(DependencyObject target, TriggerAction message, TriggerBase trigger) {
 
-             if (trigger is EventTrigger) {
 
-                 var eventTrigger = (EventTrigger) trigger;
 
-                 eventTrigger.Actions.Add(message);
 
-             }
 
-             trigger.EnterActions.Add(message);
 
-             // TriggerAction doesn't have an associated object property so we have
 
-             // to create it ourselves, could be potential issues here with leaking the associated 
 
-             // object and not correctly detaching, this may depend if the trigger implements it's
 
-             // AssociatedObject as a DependencyProperty.
 
-             var actionMessage = message as ActionMessage;
 
-             var targetElement = target as FrameworkElement;
 
-             if (actionMessage != null && targetElement != null)
 
-             {
 
-                 actionMessage.AssociatedObject = targetElement;
 
-             }
 
-         }
 
- #endif
 
- #if WinRT81
 
-         private static void AddActionToTrigger(DependencyObject target, TriggerAction message, TriggerBase trigger)
 
-         {
 
-             // This is stupid, but there a number of limitiations in the 8.1 Behaviours SDK
 
-             // The first is that there is no base class for a Trigger, just IBehaviour. Which
 
-             // means there's no strongly typed way to add an action to a trigger. Every trigger
 
-             // in the SDK implements the same pattern but no interface, we're going to have to
 
-             // use reflection to set it.
 
-             // More stupidity, ActionCollection doesn't care about IAction, but DependencyObject
 
-             // and there's no actual implementation of 
 
-             var messageDependencyObject = message as DependencyObject;
 
-             if (messageDependencyObject == null)
 
-             {
 
-                 Log.Warn("{0} doesn't inherit DependencyObject and can't be added to ActionCollection", trigger.GetType().FullName);
 
-                 return;
 
-             }
 
-             // 95% of the time the trigger will be an EventTrigger, let's optimise for that case
 
-             if (trigger is EventTrigger)
 
-             {
 
-                 var eventTrigger = (EventTrigger) trigger;
 
-                 eventTrigger.Actions.Add(messageDependencyObject);
 
-             }
 
-             else
 
-             {
 
-                 var actionsProperty = trigger.GetType().GetRuntimeProperty("Actions");
 
-                 if (actionsProperty == null)
 
-                 {
 
-                     Log.Warn("Could not find Actions collection on trigger {0}.", trigger.GetType().FullName);
 
-                     return;
 
-                 }
 
-                 var actionCollection = actionsProperty.GetValue(trigger) as ActionCollection;
 
-                 if (actionCollection == null)
 
-                 {
 
-                     Log.Warn("{0}.Actions is either not an ActionCollection or is null.", trigger.GetType().FullName);
 
-                     return;
 
-                 }
 
-                 actionCollection.Add(messageDependencyObject);
 
-             }
 
-             // The second is the IAction doesn't have an associated object property so we have
 
-             // to create it ourselves, could be potential issues here with leaking the associated 
 
-             // object and not correctly detaching, this may depend if the trigger implements it's
 
-             // AssociatedObject as a DependencyProperty.
 
-             // Turns out trying to a binding won't work because the trigger doesn't notify the 
 
-             // binding of changes, so we just need to set it, yay.
 
-             var actionMessage = message as ActionMessage;
 
-             var targetElement = target as FrameworkElement;
 
-             if (actionMessage != null && targetElement != null)
 
-             {
 
-                 //var binding = new Binding { Source = trigger, Path = new PropertyPath("AssociatedObject") };
 
-                 //BindingOperations.SetBinding(actionMessage, ActionMessage.AssociatedObjectProperty, binding);
 
-                 actionMessage.AssociatedObject = targetElement;
 
-             }
 
-             
 
-         }
 
- #endif
 
-         /// <summary>
 
-         /// The function used to generate a trigger.
 
-         /// </summary>
 
-         /// <remarks>The parameters passed to the method are the the target of the trigger and string representing the trigger.</remarks>
 
-         public static Func<DependencyObject, string, TriggerBase> CreateTrigger = (target, triggerText) =>
 
-         {
 
-             if (triggerText == null)
 
-             {
 
-                 var defaults = ConventionManager.GetElementConvention(target.GetType());
 
-                 return defaults.CreateTrigger();
 
-             }
 
-             var triggerDetail = triggerText
 
-                 .Replace("[", string.Empty)
 
-                 .Replace("]", string.Empty)
 
-                 .Replace("Event", string.Empty)
 
-                 .Trim();
 
- #if XFORMS
 
-             return new EventTrigger { Event = triggerDetail };
 
- #else
 
-             return new EventTrigger { EventName = triggerDetail };
 
- #endif
 
-         };
 
-         /// <summary>
 
-         /// Creates an instance of <see cref="ActionMessage"/> by parsing out the textual dsl.
 
-         /// </summary>
 
-         /// <param name="target">The target of the message.</param>
 
-         /// <param name="messageText">The textual message dsl.</param>
 
-         /// <returns>The created message.</returns>
 
-         public static TriggerAction CreateMessage(DependencyObject target, string messageText)
 
-         {
 
-             var openingParenthesisIndex = messageText.IndexOf('(');
 
-             if (openingParenthesisIndex < 0)
 
-             {
 
-                 openingParenthesisIndex = messageText.Length;
 
-             }
 
-             var closingParenthesisIndex = messageText.LastIndexOf(')');
 
-             if (closingParenthesisIndex < 0)
 
-             {
 
-                 closingParenthesisIndex = messageText.Length;
 
-             }
 
-             var core = messageText.Substring(0, openingParenthesisIndex).Trim();
 
-             var message = InterpretMessageText(target, core);
 
-             var withParameters = message as IHaveParameters;
 
-             if (withParameters != null)
 
-             {
 
-                 if (closingParenthesisIndex - openingParenthesisIndex > 1)
 
-                 {
 
-                     var paramString = messageText.Substring(openingParenthesisIndex + 1, closingParenthesisIndex - openingParenthesisIndex - 1);
 
-                     var parameters = StringSplitter.SplitParameters(paramString);
 
-                     foreach (var parameter in parameters)
 
-                         withParameters.Parameters.Add(CreateParameter(target, parameter.Trim()));
 
-                 }
 
-             }
 
-             return message;
 
-         }
 
-         /// <summary>
 
-         /// Function used to parse a string identified as a message.
 
-         /// </summary>
 
-         public static Func<DependencyObject, string, TriggerAction> InterpretMessageText = (target, text) =>
 
-         {
 
-             return new ActionMessage { MethodName = Regex.Replace(text, "^Action", string.Empty).Trim() };
 
-         };
 
-         /// <summary>
 
-         /// Function used to parse a string identified as a message parameter.
 
-         /// </summary>
 
-         public static Func<DependencyObject, string, Parameter> CreateParameter = (target, parameterText) =>
 
-         {
 
-             var actualParameter = new Parameter();
 
-             if (parameterText.StartsWith("'") && parameterText.EndsWith("'"))
 
-             {
 
-                 actualParameter.Value = parameterText.Substring(1, parameterText.Length - 2);
 
-             }
 
-             else if (MessageBinder.SpecialValues.ContainsKey(parameterText.ToLower()) || char.IsNumber(parameterText[0]))
 
-             {
 
-                 actualParameter.Value = parameterText;
 
-             }
 
-             else if (target is FrameworkElement)
 
-             {
 
-                 var fe = (FrameworkElement)target;
 
-                 var nameAndBindingMode = parameterText.Split(':').Select(x => x.Trim()).ToArray();
 
-                 var index = nameAndBindingMode[0].IndexOf('.');
 
-                 View.ExecuteOnLoad(fe, delegate
 
-                 {
 
-                     BindParameter(
 
-                         fe,
 
-                         actualParameter,
 
-                         index == -1 ? nameAndBindingMode[0] : nameAndBindingMode[0].Substring(0, index),
 
-                         index == -1 ? null : nameAndBindingMode[0].Substring(index + 1),
 
-                         nameAndBindingMode.Length == 2 ? (BindingMode)Enum.Parse(typeof(BindingMode), nameAndBindingMode[1], true) : BindingMode.OneWay
 
-                         );
 
-                 });
 
-             }
 
-             return actualParameter;
 
-         };
 
-         /// <summary>
 
-         /// Creates a binding on a <see cref="Parameter"/>.
 
-         /// </summary>
 
-         /// <param name="target">The target to which the message is applied.</param>
 
-         /// <param name="parameter">The parameter object.</param>
 
-         /// <param name="elementName">The name of the element to bind to.</param>
 
-         /// <param name="path">The path of the element to bind to.</param>
 
-         /// <param name="bindingMode">The binding mode to use.</param>
 
-         public static void BindParameter(FrameworkElement target, Parameter parameter, string elementName, string path, BindingMode bindingMode)
 
-         {
 
- #if XFORMS
 
-             var element = elementName == "$this" ? target : null;
 
-             if (element == null)
 
-             {
 
-                 return;
 
-             }
 
-             if (string.IsNullOrEmpty(path))
 
-             {
 
-                 path = ConventionManager.GetElementConvention(element.GetType()).ParameterProperty;
 
-             }
 
-             var binding = new Binding(path) {
 
-                 Source = element,
 
-                 Mode = bindingMode
 
-             };
 
-             parameter.SetBinding(Parameter.ValueProperty, binding);
 
- #else
 
-             var element = elementName == "$this"
 
-                 ? target
 
-                 : BindingScope.GetNamedElements(target).FindName(elementName);
 
-             if (element == null)
 
-             {
 
-                 return;
 
-             }
 
-             if (string.IsNullOrEmpty(path))
 
-             {
 
-                 path = ConventionManager.GetElementConvention(element.GetType()).ParameterProperty;
 
-             }
 
- #if WinRT
 
-             var binding = new Binding
 
-             {
 
-                 Path = new PropertyPath(path),
 
-                 Source = element,
 
-                 Mode = bindingMode
 
-             };
 
- #else
 
-             var binding = new Binding(path) {
 
-                 Source = element,
 
-                 Mode = bindingMode
 
-             };
 
- #endif
 
- #if (SILVERLIGHT && !SL5)
 
-             var expression = (BindingExpression)BindingOperations.SetBinding(parameter, Parameter.ValueProperty, binding);
 
-             var field = element.GetType().GetField(path + "Property", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
 
-             if (field == null) {
 
-                 return;
 
-             }
 
-             ConventionManager.ApplySilverlightTriggers(element, (DependencyProperty)field.GetValue(null), x => expression, null, null);
 
- #else
 
- #if !WinRT
 
-             binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
 
- #endif
 
-             BindingOperations.SetBinding(parameter, Parameter.ValueProperty, binding);
 
- #endif
 
- #endif
 
-         }
 
-     }
 
- }
 
 
  |