diff --git a/dom/html/TextControlState.cpp b/dom/html/TextControlState.cpp index 87cba87d1de9..e178595b4500 100644 --- a/dom/html/TextControlState.cpp +++ b/dom/html/TextControlState.cpp @@ -2069,6 +2069,17 @@ void TextControlState::SetSelectionRange( bool changed = false; nsresult rv = NS_OK; // For the ScrollSelectionIntoView() return value. if (IsSelectionCached()) { + nsAutoString value; + // XXXbz is "false" the right thing to pass here? Hard to tell, given the + // various mismatches between our impl and the spec. + GetValue(value, false); + uint32_t length = value.Length(); + if (aStart > length) { + aStart = length; + } + if (aEnd > length) { + aEnd = length; + } SelectionProperties& props = GetSelectionProperties(); changed = props.GetStart() != aStart || props.GetEnd() != aEnd || props.GetDirection() != aDirection; @@ -2882,7 +2893,6 @@ bool TextControlState::SetValueWithoutTextEditor( aHandlingSetValue.GetSetValueFlags())); SelectionProperties& props = GetSelectionProperties(); - props.SetMaxLength(aHandlingSetValue.GetSettingValue().Length()); if (aHandlingSetValue.GetSetValueFlags() & eSetValue_MoveCursorToEndIfValueChanged) { props.SetStart(aHandlingSetValue.GetSettingValue().Length()); @@ -2893,6 +2903,13 @@ bool TextControlState::SetValueWithoutTextEditor( props.SetStart(0); props.SetEnd(0); props.SetDirection(nsITextControlFrame::eForward); + } else { + // Make sure our cached selection position is not outside the new + // value. + props.SetStart(std::min( + props.GetStart(), aHandlingSetValue.GetSettingValue().Length())); + props.SetEnd(std::min(props.GetEnd(), + aHandlingSetValue.GetSettingValue().Length())); } } diff --git a/dom/html/TextControlState.h b/dom/html/TextControlState.h index 39dbf1a45c45..744ad3eb3707 100644 --- a/dom/html/TextControlState.h +++ b/dom/html/TextControlState.h @@ -284,12 +284,12 @@ class TextControlState final : public SupportsWeakPtr { uint32_t GetStart() const { return mStart; } void SetStart(uint32_t value) { mIsDirty = true; - mStart = std::min(value, mMaxLength); + mStart = value; } uint32_t GetEnd() const { return mEnd; } void SetEnd(uint32_t value) { mIsDirty = true; - mEnd = std::min(value, mMaxLength); + mEnd = value; } nsITextControlFrame::SelectionDirection GetDirection() const { return mDirection; @@ -298,20 +298,13 @@ class TextControlState final : public SupportsWeakPtr { mIsDirty = true; mDirection = value; } - void SetMaxLength(uint32_t aMax) { - mMaxLength = aMax; - // recompute against the new max length - SetStart(GetStart()); - SetEnd(GetEnd()); - } - // return true only if mStart, mEnd, or mDirection have been modified, // or if SetIsDirty() was explicitly called. bool IsDirty() const { return mIsDirty; } void SetIsDirty() { mIsDirty = true; } private: - uint32_t mStart, mEnd, mMaxLength; + uint32_t mStart, mEnd; bool mIsDirty = false; nsITextControlFrame::SelectionDirection mDirection; }; diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-start-end.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-start-end.html index 919d1a4d6583..4bcecf234cc0 100644 --- a/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-start-end.html +++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-start-end.html @@ -144,31 +144,6 @@ } }, "selectionEnd edge-case values"); - test(() => { - for (const el of createTestElements(testValue)) { - el.selectionStart = 200; - assert_equals(el.selectionStart, testValue.length); - el.remove(); - } - }, "selectionStart should be clamped by the current value length"); - - test(() => { - for (const el of createTestElements(testValue)) { - el.selectionStart = 300; - assert_equals(el.selectionEnd, testValue.length); - el.remove(); - } - }, "selectionEnd should be clamped by the current value length"); - - test(() => { - for (const el of createTestElements(testValue)) { - el.setSelectionRange(200, 300); - assert_equals(el.selectionStart, testValue.length); - assert_equals(el.selectionEnd, testValue.length); - el.remove(); - } - }, "setSelectionRange should be clamped by the current value length"); - test(() => { for (let el of createTestElements(testValue)) { const start = 1;