LibWeb: Implement HTMLElement.accessKeyLabel

Implement the accessKeyLabel IDL attribute per the HTML spec.

We mimic Chromium's behavior and treat the accesskey attribute value as
a single key rather than splitting on whitespace, since no browser
besides IE/Edge implemented the spec's splitting approach.

See https://github.com/whatwg/html/issues/3769
This commit is contained in:
Johan Dahlin 2026-03-19 18:36:55 +00:00 committed by Andreas Kling
parent dfe5d009d0
commit 9a34fb59aa
3 changed files with 63 additions and 2 deletions

View file

@ -2046,8 +2046,35 @@ void HTMLElement::removed_from(Node* old_parent, Node& old_root)
// https://html.spec.whatwg.org/multipage/interaction.html#dom-accesskeylabel
String HTMLElement::access_key_label() const
{
dbgln("FIXME: Implement HTMLElement::access_key_label()");
return String {};
// The accessKeyLabel IDL attribute must return a string that represents the element's assigned access key, if any.
// If the element does not have one, then the IDL attribute must return the empty string.
// An element's assigned access key is a key combination derived from the element's accesskey content attribute.
// https://html.spec.whatwg.org/multipage/interaction.html#assigned-access-key
// 1. If the element has no accesskey attribute, then skip to the fallback step below.
auto access_key = get_attribute(HTML::AttributeNames::accesskey);
if (!access_key.has_value() || access_key->is_empty())
return String {};
// 2. Otherwise, split the attribute's value on ASCII whitespace, and let keys be the resulting tokens.
// 3. For each value in keys in turn, in the order the tokens appeared in the attribute's value, run the following substeps:
// 3.1. If the value is not a string exactly one code point in length, then skip the remainder of these steps for this value.
// NB: We mimic Chromium here and treat the attribute value as a single key rather than splitting on whitespace.
// The spec says to split on whitespace and try each token, but no browser besides IE/Edge implemented that.
// If there is more than one code point, no access key is assigned. https://github.com/whatwg/html/issues/3769
if (access_key->code_points().length() > 1)
return String {};
// FIXME: 3.2. If the value does not correspond to a key on the system's keyboard, then skip the remainder of these steps for this value.
// FIXME: 3.3. If the user agent can find a mix of zero or more modifier keys that, combined with the key that corresponds to
// the value given in the attribute, can be used as the access key, then the user agent may assign that combination
// of keys as the element's assigned access key and return.
return *access_key;
// 4. Fallback: Optionally, the user agent may assign a key combination of its choosing as the element's assigned access key
// and then return.
// 5. If this step is reached, the element has no assigned access key.
}
// https://html.spec.whatwg.org/multipage/dnd.html#dom-draggable

View file

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Pass
Pass Returns non empty string when accesskey is valid
Pass Returns empty string when accesskey is invalid

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>accessKeyLabel attribute</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<script>
function createButtonWithAccessKey(accessKey) {
const button = document.createElement('button');
button.setAttribute('accesskey', accessKey);
return button;
}
// The modifiers are not the same across all browser vendors.
// Therefore, the test uses non empty.
test(() => {
const element = createButtonWithAccessKey('b');
assert_not_equals(element.accessKeyLabel, '');
}, 'Returns non empty string when accesskey is valid');
test(() => {
const element = createButtonWithAccessKey('s 0');
assert_equals(element.accessKeyLabel, '');
}, 'Returns empty string when accesskey is invalid');
</script>
</body>
</html>