From bd9b54e8c35d80fa4887ffdad000bd35592bdb6a Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 2 Oct 2025 15:25:22 -0500 Subject: [PATCH 01/16] very rough draft --- source | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 106 insertions(+), 14 deletions(-) diff --git a/source b/source index a92d86863c1..319c2a74f37 100644 --- a/source +++ b/source @@ -50075,18 +50075,22 @@ interface HTMLInputElement : HTMLElement {
  • Invoke the value sanitization algorithm, if one is defined for the type attribute's new state.

  • -
  • Let previouslySelectable be true if setRangeText() previously applied to the element, and false otherwise.

  • +
  • Let previouslySelectable be true if setRangeText() previously applied to the element, and false otherwise.

  • -
  • Let nowSelectable be true if setRangeText() now applies to the element, and false otherwise.

  • +
  • Let nowSelectable be true if setRangeText() now applies to the element, and false otherwise.

  • -
  • If previouslySelectable is false and nowSelectable is true, set the - element's text entry cursor position to the - beginning of the text control, and set its selection - direction to "none".

  • +
  • If previouslySelectable is true and nowSelectable is false, then for + each FormControlRange whose control is this element, set its + control to null and set both its start offset and end offset to 0.

  • + +
  • If previouslySelectable is false and nowSelectable is true, set the + element's text entry cursor position to the + beginning of the text control, and set its selection + direction to "none".

  • @@ -54799,6 +54803,12 @@ You cannot submit this form when the field is incorrect.
  • Invoke the value sanitization algorithm, if the element's type attribute's current state defines one.

  • +
  • If the element's value is different from + oldValue, then run adjust form-control + ranges for this element, given a change offset of 0, a deleted length of the + length of oldValue, and an inserted length of the length + of the element's current value.

  • +
  • If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the element has a text entry cursor position, @@ -54807,6 +54817,13 @@ You cannot submit this form when the field is incorrect. direction">resetting the selection direction to "none".

  • + +

    Integration with FormControlRange:

    +

    After setting the new value, run + adjust form-control ranges for this control. Treat the + entire old value as deleted and the entire new value as inserted, so that all associated ranges + update according to the rules in that section.

    +
    default @@ -57830,8 +57847,13 @@ interface HTMLTextAreaElement : HTMLElement {
  • Set this element's raw value to the new value.

  • -
  • Set this element's dirty value flag to - true.

  • +
  • Set this element's dirty value flag to + true.

  • + +
  • Run adjust form-control ranges for this element, + given a change offset of 0, a deleted length of the length of + oldAPIValue, and an inserted length of the length of this element's new + API value.

  • If the new API value is different from oldAPIValue, then move the text entry @@ -57841,6 +57863,12 @@ interface HTMLTextAreaElement : HTMLElement { +

    Integration with FormControlRange:

    +

    After setting the new value, run + adjust form-control ranges for this control. Treat the + entire old value as deleted and the entire new value as inserted, so that all associated ranges + update according to the rules in that section.

    +

    The textLength IDL attribute must return the @@ -61687,7 +61715,12 @@ MIT Room 32-G524

    -

    APIs for the text control selections

    +

    APIs for the text control selections

    + +

    + Text-entry controls support FormControlRange. Liveness is maintained by HTML's + form-control range adjustment algorithm, and the algorithms + in this section invoke it whenever they modify a control's value string.

    @@ -62137,7 +62170,13 @@ MIT Room 32-G524
  • Let new length be the length of the value of the first argument.

  • -
  • Let new end be the sum of start and new length.

  • +
  • Let new end be the sum of start and new length.

  • + +
  • Let deleted count be max(0, end minus start).

  • + +
  • Run adjust form-control ranges for this element, + given start as the change offset, deleted count as the deleted length, and + new length as the inserted length.

  • Run the appropriate set of substeps from the following list:

    @@ -62247,6 +62286,59 @@ control.setSelectionRange(oldStart + prefix.length, oldEnd + prefix.length, oldD +
    Form control range liveness
    + + + + +

    Some DOM APIs expose FormControlRange objects whose boundary points are defined over the + UTF-16 code units of a text control's value string rather than over the node tree. HTML is + responsible for keeping those ranges live when a control's value changes.

    + +
    Adjusting form-control ranges for a value change
    + +
    +

    To adjust form-control ranges for a control + |control| given a change offset, a deleted length, and an inserted length, run these steps:

    + +
      +
    1. For each FormControlRange |r| such that |r|’s + control is |control|, update each boundary (start and end) using + these plain rules:

      +
        +
      • Before the change: if the boundary comes before where the edit begins, leave it as + is.

      • +
      • Inside the removed or replaced text: if the boundary is at the edit point or falls + anywhere within the text that was removed or replaced (including exactly at its end), move + it to the edit point.

      • +
      • After the change: if the boundary comes after the edited text, move it left or right + to account for the overall change in length — insertions move it to the right, deletions + move it to the left, by the corresponding amount.

      • +
      +
    2. +
    3. Clamp both boundaries so they do not go past the end of the new value.

    4. +
    5. If the start ends up after the end, collapse the range by setting the end to match the + start.

    6. +
    +
    + +
    Where adjustments are invoked
    +

    Whenever a text control's value changes, user agents must run + adjust form-control ranges for that control. This occurs + (including but not limited to) for:

    +
      +
    • User typing, deletion, and paste that produce an input event.

    • +
    • The setRangeText() method.

    • +
    • Setting value or value (including form reset, + autofill, drag-and-drop text insertion, and undo/redo that mutate the control's value).

    • +
    + +

    If an input element's type is changed to a state that does not + support the selection APIs (see selection + applicability), then for each FormControlRange whose + control is that element, set its control to + null and set both its start offset and end offset to 0.

    +

    Constraints

    From accbe23052f355d9ebb10c13b333feff282f6acf Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 2 Oct 2025 15:41:31 -0500 Subject: [PATCH 02/16] undo whitespace --- source | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/source b/source index 319c2a74f37..63e341daa29 100644 --- a/source +++ b/source @@ -50075,22 +50075,18 @@ interface HTMLInputElement : HTMLElement {
  • Invoke the value sanitization algorithm, if one is defined for the type attribute's new state.

  • -
  • Let previouslySelectable be true if setRangeText() previously applied to the element, and false otherwise.

  • +
  • Let previouslySelectable be true if setRangeText() previously applied to the element, and false otherwise.

  • -
  • Let nowSelectable be true if setRangeText() now applies to the element, and false otherwise.

  • +
  • Let nowSelectable be true if setRangeText() now applies to the element, and false otherwise.

  • -
  • If previouslySelectable is true and nowSelectable is false, then for - each FormControlRange whose control is this element, set its - control to null and set both its start offset and end offset to 0.

  • - -
  • If previouslySelectable is false and nowSelectable is true, set the - element's text entry cursor position to the - beginning of the text control, and set its selection - direction to "none".

  • +
  • If previouslySelectable is false and nowSelectable is true, set the + element's text entry cursor position to the + beginning of the text control, and set its selection + direction to "none".

  • @@ -61715,7 +61711,7 @@ MIT Room 32-G524 -

    APIs for the text control selections

    +

    APIs for the text control selections

    Text-entry controls support FormControlRange. Liveness is maintained by HTML's @@ -62170,7 +62166,7 @@ MIT Room 32-G524

  • Let new length be the length of the value of the first argument.

  • -
  • Let new end be the sum of start and new length.

  • +
  • Let new end be the sum of start and new length.

  • Let deleted count be max(0, end minus start).

  • From 4fbc2544e10338ab4cc3282c795819d0524ca01b Mon Sep 17 00:00:00 2001 From: Stephanie Y Zhang Date: Mon, 6 Oct 2025 14:46:57 -0700 Subject: [PATCH 03/16] additional hooks --- source | 216 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 148 insertions(+), 68 deletions(-) diff --git a/source b/source index 63e341daa29..ed3ee6982a2 100644 --- a/source +++ b/source @@ -49827,10 +49827,13 @@ interface HTMLInputElement : HTMLElement { attribute gives the default value of the input element. When the value content attribute is added, set, or removed, if the control's dirty value flag - is false, the user agent must set the value of the element - to the value of the value content attribute, if there is - one, or the empty string otherwise, and then run the current value sanitization - algorithm, if one is defined.

    + is false, the user agent must:

    +
      +
    1. Let oldValue be the element's current value.

    2. +
    3. Set the value of the element to the value of the value content attribute, if there is one, or the empty string otherwise.

    4. +
    5. Run the current value sanitization algorithm, if one is defined.

    6. +
    7. If the element supports form control range and oldValue and the element's new value differ, then run the form control range full replacement steps with the element, the length of oldValue, and the length of the new value.

    8. +
    @@ -49866,17 +49869,16 @@ interface HTMLInputElement : HTMLElement {

    The reset algorithm for input - elements is to set its user validity, - dirty value flag, and - dirty checkedness flag - back to false, set the value of the element to the value - of the value content attribute, if there is one, or the - empty string otherwise, set the checkedness of the - element to true if the element has a checked content - attribute and false if it does not, empty the list of selected files, and then invoke the value - sanitization algorithm, if the type attribute's - current state defines one.

    + elements is to:

    +
      +
    1. Set its user validity, dirty value flag, and dirty checkedness flag back to false.

    2. +
    3. Let oldValue be the element's current value.

    4. +
    5. Set the value of the element to the value of the value content attribute, if there is one, or the empty string otherwise.

    6. +
    7. Set the checkedness of the element to true if the element has a checked content attribute and false if it does not.

    8. +
    9. Empty the list of selected files.

    10. +
    11. Invoke the value sanitization algorithm, if the type attribute's current state defines one.

    12. +
    13. If the element supports form control range and oldValue and the element's new value differ, then run the form control range full replacement steps with the element, the length of oldValue, and the length of the new value.

    14. +

    Each input element can be mutable. Except where @@ -50087,6 +50089,11 @@ interface HTMLInputElement : HTMLElement { element's text entry cursor position to the beginning of the text control, and set its selection direction to "none".

    + +
  • If previouslySelectable is true and nowSelectable is false, then for + each FormControlRange object whose control is this + element, set that object's control to null and set both its start offset and end offset to 0.

  • @@ -50153,6 +50160,87 @@ interface HTMLInputElement : HTMLElement { form, and name IDL attributes are part of the element's forms API.

    +

    The following concepts and algorithms integrate the {{FormControlRange}} interface (defined in + the DOM Standard) with HTML form controls.

    + +

    A {{FormControlRange}} object is associated + with an element if its control is that element. An element's form control ranges are the {{FormControlRange}} objects + associated with it.

    + +
    +

    The form control range value mutation algorithm +updates each {{FormControlRange}} associated with a supported +text control when a contiguous substring of its value string +is replaced. It is passed an element el, non‑negative integers start, +oldLength (removed length), and newLength (inserted length). Let delta = +newLengtholdLength. For each {{FormControlRange}} object range in +el's form control ranges:

    +
      +
    1. Let rs be range's start offset; let re + be its end offset.

    2. + +
    3. Let editStart be start; let editEnd be start + + oldLength.

    4. + +
    5. If editEndrs, then (edit strictly before range) set rs = + rs + delta and re = re + delta and jump to step + Clamp.

    6. + +
    7. If editStartre, then (edit strictly after range) jump to step + Clamp.

    8. + +
    9. (Overlapping removal) If oldLength > 0, then:

      +
        +
      1. If rseditStart and rs < editEnd, set + rs = editStart.

      2. + +
      3. If reeditStart and re < editEnd, set + re = editStart.

      4. +
      +
    10. + +
    11. (Replacement insertion remap) If oldLength > 0 and newLength > 0 + and editStartrsreeditEnd, then for each boundary + (rs then re): let offsetWithin be that boundary's original value − + editStart; set boundary = editStart + min(offsetWithin, + newLength).

    12. + +
    13. (Pure insertion) If oldLength = 0 and newLength > 0 and + editStart is within [rs, re] then:

      +
        +
      1. If rs = re (collapsed), set rs = re = rs + + newLength.

      2. + +
      3. Otherwise, if editStart = rs, set re = re + + newLength. (Insertion at start expands.)

      4. + +
      5. Otherwise, if editStart = re, do nothing. (Insertion at end does not + expand.)

      6. +
      +
    14. + +
    15. Clamp: Let valueLen be the length of + el's current value string. Set rs = + min(rs, valueLen) and re = min(re, valueLen). If + rs > re, then set re = rs.

    16. + +
    17. Set range's start offset to rs and its end offset to re.

    18. +
    +

    This algorithm mirrors {{Range}} boundary adjustment rules, operating instead on the +UTF-16 code unit indices of a form control's value string.

    +

    +
    + +

    The form control range full replacement steps + for an element el with previous value length oldLength and new value length + newLength are to run the form control range value + mutation algorithm with el, 0, oldLength, and newLength.

    + +

    User agents must call the algorithm explicitly at each value mutation point; it is not + implicitly invoked by unspecified text modifications.

    + @@ -54799,11 +54887,8 @@ You cannot submit this form when the field is incorrect.
  • Invoke the value sanitization algorithm, if the element's type attribute's current state defines one.

  • -
  • If the element's value is different from - oldValue, then run adjust form-control - ranges for this element, given a change offset of 0, a deleted length of the - length of oldValue, and an inserted length of the length - of the element's current value.

  • +
  • If the element's value is different from + oldValue and the element supports form control range, then run the form control range full replacement steps with the element, the length of oldValue, and the length of the element's current value.

  • If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the @@ -57542,6 +57627,7 @@ interface HTMLTextAreaElement : HTMLElement { interaction before queuing the task; for example, a user agent could wait for the user to have not hit a key for 100ms, so as to only fire the event when the user pauses, instead of continuously for each keystroke.

    +

    Additionally, before queuing that task, the user agent must run the form control range value mutation steps with the change characterized by the edit (offset, deleted length, inserted length) for this element.

    @@ -57562,7 +57648,7 @@ interface HTMLTextAreaElement : HTMLElement {

    The children changed steps for textarea elements must, if the element's dirty value flag is false, set the element's raw value to its child text - content.

    + content. If this changes the element's raw value, then run the form control range value mutation steps with a change offset of 0, a deleted length of the length of the previous API value, and an inserted length of the length of the new API value.

    @@ -57570,7 +57656,7 @@ interface HTMLTextAreaElement : HTMLElement { elements is to set the user validity to false, the dirty value flag back to false, and the raw value to its child text - content.

    + content. If this changes the element's API value, then run the form control range value mutation steps with a change offset of 0, a deleted length of the length of the old API value, and an inserted length of the length of the new API value.

    @@ -57827,7 +57913,7 @@ interface HTMLTextAreaElement : HTMLElement {

    The defaultValue attribute's setter must - string replace all with the given value within this element.

    + string replace all with the given value within this element. If the element's dirty value flag is false and this causes the element's raw value (and thus its API value) to change, then run the form control range value mutation steps with a change offset of 0, a deleted length of the length of the old API value, and an inserted length of the length of the new API value.

    @@ -57846,10 +57932,7 @@ interface HTMLTextAreaElement : HTMLElement {
  • Set this element's dirty value flag to true.

  • -
  • Run adjust form-control ranges for this element, - given a change offset of 0, a deleted length of the length of - oldAPIValue, and an inserted length of the length of this element's new - API value.

  • +
  • Run the form control range value mutation steps with this element, a change offset of 0, a deleted length of the length of oldAPIValue, and an inserted length of the length of this element's new API value.

  • If the new API value is different from oldAPIValue, then move the text entry @@ -62170,9 +62253,9 @@ MIT Room 32-G524

  • Let deleted count be max(0, end minus start).

  • -
  • Run adjust form-control ranges for this element, - given start as the change offset, deleted count as the deleted length, and - new length as the inserted length.

  • +
  • If this element supports form control range, + then run the form control range value mutation algorithm + with this element, start, deleted count, and new length.

  • Run the appropriate set of substeps from the following list:

    @@ -62287,53 +62370,50 @@ control.setSelectionRange(oldStart + prefix.length, oldEnd + prefix.length, oldD -

    Some DOM APIs expose FormControlRange objects whose boundary points are defined over the - UTF-16 code units of a text control's value string rather than over the node tree. HTML is +

    Some DOM APIs expose FormControlRange objects whose boundary points are defined over + the UTF-16 code units of a text control's value string rather than over the node tree. HTML is responsible for keeping those ranges live when a control's value changes.

    Adjusting form-control ranges for a value change
    -
    -

    To adjust form-control ranges for a control - |control| given a change offset, a deleted length, and an inserted length, run these steps:

    - -
      -
    1. For each FormControlRange |r| such that |r|’s - control is |control|, update each boundary (start and end) using - these plain rules:

      -
        -
      • Before the change: if the boundary comes before where the edit begins, leave it as - is.

      • -
      • Inside the removed or replaced text: if the boundary is at the edit point or falls - anywhere within the text that was removed or replaced (including exactly at its end), move - it to the edit point.

      • -
      • After the change: if the boundary comes after the edited text, move it left or right - to account for the overall change in length — insertions move it to the right, deletions - move it to the left, by the corresponding amount.

      • -
      -
    2. -
    3. Clamp both boundaries so they do not go past the end of the new value.

    4. -
    5. If the start ends up after the end, collapse the range by setting the end to match the - start.

    6. -
    -
    +

    The algorithm to adjust form-control ranges + for a control is defined earlier as the form control + range value mutation algorithm. This section only summarizes its purpose: to keep + FormControlRange objects live by updating their boundary offsets after each value + mutation.

    Where adjustments are invoked
    -

    Whenever a text control's value changes, user agents must run - adjust form-control ranges for that control. This occurs - (including but not limited to) for:

    -
      -
    • User typing, deletion, and paste that produce an input event.

    • -
    • The setRangeText() method.

    • -
    • Setting value or value (including form reset, - autofill, drag-and-drop text insertion, and undo/redo that mutate the control's value).

    • -
    + +

    User agents must invoke the form control range value + mutation algorithm each time a supported text control's value + string is mutated by replacing a contiguous substring (including insertions and deletions). This + includes, but is not limited to:

    +
      +
    • User editing operations (typing, confirmed IME composition, deletion, paste, drag-and-drop + text insertion, spellcheck or autocorrect replacements, undo/redo) that modify the value and dispatch + an input event.

    • + +
    • Calls to setRangeText().

    • + +
    • Scripted assignment to HTMLInputElement.value or + HTMLTextAreaElement.value, including during form reset, + autofill, session/history restoration, and drag-and-drop insertion producing a programmatic value + change.

    • + +
    • Value changes produced by sanitization algorithms that actually alter the stored value (e.g., + newline stripping, whitespace trimming).

    • +
    + +

    Selection changes alone (via setSelectionRange(), + setting selectionStart/selectionEnd, or changing selectionDirection) do not invoke the + algorithm because they do not modify the control's value string.

    If an input element's type is changed to a state that does not support the selection APIs (see selection - applicability), then for each FormControlRange whose - control is that element, set its control to - null and set both its start offset and end offset to 0.

    + applicability), then for each FormControlRange whose control is that element, set its + control to null and set both its start offset and end offset to 0.

    Constraints

    From 96d51de6fe2fda0307219a625c0a0ebfa2bff60f Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 16 Oct 2025 15:47:28 -0700 Subject: [PATCH 04/16] keep original formatting --- source | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/source b/source index ed3ee6982a2..252e7815adb 100644 --- a/source +++ b/source @@ -49827,13 +49827,14 @@ interface HTMLInputElement : HTMLElement { attribute gives the default value of the input element. When the value content attribute is added, set, or removed, if the control's dirty value flag - is false, the user agent must:

    -
      -
    1. Let oldValue be the element's current value.

    2. -
    3. Set the value of the element to the value of the value content attribute, if there is one, or the empty string otherwise.

    4. -
    5. Run the current value sanitization algorithm, if one is defined.

    6. -
    7. If the element supports form control range and oldValue and the element's new value differ, then run the form control range full replacement steps with the element, the length of oldValue, and the length of the new value.

    8. -
    + is false, the user agent must set the value of the element + to the value of the value content attribute, if there is + one, or the empty string otherwise, and then run the current value sanitization + algorithm, if one is defined. If the element + supports form control range and this operation changes its value, then run the form control range full replacement steps with the + element, the old value's length, and the new value's length.

    @@ -49869,16 +49870,23 @@ interface HTMLInputElement : HTMLElement {

    The reset algorithm for input - elements is to:

    -
      -
    1. Set its user validity, dirty value flag, and dirty checkedness flag back to false.

    2. -
    3. Let oldValue be the element's current value.

    4. -
    5. Set the value of the element to the value of the value content attribute, if there is one, or the empty string otherwise.

    6. -
    7. Set the checkedness of the element to true if the element has a checked content attribute and false if it does not.

    8. -
    9. Empty the list of selected files.

    10. -
    11. Invoke the value sanitization algorithm, if the type attribute's current state defines one.

    12. -
    13. If the element supports form control range and oldValue and the element's new value differ, then run the form control range full replacement steps with the element, the length of oldValue, and the length of the new value.

    14. -
    + elements is to set its user validity, + dirty value flag, and + dirty checkedness flag + back to false, set the value of the element to the value + of the value content attribute, if there is one, or the + empty string otherwise, set the checkedness of the + element to true if the element has a checked content + attribute and false if it does not, empty the list of selected files, and then invoke the value + sanitization algorithm, if the type attribute's + current state defines one.

    + +

    If the element supports form control range and its + value has changed as a result of this algorithm, then run the + form control range full replacement steps with the + element, the old value's length, and the new + value's length.

    Each input element can be mutable. Except where @@ -50171,7 +50179,7 @@ interface HTMLInputElement : HTMLElement {

    The form control range value mutation algorithm updates each {{FormControlRange}} associated with a supported -text control when a contiguous substring of its value string +text control when a contiguous substring of its {{FormControlRange/value string}} is replaced. It is passed an element el, non‑negative integers start, oldLength (removed length), and newLength (inserted length). Let delta = newLengtholdLength. For each {{FormControlRange}} object range in @@ -50221,7 +50229,7 @@ is replaced. It is passed an element el, non‑negative integers

  • Clamp: Let valueLen be the length of - el's current value string. Set rs = + el's current {{FormControlRange/value string}}. Set rs = min(rs, valueLen) and re = min(re, valueLen). If rs > re, then set re = rs.

  • From 3155a15f82fa8b1a2eec3269b654703efa4d1843 Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 16 Oct 2025 15:57:42 -0700 Subject: [PATCH 05/16] cleaning up textarea hooks --- source | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/source b/source index 252e7815adb..77ffbed87fd 100644 --- a/source +++ b/source @@ -50246,9 +50246,8 @@ UTF-16 code unit indices of a form control's value string.

    newLength are to run the form control range value mutation algorithm with el, 0, oldLength, and newLength.

    -

    User agents must call the algorithm explicitly at each value mutation point; it is not +

    User agents typically call the algorithm explicitly at each value mutation point; it is not implicitly invoked by unspecified text modifications.

    - @@ -54895,8 +54894,11 @@ You cannot submit this form when the field is incorrect.
  • Invoke the value sanitization algorithm, if the element's type attribute's current state defines one.

  • -
  • If the element's value is different from - oldValue and the element supports form control range, then run the form control range full replacement steps with the element, the length of oldValue, and the length of the element's current value.

  • +
  • If the element's value is different from + oldValue, and the element supports form control + range, then run the form control range full + replacement steps with element, oldValue's length, and the + current value's length.

  • If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the @@ -54906,13 +54908,6 @@ You cannot submit this form when the field is incorrect. direction">resetting the selection direction to "none".

  • - -

    Integration with FormControlRange:

    -

    After setting the new value, run - adjust form-control ranges for this control. Treat the - entire old value as deleted and the entire new value as inserted, so that all associated ranges - update according to the rules in that section.

    -
    default @@ -57635,7 +57630,10 @@ interface HTMLTextAreaElement : HTMLElement { interaction before queuing the task; for example, a user agent could wait for the user to have not hit a key for 100ms, so as to only fire the event when the user pauses, instead of continuously for each keystroke.

    -

    Additionally, before queuing that task, the user agent must run the form control range value mutation steps with the change characterized by the edit (offset, deleted length, inserted length) for this element.

    +

    Before queuing that task, the user agent must run the + form control range value mutation algorithm for this + element, using the edit's offset, deleted length, and inserted length + to describe the change.

    @@ -57656,7 +57654,11 @@ interface HTMLTextAreaElement : HTMLElement {

    The children changed steps for textarea elements must, if the element's dirty value flag is false, set the element's raw value to its child text - content. If this changes the element's raw value, then run the form control range value mutation steps with a change offset of 0, a deleted length of the length of the previous API value, and an inserted length of the length of the new API value.

    + content. If this changes the element's raw value, + then run the form control range value mutation algorithm + for the element, with a change offset of 0, a deleted length equal to the length of the previous + API value, and an inserted length equal to the length + of the new API value.

    @@ -57664,7 +57666,11 @@ interface HTMLTextAreaElement : HTMLElement { elements is to set the user validity to false, the dirty value flag back to false, and the raw value to its child text - content. If this changes the element's API value, then run the form control range value mutation steps with a change offset of 0, a deleted length of the length of the old API value, and an inserted length of the length of the new API value.

    + content. If this changes the element's API value, + then run the form control range value mutation algorithm + for the element, with a change offset of 0, a deleted length equal to the length of the previous + API value, and an inserted length equal to the length + of the new API value.

    @@ -57921,7 +57927,12 @@ interface HTMLTextAreaElement : HTMLElement {

    The defaultValue attribute's setter must - string replace all with the given value within this element. If the element's dirty value flag is false and this causes the element's raw value (and thus its API value) to change, then run the form control range value mutation steps with a change offset of 0, a deleted length of the length of the old API value, and an inserted length of the length of the new API value.

    + string replace all with the given value within this element. + If this changes the element's raw value, + then run the form control range value mutation algorithm + for the element, with a change offset of 0, a deleted length equal to the length of the previous + API value, and an inserted length equal to the length + of the new API value.

    From 90163c4a8a89134812a0c01d94c485ae4f13db3b Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 16 Oct 2025 16:08:35 -0700 Subject: [PATCH 06/16] remove unnecessary text control block --- source | 65 ++++++---------------------------------------------------- 1 file changed, 6 insertions(+), 59 deletions(-) diff --git a/source b/source index 77ffbed87fd..ed34e174f2e 100644 --- a/source +++ b/source @@ -57948,10 +57948,13 @@ interface HTMLTextAreaElement : HTMLElement {
  • Set this element's raw value to the new value.

  • -
  • Set this element's dirty value flag to - true.

  • +
  • Set this element's dirty value flag to true.

  • -
  • Run the form control range value mutation steps with this element, a change offset of 0, a deleted length of the length of oldAPIValue, and an inserted length of the length of this element's new API value.

  • +
  • If this changes the element's API value, then run the + form control range value mutation algorithm for this + element, with a change offset of 0, a deleted length equal to the length of + oldAPIValue, and an inserted length equal to the length of the element's new + API value.

  • If the new API value is different from oldAPIValue, then move the text entry @@ -57961,12 +57964,6 @@ interface HTMLTextAreaElement : HTMLElement {

  • -

    Integration with FormControlRange:

    -

    After setting the new value, run - adjust form-control ranges for this control. Treat the - entire old value as deleted and the entire new value as inserted, so that all associated ranges - update according to the rules in that section.

    -

    The textLength IDL attribute must return the @@ -62384,56 +62381,6 @@ control.setSelectionRange(oldStart + prefix.length, oldEnd + prefix.length, oldD -

    Form control range liveness
    - - - - -

    Some DOM APIs expose FormControlRange objects whose boundary points are defined over - the UTF-16 code units of a text control's value string rather than over the node tree. HTML is - responsible for keeping those ranges live when a control's value changes.

    - -
    Adjusting form-control ranges for a value change
    - -

    The algorithm to adjust form-control ranges - for a control is defined earlier as the form control - range value mutation algorithm. This section only summarizes its purpose: to keep - FormControlRange objects live by updating their boundary offsets after each value - mutation.

    - -
    Where adjustments are invoked
    - -

    User agents must invoke the form control range value - mutation algorithm each time a supported text control's value - string is mutated by replacing a contiguous substring (including insertions and deletions). This - includes, but is not limited to:

    -
      -
    • User editing operations (typing, confirmed IME composition, deletion, paste, drag-and-drop - text insertion, spellcheck or autocorrect replacements, undo/redo) that modify the value and dispatch - an input event.

    • - -
    • Calls to setRangeText().

    • - -
    • Scripted assignment to HTMLInputElement.value or - HTMLTextAreaElement.value, including during form reset, - autofill, session/history restoration, and drag-and-drop insertion producing a programmatic value - change.

    • - -
    • Value changes produced by sanitization algorithms that actually alter the stored value (e.g., - newline stripping, whitespace trimming).

    • -
    - -

    Selection changes alone (via setSelectionRange(), - setting selectionStart/selectionEnd, or changing selectionDirection) do not invoke the - algorithm because they do not modify the control's value string.

    - -

    If an input element's type is changed to a state that does not - support the selection APIs (see selection - applicability), then for each FormControlRange whose control is that element, set its - control to null and set both its start offset and end offset to 0.

    -

    Constraints

    From 7ed3fb77b0792de64da3616122de9ab84ab80794 Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 23 Oct 2025 08:38:36 -0700 Subject: [PATCH 07/16] update mutation alg --- source | 124 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/source b/source index ed34e174f2e..4e696cffb3d 100644 --- a/source +++ b/source @@ -50168,86 +50168,86 @@ interface HTMLInputElement : HTMLElement { form, and name IDL attributes are part of the element's forms API.

    -

    The following concepts and algorithms integrate the {{FormControlRange}} interface (defined in - the DOM Standard) with HTML form controls.

    - -

    A {{FormControlRange}} object is associated - with an element if its control is that element. An element's form control ranges are the {{FormControlRange}} objects +

    A {{FormControlRange}} object is associated + with an element if its control is that element. An element's + form control ranges are the {{FormControlRange}} objects associated with it.

    -

    The form control range value mutation algorithm -updates each {{FormControlRange}} associated with a supported -text control when a contiguous substring of its {{FormControlRange/value string}} -is replaced. It is passed an element el, non‑negative integers start, -oldLength (removed length), and newLength (inserted length). Let delta = -newLengtholdLength. For each {{FormControlRange}} object range in -el's form control ranges:

    -
      -
    1. Let rs be range's start offset; let re - be its end offset.

    2. +

      The form control range value mutation algorithm + updates each {{FormControlRange}} associated with a + supported text control when a contiguous substring of + its {{FormControlRange/value string}} is replaced. It is passed an element el and + non-negative integers start, oldLength (removed length), and + newLength (inserted length). Let delta = newLength - + oldLength. For each {{FormControlRange}} object range in + el's form control ranges:

      -
    3. Let editStart be start; let editEnd be start + - oldLength.

    4. +
        +
      1. Let rs be range's start offset, and + re be its end offset.

      2. -
      3. If editEndrs, then (edit strictly before range) set rs = - rs + delta and re = re + delta and jump to step - Clamp.

      4. +
      5. Let editStart be start, and let editEnd be + start + oldLength.

      6. -
      7. If editStartre, then (edit strictly after range) jump to step - Clamp.

      8. +
      9. If editEndrs, then (edit strictly before range) set + rs = rs + delta and re = re + delta, + then jump to step Clamp.

      10. -
      11. (Overlapping removal) If oldLength > 0, then:

        -
          -
        1. If rseditStart and rs < editEnd, set - rs = editStart.

        2. +
        3. If editStartre, then (edit strictly after range) jump to step + Clamp.

        4. -
        5. If reeditStart and re < editEnd, set - re = editStart.

        6. -
        -
      12. +
      13. (Overlapping removal) If oldLength > 0, then:

        +
          +
        1. If rseditStart and rs < editEnd, + set rs = editStart.

        2. -
        3. (Replacement insertion remap) If oldLength > 0 and newLength > 0 - and editStartrsreeditEnd, then for each boundary - (rs then re): let offsetWithin be that boundary's original value − - editStart; set boundary = editStart + min(offsetWithin, - newLength).

        4. +
        5. If reeditStart and re < editEnd, + set re = editStart.

        6. +
        +
      14. -
      15. (Pure insertion) If oldLength = 0 and newLength > 0 and - editStart is within [rs, re] then:

        -
          -
        1. If rs = re (collapsed), set rs = re = rs - + newLength.

        2. +
        3. (Replacement insertion remap) If oldLength > 0 and + newLength > 0 and editStartrsre ≤ + editEnd, then for each boundary (rs then re): let + offsetWithin be that boundary's original value − editStart, and set the + boundary to editStart + min(offsetWithin, newLength).

        4. -
        5. Otherwise, if editStart = rs, set re = re + - newLength. (Insertion at start expands.)

        6. +
        7. (Pure insertion) If oldLength = 0 and newLength > 0 and + editStart is within [rs, re], then:

          +
            +
          1. If rs = re (collapsed), set + rs = re = rs + newLength.

          2. -
          3. Otherwise, if editStart = re, do nothing. (Insertion at end does not - expand.)

          4. -
          -
        8. +
        9. Otherwise, if editStart = rs, set + re = re + newLength.

        10. -
        11. Clamp: Let valueLen be the length of - el's current {{FormControlRange/value string}}. Set rs = - min(rs, valueLen) and re = min(re, valueLen). If - rs > re, then set re = rs.

        12. +
        13. Otherwise, if editStart = re, do nothing.

        14. +
        +
      16. + +
      17. Clamp: Let valueLen be the length of + el's current {{FormControlRange/value string}}. Set rs = + min(rs, valueLen) and re = + min(re, valueLen). If rs > re, set + re = rs.

      18. + +
      19. Set range's start offset to rs, and + its end offset to re.

      20. +
      -
    5. Set range's start offset to rs and its end offset to re.

    6. -
    -

    This algorithm mirrors {{Range}} boundary adjustment rules, operating instead on the -UTF-16 code unit indices of a form control's value string.

    -

    +

    This algorithm mirrors {{Range}} boundary adjustment rules, operating on UTF-16 + code unit indices within a form control's value string.

    +

    -

    The form control range full replacement steps +

    The form control range full replacement steps for an element el with previous value length oldLength and new value length newLength are to run the form control range value mutation algorithm with el, 0, oldLength, and newLength.

    -

    User agents typically call the algorithm explicitly at each value mutation point; it is not - implicitly invoked by unspecified text modifications.

    +

    User agents typically call this algorithm explicitly at each value mutation point; + it is not implicitly invoked by unspecified text modifications.

    @@ -57927,7 +57927,7 @@ interface HTMLTextAreaElement : HTMLElement {

    The defaultValue attribute's setter must - string replace all with the given value within this element. + string replace all with the given value within this element. If this changes the element's raw value, then run the form control range value mutation algorithm for the element, with a change offset of 0, a deleted length equal to the length of the previous @@ -96444,7 +96444,7 @@ interface BarProp {

    The identity of the reserved environment is considered to be fully transferred to the created environment settings object. The reserved environment - is not searchable by the environment’s environment's id from this point on.

    From 202f8814e3e8da96398c530870f360e2ccb0598d Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 4 Dec 2025 08:38:24 -0800 Subject: [PATCH 08/16] rename to PlainTextRange + tpac changes pt 1 --- source | 120 +++++++++------------------------------------------------ 1 file changed, 19 insertions(+), 101 deletions(-) diff --git a/source b/source index 4e696cffb3d..d4d74e8f77a 100644 --- a/source +++ b/source @@ -49830,11 +49830,12 @@ interface HTMLInputElement : HTMLElement { is false, the user agent must set the value of the element to the value of the value content attribute, if there is one, or the empty string otherwise, and then run the current value sanitization - algorithm, if one is defined. If the element - supports form control range and this operation changes its value, then run the form control range full replacement steps with the - element, the old value's length, and the new value's length.

    + algorithm, if one is defined.

    + +

    If the element supports plain text ranges and this operation changes its + value, then the user agent must run the + plain text range full replacement steps with the element, the old value's + length, and the new value's length.

    @@ -49882,12 +49883,10 @@ interface HTMLInputElement : HTMLElement { sanitization algorithm, if the type attribute's current state defines one.

    -

    If the element supports form control range and its - value has changed as a result of this algorithm, then run the - form control range full replacement steps with the - element, the old value's length, and the new - value's length.

    -
    +

    If the element supports plain text ranges and its + value has changed as a result of this algorithm, then the + user agent must run the plain text range full replacement steps with the element, the + old value's length, and the new value's length.

    Each input element can be mutable. Except where otherwise specified, an input element is always HTMLInputElement : HTMLElement { beginning of the text control, and set its selection direction to "none".

    -
  • If previouslySelectable is true and nowSelectable is false, then for - each FormControlRange object whose control is this - element, set that object's control to null and set both its start offset and end offset to 0.

  • +
  • If previouslySelectable is true and nowSelectable is false, then for + each PlainTextRange object whose host is this element, set that object's host to + null and set both of its start and end offsets to 0.

  • @@ -50168,90 +50166,10 @@ interface HTMLInputElement : HTMLElement { form, and name IDL attributes are part of the element's forms API.

    -

    A {{FormControlRange}} object is associated - with an element if its control is that element. An element's - form control ranges are the {{FormControlRange}} objects - associated with it.

    - -
    -

    The form control range value mutation algorithm - updates each {{FormControlRange}} associated with a - supported text control when a contiguous substring of - its {{FormControlRange/value string}} is replaced. It is passed an element el and - non-negative integers start, oldLength (removed length), and - newLength (inserted length). Let delta = newLength - - oldLength. For each {{FormControlRange}} object range in - el's form control ranges:

    - -
      -
    1. Let rs be range's start offset, and - re be its end offset.

    2. - -
    3. Let editStart be start, and let editEnd be - start + oldLength.

    4. - -
    5. If editEndrs, then (edit strictly before range) set - rs = rs + delta and re = re + delta, - then jump to step Clamp.

    6. - -
    7. If editStartre, then (edit strictly after range) jump to step - Clamp.

    8. - -
    9. (Overlapping removal) If oldLength > 0, then:

      -
        -
      1. If rseditStart and rs < editEnd, - set rs = editStart.

      2. - -
      3. If reeditStart and re < editEnd, - set re = editStart.

      4. -
      -
    10. - -
    11. (Replacement insertion remap) If oldLength > 0 and - newLength > 0 and editStartrsre ≤ - editEnd, then for each boundary (rs then re): let - offsetWithin be that boundary's original value − editStart, and set the - boundary to editStart + min(offsetWithin, newLength).

    12. - -
    13. (Pure insertion) If oldLength = 0 and newLength > 0 and - editStart is within [rs, re], then:

      -
        -
      1. If rs = re (collapsed), set - rs = re = rs + newLength.

      2. - -
      3. Otherwise, if editStart = rs, set - re = re + newLength.

      4. - -
      5. Otherwise, if editStart = re, do nothing.

      6. -
      -
    14. - -
    15. Clamp: Let valueLen be the length of - el's current {{FormControlRange/value string}}. Set rs = - min(rs, valueLen) and re = - min(re, valueLen). If rs > re, set - re = rs.

    16. - -
    17. Set range's start offset to rs, and - its end offset to re.

    18. -
    - -

    This algorithm mirrors {{Range}} boundary adjustment rules, operating on UTF-16 - code unit indices within a form control's value string.

    -

    -

    The form control range full replacement steps - for an element el with previous value length oldLength and new value length - newLength are to run the form control range value - mutation algorithm with el, 0, oldLength, and newLength.

    - -

    User agents typically call this algorithm explicitly at each value mutation point; - it is not implicitly invoked by unspecified text modifications.

    -
    - - +
    States of the type attribute
    @@ -54895,10 +54813,10 @@ You cannot submit this form when the field is incorrect. data-x="attr-input-type">type attribute's current state defines one.

  • If the element's value is different from - oldValue, and the element supports form control - range, then run the form control range full - replacement steps with element, oldValue's length, and the - current value's length.

  • + oldValue, and the element supports plain text ranges, then the user + agent must run the plain text range full replacement steps with + element, oldValue's length, and the current + value's length.

  • If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the @@ -96444,7 +96362,7 @@ interface BarProp {

    The identity of the reserved environment is considered to be fully transferred to the created environment settings object. The reserved environment - is not searchable by the environment's environment’s id from this point on.

  • From dfe8b080d0cda2b0206fc952b57f3b66c5895277 Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 4 Dec 2025 09:05:59 -0800 Subject: [PATCH 09/16] rename to PlainTextRange + tpac changes pt 2 --- source | 71 +++++++++++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/source b/source index d4d74e8f77a..14fc93d3f74 100644 --- a/source +++ b/source @@ -49832,7 +49832,7 @@ interface HTMLInputElement : HTMLElement { one, or the empty string otherwise, and then run the current value sanitization algorithm, if one is defined.

    -

    If the element supports plain text ranges and this operation changes its +

    If the element supports plain text ranges and this operation changes its value, then the user agent must run the plain text range full replacement steps with the element, the old value's length, and the new value's length.

    @@ -49882,8 +49882,9 @@ interface HTMLInputElement : HTMLElement { data-x="concept-input-type-file-selected">selected files, and then invoke the value sanitization algorithm, if the type attribute's current state defines one.

    + -

    If the element supports plain text ranges and its +

    If the element supports plain text ranges and its value has changed as a result of this algorithm, then the user agent must run the plain text range full replacement steps with the element, the old value's length, and the new value's length.

    @@ -50169,7 +50170,6 @@ interface HTMLInputElement : HTMLElement { -
    States of the type attribute
    @@ -54812,11 +54812,11 @@ You cannot submit this form when the field is incorrect.
  • Invoke the value sanitization algorithm, if the element's type attribute's current state defines one.

  • -
  • If the element's value is different from - oldValue, and the element supports plain text ranges, then the user - agent must run the plain text range full replacement steps with - element, oldValue's length, and the current - value's length.

  • +
  • If the element's value is different from + oldValue, and the element supports plain text ranges, then run the + plain text range full replacement steps with the element, oldValue's + length, and the current value's + length.

  • If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the @@ -57548,10 +57548,9 @@ interface HTMLTextAreaElement : HTMLElement { interaction before queuing the task; for example, a user agent could wait for the user to have not hit a key for 100ms, so as to only fire the event when the user pauses, instead of continuously for each keystroke.

    -

    Before queuing that task, the user agent must run the - form control range value mutation algorithm for this - element, using the edit's offset, deleted length, and inserted length - to describe the change.

    +

    Before queuing that task, if the element supports plain text ranges, then run the + plain text range value mutation steps with the element, the edit's offset, + deleted length, and inserted length to describe the change.

    @@ -57573,10 +57572,10 @@ interface HTMLTextAreaElement : HTMLElement { element's dirty value flag is false, set the element's raw value to its child text content. If this changes the element's raw value, - then run the form control range value mutation algorithm - for the element, with a change offset of 0, a deleted length equal to the length of the previous - API value, and an inserted length equal to the length - of the new API value.

    + and the element supports plain text ranges, then the user agent must run the + plain text range full replacement steps with the element, the length of the previous + API value, and the length of the new + API value.

    @@ -57584,12 +57583,13 @@ interface HTMLTextAreaElement : HTMLElement { elements is to set the user validity to false, the dirty value flag back to false, and the raw value to its child text - content. If this changes the element's API value, - then run the form control range value mutation algorithm - for the element, with a change offset of 0, a deleted length equal to the length of the previous - API value, and an inserted length equal to the length - of the new API value.

    -
    + content. If this changes the element's + API value, and the element + supports plain text ranges, then the user agent must run the + plain text range full replacement steps with the element, the length of the previous + API value, and the length of the new + API value.

    + /div>

    When a textarea element is popped off the stack of open elements of @@ -57846,11 +57846,11 @@ interface HTMLTextAreaElement : HTMLElement {

    The defaultValue attribute's setter must string replace all with the given value within this element. - If this changes the element's raw value, - then run the form control range value mutation algorithm - for the element, with a change offset of 0, a deleted length equal to the length of the previous - API value, and an inserted length equal to the length - of the new API value.

    + If this changes the element's raw value, and the + element supports plain text ranges, then the user + agent must run the plain text range full replacement steps with the element, the + length of the previous API value, and the length of the + new API value.

    @@ -57868,10 +57868,10 @@ interface HTMLTextAreaElement : HTMLElement {
  • Set this element's dirty value flag to true.

  • -
  • If this changes the element's API value, then run the - form control range value mutation algorithm for this - element, with a change offset of 0, a deleted length equal to the length of - oldAPIValue, and an inserted length equal to the length of the element's new +

  • If this changes the element's API value, and the + element supports plain text ranges, then the user + agent must run the plain text range full replacement steps with this element, the + length of oldAPIValue, and the length of the element's new API value.

  • If the new API value is different from @@ -61730,11 +61730,6 @@ MIT Room 32-G524

    APIs for the text control selections

    -

    - Text-entry controls support FormControlRange. Liveness is maintained by HTML's - form-control range adjustment algorithm, and the algorithms - in this section invoke it whenever they modify a control's value string.

    -

    The input and textarea elements define several attributes and methods @@ -62187,8 +62182,8 @@ MIT Room 32-G524

  • Let deleted count be max(0, end minus start).

  • -
  • If this element supports form control range, - then run the form control range value mutation algorithm +

  • If this element supports plain text ranges, + then run the plain text range value mutation algorithm with this element, start, deleted count, and new length.

  • From 2eef616038bce3106d66c8162a8e9ea4ae484545 Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Wed, 14 Jan 2026 10:55:13 -0800 Subject: [PATCH 10/16] updated to OpaqueRange + moved update range steps from dom spec --- source | 104 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/source b/source index 14fc93d3f74..1a52dcc8568 100644 --- a/source +++ b/source @@ -49832,10 +49832,46 @@ interface HTMLInputElement : HTMLElement { one, or the empty string otherwise, and then run the current value sanitization algorithm, if one is defined.

    -

    If the element supports plain text ranges and this operation changes its - value, then the user agent must run the - plain text range full replacement steps with the element, the old value's +

    If the element supports opaque ranges and this operation changes its value, + then the user agent must run the opaque range full replacement steps with the element, the old value's length, and the new value's length.

    +
    +

    The opaque range full replacement steps, given an element element, an integer oldLength, + and an integer newLength, are to run the opaque range replacement steps with element, + 0, oldLength, and newLength.

    +
    + +
    +

    The opaque range replacement steps, given an element element, integers replaceStart and + replaceEnd, and an integer replacementLength, are:

    + +
      +
    1. Let delta be replacementLength minus (replaceEndreplaceStart).

    2. + +
    3. +

      For each {{OpaqueRange}} object range whose host is element, run these + substeps:

      + +
        +
      1. +

        For each boundary offset of range (its start offset and its + end offset), run these substeps:

        + +
          +
        1. If the boundary offset is less than or equal to replaceStart, then continue.

        2. + +
        3. Otherwise, if the boundary offset is less than or equal to replaceEnd, then set the boundary offset + to replaceStart.

        4. + +
        5. Otherwise, increase the boundary offset by delta.

        6. +
        +
      2. +
      +
    4. +
    + +

    These updates operate on UTF-16 code unit indices.

    +
    @@ -49884,10 +49920,10 @@ interface HTMLInputElement : HTMLElement { current state defines one.

    -

    If the element supports plain text ranges and its - value has changed as a result of this algorithm, then the - user agent must run the plain text range full replacement steps with the element, the - old value's length, and the new value's length.

    +

    If the element supports opaque ranges and its value + has changed as a result of this algorithm, then the user agent must run the + opaque range full replacement steps with the element, the old value's + length, and the new value's length.

    Each input element can be mutable. Except where otherwise specified, an input element is always HTMLInputElement : HTMLElement { direction to "none".

  • If previouslySelectable is true and nowSelectable is false, then for - each PlainTextRange object whose host is this element, set that object's host to - null and set both of its start and end offsets to 0.

  • + each {{OpaqueRange}} object whose host is this element, set that object's + host to null and set both of its start offset and + end offset to 0.

    @@ -54812,11 +54849,11 @@ You cannot submit this form when the field is incorrect.
  • Invoke the value sanitization algorithm, if the element's type attribute's current state defines one.

  • -
  • If the element's value is different from - oldValue, and the element supports plain text ranges, then run the - plain text range full replacement steps with the element, oldValue's - length, and the current value's - length.

  • +
  • If the element's value is different from + oldValue, and the element supports opaque ranges, then run the + opaque range full replacement steps with the element, oldValue's + length, and the current value's + length.

  • If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the @@ -57548,9 +57585,10 @@ interface HTMLTextAreaElement : HTMLElement { interaction before queuing the task; for example, a user agent could wait for the user to have not hit a key for 100ms, so as to only fire the event when the user pauses, instead of continuously for each keystroke.

    -

    Before queuing that task, if the element supports plain text ranges, then run the - plain text range value mutation steps with the element, the edit's offset, - deleted length, and inserted length to describe the change.

    +

    Before queuing that task, if the element supports opaque ranges, then run the + opaque range replacement steps with the element, the edit's offset, + (offset + deleted length), and inserted length + to describe the change.

    @@ -57572,8 +57610,8 @@ interface HTMLTextAreaElement : HTMLElement { element's dirty value flag is false, set the element's raw value to its child text content. If this changes the element's raw value, - and the element supports plain text ranges, then the user agent must run the - plain text range full replacement steps with the element, the length of the previous + and the element supports opaque ranges, then the user agent must run the + opaque range full replacement steps with the element, the length of the previous API value, and the length of the new API value.

    @@ -57585,11 +57623,11 @@ interface HTMLTextAreaElement : HTMLElement { data-x="concept-textarea-raw-value">raw value to its child text content. If this changes the element's API value, and the element - supports plain text ranges, then the user agent must run the - plain text range full replacement steps with the element, the length of the previous + supports opaque ranges, then the user agent must run the + opaque range full replacement steps with the element, the length of the previous API value, and the length of the new API value.

    - /div> +

    When a textarea element is popped off the stack of open elements of @@ -57847,10 +57885,10 @@ interface HTMLTextAreaElement : HTMLElement {

    The defaultValue attribute's setter must string replace all with the given value within this element. If this changes the element's raw value, and the - element supports plain text ranges, then the user - agent must run the plain text range full replacement steps with the element, the - length of the previous API value, and the length of the - new API value.

    + element supports opaque ranges, then the user agent must run the + opaque range full replacement steps with the element, the length of the previous + API value, and the length of the new + API value.

    @@ -57869,9 +57907,9 @@ interface HTMLTextAreaElement : HTMLElement {
  • Set this element's dirty value flag to true.

  • If this changes the element's API value, and the - element supports plain text ranges, then the user - agent must run the plain text range full replacement steps with this element, the - length of oldAPIValue, and the length of the element's new + element supports opaque ranges, then the user agent must run the + opaque range full replacement steps with this element, the length of + oldAPIValue, and the length of the element's new API value.

  • If the new API value is different from @@ -62178,13 +62216,13 @@ MIT Room 32-G524

  • Let new length be the length of the value of the first argument.

  • -
  • Let new end be the sum of start and new length.

  • +
  • Let new end be the sum of start and new length.

  • Let deleted count be max(0, end minus start).

  • -
  • If this element supports plain text ranges, - then run the plain text range value mutation algorithm - with this element, start, deleted count, and new length.

  • +
  • If this element supports opaque ranges, then run the opaque range replacement steps + with this element, start, (start + deleted count), + and new length.

  • Run the appropriate set of substeps from the following list:

    From 5aa605f04436440eb7f1dc2c56c8ef37ee51c18e Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Wed, 14 Jan 2026 13:04:09 -0800 Subject: [PATCH 11/16] Add getValueRange --- source | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/source b/source index eb20360f2c1..5fe51b1cac6 100644 --- a/source +++ b/source @@ -48558,6 +48558,7 @@ interface HTMLInputElement : HTMLElement { undefined setRangeText(DOMString replacement); undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); + [CEReactions, NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); undefined showPicker(); @@ -49937,13 +49938,13 @@ interface HTMLInputElement : HTMLElement {
  • Let delta be replacementLength minus (replaceEndreplaceStart).

  • -

    For each {{OpaqueRange}} object range whose host is element, run these - substeps:

    +

    For each OpaqueRange object range associated with element, + run these substeps:

    1. -

      For each boundary offset of range (its start offset and its - end offset), run these substeps:

      +

      For each boundary offset of range (its startOffset and its + endOffset), run these substeps:

      1. If the boundary offset is less than or equal to replaceStart, then continue.

      2. @@ -50223,9 +50224,8 @@ interface HTMLInputElement : HTMLElement { direction to "none".

      3. If previouslySelectable is true and nowSelectable is false, then for - each {{OpaqueRange}} object whose host is this element, set that object's - host to null and set both of its start offset and - end offset to 0.

      4. + each OpaqueRange object associated with this element, detach that object by setting both its + startOffset> and endOffset to 0.

      @@ -50295,6 +50295,7 @@ interface HTMLInputElement : HTMLElement { +
      States of the type attribute
      @@ -57674,6 +57675,7 @@ interface HTMLTextAreaElement : HTMLElement { undefined setRangeText(DOMString replacement); undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); + [CEReactions, NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); };
      Uses HTMLTextAreaElement.
      @@ -62005,6 +62007,19 @@ MIT Room 32-G524 + +
      range = element.getValueRange(start, end)
      + +
      +

      Returns an OpaqueRange object representing the portion of the element's + relevant value from start to end.

      + +

      Throws a "NotSupportedError" DOMException if the element does not support opaque ranges.

      + +

      Throws an "IndexSizeError" DOMException if start or end is greater + than the length of the relevant value.

      +
      +
      From 6b6108c2d04037f68cdcff91208ef40e2c171e6e Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Wed, 14 Jan 2026 13:27:20 -0800 Subject: [PATCH 12/16] specify supported input types --- source | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/source b/source index 5fe51b1cac6..7a10cd78a87 100644 --- a/source +++ b/source @@ -48741,7 +48741,8 @@ interface HTMLInputElement : HTMLElement { selectionEnd, and selectionDirection, IDL attributes, the setRangeText() and - setSelectionRange() methods, the + setSelectionRange(), and + getValueRange() methods, the stepUp() and stepDown() methods, and the input and @@ -49765,6 +49766,30 @@ interface HTMLInputElement : HTMLElement { · + + · + · + · + · + · + + · + · + · + · + + + + getValueRange() + · + Yes + Yes + Yes + · + Yes + · + + · · @@ -50225,7 +50250,7 @@ interface HTMLInputElement : HTMLElement {
    2. If previouslySelectable is true and nowSelectable is false, then for each OpaqueRange object associated with this element, detach that object by setting both its - startOffset> and endOffset to 0.

    3. + startOffset and endOffset to 0.

    @@ -62390,13 +62415,13 @@ MIT Room 32-G524
  • Let new length be the length of the value of the first argument.

  • -
  • Let new end be the sum of start and new length.

  • +
  • Let new end be the sum of start and new length.

  • Let deleted count be max(0, end minus start).

  • -
  • If this element supports opaque ranges, then run the opaque range replacement steps - with this element, start, (start + deleted count), - and new length.

  • +
  • If this element supports opaque ranges, then run the opaque range replacement steps + with this element, start, (start + deleted count), + and new length.

  • Run the appropriate set of substeps from the following list:

    From e772b1ad6f6f812ed6412642eddc29d67a2a8166 Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Sun, 8 Feb 2026 23:51:20 -0800 Subject: [PATCH 13/16] add supports opaque range def + reword of range updates --- source | 242 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 155 insertions(+), 87 deletions(-) diff --git a/source b/source index 7a10cd78a87..a1296deaa8e 100644 --- a/source +++ b/source @@ -3251,6 +3251,10 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • ShadowRoot interface
  • Text interface
  • Range interface
  • +
  • OpaqueRange interface, and its + start offset and + end offset
  • +
  • The opaque range string concept
  • node document concept
  • document type concept
  • @@ -48558,7 +48562,7 @@ interface HTMLInputElement : HTMLElement { undefined setRangeText(DOMString replacement); undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); - [CEReactions, NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); + [NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); undefined showPicker(); @@ -49783,7 +49787,7 @@ interface HTMLInputElement : HTMLElement { getValueRange() · Yes - Yes + Yes · Yes @@ -49946,46 +49950,10 @@ interface HTMLInputElement : HTMLElement { one, or the empty string otherwise, and then run the current value sanitization algorithm, if one is defined.

    -

    If the element supports opaque ranges and this operation changes its value, - then the user agent must run the opaque range full replacement steps with the element, the old value's - length, and the new value's length.

    -
    -

    The opaque range full replacement steps, given an element element, an integer oldLength, - and an integer newLength, are to run the opaque range replacement steps with element, - 0, oldLength, and newLength.

    -
    - -
    -

    The opaque range replacement steps, given an element element, integers replaceStart and - replaceEnd, and an integer replacementLength, are:

    - -
      -
    1. Let delta be replacementLength minus (replaceEndreplaceStart).

    2. - -
    3. -

      For each OpaqueRange object range associated with element, - run these substeps:

      - -
        -
      1. -

        For each boundary offset of range (its startOffset and its - endOffset), run these substeps:

        - -
          -
        1. If the boundary offset is less than or equal to replaceStart, then continue.

        2. - -
        3. Otherwise, if the boundary offset is less than or equal to replaceEnd, then set the boundary offset - to replaceStart.

        4. - -
        5. Otherwise, increase the boundary offset by delta.

        6. -
        -
      2. -
      -
    4. -
    - -

    These updates operate on UTF-16 code unit indices.

    -
    +

    If the element supports opaque ranges and this operation changes its value, then run the opaque range full replacement + steps with the element, the old value's length, and the new value's + length.

    @@ -50034,8 +50002,8 @@ interface HTMLInputElement : HTMLElement { current state defines one.

    -

    If the element supports opaque ranges and its value - has changed as a result of this algorithm, then the user agent must run the +

    If the element supports opaque ranges and its value has changed as a result of this algorithm, then run the opaque range full replacement steps with the element, the old value's length, and the new value's length.

    @@ -50094,6 +50062,13 @@ interface HTMLInputElement : HTMLElement { copy.

    +
    +

    The input HTML element removing steps, given + removedNode and oldParent, are: if removedNode supports + opaque ranges, then set removedNode's set of associated + OpaqueRanges to an empty set.

    +
    +

    The activation behavior for input elements element, given event, are these steps:

    @@ -50249,8 +50224,8 @@ interface HTMLInputElement : HTMLElement { direction to "none".

  • If previouslySelectable is true and nowSelectable is false, then for - each OpaqueRange object associated with this element, detach that object by setting both its - startOffset and endOffset to 0.

  • + each OpaqueRange in this element's set of associated OpaqueRanges, set + its start offset and end offset to 0.

    @@ -54976,11 +54951,11 @@ You cannot submit this form when the field is incorrect.
  • Invoke the value sanitization algorithm, if the element's type attribute's current state defines one.

  • -
  • If the element's value is different from - oldValue, and the element supports opaque ranges, then run the - opaque range full replacement steps with the element, oldValue's - length, and the current value's - length.

  • +
  • If the element's value is different + from oldValue, and the element supports opaque ranges, then run + the opaque range full replacement steps with the element, + oldValue's length, and the current value's length.

  • If the element's value (after applying the value sanitization algorithm) is different from oldValue, and the @@ -55468,6 +55443,9 @@ You cannot submit this form when the field is incorrect. data-x="dom-Event-composed">composed attributes initialized to true. The corresponding change event, if any, will be fired when the control loses focus.

    +

    Before queuing that task, if the element supports opaque ranges, then run the + opaque range replacement steps with the element, the edit's code unit offset, the + number of code units removed, and the number of code units inserted.

    Examples of a user changing the element's HTMLTextAreaElement : HTMLElement { undefined setRangeText(DOMString replacement); undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); - [CEReactions, NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); + [NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); };

    Uses HTMLTextAreaElement.
    @@ -57771,10 +57749,9 @@ interface HTMLTextAreaElement : HTMLElement { interaction before queuing the task; for example, a user agent could wait for the user to have not hit a key for 100ms, so as to only fire the event when the user pauses, instead of continuously for each keystroke.

    -

    Before queuing that task, if the element supports opaque ranges, then run the - opaque range replacement steps with the element, the edit's offset, - (offset + deleted length), and inserted length - to describe the change.

    +

    Before queuing that task, if the element supports opaque ranges, then run the + opaque range replacement steps with the element, the edit's code unit offset, the + number of code units removed, and the number of code units inserted.

    @@ -57791,15 +57768,21 @@ interface HTMLTextAreaElement : HTMLElement { value flag from node to copy.

    +
    +

    The textarea HTML element removing steps, given + removedNode and oldParent, are: set removedNode's set of + associated OpaqueRanges to an empty set.

    +
    +

    The children changed steps for textarea elements must, if the element's dirty value flag is false, set the element's raw value to its child text - content. If this changes the element's raw value, - and the element supports opaque ranges, then the user agent must run the - opaque range full replacement steps with the element, the length of the previous - API value, and the length of the new - API value.

    + content. If this changes the element's raw value, and the element supports opaque + ranges, then run the opaque range full replacement steps with the element, + the length of the previous API value, and the + length of the new API value.

    @@ -57807,12 +57790,11 @@ interface HTMLTextAreaElement : HTMLElement { elements is to set the user validity to false, the dirty value flag back to false, and the raw value to its child text - content. If this changes the element's - API value, and the element - supports opaque ranges, then the user agent must run the - opaque range full replacement steps with the element, the length of the previous - API value, and the length of the new - API value.

    + content. If this changes the element's API + value, and the element supports opaque ranges, then run the opaque + range full replacement steps with the element, the length of the previous API value, and the length of the new API value.

    @@ -58069,12 +58051,7 @@ interface HTMLTextAreaElement : HTMLElement {

    The defaultValue attribute's setter must - string replace all with the given value within this element. - If this changes the element's raw value, and the - element supports opaque ranges, then the user agent must run the - opaque range full replacement steps with the element, the length of the previous - API value, and the length of the new - API value.

    + string replace all with the given value within this element.

    @@ -58092,11 +58069,11 @@ interface HTMLTextAreaElement : HTMLElement {
  • Set this element's dirty value flag to true.

  • -
  • If this changes the element's API value, and the - element supports opaque ranges, then the user agent must run the - opaque range full replacement steps with this element, the length of - oldAPIValue, and the length of the element's new - API value.

  • +
  • If this changes the element's API value, + and the element supports opaque ranges, then run the opaque range full + replacement steps with this element, the length of + oldAPIValue, and the length of the element's new API value.

  • If the new API value is different from oldAPIValue, then move the text entry @@ -62036,16 +62013,21 @@ MIT Room 32-G524

    range = element.getValueRange(start, end)
    -

    Returns an OpaqueRange object representing the portion of the element's - relevant value from start to end.

    +

    Returns an OpaqueRange object representing the portion of the element's relevant value from start to + end.

    -

    Throws a "NotSupportedError" DOMException if the element does not support opaque ranges.

    +

    Throws a "NotSupportedError" DOMException if the + element does not support opaque ranges.

    -

    Throws an "IndexSizeError" DOMException if start or end is greater - than the length of the relevant value.

    +

    Throws an "IndexSizeError" DOMException if + start or end is greater than the length of the relevant value.

    + +

    If start is greater than end, the range is collapsed to + start.

    -
    @@ -62419,9 +62401,9 @@ MIT Room 32-G524
  • Let deleted count be max(0, end minus start).

  • -
  • If this element supports opaque ranges, then run the opaque range replacement steps - with this element, start, (start + deleted count), - and new length.

  • +
  • If this element supports opaque ranges, then run the opaque range + replacement steps with this element, start, deleted count, and + new length.

  • Run the appropriate set of substeps from the following list:

    @@ -62487,6 +62469,92 @@ MIT Room 32-G524 +

    An element supports opaque ranges if it is + a textarea element, or an input element whose type attribute is in the Text, Search, + Telephone, URL, or Password state.

    + +

    Each element that supports opaque ranges has a set of associated + OpaqueRanges, which is a set of OpaqueRange objects, initially + empty.

    + +

    The opaque range string for an element that + supports opaque ranges is the element's relevant value.

    + +
    +

    The opaque range full replacement steps, given an element + element, an integer oldLength, and an integer newLength, are to + run the opaque range replacement steps with element, 0, + oldLength, and newLength.

    +
    + +
    +

    The opaque range replacement steps, given an element element, + a non-negative integer offset, a non-negative integer count, and a + non-negative integer insertedLength, are:

    + +
      +
    1. For each OpaqueRange in element's set of associated + OpaqueRanges whose start offset is greater than offset but less + than or equal to offset plus count, set its start offset to + offset.

    2. + +
    3. For each OpaqueRange in element's set of associated + OpaqueRanges whose end offset is greater than offset but less + than or equal to offset plus count, set its end offset to + offset.

    4. + +
    5. For each OpaqueRange in element's set of associated + OpaqueRanges whose start offset is greater than offset plus + count, increase its start offset by insertedLength and + decrease it by count.

    6. + +
    7. For each OpaqueRange in element's set of associated + OpaqueRanges whose end offset is greater than offset plus + count, increase its end offset by insertedLength and + decrease it by count.

    8. +
    + +

    These updates operate on UTF-16 code unit indices.

    +
    + +
    +

    The getValueRange(start, + end) method, when invoked, must run the following steps:

    + +
      +
    1. If this element is an input element, and getValueRange() does not apply to this element, then throw a + "NotSupportedError" DOMException.

    2. + +
    3. Let length be the length of this element's relevant value.

    4. + +
    5. If start is greater than length, then throw an + "IndexSizeError" DOMException.

    6. + +
    7. If end is greater than length, then throw an + "IndexSizeError" DOMException.

    8. + +
    9. If start is greater than end, then set end to + start.

    10. + +
    11. Let range be a new OpaqueRange with start offset + start and end offset end.

    12. + +
    13. Append range to this element's set of + associated OpaqueRanges.

    14. + +
    15. Return range.

    16. +
    +
    +

    The setRangeText() method uses the following enumeration:

    From 568cff383e37566113e4ce895a624c5ee64accbc Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Mon, 9 Feb 2026 11:44:45 -0800 Subject: [PATCH 14/16] update to use internal containers instead of opaque range string --- source | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source b/source index a1296deaa8e..c23acb1078a 100644 --- a/source +++ b/source @@ -3252,9 +3252,11 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • Text interface
  • Range interface
  • OpaqueRange interface, and its - start offset and + start container, + start offset, + end container, and end offset
  • -
  • The opaque range string concept
  • +
  • The supports opaque ranges concept
  • node document concept
  • document type concept
  • @@ -49999,14 +50001,12 @@ interface HTMLInputElement : HTMLElement { attribute and false if it does not, empty the list of selected files, and then invoke the value sanitization algorithm, if the type attribute's - current state defines one.

    + current state defines one. If the element supports opaque ranges and its value changed, then run the opaque range full replacement + steps with the element, the old value's length, and the new value's + length.

    -

    If the element supports opaque ranges and its value has changed as a result of this algorithm, then run the - opaque range full replacement steps with the element, the old value's - length, and the new value's length.

    -

    Each input element can be mutable. Except where otherwise specified, an input element is always mutable. Similarly, except where otherwise specified, the user @@ -62469,21 +62469,20 @@ MIT Room 32-G524 -

    An element supports opaque ranges if it is - a textarea element, or an input element whose A textarea element, or an input element whose type attribute is in the Text, Search, Telephone, URL, or Password state.

    + data-x="attr-input-type-password">Password state, supports opaque ranges.

    Each element that supports opaque ranges has a set of associated OpaqueRanges, which is a set of OpaqueRange objects, initially empty.

    -

    The opaque range string for an element that - supports opaque ranges is the element's relevant value.

    +

    For an element that supports opaque ranges, the opaque range internal + container is the internal node representing the element's relevant value text.

    The opaque range full replacement steps, given an element @@ -62545,8 +62544,9 @@ MIT Room 32-G524

  • If start is greater than end, then set end to start.

  • -
  • Let range be a new OpaqueRange with start offset - start and end offset end.

  • +
  • Let range be a new OpaqueRange with start container + and end container set to this element's opaque range internal container, + start offset start, and end offset end.

  • Append range to this element's set of associated OpaqueRanges.

  • From 580e13ed4c945e4596d80f392f8435be4034ef9d Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Thu, 12 Feb 2026 00:12:06 -0800 Subject: [PATCH 15/16] rename getValueRange to createValueRange --- source | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source b/source index c23acb1078a..f35c52ecb8f 100644 --- a/source +++ b/source @@ -48564,7 +48564,7 @@ interface HTMLInputElement : HTMLElement { undefined setRangeText(DOMString replacement); undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); - [NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); + [NewObject] OpaqueRange createValueRange(unsigned long start, unsigned long end); undefined showPicker(); @@ -48748,7 +48748,7 @@ interface HTMLInputElement : HTMLElement { selectionDirection, IDL attributes, the setRangeText() and setSelectionRange(), and - getValueRange() methods, the + createValueRange() methods, the stepUp() and stepDown() methods, and the input and @@ -49786,7 +49786,7 @@ interface HTMLInputElement : HTMLElement { - getValueRange() + createValueRange() · Yes @@ -57678,7 +57678,7 @@ interface HTMLTextAreaElement : HTMLElement { undefined setRangeText(DOMString replacement); undefined setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); undefined setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); - [NewObject] OpaqueRange getValueRange(unsigned long start, unsigned long end); + [NewObject] OpaqueRange createValueRange(unsigned long start, unsigned long end); };
    Uses HTMLTextAreaElement.
    @@ -62010,7 +62010,7 @@ MIT Room 32-G524 -
    range = element.getValueRange(start, end)
    +
    range = element.createValueRange(start, end)

    Returns an OpaqueRange object representing the portion of the element's

    The getValueRange(start, + data-x="dom-textarea/input-createValueRange">createValueRange(start, end) method, when invoked, must run the following steps:

    1. If this element is an input element, and getValueRange() createValueRange() does not apply to this element, then throw a "NotSupportedError" DOMException.

    2. From 7ceff82987c5893fa0c6dc6e6e1857be06a2d603 Mon Sep 17 00:00:00 2001 From: Stephanie Zhang Date: Tue, 28 Apr 2026 09:04:02 -0700 Subject: [PATCH 16/16] Add auto-disconnect for input and textarea --- source | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/source b/source index f35c52ecb8f..9debaf45650 100644 --- a/source +++ b/source @@ -3254,9 +3254,12 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
    3. OpaqueRange interface, and its start container, start offset, - end container, and - end offset
    4. + end container, + end offset, + associated element, and + disconnect() method
    5. The supports opaque ranges concept
    6. +
    7. The opaque range disconnect steps hook
    8. node document concept
    9. document type concept
    10. @@ -50065,8 +50068,8 @@ interface HTMLInputElement : HTMLElement {

      The input HTML element removing steps, given removedNode and oldParent, are: if removedNode supports - opaque ranges, then set removedNode's set of associated - OpaqueRanges to an empty set.

      + opaque ranges, then disconnect all associated OpaqueRanges from + removedNode.

      @@ -50223,9 +50226,8 @@ interface HTMLInputElement : HTMLElement { beginning of the text control, and set its selection direction to "none".

      -
    11. If previouslySelectable is true and nowSelectable is false, then for - each OpaqueRange in this element's set of associated OpaqueRanges, set - its start offset and end offset to 0.

    12. +
    13. If previouslySelectable is true and nowSelectable is false, then + disconnect all associated OpaqueRanges from this element.

    @@ -57770,8 +57772,8 @@ interface HTMLTextAreaElement : HTMLElement {

    The textarea HTML element removing steps, given - removedNode and oldParent, are: set removedNode's set of - associated OpaqueRanges to an empty set.

    + removedNode and oldParent, are to disconnect all associated + OpaqueRanges from removedNode.

    @@ -62521,6 +62523,19 @@ MIT Room 32-G524

    These updates operate on UTF-16 code unit indices.

    +
    +

    The opaque range disconnect steps, given an element element and an + OpaqueRange range, are to remove + range from element's set of associated OpaqueRanges.

    +
    + +
    +

    To disconnect all associated OpaqueRanges from an element element that + supports opaque ranges, run the disconnect() method steps on all items in + element's set of associated OpaqueRanges.

    +
    +

    The createValueRange(start, @@ -62548,6 +62563,9 @@ MIT Room 32-G524 and end container set to this element's opaque range internal container, start offset start, and end offset end.

    +
  • Set range's associated + element to this element.

  • +
  • Append range to this element's set of associated OpaqueRanges.