diff --git a/src/Microsoft.Blazor/RenderTree/RenderTreeDiff.cs b/src/Microsoft.Blazor/RenderTree/RenderTreeDiff.cs
index 209a24044d..5b27cab8f7 100644
--- a/src/Microsoft.Blazor/RenderTree/RenderTreeDiff.cs
+++ b/src/Microsoft.Blazor/RenderTree/RenderTreeDiff.cs
@@ -5,321 +5,20 @@ using System;
namespace Microsoft.Blazor.RenderTree
{
- internal class RenderTreeDiff
+ ///
+ /// Describes changes to a component's render tree between successive renders.
+ ///
+ public struct RenderTreeDiff
{
- private const int MinBufferLength = 10;
- private RenderTreeDiffEntry[] _entries = new RenderTreeDiffEntry[10];
- private int _entriesInUse;
+ ///
+ /// Describes the render tree changes as a sequence of edit operations.
+ ///
+ public RenderTreeEdit[] Entries { get; private set; }
- public ArraySegment ComputeDifference(
- ArraySegment oldTree,
- ArraySegment newTree)
- {
- _entriesInUse = 0;
- AppendDiffEntriesForRange(oldTree.Array, 0, oldTree.Count, newTree.Array, 0, newTree.Count);
- TrimTrailingContinueNodes();
-
- // If the previous usage of the buffer showed that we have allocated
- // much more space than needed, free up the excess memory
- var shrinkToLength = Math.Max(MinBufferLength, _entries.Length / 2);
- if (_entriesInUse < shrinkToLength)
- {
- Array.Resize(ref _entries, shrinkToLength);
- }
-
- return new ArraySegment(_entries, 0, _entriesInUse);
- }
-
- private void AppendDiffEntriesForRange(
- RenderTreeNode[] oldTree, int oldStartIndex, int oldEndIndexExcl,
- RenderTreeNode[] newTree, int newStartIndex, int newEndIndexExcl)
- {
- var hasMoreOld = oldEndIndexExcl > oldStartIndex;
- var hasMoreNew = newEndIndexExcl > newStartIndex;
- var prevOldSeq = -1;
- var prevNewSeq = -1;
- while (hasMoreOld || hasMoreNew)
- {
- var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue;
- var newSeq = hasMoreNew ? newTree[newStartIndex].Sequence : int.MaxValue;
-
- if (oldSeq == newSeq)
- {
- AppendDiffEntriesForNodesWithSameSequence(oldTree, oldStartIndex, newTree, newStartIndex);
- oldStartIndex = NextSiblingIndex(oldTree, oldStartIndex);
- newStartIndex = NextSiblingIndex(newTree, newStartIndex);
- hasMoreOld = oldEndIndexExcl > oldStartIndex;
- hasMoreNew = newEndIndexExcl > newStartIndex;
- prevOldSeq = oldSeq;
- prevNewSeq = newSeq;
- }
- else
- {
- bool treatAsInsert;
- var oldLoopedBack = oldSeq <= prevOldSeq;
- var newLoopedBack = newSeq <= prevNewSeq;
- if (oldLoopedBack == newLoopedBack)
- {
- // Both sequences are proceeding through the same loop block, so do a simple
- // preordered merge join (picking from whichever side brings us closer to being
- // back in sync)
- treatAsInsert = newSeq < oldSeq;
-
- if (oldLoopedBack)
- {
- // If both old and new have now looped back, we must reset their 'looped back'
- // tracker so we can treat them as proceeding through the same loop block
- prevOldSeq = prevNewSeq = -1;
- }
- }
- else if (oldLoopedBack)
- {
- // Old sequence looped back but new one didn't
- // The new sequence either has some extra trailing elements in the current loop block
- // which we should insert, or omits some old trailing loop blocks which we should delete
- // TODO: Find a way of not recomputing this next flag on every iteration
- var newLoopsBackLater = false;
- for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++)
- {
- if (newTree[testIndex].Sequence < newSeq)
- {
- newLoopsBackLater = true;
- break;
- }
- }
-
- // If the new sequence loops back later to an earlier point than this,
- // then we know it's part of the existing loop block (so should be inserted).
- // If not, then it's unrelated to the previous loop block (so we should treat
- // the old items as trailing loop blocks to be removed).
- treatAsInsert = newLoopsBackLater;
- }
- else
- {
- // New sequence looped back but old one didn't
- // The old sequence either has some extra trailing elements in the current loop block
- // which we should delete, or the new sequence has extra trailing loop blocks which we
- // should insert
- // TODO: Find a way of not recomputing this next flag on every iteration
- var oldLoopsBackLater = false;
- for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++)
- {
- if (oldTree[testIndex].Sequence < oldSeq)
- {
- oldLoopsBackLater = true;
- break;
- }
- }
-
- // If the old sequence loops back later to an earlier point than this,
- // then we know it's part of the existing loop block (so should be removed).
- // If not, then it's unrelated to the previous loop block (so we should treat
- // the new items as trailing loop blocks to be inserted).
- treatAsInsert = !oldLoopsBackLater;
- }
-
- if (treatAsInsert)
- {
- if (newTree[newStartIndex].NodeType == RenderTreeNodeType.Attribute)
- {
- Append(RenderTreeDiffEntry.SetAttribute(newStartIndex));
- newStartIndex++;
- }
- else
- {
- Append(RenderTreeDiffEntry.PrependNode(newStartIndex));
- newStartIndex = NextSiblingIndex(newTree, newStartIndex);
- }
-
- hasMoreNew = newEndIndexExcl > newStartIndex;
- prevNewSeq = newSeq;
- }
- else
- {
- if (oldTree[oldStartIndex].NodeType == RenderTreeNodeType.Attribute)
- {
- Append(RenderTreeDiffEntry.RemoveAttribute(oldTree[oldStartIndex].AttributeName));
- oldStartIndex++;
- }
- else
- {
- Append(RenderTreeDiffEntry.RemoveNode());
- oldStartIndex = NextSiblingIndex(oldTree, oldStartIndex);
- }
- hasMoreOld = oldEndIndexExcl > oldStartIndex;
- prevOldSeq = oldSeq;
- }
- }
- }
- }
-
- private static int NextSiblingIndex(RenderTreeNode[] tree, int nodeIndex)
- {
- var descendantsEndIndex = tree[nodeIndex].ElementDescendantsEndIndex;
- return (descendantsEndIndex == 0 ? nodeIndex : descendantsEndIndex) + 1;
- }
-
- private void AppendDiffEntriesForNodesWithSameSequence(
- RenderTreeNode[] oldTree, int oldNodeIndex,
- RenderTreeNode[] newTree, int newNodeIndex)
- {
- // We can assume that the old and new nodes are of the same type, because they correspond
- // to the same sequence number (and if not, the behaviour is undefined).
- switch (newTree[newNodeIndex].NodeType)
- {
- case RenderTreeNodeType.Text:
- {
- var oldText = oldTree[oldNodeIndex].TextContent;
- var newText = newTree[newNodeIndex].TextContent;
- if (string.Equals(oldText, newText, StringComparison.Ordinal))
- {
- Append(RenderTreeDiffEntry.Continue());
- }
- else
- {
- Append(RenderTreeDiffEntry.UpdateText(newNodeIndex));
- }
- break;
- }
-
- case RenderTreeNodeType.Element:
- {
- var oldElementName = oldTree[oldNodeIndex].ElementName;
- var newElementName = newTree[newNodeIndex].ElementName;
- if (string.Equals(oldElementName, newElementName, StringComparison.Ordinal))
- {
- var oldNodeAttributesEndIndexExcl = GetAttributesEndIndexExclusive(oldTree, oldNodeIndex);
- var newNodeAttributesEndIndexExcl = GetAttributesEndIndexExclusive(newTree, newNodeIndex);
-
- // Diff the attributes
- AppendDiffEntriesForRange(
- oldTree, oldNodeIndex + 1, oldNodeAttributesEndIndexExcl,
- newTree, newNodeIndex + 1, newNodeAttributesEndIndexExcl);
-
- // Diff the children
- var oldNodeChildrenEndIndexExcl = oldTree[oldNodeIndex].ElementDescendantsEndIndex + 1;
- var newNodeChildrenEndIndexExcl = newTree[newNodeIndex].ElementDescendantsEndIndex + 1;
- var hasChildrenToProcess =
- oldNodeChildrenEndIndexExcl > oldNodeAttributesEndIndexExcl ||
- newNodeChildrenEndIndexExcl > newNodeAttributesEndIndexExcl;
- if (hasChildrenToProcess)
- {
- Append(RenderTreeDiffEntry.StepIn());
- AppendDiffEntriesForRange(
- oldTree, oldNodeAttributesEndIndexExcl, oldNodeChildrenEndIndexExcl,
- newTree, newNodeAttributesEndIndexExcl, newNodeChildrenEndIndexExcl);
- Append(RenderTreeDiffEntry.StepOut());
- }
- else
- {
- Append(RenderTreeDiffEntry.Continue());
- }
- }
- else
- {
- // Elements with different names are treated as completely unrelated
- Append(RenderTreeDiffEntry.PrependNode(newNodeIndex));
- Append(RenderTreeDiffEntry.RemoveNode());
- }
- break;
- }
-
- case RenderTreeNodeType.Component:
- {
- var oldComponentType = oldTree[oldNodeIndex].ComponentType;
- var newComponentType = newTree[newNodeIndex].ComponentType;
- if (oldComponentType == newComponentType)
- {
- // TODO: Compare attributes and notify the existing child component
- // instance of any changes
- // TODO: Also copy the existing child component instance to the new
- // tree so we can preserve it across multiple updates
-
- Append(RenderTreeDiffEntry.Continue());
- }
- else
- {
- // Child components of different types are treated as completely unrelated
- Append(RenderTreeDiffEntry.PrependNode(newNodeIndex));
- Append(RenderTreeDiffEntry.RemoveNode());
- }
- break;
- }
-
- case RenderTreeNodeType.Attribute:
- {
- var oldName = oldTree[oldNodeIndex].AttributeName;
- var newName = newTree[newNodeIndex].AttributeName;
- if (string.Equals(oldName, newName, StringComparison.Ordinal))
- {
- var changed =
- !string.Equals(oldTree[oldNodeIndex].AttributeValue, newTree[newNodeIndex].AttributeValue, StringComparison.Ordinal)
- || oldTree[oldNodeIndex].AttributeEventHandlerValue != newTree[newNodeIndex].AttributeEventHandlerValue;
- if (changed)
- {
- Append(RenderTreeDiffEntry.SetAttribute(newNodeIndex));
- }
- }
- else
- {
- // Since this code path is never reachable for Razor components (because you
- // can't have two different attribute names from the same source sequence), we
- // could consider removing the 'name equality' check entirely for perf
- Append(RenderTreeDiffEntry.SetAttribute(newNodeIndex));
- Append(RenderTreeDiffEntry.RemoveAttribute(oldName));
- }
- break;
- }
-
- default:
- throw new NotImplementedException($"Encountered unsupported node type during diffing: {newTree[newNodeIndex].NodeType}");
- }
- }
-
- private int GetAttributesEndIndexExclusive(RenderTreeNode[] tree, int rootIndex)
- {
- var descendantsEndIndex = tree[rootIndex].ElementDescendantsEndIndex;
- var index = rootIndex + 1;
- for (; index <= descendantsEndIndex; index++)
- {
- if (tree[index].NodeType != RenderTreeNodeType.Attribute)
- {
- break;
- }
- }
-
- return index;
- }
-
- private void Append(RenderTreeDiffEntry entry)
- {
- if (entry.Type == RenderTreeDiffEntryType.StepOut)
- {
- TrimTrailingContinueNodes();
-
- // If the preceding node is now a StepIn, then we can coalesce the StepIn+StepOut
- // down to a single Continue
- if (_entriesInUse > 0 && _entries[_entriesInUse - 1].Type == RenderTreeDiffEntryType.StepIn)
- {
- _entriesInUse--;
- entry = RenderTreeDiffEntry.Continue();
- }
- }
-
- if (_entriesInUse == _entries.Length)
- {
- Array.Resize(ref _entries, _entries.Length * 2);
- }
-
- _entries[_entriesInUse++] = entry;
- }
-
- private void TrimTrailingContinueNodes()
- {
- while (_entriesInUse > 0 && _entries[_entriesInUse - 1].Type == RenderTreeDiffEntryType.Continue)
- {
- _entriesInUse--;
- }
- }
+ ///
+ /// An array of structures that may be referred to
+ /// by entries in the property.
+ ///
+ public ArraySegment ReferenceTree { get; private set; }
}
}
diff --git a/src/Microsoft.Blazor/RenderTree/RenderTreeDiffComputer.cs b/src/Microsoft.Blazor/RenderTree/RenderTreeDiffComputer.cs
new file mode 100644
index 0000000000..254ed64305
--- /dev/null
+++ b/src/Microsoft.Blazor/RenderTree/RenderTreeDiffComputer.cs
@@ -0,0 +1,325 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+
+namespace Microsoft.Blazor.RenderTree
+{
+ internal class RenderTreeDiffComputer
+ {
+ private const int MinBufferLength = 10;
+ private RenderTreeEdit[] _entries = new RenderTreeEdit[10];
+ private int _entriesInUse;
+
+ public ArraySegment ComputeDifference(
+ ArraySegment oldTree,
+ ArraySegment newTree)
+ {
+ _entriesInUse = 0;
+ AppendDiffEntriesForRange(oldTree.Array, 0, oldTree.Count, newTree.Array, 0, newTree.Count);
+ TrimTrailingContinueNodes();
+
+ // If the previous usage of the buffer showed that we have allocated
+ // much more space than needed, free up the excess memory
+ var shrinkToLength = Math.Max(MinBufferLength, _entries.Length / 2);
+ if (_entriesInUse < shrinkToLength)
+ {
+ Array.Resize(ref _entries, shrinkToLength);
+ }
+
+ return new ArraySegment(_entries, 0, _entriesInUse);
+ }
+
+ private void AppendDiffEntriesForRange(
+ RenderTreeNode[] oldTree, int oldStartIndex, int oldEndIndexExcl,
+ RenderTreeNode[] newTree, int newStartIndex, int newEndIndexExcl)
+ {
+ var hasMoreOld = oldEndIndexExcl > oldStartIndex;
+ var hasMoreNew = newEndIndexExcl > newStartIndex;
+ var prevOldSeq = -1;
+ var prevNewSeq = -1;
+ while (hasMoreOld || hasMoreNew)
+ {
+ var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue;
+ var newSeq = hasMoreNew ? newTree[newStartIndex].Sequence : int.MaxValue;
+
+ if (oldSeq == newSeq)
+ {
+ AppendDiffEntriesForNodesWithSameSequence(oldTree, oldStartIndex, newTree, newStartIndex);
+ oldStartIndex = NextSiblingIndex(oldTree, oldStartIndex);
+ newStartIndex = NextSiblingIndex(newTree, newStartIndex);
+ hasMoreOld = oldEndIndexExcl > oldStartIndex;
+ hasMoreNew = newEndIndexExcl > newStartIndex;
+ prevOldSeq = oldSeq;
+ prevNewSeq = newSeq;
+ }
+ else
+ {
+ bool treatAsInsert;
+ var oldLoopedBack = oldSeq <= prevOldSeq;
+ var newLoopedBack = newSeq <= prevNewSeq;
+ if (oldLoopedBack == newLoopedBack)
+ {
+ // Both sequences are proceeding through the same loop block, so do a simple
+ // preordered merge join (picking from whichever side brings us closer to being
+ // back in sync)
+ treatAsInsert = newSeq < oldSeq;
+
+ if (oldLoopedBack)
+ {
+ // If both old and new have now looped back, we must reset their 'looped back'
+ // tracker so we can treat them as proceeding through the same loop block
+ prevOldSeq = prevNewSeq = -1;
+ }
+ }
+ else if (oldLoopedBack)
+ {
+ // Old sequence looped back but new one didn't
+ // The new sequence either has some extra trailing elements in the current loop block
+ // which we should insert, or omits some old trailing loop blocks which we should delete
+ // TODO: Find a way of not recomputing this next flag on every iteration
+ var newLoopsBackLater = false;
+ for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++)
+ {
+ if (newTree[testIndex].Sequence < newSeq)
+ {
+ newLoopsBackLater = true;
+ break;
+ }
+ }
+
+ // If the new sequence loops back later to an earlier point than this,
+ // then we know it's part of the existing loop block (so should be inserted).
+ // If not, then it's unrelated to the previous loop block (so we should treat
+ // the old items as trailing loop blocks to be removed).
+ treatAsInsert = newLoopsBackLater;
+ }
+ else
+ {
+ // New sequence looped back but old one didn't
+ // The old sequence either has some extra trailing elements in the current loop block
+ // which we should delete, or the new sequence has extra trailing loop blocks which we
+ // should insert
+ // TODO: Find a way of not recomputing this next flag on every iteration
+ var oldLoopsBackLater = false;
+ for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++)
+ {
+ if (oldTree[testIndex].Sequence < oldSeq)
+ {
+ oldLoopsBackLater = true;
+ break;
+ }
+ }
+
+ // If the old sequence loops back later to an earlier point than this,
+ // then we know it's part of the existing loop block (so should be removed).
+ // If not, then it's unrelated to the previous loop block (so we should treat
+ // the new items as trailing loop blocks to be inserted).
+ treatAsInsert = !oldLoopsBackLater;
+ }
+
+ if (treatAsInsert)
+ {
+ if (newTree[newStartIndex].NodeType == RenderTreeNodeType.Attribute)
+ {
+ Append(RenderTreeEdit.SetAttribute(newStartIndex));
+ newStartIndex++;
+ }
+ else
+ {
+ Append(RenderTreeEdit.PrependNode(newStartIndex));
+ newStartIndex = NextSiblingIndex(newTree, newStartIndex);
+ }
+
+ hasMoreNew = newEndIndexExcl > newStartIndex;
+ prevNewSeq = newSeq;
+ }
+ else
+ {
+ if (oldTree[oldStartIndex].NodeType == RenderTreeNodeType.Attribute)
+ {
+ Append(RenderTreeEdit.RemoveAttribute(oldTree[oldStartIndex].AttributeName));
+ oldStartIndex++;
+ }
+ else
+ {
+ Append(RenderTreeEdit.RemoveNode());
+ oldStartIndex = NextSiblingIndex(oldTree, oldStartIndex);
+ }
+ hasMoreOld = oldEndIndexExcl > oldStartIndex;
+ prevOldSeq = oldSeq;
+ }
+ }
+ }
+ }
+
+ private static int NextSiblingIndex(RenderTreeNode[] tree, int nodeIndex)
+ {
+ var descendantsEndIndex = tree[nodeIndex].ElementDescendantsEndIndex;
+ return (descendantsEndIndex == 0 ? nodeIndex : descendantsEndIndex) + 1;
+ }
+
+ private void AppendDiffEntriesForNodesWithSameSequence(
+ RenderTreeNode[] oldTree, int oldNodeIndex,
+ RenderTreeNode[] newTree, int newNodeIndex)
+ {
+ // We can assume that the old and new nodes are of the same type, because they correspond
+ // to the same sequence number (and if not, the behaviour is undefined).
+ switch (newTree[newNodeIndex].NodeType)
+ {
+ case RenderTreeNodeType.Text:
+ {
+ var oldText = oldTree[oldNodeIndex].TextContent;
+ var newText = newTree[newNodeIndex].TextContent;
+ if (string.Equals(oldText, newText, StringComparison.Ordinal))
+ {
+ Append(RenderTreeEdit.Continue());
+ }
+ else
+ {
+ Append(RenderTreeEdit.UpdateText(newNodeIndex));
+ }
+ break;
+ }
+
+ case RenderTreeNodeType.Element:
+ {
+ var oldElementName = oldTree[oldNodeIndex].ElementName;
+ var newElementName = newTree[newNodeIndex].ElementName;
+ if (string.Equals(oldElementName, newElementName, StringComparison.Ordinal))
+ {
+ var oldNodeAttributesEndIndexExcl = GetAttributesEndIndexExclusive(oldTree, oldNodeIndex);
+ var newNodeAttributesEndIndexExcl = GetAttributesEndIndexExclusive(newTree, newNodeIndex);
+
+ // Diff the attributes
+ AppendDiffEntriesForRange(
+ oldTree, oldNodeIndex + 1, oldNodeAttributesEndIndexExcl,
+ newTree, newNodeIndex + 1, newNodeAttributesEndIndexExcl);
+
+ // Diff the children
+ var oldNodeChildrenEndIndexExcl = oldTree[oldNodeIndex].ElementDescendantsEndIndex + 1;
+ var newNodeChildrenEndIndexExcl = newTree[newNodeIndex].ElementDescendantsEndIndex + 1;
+ var hasChildrenToProcess =
+ oldNodeChildrenEndIndexExcl > oldNodeAttributesEndIndexExcl ||
+ newNodeChildrenEndIndexExcl > newNodeAttributesEndIndexExcl;
+ if (hasChildrenToProcess)
+ {
+ Append(RenderTreeEdit.StepIn());
+ AppendDiffEntriesForRange(
+ oldTree, oldNodeAttributesEndIndexExcl, oldNodeChildrenEndIndexExcl,
+ newTree, newNodeAttributesEndIndexExcl, newNodeChildrenEndIndexExcl);
+ Append(RenderTreeEdit.StepOut());
+ }
+ else
+ {
+ Append(RenderTreeEdit.Continue());
+ }
+ }
+ else
+ {
+ // Elements with different names are treated as completely unrelated
+ Append(RenderTreeEdit.PrependNode(newNodeIndex));
+ Append(RenderTreeEdit.RemoveNode());
+ }
+ break;
+ }
+
+ case RenderTreeNodeType.Component:
+ {
+ var oldComponentType = oldTree[oldNodeIndex].ComponentType;
+ var newComponentType = newTree[newNodeIndex].ComponentType;
+ if (oldComponentType == newComponentType)
+ {
+ // TODO: Compare attributes and notify the existing child component
+ // instance of any changes
+ // TODO: Also copy the existing child component instance to the new
+ // tree so we can preserve it across multiple updates
+
+ Append(RenderTreeEdit.Continue());
+ }
+ else
+ {
+ // Child components of different types are treated as completely unrelated
+ Append(RenderTreeEdit.PrependNode(newNodeIndex));
+ Append(RenderTreeEdit.RemoveNode());
+ }
+ break;
+ }
+
+ case RenderTreeNodeType.Attribute:
+ {
+ var oldName = oldTree[oldNodeIndex].AttributeName;
+ var newName = newTree[newNodeIndex].AttributeName;
+ if (string.Equals(oldName, newName, StringComparison.Ordinal))
+ {
+ var changed =
+ !string.Equals(oldTree[oldNodeIndex].AttributeValue, newTree[newNodeIndex].AttributeValue, StringComparison.Ordinal)
+ || oldTree[oldNodeIndex].AttributeEventHandlerValue != newTree[newNodeIndex].AttributeEventHandlerValue;
+ if (changed)
+ {
+ Append(RenderTreeEdit.SetAttribute(newNodeIndex));
+ }
+ }
+ else
+ {
+ // Since this code path is never reachable for Razor components (because you
+ // can't have two different attribute names from the same source sequence), we
+ // could consider removing the 'name equality' check entirely for perf
+ Append(RenderTreeEdit.SetAttribute(newNodeIndex));
+ Append(RenderTreeEdit.RemoveAttribute(oldName));
+ }
+ break;
+ }
+
+ default:
+ throw new NotImplementedException($"Encountered unsupported node type during diffing: {newTree[newNodeIndex].NodeType}");
+ }
+ }
+
+ private int GetAttributesEndIndexExclusive(RenderTreeNode[] tree, int rootIndex)
+ {
+ var descendantsEndIndex = tree[rootIndex].ElementDescendantsEndIndex;
+ var index = rootIndex + 1;
+ for (; index <= descendantsEndIndex; index++)
+ {
+ if (tree[index].NodeType != RenderTreeNodeType.Attribute)
+ {
+ break;
+ }
+ }
+
+ return index;
+ }
+
+ private void Append(RenderTreeEdit entry)
+ {
+ if (entry.Type == RenderTreeEditType.StepOut)
+ {
+ TrimTrailingContinueNodes();
+
+ // If the preceding node is now a StepIn, then we can coalesce the StepIn+StepOut
+ // down to a single Continue
+ if (_entriesInUse > 0 && _entries[_entriesInUse - 1].Type == RenderTreeEditType.StepIn)
+ {
+ _entriesInUse--;
+ entry = RenderTreeEdit.Continue();
+ }
+ }
+
+ if (_entriesInUse == _entries.Length)
+ {
+ Array.Resize(ref _entries, _entries.Length * 2);
+ }
+
+ _entries[_entriesInUse++] = entry;
+ }
+
+ private void TrimTrailingContinueNodes()
+ {
+ while (_entriesInUse > 0 && _entries[_entriesInUse - 1].Type == RenderTreeEditType.Continue)
+ {
+ _entriesInUse--;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.Blazor/RenderTree/RenderTreeDiffEntry.cs b/src/Microsoft.Blazor/RenderTree/RenderTreeDiffEntry.cs
deleted file mode 100644
index 368239f36a..0000000000
--- a/src/Microsoft.Blazor/RenderTree/RenderTreeDiffEntry.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-
-namespace Microsoft.Blazor.RenderTree
-{
- internal struct RenderTreeDiffEntry
- {
- public RenderTreeDiffEntryType Type { get; private set; }
- public int NewTreeIndex { get; private set; }
- public string RemovedAttributeName { get; private set; }
-
- public static RenderTreeDiffEntry Continue() => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.Continue
- };
-
- internal static RenderTreeDiffEntry RemoveNode() => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.RemoveNode
- };
-
- internal static RenderTreeDiffEntry PrependNode(int newTreeIndex) => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.PrependNode,
- NewTreeIndex = newTreeIndex
- };
-
- internal static RenderTreeDiffEntry UpdateText(int newTreeIndex) => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.UpdateText,
- NewTreeIndex = newTreeIndex
- };
-
- internal static RenderTreeDiffEntry SetAttribute(int newNodeIndex) => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.SetAttribute,
- NewTreeIndex = newNodeIndex
- };
-
- internal static RenderTreeDiffEntry RemoveAttribute(string name) => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.RemoveAttribute,
- RemovedAttributeName = name
- };
-
- internal static RenderTreeDiffEntry StepIn() => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.StepIn
- };
-
- internal static RenderTreeDiffEntry StepOut() => new RenderTreeDiffEntry
- {
- Type = RenderTreeDiffEntryType.StepOut
- };
- }
-}
diff --git a/src/Microsoft.Blazor/RenderTree/RenderTreeDiffEntryType.cs b/src/Microsoft.Blazor/RenderTree/RenderTreeDiffEntryType.cs
deleted file mode 100644
index 3aaa535a01..0000000000
--- a/src/Microsoft.Blazor/RenderTree/RenderTreeDiffEntryType.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-namespace Microsoft.Blazor.RenderTree
-{
- internal enum RenderTreeDiffEntryType: int
- {
- Continue = 1,
- PrependNode = 2,
- RemoveNode = 3,
- SetAttribute = 4,
- RemoveAttribute = 5,
- UpdateText = 6,
- StepIn = 7,
- StepOut = 8,
- }
-}
diff --git a/src/Microsoft.Blazor/RenderTree/RenderTreeEdit.cs b/src/Microsoft.Blazor/RenderTree/RenderTreeEdit.cs
new file mode 100644
index 0000000000..3dfac40083
--- /dev/null
+++ b/src/Microsoft.Blazor/RenderTree/RenderTreeEdit.cs
@@ -0,0 +1,73 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.Blazor.RenderTree
+{
+ ///
+ /// Represents a single edit operation on a component's render tree.
+ ///
+ public struct RenderTreeEdit
+ {
+ ///
+ /// Gets the type of the edit operation.
+ ///
+ public RenderTreeEditType Type { get; private set; }
+
+ ///
+ /// Gets the index of related data in an associated render tree. For example, if the
+ /// value is , gets the
+ /// index of the new node data in an associated render tree.
+ ///
+ public int NewTreeIndex { get; private set; }
+
+ ///
+ /// If the value is ,
+ /// gets the name of the attribute that is being removed.
+ ///
+ public string RemovedAttributeName { get; private set; }
+
+ internal static RenderTreeEdit Continue() => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.Continue
+ };
+
+ internal static RenderTreeEdit RemoveNode() => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.RemoveNode
+ };
+
+ internal static RenderTreeEdit PrependNode(int newTreeIndex) => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.PrependNode,
+ NewTreeIndex = newTreeIndex
+ };
+
+ internal static RenderTreeEdit UpdateText(int newTreeIndex) => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.UpdateText,
+ NewTreeIndex = newTreeIndex
+ };
+
+ internal static RenderTreeEdit SetAttribute(int newNodeIndex) => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.SetAttribute,
+ NewTreeIndex = newNodeIndex
+ };
+
+ internal static RenderTreeEdit RemoveAttribute(string name) => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.RemoveAttribute,
+ RemovedAttributeName = name
+ };
+
+ internal static RenderTreeEdit StepIn() => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.StepIn
+ };
+
+ internal static RenderTreeEdit StepOut() => new RenderTreeEdit
+ {
+ Type = RenderTreeEditType.StepOut
+ };
+ }
+}
diff --git a/src/Microsoft.Blazor/RenderTree/RenderTreeEditType.cs b/src/Microsoft.Blazor/RenderTree/RenderTreeEditType.cs
new file mode 100644
index 0000000000..00b59a98c3
--- /dev/null
+++ b/src/Microsoft.Blazor/RenderTree/RenderTreeEditType.cs
@@ -0,0 +1,60 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.Blazor.RenderTree
+{
+ ///
+ /// Describes the type of a render tree edit operation.
+ ///
+ public enum RenderTreeEditType: int
+ {
+ ///
+ /// Indicates that there are no further operations on the current tree node, and
+ /// so the edit position should move to the next sibling (or if there is no next
+ /// sibling, then to the position where one would be).
+ ///
+ Continue = 1,
+
+ ///
+ /// Indicates that a new node should be inserted before the current tree node.
+ ///
+ PrependNode = 2,
+
+ ///
+ /// Indicates that the current tree node should be removed, and that the edit position
+ /// should then move to the next sibling (or if there is no next sibling, then to the
+ /// position where one would be).
+ ///
+ RemoveNode = 3,
+
+ ///
+ /// Indicates that an attribute value should be applied to the current node.
+ /// This may be a change to an existing attribute, or the addition of a new attribute.
+ ///
+ SetAttribute = 4,
+
+ ///
+ /// Indicates that a named attribute should be removed from the current node.
+ ///
+ RemoveAttribute = 5,
+
+ ///
+ /// Indicates that the text content of the current node (which must be a text node)
+ /// should be updated.
+ ///
+ UpdateText = 6,
+
+ ///
+ /// Indicates that the edit position should move inside the current node to its first
+ /// child (or, if there are no children, to a point where a first child would be).
+ ///
+ StepIn = 7,
+
+ ///
+ /// Indicates that there are no further edit operations on the current node, and the
+ /// edit position should move to the next sibling of the parent node (or if it does not
+ /// have a next sibling, then to the position where one would be).
+ ///
+ StepOut = 8,
+ }
+}
diff --git a/test/Microsoft.Blazor.Test/RenderTreeDiffTest.cs b/test/Microsoft.Blazor.Test/RenderTreeDiffComputerTest.cs
similarity index 79%
rename from test/Microsoft.Blazor.Test/RenderTreeDiffTest.cs
rename to test/Microsoft.Blazor.Test/RenderTreeDiffComputerTest.cs
index b40a9b2290..5144ccdff6 100644
--- a/test/Microsoft.Blazor.Test/RenderTreeDiffTest.cs
+++ b/test/Microsoft.Blazor.Test/RenderTreeDiffComputerTest.cs
@@ -11,7 +11,7 @@ using Xunit;
namespace Microsoft.Blazor.Test
{
- public class RenderTreeDiffTest
+ public class RenderTreeDiffComputerTest
{
[Theory]
[MemberData(nameof(RecognizesEquivalentNodesAsSameCases))]
@@ -20,7 +20,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
appendAction(oldTree);
appendAction(newTree);
@@ -51,7 +51,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(0, "text0");
oldTree.AddText(2, "text2");
newTree.AddText(0, "text0");
@@ -63,10 +63,10 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(1, entry.NewTreeIndex);
});
}
@@ -77,7 +77,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(0, "text0");
oldTree.AddText(1, "text1");
oldTree.AddText(2, "text2");
@@ -89,8 +89,8 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type));
}
[Fact]
@@ -99,7 +99,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(0, "x"); // Loop start
oldTree.AddText(1, "x"); // Will be removed
oldTree.AddText(2, "x"); // Will be removed
@@ -112,9 +112,9 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type));
}
[Fact]
@@ -123,7 +123,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(0, "x"); // Loop start
oldTree.AddText(0, "x"); // Loop start
newTree.AddText(0, "x"); // Loop start
@@ -136,15 +136,15 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(1, entry.NewTreeIndex);
},
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(2, entry.NewTreeIndex);
});
}
@@ -155,7 +155,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(0, "x");
oldTree.AddText(1, "x");
oldTree.AddText(0, "x"); // Will be removed
@@ -168,10 +168,10 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type));
}
[Fact]
@@ -180,7 +180,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(0, "x");
oldTree.AddText(1, "x");
newTree.AddText(0, "x");
@@ -193,16 +193,16 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(2, entry.NewTreeIndex);
},
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(3, entry.NewTreeIndex);
});
}
@@ -213,7 +213,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(2, "x");
oldTree.AddText(2, "x"); // Note that the '0' and '1' items are not present on this iteration
newTree.AddText(2, "x");
@@ -226,15 +226,15 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(1, entry.NewTreeIndex);
},
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(2, entry.NewTreeIndex);
});
}
@@ -245,7 +245,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(2, "x");
oldTree.AddText(0, "x");
oldTree.AddText(1, "x");
@@ -258,9 +258,9 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type));
}
[Fact]
@@ -269,7 +269,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(0, "text");
newTree.AddText(1, "text");
@@ -278,8 +278,8 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.PrependNode, entry.Type));
}
[Fact]
@@ -288,7 +288,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(123, "old text");
newTree.AddText(123, "new text");
@@ -299,7 +299,7 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.UpdateText, entry.Type);
+ Assert.Equal(RenderTreeEditType.UpdateText, entry.Type);
Assert.Equal(0, entry.NewTreeIndex);
});
}
@@ -314,7 +314,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.OpenElement(123, "old element");
oldTree.CloseElement();
newTree.OpenElement(123, "new element");
@@ -327,10 +327,10 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(0, entry.NewTreeIndex);
},
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type));
}
[Fact]
@@ -339,7 +339,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddComponent(123);
newTree.AddComponent(123);
@@ -350,10 +350,10 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.PrependNode, entry.Type);
+ Assert.Equal(RenderTreeEditType.PrependNode, entry.Type);
Assert.Equal(0, entry.NewTreeIndex);
},
- entry => Assert.Equal(RenderTreeDiffEntryType.RemoveNode, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.RemoveNode, entry.Type));
}
[Fact]
@@ -362,7 +362,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.OpenElement(0, "My element");
oldTree.AddAttribute(1, "existing", "existing value");
oldTree.CloseElement();
@@ -378,7 +378,7 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.SetAttribute, entry.Type);
+ Assert.Equal(RenderTreeEditType.SetAttribute, entry.Type);
Assert.Equal(2, entry.NewTreeIndex);
});
}
@@ -389,7 +389,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.OpenElement(0, "My element");
oldTree.AddAttribute(1, "will be removed", "will be removed value");
oldTree.AddAttribute(2, "will survive", "surviving value");
@@ -405,7 +405,7 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.RemoveAttribute, entry.Type);
+ Assert.Equal(RenderTreeEditType.RemoveAttribute, entry.Type);
Assert.Equal("will be removed", entry.RemovedAttributeName);
});
}
@@ -416,7 +416,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.OpenElement(0, "My element");
oldTree.AddAttribute(1, "will remain", "will remain value");
oldTree.AddAttribute(2, "will change", "will change value");
@@ -433,7 +433,7 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.SetAttribute, entry.Type);
+ Assert.Equal(RenderTreeEditType.SetAttribute, entry.Type);
Assert.Equal(2, entry.NewTreeIndex);
});
}
@@ -444,7 +444,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
UIEventHandler retainedHandler = _ => { };
UIEventHandler removedHandler = _ => { };
UIEventHandler addedHandler = _ => { };
@@ -464,7 +464,7 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.SetAttribute, entry.Type);
+ Assert.Equal(RenderTreeEditType.SetAttribute, entry.Type);
Assert.Equal(2, entry.NewTreeIndex);
});
}
@@ -475,7 +475,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.OpenElement(0, "My element");
oldTree.AddAttribute(1, "oldname", "same value");
oldTree.CloseElement();
@@ -490,12 +490,12 @@ namespace Microsoft.Blazor.Test
Assert.Collection(result,
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.SetAttribute, entry.Type);
+ Assert.Equal(RenderTreeEditType.SetAttribute, entry.Type);
Assert.Equal(1, entry.NewTreeIndex);
},
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.RemoveAttribute, entry.Type);
+ Assert.Equal(RenderTreeEditType.RemoveAttribute, entry.Type);
Assert.Equal("oldname", entry.RemovedAttributeName);
});
}
@@ -506,7 +506,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.OpenElement(10, "root");
oldTree.OpenElement(11, "child");
oldTree.OpenElement(12, "grandchild");
@@ -528,17 +528,17 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.StepIn, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.StepIn, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.StepIn, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.StepIn, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.StepIn, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.StepIn, entry.Type),
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.UpdateText, entry.Type);
+ Assert.Equal(RenderTreeEditType.UpdateText, entry.Type);
Assert.Equal(3, entry.NewTreeIndex);
},
- entry => Assert.Equal(RenderTreeDiffEntryType.StepOut, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.StepOut, entry.Type),
- entry => Assert.Equal(RenderTreeDiffEntryType.StepOut, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.StepOut, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.StepOut, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.StepOut, entry.Type));
}
[Fact]
@@ -547,7 +547,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.OpenElement(10, "root");
oldTree.AddText(11, "Text that will change");
oldTree.OpenElement(12, "Subtree that will not change");
@@ -571,13 +571,13 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.StepIn, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.StepIn, entry.Type),
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.UpdateText, entry.Type);
+ Assert.Equal(RenderTreeEditType.UpdateText, entry.Type);
Assert.Equal(1, entry.NewTreeIndex);
},
- entry => Assert.Equal(RenderTreeDiffEntryType.StepOut, entry.Type));
+ entry => Assert.Equal(RenderTreeEditType.StepOut, entry.Type));
}
[Fact]
@@ -586,7 +586,7 @@ namespace Microsoft.Blazor.Test
// Arrange
var oldTree = new RenderTreeBuilder(new FakeRenderer());
var newTree = new RenderTreeBuilder(new FakeRenderer());
- var diff = new RenderTreeDiff();
+ var diff = new RenderTreeDiffComputer();
oldTree.AddText(10, "text1");
oldTree.AddText(11, "text2");
oldTree.AddText(12, "text3");
@@ -601,10 +601,10 @@ namespace Microsoft.Blazor.Test
// Assert
Assert.Collection(result,
- entry => Assert.Equal(RenderTreeDiffEntryType.Continue, entry.Type),
+ entry => Assert.Equal(RenderTreeEditType.Continue, entry.Type),
entry =>
{
- Assert.Equal(RenderTreeDiffEntryType.UpdateText, entry.Type);
+ Assert.Equal(RenderTreeEditType.UpdateText, entry.Type);
Assert.Equal(1, entry.NewTreeIndex);
});
}