mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 15:10:19 +00:00
LibWeb: Don't crash on getClientRects() in document without navigable
I previously believed there was no way a detached document should have layout information, but it turns out there is a way: getComputedStyle(). So we need to account for cases where we have a layout node, but no navigable, since that is a state we can get into at this moment. Fixes #354
This commit is contained in:
parent
41cf9f6fe3
commit
1e7b17f150
Notes:
github-actions[bot]
2024-08-05 12:56:54 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/1e7b17f1502 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/971
3 changed files with 24 additions and 5 deletions
|
@ -0,0 +1,3 @@
|
|||
[object CSSStyleDeclaration]
|
||||
[object DOMRectList]
|
||||
PASS (didn't crash)
|
|
@ -0,0 +1,16 @@
|
|||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
let doc = document.implementation.createHTMLDocument();
|
||||
let div = doc.createElement("div");
|
||||
doc.body.appendChild(div);
|
||||
|
||||
// NOTE: We do a getComputedStyle() to trick the document into doing some style/layout work.
|
||||
// In the future, we may optimize away some of this work, which would potentially
|
||||
// make the test not work as intended anymore.
|
||||
println(getComputedStyle(div));
|
||||
|
||||
println(div.getClientRects());
|
||||
println("PASS (didn't crash)");
|
||||
});
|
||||
</script>
|
|
@ -949,7 +949,9 @@ JS::NonnullGCPtr<Geometry::DOMRect> Element::get_bounding_client_rect() const
|
|||
// https://drafts.csswg.org/cssom-view/#dom-element-getclientrects
|
||||
JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
|
||||
{
|
||||
Vector<JS::Handle<Geometry::DOMRect>> rects;
|
||||
auto navigable = document().navigable();
|
||||
if (!navigable)
|
||||
return Geometry::DOMRectList::create(realm(), {});
|
||||
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
|
@ -957,7 +959,7 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
|
|||
// 1. If the element on which it was invoked does not have an associated layout box return an empty DOMRectList
|
||||
// object and stop this algorithm.
|
||||
if (!layout_node())
|
||||
return Geometry::DOMRectList::create(realm(), move(rects));
|
||||
return Geometry::DOMRectList::create(realm(), {});
|
||||
|
||||
// FIXME: 2. If the element has an associated SVG layout box return a DOMRectList object containing a single
|
||||
// DOMRect object that describes the bounding box of the element as defined by the SVG specification,
|
||||
|
@ -970,9 +972,6 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
|
|||
// or inline-table include both the table box and the caption box, if any, but not the anonymous container box.
|
||||
// FIXME: - Replace each anonymous block box with its child box(es) and repeat this until no anonymous block boxes
|
||||
// are left in the final list.
|
||||
const_cast<Document&>(document()).update_layout();
|
||||
auto navigable = document().navigable();
|
||||
VERIFY(navigable);
|
||||
auto viewport_offset = navigable->viewport_scroll_offset();
|
||||
|
||||
// NOTE: Make sure CSS transforms are resolved before it is used to calculate the rect position.
|
||||
|
@ -982,6 +981,7 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
|
|||
CSSPixelPoint scroll_offset;
|
||||
auto const* paintable = this->paintable();
|
||||
|
||||
Vector<JS::Handle<Geometry::DOMRect>> rects;
|
||||
if (auto const* paintable_box = this->paintable_box()) {
|
||||
transform = Gfx::extract_2d_affine_transform(paintable_box->transform());
|
||||
for (auto const* containing_block = paintable->containing_block(); !containing_block->is_viewport(); containing_block = containing_block->containing_block()) {
|
||||
|
|
Loading…
Reference in a new issue