aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/query.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2025-04-18 16:19:24 +0200
committerMartin Robinson <mrobinson@igalia.com>2025-04-22 16:37:03 +0200
commit57428bc5da0b73f6fc81510a1aa7816e720baf14 (patch)
treeb1587a3e79a2984bea0e3a9f80ebc87830472c51 /components/layout/query.rs
parent73703e75ba17ca2b4f7999c62c1585360bda5ed6 (diff)
downloadservo-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.rs46
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>