Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /shadow-dom/reference-target/tentative/label-for.html - WPT Dashboard Interop Dashboard
<!DOCTYPE HTML>
<html>
<head>
<script src="/html/resources/common.js"></script>
<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>
<label for="x-input1">Input 1</label>
<x-input1 id="x-input1">
<template shadowrootmode="open" shadowrootreferencetarget="input1">
<input id="input1">
</template>
</x-input1>
<script>
promise_test(async t => {
const x_input = document.getElementById('x-input1');
const input = x_input.shadowRoot.getElementById('input1');
// The label should apply to the input element and not the host.
assert_equals(await test_driver.get_computed_label(x_input), "");
assert_equals(await test_driver.get_computed_label(input), "Input 1");
}, "Label for attribute targets a custom element using shadowrootreferencetarget");
</script>
<label for="x-outer2">Input 2</label>
<x-outer2 id="x-outer2">
<template shadowrootmode="open" shadowrootreferencetarget="x-inner2">
<x-inner2 id="x-inner2">
<template shadowrootmode="open" shadowrootreferencetarget="input2">
<input id="input2">
</template>
</x-inner2>
</template>
</x-outer2>
<script>
promise_test(async t => {
const outer = document.getElementById('x-outer2');
const inner = outer.shadowRoot.getElementById('x-inner2');
const input = inner.shadowRoot.getElementById('input2');
// The label should apply to the input element and not any of the hosts.
assert_equals(await test_driver.get_computed_label(outer), "");
assert_equals(await test_driver.get_computed_label(inner), "");
assert_equals(await test_driver.get_computed_label(input), "Input 2");
}, "Label for attribute targets a custom element using shadowrootreferencetarget inside multiple layers of shadow roots");
</script>
<label for="x-outer3">A</label>
<x-outer3 id="x-outer3">
<template shadowrootmode="open" shadowrootreferencetarget="x-inner3">
<label for="x-inner3">B</label>
<x-inner3 id="x-inner3">
<template shadowrootmode="open" shadowrootreferencetarget="input3">
<label for="input3">C</label>
<input id="input3">
<label for="input3">D</label>
</template>
</x-inner3>
<label for="x-inner3">E</label>
</template>
</x-outer3>
<label for="x-outer3">F</label>
<script>
promise_test(async t => {
const outer = document.getElementById('x-outer3');
const inner = outer.shadowRoot.getElementById('x-inner3');
const input = inner.shadowRoot.getElementById('input3');
const computed_label = await test_driver.get_computed_label(input);
assert_equals(computed_label, "A B C D E F");
}, "Multiple labels targeting a custom element using shadowrootreferencetarget inside multiple layers of shadow roots");
</script>
<label id="label-input4">Input 4</label>
<x-input1 id="x-input4">
<template shadowrootmode="open" shadowrootreferencetarget="input4">
<input id="input4">
</template>
</x-input1>
<script>
promise_test(async t => {
const label = document.getElementById('label-input4');
label.htmlFor = "x-input4";
const x_input = document.getElementById('x-input4');
const input = x_input.shadowRoot.getElementById('input4');
// The label should apply to the input element and not the host.
assert_equals(await test_driver.get_computed_label(x_input), "");
assert_equals(await test_driver.get_computed_label(input), "Input 4");
}, "Setting .htmlFor property to target a custom element using shadowrootreferencetarget");
</script>
<div id="test-container"></div>
<script>
for(let referenced_element_type of HTML5_LABELABLE_ELEMENTS) {
promise_test(async t => {
const test_container = document.querySelector("#test-container");
test_container.setHTMLUnsafe(`
<label>
<fancy-element id="fancy">
<template shadowrootmode="open" shadowrootreferencetarget="target">
<${referenced_element_type} id="target"></${referenced_element_type}>
</template>
</fancy-element>
fancy custom element inside label
</label>`);
const fancy_element = document.getElementById('fancy');
const target_element = fancy_element.shadowRoot.getElementById('target');
assert_equals(await test_driver.get_computed_label(fancy_element), "");
assert_equals(await test_driver.get_computed_label(target_element), "fancy custom element inside label");
}, "Implicit <label> association should work with a custom element targeting '" + referenced_element_type + "'");
}
</script>
<label>
<fancy-input id="fancy-input1">
<template shadowrootmode="open" shadowrootreferencetarget="real-input">
<input id="real-input">
</template>
</fancy-input>
<fancy-input id="fancy-input2">
<template shadowrootmode="open" shadowrootreferencetarget="real-input">
<input id="real-input">
</template>
</fancy-input>
fancy input inside label
</label>
<script>
promise_test(async t => {
const fancy_input1 = document.getElementById('fancy-input1');
const fancy_input2 = document.getElementById('fancy-input2');
const real_input1 = fancy_input1.shadowRoot.getElementById('real-input');
const real_input2 = fancy_input2.shadowRoot.getElementById('real-input');
assert_equals(await test_driver.get_computed_label(fancy_input1), "");
assert_equals(await test_driver.get_computed_label(fancy_input2), "");
assert_equals(await test_driver.get_computed_label(real_input1), "fancy input inside label");
assert_equals(await test_driver.get_computed_label(real_input2), "");
}, "Implicit <label> association should apply to only the first labelable custom element");
</script>
</body>
</html>