LibWeb: Compare anchor/focus offsets in selection.isCollapsed

The "isCollapsed" attribute on a selection must "return true if and only
if the anchor and focus are the same".

In addition to checking that the anchor and focus belonged to the same
DOM node, we now also check that they refer to the same position within
the node.

With this change Ladybird passes all the subtests in the "isCollapsed"
WPT suite.

https://wpt.live/selection/isCollapsed.html
This commit is contained in:
John Diamond 2024-10-12 02:42:55 +02:00 committed by Andreas Kling
parent 27b1d94e04
commit fadb14d31d
Notes: github-actions[bot] 2024-10-12 13:01:26 +00:00
3 changed files with 32 additions and 1 deletions

View file

@ -0,0 +1 @@
PASS

View file

@ -0,0 +1,27 @@
<script src="include.js"></script>
<p id="a">Simply selectable</p>
<script>
test(() => {
var selection = window.getSelection();
var range = document.createRange();
range.setStart(a.firstChild, 0);
range.setEnd(a.firstChild, 1);
selection.addRange(range);
if (selection.isCollapsed) {
println(`FAIL: "${selection}" is not collapsed`);
return;
}
selection.collapseToStart();
if (!selection.isCollapsed) {
println(`FAIL: "${selection}" is collapsed`);
return;
}
selection.removeAllRanges();
if (!selection.isCollapsed) {
println(`FAIL: "${selection}" is collapsed`);
return;
}
println("PASS");
})
</script>

View file

@ -96,7 +96,10 @@ bool Selection::is_collapsed() const
{
// The attribute must return true if and only if the anchor and focus are the same
// (including if both are null). Otherwise it must return false.
return const_cast<Selection*>(this)->anchor_node() == const_cast<Selection*>(this)->focus_node();
if (!m_range)
return true;
return const_cast<Selection*>(this)->anchor_node() == const_cast<Selection*>(this)->focus_node()
&& m_range->start_offset() == m_range->end_offset();
}
// https://w3c.github.io/selection-api/#dom-selection-rangecount