From c5469403d72f004876e892d26500c62f4f5e1714 Mon Sep 17 00:00:00 2001 From: "pcheng@gmx.com" Date: Mon, 16 Apr 2012 18:24:23 +0900 Subject: [PATCH] Bug 742657 - move nsAccUtils::GetRoleMapEntry(nsINode *aNode) into nsARIAMap, r=tbsaunde, f=surkov --- accessible/src/base/nsARIAMap.cpp | 45 +++++++++++++++++-- accessible/src/base/nsARIAMap.h | 31 ++++++++----- accessible/src/base/nsAccDocManager.cpp | 3 +- accessible/src/base/nsAccUtils.cpp | 41 +---------------- accessible/src/base/nsAccUtils.h | 10 ----- .../src/base/nsAccessibilityService.cpp | 9 ++-- accessible/src/base/nsAccessible.h | 9 ++-- accessible/src/base/nsDocAccessible.cpp | 4 +- .../src/html/nsHTMLImageMapAccessible.cpp | 2 +- 9 files changed, 76 insertions(+), 78 deletions(-) diff --git a/accessible/src/base/nsARIAMap.cpp b/accessible/src/base/nsARIAMap.cpp index 9a8eeeae0aa..b63cdfd9d73 100644 --- a/accessible/src/base/nsARIAMap.cpp +++ b/accessible/src/base/nsARIAMap.cpp @@ -39,11 +39,14 @@ #include "nsARIAMap.h" +#include "nsCoreUtils.h" #include "Role.h" #include "States.h" #include "nsIContent.h" +#include "nsWhitespaceTokenizer.h" +using namespace mozilla; using namespace mozilla::a11y; using namespace mozilla::a11y::aria; @@ -62,7 +65,7 @@ using namespace mozilla::a11y::aria; * banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs */ -nsRoleMapEntry nsARIAMap::gWAIRoleMap[] = +static nsRoleMapEntry sWAIRoleMaps[] = { { "alert", @@ -586,9 +589,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] = } }; -PRUint32 nsARIAMap::gWAIRoleMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIRoleMap); - -nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = { +static nsRoleMapEntry sLandmarkRoleMap = { "", roles::NOTHING, kUseNativeRole, @@ -667,3 +668,39 @@ nsAttributeCharacteristics nsARIAMap::gWAIUnivAttrMap[] = { }; PRUint32 nsARIAMap::gWAIUnivAttrMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIUnivAttrMap); + +nsRoleMapEntry* +aria::GetRoleMap(nsINode* aNode) +{ + nsIContent* content = nsCoreUtils::GetRoleContent(aNode); + nsAutoString roleString; + if (!content || + !content->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roleString) || + roleString.IsEmpty()) { + // We treat role="" as if the role attribute is absent (per aria spec:8.1.1) + return nsnull; + } + + nsWhitespaceTokenizer tokenizer(roleString); + while (tokenizer.hasMoreTokens()) { + // Do a binary search through table for the next role in role list + NS_LossyConvertUTF16toASCII role(tokenizer.nextToken()); + PRUint32 low = 0; + PRUint32 high = ArrayLength(sWAIRoleMaps); + while (low < high) { + PRUint32 idx = (low + high) / 2; + PRInt32 compare = strcmp(role.get(), sWAIRoleMaps[idx].roleString); + if (compare == 0) + return sWAIRoleMaps + idx; + + if (compare < 0) + high = idx; + else + low = idx + 1; + } + } + + // Always use some entry if there is a non-empty role string + // To ensure an accessible object is created + return &sLandmarkRoleMap; +} diff --git a/accessible/src/base/nsARIAMap.h b/accessible/src/base/nsARIAMap.h index 8ac668986b0..d461560d1df 100644 --- a/accessible/src/base/nsARIAMap.h +++ b/accessible/src/base/nsARIAMap.h @@ -45,6 +45,7 @@ class nsIAtom; class nsIContent; +class nsINode; //////////////////////////////////////////////////////////////////////////////// // Value constants @@ -210,18 +211,6 @@ struct nsRoleMapEntry */ struct nsARIAMap { - /** - * Array of supported ARIA role map entries and its length. - */ - static nsRoleMapEntry gWAIRoleMap[]; - static PRUint32 gWAIRoleMapLength; - - /** - * Landmark role map entry. Used when specified ARIA role isn't mapped to - * accessibility API. - */ - static nsRoleMapEntry gLandmarkRoleMap; - /** * Empty role map entry. Used by accessibility service to create an accessible * if the accessible can't use role of used accessible class. For example, @@ -257,4 +246,22 @@ struct nsARIAMap } }; +namespace mozilla { +namespace a11y { +namespace aria { + +/** + * Get the role map entry for a given DOM node. This will use the first + * ARIA role if the role attribute provides a space delimited list of roles. + * + * @param aNode [in] the DOM node to get the role map entry for + * @return a pointer to the role map entry for the ARIA role, or nsnull + * if none + */ +nsRoleMapEntry* GetRoleMap(nsINode* aNode); + +} // namespace aria +} // namespace a11y +} // namespace mozilla + #endif diff --git a/accessible/src/base/nsAccDocManager.cpp b/accessible/src/base/nsAccDocManager.cpp index 494400d7be4..358776c410d 100644 --- a/accessible/src/base/nsAccDocManager.cpp +++ b/accessible/src/base/nsAccDocManager.cpp @@ -41,6 +41,7 @@ #include "nsAccessibilityService.h" #include "nsAccUtils.h" #include "nsApplicationAccessible.h" +#include "nsARIAMap.h" #include "nsRootAccessibleWrap.h" #include "States.h" @@ -402,7 +403,7 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument) docAcc->Shutdown(); return nsnull; } - docAcc->SetRoleMapEntry(nsAccUtils::GetRoleMapEntry(aDocument)); + docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument)); // Bind the document to the tree. if (isRootDoc) { diff --git a/accessible/src/base/nsAccUtils.cpp b/accessible/src/base/nsAccUtils.cpp index d5aac691740..2ddb521205c 100644 --- a/accessible/src/base/nsAccUtils.cpp +++ b/accessible/src/base/nsAccUtils.cpp @@ -174,7 +174,7 @@ nsAccUtils::SetLiveContainerAttributes(nsIPersistentProperties *aAttributes, // container-live, and container-live-role attributes if (live.IsEmpty()) { - nsRoleMapEntry *role = GetRoleMapEntry(ancestor); + nsRoleMapEntry* role = aria::GetRoleMap(ancestor); if (nsAccUtils::HasDefinedARIAToken(ancestor, nsGkAtoms::aria_live)) { ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_live, @@ -418,45 +418,6 @@ nsAccUtils::GetScreenCoordsForParent(nsAccessNode *aAccessNode) return nsIntPoint(parentRect.x, parentRect.y); } -nsRoleMapEntry* -nsAccUtils::GetRoleMapEntry(nsINode *aNode) -{ - nsIContent *content = nsCoreUtils::GetRoleContent(aNode); - nsAutoString roleString; - if (!content || - !content->GetAttr(kNameSpaceID_None, nsGkAtoms::role, roleString) || - roleString.IsEmpty()) { - // We treat role="" as if the role attribute is absent (per aria spec:8.1.1) - return nsnull; - } - - nsWhitespaceTokenizer tokenizer(roleString); - while (tokenizer.hasMoreTokens()) { - // Do a binary search through table for the next role in role list - NS_LossyConvertUTF16toASCII role(tokenizer.nextToken()); - PRUint32 low = 0; - PRUint32 high = nsARIAMap::gWAIRoleMapLength; - while (low < high) { - PRUint32 index = (low + high) / 2; - PRInt32 compare = PL_strcmp(role.get(), nsARIAMap::gWAIRoleMap[index].roleString); - if (compare == 0) { - // The role attribute maps to an entry in the role table - return &nsARIAMap::gWAIRoleMap[index]; - } - if (compare < 0) { - high = index; - } - else { - low = index + 1; - } - } - } - - // Always use some entry if there is a non-empty role string - // To ensure an accessible object is created - return &nsARIAMap::gLandmarkRoleMap; -} - PRUint8 nsAccUtils::GetAttributeCharacteristics(nsIAtom* aAtom) { diff --git a/accessible/src/base/nsAccUtils.h b/accessible/src/base/nsAccUtils.h index 875cfa26bc6..35c495723fa 100644 --- a/accessible/src/base/nsAccUtils.h +++ b/accessible/src/base/nsAccUtils.h @@ -249,16 +249,6 @@ public: */ static nsIntPoint GetScreenCoordsForParent(nsAccessNode *aAccessNode); - /** - * Get the role map entry for a given DOM node. This will use the first - * ARIA role if the role attribute provides a space delimited list of roles. - * - * @param aNode [in] the DOM node to get the role map entry for - * @return a pointer to the role map entry for the ARIA role, or nsnull - * if none - */ - static nsRoleMapEntry *GetRoleMapEntry(nsINode *aNode); - /** * Return the role of the given accessible. */ diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 60a25f1a447..a4e342425f3 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -1075,12 +1075,12 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode, } newAcc = new nsHyperTextAccessibleWrap(content, docAcc); - if (docAcc->BindToDocument(newAcc, nsAccUtils::GetRoleMapEntry(aNode))) + if (docAcc->BindToDocument(newAcc, aria::GetRoleMap(aNode))) return newAcc; return nsnull; } - nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode); + nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aNode); if (roleMapEntry && !nsCRT::strcmp(roleMapEntry->roleString, "presentation")) { // Ignore presentation role if element is focusable (focus event shouldn't // be ever lost and should be sensible). @@ -1127,8 +1127,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode, } #ifdef DEBUG - nsRoleMapEntry *tableRoleMapEntry = - nsAccUtils::GetRoleMapEntry(tableContent); + nsRoleMapEntry* tableRoleMapEntry = aria::GetRoleMap(tableContent); NS_ASSERTION(tableRoleMapEntry && !nsCRT::strcmp(tableRoleMapEntry->roleString, "presentation"), "No accessible for parent table and it didn't have role of presentation"); @@ -1667,7 +1666,7 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame, if (tag == nsGkAtoms::a) { // Only some roles truly enjoy life as nsHTMLLinkAccessibles, for details // see closed bug 494807. - nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aContent); + nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent); if (roleMapEntry && roleMapEntry->role != roles::NOTHING && roleMapEntry->role != roles::LINK) { nsAccessible* accessible = new nsHyperTextAccessibleWrap(aContent, aDoc); diff --git a/accessible/src/base/nsAccessible.h b/accessible/src/base/nsAccessible.h index cd863ee69c3..b951ad44b7d 100644 --- a/accessible/src/base/nsAccessible.h +++ b/accessible/src/base/nsAccessible.h @@ -276,7 +276,7 @@ public: * @param aRoleMapEntry The ARIA nsRoleMapEntry* for the accessible, or * nsnull if none. */ - virtual void SetRoleMapEntry(nsRoleMapEntry *aRoleMapEntry); + virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry); /** * Update the children cache. @@ -836,8 +836,11 @@ protected: nsAutoPtr mGroupInfo; friend class AccGroupInfo; - - nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well + + /** + * Non-null indicates author-supplied role; possibly state & value as well + */ + nsRoleMapEntry* mRoleMapEntry; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessible, diff --git a/accessible/src/base/nsDocAccessible.cpp b/accessible/src/base/nsDocAccessible.cpp index 8c201a508e1..7702146a4ca 100644 --- a/accessible/src/base/nsDocAccessible.cpp +++ b/accessible/src/base/nsDocAccessible.cpp @@ -285,7 +285,7 @@ nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry) // Allow use of ARIA role from outer to override nsIContent *ownerContent = parentDoc->FindContentForSubDocument(mDocument); if (ownerContent) { - nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(ownerContent); + nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(ownerContent); if (roleMapEntry) mRoleMapEntry = roleMapEntry; // Override } @@ -1698,7 +1698,7 @@ nsDocAccessible::UpdateAccessibleOnAttrChange(dom::Element* aElement, // It is common for js libraries to set the role on the body element after // the document has loaded. In this case we just update the role map entry. if (mContent == aElement) { - SetRoleMapEntry(nsAccUtils::GetRoleMapEntry(aElement)); + SetRoleMapEntry(aria::GetRoleMap(aElement)); return true; } diff --git a/accessible/src/html/nsHTMLImageMapAccessible.cpp b/accessible/src/html/nsHTMLImageMapAccessible.cpp index 3d834702b4c..039ec914d1b 100644 --- a/accessible/src/html/nsHTMLImageMapAccessible.cpp +++ b/accessible/src/html/nsHTMLImageMapAccessible.cpp @@ -143,7 +143,7 @@ nsHTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents) nsAccessible* area = mChildren.SafeElementAt(idx); if (!area || area->GetContent() != areaContent) { nsRefPtr area = new nsHTMLAreaAccessible(areaContent, mDoc); - if (!mDoc->BindToDocument(area, nsAccUtils::GetRoleMapEntry(areaContent))) + if (!mDoc->BindToDocument(area, aria::GetRoleMap(areaContent))) break; if (!InsertChildAt(idx, area)) {