Skip to content

Add OpaqueRange interface#1404

Open
stephanieyzhang wants to merge 16 commits intowhatwg:mainfrom
stephanieyzhang:fcr-initial
Open

Add OpaqueRange interface#1404
stephanieyzhang wants to merge 16 commits intowhatwg:mainfrom
stephanieyzhang:fcr-initial

Conversation

@stephanieyzhang
Copy link
Copy Markdown

@stephanieyzhang stephanieyzhang commented Sep 12, 2025

OpaqueRange is a specialized, live AbstractRange subtype whose boundary points reference internal nodes within host-defined elements (e.g., <input>/<textarea> today, with a path to custom elements in the future). It enables range-based operations over encapsulated content while avoiding exposure of internal DOM nodes. This PR also updates AbstractRange so startContainer/endContainer are nullable (Node?), which allows OpaqueRange to return null for those getters while Range/StaticRange continue returning nodes.

(See WHATWG Working Mode: Changes for more details.)


Preview | Diff

@stephanieyzhang stephanieyzhang changed the title initial changes Add FormControlRange interface Sep 23, 2025
Copy link
Copy Markdown
Contributor

@dandclark dandclark left a comment

Choose a reason for hiding this comment

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

Great to see a spec for this coming together!

Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs
@rniwa
Copy link
Copy Markdown

rniwa commented Sep 29, 2025

FWIW, I'd rather extend Range so that it can work with shadow host in general instead of creating a new interface specifically for form controls.

@stephanieyzhang
Copy link
Copy Markdown
Author

FWIW, I'd rather extend Range so that it can work with shadow host in general instead of creating a new interface specifically for form controls.

We explored extending Range, including shadow host support, but found compatibility and encapsulation issues that made it risky to change existing Range semantics. Based on feedback across discussions, we went with a dedicated FormControlRange instead. The trade-offs and alternatives are covered in the explainer.

@rniwa
Copy link
Copy Markdown

rniwa commented Sep 30, 2025

FWIW, I'd rather extend Range so that it can work with shadow host in general instead of creating a new interface specifically for form controls.

We explored extending Range, including shadow host support, but found compatibility and encapsulation issues that made it risky to change existing Range semantics. Based on feedback across discussions, we went with a dedicated FormControlRange instead. The trade-offs and alternatives are covered in the explainer.

Changing the behavior of setStart/setEnd wouldn't be an only way to solve this problem. I'd instead add a new argument or a new function which specifies "offset" within element's shadow tree.

Copy link
Copy Markdown
Contributor

@dandclark dandclark 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 looking good! Next big steps will be defining the right integration points from the HTML spec, and working towards consensus on the API shape.

Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
<a>this</a>'s <a for=FormControlRange>end offset</a> to <var>endOffset</var>.
</ol>

<p>If an {{HTMLInputElement}}'s <code>type</code> changes to a type that does not
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.

(this, too, will likely need to be something that we'll need to put in the HTML spec)

Comment thread dom.bs Outdated
@dandclark
Copy link
Copy Markdown
Contributor

Changing the behavior of setStart/setEnd wouldn't be an only way to solve this problem. I'd instead add a new argument or a new function which specifies "offset" within element's shadow tree.

@rniwa Thanks for the feedback! Yeah, there are a lot of ways this could be done. This suggestion sounds closer to the 2nd considered approach here. There are enough differences in how a Range inside a builtin element would work vs a "normal" range that we believe it will be overall cleaner and less confusing to split the functionality into a different type. For example the behavior we propose here is that a FormControlRange can't have one boundary point inside a <textarea>/<input> and another boundary point outside, which would be a clumsier invariant to express with the Range API surface. Adding this to Range would also add confusion about what things like Range.selectNodeContents should do; should it move the range to select an <input>'s value string, or not? We could add a parameter to all the setter functions to switch the behavior, but again it seems cleaner to relegate the behavior to a different interface vs adding parameters to a bunch of Range functions.

Anyway, whatwg/html#11478 is a better place to have this discussion -- more folks are following that issue vs this draft PR. @stephanieyzhang it might be helpful if you could update the PR description for this to point to that issue, as well as a direct link to the explainer.

@stephanieyzhang stephanieyzhang changed the title Add FormControlRange interface Add PlainTextRange interface Dec 4, 2025
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
Comment thread dom.bs Outdated
@stephanieyzhang stephanieyzhang changed the title Add PlainTextRange interface Add OpaqueRange interface Jan 14, 2026
Comment thread dom.bs
interface OpaqueRange : AbstractRange {
DOMRectList getClientRects();
DOMRect getBoundingClientRect();
};
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.

Is there a reason why OpaqueRange offsets are readonly? Or there isn't any method to update them?

Copy link
Copy Markdown
Author

@stephanieyzhang stephanieyzhang Feb 12, 2026

Choose a reason for hiding this comment

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

The offsets are readonly since they're inherited from AbstractRange. Currently the HTML PR defines createValueRange(start, end) on the element for creation. We haven't yet added an API for updating, so that's an open question. Some options could be an element-side API (e.g. updateValueRange(range, start, end)) to keep OpaqueRange generic, or setters directly on OpaqueRange.

Would appreciate your thoughts @annevk @smaug----

Comment thread dom.bs
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Feb 20, 2026
Implement disconnect() per WHATWG DOM spec PR #1404 [0]. Detaches the
range from its element, stopping live offset updates and zeroing
offsets. Calling it multiple times is safe and has no additional effect.

Adds WPT tests covering disconnect behavior.

Automatic disconnection when the element is removed from the tree or
changes type will be handled in a follow-up CL.

[0] whatwg/dom#1404 (comment)

Low-Coverage-Reason: COVERAGE_UNDERREPORTED
Bug: 421421332
Change-Id: I6f0bb55d57f1eb1876779faad018a19d23b1d665
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7595177
Reviewed-by: Dan Clark <daniec@microsoft.com>
Commit-Queue: Stephanie Zhang <stephanie.zhang@microsoft.com>
Reviewed-by: Ana Sollano Kim <ansollan@microsoft.com>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1588113}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Feb 20, 2026
Implement disconnect() per WHATWG DOM spec PR #1404 [0]. Detaches the
range from its element, stopping live offset updates and zeroing
offsets. Calling it multiple times is safe and has no additional effect.

Adds WPT tests covering disconnect behavior.

Automatic disconnection when the element is removed from the tree or
changes type will be handled in a follow-up CL.

[0] whatwg/dom#1404 (comment)

Low-Coverage-Reason: COVERAGE_UNDERREPORTED
Bug: 421421332
Change-Id: I6f0bb55d57f1eb1876779faad018a19d23b1d665
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7595177
Reviewed-by: Dan Clark <daniec@microsoft.com>
Commit-Queue: Stephanie Zhang <stephanie.zhang@microsoft.com>
Reviewed-by: Ana Sollano Kim <ansollan@microsoft.com>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1588113}
lando-worker Bot pushed a commit to mozilla-firefox/firefox that referenced this pull request Feb 26, 2026
…estonly

Automatic update from web-platform-tests
Add OpaqueRange disconnect() method

Implement disconnect() per WHATWG DOM spec PR #1404 [0]. Detaches the
range from its element, stopping live offset updates and zeroing
offsets. Calling it multiple times is safe and has no additional effect.

Adds WPT tests covering disconnect behavior.

Automatic disconnection when the element is removed from the tree or
changes type will be handled in a follow-up CL.

[0] whatwg/dom#1404 (comment)

Low-Coverage-Reason: COVERAGE_UNDERREPORTED
Bug: 421421332
Change-Id: I6f0bb55d57f1eb1876779faad018a19d23b1d665
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7595177
Reviewed-by: Dan Clark <daniec@microsoft.com>
Commit-Queue: Stephanie Zhang <stephanie.zhang@microsoft.com>
Reviewed-by: Ana Sollano Kim <ansollan@microsoft.com>
Reviewed-by: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1588113}

--

wpt-commits: 60a655bbbf88ba39ae3959de9e405c4284dd0eba
wpt-pr: 57954
@stephanieyzhang stephanieyzhang marked this pull request as ready for review April 23, 2026 16:07
stephanieyzhang and others added 2 commits April 27, 2026 16:57
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants