Dependencies/Pixie/Pixie/Markup/Sequence.cs
using System;
using System.Collections.Generic;
namespace WasmBox.Pixie.Markup {
/// <summary>
/// A markup node that consists of a sequence of other nodes.
/// </summary>
public sealed class Sequence : MarkupNode {
/// <summary>
/// Creates a sequence node from a list of nodes.
/// </summary>
/// <param name="contents">A list of nodes to render in sequence.</param>
public Sequence(params MarkupNode[] contents)
: this((IReadOnlyList<MarkupNode>)contents) { }
/// <summary>
/// Creates a sequence node from a list of nodes.
/// </summary>
/// <param name="contents">A list of nodes to render in sequence.</param>
public Sequence(IReadOnlyList<MarkupNode> contents) {
this.Contents = contents;
}
/// <summary>
/// Gets the list of markup nodes that make up this node's contents.
/// </summary>
/// <returns>The content markup nodes.</returns>
public IReadOnlyList<MarkupNode> Contents { get; private set; }
/// <inheritdoc/>
public override MarkupNode Fallback => null;
/// <inheritdoc/>
public override MarkupNode Map(Func<MarkupNode, MarkupNode> mapping) {
var newContents = Map(Contents, mapping);
if (newContents == Contents) {
return this;
}
else {
return new Sequence(newContents);
}
}
/// <summary>
/// Applies a mapping function to a list of markup nodes.
/// If none of the markup nodes change, then the original
/// list is returned.
/// </summary>
/// <param name="elements">
/// A read-only view of a list of markup nodes.
/// </param>
/// <param name="mapping">
/// A function that maps markup nodes to markup nodes.
/// </param>
/// <returns>
/// A new list of the mapping function changed at least
/// one element; otherwise, the original list.
/// </returns>
public static IReadOnlyList<MarkupNode> Map(
IReadOnlyList<MarkupNode> elements,
Func<MarkupNode, MarkupNode> mapping) {
int count = elements.Count;
var newElements = new MarkupNode[count];
bool changed = false;
for (int i = 0; i < count; i++) {
var elem = elements[i];
var newElem = mapping(elem);
newElements[i] = newElem;
if (elem != newElem) {
changed = true;
}
}
if (changed) {
return newElements;
}
else {
return elements;
}
}
}
}