зеркало из https://github.com/mozilla/gecko-dev.git
Bug 734156 - Part 2: Clamp current selection's indexes. r=blassey
This commit is contained in:
Родитель
4049be1abc
Коммит
3d1d774472
|
@ -184,15 +184,9 @@ public class GeckoInputConnection
|
|||
|
||||
String text = content.toString();
|
||||
|
||||
clampSelection();
|
||||
int a = Selection.getSelectionStart(content);
|
||||
int b = Selection.getSelectionEnd(content);
|
||||
if (a < 0) a = 0;
|
||||
if (b < 0) b = 0;
|
||||
if (a > b) {
|
||||
int tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case R.id.selectAll:
|
||||
|
@ -239,17 +233,9 @@ public class GeckoInputConnection
|
|||
extract.partialStartOffset = -1;
|
||||
extract.partialEndOffset = -1;
|
||||
|
||||
int a = Selection.getSelectionStart(content);
|
||||
int b = Selection.getSelectionEnd(content);
|
||||
if (a > b) {
|
||||
int tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
extract.selectionStart = a;
|
||||
extract.selectionEnd = b;
|
||||
|
||||
clampSelection();
|
||||
extract.selectionStart = Selection.getSelectionStart(content);
|
||||
extract.selectionEnd = Selection.getSelectionEnd(content);
|
||||
extract.startOffset = 0;
|
||||
|
||||
try {
|
||||
|
@ -272,10 +258,80 @@ public class GeckoInputConnection
|
|||
return super.setSelection(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int leftLength, int rightLength) {
|
||||
clampSelection();
|
||||
return super.deleteSurroundingText(leftLength, rightLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCursorCapsMode(int reqModes) {
|
||||
clampSelection();
|
||||
return super.getCursorCapsMode(reqModes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextBeforeCursor(int length, int flags) {
|
||||
clampSelection();
|
||||
return super.getTextBeforeCursor(length, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSelectedText(int flags) {
|
||||
clampSelection();
|
||||
return super.getSelectedText(flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextAfterCursor(int length, int flags) {
|
||||
clampSelection();
|
||||
return super.getTextAfterCursor(length, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
replaceText(text, newCursorPosition, true);
|
||||
return true;
|
||||
clampSelection();
|
||||
return super.setComposingText(text, newCursorPosition);
|
||||
}
|
||||
|
||||
// Android's BaseInputConnection.java is vulnerable to IndexOutOfBoundsExceptions because it
|
||||
// does not adequately protect against stale indexes for selections exceeding the content length
|
||||
// when the Editable content changes. We must clamp the indexes to be safe.
|
||||
private void clampSelection() {
|
||||
Editable content = getEditable();
|
||||
if (content == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int selectionStart = Selection.getSelectionStart(content);
|
||||
final int selectionEnd = Selection.getSelectionEnd(content);
|
||||
|
||||
int a = clampContentIndex(content, selectionStart);
|
||||
int b = clampContentIndex(content, selectionEnd);
|
||||
|
||||
if (a > b) {
|
||||
int tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
if (a != selectionStart || b != selectionEnd) {
|
||||
Log.e(LOGTAG, "CLAMPING BOGUS SELECTION (" + selectionStart + ", " + selectionEnd
|
||||
+ "] -> (" + a + ", " + b + "]", new AssertionError());
|
||||
setSelection(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
private static int clampContentIndex(Editable content, int index) {
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
} else {
|
||||
final int contentLength = content.length();
|
||||
if (index > contentLength) {
|
||||
index = contentLength;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private void replaceText(CharSequence text, int newCursorPosition, boolean composing) {
|
||||
|
@ -309,15 +365,9 @@ public class GeckoInputConnection
|
|||
if (a != -1 && b != -1) {
|
||||
removeComposingSpans(content);
|
||||
} else {
|
||||
clampSelection();
|
||||
a = Selection.getSelectionStart(content);
|
||||
b = Selection.getSelectionEnd(content);
|
||||
if (a < 0) a = 0;
|
||||
if (b < 0) b = 0;
|
||||
if (b < a) {
|
||||
int tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (composing) {
|
||||
|
@ -468,8 +518,14 @@ public class GeckoInputConnection
|
|||
int start, int end) {
|
||||
if (!mBatchMode) {
|
||||
final Editable content = getEditable();
|
||||
|
||||
start = clampContentIndex(content, start);
|
||||
end = clampContentIndex(content, end);
|
||||
|
||||
clampSelection();
|
||||
int a = Selection.getSelectionStart(content);
|
||||
int b = Selection.getSelectionEnd(content);
|
||||
|
||||
if (start != a || end != b) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, String.format(
|
||||
|
@ -761,6 +817,7 @@ public class GeckoInputConnection
|
|||
!mKeyListener.onKeyDown(v, mEditable, keyCode, event)) {
|
||||
// Make sure selection in Gecko is up-to-date
|
||||
final Editable content = getEditable();
|
||||
clampSelection();
|
||||
int a = Selection.getSelectionStart(content);
|
||||
int b = Selection.getSelectionEnd(content);
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
|
|
Загрузка…
Ссылка в новой задаче