Skip to content

Commit 0011a48

Browse files
committed
abstract internal document edit into CreateSingleEdit
1 parent bfcddc8 commit 0011a48

File tree

4 files changed

+65
-65
lines changed

4 files changed

+65
-65
lines changed

Microsoft.Toolkit.Uwp.UI.Controls.Input/RichSuggestBox/RichSuggestBox.Document.cs

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
1515
/// </summary>
1616
public partial class RichSuggestBox
1717
{
18+
private void CreateSingleEdit(Action editAction)
19+
{
20+
_ignoreChange = true;
21+
editAction.Invoke();
22+
TextDocument.EndUndoGroup();
23+
TextDocument.BeginUndoGroup();
24+
_ignoreChange = false;
25+
}
26+
1827
private void ExpandSelectionOnPartialTokenSelect(ITextSelection selection, ITextRange tokenRange)
1928
{
2029
switch (selection.Type)
@@ -82,47 +91,11 @@ private void InvokeTokenPointerOver(PointerPoint pointer)
8291
}
8392
}
8493

85-
private bool TryCommitSuggestionIntoDocument(ITextRange range, string displayText, Guid id, ITextCharacterFormat format, bool addTrailingSpace = true)
86-
{
87-
// We don't want to set text when the display text doesn't change since it may lead to unexpected caret move.
88-
range.GetText(TextGetOptions.NoHidden, out var existingText);
89-
if (existingText != displayText)
90-
{
91-
range.SetText(TextSetOptions.Unhide, displayText);
92-
}
93-
94-
var formatBefore = range.CharacterFormat.GetClone();
95-
range.CharacterFormat.SetClone(format);
96-
PadRange(range, formatBefore);
97-
range.Link = $"\"{id}\"";
98-
99-
// In some rare case, setting Link can fail. Only observed when interacting with Undo/Redo feature.
100-
if (range.Link != $"\"{id}\"")
101-
{
102-
range.Delete(TextRangeUnit.Story, -1);
103-
return false;
104-
}
105-
106-
if (addTrailingSpace)
107-
{
108-
var clone = range.GetClone();
109-
clone.Collapse(false);
110-
clone.SetText(TextSetOptions.Unhide, " ");
111-
clone.Collapse(false);
112-
TextDocument.Selection.SetRange(clone.EndPosition, clone.EndPosition);
113-
}
114-
115-
return true;
116-
}
117-
11894
private void ValidateTokensInDocument()
11995
{
120-
lock (_tokensLock)
96+
foreach (var (_, token) in _tokens)
12197
{
122-
foreach (var (_, token) in _tokens)
123-
{
124-
token.Active = false;
125-
}
98+
token.Active = false;
12699
}
127100

128101
ForEachLinkInDocument(TextDocument, ValidateTokenFromRange);
@@ -138,18 +111,15 @@ private void ValidateTokenFromRange(ITextRange range)
138111
// Check for duplicate tokens. This can happen if the user copies and pastes the token multiple times.
139112
if (token.Active && token.RangeStart != range.StartPosition && token.RangeEnd != range.EndPosition)
140113
{
141-
lock (_tokensLock)
114+
var guid = Guid.NewGuid();
115+
if (TryCommitSuggestionIntoDocument(range, token.DisplayText, guid, CreateTokenFormat(range), false))
142116
{
143-
var guid = Guid.NewGuid();
144-
if (TryCommitSuggestionIntoDocument(range, token.DisplayText, guid, CreateTokenFormat(range), false))
145-
{
146-
token = new RichSuggestToken(guid, token.DisplayText) { Active = true, Item = token.Item };
147-
token.UpdateTextRange(range);
148-
_tokens.Add(range.Link, token);
149-
}
150-
151-
return;
117+
token = new RichSuggestToken(guid, token.DisplayText) { Active = true, Item = token.Item };
118+
token.UpdateTextRange(range);
119+
_tokens.Add(range.Link, token);
152120
}
121+
122+
return;
153123
}
154124

155125
if (token.ToString() != range.Text)
@@ -163,6 +133,39 @@ private void ValidateTokenFromRange(ITextRange range)
163133
token.Active = true;
164134
}
165135

136+
private bool TryCommitSuggestionIntoDocument(ITextRange range, string displayText, Guid id, ITextCharacterFormat format, bool addTrailingSpace)
137+
{
138+
// We don't want to set text when the display text doesn't change since it may lead to unexpected caret move.
139+
range.GetText(TextGetOptions.NoHidden, out var existingText);
140+
if (existingText != displayText)
141+
{
142+
range.SetText(TextSetOptions.Unhide, displayText);
143+
}
144+
145+
var formatBefore = range.CharacterFormat.GetClone();
146+
range.CharacterFormat.SetClone(format);
147+
PadRange(range, formatBefore);
148+
range.Link = $"\"{id}\"";
149+
150+
// In some rare case, setting Link can fail. Only observed when interacting with Undo/Redo feature.
151+
if (range.Link != $"\"{id}\"")
152+
{
153+
range.Delete(TextRangeUnit.Story, -1);
154+
return false;
155+
}
156+
157+
if (addTrailingSpace)
158+
{
159+
var clone = range.GetClone();
160+
clone.Collapse(false);
161+
clone.SetText(TextSetOptions.Unhide, " ");
162+
clone.Collapse(false);
163+
TextDocument.Selection.SetRange(clone.EndPosition, clone.EndPosition);
164+
}
165+
166+
return true;
167+
}
168+
166169
private bool TryExtractQueryFromSelection(out string prefix, out string query, out ITextRange range)
167170
{
168171
prefix = string.Empty;

Microsoft.Toolkit.Uwp.UI.Controls.Input/RichSuggestBox/RichSuggestBox.Helpers.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
using System;
66
using System.Linq;
7-
using Windows.Foundation;
87
using Windows.Graphics.Display;
98
using Windows.UI.Core;
109
using Windows.UI.Text;

Microsoft.Toolkit.Uwp.UI.Controls.Input/RichSuggestBox/RichSuggestBox.Suggestion.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,22 @@ internal async Task CommitSuggestionAsync(object selectedItem)
119119
return;
120120
}
121121

122-
lock (_tokensLock)
123-
{
124-
var displayText = prefix + text;
122+
var displayText = prefix + text;
125123

126-
_ignoreChange = true;
127-
var committed = TryCommitSuggestionIntoDocument(range, displayText, id, eventArgs.Format ?? format);
128-
TextDocument.EndUndoGroup();
129-
TextDocument.BeginUndoGroup();
130-
_ignoreChange = false;
131-
132-
if (committed)
124+
void RealizeToken()
125+
{
126+
if (TryCommitSuggestionIntoDocument(range, displayText, id, eventArgs.Format ?? format, true))
133127
{
134128
var token = new RichSuggestToken(id, displayText) { Active = true, Item = selectedItem };
135129
token.UpdateTextRange(range);
136-
_tokens.TryAdd(range.Link, token);
130+
_tokens.Add(range.Link, token);
137131
}
138132
}
133+
134+
lock (_tokensLock)
135+
{
136+
this.CreateSingleEdit(RealizeToken);
137+
}
139138
}
140139

141140
private void UpdateSuggestionsListSelectedItem(int choice)

Microsoft.Toolkit.Uwp.UI.Controls.Input/RichSuggestBox/RichSuggestBox.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,10 @@ private void RichEditBox_TextChanging(RichEditBox sender, RichEditBoxTextChangin
400400
return;
401401
}
402402

403-
_ignoreChange = true;
404-
ValidateTokensInDocument();
405-
TextDocument.EndUndoGroup();
406-
TextDocument.BeginUndoGroup();
407-
_ignoreChange = false;
403+
lock (_tokensLock)
404+
{
405+
this.CreateSingleEdit(ValidateTokensInDocument);
406+
}
408407
}
409408

410409
private void RichEditBox_TextChanged(object sender, RoutedEventArgs e)

0 commit comments

Comments
 (0)