Add OpaqueRange interface#1404
Conversation
dandclark
left a comment
There was a problem hiding this comment.
Great to see a spec for this coming together!
|
FWIW, I'd rather extend |
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 |
dandclark
left a comment
There was a problem hiding this comment.
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.
| <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 |
There was a problem hiding this comment.
(this, too, will likely need to be something that we'll need to put in the HTML spec)
@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 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. |
| interface OpaqueRange : AbstractRange { | ||
| DOMRectList getClientRects(); | ||
| DOMRect getBoundingClientRect(); | ||
| }; |
There was a problem hiding this comment.
Is there a reason why OpaqueRange offsets are readonly? Or there isn't any method to update them?
There was a problem hiding this comment.
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----
There was a problem hiding this comment.
I think we actually don't want to expose the offsets as per my other comment. I'm not sure if we want to expose collapsed. Perhaps it should just be separate from AbstractRange.
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}
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}
…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
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
| <dfn export id=concept-range-end-offset for=range>end offset</dfn> is its <a for=range>end</a>'s | ||
| <a for="boundary point">offset</a>. | ||
|
|
||
| <p>A <a>range</a> has an associated <dfn export for=range id=concept-range-is-opaque>is opaque</dfn> |
There was a problem hiding this comment.
associated boolean*
We don't want flags anymore.
| flag, initially false. When true, the {{AbstractRange/startContainer}} and | ||
| {{AbstractRange/endContainer}} getters return null. Only {{OpaqueRange}} objects have this flag set | ||
| to true. |
There was a problem hiding this comment.
This second bit should probably be in a note.
| interface AbstractRange { | ||
| readonly attribute Node startContainer; | ||
| readonly attribute Node? startContainer; | ||
| readonly attribute unsigned long startOffset; |
There was a problem hiding this comment.
Does it make sense to expose startOffset and endOffset if this range potentially spans multiple nodes? They will not have meaningful values I think for opaque ranges.
| </pre> | ||
|
|
||
| <p>Objects implementing the {{OpaqueRange}} interface are known as {{OpaqueRange}} objects. | ||
| {{OpaqueRange}} objects cannot be constructed directly; they are created by specifications defining |
There was a problem hiding this comment.
I thought we would have a constructor so people can create these for custom elements?
| interface OpaqueRange : AbstractRange { | ||
| DOMRectList getClientRects(); | ||
| DOMRect getBoundingClientRect(); | ||
| }; |
There was a problem hiding this comment.
I think we actually don't want to expose the offsets as per my other comment. I'm not sure if we want to expose collapsed. Perhaps it should just be separate from AbstractRange.
|
|
||
| <p>An {{OpaqueRange}} has an | ||
| <dfn export for=OpaqueRange>associated element</dfn> (an {{Element}} or null), initially null. It is | ||
| set by the specification that creates the {{OpaqueRange}}. |
There was a problem hiding this comment.
Why do we need this and disconnect()? Can't that be with the APIs that vend OpaqueRange objects? It's also a bit unclear what disconnecting means beyond that, maybe in part because this doesn't actually integrate with the tree mutation algorithms yet.
|
|
||
| <p>An {{Element}} | ||
| <dfn export id=supports-opaque-range>supports opaque ranges</dfn> if its specification defines that | ||
| it does. In HTML, this includes certain {{HTMLInputElement}} types and {{HTMLTextAreaElement}}. |
There was a problem hiding this comment.
I'm not sure why we need this concept.
|
|
||
| <p class=note>Other specifications can designate additional elements, including custom elements. | ||
|
|
||
| <p>An {{OpaqueRange}} is live, meaning its offsets are automatically updated when the underlying |
There was a problem hiding this comment.
I think we should define this very differently. We should define opaque ranges the same way we define live ranges. And then in HTML we should say that these elements have some kind of underlying Text node that this opaque range "exposes".
The reason for that is because we want opaque ranges to be a generic container. And the way you have specified them they are still very much restricted to specific elements.
|
It also seems this needs some rebasing. |
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}
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 sostartContainer/endContainerare nullable (Node?), which allows OpaqueRange to return null for those getters while Range/StaticRange continue returning nodes.Explainer: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/OpaqueRange/explainer.md
WHATWG Discussion: OpaqueRange Interface html#11478
Corresponding HTML Spec PR: Integrate OpaqueRange hooks into text controls (input/textarea) html#11741
Corresponding CSSOM PRs:
At least two implementers are interested (and none opposed):
Tests are written and can be reviewed and commented upon at:
Implementation bugs are filed:
MDN issue is filed: …
The top of this comment includes a clear commit message to use.
(See WHATWG Working Mode: Changes for more details.)
Preview | Diff