Skip to content

script: Partially implement IntersectionObserver compute the intersection algo#42204

Merged
xiaochengh merged 9 commits into
servo:mainfrom
stevennovaryo:descendant-of-query
Apr 16, 2026
Merged

script: Partially implement IntersectionObserver compute the intersection algo#42204
xiaochengh merged 9 commits into
servo:mainfrom
stevennovaryo:descendant-of-query

Conversation

@stevennovaryo

@stevennovaryo stevennovaryo commented Jan 28, 2026

Copy link
Copy Markdown
Member

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 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: #35767

Co-authored-by: Josh Matthews josh@joshmatthews.net

@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. S-needs-rebase There are merge conflict errors. labels Jan 28, 2026
@stevennovaryo stevennovaryo marked this pull request as draft January 28, 2026 02:55
@stevennovaryo stevennovaryo added the T-linux-wpt Do a try run of the WPT label Jan 28, 2026
@github-actions github-actions Bot removed the T-linux-wpt Do a try run of the WPT label Jan 28, 2026
@github-actions

Copy link
Copy Markdown

🔨 Triggering try run (#21423105665) for Linux (WPT)

@github-actions

Copy link
Copy Markdown

Test results for linux-wpt from try job (#21423105665):

Flaky unexpected result (38)
  • OK /FileAPI/file/send-file-form-punctuation.html
    • PASS [expected FAIL] subtest: Upload file-for-upload-in-form-LEFT-CURLY-BRACKET-[{].txt (ASCII) in UTF-8 form
  • OK /FileAPI/file/send-file-form-utf-8.html
    • FAIL [expected PASS] subtest: Upload file-for-upload-in-form-☺😂.txt (windows-1252) in UTF-8 form

      assert_greater_than: file-for-upload-in-form-☺😂.txt: multipart form data must have at least 3 lines: "" expected a number greater than 2 but got 0
      

  • OK /IndexedDB/idbfactory-open-error-properties.any.html
    • PASS [expected FAIL] subtest: Properties of error event from failed open()
  • OK /IndexedDB/idbfactory-open-error-properties.any.worker.html
    • PASS [expected FAIL] subtest: Properties of error event from failed open()
  • CRASH [expected ERROR] /_webgl/conformance2/textures/misc/tex-input-validation.html (#38890)
  • FAIL [expected PASS] /css/css-backgrounds/background-size-042.html
  • OK /css/css-fonts/generic-family-keywords-002.html (#40929)
    • FAIL [expected PASS] subtest: font-family: -webkit-serif treated as <font-family>, not <generic-name>

      assert_equals: expected 30 but got 50
      

    • FAIL [expected PASS] subtest: font-family: -webkit-sans-serif treated as <font-family>, not <generic-name>

      assert_equals: expected 30 but got 50
      

    • FAIL [expected PASS] subtest: font-family: -webkit-cursive treated as <font-family>, not <generic-name>

      assert_equals: expected 30 but got 50
      

    • FAIL [expected PASS] subtest: font-family: -webkit-fantasy treated as <font-family>, not <generic-name>

      assert_equals: expected 30 but got 50
      

    • FAIL [expected PASS] subtest: font-family: -webkit-monospace treated as <font-family>, not <generic-name>

      assert_equals: expected 30 but got 50
      

    • FAIL [expected PASS] subtest: font-family: -webkit-system-ui treated as <font-family>, not <generic-name>

      assert_equals: expected 30 but got 50
      

    • FAIL [expected PASS] subtest: font-family: -webkit-math treated as <font-family>, not <generic-name>

      assert_equals: expected 30 but got 50
      

    • PASS [expected FAIL] subtest: font-family: -webkit-generic(fangsong) treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-generic(kai) treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-generic(khmer-mul) treated as <font-family>, not <generic-name>
    • And 12 more unexpected results...
  • CRASH [expected PASS] /css/css-overflow/scroll-marker-in-display-none-column-crash.html
  • TIMEOUT [expected OK] /css/cssom/HTMLLinkElement-load-event-002.html (#42187)
    • TIMEOUT [expected PASS] subtest: Load event doesn't fire for removed sheet

      Test timed out
      

  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Single value - empty name exists
  • OK [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/multiple-iframes.https.window.html (#35176)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html (#28691)
    • FAIL [expected PASS] subtest: load event does not fire on window.open('about:blank')

      assert_unreached: load should not be fired Reached unreachable code
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.html (#29056)
    • PASS [expected FAIL] subtest: Cross-origin navigation started from unload handler must be ignored
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
    • PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
  • OK /html/browsers/history/the-history-interface/traverse_the_history_2.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/history/the-history-interface/traverse_the_history_3.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html (#28259)
    • TIMEOUT [expected FAIL] subtest: Autofocus elements in top-level browsing context's documents with empty fragments should work.

      Test timed out
      

  • OK /html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-2.html (#39703)
    • FAIL [expected PASS] subtest: Meta refresh of the original iframe is not blocked if moved into a sandboxed iframe

      uncaught exception: Error: assert_unreached: The iframe into which the meta was moved must not refresh Reached unreachable code
      

  • OK [expected TIMEOUT] /html/semantics/embedded-content/media-elements/preserves-pitch.html (#40352)
    • PASS [expected TIMEOUT] subtest: Speed-ups should not change the pitch when preservesPitch=true
    • PASS [expected NOTRUN] subtest: Slow-downs should not change the pitch when preservesPitch=true
    • FAIL [expected NOTRUN] subtest: Speed-ups should change the pitch when preservesPitch=false

      assert_approx_equals: The actual pitch should be close to the expected pitch. expected 880 +/- 132 but got 431.0850439882698
      

    • FAIL [expected NOTRUN] subtest: Slow-downs should change the pitch when preservesPitch=false

      assert_approx_equals: The actual pitch should be close to the expected pitch. expected 220 +/- 33 but got 431.0850439882698
      

  • TIMEOUT [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigate_other_frame_popup.sub.html (#39702)
    • TIMEOUT [expected FAIL] subtest: Sandboxed iframe can not navigate other frame's popup

      Test timed out
      

  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • FAIL [expected PASS] subtest: multipart/form-data: Basic test (formdata event)

      assert_equals: expected "\r\nContent-Disposition: form-data; name=\"basic\"\r\n\r\ntest\r\n--\r\n" but got ""
      

    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in value (formdata event)
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • FAIL [expected PASS] subtest: text/plain: Basic test (formdata event)

      assert_equals: expected "basic=test\r\n" but got ""
      

    • FAIL [expected PASS] subtest: text/plain: Basic File test (normal form)

      assert_equals: expected "basic=file-test.txt\r\n" but got ""
      

    • PASS [expected FAIL] subtest: text/plain: Basic File test (formdata event)
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • FAIL [expected PASS] subtest: application/x-www-form-urlencoded: Basic File test (normal form)

      assert_equals: expected "basic=file-test.txt" but got ""
      

    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in name (normal form)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in value (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: backslash in name (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: character not in encoding in filename (normal form)
  • CRASH [expected OK] /html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-5.html
  • ERROR [expected OK] /intersection-observer/v2/animated-opacity.html (#40827)
  • PASS [expected FAIL] /png/apng/acTL-plays-one.html (#41218)
  • OK /touch-events/single-tap-when-touchend-listener-use-sync-xhr.html (#41175)
    • PASS [expected FAIL] subtest: Click event should be fired when touchend opens synchronous XHR
  • CRASH [expected OK] /trusted-types/Element-setAttribute-setAttributeNS-sinks.tentative.html
  • CRASH [expected ERROR] /trusted-types/SharedWorker-importScripts.html
  • TIMEOUT /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • TIMEOUT [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.

      Test timed out
      

    • NOTRUN [expected TIMEOUT] subtest: Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • PASS [expected TIMEOUT] subtest: Navigate a window via form-submission with javascript:-urls in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ default policy in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via form-submission with javascript:-urls in enforcing mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in enforcing mode.
  • TIMEOUT /trusted-types/trusted-types-navigation.html?31-35 (#38034)
    • TIMEOUT [expected PASS] subtest: Navigate a frame via form-submission with javascript:-urls in report-only mode.

      Test timed out
      

    • NOTRUN [expected TIMEOUT] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in report-only mode.
  • CRASH [expected TIMEOUT] /uievents/mouse/cancel-mousedown-in-subframe.html
  • CRASH [expected OK] /wasm/webapi/esm-integration/wasm-to-wasm-link-error.tentative.html
  • OK /webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html (#22849)
    • FAIL [expected PASS] subtest: buffer-stitching-2

      assert_approx_equals: Stitched sine‑wave buffers at sample rate 43800 sample[21597] |2.2206448287037324e-24 - 0.12363679707050323| = 0.12363679707050323 > 0.0038986 expected 0.12363679707050323 +/- 0.0038986 but got 2.2206448287037324e-24
      

  • OK /webdriver/tests/classic/dismiss_alert/dismiss.py (#39098)
    • FAIL [expected PASS] subtest: test_dismiss_in_popup_window

      AssertionError: no such alert (404): No user prompt is currently active.
      

  • CRASH [expected OK] /webxr/hit-test/ar_hittest_source_cancel.https.html
  • ERROR [expected OK] /webxr/render_state_update.https.html (#27535)
Stable unexpected results that are known to be intermittent (30)
  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor

      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor

      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.html (#38895)
    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.worker.html (#38971)
    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys

      assert_throws_exactly: throwing getter should rethrow during clone function "() => {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys

      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys

      assert_throws_exactly: throwing getter should rethrow during clone function "() => {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/transaction-deactivation-timing.any.html (#38772)
    • PASS [expected FAIL] subtest: New transactions are deactivated before next task
    • PASS [expected FAIL] subtest: New transactions from microtask are deactivated before next task
  • OK /IndexedDB/transaction-deactivation-timing.any.worker.html (#38808)
    • PASS [expected FAIL] subtest: New transactions are deactivated before next task
    • PASS [expected FAIL] subtest: New transactions from microtask are deactivated before next task
  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo

      Test timed out
      

  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • FAIL [expected PASS] subtest: WebGL test #45

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #47

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #49

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #51

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • PASS [expected FAIL] subtest: WebGL test #53
    • PASS [expected FAIL] subtest: WebGL test #55
    • PASS [expected FAIL] subtest: WebGL test #57
    • PASS [expected FAIL] subtest: WebGL test #59
    • FAIL [expected PASS] subtest: WebGL test #61

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #63

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • And 6 more unexpected results...
  • OK /css/css-cascade/layer-font-face-override.html (#35935)
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 1
  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(fangsong)
    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(nastaliq)

      assert_equals: quoted generic(nastaliq) matches  @font-face rule expected 50 but got 30
      

  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted cursive (drawing text in a canvas)
    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted fantasy (drawing text in a canvas)

      assert_equals: quoted fantasy matches  @font-face rule expected 125 but got 40
      

    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted system-ui (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-monospace (drawing text in a canvas)
  • OK /css/cssom-view/offsetTopLeft-border-box.html (#40826)
    • PASS [expected FAIL] subtest: container: 0
    • PASS [expected FAIL] subtest: container: 1
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • FAIL [expected PASS] subtest: sec-fetch-mode

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-dest
    • FAIL [expected PASS] subtest: sec-fetch-user

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-origin destination
  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • CRASH [expected OK] /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
  • TIMEOUT /html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy.https.sub.html (#41404)
    • TIMEOUT [expected PASS] subtest: Feature-Policy header: autoplay * allows same-origin iframes.

      Test timed out
      

  • TIMEOUT /html/semantics/embedded-content/media-elements/autoplay-default-feature-policy.https.sub.html (#41193)
    • TIMEOUT [expected PASS] subtest: Default "autoplay" feature policy ["self"] allows same-origin iframes.

      Test timed out
      

  • TIMEOUT /html/semantics/embedded-content/media-elements/autoplay-disabled-by-feature-policy.https.sub.html (#41221)
    • TIMEOUT [expected FAIL] subtest: Feature-Policy header: autoplay "none" disallows same-origin iframes.

      Test timed out
      

  • OK /html/semantics/embedded-content/media-elements/media_fragment_seek.html (#24114)
    • FAIL [expected PASS] subtest: Video should seek to time specified in media fragment syntax

      assert_equals: expected 3 but got 0
      

  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • FAIL [expected PASS] subtest: print() during unload

      assert_array_equals: expected property 1 to be "destination" but got "error: window.print is not a function" (expected array ["start", "destination"] got ["start", "error: window.print is not a function"])
      

  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domComplete > Original domComplete
    • PASS [expected FAIL] subtest: Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventEnd > Original loadEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventStart > Original loadEventStart
  • TIMEOUT /resource-timing/test_resource_timing.https.html (#25216)
    • FAIL [expected PASS] subtest: PerformanceEntry has correct name, initiatorType, startTime, and duration (img)

      assert_equals: expected 6.509999999999998 but got 6.5
      

  • TIMEOUT [expected OK] /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • TIMEOUT [expected PASS] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.

      Test timed out
      

    • NOTRUN [expected PASS] subtest: Navigate a window via anchor with javascript:-urls w/ default policy in report-only mode.
    • NOTRUN [expected PASS] subtest: Navigate a frame via anchor with javascript:-urls in enforcing mode.
  • OK [expected TIMEOUT] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • PASS [expected TIMEOUT] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe
Stable unexpected results (17)
  • OK [expected TIMEOUT] /css/css-overflow/overflow-clip-margin-intersection-observer.html
    • FAIL [expected TIMEOUT] subtest: ParentWithOverflowClipMargin

      assert_true: expected true got false
      

  • OK /intersection-observer/fixed-position-iframe-scroll.html
    • PASS [expected FAIL] subtest: scrollTo(0, 1000)
  • OK /intersection-observer/iframe-no-root-with-wrapping-scroller.html
    • PASS [expected FAIL] subtest: First rAF.
    • PASS [expected FAIL] subtest: iframe.contentDocument.scrollingElement.scrollTop = 250
    • PASS [expected FAIL] subtest: document.scrollingElement.scrollTop = 100
  • OK /intersection-observer/iframe-no-root.html
    • PASS [expected FAIL] subtest: First rAF.
    • PASS [expected FAIL] subtest: iframe.contentDocument.scrollingElement.scrollTop = 250
    • PASS [expected FAIL] subtest: document.scrollingElement.scrollTop = 100
  • OK /intersection-observer/scroll-margin-4-val.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin-dynamic.html
    • PASS [expected FAIL] subtest: Test no initial scroll margin intersection
  • OK /intersection-observer/scroll-margin-horizontal.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin-nested-2.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin-nested-3.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin-nested.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin-no-intersect.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin-propagation.html
    • PASS [expected FAIL] subtest: Scroll margin is applied to iframe 2, because it's same-origin-domain with iframe 3
  • OK /intersection-observer/scroll-margin-with-border-outline.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin-zero.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/scroll-margin.html
    • PASS [expected FAIL] subtest: Test scroll margin intersection
  • OK /intersection-observer/timestamp.html
    • PASS [expected FAIL] subtest: Generate notifications.
  • OK /intersection-observer/v2/position-absolute-overflow-visible-and-not-visible.html
    • FAIL [expected PASS] subtest: ParentWithOverflowVisibleAndNotVisible

      assert_equals: expected 1 but got 0
      

@github-actions

Copy link
Copy Markdown

⚠️ Try run (#21423105665) failed!

@stevennovaryo stevennovaryo force-pushed the descendant-of-query branch 4 times, most recently from 5f63e0f to a3c9828 Compare March 25, 2026 09:30
@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

🤖 Opened new upstream WPT pull request (web-platform-tests/wpt#58738) with upstreamable changes.

Comment on lines +886 to +889
// Total offsets gained from traversing through multiple navigables. We use this to map the coordinate space.
// TODO: We should store the product sum of transformation matrices instead. But this should be enough to handle
// scrolling, simple translation, and offset from containing block.
let mut total_inter_document_offset = Vector2D::zero();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation is considered to avoid bloating the PR. Adding a mapping of coordinate spaces query would require much more changes in the code.

@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#58738).

@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

✍ Updated existing upstream WPT pull request (web-platform-tests/wpt#58738) title and body.

@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#58738).

@stevennovaryo

Copy link
Copy Markdown
Member Author

This should be ready for a review! My main concern is about the performance degradation, but theoretically, we are just implementing the correct steps of the algorithm.

cc: @mrobinson @jdm @Loirooriol please let me know if you have some suggestion. Particularly if we want to split or include other part of the implementation in the PR. Cheers!

@stevennovaryo stevennovaryo marked this pull request as ready for review March 25, 2026 10:05
@servo-highfive servo-highfive removed the S-needs-rebase There are merge conflict errors. label Mar 25, 2026
@stevennovaryo stevennovaryo requested a review from jdm March 25, 2026 10:05
Comment on lines +1 to +3
[position-absolute-overflow-visible-and-not-visible.html]
[ParentWithOverflowVisibleAndNotVisible]
expected: FAIL

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These fails happens because we doesn't consider two axis independently, I have added a TODO about this.

@xiaochengh xiaochengh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good in general!

Comment thread components/script/dom/node.rs Outdated
Comment thread components/layout/query.rs
Comment thread components/layout/query.rs Outdated
Comment thread components/script/dom/intersectionobserver.rs Outdated
Comment thread components/script/dom/intersectionobserver.rs Outdated
Comment thread components/script/dom/intersectionobserver.rs Outdated
Comment thread components/script/dom/intersectionobserver.rs Outdated
Comment thread components/script/dom/intersectionobserver.rs Outdated
Comment thread components/script/dom/intersectionobserver.rs Outdated
@servo-highfive servo-highfive added S-needs-rebase There are merge conflict errors. and removed S-needs-rebase There are merge conflict errors. labels Apr 1, 2026
@stevennovaryo

stevennovaryo commented Apr 15, 2026

Copy link
Copy Markdown
Member Author

Looks good! Sorry for the long delay.

Thanks! Updated the WPTs, seems that I missed the WPTs after getting back to the issue. 😓
That aside since we are not supposed to pass the WPTs, since IntersectionObserver haven't consider the overflow-clip-margin yet.

@jdm

jdm commented Apr 15, 2026

Copy link
Copy Markdown
Member

Oof, yet another merge conflict.

@jdm jdm added S-needs-rebase There are merge conflict errors. and removed S-awaiting-review There is new code that needs to be reviewed. labels Apr 15, 2026
jdm and others added 8 commits April 16, 2026 11:30
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-rebase There are merge conflict errors. labels Apr 16, 2026
@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#58738).

Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#58738).

@xiaochengh

Copy link
Copy Markdown
Contributor

Please let us know when this is ready for merge, or there are substantial changes to be further reviewed. Thanks!

@stevennovaryo

Copy link
Copy Markdown
Member Author

Please let us know when this is ready for merge, or there are substantial changes to be further reviewed. Thanks!

I have nothing else to add for now. If there are no concer, we could proceed so that we could add IntersectionObserver enhancement incrementally. Thanks!

@xiaochengh xiaochengh added this pull request to the merge queue Apr 16, 2026
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Apr 16, 2026
Merged via the queue into servo:main with commit 02ba2ea Apr 16, 2026
30 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Apr 16, 2026
@servo-wpt-sync

Copy link
Copy Markdown
Collaborator

⛔ Failed to properly merge the upstream pull request (web-platform-tests/wpt#58738). Please address any CI issues and try to merge manually.

@stevennovaryo

stevennovaryo commented Apr 16, 2026

Copy link
Copy Markdown
Member Author
image Seems that CI failed in WPT repo due to connection issues. Might be affected by https://status.canonical.com/#/incident/KNms6QK9ewuzz-7xUsPsNylV20jEt5kyKsd8A-3ptQG-0Dp5D6IWR-Dw5G2pjG-aXrj_4QfzB2lRNFJhfuReyQ==

@stevennovaryo stevennovaryo deleted the descendant-of-query branch April 21, 2026 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-awaiting-review There is new code that needs to be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants