mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Bug 1768927 - Preload localized role strings and heading levels at init. r=Jamie
We can't use the StringBundle object off the main thread. We need to pre-load all the strings we may use. This is a small set of roles. We also need formatted heading levels, so we preload heading level 1 to 6. Differential Revision: https://phabricator.services.mozilla.com/D146112
This commit is contained in:
parent
9e50a40691
commit
dbd21dbf8b
@ -529,11 +529,13 @@ void AccessibleWrap::GetRoleDescription(role aRole, AccAttributes* aAttributes,
|
||||
nsAString& aRoleDescription) {
|
||||
if (aRole == roles::HEADING && aAttributes) {
|
||||
// The heading level is an attribute, so we need that.
|
||||
AutoTArray<nsString, 1> formatString;
|
||||
if (aAttributes->GetAttribute(nsGkAtoms::level,
|
||||
*formatString.AppendElement()) &&
|
||||
LocalizeString("headingLevel", aRoleDescription, formatString)) {
|
||||
return;
|
||||
nsAutoString headingLevel;
|
||||
if (aAttributes->GetAttribute(nsGkAtoms::level, headingLevel)) {
|
||||
nsAutoString token(u"heading-");
|
||||
token.Append(headingLevel);
|
||||
if (LocalizeString(token, aRoleDescription)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -542,8 +544,7 @@ void AccessibleWrap::GetRoleDescription(role aRole, AccAttributes* aAttributes,
|
||||
if (aAttributes->GetAttribute(nsGkAtoms::xmlroles, xmlRoles)) {
|
||||
nsWhitespaceTokenizer tokenizer(xmlRoles);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
if (LocalizeString(NS_ConvertUTF16toUTF8(tokenizer.nextToken()).get(),
|
||||
aRoleDescription)) {
|
||||
if (LocalizeString(tokenizer.nextToken(), aRoleDescription)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -551,7 +552,7 @@ void AccessibleWrap::GetRoleDescription(role aRole, AccAttributes* aAttributes,
|
||||
}
|
||||
|
||||
GetAccService()->GetStringRole(aRole, aGeckoRole);
|
||||
LocalizeString(NS_ConvertUTF16toUTF8(aGeckoRole).get(), aRoleDescription);
|
||||
LocalizeString(aGeckoRole, aRoleDescription);
|
||||
}
|
||||
|
||||
int32_t AccessibleWrap::AndroidClass(Accessible* aAccessible) {
|
||||
|
@ -19,11 +19,63 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
static nsIStringBundle* sStringBundle;
|
||||
static nsTHashMap<nsStringHashKey, nsString> sLocalizedStrings;
|
||||
|
||||
void a11y::PlatformInit() {}
|
||||
void a11y::PlatformInit() {
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
components::StringBundle::Service();
|
||||
if (!stringBundleService) return;
|
||||
|
||||
void a11y::PlatformShutdown() { NS_IF_RELEASE(sStringBundle); }
|
||||
nsCOMPtr<nsIStringBundle> stringBundle;
|
||||
nsCOMPtr<nsIStringBundleService> sbs = components::StringBundle::Service();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get string bundle service");
|
||||
return;
|
||||
}
|
||||
|
||||
rv = sbs->CreateBundle(ROLE_STRINGS_URL, getter_AddRefs(stringBundle));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get string bundle");
|
||||
return;
|
||||
}
|
||||
|
||||
nsString localizedStr;
|
||||
// Preload the state required localized string.
|
||||
rv = stringBundle->GetStringFromName("stateRequired", localizedStr);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
sLocalizedStrings.InsertOrUpdate(u"stateRequired"_ns, localizedStr);
|
||||
}
|
||||
|
||||
// Preload heading level localized descriptions 1 thru 6.
|
||||
for (int32_t level = 1; level <= 6; level++) {
|
||||
nsAutoString token;
|
||||
token.AppendPrintf("heading-%d", level);
|
||||
|
||||
nsAutoString formatString;
|
||||
formatString.AppendInt(level);
|
||||
AutoTArray<nsString, 1> formatParams;
|
||||
formatParams.AppendElement(formatString);
|
||||
rv = stringBundle->FormatStringFromName("headingLevel", formatParams,
|
||||
localizedStr);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
sLocalizedStrings.InsertOrUpdate(token, localizedStr);
|
||||
}
|
||||
}
|
||||
|
||||
// Preload any roles that have localized versions
|
||||
#define ROLE(geckoRole, stringRole, atkRole, macRole, macSubrole, msaaRole, \
|
||||
ia2Role, androidClass, nameRule) \
|
||||
rv = stringBundle->GetStringFromName(stringRole, localizedStr); \
|
||||
if (NS_SUCCEEDED(rv)) { \
|
||||
sLocalizedStrings.InsertOrUpdate(u##stringRole##_ns, localizedStr); \
|
||||
}
|
||||
|
||||
#include "RoleMap.h"
|
||||
#undef ROLE
|
||||
}
|
||||
|
||||
void a11y::PlatformShutdown() { sLocalizedStrings.Clear(); }
|
||||
|
||||
void a11y::ProxyCreated(RemoteAccessible* aProxy) {
|
||||
SessionAccessibility::RegisterAccessible(aProxy);
|
||||
@ -202,42 +254,14 @@ void a11y::ProxyBatch(RemoteAccessible* aDocument, const uint64_t aBatchType,
|
||||
}
|
||||
}
|
||||
|
||||
bool a11y::LocalizeString(const char* aToken, nsAString& aLocalized,
|
||||
const nsTArray<nsString>& aFormatString) {
|
||||
bool a11y::LocalizeString(const nsAString& aToken, nsAString& aLocalized) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
nsresult rv = NS_OK;
|
||||
if (!sStringBundle) {
|
||||
nsCOMPtr<nsIStringBundleService> sbs = components::StringBundle::Service();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get string bundle service");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStringBundle> sb;
|
||||
rv = sbs->CreateBundle(ROLE_STRINGS_URL, getter_AddRefs(sb));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get string bundle");
|
||||
return false;
|
||||
}
|
||||
|
||||
sb.forget(&sStringBundle);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(sStringBundle);
|
||||
|
||||
if (aFormatString.Length()) {
|
||||
rv = sStringBundle->FormatStringFromName(aToken, aFormatString, aLocalized);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return true;
|
||||
}
|
||||
auto str = sLocalizedStrings.Lookup(aToken);
|
||||
if (str) {
|
||||
aLocalized.Assign(*str);
|
||||
} else {
|
||||
rv = sStringBundle->GetStringFromName(aToken, aLocalized);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
NS_WARNING("Failed to localize string");
|
||||
aLocalized.AssignLiteral("");
|
||||
return false;
|
||||
return !!str;
|
||||
}
|
||||
|
@ -719,7 +719,7 @@ mozilla::java::GeckoBundle::LocalRef SessionAccessibility::ToBundle(
|
||||
|
||||
if ((aState & states::REQUIRED) != 0) {
|
||||
nsAutoString requiredString;
|
||||
if (LocalizeString("stateRequired", requiredString)) {
|
||||
if (LocalizeString(u"stateRequired"_ns, requiredString)) {
|
||||
if (!hint.IsEmpty()) {
|
||||
// If the hint is non-empty, concatenate with a comma for a brief pause.
|
||||
hint.AppendLiteral(", ");
|
||||
@ -899,7 +899,7 @@ void SessionAccessibility::PopulateNodeInfo(
|
||||
|
||||
if ((state & states::REQUIRED) != 0) {
|
||||
nsAutoString requiredString;
|
||||
if (LocalizeString("stateRequired", requiredString)) {
|
||||
if (LocalizeString(u"stateRequired"_ns, requiredString)) {
|
||||
if (!hint.IsEmpty()) {
|
||||
// If the hint is non-empty, concatenate with a comma for a brief pause.
|
||||
hint.AppendLiteral(", ");
|
||||
|
@ -141,9 +141,7 @@ void ProxyBatch(RemoteAccessible* aDocument, const uint64_t aBatchType,
|
||||
const nsTArray<RemoteAccessible*>& aAccessibles,
|
||||
const nsTArray<BatchData>& aData);
|
||||
|
||||
bool LocalizeString(
|
||||
const char* aToken, nsAString& aLocalized,
|
||||
const nsTArray<nsString>& aFormatString = nsTArray<nsString>());
|
||||
bool LocalizeString(const nsAString& aToken, nsAString& aLocalized);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
|
Loading…
Reference in New Issue
Block a user