Skip to content

Commit

Permalink
LibWeb: fix "incorrect behavior on select()" LadybirdBrowser#1446
Browse files Browse the repository at this point in the history
This patch resolves the problem outlined in issue LadybirdBrowser#1446, where the
cursor_position node could be substituted with any other existing
node by the mousedown event. Previously, if this new node was not
equal to m_text_node, the function would return prematurely without
updating the selection.

With this fix, we ensure that the selection is properly updated in
such cases, rather than simply exiting the function.
  • Loading branch information
An-n-ya committed Sep 20, 2024
1 parent 5ac0e81 commit 3a32c9c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!--refer to https://wpt.live/css/cssom-view/range-bounding-client-rect-with-display-contents.html -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Include display:contents elements recursively when calculating bounding rect for a ranges</title>
<script src="../include.js"></script>
<div id="container">
<div id="spacerBefore">spacer before</div>
<div style="display:contents" id="parent">
<div style="height:30px; background:lightblue" id="first">
HEIGHT: 30px
</div>
<div style="display:contents" id="second">
<div style="display:contents">
<div style="height:30px; background:lightblue">
HEIGHT: 30px
</div>
</div>
</div>
</div>
<div id="spacerAfter">spacer after</div>
</div>
<script>
test(function () {
const spacerBefore = document.getElementById("spacerBefore");
const spacerAfter = document.getElementById("spacerAfter");

const expected = spacerAfter.getBoundingClientRect().top - spacerBefore.getBoundingClientRect().bottom;

const rangeBetweenSpacers = document.createRange();
rangeBetweenSpacers.setStartAfter(spacerBefore);
rangeBetweenSpacers.setEndBefore(spacerAfter);

let rects = rangeBetweenSpacers.getClientRects();
console.log(rects);

const actual = rangeBetweenSpacers.getBoundingClientRect().height;

console.log(expected);
console.log(actual);

println(actual > 0);
println(expected == actual);
})
</script>
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2429,7 +2429,7 @@ HTMLInputElement::ValueAttributeMode HTMLInputElement::value_attribute_mode() co

void HTMLInputElement::selection_was_changed(size_t selection_start, size_t selection_end)
{
if (!m_text_node || !document().cursor_position() || document().cursor_position()->node() != m_text_node)
if (!m_text_node)
return;

document().set_cursor_position(DOM::Position::create(realm(), *m_text_node, selection_end));
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ void HTMLTextAreaElement::queue_firing_input_event()

void HTMLTextAreaElement::selection_was_changed(size_t selection_start, size_t selection_end)
{
if (!m_text_node || !document().cursor_position() || document().cursor_position()->node() != m_text_node)
if (!m_text_node)
return;

document().set_cursor_position(DOM::Position::create(realm(), *m_text_node, selection_end));
Expand Down

0 comments on commit 3a32c9c

Please sign in to comment.