/// <summary> /// Updates positions of all elements and attributes in the tree /// reflecting change made to the source text buffer. /// </summary> /// <param name="start">Start position of the change</param> /// <param name="oldLength">Length of changed fragment before the change</param> /// <param name="newLength">Length of changed fragment after the change</param> public void ReflectTextChanges(IList <TextChangeEventArgs> textChanges) { if (textChanges.Count == 1) { ReflectTextChange(textChanges[0].Start, textChanges[0].OldLength, textChanges[0].NewLength); } else if (textChanges.Count > 1) { // See if we can merge the edits into a single ReflectTextChange call TextChangeEventArgs firstChange = textChanges[0]; TextChangeEventArgs lastChange = textChanges[textChanges.Count - 1]; int start = firstChange.Start; int oldLength = (lastChange.OldStart - firstChange.OldStart) + lastChange.OldLength; bool allowMerge = true; int firstItemAtOrAfter; if (allowMerge) { firstItemAtOrAfter = CommentCollection.GetFirstItemAfterOrAtPosition(start); if ((firstItemAtOrAfter >= 0) && (CommentCollection[firstItemAtOrAfter].Start <= start + oldLength)) { allowMerge = false; } } if (allowMerge) { ElementNode element = RootNode.ElementFromPosition(start); if ((element == null) || (element.InnerRange.Start > start) || (element.InnerRange.End < (start + oldLength))) { allowMerge = false; } else if (element.Children.Count != 0) { allowMerge = false; } } if (allowMerge) { int newLength = (lastChange.Start - firstChange.Start) + lastChange.NewLength; ReflectTextChange(start, oldLength, newLength); } else { foreach (TextChangeEventArgs curChange in textChanges) { ReflectTextChange(curChange.Start, curChange.OldLength, curChange.NewLength); } } } }