Skip to content

layout: Lay out Shadow DOM elements#34701

Merged
mrobinson merged 1 commit intoservo:mainfrom
mrobinson:layout-shadow-dom
Dec 19, 2024
Merged

layout: Lay out Shadow DOM elements#34701
mrobinson merged 1 commit intoservo:mainfrom
mrobinson:layout-shadow-dom

Conversation

@mrobinson
Copy link
Copy Markdown
Member

When an element is a shadow root, lay out the shadow root elements
instead of the non-shadow children.

This fixes some tests and introduces some failures, due to bugs in the
Shadow DOM implementation. In general, this is very low impact as the
Shadow DOM is still disabled by default. At least this gets elements
rendering when the preference is turned on though.

Signed-off-by: Martin Robinson [email protected]


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • There are tests for these changes

When an element is a shadow root, lay out the shadow root elements
instead of the non-shadow children.

This fixes some tests and introduces some failures, due to bugs in the
Shadow DOM implementation. In general, this is very low impact as the
Shadow DOM is still disabled by default. At least this gets elements
rendering when the preference is turned on though.

Signed-off-by: Martin Robinson <[email protected]>
@mrobinson mrobinson added the T-linux-wpt Do a try run of the WPT label Dec 19, 2024
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Dec 19, 2024
@github-actions
Copy link
Copy Markdown

🔨 Triggering try run (#12413802559) for Linux WPT

@github-actions
Copy link
Copy Markdown

Test results for linux-wpt-layout-2020 from try job (#12413802559):

Flaky unexpected result (21)
  • TIMEOUT [expected OK] /_webgl/conformance/glsl/misc/shader-uniform-packing-restrictions.html (#28103)
  • TIMEOUT [expected OK] /_webgl/conformance/reading/read-pixels-test.html
  • TIMEOUT [expected OK] /_webgl/conformance/uniforms/out-of-bounds-uniform-array-access.html (#26225)
    • NOTRUN [expected PASS] subtest: Overall test
  • TIMEOUT [expected OK] /_webgl/conformance2/textures/misc/immutable-tex-render-feedback.html
  • FAIL [expected PASS] /css/css-conditional/container-queries/container-for-cue.html (#34528)
  • TIMEOUT [expected OK] /css/css-flexbox/abspos/position-absolute-013.html
  • OK /css/css-values/cap-invalidation.html (#32757)
    • FAIL [expected PASS] subtest: CSS Values and Units Test: cap invalidation

      uncaught exception: Error: assert_not_equals: expect the capital height of Ahem and sans-serif to be different got disallowed value 371.3333333333333
      

  • TIMEOUT [expected OK] /custom-elements/reactions/customized-builtins/HTMLMediaElement.html (#31014)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html (#28066)
    • FAIL [expected PASS] subtest: 0041 set in href="" targeting a frame and clicked

      assert_equals: expected "A" but got ""
      

    • FAIL [expected PASS] subtest: 0080 00FF set in href="" targeting a frame and clicked

      assert_equals: expected "�ÿ" but got ""
      

    • FAIL [expected PASS] subtest: 0080 00FF 0100 set in href="" targeting a frame and clicked

      assert_equals: expected "�ÿĀ" but got ""
      

    • FAIL [expected PASS] subtest: D83D DE0D set in href="" targeting a frame and clicked

      assert_equals: expected "😍" but got ""
      

    • FAIL [expected PASS] subtest: DE0D 0041 set in href="" targeting a frame and clicked

      assert_equals: expected "\ufffdA" but got ""
      

  • 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
  • TIMEOUT [expected OK] /html/browsers/history/the-location-interface/assign-replace-from-iframe.html (#31638)
    • TIMEOUT [expected PASS] subtest: Browser sends Referer header in iframe request when location.replace is called from an iframe

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: Browser sends Referer header in iframe request when location.assign is called from an iframe

      Test timed out
      

  • TIMEOUT [expected OK] /html/browsers/origin/cross-origin-objects/cross-origin-objects.html (#28569)
  • OK /html/browsers/windows/browsing-context-names/duplicate-name-order.html (#34623)
    • FAIL [expected PASS] subtest: Duplicate name lookup order

      assert_equals: subtree first expected "ChildA" but got "PopupA"
      

  • TIMEOUT [expected ERROR] /html/canvas/element/manual/imagebitmap/createImageBitmap-serializable.html (#34120)
  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-replace.html (#32604)
    • FAIL [expected PASS] subtest: Navigating iframe loading='lazy' before it is loaded: location.replace

      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?nav" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
      

  • OK [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html (#24066)
    • FAIL [expected NOTRUN] subtest: Check that popups from a sandboxed iframe do not escape the sandbox

      assert_equals: It came from a sandboxed iframe expected "null" but got "http://web-platform.test:8000"
      

  • OK [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html (#24066)
    • FAIL [expected NOTRUN] subtest: Check that popups from a sandboxed iframe do not escape the sandbox

      assert_equals: It came from a sandboxed iframe expected "null" but got "http://web-platform.test:8000"
      

  • OK /html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html (#26243)
    • FAIL [expected PASS] subtest: document.write in an imported module

      assert_true: onload must be called expected true got false
      

  • OK /html/webappapis/dynamic-markup-insertion/document-write/module-tla-delayed.html (#29137)
    • FAIL [expected PASS] subtest: document.write in an imported module

      assert_true: onload must be called expected true got false
      

  • OK [expected ERROR] /workers/constructors/Worker/Worker-constructor.html (#22991)
  • OK /xhr/open-url-multi-window-5.htm (#23360)
    • FAIL [expected PASS] subtest: XMLHttpRequest: open() resolving URLs (multi-Window; 5)

      assert_throws_dom: function "function() {client.open("GET", "...") }" did not throw
      

Stable unexpected results that are known to be intermittent (11)
  • FAIL [expected PASS] /_mozilla/css/dirty_viewport.html (#13731)
  • FAIL [expected PASS] /_mozilla/css/iframe/hide_and_show.html (#15265)
  • 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
  • OK [expected TIMEOUT] /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html (#29048)
    • FAIL [expected PASS] subtest: Navigating to a different document with location.href

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?1" but got "about:blank"
      

    • PASS [expected FAIL] subtest: Navigating to a different document with link click
    • FAIL [expected TIMEOUT] subtest: Navigating to a different document with form submission

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?1=" but got "about:blank"
      

  • OK [expected TIMEOUT] /html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html (#21581)
    • PASS [expected TIMEOUT] subtest: Traverse the history when a history entry is written in the load event
  • TIMEOUT [expected OK] /html/semantics/document-metadata/the-base-element/base_target_does_not_affect_location_assignment.html (#32615)
    • TIMEOUT [expected PASS] subtest: base_target_does_not_affect_location_assignment

      Test timed out
      

  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-form-submit.html (#32607)
    • FAIL [expected PASS] subtest: Navigating iframe loading='lazy' before it is loaded: form submit

      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
      

  • TIMEOUT /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html (#22667)
    • TIMEOUT [expected FAIL] subtest: Check that popups from a sandboxed iframe escape the sandbox if allow-popups-to-escape-sandbox is used

      Test timed out
      

  • OK /html/webappapis/update-rendering/child-document-raf-order.html (#33028)
    • PASS [expected FAIL] subtest: Ordering of steps in "Update the Rendering" - child document requestAnimationFrame order
  • OK /resize-observer/eventloop.html (#33599)
    • PASS [expected FAIL] subtest: test1: depths of shadow roots
  • 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

@github-actions
Copy link
Copy Markdown

✨ Try run (#12413802559) succeeded.

@mrobinson mrobinson added this pull request to the merge queue Dec 19, 2024
Merged via the queue into servo:main with commit 50c9c72 Dec 19, 2024
@mrobinson mrobinson deleted the layout-shadow-dom branch December 19, 2024 20:49
simonwuelker added a commit to simonwuelker/servo that referenced this pull request Jan 28, 2025
There is some interesting history to this change:

* servo#33495: Servo crashes on
  Cloudflare's turnstile, because we didn't compute style for
  elements inside shadow trees
* servo#34298: Resolves the issue
  by computing style for children of a potential shadow root,
  in addition to the children of an element
* servo#34701: Changes layout
  of elements with shadow roots such that only the contents
  of the shadow root are laid out

Now, we compute style for both the children of the element
and a potential shadow root, but only lay out the contents
of the shadow tree (if there is one).

This behaviour is not technically incorrect,
since regular children are not included in layout
their style doesn't matter. However, it is
inefficient: the only case where we need to compute
style for a child of a shadow host is when
that child is an assigned slottable in a slot
somewhere else.

This part 1/n of upstreaming the changes necessary
to lay out <slot> contents. Note that trying to compute
style for <slot> contents *and* children of shadow hosts
will crash in stylo, since it expects to see each
element only once.

Signed-off-by: Simon Wülker <[email protected]>
simonwuelker added a commit to simonwuelker/servo that referenced this pull request Jan 28, 2025
There is some interesting history to this change:

* servo#33495: Servo crashes on
  Cloudflare's turnstile, because we didn't compute style for
  elements inside shadow trees
* servo#34298: Resolves the issue
  by computing style for children of a potential shadow root,
  in addition to the children of an element
* servo#34701: Changes layout
  of elements with shadow roots such that only the contents
  of the shadow root are laid out

Now, we compute style for both the children of the element
and a potential shadow root, but only lay out the contents
of the shadow tree (if there is one).

This behaviour is not technically incorrect,
since regular children are not included in layout
their style doesn't matter. However, it is
inefficient: the only case where we need to compute
style for a child of a shadow host is when
that child is an assigned slottable in a slot
somewhere else.

This part 1/n of upstreaming the changes necessary
to lay out <slot> contents. Note that trying to compute
style for <slot> contents *and* children of shadow hosts
will crash in stylo, since it expects to see each
element only once.

Signed-off-by: Simon Wülker <[email protected]>
simonwuelker added a commit to simonwuelker/servo that referenced this pull request Jan 28, 2025
There is some interesting history to this change:

* servo#33495: Servo crashes on
  Cloudflare's turnstile, because we didn't compute style for
  elements inside shadow trees
* servo#34298: Resolves the issue
  by computing style for children of a potential shadow root,
  in addition to the children of an element
* servo#34701: Changes layout
  of elements with shadow roots such that only the contents
  of the shadow root are laid out

Now, we compute style for both the children of the element
and a potential shadow root, but only lay out the contents
of the shadow tree (if there is one).

This behaviour is not technically incorrect,
since regular children are not included in layout
their style doesn't matter. However, it is
inefficient: the only case where we need to compute
style for a child of a shadow host is when
that child is an assigned slottable in a slot
somewhere else.

This part 1/n of upstreaming the changes necessary
to lay out `<slot>` contents. Note that trying to compute
style for `<slot>` contents *and* children of shadow hosts
will crash in stylo, since it expects to see each
element only once.

Signed-off-by: Simon Wülker <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Jan 28, 2025
There is some interesting history to this change:

* #33495: Servo crashes on
  Cloudflare's turnstile, because we didn't compute style for
  elements inside shadow trees
* #34298: Resolves the issue
  by computing style for children of a potential shadow root,
  in addition to the children of an element
* #34701: Changes layout
  of elements with shadow roots such that only the contents
  of the shadow root are laid out

Now, we compute style for both the children of the element
and a potential shadow root, but only lay out the contents
of the shadow tree (if there is one).

This behaviour is not technically incorrect,
since regular children are not included in layout
their style doesn't matter. However, it is
inefficient: the only case where we need to compute
style for a child of a shadow host is when
that child is an assigned slottable in a slot
somewhere else.

This part 1/n of upstreaming the changes necessary
to lay out `<slot>` contents. Note that trying to compute
style for `<slot>` contents *and* children of shadow hosts
will crash in stylo, since it expects to see each
element only once.

Signed-off-by: Simon Wülker <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants