Skip to content

Conversation

simonwuelker
Copy link
Contributor

Currently the embedding API only provides the embedder with the URL for a favicon. This is not great, for multiple reasons:

  • Loading the icon should happen according to the fetch spec which is not easy for the embedder to recreate (consider CSP, timing information etc)
  • Rasterizing a svg favicon is not trivial

With this change, servo fetches and rasterizes the icon to a bitmap which is then passed to the embedder.

Testing: I'm not sure how I can write tests for the embedding api. I've tested the correctness manually using #36680.
Prepares for #36680

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
@simonwuelker simonwuelker requested a review from gterzian as a code owner August 26, 2025 20:11
@simonwuelker simonwuelker changed the title Pass favicons as a bitmap to the embedder script: Load and rasterize favicons before passing them to the embedder Aug 26, 2025
@simonwuelker simonwuelker force-pushed the load-favicon branch 2 times, most recently from 8b4b9cd to 5ba8cd0 Compare August 26, 2025 20:27
Copy link
Member

@mrobinson mrobinson left a comment

Choose a reason for hiding this comment

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

Nice! I haven't had time to look at the script side part of this, but just had one comment about the API bits. Thanks for following the existing pattern for WebView properties!

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
link: Trusted::new(self),
resource_timing: ResourceFetchTiming::new(ResourceTimingType::Resource),
};
document.fetch_background(request, fetch_context);
Copy link
Contributor

Choose a reason for hiding this comment

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

@jdm jdm added the T-linux-wpt Do a try run of the WPT label Aug 27, 2025
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Aug 27, 2025
Copy link

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

Copy link

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

Flaky unexpected result (25)
  • CRASH [expected TIMEOUT] /IndexedDB/crashtests/create-index.any.html
  • 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
      

  • FAIL [expected PASS] /css/CSS2/margin-padding-clear/margin-collapse-clear-011.xht
  • OK /css/css-cascade/layer-cssom-order-reverse.html (#36094)
    • PASS [expected FAIL] subtest: Delete layer invalidates @font-face
  • FAIL [expected PASS] /css/css-fonts/font-stretch-10.html
  • TIMEOUT [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/max-payload.tentative.https.window.html (#35210)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/008.html (#24456)
    • PASS [expected FAIL] subtest: Link with onclick form submit to javascript url and href navigation
  • 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"
      

  • CRASH [expected OK] /html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html (#29046)
  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • PASS [expected FAIL] subtest: opener of discarded auxiliary browsing context
  • PASS [expected FAIL] /html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html (#30063)
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/update-the-rendering.html (#24145)
    • TIMEOUT [expected FAIL] subtest: "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks

      Test timed out
      

  • OK [expected TIMEOUT] /html/semantics/embedded-content/media-elements/playing-the-media-resource/loop-from-ended.tentative.html (#33778)
    • FAIL [expected TIMEOUT] subtest: play() with loop set to true after playback ended

      this argument is not a finite floating-point value
      

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

      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"
      

  • TIMEOUT [expected CRASH] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html (#22667)
  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • PASS [expected FAIL] subtest: multipart/form-data: Basic test (normal form)
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • PASS [expected FAIL] subtest: text/plain: Basic test (normal form)
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: double quote in filename (formdata event)
  • OK /html/semantics/scripting-1/the-script-element/execution-timing/077.html (#22139)
    • PASS [expected FAIL] subtest: adding several types of scripts through the DOM and removing some of them confuses scheduler
  • FAIL [expected PASS] /png/apng/fcTL-blend-source-solid.html
  • ERROR /service-workers/idlharness.https.any.html (#36250)
    • PASS [expected TIMEOUT] subtest: ServiceWorkerContainer interface: operation register((TrustedScriptURL or USVString), optional RegistrationOptions)
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation enable()
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation disable()
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation setHeaderValue(ByteString)
    • PASS [expected TIMEOUT] subtest: NavigationPreloadManager interface: operation getState()
  • TIMEOUT [expected OK] /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • TIMEOUT [expected FAIL] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in enforcing mode.

      Test timed out
      

  • TIMEOUT [expected OK] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • TIMEOUT [expected PASS] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe

      Test timed out
      

  • ERROR [expected OK] /webxr/render_state_update.https.html (#27535)
  • 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 (19)
  • FAIL [expected PASS] /_mozilla/css/stacked_layers.html (#15988)
  • 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)
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 1
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 2
  • PASS [expected FAIL] /css/css-fonts/downloadable-font-scoped-to-document.html (#38691)
  • TIMEOUT [expected FAIL] /dom/xslt/large-cdata.html (#38029)
  • OK /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 form submission

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

  • OK /html/browsers/browsing-the-web/navigating-across-documents/refresh/same-document-refresh.html (#34597)
    • PASS [expected FAIL] subtest: Same-Document Referrer from Refresh
  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html (#28259)
    • FAIL [expected TIMEOUT] subtest: Autofocus elements in top-level browsing context's documents with empty fragments should work.

      assert_not_equals: got disallowed value Element node &lt;body&gt;&lt;/body&gt;
      

  • TIMEOUT /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • TIMEOUT [expected PASS] subtest: Non-HTMLElement should not support autofocus

      Test timed out
      

  • CRASH [expected OK] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html (#24066)
  • CRASH [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html (#24066)
  • OK [expected CRASH] /html/semantics/forms/the-fieldset-element/disabled-003.html (#31730)
  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • FAIL [expected PASS] subtest: Reload domComplete &gt; Original domComplete

      assert_true: Reload domComplete &gt; Original domComplete expected true got false
      

    • PASS [expected FAIL] subtest: Reload domContentLoadedEventStart &gt; Original domContentLoadedEventStart
    • PASS [expected FAIL] subtest: Reload domInteractive &gt; Original domInteractive
    • PASS [expected FAIL] subtest: Reload fetchStart &gt; Original fetchStart
    • FAIL [expected PASS] subtest: Reload loadEventEnd &gt; Original loadEventEnd

      assert_true: Reload loadEventEnd &gt; Original loadEventEnd expected true got false
      

    • FAIL [expected PASS] subtest: Reload loadEventStart &gt; Original loadEventStart

      assert_true: Reload loadEventStart &gt; Original loadEventStart expected true got false
      

  • 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-error.sub.html (#37177)
    • FAIL [expected PASS] subtest: 404 (style): main

      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.css?pipe=status%28404%29&amp;label=style should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: CORS (style): main
    • PASS [expected FAIL] subtest: 404 (script): main
    • FAIL [expected PASS] subtest: CORS (script): main

      assert_greater_than: http://not-web-platform.test:8000/preload/resources/dummy.js?pipe=header%28Access-Control-Allow-Origin%2C*%29&amp;label=script should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: success (xhr): main
    • FAIL [expected PASS] subtest: 404 (xhr): main

      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?pipe=status%28404%29&amp;label=xhr should be loaded expected a number greater than 0 but got 0
      

    • FAIL [expected PASS] subtest: CORS (xhr): main

      assert_greater_than: http://not-web-platform.test:8000/preload/resources/dummy.xml?pipe=header%28Access-Control-Allow-Origin%2C*%29&amp;label=xhr should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: Decode-error (script): main
  • TIMEOUT [expected CRASH] /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • TIMEOUT [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.

      Test timed out
      

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

      promise_test: Unhandled rejection with value: "Unexpected message received: {\"type\":\"DOMContentLoaded\",\"uri\":\"http://web-platform.test:8000/trusted-types/support/navigation-support.html?form-submission=1&amp;defaultpolicy=replace&amp;frame=1&amp;navigationattempted=1&amp;continue=1\"}"
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in enforcing mode.

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

    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in report-only mode.

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

    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy making the URL invalid in enforcing mode.

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

  • OK [expected ERROR] /workers/constructors/Worker/Worker-constructor.html (#22991)
Stable unexpected results (3)
  • OK [expected TIMEOUT] /content-security-policy/img-src/icon-blocked.sub.html
    • PASS [expected NOTRUN] subtest: Test that spv event is fired
  • OK [expected TIMEOUT] /fetch/metadata/generated/element-link-icon.https.sub.html
    • PASS [expected TIMEOUT] subtest: sec-fetch-site - Same origin no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Cross-site no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Same site no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Same-Origin -&gt; Cross-Site -&gt; Same-Origin redirect no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Same-Origin -&gt; Same-Site -&gt; Same-Origin redirect no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Cross-Site -&gt; Same Origin no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Cross-Site -&gt; Same-Site no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Cross-Site -&gt; Cross-Site no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Same-Origin -&gt; Same Origin no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Same-Origin -&gt; Same-Site no attributes
    • And 12 more unexpected results...
  • OK [expected TIMEOUT] /fetch/metadata/generated/element-link-icon.sub.html
    • PASS [expected TIMEOUT] subtest: sec-fetch-site - Not sent to non-trustworthy same-origin destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Not sent to non-trustworthy same-site destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-site - Not sent to non-trustworthy cross-site destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-mode - Not sent to non-trustworthy same-origin destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-mode - Not sent to non-trustworthy same-site destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-mode - Not sent to non-trustworthy cross-site destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-dest - Not sent to non-trustworthy same-origin destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-dest - Not sent to non-trustworthy same-site destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-dest - Not sent to non-trustworthy cross-site destination no attributes
    • PASS [expected NOTRUN] subtest: sec-fetch-user - Not sent to non-trustworthy same-origin destination no attributes
    • And 8 more unexpected results...

Copy link

⚠️ Try run (#17258343607) failed.

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Copy link
Member

@mrobinson mrobinson left a comment

Choose a reason for hiding this comment

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

Great work!

@simonwuelker simonwuelker added this pull request to the merge queue Aug 27, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 27, 2025
@simonwuelker simonwuelker added this pull request to the merge queue Aug 27, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 27, 2025
@simonwuelker simonwuelker added this pull request to the merge queue Aug 27, 2025
Merged via the queue into servo:main with commit dcd2507 Aug 27, 2025
22 checks passed
@simonwuelker simonwuelker deleted the load-favicon branch August 27, 2025 18:01
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.

4 participants