Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions dom.bs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ H1: DOM
Shortname: dom
Text Macro: TWITTER thedomstandard
Text Macro: LATESTRD 2025-06
Text Macro: COMMIT-SHA 0000000
Copy link
Author

Choose a reason for hiding this comment

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

Remove

Abstract: DOM defines a platform-neutral model for events, aborting activities, and node trees.
Translation: ja https://triple-underscore.github.io/DOM4-ja.html
Translation: zh-Hans https://htmlspecs.com/dom/
Expand Down Expand Up @@ -9892,6 +9893,176 @@ and {{Range/getBoundingClientRect()}} methods are defined in other specification
[[CSSOM-VIEW]]


<h3 id=interface-formcontrolrange>Interface {{FormControlRange}}</h3>

<pre class=idl>
[Exposed=Window]
interface FormControlRange : AbstractRange {
constructor();

undefined setFormControlRange((HTMLInputElement or HTMLTextAreaElement) element,
unsigned long startOffset,
unsigned long endOffset
);
<!-- TODO: Bikeshed method name. Alternatives suggested include setInFormControl,
setFormControl, setControl, setStartAndEnd, or simply set. Tracked as an
Open Question in the explainer:
https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/FormControlRange/explainer.md#open-questions -->

DOMRectList getClientRects();
DOMRect getBoundingClientRect();
stringifier;
};
</pre>

<p>Objects implementing the {{FormControlRange}} interface are known as {{FormControlRange}} objects.

<dl class=domintro>
<dt><code><var ignore>formControlRange</var> = new
<a constructor lt="FormControlRange()">FormControlRange</a>()</code>
<dd>Returns a new {{FormControlRange}} that tracks text offsets in a text control's value as it
changes.

<dt><code><var ignore>formControlRange</var>.
{{FormControlRange/setFormControlRange()}}(<var ignore>element</var>,
<var ignore>startOffset</var>, <var ignore>endOffset</var>)</code>
<dd>Sets the endpoints to <code>[startOffset, endOffset]</code> within <var>element</var>'s
<a href="#formcontrolrange-value-string">value string</a>. Throws {{NotSupportedError}} for
unsupported elements and {{IndexSizeError}} for out-of-bounds offsets.
</dl>

<p>A {{FormControlRange}} is a range whose <a>boundary points</a> are defined in the host text
control's <a href="#formcontrolrange-value-string">value string</a> rather than in the <a>node tree</a>.
Its <a for=range>start node</a> and <a for=range>end node</a> are always the host <code>&lt;input></code>
or <code>&lt;textarea></code>, and its offsets are indices into that string.

<p>A {{FormControlRange}} has associated state:

<ul>
<li><p><dfn export for=FormControlRange id=formcontrolrange-control>control</dfn> (null or an
{{HTMLInputElement}}/{{HTMLTextAreaElement}}).

<li><p><dfn export for=FormControlRange id=formcontrolrange-start>start offset</dfn> (a
non-negative integer).

<li><p><dfn export for=FormControlRange id=formcontrolrange-end>end offset</dfn> (a non-negative
integer).
</ul>

<p>The startContainer getter steps are to return <a>this</a>'s
<a for=FormControlRange>control</a>.

<p>The endContainer getter steps are to return <a>this</a>'s
<a for=FormControlRange>control</a>.

<p>The startOffset getter steps are to return <a>this</a>'s
<a for=FormControlRange>start offset</a>.

<p>The endOffset getter steps are to return <a>this</a>'s
<a for=FormControlRange>end offset</a>.

<p>The collapsed getter steps are to return true if <a>this</a>'s
<a for=FormControlRange>start offset</a> equals <a>this</a>'s
<a for=FormControlRange>end offset</a>; otherwise false.

<p>An {{Element}} <var>el</var>
<dfn export id=supports-form-control-range>supports form control range</dfn> if it is an
{{HTMLTextAreaElement}}, or an {{HTMLInputElement}} whose type is one of
"<code>text</code>", "<code>search</code>", "<code>tel</code>", "<code>url</code>", or
"<code>password</code>".

<p class=note>These are exactly the types for which the related selection APIs
apply in HTML; see <a href="https://html.spec.whatwg.org/multipage/input.html#do-not-apply">
selection APIs applicability for <code>input</code> types</a>.
This list is the complement of that section.</p>

<p>The <dfn constructor for=FormControlRange lt="FormControlRange()">
<code>new FormControlRange()</code></dfn> constructor steps are to set <a>this</a>'s
<a for=FormControlRange>control</a> to null and its <a for=FormControlRange>start offset</a> and
<a for=FormControlRange>end offset</a> to 0.

<p>For a <a lt="supports form control range">supported</a> host element <var>el</var>, its
<dfn export id=formcontrolrange-value-string>value string</dfn> is the same string exposed by its IDL
attribute {{HTMLInputElement/value}}/{{HTMLTextAreaElement/value}}. Offsets for {{FormControlRange}}
are indices into this <a href="#formcontrolrange-value-string">value string</a> in the inclusive
range [0, <code>value.length</code>], matching
{{HTMLInputElement/selectionStart}}/{{HTMLInputElement/selectionEnd}} and
{{HTMLTextAreaElement/selectionStart}}/{{HTMLTextAreaElement/selectionEnd}} units.</p>

<p>The <dfn method for=FormControlRange>
<code>setFormControlRange(<var>element</var>, <var>startOffset</var>,
<var>endOffset</var>)</code></dfn> method steps are:

<ol>
<li><p>If <var>element</var> does not <a>support form control range</a>, then <a>throw</a> a
"{{NotSupportedError!!exception}}" {{DOMException}}.

<li><p>Let <var>len</var> be the length of <var>element</var>'s
<a href="#formcontrolrange-value-string">value string</a>.

<li><p>If <var>startOffset</var> &gt; <var>len</var> or <var>endOffset</var> &gt; <var>len</var>,
then <a>throw</a> an "{{IndexSizeError!!exception}}" {{DOMException}}.

<li><p>If <var>startOffset</var> &gt; <var>endOffset</var>, then set <var>endOffset</var> to
<var>startOffset</var>.

<li><p>Set <a>this</a>'s <a for=FormControlRange>control</a> to <var>element</var>,
<a>this</a>'s <a for=FormControlRange>start offset</a> to <var>startOffset</var>, and
<a>this</a>'s <a for=FormControlRange>end offset</a> to <var>endOffset</var>.
</ol>

<p>If an {{HTMLInputElement}}'s <code>type</code> changes to a type that does not
Copy link
Contributor

Choose a reason for hiding this comment

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

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

<a>support form control range</a> (e.g., switching to <code>date</code>), then each associated
{{FormControlRange}} must set its <a for=FormControlRange>control</a> to null and set both its
<a for=FormControlRange>start offset</a> and <a for=FormControlRange>end offset</a> to 0.

<p class=note>HTML will normatively call the associated range-adjustment algorithm wherever a
control’s value changes or its type ceases to support selection.</p>

<p>A {{FormControlRange}} is live: when the control's <a href="#formcontrolrange-value-string">value
string</a> changes, the range's {{AbstractRange/startOffset}} and {{AbstractRange/endOffset}} are
updated automatically to preserve the same logical content. These behaviors mirror {{Range}}
boundary adjustments in the DOM, but are applied to the UTF-16 code units of a form control's value.

<ul>
<li><p>Edits before the range: Offsets shift by the net length change.

<li><p>Edits after the range: Offsets remain unchanged.

<li><p>Edits overlapping the range: If a boundary falls inside text that was removed, move it to the
start of the change. If the edit also inserted new text, remap the boundary into the inserted span
at the closest corresponding offset, not exceeding its end.

<li><p>Insertion at the start boundary: A non-{{AbstractRange/collapsed}} range expands to include
the new text. A collapsed range (caret) moves after the insertion.

<li><p>Insertion at the end boundary: A non-collapsed range does not expand to include the new text.
A collapsed range moves after the insertion.

<li><p>Clamping and collapse: Offsets are clamped to the current value length. If the
{{AbstractRange/startOffset}} would exceed the {{AbstractRange/endOffset}}, set the end to the
start.
</ul>

<!-- TODO: Define boundary adjustment algorithm in HTML spec. DOM spec currently describes
expected behaviors, but HTML spec should normatively call this algorithm anywhere a form
control value changes (similar to Range update handling in DOM). -->

<p>The <dfn export for=FormControlRange id=dom-formcontrolrange-stringifier>stringification
behavior</dfn> must run these steps:</p>

<ol>
<li><p>If <a>this</a>'s <a for=FormControlRange>control</a> is null, then return the empty string.</p></li>

<li><p>Let <var>value</var> be <a>this</a>'s <a for=FormControlRange>control</a>'s
<a href="#formcontrolrange-value-string">value string</a>.</p></li>

<li><p>Let <var>start</var> be <a>this</a>'s <a for=FormControlRange>start offset</a>, and let
<var>end</var> be <a>this</a>'s <a for=FormControlRange>end offset</a>.</p></li>

<li><p>Return the substring of <var>value</var> from <var>start</var> to <var>end</var>.</p></li>
</ol>


<h2 id="traversal">Traversal</h2>

Expand Down