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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
<!DOCTYPE HTML>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/wai-aria/scripts/aria-utils.js"></script>
</head>
<body>
<div id="test-container"></div>
<script>
async function setup_test() {
const test_container = document.querySelector("#test-container");
test_container.setHTMLUnsafe(`
<div id="host1">
<template shadowrootmode="open" shadowrootreferencetarget="label1">
<span>Outside the label</span>
<label id="label1">Label 1</label>
<label id="label2">Label 2</label>
</template>
</div>
<input id="input1" aria-labelledby="host1">`);
const input1 = test_container.querySelector("#input1");
assert_equals(await test_driver.get_computed_label(input1), "Label 1");
return test_container
}
promise_test(async t => {
const test_container = await setup_test();
const host1 = test_container.querySelector("#host1");
const label1 = host1.shadowRoot.querySelector("#label1");
label1.id = "new_id";
assert_equals(await test_driver.get_computed_label(input1), "");
}, "Changing the ID of the referenced element results in an empty computed label");
promise_test(async t => {
const test_container = await setup_test();
const host1 = test_container.querySelector("#host1");
const label1 = host1.shadowRoot.querySelector("#label1");
label1.remove();
assert_equals(await test_driver.get_computed_label(input1), "");
}, "Removing the referenced element results in an empty computed label");
promise_test(async t => {
const test_container = await setup_test();
const host1 = test_container.querySelector("#host1");
const new_label = document.createElement("label");
new_label.id = "label1";
new_label.textContent = "New label";
host1.shadowRoot.prepend(new_label);
assert_equals(await test_driver.get_computed_label(input1), "New label");
}, "New referenced element prepended to the shadow supercedes the existing label");
promise_test(async t => {
const test_container = await setup_test();
const host1 = test_container.querySelector("#host1");
const new_label = document.createElement("label");
new_label.id = "label1";
new_label.textContent = "New label";
host1.shadowRoot.append(new_label);
assert_equals(await test_driver.get_computed_label(input1), "Label 1");
}, "The existing label supercedes new element (with same id as the existing label) appended to the shadow");
promise_test(async t => {
const test_container = await setup_test();
const host1 = test_container.querySelector("#host1");
host1.shadowRoot.referenceTarget = "label2";
assert_equals(await test_driver.get_computed_label(input1), "Label 2");
}, "Changing the reference target ID updates the computed label");
async function setup_nested_reference_target() {
const test_container = document.querySelector("#test-container");
test_container.setHTMLUnsafe(`
<div id="outer_host">
<template shadowrootmode="open" shadowrootreferencetarget="inner_host">
<span>shadow tree level 1</span>
<div id="inner_host">
<template shadowrootmode="open" shadowrootreferencetarget="real_label1">
<span>shadow tree level 2</span>
<label id="real_label1">Real Label 1</label>
<label id="real_label2">Real Label 2</label>
</template>
</div>
</template>
</div>
<input id="input1" aria-labelledby="outer_host">`);
const input1 = test_container.querySelector("#input1");
assert_equals(await test_driver.get_computed_label(input1), "Real Label 1");
return test_container
}
promise_test(async t => {
const test_container = await setup_nested_reference_target();
const outer_host = test_container.querySelector("#outer_host");
const inner_host = outer_host.shadowRoot.querySelector("#inner_host");
inner_host.shadowRoot.referenceTarget = "real_label2";
assert_equals(await test_driver.get_computed_label(input1), "Real Label 2");
}, "Changing the nested referenceTarget to reference a different element updates the computed label");
promise_test(async t => {
const test_container = await setup_nested_reference_target();
const outer_host = test_container.querySelector("#outer_host");
const inner_host = outer_host.shadowRoot.querySelector("#inner_host");
const real_label1 = inner_host.shadowRoot.querySelector("#real_label1");
real_label1.id = "new_id";
assert_equals(await test_driver.get_computed_label(input1), "");
}, "Changing the ID of the nested referenced element results in an empty computed label");
</script>
<label id="label2" for="x-input2">Input 2</label>
<x-input2 id="x-input2">
<template shadowrootmode="open" shadowrootreferencetarget="input2">
<input id="input2">
</template>
</x-input2>
<script>
promise_test(async t => {
const x_input = document.getElementById('x-input2');
const input = x_input.shadowRoot.getElementById('input2');
const label = document.getElementById('label2');
label.htmlFor = '';
assert_array_equals(Array.from(input['labels']), []);
label.htmlFor = x_input.id;
assert_array_equals(Array.from(input['labels']), [label]);
}, ".labels property is updated when for attribute changes on label outside of shadow root");
</script>
<label id="label3" for="x-input3">Input 3</label>
<x-input3 id="x-input3">
<template shadowrootmode="open" shadowrootreferencetarget="input3">
<input id="input3">
</template>
</x-input3>
<script>
promise_test(async t => {
const x_input = document.getElementById('x-input3');
const input = x_input.shadowRoot.getElementById('input3');
const label = document.getElementById('label3');
x_input.removeAttribute('id');
assert_array_equals(Array.from(input['labels']), []);
x_input.id = label.htmlFor;
assert_array_equals(Array.from(input['labels']), [label]);
}, ".labels property is updated when ID changes on input");
</script>
<label id="label4" for="x-input4">Input 4</label>
<x-input4 id="x-input4">
<template shadowrootmode="open" shadowrootreferencetarget="input4">
<input id="input4">
</template>
</x-input4>
<script>
promise_test(async t => {
const x_input = document.getElementById('x-input4');
const input = x_input.shadowRoot.getElementById('input4');
const label = document.getElementById('label4');
x_input.shadowRoot.referenceTarget = null;
assert_array_equals(Array.from(input['labels']), []);
x_input.shadowRoot.referenceTarget = input.id;
assert_array_equals(Array.from(input['labels']), [label]);
}, ".labels property is updated when reference target changes on shadow root");
</script>
<label id="label5-A">A
<x-input5 id="x-input5">
<template shadowrootmode="open" shadowrootreferencetarget="input5">
<input id="input5">
</template>
</x-input5>
</label>
<label id="label5-B"></label>
<script>
promise_test(async t => {
const x_input = document.getElementById('x-input5');
const input = x_input.shadowRoot.getElementById('input5');
const A = document.getElementById('label5-A');
assert_array_equals(Array.from(input['labels']), [A]);
const B = document.getElementById('label5-B');
B.appendChild(x_input);
assert_array_equals(Array.from(input['labels']), [B]);
}, ".labels property is updated when wrapped label changes");
</script>
</body>
</html>
|