From f3f0db7fdaa3b4026001df3a71d94123c84b1283 Mon Sep 17 00:00:00 2001
From: Di Zhang
[=editing hosts=] in the document.
- Each selection can be associated with a single range. + Each selection can be associated with a single + composed live range range. When there is no range associated with the selection, the selection is empty. The selection must be initially empty. @@ -127,6 +128,20 @@
To reset the range of [=this=], given the + boundary point start and boundary point + end, run these steps: +
+Once a selection is associated with a given range, it must continue to be associated with that same range until this @@ -167,13 +182,14 @@
- Each selections also have an anchor and a + Each selection also has an anchor and a focus. If the selection's range is null, its anchor and focus are both null. If the selection's range is not null and its direction is forwards, - its anchor is the range's [=range/start=], and its - focus is the [=range/end=]. Otherwise, its focus is the - [=range/start=] and its anchor is the [=range/end=]. + its anchor is the range's cached live range's + [=range/start=], and its focus is the [=range/end=]. Otherwise, + its focus is the [=range/start=] and its anchor is the + [=range/end=].
anchor and focus of selection need not to be in @@ -320,7 +336,7 @@
0
, or if [=this=] is
empty or either focus or anchor is not in the
[=document tree=]. Otherwise, it must return a reference to (not a
- copy of) [=this=]'s range.
+ copy of) [=this=]'s range's cached live range.
Thus subsequent calls of this method returns the same range @@ -345,8 +361,8 @@
rangeCount
is not 0
, abort these
steps.
@@ -379,8 +395,8 @@
The method must make [=this=] empty by disassociating its - range if [=this=]'s range is range. - Otherwise, it must throw a {{NotFoundError}}. + range if [=this=]'s range's cached live range is + range. Otherwise, it must throw a {{NotFoundError}}.
- The method must throw {{InvalidStateError}} exception if the - [=this=] is empty. Otherwise, it must create a new - range, [=Range/set the start=] both its [=range/start=] and - [=range/end=] to the [=range/start=] of [=this=]'s range, - and then set [=this=]'s range to the newly-created - range. + The method must follow these steps:
+For collapseToStart/End, IE9 mutates the existing range, while Firefox 9.0a2 and Chrome 15 dev replace it with a new one. The spec @@ -518,13 +533,18 @@
- The method must throw {{InvalidStateError}} exception if the - [=this=] is empty. Otherwise, it must create a new - range, [=Range/set the start=] both its [=range/start=] and - [=range/end=] to the [=range/end=] of [=this=]'s range, and - then set [=this=]'s range to the newly-created range. -
++ The method must follow these steps: +
+0
).
- 0
)
+ and (node, childCount).
Each selection can be associated with a single - composed live range range. + composed selection range range. When there is no range associated with the selection, the selection is empty. The selection must be initially empty. @@ -128,19 +128,30 @@
To reset the range of [=this=], given the +
To set the composed selection range of [=this=], given the boundary point start and boundary point end, run these steps:
+ While the above steps might look identical, liveRange and + composedRange could end up in very different states. The + liveRange follows [=Range/set the start=] and + [=Range/set the end=] algorithms, which will collapse in cross-root + cases. On the other hand, composedRange is set directly + without any collapsing logic. +
+Once a selection is associated with a given range, it @@ -186,7 +197,7 @@
0
, or if [=this=] is
empty or either focus or anchor is not in the
[=document tree=]. Otherwise, it must return a reference to (not a
- copy of) [=this=]'s range's cached live range.
+ copy of) [=this=]'s range's legacy selection range.
Thus subsequent calls of this method returns the same range @@ -361,8 +372,8 @@
rangeCount
is not 0
, abort these
steps.
@@ -395,7 +406,7 @@
The method must make [=this=] empty by disassociating its - range if [=this=]'s range's cached live range is + range if [=this=]'s range's legacy selection range is range. Otherwise, it must throw a {{NotFoundError}}.
@@ -542,7 +556,8 @@
0
)
+ 0
)
and (node, childCount).
- While the above steps might look identical, liveRange and +
+ While the steps 2-3 and 4 might look identical, liveRange and composedRange could end up in very different states. The liveRange follows [=Range/set the start=] and [=Range/set the end=] algorithms, which will collapse in cross-root cases. On the other hand, composedRange is set directly without any collapsing logic. -
-
Once a selection is associated with a given range, it
must continue to be associated with that same range until this
From c58cfb16a63f13b4f9916dc7ed5801e7e9636bc9 Mon Sep 17 00:00:00 2001
From: Di Zhang
Each selection can be associated with a single - composed selection range range. - When there is no range associated with the selection, the - selection is empty. The selection must be initially - empty. + composed range composed range, + which will have an associated legacy uncomposed range + uncomposed range. When there is no composed range + associated with the selection, the selection is empty. + The selection must be initially empty.
A document's selection is a singleton object associated @@ -128,23 +129,22 @@
To set the composed selection range of [=this=], given the +
To set the composed range of [=this=], given the boundary point start and boundary point end, run these steps:
- Once a selection is associated with a given range, it - must continue to be associated with that same range until this - specification requires otherwise. + Once a selection is associated with a given + composed range, it must continue to be associated with that same + composed range until this specification requires otherwise.
For instance, if the DOM changes in a way that changes the range's @@ -170,40 +170,41 @@
- If the selection's range is not null and is + If the selection's uncomposed range is not null and is [=range/collapsed=], then the caret position must be at that - range's boundary point. When the selection is not - [=range/collapsed=], this specification does not define the caret - position; user agents should follow platform conventions in deciding - whether the caret is at the start of the selection, the end of - the selection, or somewhere else. + uncomposed range's boundary point. When the + selection is not [=range/collapsed=], this specification does not + define the caret position; user agents should follow platform + conventions in deciding whether the caret is at the start of the + selection, the end of the selection, or somewhere else.
Each selection has a direction: forwards, backwards, or directionless. If the user creates a selection by indicating first one boundary point of the - range and then the other (such as by clicking on one point and - dragging to another), and the first indicated boundary point is - [=boundary point/after=] the second, then the corresponding - selection must initially be backwards. If the first - indicated boundary point is [=boundary point/before=] the - second, then the corresponding selection must initially be - forwards. Otherwise, it must be directionless. + composed range and then the other (such as by clicking on one + point and dragging to another), and the first indicated + boundary point is [=boundary point/after=] the second, then the + corresponding selection must initially be backwards. + If the first indicated boundary point is + [=boundary point/before=] the second, then the corresponding + selection must initially be forwards. + Otherwise, it must be directionless.
- When the selection's range is mutated by scripts, e.g. - via {{Range/selectNode(node)}}, direction of the + When the selection's composed range is mutated by scripts, + e.g. via {{Range/selectNode(node)}}, direction of the selection must be preserved.
Each selection also has an anchor and a - focus. If the selection's range is null, its - anchor and focus are both null. If the selection's - range is not null and its direction is forwards, - its anchor is the range's legacy selection range's - [=range/start=], and its focus is the [=range/end=]. Otherwise, - its focus is the [=range/start=] and its anchor is the - [=range/end=]. + focus. If the selection's uncomposed range is + null, its anchor and focus are both null. If the + selection's uncomposed range is not null and its + direction is forwards, its anchor is the + uncomposed range's [=range/start=], and its focus is the + [=range/end=]. Otherwise, its focus is the [=range/start=] and + its anchor is the [=range/end=].
anchor and focus of selection need not to be in @@ -326,7 +327,7 @@
The attribute must return `"None"` if [=this=] is empty or either focus or anchor is not in the [=document - tree=], `"Caret"` if [=this=]'s range is + tree=], `"Caret"` if [=this=]'s uncomposed range is [=range/collapsed=], and `"Range"` otherwise.
@@ -350,12 +351,13 @@0
, or if [=this=] is
empty or either focus or anchor is not in the
[=document tree=]. Otherwise, it must return a reference to (not a
- copy of) [=this=]'s range's legacy selection range.
+ copy of) [=this=]'s uncomposed range.
- Thus subsequent calls of this method returns the same range
- object if nothing has removed [=this=]'s range in the meantime. In
- particular, getSelection().getRangeAt(0) ===
+ Thus subsequent calls of this method returns the same
+ uncomposed range object if nothing has removed [=this=]'s
+ range in the meantime. In particular,
+
getSelection().getRangeAt(0) ===
getSelection().getRangeAt(0)
evaluates to true
if the selection is not empty.
rangeCount
is not 0
, abort these
steps.
- Since range is added by reference, subsequent calls to
- getRangeAt(0)
returns the same object, and any changes
- that a script makes to range after it is added must be
- reflected in the selection, until something else removes or
- replaces [=this=]'s range. In particular, the
- selection will contain b as opposed to
- a after running the following code: var r =
- document.createRange(); r.selectNode(a);
+ Since uncomposed range is added by reference, subsequent
+ calls to
getRangeAt(0)
returns the same object, and any
+ changes that a script makes to uncomposed range after it is
+ added must be reflected in the selection, until something
+ else removes or replaces [=this=]'s uncomposed range.
+ In particular, the selection will contain b as
+ opposed to a after running the following code:
+ var r = document.createRange(); r.selectNode(a);
getSelection().addRange(r); r.selectNode(b);
At Step 2, Chrome 58 and Edge 25 do nothing. Firefox 51 gives you a multi-range selection. At least they keep the exisiting - range. + uncomposed range.
At Step 3, Chrome 58 and Firefox 51 store a reference, as described here. Edge 25 stores a copy. Firefox 51 changes its - selection if the range is modified. + selection if the uncomposed range is modified.
The method must make [=this=] empty by disassociating its - range if [=this=]'s range's legacy selection range is + composed range if [=this=]'s uncomposed range is range. Otherwise, it must throw a {{NotFoundError}}.
The method must make [=this=] empty by disassociating its - range if [=this=] has an associated range. + composed range if [=this=] has an associated + composed range.
0
)
and (node, childCount).
The method must invoke {{Range/deleteContents()}} on [=this=]'s - range if [=this=] is not empty and both focus - and anchor are in the [=document tree=]. Otherwise the - method must do nothing. + uncomposed range if [=this=] is not empty and + both focus and anchor are in the [=document tree=]. + Otherwise the method must do nothing.
This is the one method that actually mutates the range instead of @@ -792,21 +801,22 @@
Otherwise, if allowPartialContainment is
false
, the method must return true
if and
- only if [=range/start=] of its range is [=boundary
+ only if [=range/start=] of its uncomposed range is [=boundary
point/before=] or visually equivalent to the first boundary
point in the node and [=range/end=]
- of its range is [=boundary point/after=] or visually
- equivalent to the last boundary point in the
+ of its uncomposed range is [=boundary point/after=] or
+ visually equivalent to the last boundary point in the
node.
If allowPartialContainment is true
, the
method must return true
if and only if [=range/start=]
- of its range is [=boundary point/before=] or visually
- equivalent to the last boundary point in the node
- and [=range/end=] of its range is
- [=boundary point/after=] or visually equivalent to the first
- boundary point in the node.
+ of its uncomposed range is [=boundary point/before=] or
+ visually equivalent to the last boundary point in the
+ node and [=range/end=] of its
+ uncomposed range is [=boundary point/after=] or visually
+ equivalent to the first boundary point in the
+ node.
The stringification must return the string, which is the - concatenation of the rendered text if there is a [=range=] - associated with [=this=]. + concatenation of the rendered text if there is a + uncomposed range associated with [=this=].
If the selection is within a textarea or input @@ -856,7 +866,7 @@
All of the members of the {{Selection}} interface are defined in terms
- of operations on the range
object (if any)
+ of operations on the composed range
object (if any)
represented by the object. These operations can raise exceptions, as
defined for the {{Range}} interface; this can therefore result in the
members of the Selection interface raising exceptions as well,
@@ -970,25 +980,26 @@
When the user agent is to [=replace data=] or [=CharacterData/substring data=] on {{CharacterData}}, the user agent must update the - range associated with selection of the [=Node/node - document=] of the {{CharacterData}} as if it's a live range. + composed range and uncomposed range associated with + selection of the [=Node/node document=] of the {{CharacterData}}.
When the user agent is to split a {{Text}} [=node=], the user agent - must update the range associated with selection of the - [=Node/node document=] of the {{Text}} as if it's a live range. + must update the composed range and uncomposed range + associated with selection of the [=Node/node document=] of the + {{Text}}.
When the user agent is to run steps for normalize()
- method, the user agent must update the range associated with
- selection of the [=Node/node document=] of [=this=] as if it's a
- live range.
+ method, the user agent must update the composed range and
+ uncomposed range associated with selection of the
+ [=Node/node document=] of [=this=].
When the user agent is to [=remove=] or [=insert=] a [=node=], the user - agent must update the range associated with selection of - the [=Node/node document=] of the [=node=] as if it's a live - range. + agent must update the composed range and uncomposed range + associated with selection of the [=Node/node document=] of the + [=node=].
The user agent must not make a selection empty if it was @@ -1049,8 +1060,9 @@
selectionchange
event
- When the selection is dissociated with its range, - associated with a new range, or the associated range's + When the selection is dissociated with its composed range, + associated with a new composed range, or the associated + composed range or uncomposed range's boundary point is mutated either by the user or the content script, the user agent must schedule a selectionchange event on document.