Bug 1467382 - Support aria-keyshortcuts. r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D246695
This commit is contained in:
Eitan Isaacson
2025-04-29 16:42:31 +00:00
parent eab92e0de5
commit 18c81c366f
15 changed files with 144 additions and 13 deletions

View File

@@ -404,6 +404,9 @@ class Accessible {
virtual Maybe<int32_t> GetIntARIAAttr(nsAtom* aAttrName) const = 0; virtual Maybe<int32_t> GetIntARIAAttr(nsAtom* aAttrName) const = 0;
virtual bool GetStringARIAAttr(nsAtom* aAttrName,
nsAString& aAttrValue) const = 0;
/** /**
* Get the relation of the given type. * Get the relation of the given type.
*/ */

View File

@@ -4490,3 +4490,11 @@ Maybe<int32_t> LocalAccessible::GetIntARIAAttr(nsAtom* aAttrName) const {
} }
return Nothing(); return Nothing();
} }
bool LocalAccessible::GetStringARIAAttr(nsAtom* aAttrName,
nsAString& aAttrValue) const {
if (dom::Element* elm = Elm()) {
return nsAccUtils::GetARIAAttr(elm, aAttrName, aAttrValue);
}
return false;
}

View File

@@ -435,6 +435,9 @@ class LocalAccessible : public nsISupports, public Accessible {
virtual Maybe<int32_t> GetIntARIAAttr(nsAtom* aAttrName) const override; virtual Maybe<int32_t> GetIntARIAAttr(nsAtom* aAttrName) const override;
virtual bool GetStringARIAAttr(nsAtom* aAttrName,
nsAString& aAttrValue) const override;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Downcasting and types // Downcasting and types

View File

@@ -2337,6 +2337,18 @@ Maybe<int32_t> RemoteAccessible::GetIntARIAAttr(nsAtom* aAttrName) const {
return Nothing(); return Nothing();
} }
bool RemoteAccessible::GetStringARIAAttr(nsAtom* aAttrName,
nsAString& aAttrValue) const {
if (RequestDomainsIfInactive(CacheDomain::ARIA)) {
return false;
}
if (auto attrs = GetCachedARIAAttributes()) {
return attrs->GetAttribute(aAttrName, aAttrValue);
}
return false;
}
void RemoteAccessible::Language(nsAString& aLocale) { void RemoteAccessible::Language(nsAString& aLocale) {
if (RequestDomainsIfInactive(CacheDomain::Text)) { if (RequestDomainsIfInactive(CacheDomain::Text)) {
return; return;

View File

@@ -230,6 +230,9 @@ class RemoteAccessible : public Accessible, public HyperTextAccessibleBase {
virtual Maybe<int32_t> GetIntARIAAttr(nsAtom* aAttrName) const override; virtual Maybe<int32_t> GetIntARIAAttr(nsAtom* aAttrName) const override;
virtual bool GetStringARIAAttr(nsAtom* aAttrName,
nsAString& aAttrValue) const override;
virtual void Language(nsAString& aLocale) override; virtual void Language(nsAString& aLocale) override;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@@ -341,6 +341,9 @@
// AXLanguage // AXLanguage
- (NSString* _Nullable)moxLanguage; - (NSString* _Nullable)moxLanguage;
// AXKeyShortcutsValue
- (NSString* _Nullable)moxKeyShortcutsValue;
// AXMozDebugDescription // AXMozDebugDescription
- (NSString* _Nullable)moxMozDebugDescription; - (NSString* _Nullable)moxMozDebugDescription;

View File

@@ -248,6 +248,9 @@ enum CheckedState {
// override // override
- (NSString*)moxLanguage; - (NSString*)moxLanguage;
// override
- (NSString*)moxKeyShortcutsValue;
#ifndef RELEASE_OR_BETA #ifndef RELEASE_OR_BETA
// override // override
- (NSString*)moxMozDebugDescription; - (NSString*)moxMozDebugDescription;

View File

@@ -769,6 +769,19 @@ struct RoleDescrComparator {
return nsCocoaUtils::ToNSString(lang); return nsCocoaUtils::ToNSString(lang);
} }
- (NSString*)moxKeyShortcutsValue {
MOZ_ASSERT(mGeckoAccessible);
nsAutoString shortcut;
if (!mGeckoAccessible->GetStringARIAAttr(nsGkAtoms::aria_keyshortcuts,
shortcut)) {
return nil;
}
return nsCocoaUtils::ToNSString(shortcut);
}
#ifndef RELEASE_OR_BETA #ifndef RELEASE_OR_BETA
- (NSString*)moxMozDebugDescription { - (NSString*)moxMozDebugDescription {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN; NS_OBJC_BEGIN_TRY_BLOCK_RETURN;

View File

@@ -29,6 +29,8 @@ skip-if = ["os == 'mac' && os_version == '15.30' && arch == 'aarch64' && opt"] #
["browser_aria_haspopup.js"] ["browser_aria_haspopup.js"]
["browser_aria_keyshortcuts.js"]
["browser_aria_placeholder.js"] ["browser_aria_placeholder.js"]
["browser_aria_setsize.js"] ["browser_aria_setsize.js"]

View File

@@ -0,0 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Test aria-keyshortcuts
*/
addAccessibleTask(
`
<div id="btn" role="button" aria-keyshortcuts="Alt+Shift+f">bar</div>
`,
(browser, accDoc) => {
let btn = getNativeInterface(accDoc, "btn");
is(
btn.getAttributeValue("AXKeyShortcutsValue"),
"Alt+Shift+f",
"aria-keyshortcuts value is correct"
);
}
);

View File

@@ -15,6 +15,8 @@ prefs = [
["browser_groupPosition.js"] ["browser_groupPosition.js"]
["browser_keyboard_shortcut.js"]
["browser_osPicker.js"] ["browser_osPicker.js"]
["browser_role.js"] ["browser_role.js"]

View File

@@ -0,0 +1,35 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
addAccessibleTask(
`
<button id="btn1" accesskey="s">foo</button>
<div id="btn2" role="button" aria-keyshortcuts="Alt+Shift+f">bar</div>
`,
async function () {
is(
await runPython(`
global doc
doc = getDocIa2()
btn = findIa2ByDomId(doc, "btn1")
return btn.accKeyboardShortcut(CHILDID_SELF)
`),
"Alt+Shift+s",
"btn1 has correct keyboard shortcut"
);
is(
await runPython(`
btn = findIa2ByDomId(doc, "btn2")
return btn.accKeyboardShortcut(CHILDID_SELF)
`),
"Alt+Shift+f",
"btn2 has correct keyboard shortcut"
);
},
{ chrome: true, topLevel: true }
);

View File

@@ -453,3 +453,21 @@ addUiaTask(
); );
} }
); );
/**
* Test the AcceleratorKey property.
*/
addUiaTask(
`
<div id="button" role="button" aria-keyshortcuts="Alt+Shift+f">foo</div>
`,
async function testAcceleratorKey() {
await definePyVar("doc", `getDocUia()`);
is(
await runPython(`findUiaByDomId(doc, "button").CurrentAcceleratorKey`),
"Alt+Shift+f",
"button has correct AcceleratorKey"
);
},
{ uiaEnabled: true, uiaDisabled: false }
);

View File

@@ -865,15 +865,18 @@ MsaaAccessible::get_accKeyboardShortcut(
pszKeyboardShortcut); pszKeyboardShortcut);
} }
KeyBinding keyBinding = mAcc->AccessKey();
if (keyBinding.IsEmpty()) {
if (LocalAccessible* localAcc = mAcc->AsLocal()) {
keyBinding = localAcc->KeyboardShortcut();
}
}
nsAutoString shortcut; nsAutoString shortcut;
keyBinding.ToString(shortcut);
if (!mAcc->GetStringARIAAttr(nsGkAtoms::aria_keyshortcuts, shortcut)) {
KeyBinding keyBinding = mAcc->AccessKey();
if (keyBinding.IsEmpty()) {
if (LocalAccessible* localAcc = mAcc->AsLocal()) {
keyBinding = localAcc->KeyboardShortcut();
}
}
keyBinding.ToString(shortcut);
}
*pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(), shortcut.Length()); *pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(), shortcut.Length());
return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY; return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY;

View File

@@ -514,13 +514,14 @@ uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId,
switch (aPropertyId) { switch (aPropertyId) {
// Accelerator Key / shortcut. // Accelerator Key / shortcut.
case UIA_AcceleratorKeyPropertyId: { case UIA_AcceleratorKeyPropertyId: {
if (!localAcc) {
// KeyboardShortcut is only currently relevant for LocalAccessible.
break;
}
nsAutoString keyString; nsAutoString keyString;
localAcc->KeyboardShortcut().ToString(keyString); if (!acc->GetStringARIAAttr(nsGkAtoms::aria_keyshortcuts, keyString)) {
if (localAcc) {
// KeyboardShortcut is only currently relevant for LocalAccessible.
localAcc->KeyboardShortcut().ToString(keyString);
}
}
if (!keyString.IsEmpty()) { if (!keyString.IsEmpty()) {
aPropertyValue->vt = VT_BSTR; aPropertyValue->vt = VT_BSTR;