Skip to content

script: Use range boundary point position algorithm - #46126

Merged
SimonSapin merged 1 commit into
servo:mainfrom
SimonSapin:range-boundary-point-position
Jul 1, 2026
Merged

SimonSapin merged 1 commit into
servo:mainfrom
SimonSapin:range-boundary-point-position

Conversation

@SimonSapin

@SimonSapin SimonSapin commented Jun 30, 2026

Copy link
Copy Markdown
Member

Some parts of the Selection API spec link to https://dom.spec.whatwg.org/#concept-range-bp-position to define a range boundary point (start or end)’s position as before, equal, or after another boundary point.

Use our existing implementation of this algorithm in abstractrange.rs rather than multiple partial ad-hoc implementations in selection.rs.

Testing: fixes an existing test in WPT

@SimonSapin
SimonSapin requested a review from gterzian as a code owner June 30, 2026 17:59
@SimonSapin SimonSapin added the T-linux-wpt Do a try run of the WPT label Jun 30, 2026
@github-actions github-actions Bot removed the T-linux-wpt Do a try run of the WPT label Jun 30, 2026
@github-actions

Copy link
Copy Markdown

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

@github-actions

Copy link
Copy Markdown

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

Flaky unexpected result (33)
  • ERROR [expected OK] /_mozilla/mozilla/iframe-contentDocument.html
  • TIMEOUT [expected OK] /_webgl/conformance/reading/read-pixels-test.html
  • CRASH [expected OK] /_webgl/conformance/uniforms/no-over-optimization-on-uniform-array-06.html
  • TIMEOUT [expected OK] /_webgl/conformance/uniforms/no-over-optimization-on-uniform-array-09.html
    • NOTRUN [expected PASS] subtest: Overall test
  • CRASH [expected OK] /_webgl/conformance/uniforms/no-over-optimization-on-uniform-array-14.html
  • TIMEOUT [expected OK] /_webgl/conformance2/transform_feedback/transform_feedback.html
    • NOTRUN [expected PASS] subtest: Overall test
  • TIMEOUT [expected OK] /cookies/attributes/domain.sub.html
    • TIMEOUT [expected PASS] subtest: Return cookie with valid domain after domain with single dot ('.') value.

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: Empty domain treated as host cookie 1
    • NOTRUN [expected FAIL] subtest: Empty domain treated as host cookie 2
    • NOTRUN [expected PASS] subtest: Empty domain treated as host cookie 3
    • NOTRUN [expected PASS] subtest: No host cookies returned for host cookies after non-host redirect 1
    • NOTRUN [expected PASS] subtest: No host cookies returned for host cookies after non-host redirect 2
    • NOTRUN [expected PASS] subtest: No host cookies returned for host cookies after non-host redirect 3
  • 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
  • OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
    • FAIL [expected PASS] subtest: Matching font-weight: '399' should prefer '500 501' over '502 510'

      assert_equals: Unexpected font on test element expected 487 but got 532
      

  • FAIL [expected PASS] /css/css-sizing/dynamic-available-size-iframe.html (#45763)
  • PASS [expected FAIL] /css/css-text-decor/text-underline-position-from-font-variable.html (#45615)
  • CRASH [expected ERROR] /css/filter-effects/parsing/flood-opacity-valid.svg
  • TIMEOUT [expected OK] /fetch/content-encoding/br/big-br-body.https.any.html
  • TIMEOUT [expected OK] /fetch/content-encoding/br/big-br-body.https.any.worker.html
    • TIMEOUT [expected PASS] subtest: large br data should be decompressed successfully

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: large br data should be decompressed successfully with byte stream
  • OK [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/sandboxed-iframe.https.window.html (#41704)
  • 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/browsers/browsing-the-web/navigating-across-documents/replace-before-load/form-submit-button-click.html (#44099)
    • FAIL [expected TIMEOUT] subtest: Replace before load, triggered by submitButton.click()

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?thereplacement=" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/resources/code-injector.html?pipe=sub(none)&code=%0A%20%20%20%20const%20form%20%3D%20document.createElement(%22form%22)%3B%0A%20%20%20%20form.action%20%3D%20%22%2Fcommon%2Fblank.html%22%3B%0A%0A%20%20%20%20const%20input%20%3D%20document.createElement(%22input%22)%3B%0A%20%20%20%20input.type%20%3D%20%22hidden%22%3B%0A%20%20%20%20input.name%20%3D%20%22thereplacement%22%3B%0A%20%20%20%20form.append(input)%3B%0A%0A%20%20%20%20const%20button%20%3D%20document.createElement(%22button%22)%3B%0A%20%20%20%20button.type%20%3D%20%22submit%22%3B%0A%20%20%20%20form.append(button)%3B%0A%0A%20%20%20%20document.currentScript.before(form)%3B%0A%20%20%20%20button.click()%3B%0A%20%20"
      

  • 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/history/the-history-interface/traverse_the_history_5.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • TIMEOUT [expected ERROR] /html/browsers/history/the-location-interface/location_replace_session_history.html (#41896)
  • 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]
      }"
      

  • 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
  • TIMEOUT [expected OK] /html/syntax/parsing/html5lib_write.html?file=tests1
    • TIMEOUT [expected PASS] subtest: Test

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <p>One<p>Two

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: Line1<br>Line2<br>Line3<br>Line4

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <html>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <head>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <body>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <html><head>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <html><head></head>

      Test timed out
      

    • NOTRUN [expected PASS] subtest: <html><head></head><body>
    • NOTRUN [expected PASS] subtest: <html><head></head><body></body>
    • And 102 more unexpected results...
  • 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"])
      

  • TIMEOUT [expected OK] /infrastructure/testdriver/click_nested.html (#43887)
    • NOTRUN [expected FAIL] subtest: TestDriver click method with multiple windows and nested iframe
  • ERROR [expected OK] /intersection-observer/v2/animated-opacity.html (#40827)
  • OK /paint-timing/fcp-only/fcp-svg.html (#45878)
    • PASS [expected FAIL] subtest: First contentful paint fires when SVG becomes contentful.
  • OK /preload/preload-resource-match.https.html
    • PASS [expected FAIL] subtest: Loading font (same-origin) with link (same-origin) should reuse the preloaded response
  • OK /resource-timing/buffer-full-add-then-clear.html (#40819)
    • FAIL [expected PASS] subtest: Test that if the buffer is cleared after entries were added to the secondary buffer, those entries make it into the primary one

      assert_equals: Number of entries does not match the expected value. expected 3 but got 0
      

  • CRASH [expected OK] /trusted-types/TrustedTypePolicyFactory-createPolicy-unenforced.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[27457] |0.011629591695964336 - -0.32455745339393616| = 0.3361870450899005 > 0.0038986 expected -0.32455745339393616 +/- 0.0038986 but got 0.011629591695964336
      

  • OK /webdriver/tests/classic/perform_actions/wheel_events.py
    • FAIL [expected PASS] subtest: test_scroll_on_iframe_with_overflow_scroll[delta-x]

      webdriver.error.TimeoutException: timeout (500): Timed out after 0.5 seconds with message: Didn't receive all events: expected at least 1, got 0
      

  • CRASH [expected OK] /webstorage/storage_session_setitem_quotaexceedederr.window.html
Stable unexpected results that are known to be intermittent (22)
  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • PASS [expected FAIL] subtest: WebGL test #45
    • PASS [expected FAIL] subtest: WebGL test #47
    • PASS [expected FAIL] subtest: WebGL test #49
    • PASS [expected FAIL] subtest: WebGL test #51
    • FAIL [expected PASS] subtest: WebGL test #53

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

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

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

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

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

      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 #61
    • PASS [expected FAIL] subtest: WebGL test #63
    • And 30 more unexpected results...
  • OK /beacon/beacon-basic.https.window.html (#41723)
    • FAIL [expected PASS] subtest: Payload size restriction should be accumulated: type = string

      assert_false: expected false got true
      

    • FAIL [expected PASS] subtest: Payload size restriction should be accumulated: type = arraybuffer

      assert_false: expected false got true
      

  • TIMEOUT /content-security-policy/inheritance/auxiliary-blank-document.html (#44821)
    • PASS [expected FAIL] subtest: For transient doc, violation event occurs in auxiliary, not opener window.
  • OK /css/css-animations/animation-iteration-event-001.html (#46004)
    • PASS [expected FAIL] subtest: Got the expected elapsedTime in the correct order
  • TIMEOUT [expected OK] /fetch/api/redirect/redirect-keepalive.https.any.html (#32153)
    • TIMEOUT [expected PASS] subtest: [keepalive][iframe][load] mixed content redirect; setting up

      Test timed out
      

  • ERROR [expected OK] /fetch/fetch-later/quota/same-origin-iframe/accumulated-oversized-payload.https.window.html (#41705)
  • OK [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/multiple-iframes.https.window.html (#35176)
  • TIMEOUT [expected ERROR] /html/browsers/browsing-the-web/history-traversal/pageswap/pageswap-initial-navigation.html (#40387)
  • 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 [expected TIMEOUT] /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/form-requestsubmit.html (#44098)
    • FAIL [expected TIMEOUT] subtest: Replace before load, triggered by formElement.requestSubmit()

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?thereplacement=" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/resources/code-injector.html?pipe=sub(none)&code=%0A%20%20%20%20const%20form%20%3D%20document.createElement(%22form%22)%3B%0A%20%20%20%20form.action%20%3D%20%22%2Fcommon%2Fblank.html%22%3B%0A%0A%20%20%20%20const%20input%20%3D%20document.createElement(%22input%22)%3B%0A%20%20%20%20input.type%20%3D%20%22hidden%22%3B%0A%20%20%20%20input.name%20%3D%20%22thereplacement%22%3B%0A%20%20%20%20form.append(input)%3B%0A%0A%20%20%20%20document.currentScript.before(form)%3B%0A%20%20%20%20form.requestSubmit()%3B%0A%20%20"
      

  • TIMEOUT [expected OK] /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/form-submit.html (#44028)
  • TIMEOUT [expected CRASH] /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 /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • TIMEOUT [expected PASS] subtest: Non-HTMLElement should not support autofocus

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: Host element with delegatesFocus should support autofocus
    • NOTRUN [expected FAIL] subtest: Host element with delegatesFocus including no focusable descendants should be skipped
  • 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
      

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

      Test timed out
      

    • NOTRUN [expected PASS] subtest: Slow-downs should not change the pitch when preservesPitch=true
    • NOTRUN [expected TIMEOUT] subtest: Speed-ups should change the pitch when preservesPitch=false
  • OK [expected TIMEOUT] /html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)
    • PASS [expected TIMEOUT] subtest: HTMLMediaElement.srcObject blob
  • OK /html/semantics/scripting-1/the-script-element/module/choice-of-error-1.html (#44058)
    • FAIL [expected PASS] subtest: Parse errors in different files should be reported depending on different roots

      assert_not_equals: two different parse errors should be reported got disallowed value object "SyntaxError: expected expression, got '%'"
      

  • OK [expected CRASH] /resource-timing/render-blocking-status-link.html (#41664)
    • FAIL [expected PASS] subtest: Validate render blocking status of link resources in PerformanceResourceTiming

      assert_equals: render blocking status for http://web-platform.test:8000/resource-timing/resources/empty_style.css?stylesheet-head should be blocking expected (string) "blocking" but got (undefined) undefined
      

  • OK /touch-events/single-tap-when-touchend-listener-use-sync-xhr.html (#41175)
    • FAIL [expected PASS] subtest: Click event should be fired when touchend opens synchronous XHR

      assert_equals: expected "touchend@div, mousedown@div, mouseup@div, click@div" but got "touchend@div, mousedown@div"
      

  • TIMEOUT [expected OK] /trusted-types/trusted-types-navigation.html?16-20 (#44835)
    • FAIL [expected PASS] subtest: Navigate a frame via area with javascript:-urls in report-only mode.

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

    • TIMEOUT [expected PASS] subtest: Navigate a frame via area with javascript:-urls w/ default policy in report-only mode.

      Test timed out
      

  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?31-35 (#38034)
    • PASS [expected TIMEOUT] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in report-only mode.
    • 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 TIMEOUT] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • FAIL [expected TIMEOUT] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe

      assert_true: about:blank window opened by 3P iframe does not inherit 3P iframe's StorageKey expected true got false
      

Stable unexpected results (1)
  • OK /selection/anonymous/setBaseAndExtent-start-or-end-in-anonymous-shadow-container.html
    • PASS [expected FAIL] subtest: setBaseAndExtent(circle, 0, use, 1) in "<svg><use><circle></circle></use></svg>"

@github-actions

Copy link
Copy Markdown

⚠️ Try run (#28465290909) failed!

(last_offset, first_offset)
} else {
(first_offset, last_offset)
};

@simonwuelker simonwuelker Jul 1, 2026

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.

This is so much nicer than before.

@SimonSapin
SimonSapin force-pushed the range-boundary-point-position branch from 192d701 to d0284a4 Compare July 1, 2026 10:23
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Jul 1, 2026
@SimonSapin
SimonSapin enabled auto-merge July 1, 2026 10:24
@SimonSapin
SimonSapin disabled auto-merge July 1, 2026 10:25
Some parts of the Selection API spec link to
https://dom.spec.whatwg.org/#concept-range-bp-position
to define a range boundary point (start or end)’s position
as before, equal, or after another boundary point.

Use our existing implementation of this algorithm in `abstractrange.rs`
rather than multiple partial ad-hoc implementations in `selection.rs`.

Signed-off-by: Simon Sapin <[email protected]>
@SimonSapin
SimonSapin force-pushed the range-boundary-point-position branch from d0284a4 to e02be1e Compare July 1, 2026 10:27
@SimonSapin
SimonSapin enabled auto-merge July 1, 2026 10:27
@SimonSapin
SimonSapin added this pull request to the merge queue Jul 1, 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 Jul 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 1, 2026
@servo-highfive servo-highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Jul 1, 2026
@SimonSapin
SimonSapin added this pull request to the merge queue Jul 1, 2026
@servo-highfive servo-highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-tests-failed The changes caused existing tests to fail. labels Jul 1, 2026
Merged via the queue into servo:main with commit 794ba56 Jul 1, 2026
37 checks passed
@SimonSapin
SimonSapin deleted the range-boundary-point-position branch July 1, 2026 14:42
@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 Jul 1, 2026
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.

3 participants