From 9aee6bc5acd5b454bb3145888026ef57c0b8b6d3 Mon Sep 17 00:00:00 2001 From: "Frank A. Krueger" Date: Mon, 12 Jun 2017 13:45:27 -0700 Subject: [PATCH] Reintroduce Node to better model HTML --- Ooui/Element.cs | 83 ++----------------------------- Ooui/Message.cs | 8 +-- Ooui/Node.cs | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 84 deletions(-) create mode 100644 Ooui/Node.cs diff --git a/Ooui/Element.cs b/Ooui/Element.cs index 0155daf..fe13d01 100644 --- a/Ooui/Element.cs +++ b/Ooui/Element.cs @@ -1,86 +1,13 @@ using System; -using System.Collections.Generic; -using System.Linq; namespace Ooui { - public class Element + public abstract class Element : Node { - public string Id { get; private set; } = GenerateId (); - - public HtmlMapping Mapping { get; private set; } - - readonly List messages = new List (); - readonly List stateMessages = new List (); - - public Element () - { - Mapping = HtmlMapping.Get (GetType ()); - LogCreate (); - } - - protected void Log (Message message) - { - messages.Add (message); - - switch (message.MessageType) { - case MessageType.Create: - stateMessages.Add (message); - break; - case MessageType.SetProperty: - { - var old = stateMessages.FirstOrDefault ( - x => x.MessageType == MessageType.SetProperty && - x.Member == message.Member); - if (old != null) { - stateMessages.Remove (old); - } - stateMessages.Add (message); - } - break; - } - } - - protected void LogCreate () - { - Log (new Message { - MessageType = MessageType.Create, - TargetId = Id, - Value = Mapping.TagName, - }); - } - - protected void LogSetProperty (string propertyName, object value) - { - var m = new Message { - MessageType = MessageType.SetProperty, - TargetId = Id, - Member = Mapping.GetMemberPath (propertyName), - }; - m.SetValue (value); - Log (m); - } - - protected bool SetProperty (ref T backingStore, T newValue, string propertyName = "") - { - if (!backingStore.Equals (newValue)) { - backingStore = newValue; - LogSetProperty (propertyName, newValue); - return true; - } - return false; - } - - const string IdChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - - static string GenerateId () - { - var rand = new Random(); - var chars = new char[8]; - for (var i = 0; i < chars.Length; i++) { - chars[i] = IdChars[rand.Next(0, IdChars.Length)]; - } - return new string(chars); + string className = ""; + public string ClassName { + get => className; + set => SetProperty (ref className, value); } } } diff --git a/Ooui/Message.cs b/Ooui/Message.cs index fcde6c0..4d8f00f 100644 --- a/Ooui/Message.cs +++ b/Ooui/Message.cs @@ -39,11 +39,7 @@ namespace Ooui { Nop, Create, - SetProperty, - } - - public enum ValueType - { - String + Set, + Call, } } diff --git a/Ooui/Node.cs b/Ooui/Node.cs new file mode 100644 index 0000000..b9ddad3 --- /dev/null +++ b/Ooui/Node.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Ooui +{ + public abstract class Node + { + public string Id { get; private set; } = GenerateId (); + + public HtmlMapping Mapping { get; private set; } + + readonly List children = new List (); + readonly List messages = new List (); + readonly List stateMessages = new List (); + + public Node () + { + Mapping = HtmlMapping.Get (GetType ()); + LogCreate (); + } + + public Node AppendChild (Node newChild) + { + return InsertBefore (newChild, null); + } + + public Node ParentNode { get; private set; } + + public Node InsertBefore (Node newChild, Node referenceChild) + { + if (referenceChild == null) { + children.Add (newChild); + } + else { + var index = children.IndexOf (referenceChild); + if (index < 0) { + throw new ArgumentException ("Reference must be a child of this element", nameof(referenceChild)); + } + children.Insert (index, newChild); + } + newChild.ParentNode = this; + LogCall ("insertBefore", newChild, referenceChild); + return newChild; + } + + public Node RemoveChild (Node child) + { + if (!children.Remove (child)) { + throw new ArgumentException ("Child not contained in this element", nameof(child)); + } + child.ParentNode = null; + LogCall ("removeChild", child); + return child; + } + + protected void Log (Message message) + { + messages.Add (message); + + switch (message.MessageType) { + case MessageType.Create: + stateMessages.Add (message); + break; + case MessageType.Set: + { + var old = stateMessages.FirstOrDefault ( + x => x.MessageType == MessageType.Set && + x.Member == message.Member); + if (old != null) { + stateMessages.Remove (old); + } + stateMessages.Add (message); + } + break; + } + } + + protected void LogCreate () + { + Log (new Message { + MessageType = MessageType.Create, + TargetId = Id, + Value = Mapping.TagName, + }); + } + + protected void LogCall (string methodName, params object[] args) + { + Log (new Message { + MessageType = MessageType.Call, + TargetId = Id, + Member = methodName, + }); + } + + protected void LogSet (string propertyName, object value) + { + var m = new Message { + MessageType = MessageType.Set, + TargetId = Id, + Member = Mapping.GetMemberPath (propertyName), + }; + m.SetValue (value); + Log (m); + } + + protected bool SetProperty (ref T backingStore, T newValue, string propertyName = "") + { + if (!backingStore.Equals (newValue)) { + backingStore = newValue; + LogSet (propertyName, newValue); + return true; + } + return false; + } + + const string IdChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + static string GenerateId () + { + var rand = new Random(); + var chars = new char[8]; + for (var i = 0; i < chars.Length; i++) { + chars[i] = IdChars[rand.Next(0, IdChars.Length)]; + } + return new string(chars); + } + } +}