mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1051556 - Make GeckoEditable.onTextChange more efficient; r=esawin
This patch simplifies the onTextChange method, makes it more efficient by avoiding unnecessary text copying, and fixes some small bugs.
This commit is contained in:
parent
8535f18422
commit
aa9db9aeed
@ -968,10 +968,14 @@ final class GeckoEditable extends JNIObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void geckoReplaceText(int start, int oldEnd, CharSequence newText) {
|
private void geckoReplaceText(int start, int oldEnd, CharSequence newText) {
|
||||||
// Don't use replace() because Gingerbread has a bug where if the replaced text
|
if (AppConstants.Versions.preHC) {
|
||||||
// has the same spans as the original text, the spans will end up being deleted
|
// Don't use replace() because Gingerbread has a bug where if the replaced text
|
||||||
mText.delete(start, oldEnd);
|
// has the same spans as the original text, the spans will end up being deleted
|
||||||
mText.insert(start, newText);
|
mText.delete(start, oldEnd);
|
||||||
|
mText.insert(start, newText);
|
||||||
|
} else {
|
||||||
|
mText.replace(start, oldEnd, newText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSameText(int start, int oldEnd, CharSequence newText) {
|
private boolean isSameText(int start, int oldEnd, CharSequence newText) {
|
||||||
@ -1013,62 +1017,42 @@ final class GeckoEditable extends JNIObject
|
|||||||
// Simply replace the text for newly-focused editors.
|
// Simply replace the text for newly-focused editors.
|
||||||
mText.replace(0, mText.length(), text);
|
mText.replace(0, mText.length(), text);
|
||||||
|
|
||||||
} else {
|
} else if (action != null &&
|
||||||
mChangedText.clearSpans();
|
action.mType == Action.TYPE_REPLACE_TEXT &&
|
||||||
mChangedText.replace(0, mChangedText.length(), text);
|
start <= action.mStart &&
|
||||||
// Preserve as many spans as possible
|
oldEnd >= action.mEnd &&
|
||||||
TextUtils.copySpansFrom(mText, start, Math.min(oldEnd, newEnd),
|
newEnd >= action.mStart + action.mSequence.length()) {
|
||||||
Object.class, mChangedText, 0);
|
|
||||||
|
|
||||||
if (action != null &&
|
// actionNewEnd is the new end of the original replacement action
|
||||||
action.mType == Action.TYPE_REPLACE_TEXT &&
|
final int actionNewEnd = action.mStart + action.mSequence.length();
|
||||||
start <= action.mStart &&
|
|
||||||
action.mStart + action.mSequence.length() <= newEnd) {
|
|
||||||
|
|
||||||
// actionNewEnd is the new end of the original replacement action
|
|
||||||
final int actionNewEnd = action.mStart + action.mSequence.length();
|
|
||||||
int selStart = Selection.getSelectionStart(mText);
|
|
||||||
int selEnd = Selection.getSelectionEnd(mText);
|
|
||||||
|
|
||||||
// Replace old spans with new spans
|
|
||||||
mChangedText.replace(action.mStart - start, actionNewEnd - start,
|
|
||||||
action.mSequence);
|
|
||||||
geckoReplaceText(start, oldEnd, mChangedText);
|
|
||||||
|
|
||||||
// delete/insert above might have moved our selection to somewhere else
|
|
||||||
// this happens when the Gecko text change covers a larger range than
|
|
||||||
// the original replacement action. Fix selection here
|
|
||||||
if (selStart >= start && selStart <= oldEnd) {
|
|
||||||
selStart = selStart < action.mStart ? selStart :
|
|
||||||
selStart < action.mEnd ? actionNewEnd :
|
|
||||||
selStart + actionNewEnd - action.mEnd;
|
|
||||||
mText.setSpan(Selection.SELECTION_START, selStart, selStart,
|
|
||||||
Spanned.SPAN_POINT_POINT);
|
|
||||||
}
|
|
||||||
if (selEnd >= start && selEnd <= oldEnd) {
|
|
||||||
selEnd = selEnd < action.mStart ? selEnd :
|
|
||||||
selEnd < action.mEnd ? actionNewEnd :
|
|
||||||
selEnd + actionNewEnd - action.mEnd;
|
|
||||||
mText.setSpan(Selection.SELECTION_END, selEnd, selEnd,
|
|
||||||
Spanned.SPAN_POINT_POINT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore the next selection change because the selection change is a
|
|
||||||
// side-effect of the replace-text event we sent.
|
|
||||||
mIgnoreSelectionChange = true;
|
|
||||||
|
|
||||||
|
// Replace old spans with new spans
|
||||||
|
if (start == action.mStart && oldEnd == action.mEnd && newEnd == actionNewEnd) {
|
||||||
|
// The new text exactly matches our sequence, so do a direct replace.
|
||||||
|
geckoReplaceText(start, oldEnd, action.mSequence);
|
||||||
} else {
|
} else {
|
||||||
// Gecko side initiated the text change.
|
mChangedText.clearSpans();
|
||||||
if (isSameText(start, oldEnd, mChangedText)) {
|
mChangedText.replace(0, mChangedText.length(), mText, start, oldEnd);
|
||||||
// Nothing to do because the text is the same. This could happen when
|
mChangedText.replace(action.mStart - start, action.mEnd - start, action.mSequence);
|
||||||
// the composition is updated for example. Ignore the next selection
|
|
||||||
// change because the selection change is a side-effect of the
|
|
||||||
// update-composition event we sent.
|
|
||||||
mIgnoreSelectionChange = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
geckoReplaceText(start, oldEnd, mChangedText);
|
geckoReplaceText(start, oldEnd, mChangedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ignore the next selection change because the selection change is a
|
||||||
|
// side-effect of the replace-text event we sent.
|
||||||
|
mIgnoreSelectionChange = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Gecko side initiated the text change.
|
||||||
|
if (isSameText(start, oldEnd, text)) {
|
||||||
|
// Nothing to do because the text is the same. This could happen when
|
||||||
|
// the composition is updated for example. Ignore the next selection
|
||||||
|
// change because the selection change is a side-effect of the
|
||||||
|
// update-composition event we sent.
|
||||||
|
mIgnoreSelectionChange = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
geckoReplaceText(start, oldEnd, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
geckoPostToIc(new Runnable() {
|
geckoPostToIc(new Runnable() {
|
||||||
|
Loading…
Reference in New Issue
Block a user