public void InsertAfter(LinkMember node) { if (this == node) { return; } LinkMember after; if ((after = NextSibling) is null) { Parent.Add(node); } else { if (IsAncestorOf(node)) { return; } Mend(END, after, node); node.Parent = Parent; } }
public void InsertBefore(LinkMember node) { if (this == node) { return; } //Can't insert itself before itself. var first = PreviousSibling; if (first is null) { Parent.Prepend(node); //If previous sibling is null, we have to perform Parent.Prepend(node) } else { if (IsAncestorOf(node)) { return; } //IsAncestorOf is checked in a similar way in Parent.Prepend. //The check for PreviousSibling being null is quicker than IsAncestorOf //so calling IsAncestorOf here is more appropriate than calling first. Mend(first.END, this, node); node.Parent = Parent; } }
private void Mend(LinkMember start, LinkMember finish, LinkMember node) { node.Pop(); start?.SetNext(node); node.SetPrev(start); finish?.SetPrev(node.END); node.END.SetNext(finish); }
public void Add(LinkMember node) { if (this == node || IsAncestorOf(node)) { return; } Mend(END.Prev, END, node); node.Parent = this; }
public void Prepend(LinkMember node) { if (this == node || IsAncestorOf(node)) { return; } Mend(this, Next, node); node.Parent = this; }
public LinkMember(object value) { END = new LinkMember() { Value = "END" }; Value = value; Next = END; END.Prev = this; END.Parent = this; }
public void Replace(LinkMember remove, LinkMember insert) { remove.InsertAfter(insert); remove.Pop(); }
public bool IsAncestorOf(LinkMember linkMember) => GetParents().FirstOrDefault(parent => parent == linkMember) is not null;
public void SetPrev(LinkMember node) => Prev = node;
public void SetNext(LinkMember node) => Next = node;