diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-04-18 16:19:24 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2025-04-22 16:37:03 +0200 |
commit | 57428bc5da0b73f6fc81510a1aa7816e720baf14 (patch) | |
tree | b1587a3e79a2984bea0e3a9f80ebc87830472c51 /components/layout/query.rs | |
parent | 73703e75ba17ca2b4f7999c62c1585360bda5ed6 (diff) | |
download | servo-57428bc5da0b73f6fc81510a1aa7816e720baf14.tar.gz servo-57428bc5da0b73f6fc81510a1aa7816e720baf14.zip |
layout: Implement node geometry queries against `BoxTree`'s `Fragment`
This is a followup to #36629, continuing to implement script-based
layout queries using the `Fragment`s attached to the `BoxTree`. In this
change, geometry queris (apart from parent offset) are calculated using
`Fragment`s hanging of the `BoxTree`.
In order to make this work, all `Fragment`s for inlines split by blocks,
need to be accessible in the `BoxTree`. This required some changes to
the way that box tree items were stored in DOM `BoxSlot`s. Now every
inline level item can have more than a single `BoxTree` item. These are
carefully collected by the `InlineFormattingContextBuilder` -- currently
a bit fragile, but with more documentation.
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/layout/query.rs')
-rw-r--r-- | components/layout/query.rs | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/components/layout/query.rs b/components/layout/query.rs index 3409f7c1923..3badff83672 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -46,40 +46,34 @@ use crate::fragment_tree::{ use crate::geom::{PhysicalRect, PhysicalVec}; use crate::taffy::SpecificTaffyGridInfo; -pub fn process_content_box_request( - requested_node: OpaqueNode, - fragment_tree: Option<Arc<FragmentTree>>, -) -> Option<Rect<Au>> { - let rects = fragment_tree?.get_content_boxes_for_node(requested_node); +pub fn process_content_box_request<'dom>(node: impl LayoutNode<'dom> + 'dom) -> Option<Rect<Au>> { + let rects: Vec<_> = node + .fragments_for_pseudo(None) + .iter() + .filter_map(Fragment::cumulative_content_box_rect) + .collect(); if rects.is_empty() { return None; } - Some( - rects - .iter() - .fold(Rect::zero(), |unioned_rect, rect| rect.union(&unioned_rect)), - ) + Some(rects.iter().fold(Rect::zero(), |unioned_rect, rect| { + rect.to_untyped().union(&unioned_rect) + })) } -pub fn process_content_boxes_request( - requested_node: OpaqueNode, - fragment_tree: Option<Arc<FragmentTree>>, -) -> Vec<Rect<Au>> { - fragment_tree - .map(|tree| tree.get_content_boxes_for_node(requested_node)) - .unwrap_or_default() +pub fn process_content_boxes_request<'dom>(node: impl LayoutNode<'dom> + 'dom) -> Vec<Rect<Au>> { + node.fragments_for_pseudo(None) + .iter() + .filter_map(Fragment::cumulative_content_box_rect) + .map(|rect| rect.to_untyped()) + .collect() } -pub fn process_node_geometry_request( - requested_node: OpaqueNode, - fragment_tree: Option<Arc<FragmentTree>>, -) -> Rect<i32> { - if let Some(fragment_tree) = fragment_tree { - fragment_tree.get_border_dimensions_for_node(requested_node) - } else { - Rect::zero() - } +pub fn process_client_rect_request<'dom>(node: impl LayoutNode<'dom> + 'dom) -> Rect<i32> { + node.fragments_for_pseudo(None) + .first() + .map(Fragment::client_rect) + .unwrap_or_default() } /// <https://drafts.csswg.org/cssom-view/#scrolling-area> |