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 event Action<Message> MessageSent;
|
||||||
|
|
||||||
public IEnumerable<Message> StateMessages {
|
public IReadOnlyList<Message> StateMessages {
|
||||||
get {
|
get {
|
||||||
lock (stateMessages) {
|
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)
|
public virtual EventTarget GetElementById (string id)
|
||||||
{
|
{
|
||||||
if (id == Id) return this;
|
if (id == Id) return this;
|
||||||
|
@ -134,37 +136,30 @@ namespace Ooui
|
||||||
TriggerEventFromMessage (message);
|
TriggerEventFromMessage (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SaveStateMessage (Message message)
|
protected void AddStateMessage (Message message)
|
||||||
{
|
{
|
||||||
lock (stateMessages) stateMessages.Add (message);
|
lock (stateMessages) stateMessages.Add (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LockedReplaceStateMessage (Message old, Message message)
|
protected void UpdateStateMessages (Action<List<Message>> updater)
|
||||||
{
|
{
|
||||||
if (old != null) {
|
lock (stateMessages) updater (stateMessages);
|
||||||
stateMessages.Remove (old);
|
|
||||||
}
|
|
||||||
stateMessages.Add (message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void SaveStateMessageIfNeeded (Message message)
|
protected virtual void SaveStateMessageIfNeeded (Message message)
|
||||||
{
|
{
|
||||||
switch (message.MessageType) {
|
switch (message.MessageType) {
|
||||||
case MessageType.Create:
|
case MessageType.Create:
|
||||||
SaveStateMessage (message);
|
AddStateMessage (message);
|
||||||
break;
|
break;
|
||||||
case MessageType.Set:
|
case MessageType.Set:
|
||||||
{
|
UpdateStateMessages (state => {
|
||||||
lock (stateMessages) {
|
state.RemoveAll (x => x.MessageType == MessageType.Set && x.Key == message.Key);
|
||||||
var old = stateMessages.FirstOrDefault (
|
state.Add (message);
|
||||||
x => x.MessageType == MessageType.Set &&
|
});
|
||||||
x.Key == message.Key);
|
|
||||||
LockedReplaceStateMessage (old, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MessageType.Listen:
|
case MessageType.Listen:
|
||||||
SaveStateMessage (message);
|
AddStateMessage (message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
Ooui/Node.cs
28
Ooui/Node.cs
|
@ -103,10 +103,30 @@ namespace Ooui
|
||||||
protected override void SaveStateMessageIfNeeded (Message message)
|
protected override void SaveStateMessageIfNeeded (Message message)
|
||||||
{
|
{
|
||||||
switch (message.MessageType) {
|
switch (message.MessageType) {
|
||||||
case MessageType.Call when
|
case MessageType.Call when message.Key == "insertBefore":
|
||||||
message.Key == "insertBefore" ||
|
AddStateMessage (message);
|
||||||
message.Key == "removeChild":
|
break;
|
||||||
SaveStateMessage (message);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
base.SaveStateMessageIfNeeded (message);
|
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