// Token: 0x06002BD1 RID: 11217 RVA: 0x000C7918 File Offset: 0x000C5B18 private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange) { Invariant.Assert(!this._isReadOnly, "Illegal to modify DocumentSequenceTextContainer inside Change event scope!"); ((ITextContainer)this).BeginChange(); try { if (this.Changing != null) { this.Changing(this, EventArgs.Empty); } if (this._changes == null) { this._changes = new TextContainerChangedEventArgs(); } this._changes.AddChange(precursorTextChange, DocumentSequenceTextPointer.GetOffsetToPosition(this._start, startPosition), symbolCount, false); if (this.Change != null) { Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved; this._isReadOnly = true; try { this.Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, -1, textChange)); } finally { this._isReadOnly = false; } } } finally { ((ITextContainer)this).EndChange(); } }
// Token: 0x060037B5 RID: 14261 RVA: 0x000F8C68 File Offset: 0x000F6E68 internal void AddChange(PrecursorTextChangeType textChange, int offset, int length, bool collectTextChanges) { if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded || textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted) { this._hasContentAddedOrRemoved = true; } if (!collectTextChanges) { return; } if (textChange == PrecursorTextChangeType.ElementAdded) { this.AddChangeToList(textChange, offset, 1); this.AddChangeToList(textChange, offset + length - 1, 1); return; } if (textChange == PrecursorTextChangeType.ElementExtracted) { this.AddChangeToList(textChange, offset + length - 1, 1); this.AddChangeToList(textChange, offset, 1); return; } if (textChange == PrecursorTextChangeType.PropertyModified) { return; } this.AddChangeToList(textChange, offset, length); }
// Token: 0x0600539A RID: 21402 RVA: 0x00173170 File Offset: 0x00171370 private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange) { Invariant.Assert(this._changeBlockLevel > 0, "All public APIs must call BeginChange!"); Invariant.Assert(!this._isReadOnly, "Illegal to modify PasswordTextContainer inside Change event scope!"); if (this.Changing != null) { this.Changing(this, EventArgs.Empty); } if (this._changes == null) { this._changes = new TextContainerChangedEventArgs(); } this._changes.AddChange(precursorTextChange, startPosition.Offset, symbolCount, false); if (this.Change != null) { Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved; this._isReadOnly = true; try { this.Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, symbolCount, textChange)); } finally { this._isReadOnly = false; } } }
private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange) { Invariant.Assert(!_isReadOnly, "Illegal to modify DocumentSequenceTextContainer inside Change event scope!"); ITextContainer textContainer = (ITextContainer)this; textContainer.BeginChange(); try { // Contact any listeners. if (this.Changing != null) { Changing(this, EventArgs.Empty); } // Fire the ChangingEvent now if we haven't already. if (_changes == null) { _changes = new TextContainerChangedEventArgs(); } _changes.AddChange(precursorTextChange, DocumentSequenceTextPointer.GetOffsetToPosition(_start, startPosition), symbolCount, false /* collectTextChanges */); if (this.Change != null) { Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved; _isReadOnly = true; try { // Pass in a -1 for charCount parameter. DocumentSequenceTextContainer // doesn't support this feature because it is only consumed by IMEs // which never run on read-only documents. Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, -1, textChange)); } finally { _isReadOnly = false; } } } finally { textContainer.EndChange(); } }
// Adds a new change to the Delta list. internal void AddChange(PrecursorTextChangeType textChange, int offset, int length, bool collectTextChanges) { if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded || textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted) { _hasContentAddedOrRemoved = true; } if (!collectTextChanges) { return; } // We only want to add or remove the edges for empty elements (and ElementAdded / // ElementRemoved are only used with empty elements). Note that since we're making // two changes instead of one the order matters. We have to treat the two cases differently. if (textChange == PrecursorTextChangeType.ElementAdded) { AddChangeToList(textChange, offset, 1); AddChangeToList(textChange, offset + length - 1, 1); } else if (textChange == PrecursorTextChangeType.ElementExtracted) { AddChangeToList(textChange, offset + length - 1, 1); AddChangeToList(textChange, offset, 1); } else if (textChange == PrecursorTextChangeType.PropertyModified) { // ignore property changes return; } else { AddChangeToList(textChange, offset, length); } }
// Adds a new change to the Delta list. internal void AddChange(PrecursorTextChangeType textChange, int offset, int length, bool collectTextChanges) { if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded || textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted) { _hasContentAddedOrRemoved = true; } if (!collectTextChanges) { return; } // We only want to add or remove the edges for empty elements (and ElementAdded / // ElementRemoved are only used with empty elements). Note that since we're making // two changes instead of one the order matters. We have to treat the two cases differently. if (textChange == PrecursorTextChangeType.ElementAdded) { AddChangeToList(textChange, offset, 1); AddChangeToList(textChange, offset + length - 1, 1); } else if (textChange == PrecursorTextChangeType.ElementExtracted) { AddChangeToList(textChange, offset + length - 1, 1); AddChangeToList(textChange, offset, 1); } else if (textChange == PrecursorTextChangeType.PropertyModified) { // ignore property changes return; } else { AddChangeToList(textChange, offset, length); } }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ #region Private Methods private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange) { Invariant.Assert(_changeBlockLevel > 0, "All public APIs must call BeginChange!"); Invariant.Assert(!_isReadOnly, "Illegal to modify PasswordTextContainer inside Change event scope!"); // Contact any listeners. if (this.Changing != null) { Changing(this, EventArgs.Empty); } // Fire the ChangingEvent now if we haven't already. if (_changes == null) { _changes = new TextContainerChangedEventArgs(); } _changes.AddChange(precursorTextChange, startPosition.Offset, symbolCount, false /* collectTextChanges */); if (this.Change != null) { Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved; _isReadOnly = true; try { Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, symbolCount, textChange)); } finally { _isReadOnly = false; } } }
//----------------------------------------------------- // // Private Methods // //------------------------------------------------------ // // First we discover where the new change goes in the sorted list. If there's already // a change there, merge the new one with the old one. // // Next, if the new change is an insertion or deletion, see if the offset of the change // is within a range covered by an insertion at a lower offset. If so, merge the change at // the higher offset into the previous change and delete the change at the higher offset. // // Next, if the change is a deletion, see if we delete enough characters to run into a // change at a higher offset. If so, merge the change at the higher offset into this newer // change and delete the older, higher-offset change. // // Finally, update all offsets higher than the current change to reflect the number of // characters inserted or deleted. // private void AddChangeToList(PrecursorTextChangeType textChange, int offset, int length) { int offsetDelta = 0; // Value by which to adjust other offsets in list int curIndex; // loop counter TextChange change = null; // initialize to satisfy compiler bool isDeletion = false; #if PROPERTY_CHANGES bool shiftPropertyChanges = false; #endif // // Is there already a change at this offset in our list? If so, use it // int keyIndex = Changes.IndexOfKey(offset); if (keyIndex != -1) { change = Changes.Values[keyIndex]; } else { change = new TextChange(); change.Offset = offset; Changes.Add(offset, change); keyIndex = Changes.IndexOfKey(offset); } // // Merge values from new change into empty or pre-existing change // if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded) { change.AddedLength += length; offsetDelta = length; #if PROPERTY_CHANGES if (change.PropertyCount > 0) { shiftPropertyChanges = true; } #endif } else if (textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted) { // Any deletions made after an addition just cancel out the earlier addition change.RemovedLength += Math.Max(0, length - change.AddedLength); change.AddedLength = Math.Max(0, change.AddedLength - length); #if PROPERTY_CHANGES // If an element was extracted, any property change made on that element should be removed as well if (textChange == PrecursorTextChangeType.ElementExtracted) { change.SetPropertyCount(0); } else { change.SetPropertyCount(Math.Max(0, change.PropertyCount - length)); } #endif offsetDelta = -length; isDeletion = true; } #if PROPERTY_CHANGES else { // Property change if (change.PropertyCount < length) { change.SetPropertyCount(length); } } #endif // // Done with simple case. Now look for changes that intersect. // There are two possible (non-exclusive) merge conditions: // 1. A positionally preceding change spans this offset (this change is inserting // into or deleting from the middle or right edge of previous inserted text) // 2. On deletion, the change spans one or more positionally later changes // if (keyIndex > 0 && textChange != PrecursorTextChangeType.PropertyModified) { curIndex = keyIndex - 1; // Since we don't merge property changes, there could be an arbitrary number of // them between the new change and an overlapping insertion or overlapping property // change. In fact, there could be multiple property changes that overlap this // change. We need to adjust ALL of them. There can be only one overlapping // insertion, but there's no way to leverage that fact. TextChange mergedChange = null; while (curIndex >= 0) { TextChange prevChange = Changes.Values[curIndex]; #if PROPERTY_CHANGES if (prevChange.Offset + prevChange.AddedLength >= offset || prevChange.Offset + prevChange.PropertyCount >= offset) #else if (prevChange.Offset + prevChange.AddedLength >= offset) #endif { if (MergeTextChangeLeft(prevChange, change, isDeletion, length)) { mergedChange = prevChange; } } curIndex--; } if (mergedChange != null) { // the change got merged. Use the merged change as the basis for righthand merging. change = mergedChange; } // changes may have been deleted, so update the index of the change we're working with keyIndex = Changes.IndexOfKey(change.Offset); } curIndex = keyIndex + 1; if (isDeletion && curIndex < Changes.Count) { while (curIndex < Changes.Count && Changes.Values[curIndex].Offset <= offset + length) { // offset and length must be passed because if we've also merged left, we haven't yet adjusted indices. // Note that MergeTextChangeRight() always removes Changes.Values[curIndex] from the list, so // we don't need to increment curIndex. MergeTextChangeRight(Changes.Values[curIndex], change, offset, length); } // changes may have been deleted, so update the index of the change we're working with keyIndex = Changes.IndexOfKey(change.Offset); } // Update all changes to reflect new offsets. // If offsetDelta is positive, go right to left; otherwise, go left to right. // The order of the offsets will never change, so we can use an indexer safely. // To avoid nasty N-squared perf, create a new list instead of moving things within // the old one. // if (offsetDelta != 0) { SortedList<int, TextChange> newChanges = new SortedList<int, TextChange>(Changes.Count); for (curIndex = 0; curIndex < Changes.Count; curIndex++) { TextChange curChange = Changes.Values[curIndex]; if (curIndex > keyIndex) { curChange.Offset += offsetDelta; } newChanges.Add(curChange.Offset, curChange); } _changes = newChanges; } DeleteChangeIfEmpty(change); #if PROPERTY_CHANGES // Finally, if the change was an insertion and there are property changes starting // at this location, the insertion is not part of the property changes. Shift the // property changes forward by the length of the insertion. if (shiftPropertyChanges) { int propertyCount = change.PropertyCount; change.SetPropertyCount(0); AddChangeToList(PrecursorTextChangeType.PropertyModified, offset + offsetDelta, propertyCount); } #endif }
//----------------------------------------------------- // // Private Methods // //----------------------------------------------------- #region Private Methods private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange) { Invariant.Assert(_changeBlockLevel > 0, "All public APIs must call BeginChange!"); Invariant.Assert(!_isReadOnly, "Illegal to modify PasswordTextContainer inside Change event scope!"); // Contact any listeners. if (this.Changing != null) { Changing(this, EventArgs.Empty); } // Fire the ChangingEvent now if we haven't already. if (_changes == null) { _changes = new TextContainerChangedEventArgs(); } _changes.AddChange(precursorTextChange, startPosition.Offset, symbolCount, false /* collectTextChanges */); if (this.Change != null) { Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved; _isReadOnly = true; try { Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, symbolCount, textChange)); } finally { _isReadOnly = false; } } }
// Returns the TextChange matching an ContentAdded, ContentRemoved, // or PropertyModified PrecursorTextChange. private TextChangeType ConvertSimplePrecursorChangeToTextChange(PrecursorTextChangeType precursorTextChange) { Invariant.Assert(precursorTextChange != PrecursorTextChangeType.ElementAdded && precursorTextChange != PrecursorTextChangeType.ElementExtracted); return (TextChangeType)precursorTextChange; }
private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange) { Invariant.Assert(!_isReadOnly, "Illegal to modify DocumentSequenceTextContainer inside Change event scope!"); ITextContainer textContainer = (ITextContainer)this; textContainer.BeginChange(); try { // Contact any listeners. if (this.Changing != null) { Changing(this, EventArgs.Empty); } // Fire the ChangingEvent now if we haven't already. if (_changes == null) { _changes = new TextContainerChangedEventArgs(); } _changes.AddChange(precursorTextChange, DocumentSequenceTextPointer.GetOffsetToPosition(_start, startPosition), symbolCount, false /* collectTextChanges */); if (this.Change != null) { Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved); TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved; _isReadOnly = true; try { // Pass in a -1 for charCount parameter. DocumentSequenceTextContainer // doesn't support this feature because it is only consumed by IMEs // which never run on read-only documents. Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, -1, textChange)); } finally { _isReadOnly = false; } } } finally { textContainer.EndChange(); } }
// Adds a change to the current change block. // This call must be preceeded by a matching BeforeAddChange. internal void AddChange(TextPointer startPosition, int symbolCount, int charCount, PrecursorTextChangeType textChange) { AddChange(startPosition, symbolCount, charCount, textChange, null, false); }
// Adds a change to the current change block. // This call must be preceeded by a matching BeforeAddChange. internal void AddChange(TextPointer startPosition, int symbolCount, int charCount, PrecursorTextChangeType textChange, DependencyProperty property, bool affectsRenderOnly) { Invariant.Assert(textChange != PrecursorTextChangeType.ElementAdded && textChange != PrecursorTextChangeType.ElementExtracted, "Need second TextPointer for ElementAdded/Extracted operations!"); AddChange(startPosition, null, symbolCount, /* leftEdgeCharCount */ 0, charCount, textChange, property, affectsRenderOnly); }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ // // First we discover where the new change goes in the sorted list. If there's already // a change there, merge the new one with the old one. // // Next, if the new change is an insertion or deletion, see if the offset of the change // is within a range covered by an insertion at a lower offset. If so, merge the change at // the higher offset into the previous change and delete the change at the higher offset. // // Next, if the change is a deletion, see if we delete enough characters to run into a // change at a higher offset. If so, merge the change at the higher offset into this newer // change and delete the older, higher-offset change. // // Finally, update all offsets higher than the current change to reflect the number of // characters inserted or deleted. // private void AddChangeToList(PrecursorTextChangeType textChange, int offset, int length) { int offsetDelta = 0; // Value by which to adjust other offsets in list int curIndex; // loop counter TextChange change = null; // initialize to satisfy compiler bool isDeletion = false; #if PROPERTY_CHANGES bool shiftPropertyChanges = false; #endif // // Is there already a change at this offset in our list? If so, use it // int keyIndex = Changes.IndexOfKey(offset); if (keyIndex != -1) { change = Changes.Values[keyIndex]; } else { change = new TextChange(); change.Offset = offset; Changes.Add(offset, change); keyIndex = Changes.IndexOfKey(offset); } // // Merge values from new change into empty or pre-existing change // if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded) { change.AddedLength += length; offsetDelta = length; #if PROPERTY_CHANGES if (change.PropertyCount > 0) { shiftPropertyChanges = true; } #endif } else if (textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted) { // Any deletions made after an addition just cancel out the earlier addition change.RemovedLength += Math.Max(0, length - change.AddedLength); change.AddedLength = Math.Max(0, change.AddedLength - length); #if PROPERTY_CHANGES // If an element was extracted, any property change made on that element should be removed as well if (textChange == PrecursorTextChangeType.ElementExtracted) { change.SetPropertyCount(0); } else { change.SetPropertyCount(Math.Max(0, change.PropertyCount - length)); } #endif offsetDelta = -length; isDeletion = true; } #if PROPERTY_CHANGES else { // Property change if (change.PropertyCount < length) { change.SetPropertyCount(length); } } #endif // // Done with simple case. Now look for changes that intersect. // There are two possible (non-exclusive) merge conditions: // 1. A positionally preceding change spans this offset (this change is inserting // into or deleting from the middle or right edge of previous inserted text) // 2. On deletion, the change spans one or more positionally later changes // if (keyIndex > 0 && textChange != PrecursorTextChangeType.PropertyModified) { curIndex = keyIndex - 1; // Since we don't merge property changes, there could be an arbitrary number of // them between the new change and an overlapping insertion or overlapping property // change. In fact, there could be multiple property changes that overlap this // change. We need to adjust ALL of them. There can be only one overlapping // insertion, but there's no way to leverage that fact. TextChange mergedChange = null; while (curIndex >= 0) { TextChange prevChange = Changes.Values[curIndex]; #if PROPERTY_CHANGES if (prevChange.Offset + prevChange.AddedLength >= offset || prevChange.Offset + prevChange.PropertyCount >= offset) #else if (prevChange.Offset + prevChange.AddedLength >= offset) #endif { if (MergeTextChangeLeft(prevChange, change, isDeletion, length)) { mergedChange = prevChange; } } curIndex--; } if (mergedChange != null) { // the change got merged. Use the merged change as the basis for righthand merging. change = mergedChange; } // changes may have been deleted, so update the index of the change we're working with keyIndex = Changes.IndexOfKey(change.Offset); } curIndex = keyIndex + 1; if (isDeletion && curIndex < Changes.Count) { while (curIndex < Changes.Count && Changes.Values[curIndex].Offset <= offset + length) { // offset and length must be passed because if we've also merged left, we haven't yet adjusted indices. // Note that MergeTextChangeRight() always removes Changes.Values[curIndex] from the list, so // we don't need to increment curIndex. MergeTextChangeRight(Changes.Values[curIndex], change, offset, length); } // changes may have been deleted, so update the index of the change we're working with keyIndex = Changes.IndexOfKey(change.Offset); } // Update all changes to reflect new offsets. // If offsetDelta is positive, go right to left; otherwise, go left to right. // The order of the offsets will never change, so we can use an indexer safely. // To avoid nasty N-squared perf, create a new list instead of moving things within // the old one. // Change the implementation of Changes to a more efficient structure. if (offsetDelta != 0) { SortedList <int, TextChange> newChanges = new SortedList <int, TextChange>(Changes.Count); for (curIndex = 0; curIndex < Changes.Count; curIndex++) { TextChange curChange = Changes.Values[curIndex]; if (curIndex > keyIndex) { curChange.Offset += offsetDelta; } newChanges.Add(curChange.Offset, curChange); } _changes = newChanges; } DeleteChangeIfEmpty(change); #if PROPERTY_CHANGES // Finally, if the change was an insertion and there are property changes starting // at this location, the insertion is not part of the property changes. Shift the // property changes forward by the length of the insertion. if (shiftPropertyChanges) { int propertyCount = change.PropertyCount; change.SetPropertyCount(0); AddChangeToList(PrecursorTextChangeType.PropertyModified, offset + offsetDelta, propertyCount); } #endif }
// Adds a change to the current change block. // This call must be preceeded by a matching BeforeAddChange. internal void AddChange(TextPointer startPosition, TextPointer endPosition, int symbolCount, int leftEdgeCharCount, int childCharCount, PrecursorTextChangeType textChange, DependencyProperty property, bool affectsRenderOnly) { Invariant.Assert(_changeBlockLevel > 0, "All public APIs must call BeginChange!"); Invariant.Assert(!CheckFlags(Flags.ReadOnly) || textChange == PrecursorTextChangeType.PropertyModified, "Illegal to modify TextContainer structure inside Change event scope!"); if (this.HasListeners) { // Lazy init _changes. This looks redundant with the BeforeAddChange call // we already require -- strictly speaking that's true. But in practice, // we want the Invariant in this method to remind callers to think about // when they must call BeforeAddChange ahead of logical tree events. Then, // in practice, there's a subtle bug where a listener might not initially // exist but is added during the logical tree events. That we handle // here with an additional BeforeAddChange call instead of requiring all // our callers to remember to handle the more subtle case. if (_changes == null) { _changes = new TextContainerChangedEventArgs(); } Invariant.Assert(_changes != null, "Missing call to BeforeAddChange!"); _changes.AddChange(textChange, startPosition.Offset, symbolCount, this.CollectTextChanges); if (this.ChangeHandler != null) { FireChangeEvent(startPosition, endPosition, symbolCount, leftEdgeCharCount, childCharCount, textChange, property, affectsRenderOnly); } } }
// Worker for AddChange, fires a Change event. private void FireChangeEvent(TextPointer startPosition, TextPointer endPosition, int symbolCount, int leftEdgeCharCount, int childCharCount, PrecursorTextChangeType precursorTextChange, DependencyProperty property, bool affectsRenderOnly) { Invariant.Assert(this.ChangeHandler != null); // Set a flag to disallow reentrant edits. We really can't support // that here, because any edits to the document would break the // BeginChange/EndChange contract (no edits by listeners in a change // block!). // (Note, we will allow re-entrant property changes only, because // property change events are not exposed publicly on TextBox or RTB.) SetFlags(true, Flags.ReadOnly); try { if (precursorTextChange == PrecursorTextChangeType.ElementAdded) { Invariant.Assert(symbolCount > 2, "ElementAdded must span at least two element edges and one content symbol!"); TextContainerChangeEventArgs args1 = new TextContainerChangeEventArgs(startPosition, 1, leftEdgeCharCount, TextChangeType.ContentAdded); TextContainerChangeEventArgs args2 = new TextContainerChangeEventArgs(endPosition, 1, 0, TextChangeType.ContentAdded); ChangeHandler(this, args1); ChangeHandler(this, args2); } else if (precursorTextChange == PrecursorTextChangeType.ElementExtracted) { Invariant.Assert(symbolCount > 2, "ElementExtracted must span at least two element edges and one content symbol!"); TextContainerChangeEventArgs args1 = new TextContainerChangeEventArgs(startPosition, 1, leftEdgeCharCount, TextChangeType.ContentRemoved); TextContainerChangeEventArgs args2 = new TextContainerChangeEventArgs(endPosition, 1, 0, TextChangeType.ContentRemoved); ChangeHandler(this, args1); ChangeHandler(this, args2); } else { TextContainerChangeEventArgs args = new TextContainerChangeEventArgs(startPosition, symbolCount, leftEdgeCharCount + childCharCount, ConvertSimplePrecursorChangeToTextChange(precursorTextChange), property, affectsRenderOnly); ChangeHandler(this, args); } } finally { SetFlags(false, Flags.ReadOnly); } }
// Token: 0x060037B9 RID: 14265 RVA: 0x000F8CEC File Offset: 0x000F6EEC private void AddChangeToList(PrecursorTextChangeType textChange, int offset, int length) { int num = 0; bool flag = false; int num2 = this.Changes.IndexOfKey(offset); TextChange textChange2; if (num2 != -1) { textChange2 = this.Changes.Values[num2]; } else { textChange2 = new TextChange(); textChange2.Offset = offset; this.Changes.Add(offset, textChange2); num2 = this.Changes.IndexOfKey(offset); } if (textChange == PrecursorTextChangeType.ContentAdded || textChange == PrecursorTextChangeType.ElementAdded) { textChange2.AddedLength += length; num = length; } else if (textChange == PrecursorTextChangeType.ContentRemoved || textChange == PrecursorTextChangeType.ElementExtracted) { textChange2.RemovedLength += Math.Max(0, length - textChange2.AddedLength); textChange2.AddedLength = Math.Max(0, textChange2.AddedLength - length); num = -length; flag = true; } int i; if (num2 > 0 && textChange != PrecursorTextChangeType.PropertyModified) { i = num2 - 1; TextChange textChange3 = null; while (i >= 0) { TextChange textChange4 = this.Changes.Values[i]; if (textChange4.Offset + textChange4.AddedLength >= offset && this.MergeTextChangeLeft(textChange4, textChange2, flag, length)) { textChange3 = textChange4; } i--; } if (textChange3 != null) { textChange2 = textChange3; } num2 = this.Changes.IndexOfKey(textChange2.Offset); } i = num2 + 1; if (flag && i < this.Changes.Count) { while (i < this.Changes.Count && this.Changes.Values[i].Offset <= offset + length) { this.MergeTextChangeRight(this.Changes.Values[i], textChange2, offset, length); } num2 = this.Changes.IndexOfKey(textChange2.Offset); } if (num != 0) { SortedList <int, TextChange> sortedList = new SortedList <int, TextChange>(this.Changes.Count); for (i = 0; i < this.Changes.Count; i++) { TextChange textChange5 = this.Changes.Values[i]; if (i > num2) { textChange5.Offset += num; } sortedList.Add(textChange5.Offset, textChange5); } this._changes = sortedList; } this.DeleteChangeIfEmpty(textChange2); }