1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
<!DOCTYPE HTML>
<meta charset="utf-8" />
<link rel=help href="https://html.spec.whatwg.org/#attr-associated-element">
<link rel="author" href="masonf@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=single_element>
<input aria-activedescendant=foo>
<p id=foo></p>
</div>
<div id=array>
<input aria-describedby="foo1 foo2">
<div id=targets>
<p id=foo1></p>
<p id=foo2></p>
</div>
</div>
<script>
function isIterable(obj) {
if (obj === null)
return false;
return typeof obj[Symbol.iterator] === 'function';
}
function toSet(elementOrList) {
if (!isIterable(elementOrList)) {
return new Set([elementOrList]);
}
return new Set(elementOrList);
}
function assert_equal_elements(arr1, arr2, msg) {
msg = msg || "Arrays not equal";
arr1 = toSet(arr1);
arr2 = toSet(arr2);
assert_true(arr1.size === arr2.size &&
[...arr1].every((x) => arr2.has(x)), msg);
}
function single_test(container, targets, contentAttr, idlAttr, isSingleTarget) {
// Start with idref-based reference:
const el = container.querySelector('input');
assert_true(el.getAttribute(contentAttr) != null && el.getAttribute(contentAttr) != '','Should start with idref attribute');
assert_equal_elements(el[idlAttr],targets);
container.remove();
assert_equal_elements(el[idlAttr],targets,'idrefs should continue to work when target is disconnected');
document.body.appendChild(container);
assert_equal_elements(el[idlAttr],targets,'functional when reconnected');
// Now set up an attr-associated element:
el[idlAttr] = isSingleTarget ? targets[0] : targets;
assert_equal_elements(el[idlAttr],targets);
assert_equals(el.getAttribute(contentAttr),'','Content attribute is present but empty');
container.remove();
assert_equal_elements(el[idlAttr],targets,'attr-associated element still functional');
assert_equals(el.getAttribute(contentAttr),'','Attribute still blank');
document.body.appendChild(container);
assert_equal_elements(el[idlAttr],targets,'still functional when reconnected');
// Sanity check:
el.removeAttribute(contentAttr);
assert_equal_elements(el[idlAttr],null);
assert_equals(el.getAttribute(contentAttr),null);
container.remove();
assert_equal_elements(el[idlAttr],null);
assert_equals(el.getAttribute(contentAttr),null);
document.body.appendChild(container);
}
test(() => {
const container = document.getElementById('single_element');
const targets = [container.querySelector('#foo')];
single_test(container, targets, 'aria-activedescendant', 'ariaActiveDescendantElement', true);
},'Element references should stay valid when content is disconnected (single element)');
test(() => {
const container = document.getElementById('array');
const targets = Array.from(container.querySelector('#targets').children);
single_test(container, targets, 'aria-describedby', 'ariaDescribedByElements', false);
},'Element references should stay valid when content is disconnected (element array)');
</script>
|