-
Notifications
You must be signed in to change notification settings - Fork 305
Add definition for composed selection range #1342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smaug---- you should review this as well in due course. And @rniwa too I suspect.
54e6984
to
487cac0
Compare
I have opened the draft PR for Selection API to use the definition described here, to help visualize: |
When a live range attached to a document is modified, this change is upstreamed to the FrameSelection. New spec [1] says to only update the composed live range (frame selection)'s start position if setStart is called and only update end position if setEnd is called: whatwg/dom#1342 This is the proposal (B) discussed here: whatwg/dom#772 (comment) To do this, we define enum UpdateSelectionIfAddedToSelection to have three possible update selection behavior: 1. kAll, set selection to have the same start and end as range. --> Default case, when both setStart, setEnd are called. 2. kStartOnly, set selection to have the same start as range only. --> When only setStart is called. 3. kEndOnly, set selection to have the same end as range only. --> When only setEnd is called. We add a WPT test for this new behavior, which only affects the output of getComposedRanges() as it is the only API that accesses the frame selection's endpoints directly. Change-Id: I51ea53fe6156164ba3fbe38b14bc47ff502633b1 Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6188157 Reviewed-by: Siye Liu <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1411209}
When a live range attached to a document is modified, this change is upstreamed to the FrameSelection. New spec [1] says to only update the composed live range (frame selection)'s start position if setStart is called and only update end position if setEnd is called: whatwg/dom#1342 This is the proposal (B) discussed here: whatwg/dom#772 (comment) To do this, we define enum UpdateSelectionIfAddedToSelection to have three possible update selection behavior: 1. kAll, set selection to have the same start and end as range. --> Default case, when both setStart, setEnd are called. 2. kStartOnly, set selection to have the same start as range only. --> When only setStart is called. 3. kEndOnly, set selection to have the same end as range only. --> When only setEnd is called. We add a WPT test for this new behavior, which only affects the output of getComposedRanges() as it is the only API that accesses the frame selection's endpoints directly. Change-Id: I51ea53fe6156164ba3fbe38b14bc47ff502633b1 Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6188157 Reviewed-by: Siye Liu <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1411209}
When a live range attached to a document is modified, this change is upstreamed to the FrameSelection. New spec [1] says to only update the composed live range (frame selection)'s start position if setStart is called and only update end position if setEnd is called: whatwg/dom#1342 This is the proposal (B) discussed here: whatwg/dom#772 (comment) To do this, we define enum UpdateSelectionIfAddedToSelection to have three possible update selection behavior: 1. kAll, set selection to have the same start and end as range. --> Default case, when both setStart, setEnd are called. 2. kStartOnly, set selection to have the same start as range only. --> When only setStart is called. 3. kEndOnly, set selection to have the same end as range only. --> When only setEnd is called. We add a WPT test for this new behavior, which only affects the output of getComposedRanges() as it is the only API that accesses the frame selection's endpoints directly. Change-Id: I51ea53fe6156164ba3fbe38b14bc47ff502633b1 Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6188157 Reviewed-by: Siye Liu <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1411209}
…dateSelectionIfAddedToSelection, a=testonly Automatic update from web-platform-tests Add UpdateSelectionBehavior to Range::UpdateSelectionIfAddedToSelection When a live range attached to a document is modified, this change is upstreamed to the FrameSelection. New spec [1] says to only update the composed live range (frame selection)'s start position if setStart is called and only update end position if setEnd is called: whatwg/dom#1342 This is the proposal (B) discussed here: whatwg/dom#772 (comment) To do this, we define enum UpdateSelectionIfAddedToSelection to have three possible update selection behavior: 1. kAll, set selection to have the same start and end as range. --> Default case, when both setStart, setEnd are called. 2. kStartOnly, set selection to have the same start as range only. --> When only setStart is called. 3. kEndOnly, set selection to have the same end as range only. --> When only setEnd is called. We add a WPT test for this new behavior, which only affects the output of getComposedRanges() as it is the only API that accesses the frame selection's endpoints directly. Change-Id: I51ea53fe6156164ba3fbe38b14bc47ff502633b1 Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6188157 Reviewed-by: Siye Liu <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1411209} -- wpt-commits: e679be39aa83e65a06627a8a5b911648f5312f13 wpt-pr: 50283
…dateSelectionIfAddedToSelection, a=testonly Automatic update from web-platform-tests Add UpdateSelectionBehavior to Range::UpdateSelectionIfAddedToSelection When a live range attached to a document is modified, this change is upstreamed to the FrameSelection. New spec [1] says to only update the composed live range (frame selection)'s start position if setStart is called and only update end position if setEnd is called: whatwg/dom#1342 This is the proposal (B) discussed here: whatwg/dom#772 (comment) To do this, we define enum UpdateSelectionIfAddedToSelection to have three possible update selection behavior: 1. kAll, set selection to have the same start and end as range. --> Default case, when both setStart, setEnd are called. 2. kStartOnly, set selection to have the same start as range only. --> When only setStart is called. 3. kEndOnly, set selection to have the same end as range only. --> When only setEnd is called. We add a WPT test for this new behavior, which only affects the output of getComposedRanges() as it is the only API that accesses the frame selection's endpoints directly. Change-Id: I51ea53fe6156164ba3fbe38b14bc47ff502633b1 Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6188157 Reviewed-by: Siye Liu <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1411209} -- wpt-commits: e679be39aa83e65a06627a8a5b911648f5312f13 wpt-pr: 50283
… start/end algorithm
dom.bs
Outdated
|
||
<p>A <dfn export id=concept-composed-selection-range>composed selection range</dfn> is a | ||
<a>live range</a> that has an associated {{Range}} object, a | ||
<dfn export id=concept-legacy-selection-range for="composed selection range">legacy selection range</dfn>.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, I don't like calling the normal Range as legacy. Nothing really legacy there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not the Range
object that's legacy, it's having to keep around a pretend range for the purposes of the selection API as it was designed pre-shadow-trees that's kinda legacy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but I don't still like it. It is not legacy, in the sense that there would be some better thing to replace it or so (in case of light dom). "Legacy" doesn't explain what the range is for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would you propose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe the legacy selection range
could be same-tree selection range
, and composed selection range
could be composed-tree selection range
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same-tree selection range sounds kinda nice. I personally think "composed selection range" is fine as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Listing the naming options:
- "composed live range" and "cached live range"
- "composed selection range" and "legacy selection range"
- "composed-tree selection range" and "same-tree selection range"
- "composed selection range" and "same-tree selection range"
- "composed selection range" and "selection range"
All these names seem ok to me, I will let the majority decide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on an email conversation I'm a bit less sure what the semantics of this range are. Say you have an element with a shadow root that contains the word "Test". The end user selects "es". getSelection()
should not provide access to this shadow root, but apparently the set of changes proposed here do not enforce that. Or am I misunderstanding something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this PR looks good; I'll let Anne comment on editorial/wrapping stuff, as the wrapping seems odd, but it was odd before the PR anyways. But I want to just highlight two interesting implications of this PR, for implementers like @sefeng211 to weigh in on.
The meat of this PR is the modification to "set the start"/"set the end". There are no semantic changes to legacy live ranges returned by getRangeAt(0)
—the only change is that when "legacy uncomposed range"s are updated, we propagate the changes up to its "composed selection range", maintained by the Selection API. For example, when we "set the start" of a "legacy uncomposed range", we always set its "composed selection range" start too; the same goes for end. That's not too interesting. But there are two interesting implications around collapsing that we should agree on.
-
When we "set the start" of a "legacy uncomposed range" across shadow boundaries, the "legacy uncomposed range" collapses to the new start boundary point—that's all fine as it predates this PR. However, this PR DOES NOT collapse its associated "composed selection range", as long as everything is same-document. This is exercised by this line in the spec. Firefox currently collapses the composed selection range in this case, going against this PR, so we should confirm with @sefeng211 if this PR is acceptable and Firefox can change their behavior. @dizhang168 is working on a WPT for this case now, but you can see an example of this scenario in https://gist.github.com/domfarolino/92d04f5e517da13971f69171476043d0.
-
When we "set the start" of a "legacy uncomposed range" in the same root, but in a way that inverts its start/end, the "legacy uncomposed range" collapses to the new start—that behavior predates this PR too. But per this PR, we ALSO collapse its associated "composed selection range" at the new start boundary point. This is done by this line in the spec. Implications:
// The composed range is not collapsed, but getRangeAt(0) *is* (inside shadow). getSelection().setBaseAndExtent(lightDom, 0, shadowText, 5); // This inverts the legacy uncomposed range, re-collapsing it at offset `10`. // It ALSO collapses the *composed* selection range. getSelection().getRangeAt(0).setStart(shadowText, 10);
All of this is fine to me, but since these are the tricker parts of this PR I just want to highlight them here. @sefeng211 + @annevk, how do Firefox / WebKit feel about these implications? Again, this is not about how getRangeAt(0)
behaves after these options—it's about how changes to that range collapse or do not collapse the composed selection range. If there are strong preferences on either of the two cases here, we'd love to know.
Di changed the PR to use shadow-including root rather than comparing the document, I think we now also collapse the composed selection range which is correct IMO.
This also looks fine to me. |
But shadow-including root will climb up to the document, if the node is connected. So I don't think there's a difference here. I believe the spec does not collapse in this case, because it is basically doing a same-document comparison check. |
Yeah, I mean with this we collapse if one of the nodes is disconnected which is something the PR didn't do before. |
OK, got it. So just to be clear, the behavior of NOT collapsing the composed selection range in the first case I mention is fine with you? I ask only because it looks like Firefox DOES collapse the composed selection range in that case, which I think would fail the incoming WPT being written. |
I think we are on the same page but let me reiterate. You mean that we don't collapse the composed selection range as long as both nodes are connected right? I am fine with this. If Firefox collapses in case then I think it's a Firefox bug... |
Right. The spec collapses the live range (the
Great to know! Yeah Di is adding a test for this in https://crrev.com/c/6354926 to assert the spec behavior, so hopefully that helps. Thanks a lot! |
This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019}
This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019}
This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019}
Hi @domfarolino @sefeng211! I have updated the tests to test out the "set the start/end" algorithm, as discussed in the conversation above. |
This change updates the logic in Range::CollapseIfNeeded to match the spec at whatwg/dom#1342: - If composed range is not null, then: - If range’s start/end node’s shadow-including root is not node’s shadow-including root, or if bp is composed after/before the range’s end/start, set composed range’s end/start to bp. Change-Id: I8ab13e2877f7506bac63f20ae2bb44994d197ed8 Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6387986 Reviewed-by: Mason Freed <[email protected]> Commit-Queue: Di Zhang <[email protected]> Reviewed-by: Dominic Farolino <[email protected]> Cr-Commit-Position: refs/heads/main@{#1438227}
…posedRanges-range-update.html, a=testonly Automatic update from web-platform-tests [selection api] Rewrite Selection-getComposedRanges-range-update.html This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019} -- wpt-commits: a83a40dc55d7f3387b30af0e3421741ce55932fc wpt-pr: 51561
This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019}
…posedRanges-range-update.html, a=testonly Automatic update from web-platform-tests [selection api] Rewrite Selection-getComposedRanges-range-update.html This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019} -- wpt-commits: a83a40dc55d7f3387b30af0e3421741ce55932fc wpt-pr: 51561
Thanks, LGTM! |
…posedRanges-range-update.html, a=testonly Automatic update from web-platform-tests [selection api] Rewrite Selection-getComposedRanges-range-update.html This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019} -- wpt-commits: a83a40dc55d7f3387b30af0e3421741ce55932fc wpt-pr: 51561
…posedRanges-range-update.html, a=testonly Automatic update from web-platform-tests [selection api] Rewrite Selection-getComposedRanges-range-update.html This change reformat the tentative test Selection-getComposedRanges-range-update.html to match the spec at whatwg/dom#1342: 1. If selection is across different roots, getRangeAt(0) should throw INDEX_SIZE_ERR. 2. If a live range sets its end/start to a disconnected node, the live range and the selection are both collapsed. 3. If a live range sets its end/start to cross a shadow boundary such that the range has start before end, collapse the live range, but not the composed selection range. 4. If a live range sets its end/start to cross a shadow boundary such that the range has start after end, collapse both the live range and the composed selection range. We also clean up the other range API tests: selectNode(), collapse, createRange(), addRange(). Change-Id: I03f9309be67b21a781c47d555732a3480322097b Bug: 40286116 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6383722 Reviewed-by: Dominic Farolino <[email protected]> Commit-Queue: Di Zhang <[email protected]> Cr-Commit-Position: refs/heads/main@{#1437019} -- wpt-commits: a83a40dc55d7f3387b30af0e3421741ce55932fc wpt-pr: 51561
As discussed at TPAC 2024, the specification for the new getComposedRanges() API need the introduction of the new definition "Composed live range" [1], which should react to mutations. This PR attempts to define that new concept. Once landed, we will add the spec language that uses composed live range in the Selection API. An overview of the spec changes necessary can be found at [2].
[1] w3c/selection-api#2 (comment)
[2] https://github.com/dizhang168/shadow-dom-selection/blob/main/selection-api-spec-changes.md
01/28/2025 Edit: Changed naming to Composed Selection Range.
(See WHATWG Working Mode: Changes for more details.)
Preview | Diff