Skip to content

script: Implement Origin API#41712

Merged
TimvdLippe merged 1 commit intoservo:mainfrom
WaterWhisperer:origin-api
Jan 8, 2026
Merged

script: Implement Origin API#41712
TimvdLippe merged 1 commit intoservo:mainfrom
WaterWhisperer:origin-api

Conversation

@WaterWhisperer
Copy link
Copy Markdown
Contributor

Testing: ./mach test-wpt /html/browsers/origin/api/
Fixes: #41106

@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Jan 6, 2026
Copy link
Copy Markdown
Contributor

@TimvdLippe TimvdLippe left a comment

Choose a reason for hiding this comment

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

Nice work! This mostly looks good, but we are missing the concept of the Platform Object. If you implement that, I expect almost all tests to pass.

@servo-highfive servo-highfive added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Jan 6, 2026
@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Jan 7, 2026
Copy link
Copy Markdown
Contributor

@TimvdLippe TimvdLippe left a comment

Choose a reason for hiding this comment

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

Only some nits, we are almost there. Test results look a lot better already.

return None;
}

if let Ok(area_obj) = root_from_handlevalue::<HTMLAreaElement>(value, cx) {
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.

Instead of HTMLAreaElement, did you try to use HTMLHyperlinkElementUtils instead? That's what the spec uses and I would have thought that would have worked. If it doesn't, then the current approach is (unfortunately) the way to go.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's not a real interface, just a mixin:

interface mixin HTMLHyperlinkElementUtils {
. The Rust type is just a trait that we implement for certain DOM types.

Copy link
Copy Markdown
Contributor Author

@WaterWhisperer WaterWhisperer Jan 8, 2026

Choose a reason for hiding this comment

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

I remember I tried HTMLHyperlinkElementUtils at first but it failed, so I changed it to HTMLAreaElement

@servo-highfive servo-highfive added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Jan 7, 2026
@TimvdLippe TimvdLippe added the T-linux-wpt Do a try run of the WPT label Jan 7, 2026
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Jan 7, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 7, 2026

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

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 7, 2026

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

Flaky unexpected result (33)
  • OK /_mozilla/webxr/obtain_frame.https.html
    • FAIL [expected PASS] subtest: obtain_frame

      promise_test: Unhandled rejection with value: object "TypeError: can't access property "simulateDeviceConnection", navigator.xr.test is undefined"
      

  • OK [expected TIMEOUT] /_webgl/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html (#39735)
    • PASS [expected NOTRUN] subtest: Overall test
    • PASS [expected FAIL] subtest: WebGL test #0
  • 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.
  • TIMEOUT /content-security-policy/inheritance/location-reload.html (#38983)
    • FAIL [expected PASS] subtest: location.reload() of empty iframe.

      assert_equals: Image should be blocked by CSP after reload. expected "img blocked" but got "img loaded"
      

  • FAIL [expected PASS] /css/css-backgrounds/background-size-041.html
  • TIMEOUT [expected PASS] /css/css-namespaces/syntax-007.xml
  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Null value should submit nothing
    • PASS [expected FAIL] subtest: Newline normalization - \r\n in name (urlencoded)
  • OK [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/sandboxed-iframe.https.window.html (#41704)
  • CRASH [expected OK] /html/browsers/browsing-the-web/navigating-across-documents/014.html
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html (#28691)
    • PASS [expected FAIL] subtest: load event does not fire on window.open('about:blank')
  • 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_5.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • CRASH [expected OK] /html/browsers/history/the-location-interface/location-prototype-setting-same-origin.html
  • CRASH [expected TIMEOUT] /html/canvas/offscreen/text/2d.text.measure.strokeTextCluster-align.tentative.w.html
  • 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 /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 [expected TIMEOUT] /html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)
    • PASS [expected TIMEOUT] subtest: HTMLMediaElement.srcObject blob
  • 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 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/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 /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • PASS [expected FAIL] subtest: multipart/form-data: \r\n in value (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: double quote 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)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in value (formdata event)
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • FAIL [expected PASS] subtest: application/x-www-form-urlencoded: Basic test (formdata event)

      assert_equals: expected "basic=test" but got ""
      

    • 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: single quote in filename (formdata event)
  • ERROR [expected TIMEOUT] /html/semantics/forms/form-submission-target/rel-base-target.html (#40379)
  • CRASH [expected OK] /html/webappapis/system-state-and-capabilities/the-navigator-object/secure_context.html
  • FAIL [expected PASS] /png/apng/acTL-plays-one.html (#41218)
  • ERROR [expected OK] /resource-timing/cors-preflight.any.html (#28694)
  • CRASH [expected ERROR] /trusted-types/SharedWorker-importScripts.html
  • CRASH [expected TIMEOUT] /trusted-types/should-trusted-type-policy-creation-be-blocked-by-csp-002.html
  • TIMEOUT /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected FAIL] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.
  • CRASH [expected OK] /upgrade-insecure-requests/gen/sharedworker-classic-data.meta/upgrade/xhr.https.html
  • CRASH [expected ERROR] /wasm/webapi/empty-body.any.serviceworker.html
  • CRASH [expected TIMEOUT] /wasm/webapi/invalid-code.any.worker.html
Stable unexpected results that are known to be intermittent (28)
  • 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 "() =&gt; {
            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 "() =&gt; {
            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 "() =&gt; {
            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 "() =&gt; {
            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.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 #77

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

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

      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 #81

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

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

      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 #85
    • PASS [expected FAIL] subtest: WebGL test #87
    • PASS [expected FAIL] subtest: WebGL test #89
    • PASS [expected FAIL] subtest: WebGL test #91
  • OK /css/css-cascade/layer-cssom-order-reverse.html (#36094)
    • PASS [expected FAIL] subtest: Delete layer invalidates @font-face
  • 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)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-monospace (drawing text in a canvas)
  • 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
  • CRASH [expected OK] /fetch/metadata/generated/element-iframe.https.sub.html (#40341)
  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • FAIL [expected NOTRUN] subtest: Host element with delegatesFocus should support autofocus

      assert_equals: expected Element node &lt;div autofocus=""&gt;&lt;/div&gt; but got Element node &lt;body&gt;&lt;div autofocus=""&gt;&lt;/div&gt;&lt;/body&gt;
      

    • FAIL [expected NOTRUN] subtest: Host element with delegatesFocus including no focusable descendants should be skipped

      assert_equals: expected Element node &lt;input autofocus=""&gt;&lt;/input&gt; but got Element node &lt;body&gt;&lt;/body&gt;
      

    • FAIL [expected NOTRUN] subtest: Area element should support autofocus

      assert_equals: expected Element node &lt;area autofocus="" href="/common/blank.html"&gt;&lt;/area&gt; but got Element node &lt;body&gt;
      &lt;img src="/media/poster.png" usemap="#map"&gt;
      &lt;map n...
      

  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/update-the-rendering.html (#24145)
    • FAIL [expected TIMEOUT] subtest: "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks

      assert_array_equals: animationFrame lengths differ, expected array ["autofocus", "scroll", "animationFrame"] length 3, got ["animationFrame"] length 1
      

  • OK /html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html (#39694)
    • PASS [expected FAIL] subtest: Meta refresh is blocked by the allow-scripts sandbox flag at its creation time, not when refresh comes due
  • TIMEOUT /html/semantics/embedded-content/media-elements/autoplay-allowed-by-feature-policy.https.sub.html (#41404)
    • PASS [expected TIMEOUT] subtest: Feature-Policy header: autoplay * allows the top-level document.
  • 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 /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • PASS [expected FAIL] subtest: print() during unload
  • OK /preload/preload-error.sub.html (#37177)
    • PASS [expected FAIL] subtest: 404 (image): main
    • FAIL [expected PASS] subtest: 404 (style): main

      assert_unreached: Should have rejected: undefined Reached unreachable code
      

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

      assert_unreached: Should have rejected: undefined Reached unreachable code
      

    • PASS [expected FAIL] subtest: CORS (fetch): main
  • CRASH [expected OK] /resource-timing/render-blocking-status-link.html (#41664)
  • TIMEOUT /resource-timing/test_resource_timing.html (#25720)
    • PASS [expected FAIL] subtest: window.performance.getEntriesByName() and window.performance.getEntriesByNameType() return same data (xmlhttprequest)
  • TIMEOUT /resource-timing/test_resource_timing.https.html (#25216)
    • PASS [expected FAIL] subtest: window.performance.getEntriesByName() and window.performance.getEntriesByNameType() return same data (xmlhttprequest)
    • PASS [expected FAIL] subtest: PerformanceEntry has correct name, initiatorType, startTime, and duration (xmlhttprequest)
  • 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
Stable unexpected results (4)
  • OK /_mozilla/mozilla/interfaces.https.html
    • FAIL [expected PASS] subtest: Interfaces exposed on the window

      assert_true: If this is failing: DANGER, are you sure you want to expose the new interface Origin to all webpages as a property on the global? expected true got false
      

  • OK /_mozilla/mozilla/interfaces.worker.html
    • FAIL [expected PASS] subtest: interfaces

      assert_true: If this is failing: DANGER, are you sure you want to expose the new interface Origin to all webpages as a property on the global? expected true got false
      

  • OK /html/dom/idlharness.any.worker.html
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface object
    • PASS [expected FAIL] subtest: Origin interface object length
    • PASS [expected FAIL] subtest: Origin interface object name
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface prototype object
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface prototype object's "constructor" property
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface prototype object's @@unscopables property
    • PASS [expected FAIL] subtest: Origin interface: operation from(any)
    • PASS [expected FAIL] subtest: Origin interface: attribute opaque
    • PASS [expected FAIL] subtest: Origin interface: operation isSameOrigin(Origin)
    • PASS [expected FAIL] subtest: Origin interface: operation isSameSite(Origin)
    • And 9 more unexpected results...
  • OK /html/dom/idlharness.https.html?exclude=(Document|Window|HTML.+)
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface object
    • PASS [expected FAIL] subtest: Origin interface object length
    • PASS [expected FAIL] subtest: Origin interface object name
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface prototype object
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface prototype object's "constructor" property
    • PASS [expected FAIL] subtest: Origin interface: existence and properties of interface prototype object's @@unscopables property
    • PASS [expected FAIL] subtest: Origin interface: operation from(any)
    • PASS [expected FAIL] subtest: Origin interface: attribute opaque
    • PASS [expected FAIL] subtest: Origin interface: operation isSameOrigin(Origin)
    • PASS [expected FAIL] subtest: Origin interface: operation isSameSite(Origin)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 7, 2026

⚠️ Try run (#20781151196) failed!

@TimvdLippe
Copy link
Copy Markdown
Contributor

OK /_mozilla/mozilla/interfaces.https.html
FAIL [expected PASS] subtest: Interfaces exposed on the window
assert_true: If this is failing: DANGER, are you sure you want to expose the new interface Origin to all webpages as a property on the global? expected true got false

You can safely add them to both of these interfaces tests. The other tests you can also update the test expectations for.

You can use the following command to make that easier:

./mach update-wpt https://github.com/servo/servo/actions/runs/20781151196

Note that you need the GitHub CLI installed to make it run.

@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Jan 8, 2026
Copy link
Copy Markdown
Contributor

@TimvdLippe TimvdLippe left a comment

Choose a reason for hiding this comment

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

One last change regarding the test expectations. The rest LGTM. Thank you!

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Jan 8, 2026
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Jan 8, 2026
Signed-off-by: WaterWhisperer <[email protected]>
Copy link
Copy Markdown
Contributor

@TimvdLippe TimvdLippe left a comment

Choose a reason for hiding this comment

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

Thanks!

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Jan 8, 2026
@TimvdLippe TimvdLippe enabled auto-merge January 8, 2026 15:32
@WaterWhisperer
Copy link
Copy Markdown
Contributor Author

Thanks!

Thanks for your guidance, it was an interesting and enjoyable exploration, and I learned a lot

@TimvdLippe TimvdLippe added this pull request to the merge queue Jan 8, 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 Jan 8, 2026
Merged via the queue into servo:main with commit 56bc26a Jan 8, 2026
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 Jan 8, 2026
@WaterWhisperer WaterWhisperer deleted the origin-api branch January 9, 2026 06:43
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.

Implement Origin API

4 participants