Skip to content

Commit 60a655b

Browse files
Add OpaqueRange disconnect() method
Implement disconnect() per WHATWG DOM spec PR #1404 [0]. Detaches the range from its element, stopping live offset updates and zeroing offsets. Calling it multiple times is safe and has no additional effect. Adds WPT tests covering disconnect behavior. Automatic disconnection when the element is removed from the tree or changes type will be handled in a follow-up CL. [0] whatwg/dom#1404 (comment) Low-Coverage-Reason: COVERAGE_UNDERREPORTED Bug: 421421332 Change-Id: I6f0bb55d57f1eb1876779faad018a19d23b1d665 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7595177 Reviewed-by: Dan Clark <daniec@microsoft.com> Commit-Queue: Stephanie Zhang <stephanie.zhang@microsoft.com> Reviewed-by: Ana Sollano Kim <ansollan@microsoft.com> Reviewed-by: Mason Freed <masonf@chromium.org> Cr-Commit-Position: refs/heads/main@{#1588113}
1 parent 097fdf1 commit 60a655b

1 file changed

Lines changed: 74 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<!DOCTYPE html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<body></body>
5+
<script>
6+
test(() => {
7+
document.body.innerHTML = '<textarea>Hello</textarea>';
8+
const textarea = document.body.firstElementChild;
9+
const range = textarea.getValueRange(1, 4);
10+
11+
range.disconnect();
12+
13+
assert_equals(range.startOffset, 0, "startOffset resets to 0");
14+
assert_equals(range.endOffset, 0, "endOffset resets to 0");
15+
assert_true(range.collapsed, "range is collapsed");
16+
assert_equals(range.startContainer, null, "startContainer remains null");
17+
assert_equals(range.endContainer, null, "endContainer remains null");
18+
assert_equals(range.getClientRects().length, 0, "no client rects");
19+
assert_equals(range.getBoundingClientRect().width, 0, "bounding rect width is 0");
20+
assert_equals(range.getBoundingClientRect().height, 0, "bounding rect height is 0");
21+
}, "disconnect() resets range state and geometry.");
22+
23+
test(() => {
24+
document.body.innerHTML = '<textarea>Hello</textarea>';
25+
const textarea = document.body.firstElementChild;
26+
const range = textarea.getValueRange(1, 4);
27+
28+
range.disconnect();
29+
range.disconnect();
30+
31+
assert_equals(range.startOffset, 0);
32+
assert_equals(range.endOffset, 0);
33+
}, "disconnect() is idempotent.");
34+
35+
test(() => {
36+
document.body.innerHTML = '<textarea>Hello</textarea>';
37+
const textarea = document.body.firstElementChild;
38+
const range = textarea.getValueRange(1, 4);
39+
40+
range.disconnect();
41+
textarea.value = "World!";
42+
43+
assert_equals(range.startOffset, 0, "disconnected range ignores value change");
44+
assert_equals(range.endOffset, 0);
45+
}, "disconnect() stops live offset updates.");
46+
47+
test(() => {
48+
document.body.innerHTML = '<textarea>Hello</textarea>';
49+
const textarea = document.body.firstElementChild;
50+
const range1 = textarea.getValueRange(0, 3);
51+
const range2 = textarea.getValueRange(2, 5);
52+
53+
range1.disconnect();
54+
55+
assert_equals(range2.startOffset, 2, "sibling range unaffected by disconnect");
56+
assert_equals(range2.endOffset, 5);
57+
58+
textarea.value = "Modified";
59+
assert_equals(range1.startOffset, 0, "disconnected range stays at 0");
60+
assert_equals(range2.startOffset, 0, "sibling range still receives updates");
61+
}, "disconnect() only affects the target range.");
62+
63+
test(() => {
64+
document.body.innerHTML = '<textarea>Hello</textarea>';
65+
const textarea = document.body.firstElementChild;
66+
const range = textarea.getValueRange(1, 4);
67+
range.disconnect();
68+
69+
const newRange = textarea.getValueRange(0, 5);
70+
assert_equals(newRange.startOffset, 0);
71+
assert_equals(newRange.endOffset, 5);
72+
assert_false(newRange.collapsed);
73+
}, "Element accepts new ranges after a prior range is disconnected.");
74+
</script>

0 commit comments

Comments
 (0)