Skip to content
Draft
Changes from 1 commit
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
Prev Previous commit
Next Next commit
updates
  • Loading branch information
stephanieyzhang committed Oct 6, 2025
commit 09c8acb7fb60b8944967b63b8253f70113605775
60 changes: 43 additions & 17 deletions cssom-view-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2051,23 +2051,40 @@ Note: The {{DOMRect}} object returned by {{Range/getBoundingClientRect()}} is no
<h2 id=formcontrolrange-geometry>FormControlRange geometry</h2>

<p>This section defines {{FormControlRange/getClientRects()}} and
{{FormControlRange/getBoundingClientRect()}}. The {{FormControlRange}} interface is defined in
[[DOM]]. These methods mirror {{Range/getClientRects()}} and {{Range/getBoundingClientRect()}}, but
apply to the selected portion of a text control’s <em>value</em>.</p>
{{FormControlRange/getBoundingClientRect()}} for {{FormControlRange}} (interface defined in [[DOM]]).
They mirror {{Range/getClientRects()}} and {{Range/getBoundingClientRect()}}, but operate on the
selected portion of a text control’s <em>value</em>.</p>

<p class=note>The IDL for these methods appears in [[DOM]]; it is not repeated here to avoid
duplication.</p>

<p>The <dfn>associated control</dfn> of a {{FormControlRange}} is the <code>&lt;textarea></code> or
text-supporting <code>&lt;input></code> whose editable <em>value</em> the range indexes into.</p>

<p class=note>User agents typically represent the control’s value with a single internal text node.
If a future implementation were to use multiple nodes, this specification would need adjustment;
until then, algorithms assume a single backing text node.</p>

<p class=note>Unlike {{Range/getClientRects()}}, which historically returns an empty list for a
collapsed {{Range}}, this specification explicitly preserves that legacy behavior for
{{FormControlRange/getClientRects()}}: a collapsed {{FormControlRange}} also returns an empty
{{DOMRectList}}. Authors that need caret metrics should use
{{FormControlRange/getBoundingClientRect()}}.</p>

<div algorithm>
<p>The <dfn method for=FormControlRange>getClientRects()</dfn> method, when invoked, must run these
steps:</p>
<ol>
<li><p>If the associated control is not connected or its computed <code>display</code> is
<code>none</code>, return an empty {{DOMRectList}}.</p></li>
<li><p>Update style and layout for the associated control.</p></li>
<li><p>Let <var>start</var> and <var>end</var> be this range’s boundary offsets, clamped to the
current length of the control’s value.</p></li>
<li><p>Let <var>text</var> be the single text node that backs the control’s editable value. If there
is no such node, return an empty {{DOMRectList}}.</p></li>
<li><p>Let <var>r</var> be a {{Range}} whose start and end are (<var>text</var>, <var>start</var>)
and (<var>text</var>, <var>end</var>).</p></li>
<li><p>If the <a>associated control</a> is not <a>connected</a> or its computed <code>display</code>
is <code>none</code>, return an empty {{DOMRectList}}.</p></li>
<li><p>Update style and layout for the <a>associated control</a>.</p></li>
<li><p>Let <var>value length</var> be the current length of the <a>associated control</a>'s value.</p></li>
<li><p>Let <var>start</var> be min(this range’s start boundary point offset, <var>value length</var>)
and <var>end</var> be min(this range’s end boundary point offset, <var>value length</var>).</p></li>
<li><p>If <var>start</var> &gt; <var>end</var>, set <var>end</var> to <var>start</var>. <span class=note>This collapses backwards ranges per current implementations.</span></p></li>
<li><p>If <var>start</var> = <var>end</var>, return an empty {{DOMRectList}}.</p></li>
<li><p>Let <var>text</var> be the single text node that backs the control’s editable value. If none, return an empty {{DOMRectList}}.</p></li>
<li><p>Let <var>r</var> be a conceptual {{Range}} whose start is (<var>text</var>, <var>start</var>) and end is (<var>text</var>, <var>end</var>).</p></li>
<li><p>Return <var>r</var>.{{Range/getClientRects()}}.</p></li>
</ol>
</div>
Expand All @@ -2080,17 +2097,26 @@ these steps:</p>
<li>
<p>If <var>rects</var> is empty:</p>
<ol>
<li><p>If this range is {{AbstractRange/collapsed}} and the control is visible (its computed
<code>display</code> is not <code>none</code>), return a zero-width {{DOMRect}} positioned at the
caret, whose height equals the line height at that position.</p></li>
<li><p>Otherwise, return a {{DOMRect}} with zero width and height.</p></li>
<li><p>If this range is {{AbstractRange/collapsed}} and the <a>associated control</a> is visible
(its computed <code>display</code> is not <code>none</code>), return a zero-width [=scaled=]
{{DOMRect}} positioned at the caret (insertion point). Its block-size (height in horizontal
writing modes) is the line box block-size at that position, with any <a>transforms</a> that
apply to the control and its ancestors applied.</p></li>
<li><p>Otherwise, return a {{DOMRect}} whose {{DOMRect/x}}, {{DOMRect/y}}, {{DOMRect/width}}, and
{{DOMRect/height}} members are zero.</p></li>
</ol>
</li>
<li><p>Otherwise, return the union of the rectangles in <var>rects</var>, as for
<li><p>Otherwise, return a {{DOMRect}} describing the smallest rectangle that includes every
rectangle in <var>rects</var> whose width or height is not zero, as for
{{Range/getBoundingClientRect()}}.</p></li>
</ol>
</div>

<p class=note>If implementations later expose a caret rectangle via
{{FormControlRange/getClientRects()}} for collapsed ranges, this section will be updated. Authors
SHOULD NOT rely on observing an empty list vs. a zero-width caret rectangle to detect collapse;
use {{AbstractRange/collapsed}}.</p>

<h2 id=extensions-to-the-mouseevent-interface>Extensions to the {{MouseEvent}} Interface</h2>

Issue: The object IDL fragment redefines some members. Can we resolve this somehow?
Expand Down