Bug 1343037 part 6. Simplify the setup around the editor state's GetSelectionRange function. r=ehsan

Really, there are only two cases we need to worry about.  Either
IsSelectionCached(), and then our SelectionProperties has the data we want, or
not and then we have a non-null mSelCon which has the data we want.

Since we are now using cached selection state a lot more (instead of
initializing the editor whenever someone asks for selection state), we need to
actually update it more correctly when .value is set.

And since we now update the cached selection state for the case when .value has
been set (to point to the end of the text), we need to change
HTMLInputElement::HasCachedSelection to return false for that case.  Otherwise
we will always do eager editor init on value set.  We handle that by not doing
eager init if the cached selection is collapsed.

The web platform test changes test the "update on .value set" behavior.  They
fail without this patch, pass with it.

MozReview-Commit-ID: DDU8U4MGb23
This commit is contained in:
Boris Zbarsky
2017-03-09 14:44:04 -05:00
parent a2bb5d0726
commit 0ff1feefd2
10 changed files with 226 additions and 207 deletions

View File

@@ -354,7 +354,8 @@ HTMLTextAreaElement::SetValue(const nsAString& aValue)
nsresult rv =
SetValueInternal(aValue, nsTextEditorState::eSetValue_ByContent |
nsTextEditorState::eSetValue_Notify);
nsTextEditorState::eSetValue_Notify |
nsTextEditorState::eSetValue_MoveCursorToEnd);
NS_ENSURE_SUCCESS(rv, rv);
if (mFocusedValue.Equals(currentValue)) {
@@ -369,7 +370,8 @@ HTMLTextAreaElement::SetUserInput(const nsAString& aValue)
{
return SetValueInternal(aValue,
nsTextEditorState::eSetValue_BySetUserInput |
nsTextEditorState::eSetValue_Notify);
nsTextEditorState::eSetValue_Notify|
nsTextEditorState::eSetValue_MoveCursorToEnd);
}
NS_IMETHODIMP
@@ -700,14 +702,7 @@ Nullable<uint32_t>
HTMLTextAreaElement::GetSelectionStart(ErrorResult& aError)
{
int32_t selStart, selEnd;
nsresult rv = GetSelectionRange(&selStart, &selEnd);
if (NS_FAILED(rv) && mState.IsSelectionCached()) {
return Nullable<uint32_t>(mState.GetSelectionProperties().GetStart());
}
if (NS_FAILED(rv)) {
aError.Throw(rv);
}
GetSelectionRange(&selStart, &selEnd, aError);
return Nullable<uint32_t>(selStart);
}
@@ -732,9 +727,8 @@ HTMLTextAreaElement::SetSelectionStart(const Nullable<uint32_t>& aSelectionStart
return;
}
int32_t start, end;
rv = GetSelectionRange(&start, &end);
if (NS_FAILED(rv)) {
aError.Throw(rv);
GetSelectionRange(&start, &end, aError);
if (aError.Failed()) {
return;
}
start = selStart;
@@ -751,14 +745,7 @@ Nullable<uint32_t>
HTMLTextAreaElement::GetSelectionEnd(ErrorResult& aError)
{
int32_t selStart, selEnd;
nsresult rv = GetSelectionRange(&selStart, &selEnd);
if (NS_FAILED(rv) && mState.IsSelectionCached()) {
return Nullable<uint32_t>(mState.GetSelectionProperties().GetEnd());
}
if (NS_FAILED(rv)) {
aError.Throw(rv);
}
GetSelectionRange(&selStart, &selEnd, aError);
return Nullable<uint32_t>(selEnd);
}
@@ -783,9 +770,8 @@ HTMLTextAreaElement::SetSelectionEnd(const Nullable<uint32_t>& aSelectionEnd,
return;
}
int32_t start, end;
rv = GetSelectionRange(&start, &end);
if (NS_FAILED(rv)) {
aError.Throw(rv);
GetSelectionRange(&start, &end, aError);
if (aError.Failed()) {
return;
}
end = selEnd;
@@ -798,16 +784,12 @@ HTMLTextAreaElement::SetSelectionEnd(const Nullable<uint32_t>& aSelectionEnd,
}
}
NS_IMETHODIMP
void
HTMLTextAreaElement::GetSelectionRange(int32_t* aSelectionStart,
int32_t* aSelectionEnd)
int32_t* aSelectionEnd,
ErrorResult& aRv)
{
// Flush frames, because our editor state will want to work with the frame.
if (IsInComposedDoc()) {
GetComposedDoc()->FlushPendingNotifications(FlushType::Frames);
}
return mState.GetSelectionRange(aSelectionStart, aSelectionEnd);
return mState.GetSelectionRange(aSelectionStart, aSelectionEnd, aRv);
}
static void
@@ -878,10 +860,12 @@ HTMLTextAreaElement::SetSelectionDirection(const nsAString& aDirection,
}
int32_t start, end;
nsresult rv = GetSelectionRange(&start, &end);
if (NS_SUCCEEDED(rv)) {
rv = SetSelectionRange(start, end, aDirection);
GetSelectionRange(&start, &end, aError);
if (aError.Failed()) {
return;
}
nsresult rv = SetSelectionRange(start, end, aDirection);
if (NS_FAILED(rv)) {
aError.Throw(rv);
}
@@ -937,13 +921,9 @@ HTMLTextAreaElement::SetRangeText(const nsAString& aReplacement,
ErrorResult& aRv)
{
int32_t start, end;
aRv = GetSelectionRange(&start, &end);
GetSelectionRange(&start, &end, aRv);
if (aRv.Failed()) {
if (mState.IsSelectionCached()) {
start = mState.GetSelectionProperties().GetStart();
end = mState.GetSelectionProperties().GetEnd();
aRv = NS_OK;
}
return;
}
SetRangeText(aReplacement, start, end, mozilla::dom::SelectionMode::Preserve,
@@ -975,13 +955,9 @@ HTMLTextAreaElement::SetRangeText(const nsAString& aReplacement,
}
if (aSelectionStart == -1 && aSelectionEnd == -1) {
aRv = GetSelectionRange(&aSelectionStart, &aSelectionEnd);
GetSelectionRange(&aSelectionStart, &aSelectionEnd, aRv);
if (aRv.Failed()) {
if (mState.IsSelectionCached()) {
aSelectionStart = mState.GetSelectionProperties().GetStart();
aSelectionEnd = mState.GetSelectionProperties().GetEnd();
aRv = NS_OK;
}
return;
}
}
@@ -1041,17 +1017,12 @@ HTMLTextAreaElement::SetRangeText(const nsAString& aReplacement,
nsresult
HTMLTextAreaElement::Reset()
{
nsresult rv;
// To get the initial spellchecking, reset value to
// empty string before setting the default value.
rv = SetValue(EmptyString());
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString resetVal;
GetDefaultValue(resetVal);
SetValueChanged(false);
rv = SetValueInternal(resetVal, nsTextEditorState::eSetValue_Internal);
nsresult rv = SetValueInternal(resetVal,
nsTextEditorState::eSetValue_Internal);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;