Remove children from state
This commit is contained in:
parent
e2f6e7ed3f
commit
15578a6bac
|
@ -18,10 +18,10 @@ namespace Ooui
|
|||
|
||||
public event Action<Message> MessageSent;
|
||||
|
||||
public IEnumerable<Message> StateMessages {
|
||||
public IReadOnlyList<Message> StateMessages {
|
||||
get {
|
||||
lock (stateMessages) {
|
||||
return new List<Message> (stateMessages);
|
||||
return new List<Message> (stateMessages).AsReadOnly ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ namespace Ooui
|
|||
});
|
||||
}
|
||||
|
||||
public override string ToString() => $"<{TagName} id=\"{Id}\" />";
|
||||
|
||||
public virtual EventTarget GetElementById (string id)
|
||||
{
|
||||
if (id == Id) return this;
|
||||
|
@ -134,37 +136,30 @@ namespace Ooui
|
|||
TriggerEventFromMessage (message);
|
||||
}
|
||||
|
||||
protected void SaveStateMessage (Message message)
|
||||
protected void AddStateMessage (Message message)
|
||||
{
|
||||
lock (stateMessages) stateMessages.Add (message);
|
||||
}
|
||||
|
||||
void LockedReplaceStateMessage (Message old, Message message)
|
||||
protected void UpdateStateMessages (Action<List<Message>> updater)
|
||||
{
|
||||
if (old != null) {
|
||||
stateMessages.Remove (old);
|
||||
}
|
||||
stateMessages.Add (message);
|
||||
lock (stateMessages) updater (stateMessages);
|
||||
}
|
||||
|
||||
protected virtual void SaveStateMessageIfNeeded (Message message)
|
||||
{
|
||||
switch (message.MessageType) {
|
||||
case MessageType.Create:
|
||||
SaveStateMessage (message);
|
||||
AddStateMessage (message);
|
||||
break;
|
||||
case MessageType.Set:
|
||||
{
|
||||
lock (stateMessages) {
|
||||
var old = stateMessages.FirstOrDefault (
|
||||
x => x.MessageType == MessageType.Set &&
|
||||
x.Key == message.Key);
|
||||
LockedReplaceStateMessage (old, message);
|
||||
}
|
||||
}
|
||||
UpdateStateMessages (state => {
|
||||
state.RemoveAll (x => x.MessageType == MessageType.Set && x.Key == message.Key);
|
||||
state.Add (message);
|
||||
});
|
||||
break;
|
||||
case MessageType.Listen:
|
||||
SaveStateMessage (message);
|
||||
AddStateMessage (message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
28
Ooui/Node.cs
28
Ooui/Node.cs
|
@ -103,10 +103,30 @@ namespace Ooui
|
|||
protected override void SaveStateMessageIfNeeded (Message message)
|
||||
{
|
||||
switch (message.MessageType) {
|
||||
case MessageType.Call when
|
||||
message.Key == "insertBefore" ||
|
||||
message.Key == "removeChild":
|
||||
SaveStateMessage (message);
|
||||
case MessageType.Call when message.Key == "insertBefore":
|
||||
AddStateMessage (message);
|
||||
break;
|
||||
case MessageType.Call when message.Key == "removeChild" && message.Value is Array ma && ma.Length == 1:
|
||||
UpdateStateMessages (state => {
|
||||
var mchild = ma.GetValue (0);
|
||||
Node nextChild = null;
|
||||
for (var i = 0; i < state.Count; ) {
|
||||
var x = state[i];
|
||||
if (x.Key == "insertBefore" && x.Value is Array xa && xa.Length == 2 && ReferenceEquals (xa.GetValue (0), mchild)) {
|
||||
// Remove any inserts for this node
|
||||
nextChild = xa.GetValue (1) as Node;
|
||||
state.RemoveAt (i);
|
||||
}
|
||||
else if (x.Key == "insertBefore" && x.Value is Array ya && ya.Length == 2 && ReferenceEquals (ya.GetValue (1), mchild)) {
|
||||
// Replace inserts that reference this node
|
||||
state[i] = Message.Call (Id, "insertBefore", ya.GetValue (0), nextChild);
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
base.SaveStateMessageIfNeeded (message);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using Ooui;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class EventTargetTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void CreationState ()
|
||||
{
|
||||
var b = new Button ();
|
||||
Assert.AreEqual (1, b.StateMessages.Count);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
using Ooui;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class NodeTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TextState ()
|
||||
{
|
||||
var b = new Button ();
|
||||
Assert.AreEqual (1, b.StateMessages.Count);
|
||||
b.Text = "Hello";
|
||||
Assert.AreEqual (2, b.StateMessages.Count);
|
||||
b.Text = "Bye";
|
||||
Assert.AreEqual (2, b.StateMessages.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InsertBeforeOfRemovedNodeStillWorks ()
|
||||
{
|
||||
var p = new Div ();
|
||||
var c0 = new Span ();
|
||||
var c1 = new Span ();
|
||||
var c2 = new Span ();
|
||||
p.InsertBefore (c2, null);
|
||||
p.InsertBefore (c1, c2);
|
||||
p.InsertBefore (c0, c1);
|
||||
p.RemoveChild (c1);
|
||||
var ms = p.StateMessages;
|
||||
Assert.AreEqual (3, ms.Count);
|
||||
var c0s = (Array)ms[2].Value;
|
||||
Assert.AreEqual (2, c0s.Length);
|
||||
Assert.AreEqual (c0, c0s.GetValue (0));
|
||||
Assert.AreEqual (c2, c0s.GetValue (1));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue