Bug 1343037 part 18. Implement nsTextEditorState::SetRangeText. r=ehsan

MozReview-Commit-ID: FEo9yv5iu6U
This commit is contained in:
Boris Zbarsky 2017-03-09 14:44:06 -05:00
parent 8a2f1929a5
commit 0cf9adf6a5
7 changed files with 151 additions and 174 deletions

View File

@ -6291,102 +6291,36 @@ HTMLInputElement::SetRangeText(const nsAString& aReplacement, ErrorResult& aRv)
return;
}
int32_t start, end;
GetSelectionRange(&start, &end, aRv);
if (aRv.Failed()) {
return;
}
SetRangeText(aReplacement, start, end, mozilla::dom::SelectionMode::Preserve,
aRv, start, end);
nsTextEditorState* state = GetEditorState();
MOZ_ASSERT(state, "SupportsTextSelection() returned true!");
state->SetRangeText(aReplacement, aRv);
}
void
HTMLInputElement::SetRangeText(const nsAString& aReplacement, uint32_t aStart,
uint32_t aEnd, const SelectionMode& aSelectMode,
ErrorResult& aRv, int32_t aSelectionStart,
int32_t aSelectionEnd)
uint32_t aEnd, SelectionMode aSelectMode,
ErrorResult& aRv)
{
if (!SupportsTextSelection()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (aStart > aEnd) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
nsTextEditorState* state = GetEditorState();
MOZ_ASSERT(state, "SupportsTextSelection() returned true!");
state->SetRangeText(aReplacement, aStart, aEnd, aSelectMode, aRv);
}
nsAutoString value;
GetNonFileValueInternal(value);
uint32_t inputValueLength = value.Length();
void
HTMLInputElement::GetValueFromSetRangeText(nsAString& aValue)
{
GetNonFileValueInternal(aValue);
}
if (aStart > inputValueLength) {
aStart = inputValueLength;
}
if (aEnd > inputValueLength) {
aEnd = inputValueLength;
}
if (aSelectionStart == -1 && aSelectionEnd == -1) {
GetSelectionRange(&aSelectionStart, &aSelectionEnd, aRv);
if (aRv.Failed()) {
return;
}
}
if (aStart <= aEnd) {
value.Replace(aStart, aEnd - aStart, aReplacement);
nsresult rv =
SetValueInternal(value, nsTextEditorState::eSetValue_ByContent);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
}
uint32_t newEnd = aStart + aReplacement.Length();
int32_t delta = aReplacement.Length() - (aEnd - aStart);
switch (aSelectMode) {
case mozilla::dom::SelectionMode::Select:
{
aSelectionStart = aStart;
aSelectionEnd = newEnd;
}
break;
case mozilla::dom::SelectionMode::Start:
{
aSelectionStart = aSelectionEnd = aStart;
}
break;
case mozilla::dom::SelectionMode::End:
{
aSelectionStart = aSelectionEnd = newEnd;
}
break;
case mozilla::dom::SelectionMode::Preserve:
{
if ((uint32_t)aSelectionStart > aEnd) {
aSelectionStart += delta;
} else if ((uint32_t)aSelectionStart > aStart) {
aSelectionStart = aStart;
}
if ((uint32_t)aSelectionEnd > aEnd) {
aSelectionEnd += delta;
} else if ((uint32_t)aSelectionEnd > aStart) {
aSelectionEnd = newEnd;
}
}
break;
default:
MOZ_CRASH("Unknown mode!");
}
Optional<nsAString> direction;
SetSelectionRange(aSelectionStart, aSelectionEnd, direction, aRv);
nsresult
HTMLInputElement::SetValueFromSetRangeText(const nsAString& aValue)
{
return SetValueInternal(aValue, nsTextEditorState::eSetValue_ByContent);
}
Nullable<uint32_t>

View File

@ -239,6 +239,8 @@ public:
NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
virtual void GetValueFromSetRangeText(nsAString& aValue) override;
virtual nsresult SetValueFromSetRangeText(const nsAString& aValue) override;
NS_IMETHOD_(bool) HasCachedSelection() override;
// Methods for nsFormFillController so it can do selection operations on input
@ -730,9 +732,8 @@ public:
void SetRangeText(const nsAString& aReplacement, ErrorResult& aRv);
void SetRangeText(const nsAString& aReplacement, uint32_t aStart,
uint32_t aEnd, const SelectionMode& aSelectMode,
ErrorResult& aRv, int32_t aSelectionStart = -1,
int32_t aSelectionEnd = -1);
uint32_t aEnd, SelectionMode aSelectMode,
ErrorResult& aRv);
bool Allowdirs() const
{

View File

@ -763,98 +763,28 @@ void
HTMLTextAreaElement::SetRangeText(const nsAString& aReplacement,
ErrorResult& aRv)
{
int32_t start, end;
GetSelectionRange(&start, &end, aRv);
if (aRv.Failed()) {
return;
}
SetRangeText(aReplacement, start, end, mozilla::dom::SelectionMode::Preserve,
aRv, start, end);
mState.SetRangeText(aReplacement, aRv);
}
void
HTMLTextAreaElement::SetRangeText(const nsAString& aReplacement,
uint32_t aStart, uint32_t aEnd,
const SelectionMode& aSelectMode,
ErrorResult& aRv, int32_t aSelectionStart,
int32_t aSelectionEnd)
SelectionMode aSelectMode,
ErrorResult& aRv)
{
if (aStart > aEnd) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
mState.SetRangeText(aReplacement, aStart, aEnd, aSelectMode, aRv);
}
nsAutoString value;
GetValueInternal(value, false);
uint32_t inputValueLength = value.Length();
void
HTMLTextAreaElement::GetValueFromSetRangeText(nsAString& aValue)
{
GetValueInternal(aValue, false);
}
if (aStart > inputValueLength) {
aStart = inputValueLength;
}
if (aEnd > inputValueLength) {
aEnd = inputValueLength;
}
if (aSelectionStart == -1 && aSelectionEnd == -1) {
GetSelectionRange(&aSelectionStart, &aSelectionEnd, aRv);
if (aRv.Failed()) {
return;
}
}
if (aStart <= aEnd) {
value.Replace(aStart, aEnd - aStart, aReplacement);
nsresult rv =
SetValueInternal(value, nsTextEditorState::eSetValue_ByContent);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
}
uint32_t newEnd = aStart + aReplacement.Length();
int32_t delta = aReplacement.Length() - (aEnd - aStart);
switch (aSelectMode) {
case mozilla::dom::SelectionMode::Select:
{
aSelectionStart = aStart;
aSelectionEnd = newEnd;
}
break;
case mozilla::dom::SelectionMode::Start:
{
aSelectionStart = aSelectionEnd = aStart;
}
break;
case mozilla::dom::SelectionMode::End:
{
aSelectionStart = aSelectionEnd = newEnd;
}
break;
case mozilla::dom::SelectionMode::Preserve:
{
if ((uint32_t)aSelectionStart > aEnd) {
aSelectionStart += delta;
} else if ((uint32_t)aSelectionStart > aStart) {
aSelectionStart = aStart;
}
if ((uint32_t)aSelectionEnd > aEnd) {
aSelectionEnd += delta;
} else if ((uint32_t)aSelectionEnd > aStart) {
aSelectionEnd = newEnd;
}
}
break;
default:
MOZ_CRASH("Unknown mode!");
}
Optional<nsAString> direction;
SetSelectionRange(aSelectionStart, aSelectionEnd, direction, aRv);
nsresult
HTMLTextAreaElement::SetValueFromSetRangeText(const nsAString& aValue)
{
return SetValueInternal(aValue, nsTextEditorState::eSetValue_ByContent);
}
nsresult

View File

@ -108,6 +108,8 @@ public:
NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
virtual void GetValueFromSetRangeText(nsAString& aValue) override;
virtual nsresult SetValueFromSetRangeText(const nsAString& aValue) override;
NS_IMETHOD_(bool) HasCachedSelection() override;
@ -248,9 +250,8 @@ public:
void SetRangeText(const nsAString& aReplacement, ErrorResult& aRv);
void SetRangeText(const nsAString& aReplacement, uint32_t aStart,
uint32_t aEnd, const SelectionMode& aSelectMode,
ErrorResult& aRv, int32_t aSelectionStart = -1,
int32_t aSelectionEnd = -1);
uint32_t aEnd, SelectionMode aSelectMode,
ErrorResult& aRv);
void SetRequired(bool aRequired, ErrorResult& aError)
{

View File

@ -174,6 +174,12 @@ public:
*/
NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) = 0;
/**
* Helpers for value manipulation from SetRangeText.
*/
virtual void GetValueFromSetRangeText(nsAString& aValue) = 0;
virtual nsresult SetValueFromSetRangeText(const nsAString& aValue) = 0;
static const int32_t DEFAULT_COLS = 20;
static const int32_t DEFAULT_ROWS = 1;
static const int32_t DEFAULT_ROWS_TEXTAREA = 2;

View File

@ -1843,6 +1843,100 @@ nsTextEditorState::SetSelectionRange(int32_t aSelectionStart,
SetSelectionRange(aSelectionStart, aSelectionEnd, dir, aRv);
}
void
nsTextEditorState::SetRangeText(const nsAString& aReplacement,
ErrorResult& aRv)
{
int32_t start, end;
GetSelectionRange(&start, &end, aRv);
if (aRv.Failed()) {
return;
}
SetRangeText(aReplacement, start, end, SelectionMode::Preserve,
aRv, start, end);
}
void
nsTextEditorState::SetRangeText(const nsAString& aReplacement, uint32_t aStart,
uint32_t aEnd, SelectionMode aSelectMode,
ErrorResult& aRv, int32_t aSelectionStart,
int32_t aSelectionEnd)
{
if (aStart > aEnd) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
nsAutoString value;
mTextCtrlElement->GetValueFromSetRangeText(value);
uint32_t inputValueLength = value.Length();
if (aStart > inputValueLength) {
aStart = inputValueLength;
}
if (aEnd > inputValueLength) {
aEnd = inputValueLength;
}
if (aSelectionStart == -1 && aSelectionEnd == -1) {
GetSelectionRange(&aSelectionStart, &aSelectionEnd, aRv);
if (aRv.Failed()) {
return;
}
}
MOZ_ASSERT(aStart <= aEnd);
value.Replace(aStart, aEnd - aStart, aReplacement);
nsresult rv = mTextCtrlElement->SetValueFromSetRangeText(value);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return;
}
uint32_t newEnd = aStart + aReplacement.Length();
int32_t delta = aReplacement.Length() - (aEnd - aStart);
switch (aSelectMode) {
case mozilla::dom::SelectionMode::Select:
{
aSelectionStart = aStart;
aSelectionEnd = newEnd;
}
break;
case mozilla::dom::SelectionMode::Start:
{
aSelectionStart = aSelectionEnd = aStart;
}
break;
case mozilla::dom::SelectionMode::End:
{
aSelectionStart = aSelectionEnd = newEnd;
}
break;
case mozilla::dom::SelectionMode::Preserve:
{
if ((uint32_t)aSelectionStart > aEnd) {
aSelectionStart += delta;
} else if ((uint32_t)aSelectionStart > aStart) {
aSelectionStart = aStart;
}
if ((uint32_t)aSelectionEnd > aEnd) {
aSelectionEnd += delta;
} else if ((uint32_t)aSelectionEnd > aStart) {
aSelectionEnd = newEnd;
}
}
break;
default:
MOZ_CRASH("Unknown mode!");
}
SetSelectionRange(aSelectionStart, aSelectionEnd, Optional<nsAString>(), aRv);
}
HTMLInputElement*
nsTextEditorState::GetParentNumberControl(nsFrame* aFrame) const
{

View File

@ -15,6 +15,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/HTMLInputElementBinding.h"
#include "mozilla/dom/Nullable.h"
class nsTextInputListener;
@ -330,6 +331,16 @@ public:
void SetSelectionDirection(const nsAString& aDirection,
mozilla::ErrorResult& aRv);
// Set the range text. This basically implements
// https://html.spec.whatwg.org/multipage/forms.html#dom-textarea/input-setrangetext
void SetRangeText(const nsAString& aReplacement, mozilla::ErrorResult& aRv);
// The last two arguments are -1 if we don't know our selection range;
// otherwise they're the start and end of our selection range.
void SetRangeText(const nsAString& aReplacement, uint32_t aStart,
uint32_t aEnd, mozilla::dom::SelectionMode aSelectMode,
mozilla::ErrorResult& aRv, int32_t aSelectionStart = -1,
int32_t aSelectionEnd = -1);
void UpdateEditableState(bool aNotify) {
if (mRootNode) {
mRootNode->UpdateEditableState(aNotify);