Skip to content

Conversation

@stevennovaryo
Copy link
Contributor

@stevennovaryo stevennovaryo commented Nov 6, 2025

Currently when we call a Focus we always scroll a focusable element to the center of the container. However, this would causes a different behavior where UAs wouldn't scroll when a focus is called to a visible element. This PR add implementations following the behavior of Firefox nsFocusManager::ScrollIntoView, where we are scrolling to the element if it is not visible.

This would enhance the user experience of focusing an input element, where we should avoid moving the element if it is visible.

Incidentally fix a calculation bug for the calculation of ScrollIntoView with nearest block or inline option.

Testing: Private WPT for the implementation defined behavior and public WPT for the bug.

@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Nov 6, 2025
@stevennovaryo stevennovaryo force-pushed the not-visible-element branch 2 times, most recently from aa9f596 to f382e2b Compare November 6, 2025 08:41
@stevennovaryo stevennovaryo added the T-linux-wpt Do a try run of the WPT label Nov 6, 2025
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Nov 6, 2025
@github-actions
Copy link

github-actions bot commented Nov 6, 2025

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

@github-actions
Copy link

github-actions bot commented Nov 6, 2025

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

Flaky unexpected result (42)
  • OK /IndexedDB/idbfactory_open.any.html
    • FAIL [expected PASS] subtest: Calling open() with version argument 1.5 should not throw.

      assert_equals: version expected 1 but got 9007199254740991
      

  • CRASH [expected PASS] /_mozilla/shadow-dom/move-element-with-ua-shadow-tree-crash.html (#39473)
  • OK /_mozilla/webxr/create_session.https.html
    • FAIL [expected PASS] subtest: create_session

      can't access property "simulateDeviceConnection", navigator.xr.test is undefined
      

  • CRASH [expected OK] /_webgl/conformance/glsl/implicit/multiply_int_vec3.vert.html
  • CRASH [expected OK] /_webgl/conformance/ogles/GL/cross/cross_001_to_002.html
  • CRASH [expected OK] /_webgl/conformance/ogles/GL/degrees/degrees_001_to_006.html
  • CRASH [expected OK] /_webgl/conformance/ogles/GL/refract/refract_001_to_006.html
  • CRASH [expected OK] /_webgl/conformance/renderbuffers/renderbuffer-initialization.html
  • CRASH [expected ERROR] /_webgl/conformance/rendering/clear-default-framebuffer-with-scissor-test.html
  • CRASH [expected OK] /_webgl/conformance/rendering/draw-elements-out-of-bounds.html
  • CRASH [expected ERROR] /_webgl/conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html
  • CRASH [expected OK] /_webgl/conformance/textures/misc/texture-upload-cube-maps.html
  • CRASH [expected OK] /_webgl/conformance2/attribs/gl-vertex-attrib-i-render.html
  • CRASH [expected OK] /_webgl/conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html
  • CRASH [expected OK] /_webgl/conformance2/wasm/readpixels-2gb-in-4gb-wasm-memory.html
  • OK /content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html (#36468)
    • PASS [expected FAIL] subtest: A 'frame-ancestors' CSP directive with a URL that includes a path should be ignored.
  • OK /cookiestore/cookieStore_getAll_set_creation_url.https.any.html
    • FAIL [expected PASS] subtest: cookieStore.set and cookieStore.getAll use the creation url

      assert_equals: expected 1 but got 2
      

  • CRASH [expected OK] /cookiestore/idlharness.https.any.worker.html
  • FAIL [expected PASS] /css/css-backgrounds/background-size-042.html
  • OK /css/css-cascade/layer-cssom-order-reverse.html (#36094)
    • FAIL [expected PASS] subtest: Delete layer invalidates @font-face

      assert_equals: expected "220px" but got "133px"
      

  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(fangsong)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(kai)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(khmer-mul)
  • CRASH [expected OK] /css/css-shadow-parts/double-forward.html
  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Null value should submit nothing
    • PASS [expected FAIL] subtest: setFormValue with an empty FormData should submit nothing
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in name (urlencoded)
  • OK /fetch/fetch-later/permissions-policy/deferred-fetch-allowed-by-permissions-policy.https.window.html
    • FAIL [expected PASS] subtest: Permissions policy header: "deferred-fetch=*" allows fetchLater() in the top-level document.

      assert_equals: Number of sent beacons does not match expected count: expected 1 but got 0
      

  • 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."
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • FAIL [expected PASS] subtest: Link with onclick navigation and href navigation

      assert_equals: expected "href" but got "click"
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html (#28681)
    • FAIL [expected PASS] subtest: load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank'

      assert_unreached: load should not be fired Reached unreachable code
      

  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • FAIL [expected PASS] subtest: opener of discarded auxiliary browsing context

      assert_object_equals: property "get" expected function "function opener() {
          [native code]
      }" got function "function opener() {
          [native code]
      }"
      

  • CRASH [expected OK] /html/canvas/element/color-type/2d.color.type.u8p3.to.f16srgb.to.u8p3.html
  • TIMEOUT [expected OK] /html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)
    • TIMEOUT [expected PASS] subtest: HTMLMediaElement.srcObject blob

      Test timed out
      

  • OK /html/semantics/forms/form-submission-0/jsurl-form-submit.tentative.html (#36489)
    • PASS [expected FAIL] subtest: Verifies that form submissions scheduled inside javascript: urls take precedence over the javascript: url's return value.
  • OK [expected CRASH] /html/semantics/forms/the-fieldset-element/disabled-003.html (#31730, #39631)
  • OK /html/semantics/scripting-1/the-script-element/execution-timing/077.html (#22139)
    • FAIL [expected PASS] subtest: adding several types of scripts through the DOM and removing some of them confuses scheduler

      assert_array_equals: expected property 1 to be "Script #1 ran" but got "Script #3 ran" (expected array ["Script #2 ran", "Script #1 ran", "Script #3 ran", "Script #4 ran"] got ["Script #2 ran", "Script #3 ran", "Script #4 ran", "Script #1 ran"])
      

  • OK [expected ERROR] /html/user-activation/no-activation-thru-escape-key.html (#40343)
  • OK /preload/prefetch-document.html (#37210)
    • FAIL [expected PASS] subtest: different-site document prefetch with 'as=document' should not be consumed

      assert_equals: expected 2 but got 1
      

  • OK /preload/preload-xhr.html (#39092)
    • FAIL [expected PASS] subtest: Make an XHR request immediately after creating link rel=preload.

      assert_equals: resources/dummy.xml?token=5efedbaf-6e5b-451c-a61c-86228d3be45e expected 1 but got 0
      

  • CRASH [expected OK] /trusted-types/block-string-assignment-to-DedicatedWorker-setTimeout-setInterval.html
  • CRASH [expected OK] /uievents/idlharness.window.html
  • CRASH [expected ERROR] /wasm/webapi/empty-body.any.serviceworker.html
  • ERROR [expected OK] /workers/baseurl/alpha/import-in-moduleworker.html (#21315)
  • ERROR [expected OK] /workers/baseurl/alpha/sharedworker-in-worker.html (#21315)
Stable unexpected results that are known to be intermittent (27)
  • 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/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"
      

  • 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 /_mozilla/mozilla/FileAPI/file-upload.html (#40348)
    • FAIL [expected PASS] subtest: form submission of uploaded file

      assert_equals: expected "OK" but got "\n\n\n\n\n    var fileInput = document.getElementById(\"file-input\");\n    fileInput.addEventListener(\"change\", () => {\n      parent.postMessage(\"loadedAndFilesChanged\");\n    });\n    fileInput.selectFiles([\"./tests/wpt/mozilla/tests/mozilla/FileAPI/resource/upload.txt\"]);\n\n"
      

  • 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 /css/css-cascade/layer-font-face-override.html (#35935)
    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 1

      assert_equals: expected "80px" but got "38.3166666666667px"
      

    • FAIL [expected PASS] subtest: @font-face override update with appended sheet 2

      assert_equals: expected "80px" but got "38.3166666666667px"
      

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

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

    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted sans-serif (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted cursive (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted fantasy (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted monospace (drawing text in a canvas)
    • 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 math (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(fangsong) (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(kai) (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(khmer-mul) (drawing text in a canvas)
    • And 5 more unexpected results...
  • OK /custom-elements/form-associated/form-disabled-callback.html (#38843)
    • PASS [expected FAIL] subtest: A disabled form-associated custom element should not submit an entry for it
  • FAIL [expected TIMEOUT] /dom/xslt/large-cdata.html (#38029)
  • 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-site destination
    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy cross-site destination
  • TIMEOUT [expected CRASH] /fetch/metadata/window-open.https.sub.html (#40339)
  • OK [expected ERROR] /focus/focus-event-after-switching-iframes.sub.html (#40368)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/008.html (#24456)
    • FAIL [expected PASS] subtest: Link with onclick form submit to javascript url and href navigation

      assert_equals: expected "href" but got "click"
      

  • TIMEOUT /html/browsers/history/the-history-interface/001.html (#12580)
    • FAIL [expected PASS] subtest: traversing history must also traverse hash changes

      assert_equals: (this could cause other failures later on) expected "" but got "test"
      

  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent.html (#28259)
    • TIMEOUT [expected FAIL] subtest: Autofocus elements in top-level browsing context's documents with non-existent fragments should work.

      Test timed out
      

  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • PASS [expected FAIL] subtest: multipart/form-data: Basic test (normal form)
    • PASS [expected FAIL] subtest: multipart/form-data: Basic test (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in value (normal form)
    • PASS [expected FAIL] subtest: multipart/form-data: backslash in name (normal form)
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • PASS [expected FAIL] subtest: text/plain: Basic test (normal form)
    • PASS [expected FAIL] subtest: text/plain: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in name (normal form)
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: Basic test (normal form)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: Basic test (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in value (normal form)
  • OK /html/semantics/forms/historical.html (#28568)
    • PASS [expected FAIL] subtest: <input name=isindex> should not be supported
  • TIMEOUT [expected ERROR] /html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html (#40347)
  • OK /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • FAIL [expected PASS] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

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

      Test timed out
      

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

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in enforcing mode.
    • NOTRUN [expected FAIL] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in report-only mode.
    • NOTRUN [expected FAIL] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy making the URL invalid in enforcing mode.
  • OK [expected ERROR] /webxr/render_state_update.https.html (#27535)
Stable unexpected results (2)
  • PASS [expected FAIL] /focus/focus-large-element-in-overflow-hidden-container.html
  • OK /html/interaction/focus/processing-model/textarea-scroll-selection.html
    • FAIL [expected PASS] subtest: programatic focus() scrolls selection into view including ancestors

      assert_not_equals: Should've scrolled ancestor to show the selection got disallowed value 0
      

@github-actions
Copy link

github-actions bot commented Nov 6, 2025

⚠️ Try run (#19129788987) failed.

@stevennovaryo
Copy link
Contributor Author

stevennovaryo commented Nov 6, 2025

Test /html/interaction/focus/processing-model/textarea-scroll-selection.html fails because we doesn't scroll the input boxes based on the selection/caret. We will need to implement a function to get the bounding rectangle of the selection first to table this.

Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
@stevennovaryo
Copy link
Contributor Author

Updated the WPT result, and tracking issues for selection ScrollIntoView (#40474).

@stevennovaryo stevennovaryo requested a review from jdm November 7, 2025 06:45
Comment on lines +1450 to +1459
// We are following the firefox implementation where we are only scrolling to the element
// if the element itself it not visible.
let scroll_axis = ScrollAxisState {
position: ScrollLogicalPosition::Center,
requirement: ScrollRequirement::IfNotVisible,
};

// TODO(stevennovaryo): we doesn't differentiate focus operation from script and from user
// for a scroll yet.
// TODO(#40474): Implement specific ScrollIntoView for a selection of text control element.
Copy link
Member

Choose a reason for hiding this comment

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

Instead of making all the conceptual changes to scroll_into_view_with_options, would it be possible to first just check if the element is already visible and not call scroll_into_view_with_options?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be possible, if we are still maintaining the behavior where we just compare the clip rectangle of scroll container ancestor to it's target element, I think we might end-up iterating the same element with the same queries. I would be glad to hear about the concern for this behavior. For now we are following the Mozilla's behavior for this one.

Copy link
Member

Choose a reason for hiding this comment

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

What do you mean by iterating the same element with the same queries? Running this query twice shouldn't be a problem, as the translation will be cached the first time and the second time it will be a single matrix multiplication. I think this will greatly simplify the change if you wouldn't mind just doing that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand the idea. I just want to checkout that we have considered a same concern.

I just afraid that we will duplicate a lot of codes in the iteration and the calculation the dimension of container and it's target rectangle, not to mention that the scroll_into_view_with_options is not complete (e.g. no writing modes). Additionally, we would also have slight difference in how it would behave compared to Firefox, but I am not sure this would be relevant.

Copy link
Member

Choose a reason for hiding this comment

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

Can't you just calculate the result of getBoundingClientRect(), check to see if it is fully enclosed by the viewport, and, if so, return early?

Copy link
Contributor Author

@stevennovaryo stevennovaryo Nov 18, 2025

Choose a reason for hiding this comment

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

I am not sure that the desirable way to check the visibility is to only check for the viewport. Following the behavior of ScrollIntoView, that iterates through the scroll container, checking whether a element is visible relative to each scroll container that contains its should be more reasonable.

Copy link
Member

@yezhizhen yezhizhen Nov 20, 2025

Choose a reason for hiding this comment

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

Instead of making all the conceptual changes to scroll_into_view_with_options, would it be possible to first just check if the element is already visible and not call scroll_into_view_with_options?

I kinda agree. Because we sometimes we want to scroll_into_view_with_options without caring about whether the target is visible or not.

Copy link
Member

@yezhizhen yezhizhen Nov 21, 2025

Choose a reason for hiding this comment

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

This should be ok. As we pass the check-visibility-or-not flag to scroll_into_view_with_options now.

@yezhizhen yezhizhen self-requested a review November 20, 2025 03:39
Copy link
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

This is nice. But I'm curious about the motivation of the change, if this is implementation defined.

// box start edge and scrolling box end edge or an invalid situation: Do nothing.
else {
current_scroll_offset
0.
Copy link
Member

Choose a reason for hiding this comment

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

I suppose this fixes a bug not mentioned?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added in PR description and a WPT test for the bug.

ScrollRequirement::IfNotVisible => {
// Because the element_start and element_end have taken into account the scroll_offset, the
// viewport_start and viewport_end should have the root coordinate space.
let viewport_start = 0.;
Copy link
Member

Choose a reason for hiding this comment

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

Is the container always Viewport? Would it be possible that this is Element?

Copy link
Contributor Author

@stevennovaryo stevennovaryo Nov 25, 2025

Choose a reason for hiding this comment

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

This is quite not descriptive for me as well. I have changed it to be a scrollport for now. Let me know if there is a better suggestion.

Comment on lines +1450 to +1459
// We are following the firefox implementation where we are only scrolling to the element
// if the element itself it not visible.
let scroll_axis = ScrollAxisState {
position: ScrollLogicalPosition::Center,
requirement: ScrollRequirement::IfNotVisible,
};

// TODO(stevennovaryo): we doesn't differentiate focus operation from script and from user
// for a scroll yet.
// TODO(#40474): Implement specific ScrollIntoView for a selection of text control element.
Copy link
Member

@yezhizhen yezhizhen Nov 20, 2025

Choose a reason for hiding this comment

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

Instead of making all the conceptual changes to scroll_into_view_with_options, would it be possible to first just check if the element is already visible and not call scroll_into_view_with_options?

I kinda agree. Because we sometimes we want to scroll_into_view_with_options without caring about whether the target is visible or not.

@servo-wpt-sync
Copy link
Collaborator

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

@servo-wpt-sync
Copy link
Collaborator

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

Copy link
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

Testing: Private WPT since this is implementation defined.

In the end, we added a new public WPT as well :)

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Nov 26, 2025
<!DOCTYPE html>
<html>
<head>
<title>scrollIntoView called on the descendant of shadow host with a slot should treat the slot as a pontential scroll container</title>
Copy link
Member

Choose a reason for hiding this comment

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

Btw we should change the title here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I have changed the title and updated the description.

@servo-wpt-sync
Copy link
Collaborator

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

@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Nov 27, 2025
@servo-wpt-sync
Copy link
Collaborator

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

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<title>scrollIntoView nearest shouldn't scroll a completely visible element</title>

Typo.

@servo-wpt-sync
Copy link
Collaborator

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

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

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

@yezhizhen yezhizhen enabled auto-merge November 28, 2025 01:52
@yezhizhen yezhizhen added this pull request to the merge queue Nov 28, 2025
@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 Nov 28, 2025
Merged via the queue into servo:main with commit e05e973 Nov 28, 2025
29 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 Nov 28, 2025
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