dom: Implement minimal IntersectionObserver workflow (#35551)

* Add very rough implemnentation of observation steps

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix entry reflection and propagate can_gc

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix BorrowError and add fragment find descendant

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Implement is descendant in containing block path correctly

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix unrooted error and tidy issues

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix comments

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Remove is descendant of other node query

I suppose these changes is better separated to other PRs.

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix intersection and refactor registration

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Use AppUnit more and propagate GlobalScope better

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Update WPT expectations

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Revert delay changes

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Align compute intersection algo to other browser actual behavior

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Align processing documents and note several issues

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Update WPT

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Minor lint

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix top level browsing context

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Make Registration rootable

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Avoid reflow inside observation step algo

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Using borrow for iterating registration

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix document disconnect

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Update WPT

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Address comments and minor quality suggestions

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Root the observer before nofifying any of it

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Tidy docs

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Account not found element and refactor observation step

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix documentations

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Ignore position of document viewport

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Refactor root intersection rectangle

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Add can GC note to the callback

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix top-level browsing context term

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

* Fix minor comments

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>

---------

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
Steven Novaryo 2025-03-18 19:09:44 +08:00 committed by GitHub
parent 2113e54819
commit 67a5f285ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 850 additions and 175 deletions

View file

@ -3,14 +3,16 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Copy of Stylo Gecko's [`style::values::specified::gecko::IntersectionObserverRootMargin`] implementation.
//! TODO: expose the object to servo as well in Stylo
//! TODO(#35907): make a thin wrapper and remove copied codes
use std::fmt;
use app_units::Au;
use cssparser::{Parser, Token, match_ignore_ascii_case};
use euclid::default::{Rect, SideOffsets2D};
use style::parser::{Parse, ParserContext};
use style::values::computed::{self, Length, LengthPercentage};
use style::values::generics::rect::Rect;
use style::values::generics::rect::Rect as StyleRect;
use style_traits::values::SequenceWriter;
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
@ -44,7 +46,7 @@ fn parse_pixel_or_percent<'i>(
///
/// <https://w3c.github.io/IntersectionObserver/#parse-a-root-margin>
#[repr(transparent)]
pub struct IntersectionObserverRootMargin(pub Rect<LengthPercentage>);
pub struct IntersectionObserverRootMargin(pub StyleRect<LengthPercentage>);
impl Parse for IntersectionObserverRootMargin {
fn parse<'i>(
@ -54,11 +56,11 @@ impl Parse for IntersectionObserverRootMargin {
use style::Zero;
if input.is_exhausted() {
// If there are zero elements in tokens, set tokens to ["0px"].
return Ok(IntersectionObserverRootMargin(Rect::all(
return Ok(IntersectionObserverRootMargin(StyleRect::all(
LengthPercentage::zero(),
)));
}
let rect = Rect::parse_with(context, input, parse_pixel_or_percent)?;
let rect = StyleRect::parse_with(context, input, parse_pixel_or_percent)?;
Ok(IntersectionObserverRootMargin(rect))
}
}
@ -82,3 +84,20 @@ impl ToCss for IntersectionObserverRootMargin {
writer.item(&rect.3)
}
}
// TODO(stevennovaryo): move this to the wrapper later
impl IntersectionObserverRootMargin {
// Resolve to used values.
pub(crate) fn resolve_percentages_with_basis(
&self,
containing_block: Rect<Au>,
) -> SideOffsets2D<Au> {
let inner = &self.0;
SideOffsets2D::new(
inner.0.to_used_value(containing_block.height()),
inner.1.to_used_value(containing_block.width()),
inner.2.to_used_value(containing_block.height()),
inner.3.to_used_value(containing_block.width()),
)
}
}