Bug 1679461 - Use SetSelectionRange in Select(), regardless of focus state r=masayuki
SelectAll() also is no-op without a frame, so this replaces it with SetSelectionRange. Differential Revision: https://phabricator.services.mozilla.com/D98184
This commit is contained in:
@@ -3020,17 +3020,11 @@ void HTMLInputElement::Select() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Bug? We have to give the input focus before contents can be
|
TextControlState* state = GetEditorState();
|
||||||
// selected
|
MOZ_ASSERT(state, "Single line text controls are expected to have a state");
|
||||||
|
|
||||||
FocusTristate state = FocusState();
|
if (FocusState() != eUnfocusable) {
|
||||||
if (state == eUnfocusable) {
|
RefPtr<nsFrameSelection> fs = state->GetConstFrameSelection();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextControlState* tes = GetEditorState();
|
|
||||||
if (tes) {
|
|
||||||
RefPtr<nsFrameSelection> fs = tes->GetConstFrameSelection();
|
|
||||||
if (fs && fs->MouseDownRecorded()) {
|
if (fs && fs->MouseDownRecorded()) {
|
||||||
// This means that we're being called while the frame selection has a
|
// This means that we're being called while the frame selection has a
|
||||||
// mouse down event recorded to adjust the caret during the mouse up
|
// mouse down event recorded to adjust the caret during the mouse up
|
||||||
@@ -3039,27 +3033,24 @@ void HTMLInputElement::Select() {
|
|||||||
// select() call takes effect.
|
// select() call takes effect.
|
||||||
fs->SetDelayedCaretData(nullptr);
|
fs->SetDelayedCaretData(nullptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
|
||||||
|
fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
|
||||||
|
|
||||||
RefPtr<nsPresContext> presContext = GetPresContext(eForComposedDoc);
|
// A focus event handler may change the type attribute, which will destroy
|
||||||
if (state == eInactiveWindow) {
|
// the previous state object.
|
||||||
if (fm) fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
|
state = GetEditorState();
|
||||||
SelectAll(presContext);
|
if (!state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchSelectEvent(presContext);
|
|
||||||
if (fm) {
|
|
||||||
fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
|
|
||||||
|
|
||||||
// ensure that the element is actually focused
|
|
||||||
if (this == fm->GetFocusedElement()) {
|
|
||||||
// Now Select all the text!
|
|
||||||
SelectAll(presContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Directly call TextControlState::SetSelectionRange because
|
||||||
|
// HTMLInputElement::SetSelectionRange only applies to fewer types
|
||||||
|
state->SetSelectionRange(0, UINT32_MAX,
|
||||||
|
nsITextControlFrame::SelectionDirection::eNone,
|
||||||
|
IgnoredErrorResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTMLInputElement::DispatchSelectEvent(nsPresContext* aPresContext) {
|
void HTMLInputElement::DispatchSelectEvent(nsPresContext* aPresContext) {
|
||||||
|
|||||||
@@ -670,7 +670,7 @@ class HTMLInputElement final : public TextControlElement,
|
|||||||
|
|
||||||
already_AddRefed<nsINodeList> GetLabels();
|
already_AddRefed<nsINodeList> GetLabels();
|
||||||
|
|
||||||
void Select();
|
MOZ_CAN_RUN_SCRIPT void Select();
|
||||||
|
|
||||||
Nullable<uint32_t> GetSelectionStart(ErrorResult& aRv);
|
Nullable<uint32_t> GetSelectionStart(ErrorResult& aRv);
|
||||||
MOZ_CAN_RUN_SCRIPT void SetSelectionStart(const Nullable<uint32_t>& aValue,
|
MOZ_CAN_RUN_SCRIPT void SetSelectionStart(const Nullable<uint32_t>& aValue,
|
||||||
|
|||||||
@@ -132,37 +132,14 @@ nsresult HTMLTextAreaElement::Clone(dom::NodeInfo* aNodeInfo,
|
|||||||
// nsIContent
|
// nsIContent
|
||||||
|
|
||||||
void HTMLTextAreaElement::Select() {
|
void HTMLTextAreaElement::Select() {
|
||||||
// XXX Bug? We have to give the input focus before contents can be
|
if (FocusState() != eUnfocusable) {
|
||||||
// selected
|
if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) {
|
||||||
|
fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
|
||||||
FocusTristate state = FocusState();
|
|
||||||
if (state == eUnfocusable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
||||||
|
|
||||||
RefPtr<nsPresContext> presContext = GetPresContext(eForComposedDoc);
|
|
||||||
if (state == eInactiveWindow) {
|
|
||||||
if (fm) fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
|
|
||||||
SelectAll(presContext);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WidgetGUIEvent event(true, eFormSelect, nullptr);
|
|
||||||
// XXXbz HTMLInputElement guards against this reentering; shouldn't we?
|
|
||||||
EventDispatcher::Dispatch(static_cast<nsIContent*>(this), presContext,
|
|
||||||
&event);
|
|
||||||
|
|
||||||
if (fm) {
|
|
||||||
fm->SetFocus(this, nsIFocusManager::FLAG_NOSCROLL);
|
|
||||||
|
|
||||||
// ensure that the element is actually focused
|
|
||||||
if (this == fm->GetFocusedElement()) {
|
|
||||||
// Now Select all the text!
|
|
||||||
SelectAll(presContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetSelectionRange(0, UINT32_MAX, mozilla::dom::Optional<nsAString>(),
|
||||||
|
IgnoredErrorResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ class HTMLTextAreaElement final : public TextControlElement,
|
|||||||
// via bindings.
|
// via bindings.
|
||||||
void SetCustomValidity(const nsAString& aError);
|
void SetCustomValidity(const nsAString& aError);
|
||||||
|
|
||||||
void Select();
|
MOZ_CAN_RUN_SCRIPT void Select();
|
||||||
Nullable<uint32_t> GetSelectionStart(ErrorResult& aError);
|
Nullable<uint32_t> GetSelectionStart(ErrorResult& aError);
|
||||||
MOZ_CAN_RUN_SCRIPT void SetSelectionStart(
|
MOZ_CAN_RUN_SCRIPT void SetSelectionStart(
|
||||||
const Nullable<uint32_t>& aSelectionStart, ErrorResult& aError);
|
const Nullable<uint32_t>& aSelectionStart, ErrorResult& aError);
|
||||||
|
|||||||
@@ -95,12 +95,9 @@
|
|||||||
// to the character that immediately follows the text entry cursor.
|
// to the character that immediately follows the text entry cursor.
|
||||||
assert_equals(el.selectionStart, el.value.length,
|
assert_equals(el.selectionStart, el.value.length,
|
||||||
"SelectionStart offset without selection in " + el.id);
|
"SelectionStart offset without selection in " + el.id);
|
||||||
if (!el.parentNode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
el.select();
|
el.select();
|
||||||
assert_equals(el.selectionStart, 0, "SelectionStart offset");
|
assert_equals(el.selectionStart, 0, "SelectionStart offset");
|
||||||
el.parentNode.removeChild(el);
|
el.remove();
|
||||||
}, "test SelectionStart offset for input that is " +
|
}, "test SelectionStart offset for input that is " +
|
||||||
(append ? "appended" : " not appended"));
|
(append ? "appended" : " not appended"));
|
||||||
}
|
}
|
||||||
@@ -112,12 +109,9 @@
|
|||||||
// to the character that immediately follows the text entry cursor.
|
// to the character that immediately follows the text entry cursor.
|
||||||
assert_equals(el.selectionStart, el.value.length,
|
assert_equals(el.selectionStart, el.value.length,
|
||||||
"SelectionStart offset without selection in " + el.id);
|
"SelectionStart offset without selection in " + el.id);
|
||||||
if (!el.parentNode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
el.select();
|
el.select();
|
||||||
assert_equals(el.selectionStart, 0, "SelectionStart offset");
|
assert_equals(el.selectionStart, 0, "SelectionStart offset");
|
||||||
el.parentNode.removeChild(el);
|
el.remove();
|
||||||
}, "test SelectionStart offset for textarea that is " +
|
}, "test SelectionStart offset for textarea that is " +
|
||||||
(append ? "appended" : " not appended"));
|
(append ? "appended" : " not appended"));
|
||||||
}
|
}
|
||||||
@@ -129,12 +123,9 @@
|
|||||||
// to the character that immediately follows the text entry cursor.
|
// to the character that immediately follows the text entry cursor.
|
||||||
assert_equals(el.selectionEnd, el.value.length,
|
assert_equals(el.selectionEnd, el.value.length,
|
||||||
"SelectionEnd offset without selection in " + el.id);
|
"SelectionEnd offset without selection in " + el.id);
|
||||||
if (!el.parentNode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
el.select();
|
el.select();
|
||||||
assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset");
|
assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset");
|
||||||
el.parentNode.removeChild(el);
|
el.remove();
|
||||||
}, "test SelectionEnd offset for input that is " +
|
}, "test SelectionEnd offset for input that is " +
|
||||||
(append ? "appended" : " not appended"));
|
(append ? "appended" : " not appended"));
|
||||||
}
|
}
|
||||||
@@ -147,12 +138,9 @@
|
|||||||
// to the character that immediately follows the text entry cursor.
|
// to the character that immediately follows the text entry cursor.
|
||||||
assert_equals(el.selectionEnd, el.value.length,
|
assert_equals(el.selectionEnd, el.value.length,
|
||||||
"SelectionEnd offset without selection in " + el.id);
|
"SelectionEnd offset without selection in " + el.id);
|
||||||
if (!el.parentNode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
el.select();
|
el.select();
|
||||||
assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset");
|
assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset");
|
||||||
el.parentNode.removeChild(el);
|
el.remove();
|
||||||
}, "test SelectionEnd offset for textarea that is " +
|
}, "test SelectionEnd offset for textarea that is " +
|
||||||
(append ? "appended" : " not appended"));
|
(append ? "appended" : " not appended"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user