mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibWeb: Update the document cursor position when the selection changes
Otherwise, it looks a bit awkward where the cursor position does not update while the selection is elsewhere. Note that this requires passing along the raw selection positions from `set the selection range` to the elements. Otherwise, consider what will happen if we set the selection start and end to the same value. By going through the API accessor, we hit the case where the start and end are the same value, and return the document cursor position. This would mean the cursor position would not be updated. The test changes here more closely match what Firefox produces now. It is not a 100% match; the `select event fired` test case isn't right. The problem is the event fires for the input element, but we most recently focused the textarea element. Thus, when we retrieve the selection from the input element, we return the document's cursor position, which is actually in the textarea element. The fix will ultimately be to fully implement the following: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-cursor That is, each input / textarea element should separately track its own text cursor position.
This commit is contained in:
parent
430c9d3e3f
commit
fd289deb44
Notes:
github-actions[bot]
2024-08-31 13:52:26 +00:00
Author: https://github.com/trflynn89
Commit: fd289deb44
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1205
7 changed files with 16 additions and 12 deletions
|
@ -8,7 +8,7 @@ text-input selectionStart: 0 selectionEnd: 18 selectionDirection: none
|
||||||
text-input selectionStart: 2 selectionEnd: 4 selectionDirection: forward
|
text-input selectionStart: 2 selectionEnd: 4 selectionDirection: forward
|
||||||
text-input selectionStart: 1 selectionEnd: 4 selectionDirection: forward
|
text-input selectionStart: 1 selectionEnd: 4 selectionDirection: forward
|
||||||
text-input selectionStart: 1 selectionEnd: 5 selectionDirection: forward
|
text-input selectionStart: 1 selectionEnd: 5 selectionDirection: forward
|
||||||
text-input selectionStart: 18 selectionEnd: 18 selectionDirection: forward
|
text-input selectionStart: 6 selectionEnd: 6 selectionDirection: forward
|
||||||
text-input selectionStart: 18 selectionEnd: 18 selectionDirection: backward
|
text-input selectionStart: 6 selectionEnd: 6 selectionDirection: backward
|
||||||
textarea selectionStart: 0 selectionEnd: 9 selectionDirection: none
|
textarea selectionStart: 0 selectionEnd: 9 selectionDirection: none
|
||||||
select event fired: 18 18
|
select event fired: 9 9
|
||||||
|
|
|
@ -541,7 +541,7 @@ void FormAssociatedTextControlElement::set_the_selection_range(Optional<WebIDL::
|
||||||
|
|
||||||
// AD-HOC: Notify the element that the selection was changed, so it can perform
|
// AD-HOC: Notify the element that the selection was changed, so it can perform
|
||||||
// element-specific updates.
|
// element-specific updates.
|
||||||
selection_was_changed();
|
selection_was_changed(m_selection_start, m_selection_end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,6 @@ protected:
|
||||||
void form_node_was_removed();
|
void form_node_was_removed();
|
||||||
void form_node_attribute_changed(FlyString const&, Optional<String> const&);
|
void form_node_attribute_changed(FlyString const&, Optional<String> const&);
|
||||||
|
|
||||||
virtual void selection_was_changed() { }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset_form_owner();
|
void reset_form_owner();
|
||||||
|
|
||||||
|
@ -159,6 +157,8 @@ protected:
|
||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-relevant-value
|
||||||
void relevant_value_was_changed(JS::GCPtr<DOM::Text>);
|
void relevant_value_was_changed(JS::GCPtr<DOM::Text>);
|
||||||
|
|
||||||
|
virtual void selection_was_changed([[maybe_unused]] size_t selection_start, [[maybe_unused]] size_t selection_end) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-selection
|
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#concept-textarea/input-selection
|
||||||
WebIDL::UnsignedLong m_selection_start { 0 };
|
WebIDL::UnsignedLong m_selection_start { 0 };
|
||||||
|
|
|
@ -2362,13 +2362,15 @@ HTMLInputElement::ValueAttributeMode HTMLInputElement::value_attribute_mode() co
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTMLInputElement::selection_was_changed()
|
void HTMLInputElement::selection_was_changed(size_t selection_start, size_t selection_end)
|
||||||
{
|
{
|
||||||
|
document().set_cursor_position(DOM::Position::create(realm(), *m_text_node, selection_end));
|
||||||
|
|
||||||
auto selection = document().get_selection();
|
auto selection = document().get_selection();
|
||||||
if (!selection || selection->range_count() == 0)
|
if (!selection || selection->range_count() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MUST(selection->set_base_and_extent(*m_text_node, selection_start().value(), *m_text_node, selection_end().value()));
|
MUST(selection->set_base_and_extent(*m_text_node, selection_start, *m_text_node, selection_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,7 @@ public:
|
||||||
bool selection_or_range_applies() const;
|
bool selection_or_range_applies() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void selection_was_changed() override;
|
void selection_was_changed(size_t selection_start, size_t selection_end) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HTMLInputElement(DOM::Document&, DOM::QualifiedName);
|
HTMLInputElement(DOM::Document&, DOM::QualifiedName);
|
||||||
|
|
|
@ -460,13 +460,15 @@ void HTMLTextAreaElement::queue_firing_input_event()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTMLTextAreaElement::selection_was_changed()
|
void HTMLTextAreaElement::selection_was_changed(size_t selection_start, size_t selection_end)
|
||||||
{
|
{
|
||||||
|
document().set_cursor_position(DOM::Position::create(realm(), *m_text_node, selection_end));
|
||||||
|
|
||||||
auto selection = document().get_selection();
|
auto selection = document().get_selection();
|
||||||
if (!selection || selection->range_count() == 0)
|
if (!selection || selection->range_count() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MUST(selection->set_base_and_extent(*m_text_node, selection_start().value(), *m_text_node, selection_end().value()));
|
MUST(selection->set_base_and_extent(*m_text_node, selection_start, *m_text_node, selection_end));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ public:
|
||||||
void set_dirty_value_flag(Badge<FormAssociatedElement>, bool flag) { m_dirty_value = flag; }
|
void set_dirty_value_flag(Badge<FormAssociatedElement>, bool flag) { m_dirty_value = flag; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void selection_was_changed() override;
|
void selection_was_changed(size_t selection_start, size_t selection_end) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HTMLTextAreaElement(DOM::Document&, DOM::QualifiedName);
|
HTMLTextAreaElement(DOM::Document&, DOM::QualifiedName);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue