mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1345237. Propagate uint32_t deeper into the editor state and text control frame code. r=mystor
MozReview-Commit-ID: KeUo8My6eBJ
This commit is contained in:
parent
24aa6df7ff
commit
b73c71861b
@ -7058,8 +7058,8 @@ nsContentUtils::GetAdjustedOffsetInTextControl(nsIFrame* aOffsetFrame,
|
||||
void
|
||||
nsContentUtils::GetSelectionInTextControl(Selection* aSelection,
|
||||
Element* aRoot,
|
||||
int32_t& aOutStartOffset,
|
||||
int32_t& aOutEndOffset)
|
||||
uint32_t& aOutStartOffset,
|
||||
uint32_t& aOutEndOffset)
|
||||
{
|
||||
MOZ_ASSERT(aSelection && aRoot);
|
||||
|
||||
|
@ -2417,8 +2417,8 @@ public:
|
||||
*/
|
||||
static void GetSelectionInTextControl(mozilla::dom::Selection* aSelection,
|
||||
Element* aRoot,
|
||||
int32_t& aOutStartOffset,
|
||||
int32_t& aOutEndOffset);
|
||||
uint32_t& aOutStartOffset,
|
||||
uint32_t& aOutEndOffset);
|
||||
|
||||
/**
|
||||
* Takes a frame for anonymous content within a text control (<input> or
|
||||
|
@ -6332,7 +6332,7 @@ HTMLInputElement::GetSelectionStart(ErrorResult& aRv)
|
||||
return Nullable<uint32_t>();
|
||||
}
|
||||
|
||||
int32_t selEnd, selStart;
|
||||
uint32_t selEnd, selStart;
|
||||
GetSelectionRange(&selStart, &selEnd, aRv);
|
||||
return Nullable<uint32_t>(selStart);
|
||||
}
|
||||
@ -6358,7 +6358,7 @@ HTMLInputElement::GetSelectionEnd(ErrorResult& aRv)
|
||||
return Nullable<uint32_t>();
|
||||
}
|
||||
|
||||
int32_t selEnd, selStart;
|
||||
uint32_t selEnd, selStart;
|
||||
GetSelectionRange(&selStart, &selEnd, aRv);
|
||||
return Nullable<uint32_t>(selEnd);
|
||||
}
|
||||
@ -6386,8 +6386,8 @@ HTMLInputElement::GetFiles(nsIDOMFileList** aFileList)
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::GetSelectionRange(int32_t* aSelectionStart,
|
||||
int32_t* aSelectionEnd,
|
||||
HTMLInputElement::GetSelectionRange(uint32_t* aSelectionStart,
|
||||
uint32_t* aSelectionEnd,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsTextEditorState* state = GetEditorState();
|
||||
|
@ -1486,8 +1486,8 @@ protected:
|
||||
* A helper to get the current selection range. Will throw on the ErrorResult
|
||||
* if we have no editor state.
|
||||
*/
|
||||
void GetSelectionRange(int32_t* aSelectionStart,
|
||||
int32_t* aSelectionEnd,
|
||||
void GetSelectionRange(uint32_t* aSelectionStart,
|
||||
uint32_t* aSelectionEnd,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsCOMPtr<nsIControllers> mControllers;
|
||||
|
@ -701,7 +701,7 @@ HTMLTextAreaElement::GetTextLength(int32_t *aTextLength)
|
||||
Nullable<uint32_t>
|
||||
HTMLTextAreaElement::GetSelectionStart(ErrorResult& aError)
|
||||
{
|
||||
int32_t selStart, selEnd;
|
||||
uint32_t selStart, selEnd;
|
||||
GetSelectionRange(&selStart, &selEnd, aError);
|
||||
return Nullable<uint32_t>(selStart);
|
||||
}
|
||||
@ -716,7 +716,7 @@ HTMLTextAreaElement::SetSelectionStart(const Nullable<uint32_t>& aSelectionStart
|
||||
Nullable<uint32_t>
|
||||
HTMLTextAreaElement::GetSelectionEnd(ErrorResult& aError)
|
||||
{
|
||||
int32_t selStart, selEnd;
|
||||
uint32_t selStart, selEnd;
|
||||
GetSelectionRange(&selStart, &selEnd, aError);
|
||||
return Nullable<uint32_t>(selEnd);
|
||||
}
|
||||
@ -729,8 +729,8 @@ HTMLTextAreaElement::SetSelectionEnd(const Nullable<uint32_t>& aSelectionEnd,
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTextAreaElement::GetSelectionRange(int32_t* aSelectionStart,
|
||||
int32_t* aSelectionEnd,
|
||||
HTMLTextAreaElement::GetSelectionRange(uint32_t* aSelectionStart,
|
||||
uint32_t* aSelectionEnd,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
return mState.GetSelectionRange(aSelectionStart, aSelectionEnd, aRv);
|
||||
|
@ -396,8 +396,8 @@ protected:
|
||||
* A helper to get the current selection range. Will throw on the ErrorResult
|
||||
* if we have no editor state.
|
||||
*/
|
||||
void GetSelectionRange(int32_t* aSelectionStart,
|
||||
int32_t* aSelectionEnd,
|
||||
void GetSelectionRange(uint32_t* aSelectionStart,
|
||||
uint32_t* aSelectionEnd,
|
||||
ErrorResult& aRv);
|
||||
private:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
|
@ -1577,8 +1577,8 @@ nsTextEditorState::SetSelectionProperties(nsTextEditorState::SelectionProperties
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEditorState::GetSelectionRange(int32_t* aSelectionStart,
|
||||
int32_t* aSelectionEnd,
|
||||
nsTextEditorState::GetSelectionRange(uint32_t* aSelectionStart,
|
||||
uint32_t* aSelectionEnd,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSelectionStart);
|
||||
@ -1640,7 +1640,7 @@ nsTextEditorState::GetSelectionDirection(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEditorState::SetSelectionRange(int32_t aStart, int32_t aEnd,
|
||||
nsTextEditorState::SetSelectionRange(uint32_t aStart, uint32_t aEnd,
|
||||
nsITextControlFrame::SelectionDirection aDirection,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
@ -1659,10 +1659,10 @@ nsTextEditorState::SetSelectionRange(int32_t aStart, int32_t aEnd,
|
||||
// various mismatches between our impl and the spec.
|
||||
GetValue(value, false);
|
||||
uint32_t length = value.Length();
|
||||
if (uint32_t(aStart) > length) {
|
||||
if (aStart > length) {
|
||||
aStart = length;
|
||||
}
|
||||
if (uint32_t(aEnd) > length) {
|
||||
if (aEnd > length) {
|
||||
aEnd = length;
|
||||
}
|
||||
SelectionProperties& props = GetSelectionProperties();
|
||||
@ -1703,17 +1703,15 @@ nsTextEditorState::SetSelectionRange(int32_t aStart, int32_t aEnd,
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEditorState::SetSelectionStart(const mozilla::dom::Nullable<uint32_t>& aStart,
|
||||
nsTextEditorState::SetSelectionStart(const Nullable<uint32_t>& aStart,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
int32_t start = 0;
|
||||
uint32_t start = 0;
|
||||
if (!aStart.IsNull()) {
|
||||
// XXXbz This will do the wrong thing for input values that are out of the
|
||||
// int32_t range...
|
||||
start = aStart.Value();
|
||||
}
|
||||
|
||||
int32_t ignored, end;
|
||||
uint32_t ignored, end;
|
||||
GetSelectionRange(&ignored, &end, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
@ -1732,17 +1730,15 @@ nsTextEditorState::SetSelectionStart(const mozilla::dom::Nullable<uint32_t>& aSt
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEditorState::SetSelectionEnd(const mozilla::dom::Nullable<uint32_t>& aEnd,
|
||||
nsTextEditorState::SetSelectionEnd(const Nullable<uint32_t>& aEnd,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
int32_t end = 0;
|
||||
uint32_t end = 0;
|
||||
if (!aEnd.IsNull()) {
|
||||
// XXXbz This will do the wrong thing for input values that are out of the
|
||||
// int32_t range...
|
||||
end = aEnd.Value();
|
||||
}
|
||||
|
||||
int32_t start, ignored;
|
||||
uint32_t start, ignored;
|
||||
GetSelectionRange(&start, &ignored, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
@ -1805,7 +1801,7 @@ nsTextEditorState::SetSelectionDirection(const nsAString& aDirection,
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t start, end;
|
||||
uint32_t start, end;
|
||||
GetSelectionRange(&start, &end, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
@ -1826,8 +1822,8 @@ DirectionStringToSelectionDirection(const Optional<nsAString>& aDirection)
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEditorState::SetSelectionRange(int32_t aSelectionStart,
|
||||
int32_t aSelectionEnd,
|
||||
nsTextEditorState::SetSelectionRange(uint32_t aSelectionStart,
|
||||
uint32_t aSelectionEnd,
|
||||
const Optional<nsAString>& aDirection,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
@ -1841,21 +1837,22 @@ void
|
||||
nsTextEditorState::SetRangeText(const nsAString& aReplacement,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
int32_t start, end;
|
||||
uint32_t start, end;
|
||||
GetSelectionRange(&start, &end, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetRangeText(aReplacement, start, end, SelectionMode::Preserve,
|
||||
aRv, start, end);
|
||||
aRv, Some(start), Some(end));
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEditorState::SetRangeText(const nsAString& aReplacement, uint32_t aStart,
|
||||
uint32_t aEnd, SelectionMode aSelectMode,
|
||||
ErrorResult& aRv, int32_t aSelectionStart,
|
||||
int32_t aSelectionEnd)
|
||||
ErrorResult& aRv,
|
||||
const Maybe<uint32_t>& aSelectionStart,
|
||||
const Maybe<uint32_t>& aSelectionEnd)
|
||||
{
|
||||
if (aStart > aEnd) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
@ -1874,11 +1871,17 @@ nsTextEditorState::SetRangeText(const nsAString& aReplacement, uint32_t aStart,
|
||||
aEnd = inputValueLength;
|
||||
}
|
||||
|
||||
if (aSelectionStart == -1 && aSelectionEnd == -1) {
|
||||
GetSelectionRange(&aSelectionStart, &aSelectionEnd, aRv);
|
||||
uint32_t selectionStart, selectionEnd;
|
||||
if (!aSelectionStart) {
|
||||
MOZ_ASSERT(!aSelectionEnd);
|
||||
GetSelectionRange(&selectionStart, &selectionEnd, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(aSelectionEnd);
|
||||
selectionStart = *aSelectionStart;
|
||||
selectionEnd = *aSelectionEnd;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aStart <= aEnd);
|
||||
@ -1895,32 +1898,32 @@ nsTextEditorState::SetRangeText(const nsAString& aReplacement, uint32_t aStart,
|
||||
switch (aSelectMode) {
|
||||
case mozilla::dom::SelectionMode::Select:
|
||||
{
|
||||
aSelectionStart = aStart;
|
||||
aSelectionEnd = newEnd;
|
||||
selectionStart = aStart;
|
||||
selectionEnd = newEnd;
|
||||
}
|
||||
break;
|
||||
case mozilla::dom::SelectionMode::Start:
|
||||
{
|
||||
aSelectionStart = aSelectionEnd = aStart;
|
||||
selectionStart = selectionEnd = aStart;
|
||||
}
|
||||
break;
|
||||
case mozilla::dom::SelectionMode::End:
|
||||
{
|
||||
aSelectionStart = aSelectionEnd = newEnd;
|
||||
selectionStart = selectionEnd = newEnd;
|
||||
}
|
||||
break;
|
||||
case mozilla::dom::SelectionMode::Preserve:
|
||||
{
|
||||
if ((uint32_t)aSelectionStart > aEnd) {
|
||||
aSelectionStart += delta;
|
||||
} else if ((uint32_t)aSelectionStart > aStart) {
|
||||
aSelectionStart = aStart;
|
||||
if (selectionStart > aEnd) {
|
||||
selectionStart += delta;
|
||||
} else if (selectionStart > aStart) {
|
||||
selectionStart = aStart;
|
||||
}
|
||||
|
||||
if ((uint32_t)aSelectionEnd > aEnd) {
|
||||
aSelectionEnd += delta;
|
||||
} else if ((uint32_t)aSelectionEnd > aStart) {
|
||||
aSelectionEnd = newEnd;
|
||||
if (selectionEnd > aEnd) {
|
||||
selectionEnd += delta;
|
||||
} else if (selectionEnd > aStart) {
|
||||
selectionEnd = newEnd;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1928,7 +1931,7 @@ nsTextEditorState::SetRangeText(const nsAString& aReplacement, uint32_t aStart,
|
||||
MOZ_CRASH("Unknown mode!");
|
||||
}
|
||||
|
||||
SetSelectionRange(aSelectionStart, aSelectionEnd, Optional<nsAString>(), aRv);
|
||||
SetSelectionRange(selectionStart, selectionEnd, Optional<nsAString>(), aRv);
|
||||
}
|
||||
|
||||
HTMLInputElement*
|
||||
@ -2008,7 +2011,7 @@ nsTextEditorState::UnbindFromFrame(nsTextControlFrame* aFrame)
|
||||
// controller, and so forth.
|
||||
if (!IsSelectionCached()) {
|
||||
// Go ahead and cache it now.
|
||||
int32_t start = 0, end = 0;
|
||||
uint32_t start = 0, end = 0;
|
||||
IgnoredErrorResult rangeRv;
|
||||
GetSelectionRange(&start, &end, rangeRv);
|
||||
|
||||
@ -2575,8 +2578,8 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
|
||||
props.SetEnd(value.Length());
|
||||
} else {
|
||||
// Make sure our cached selection position is not outside the new value.
|
||||
props.SetStart(std::min(uint32_t(props.GetStart()), value.Length()));
|
||||
props.SetEnd(std::min(uint32_t(props.GetEnd()), value.Length()));
|
||||
props.SetStart(std::min(props.GetStart(), value.Length()));
|
||||
props.SetEnd(std::min(props.GetEnd(), value.Length()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,20 +227,20 @@ public:
|
||||
return mStart == 0 && mEnd == 0 &&
|
||||
mDirection == nsITextControlFrame::eForward;
|
||||
}
|
||||
int32_t GetStart() const
|
||||
uint32_t GetStart() const
|
||||
{
|
||||
return mStart;
|
||||
}
|
||||
void SetStart(int32_t value)
|
||||
void SetStart(uint32_t value)
|
||||
{
|
||||
mIsDirty = true;
|
||||
mStart = value;
|
||||
}
|
||||
int32_t GetEnd() const
|
||||
uint32_t GetEnd() const
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
void SetEnd(int32_t value)
|
||||
void SetEnd(uint32_t value)
|
||||
{
|
||||
mIsDirty = true;
|
||||
mEnd = value;
|
||||
@ -260,7 +260,7 @@ public:
|
||||
return mIsDirty;
|
||||
}
|
||||
private:
|
||||
int32_t mStart, mEnd;
|
||||
uint32_t mStart, mEnd;
|
||||
bool mIsDirty = false;
|
||||
nsITextControlFrame::SelectionDirection mDirection;
|
||||
};
|
||||
@ -276,7 +276,7 @@ public:
|
||||
void SyncUpSelectionPropertiesBeforeDestruction();
|
||||
|
||||
// Get the selection range start and end points in our text.
|
||||
void GetSelectionRange(int32_t* aSelectionStart, int32_t* aSelectionEnd,
|
||||
void GetSelectionRange(uint32_t* aSelectionStart, uint32_t* aSelectionEnd,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
// Get the selection direction
|
||||
@ -295,15 +295,15 @@ public:
|
||||
//
|
||||
// XXXbz This should really take uint32_t, but none of our guts (either the
|
||||
// frame or our cached selection state) work with uint32_t at the moment...
|
||||
void SetSelectionRange(int32_t aStart, int32_t aEnd,
|
||||
void SetSelectionRange(uint32_t aStart, uint32_t aEnd,
|
||||
nsITextControlFrame::SelectionDirection aDirection,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
// Set the selection range, but with an optional string for the direction.
|
||||
// This will convert aDirection to an nsITextControlFrame::SelectionDirection
|
||||
// and then call our other SetSelectionRange overload.
|
||||
void SetSelectionRange(int32_t aSelectionStart,
|
||||
int32_t aSelectionEnd,
|
||||
void SetSelectionRange(uint32_t aSelectionStart,
|
||||
uint32_t aSelectionEnd,
|
||||
const mozilla::dom::Optional<nsAString>& aDirection,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
@ -338,8 +338,11 @@ public:
|
||||
// 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);
|
||||
mozilla::ErrorResult& aRv,
|
||||
const mozilla::Maybe<uint32_t>& aSelectionStart =
|
||||
mozilla::Nothing(),
|
||||
const mozilla::Maybe<uint32_t>& aSelectionEnd =
|
||||
mozilla::Nothing());
|
||||
|
||||
void UpdateEditableState(bool aNotify) {
|
||||
if (mRootNode) {
|
||||
|
@ -631,8 +631,8 @@ TextEditRules::WillInsertText(EditAction aAction,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t start = 0;
|
||||
int32_t end = 0;
|
||||
uint32_t start = 0;
|
||||
uint32_t end = 0;
|
||||
|
||||
// handle password field docs
|
||||
if (IsPasswordEditor()) {
|
||||
@ -855,7 +855,7 @@ TextEditRules::WillDeleteSelection(Selection* aSelection,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// manage the password buffer
|
||||
int32_t start, end;
|
||||
uint32_t start, end;
|
||||
nsContentUtils::GetSelectionInTextControl(aSelection,
|
||||
mTextEditor->GetRoot(),
|
||||
start, end);
|
||||
@ -872,7 +872,7 @@ TextEditRules::WillDeleteSelection(Selection* aSelection,
|
||||
// Collapsed selection.
|
||||
if (end == start) {
|
||||
// Deleting back.
|
||||
if (nsIEditor::ePrevious == aCollapsedAction && 0<start) {
|
||||
if (nsIEditor::ePrevious == aCollapsedAction && start > 0) {
|
||||
mPasswordText.Cut(start-1, 1);
|
||||
}
|
||||
// Deleting forward.
|
||||
@ -1277,15 +1277,15 @@ TextEditRules::TruncateInsertionIfNeeded(Selection* aSelection,
|
||||
return rv;
|
||||
}
|
||||
|
||||
int32_t start, end;
|
||||
uint32_t start, end;
|
||||
nsContentUtils::GetSelectionInTextControl(aSelection,
|
||||
mTextEditor->GetRoot(),
|
||||
start, end);
|
||||
|
||||
TextComposition* composition = mTextEditor->GetComposition();
|
||||
int32_t oldCompStrLength = composition ? composition->String().Length() : 0;
|
||||
uint32_t oldCompStrLength = composition ? composition->String().Length() : 0;
|
||||
|
||||
const int32_t selectionLength = end - start;
|
||||
const uint32_t selectionLength = end - start;
|
||||
const int32_t resultingDocLength = docLength - selectionLength - oldCompStrLength;
|
||||
if (resultingDocLength >= aMaxLength) {
|
||||
// This call is guaranteed to reduce the capacity of the string, so it
|
||||
@ -1327,7 +1327,7 @@ TextEditRules::ResetIMETextPWBuf()
|
||||
}
|
||||
|
||||
void
|
||||
TextEditRules::RemoveIMETextFromPWBuf(int32_t& aStart,
|
||||
TextEditRules::RemoveIMETextFromPWBuf(uint32_t& aStart,
|
||||
nsAString* aIMEString)
|
||||
{
|
||||
MOZ_ASSERT(aIMEString);
|
||||
@ -1371,7 +1371,7 @@ TextEditRules::HideLastPWInput()
|
||||
NS_ENSURE_STATE(mTextEditor);
|
||||
RefPtr<Selection> selection = mTextEditor->GetSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
int32_t start, end;
|
||||
uint32_t start, end;
|
||||
nsContentUtils::GetSelectionInTextControl(selection, mTextEditor->GetRoot(),
|
||||
start, end);
|
||||
|
||||
@ -1379,6 +1379,8 @@ TextEditRules::HideLastPWInput()
|
||||
NS_ENSURE_TRUE(selNode, NS_OK);
|
||||
|
||||
selNode->GetAsText()->ReplaceData(mLastStart, mLastLength, hiddenText);
|
||||
// XXXbz Selection::Collapse/Extend take int32_t, but there are tons of
|
||||
// callsites... Converting all that is a battle for another day.
|
||||
selection->Collapse(selNode, start);
|
||||
if (start != end) {
|
||||
selection->Extend(selNode, end);
|
||||
|
@ -199,7 +199,7 @@ protected:
|
||||
/**
|
||||
* Remove IME composition text from password buffer.
|
||||
*/
|
||||
void RemoveIMETextFromPWBuf(int32_t& aStart, nsAString* aIMEString);
|
||||
void RemoveIMETextFromPWBuf(uint32_t& aStart, nsAString* aIMEString);
|
||||
|
||||
nsresult CreateMozBR(nsIDOMNode* inParent, int32_t inOffset,
|
||||
nsIDOMNode** outBRNode = nullptr);
|
||||
|
@ -25,8 +25,8 @@ public:
|
||||
|
||||
NS_IMETHOD GetEditor(nsIEditor **aEditor) = 0;
|
||||
|
||||
NS_IMETHOD SetSelectionRange(int32_t aSelectionStart,
|
||||
int32_t aSelectionEnd,
|
||||
NS_IMETHOD SetSelectionRange(uint32_t aSelectionStart,
|
||||
uint32_t aSelectionEnd,
|
||||
SelectionDirection aDirection = eNone) = 0;
|
||||
|
||||
NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon) = 0;
|
||||
|
@ -306,7 +306,7 @@ nsTextControlFrame::EnsureEditorInitialized()
|
||||
mEditorHasBeenInitialized = true;
|
||||
|
||||
if (weakFrame.IsAlive()) {
|
||||
int32_t position = 0;
|
||||
uint32_t position = 0;
|
||||
|
||||
// Set the selection to the end of the text field (bug 1287655),
|
||||
// but only if the contents has changed (bug 1337392).
|
||||
@ -744,9 +744,9 @@ nsTextControlFrame::GetEditor(nsIEditor **aEditor)
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::SetSelectionInternal(nsIDOMNode *aStartNode,
|
||||
int32_t aStartOffset,
|
||||
uint32_t aStartOffset,
|
||||
nsIDOMNode *aEndNode,
|
||||
int32_t aEndOffset,
|
||||
uint32_t aEndOffset,
|
||||
nsITextControlFrame::SelectionDirection aDirection)
|
||||
{
|
||||
// Create a new range to represent the new selection.
|
||||
@ -758,6 +758,11 @@ nsTextControlFrame::SetSelectionInternal(nsIDOMNode *aStartNode,
|
||||
// we have access to the node.
|
||||
nsCOMPtr<nsINode> start = do_QueryInterface(aStartNode);
|
||||
nsCOMPtr<nsINode> end = do_QueryInterface(aEndNode);
|
||||
// XXXbz nsRange::Set takes int32_t (and ranges generally work on int32_t),
|
||||
// but we're passing uint32_t. The good news is that at this point our
|
||||
// endpoints should really be within our length, so not really that big. And
|
||||
// if they _are_ that big, Set() will simply error out, which is not too bad
|
||||
// for a case we don't expect to happen.
|
||||
nsresult rv = range->Set(start, aStartOffset, end, aEndOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -861,7 +866,7 @@ nsTextControlFrame::SelectAllOrCollapseToEndOfText(bool aSelect)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::SetSelectionEndPoints(int32_t aSelStart, int32_t aSelEnd,
|
||||
nsTextControlFrame::SetSelectionEndPoints(uint32_t aSelStart, uint32_t aSelEnd,
|
||||
nsITextControlFrame::SelectionDirection aDirection)
|
||||
{
|
||||
NS_ASSERTION(aSelStart <= aSelEnd, "Invalid selection offsets!");
|
||||
@ -870,7 +875,7 @@ nsTextControlFrame::SetSelectionEndPoints(int32_t aSelStart, int32_t aSelEnd,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
int32_t startOffset, endOffset;
|
||||
uint32_t startOffset, endOffset;
|
||||
|
||||
// Calculate the selection start point.
|
||||
|
||||
@ -896,7 +901,7 @@ nsTextControlFrame::SetSelectionEndPoints(int32_t aSelStart, int32_t aSelEnd,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextControlFrame::SetSelectionRange(int32_t aSelStart, int32_t aSelEnd,
|
||||
nsTextControlFrame::SetSelectionRange(uint32_t aSelStart, uint32_t aSelEnd,
|
||||
nsITextControlFrame::SelectionDirection aDirection)
|
||||
{
|
||||
nsresult rv = EnsureEditorInitialized();
|
||||
@ -914,9 +919,9 @@ nsTextControlFrame::SetSelectionRange(int32_t aSelStart, int32_t aSelEnd,
|
||||
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::OffsetToDOMPoint(int32_t aOffset,
|
||||
nsTextControlFrame::OffsetToDOMPoint(uint32_t aOffset,
|
||||
nsIDOMNode** aResult,
|
||||
int32_t* aPosition)
|
||||
uint32_t* aPosition)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult && aPosition);
|
||||
|
||||
@ -948,13 +953,13 @@ nsTextControlFrame::OffsetToDOMPoint(int32_t aOffset,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(firstNode);
|
||||
|
||||
if (length == 0 || aOffset < 0) {
|
||||
if (length == 0) {
|
||||
NS_IF_ADDREF(*aResult = rootNode);
|
||||
*aPosition = 0;
|
||||
} else if (textNode) {
|
||||
uint32_t textLength = 0;
|
||||
textNode->GetLength(&textLength);
|
||||
if (length == 2 && uint32_t(aOffset) == textLength) {
|
||||
if (length == 2 && aOffset == textLength) {
|
||||
// If we're at the end of the text node and we have a trailing BR node,
|
||||
// set the selection on the BR node.
|
||||
NS_IF_ADDREF(*aResult = rootNode);
|
||||
@ -962,7 +967,7 @@ nsTextControlFrame::OffsetToDOMPoint(int32_t aOffset,
|
||||
} else {
|
||||
// Otherwise, set the selection on the textnode itself.
|
||||
NS_IF_ADDREF(*aResult = firstNode);
|
||||
*aPosition = std::min(aOffset, int32_t(textLength));
|
||||
*aPosition = std::min(aOffset, textLength);
|
||||
}
|
||||
} else {
|
||||
NS_IF_ADDREF(*aResult = rootNode);
|
||||
|
@ -142,8 +142,8 @@ public:
|
||||
//==== NSITEXTCONTROLFRAME
|
||||
|
||||
NS_IMETHOD GetEditor(nsIEditor **aEditor) override;
|
||||
NS_IMETHOD SetSelectionRange(int32_t aSelectionStart,
|
||||
int32_t aSelectionEnd,
|
||||
NS_IMETHOD SetSelectionRange(uint32_t aSelectionStart,
|
||||
uint32_t aSelectionEnd,
|
||||
SelectionDirection aDirection = eNone) override;
|
||||
NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon) override;
|
||||
virtual nsFrameSelection* GetOwnedFrameSelection() override;
|
||||
@ -265,7 +265,7 @@ protected:
|
||||
nsTextControlFrame* mFrame;
|
||||
};
|
||||
|
||||
nsresult OffsetToDOMPoint(int32_t aOffset, nsIDOMNode** aResult, int32_t* aPosition);
|
||||
nsresult OffsetToDOMPoint(uint32_t aOffset, nsIDOMNode** aResult, uint32_t* aPosition);
|
||||
|
||||
/**
|
||||
* Update the textnode under our anonymous div to show the new
|
||||
@ -308,11 +308,11 @@ protected:
|
||||
|
||||
private:
|
||||
//helper methods
|
||||
nsresult SetSelectionInternal(nsIDOMNode *aStartNode, int32_t aStartOffset,
|
||||
nsIDOMNode *aEndNode, int32_t aEndOffset,
|
||||
nsresult SetSelectionInternal(nsIDOMNode *aStartNode, uint32_t aStartOffset,
|
||||
nsIDOMNode *aEndNode, uint32_t aEndOffset,
|
||||
SelectionDirection aDirection = eNone);
|
||||
nsresult SelectAllOrCollapseToEndOfText(bool aSelect);
|
||||
nsresult SetSelectionEndPoints(int32_t aSelStart, int32_t aSelEnd,
|
||||
nsresult SetSelectionEndPoints(uint32_t aSelStart, uint32_t aSelEnd,
|
||||
SelectionDirection aDirection = eNone);
|
||||
|
||||
/**
|
||||
|
@ -23,10 +23,3 @@
|
||||
|
||||
[textarea direction of setSelectionRange(0,1)]
|
||||
expected: FAIL
|
||||
|
||||
[input setSelectionRange(1,-1)]
|
||||
expected: FAIL
|
||||
|
||||
[input setSelectionRange(-1,1)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -27,11 +27,30 @@
|
||||
return el;
|
||||
};
|
||||
|
||||
function createPrefocusedInputElement(value, append) {
|
||||
var el = createInputElement(value, append);
|
||||
el.focus();
|
||||
el.blur();
|
||||
return el;
|
||||
}
|
||||
|
||||
function createPrefocusedTextareaElement(value, append) {
|
||||
var el = createTextareaElement(value, append);
|
||||
el.focus();
|
||||
el.blur();
|
||||
return el;
|
||||
}
|
||||
|
||||
function createTestElements(value) {
|
||||
return [ createInputElement(value, true),
|
||||
createInputElement(value, false),
|
||||
createPrefocusedInputElement(value, true),
|
||||
createPrefocusedInputElement(value, false),
|
||||
createTextareaElement(value, true),
|
||||
createTextareaElement(value, false) ];
|
||||
createTextareaElement(value, false),
|
||||
createPrefocusedTextareaElement(value, true),
|
||||
createPrefocusedTextareaElement(value, false),
|
||||
];
|
||||
}
|
||||
|
||||
const testValue = "abcdefghij";
|
||||
@ -92,4 +111,38 @@
|
||||
el.remove();
|
||||
}
|
||||
}, "Setting selectionEnd to a value smaller than selectionStart should decrease selectionStart");
|
||||
|
||||
test(function() {
|
||||
for (let el of createTestElements(testValue)) {
|
||||
el.selectionStart = 0;
|
||||
assert_equals(el.selectionStart, 0, `We just set it on ${el.id}`);
|
||||
el.selectionStart = -1;
|
||||
assert_equals(el.selectionStart, testValue.length,
|
||||
`selectionStart setter on ${el.id} should convert -1 to 2^32-1`);
|
||||
el.selectionStart = Math.pow(2, 32);
|
||||
assert_equals(el.selectionStart, 0,
|
||||
`selectionStart setter on ${el.id} should convert 2^32 to 0`);
|
||||
el.selectionStart = Math.pow(2, 32) - 1;
|
||||
assert_equals(el.selectionStart, testValue.length,
|
||||
`selectionStart setter on ${el.id} should leave 2^32-1 as-is`);
|
||||
el.remove();
|
||||
}
|
||||
}, "selectionStart edge-case values");
|
||||
|
||||
test(function() {
|
||||
for (let el of createTestElements(testValue)) {
|
||||
el.selectionEnd = 0;
|
||||
assert_equals(el.selectionEnd, 0, `We just set it on ${el.id}`);
|
||||
el.selectionEnd = -1;
|
||||
assert_equals(el.selectionEnd, testValue.length,
|
||||
`selectionEnd setter on ${el.id} should convert -1 to 2^32-1`);
|
||||
el.selectionEnd = Math.pow(2, 32);
|
||||
assert_equals(el.selectionEnd, 0,
|
||||
`selectionEnd setter on ${el.id} should convert 2^32 to 0`);
|
||||
el.selectionEnd = Math.pow(2, 32) - 1;
|
||||
assert_equals(el.selectionEnd, testValue.length,
|
||||
`selectionEnd setter on ${el.id} should leave 2^32-1 as-is`);
|
||||
el.remove();
|
||||
}
|
||||
}, "selectionEnd edge-case values");
|
||||
</script>
|
||||
|
@ -138,6 +138,22 @@ test(function() {
|
||||
assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
|
||||
assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
|
||||
},'input setSelectionRange(undefined,1)');
|
||||
|
||||
test(function() {
|
||||
input.setSelectionRange(Math.pow(2,32) - 2, Math.pow(2,32) - 1);
|
||||
assert_equals(input.selectionStart, input.value.length,
|
||||
"element.selectionStart should be value.length");
|
||||
assert_equals(input.selectionEnd, input.value.length,
|
||||
"element.selectionEnd should be value.length");
|
||||
}, 'input setSelectionRange(Math.pow(2,32) - 2, Math.pow(2,32) - 1)');
|
||||
|
||||
test(function() {
|
||||
input.setSelectionRange(Math.pow(2,31), Math.pow(2,32) - 1);
|
||||
assert_equals(input.selectionStart, input.value.length,
|
||||
"element.selectionStart should be value.length");
|
||||
assert_equals(input.selectionEnd, input.value.length,
|
||||
"element.selectionEnd should be value.length");
|
||||
}, 'input setSelectionRange(Math.pow(2,31), Math.pow(2,32) - 1)');
|
||||
},"test of input.setSelectionRange");
|
||||
|
||||
async_test(function() {
|
||||
@ -257,6 +273,22 @@ test(function() {
|
||||
assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
|
||||
assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
|
||||
},'textarea setSelectionRange(undefined,1)');
|
||||
|
||||
test(function() {
|
||||
textarea.setSelectionRange(Math.pow(2,32) - 2, Math.pow(2,32) - 1);
|
||||
assert_equals(textarea.selectionStart, textarea.value.length,
|
||||
"element.selectionStart should be value.length");
|
||||
assert_equals(textarea.selectionEnd, textarea.value.length,
|
||||
"element.selectionEnd should be value.length");
|
||||
}, 'textarea setSelectionRange(Math.pow(2,32) - 2, Math.pow(2,32) - 1)');
|
||||
|
||||
test(function() {
|
||||
textarea.setSelectionRange(Math.pow(2,31), Math.pow(2,32) - 1);
|
||||
assert_equals(textarea.selectionStart, textarea.value.length,
|
||||
"element.selectionStart should be value.length");
|
||||
assert_equals(textarea.selectionEnd, textarea.value.length,
|
||||
"element.selectionEnd should be value.length");
|
||||
}, 'textarea setSelectionRange(Math.pow(2,31), Math.pow(2,32) - 1)');
|
||||
},"test of textarea.setSelectionRange");
|
||||
|
||||
async_test(function() {
|
||||
|
Loading…
Reference in New Issue
Block a user