mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
layout: Add basic support for getClientRects()
queries (#31696)
This adds basic support for `getClientRects()` by sharing code with the implementation of `getBoundingClientRect()`. In addition to sharing code, it also shares all of the bugs. Primarily, scrolilng positions are not taken into account when return boundary rectangles.
This commit is contained in:
parent
3f3820b3dc
commit
47a4ce467f
15 changed files with 48 additions and 71 deletions
|
@ -17,7 +17,7 @@ use super::{ContainingBlockManager, Fragment, Tag};
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
use crate::display_list::StackingContext;
|
use crate::display_list::StackingContext;
|
||||||
use crate::flow::CanvasBackground;
|
use crate::flow::CanvasBackground;
|
||||||
use crate::geom::PhysicalRect;
|
use crate::geom::{physical_rect_to_au_rect, PhysicalRect};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct FragmentTree {
|
pub struct FragmentTree {
|
||||||
|
@ -97,9 +97,13 @@ impl FragmentTree {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_content_box_for_node(&self, requested_node: OpaqueNode) -> Option<Rect<Au>> {
|
/// Get the vector of rectangles that surrounds the fragments of the node with the given address.
|
||||||
let mut bounding_box = PhysicalRect::zero();
|
/// This function answers the `getClientRects()` query and the union of the rectangles answers
|
||||||
let mut found_any_nodes = false;
|
/// the `getBoundingClientRect()` query.
|
||||||
|
///
|
||||||
|
/// TODO: This function is supposed to handle scroll offsets, but that isn't happening at all.
|
||||||
|
pub fn get_content_boxes_for_node(&self, requested_node: OpaqueNode) -> Vec<Rect<Au>> {
|
||||||
|
let mut content_boxes = Vec::new();
|
||||||
let tag_to_find = Tag::new(requested_node);
|
let tag_to_find = Tag::new(requested_node);
|
||||||
self.find(|fragment, _, containing_block| {
|
self.find(|fragment, _, containing_block| {
|
||||||
if fragment.tag() != Some(tag_to_find) {
|
if fragment.tag() != Some(tag_to_find) {
|
||||||
|
@ -121,27 +125,12 @@ impl FragmentTree {
|
||||||
Fragment::IFrame(_) => return None,
|
Fragment::IFrame(_) => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
found_any_nodes = true;
|
content_boxes.push(physical_rect_to_au_rect(
|
||||||
bounding_box = fragment_relative_rect
|
fragment_relative_rect.translate(containing_block.origin.to_vector()),
|
||||||
.translate(containing_block.origin.to_vector())
|
));
|
||||||
.union(&bounding_box);
|
|
||||||
None::<()>
|
None::<()>
|
||||||
});
|
});
|
||||||
|
content_boxes
|
||||||
if found_any_nodes {
|
|
||||||
Some(Rect::new(
|
|
||||||
Point2D::new(
|
|
||||||
Au::from_f32_px(bounding_box.origin.x.px()),
|
|
||||||
Au::from_f32_px(bounding_box.origin.y.px()),
|
|
||||||
),
|
|
||||||
Size2D::new(
|
|
||||||
Au::from_f32_px(bounding_box.size.width.px()),
|
|
||||||
Au::from_f32_px(bounding_box.size.height.px()),
|
|
||||||
),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_border_dimensions_for_node(&self, requested_node: OpaqueNode) -> Rect<i32> {
|
pub fn get_border_dimensions_for_node(&self, requested_node: OpaqueNode) -> Rect<i32> {
|
||||||
|
|
|
@ -525,3 +525,17 @@ impl From<LogicalRect<CSSPixelLength>> for LogicalRect<Au> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a `PhysicalRect<Length>` (one that uses CSSPixel as the unit) to an untyped `Rect<Au>`.
|
||||||
|
pub fn physical_rect_to_au_rect(rect: PhysicalRect<Length>) -> euclid::default::Rect<Au> {
|
||||||
|
euclid::default::Rect::new(
|
||||||
|
euclid::default::Point2D::new(
|
||||||
|
Au::from_f32_px(rect.origin.x.px()),
|
||||||
|
Au::from_f32_px(rect.origin.y.px()),
|
||||||
|
),
|
||||||
|
euclid::default::Size2D::new(
|
||||||
|
Au::from_f32_px(rect.size.width.px()),
|
||||||
|
Au::from_f32_px(rect.size.height.px()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -179,11 +179,25 @@ pub fn process_content_box_request(
|
||||||
requested_node: OpaqueNode,
|
requested_node: OpaqueNode,
|
||||||
fragment_tree: Option<Arc<FragmentTree>>,
|
fragment_tree: Option<Arc<FragmentTree>>,
|
||||||
) -> Option<Rect<Au>> {
|
) -> Option<Rect<Au>> {
|
||||||
fragment_tree?.get_content_box_for_node(requested_node)
|
let rects = fragment_tree?.get_content_boxes_for_node(requested_node);
|
||||||
|
if rects.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(
|
||||||
|
rects
|
||||||
|
.iter()
|
||||||
|
.fold(Rect::zero(), |unioned_rect, rect| rect.union(&unioned_rect)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_content_boxes_request(_requested_node: OpaqueNode) -> Vec<Rect<Au>> {
|
pub fn process_content_boxes_request(
|
||||||
vec![]
|
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_node_geometry_request(
|
pub fn process_node_geometry_request(
|
||||||
|
|
|
@ -857,7 +857,8 @@ impl LayoutThread {
|
||||||
process_content_box_request(node, self.fragment_tree.borrow().clone());
|
process_content_box_request(node, self.fragment_tree.borrow().clone());
|
||||||
},
|
},
|
||||||
&QueryMsg::ContentBoxesQuery(node) => {
|
&QueryMsg::ContentBoxesQuery(node) => {
|
||||||
rw_data.content_boxes_response = process_content_boxes_request(node);
|
rw_data.content_boxes_response =
|
||||||
|
process_content_boxes_request(node, self.fragment_tree.borrow().clone());
|
||||||
},
|
},
|
||||||
&QueryMsg::TextIndexQuery(node, point_in_node) => {
|
&QueryMsg::TextIndexQuery(node, point_in_node) => {
|
||||||
let point_in_node = Point2D::new(
|
let point_in_node = Point2D::new(
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[cssom-getClientRects-002.html]
|
|
||||||
[CSSOM View - GetClientRects().length is the same regardless source new lines]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[getClientRects-br-htb-ltr.html]
|
|
||||||
[Position of the BR element]
|
|
||||||
expected: FAIL
|
|
|
@ -1,4 +0,0 @@
|
||||||
[getClientRects-br-vlr-ltr.html]
|
|
||||||
[Position of the BR element]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
[getClientRects-inline-atomic-child.html]
|
|
||||||
[getClientRects-inline-atomic-child]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[getClientRects-inline-atomic-child 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[getClientRects-inline-atomic-child 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[getClientRects-inline.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,7 +1,4 @@
|
||||||
[getClientRects-zoom.html]
|
[getClientRects-zoom.html]
|
||||||
[getBoundingClientRect for elements with css zoom 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[getBoundingClientRect for elements with css zoom 2]
|
[getBoundingClientRect for elements with css zoom 2]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,6 @@
|
||||||
|
|
||||||
[Make sure the page is ready for animation.]
|
[Make sure the page is ready for animation.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Smooth scrolling while doing history navigation.]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
[ttwf-js-cssomview-getclientrects-length.html]
|
|
||||||
[assert_length_of_getClientRects_from_Link]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[assert_length_of_getClientRects_from_Parent]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[assert_length_of_getClientRects_from_Button]
|
|
||||||
expected: FAIL
|
|
|
@ -7,9 +7,3 @@
|
||||||
|
|
||||||
[DOMRectList item()]
|
[DOMRectList item()]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[DOMRectList length]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[DOMRectList indexed getter]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -88,6 +88,3 @@
|
||||||
|
|
||||||
[DOMMatrix clone: non-initial values (3d)]
|
[DOMMatrix clone: non-initial values (3d)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[DOMRectList clone]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[canvas-descendants-focusability-003.tentative.html]
|
[canvas-descendants-focusability-003.tentative.html]
|
||||||
expected: ERROR
|
|
||||||
[<div tabindex="-1" data-focusable="false">]
|
[<div tabindex="-1" data-focusable="false">]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue