script: Partially implement IntersectionObserver compute the intersection algo (#42204)

Depends on #42251 for the overflow query.

Use containing block queries to implement the iteration of step [3.2.7.
Compute the Intersection of a Target Element and the
Root](https://w3c.github.io/IntersectionObserver/#compute-the-intersection)
within `IntersectionObserver` algorithm.

Contrary to the algorithm in the spec that maps the coordinate space of
the element for each iteration, we uses bounding client rect queries to
get the appropriate clip rect. And, to handle the mapping between
different coordinate spaces of iframes, we use a simple translation.

Due to the platform limitation, currently it would only handle the same
`ScriptThread` browsing context. Therefore innaccuracy any usage with
cross origin iframes is expected.

Testing: Existing and new WPTs.
Part of: https://github.com/servo/servo/issues/35767

Co-authored-by: Josh Matthews
[josh@joshmatthews.net](josh@joshmatthews.net)

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Steven Novaryo
2026-04-16 17:04:53 +08:00
committed by GitHub
parent 6c14aed993
commit 02ba2eaa62
30 changed files with 412 additions and 217 deletions

View File

@@ -1052,6 +1052,12 @@ impl Node {
TrustedNodeAddress(self as *const Node as *const libc::c_void)
}
/// Return the node that establishes a containing block for this node.
pub(crate) fn containing_block_node_without_reflow(&self) -> Option<DomRoot<Node>> {
self.owner_window()
.containing_block_node_query_without_reflow(self)
}
pub(crate) fn padding(&self) -> Option<PhysicalSides> {
self.owner_window().padding_query_without_reflow(self)
}
@@ -1066,11 +1072,21 @@ impl Node {
.box_area_query(self, BoxAreaType::Border, false)
}
pub(crate) fn border_box_without_reflow(&self) -> Option<Rect<Au, CSSPixel>> {
self.owner_window()
.box_area_query_without_reflow(self, BoxAreaType::Border, false)
}
pub(crate) fn padding_box(&self) -> Option<Rect<Au, CSSPixel>> {
self.owner_window()
.box_area_query(self, BoxAreaType::Padding, false)
}
pub(crate) fn padding_box_without_reflow(&self) -> Option<Rect<Au, CSSPixel>> {
self.owner_window()
.box_area_query_without_reflow(self, BoxAreaType::Padding, false)
}
pub(crate) fn border_boxes(&self) -> CSSPixelRectIterator {
self.owner_window()
.box_areas_query(self, BoxAreaType::Border)