author | pcheng@gmx.com <pcheng@gmx.com> |
Mon, 16 Apr 2012 18:24:23 +0900 | |
changeset 91748 | 5972e57175a560315683a098c0e57563027db456 |
parent 91747 | 01fd11649cc8f93cc9d4df770884019938794361 |
child 91749 | 61088f8aa842fb7042453ce2b2565492b32322d8 |
push id | 22472 |
push user | eakhgari@mozilla.com |
push date | Mon, 16 Apr 2012 15:03:21 +0000 |
treeherder | mozilla-central@0066df252596 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tbsaunde |
bugs | 742657 |
milestone | 14.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/src/base/nsARIAMap.cpp +++ b/accessible/src/base/nsARIAMap.cpp @@ -34,21 +34,24 @@ * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #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; /** * This list of WAI-defined roles are currently hardcoded. * Eventually we will most likely be loading an RDF resource that contains this information * Using RDF will also allow for role extensibility. See bug 280138. * @@ -57,17 +60,17 @@ using namespace mozilla::a11y::aria; * When no nsIAccessibleRole enum mapping exists for an ARIA role, the * role will be exposed via the object attribute "xml-roles". * In addition, in MSAA, the unmapped role will also be exposed as a BSTR string role. * * There are no nsIAccessibleRole enums for the following landmark roles: * banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs */ -nsRoleMapEntry nsARIAMap::gWAIRoleMap[] = +static nsRoleMapEntry sWAIRoleMaps[] = { { "alert", roles::ALERT, kUseMapRole, eNoValue, eNoAction, eNoLiveAttr, @@ -581,19 +584,17 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] // on states eNoLiveAttr, kNoReqStates, eARIASelectable, eARIACheckedMixed } }; -PRUint32 nsARIAMap::gWAIRoleMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIRoleMap); - -nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = { +static nsRoleMapEntry sLandmarkRoleMap = { "", roles::NOTHING, kUseNativeRole, eNoValue, eNoAction, eNoLiveAttr, kNoReqStates }; @@ -662,8 +663,44 @@ nsAttributeCharacteristics nsARIAMap::gW {&nsGkAtoms::aria_sort, ATTR_VALTOKEN }, {&nsGkAtoms::aria_valuenow, ATTR_BYPASSOBJ }, {&nsGkAtoms::aria_valuemin, ATTR_BYPASSOBJ }, {&nsGkAtoms::aria_valuemax, ATTR_BYPASSOBJ }, {&nsGkAtoms::aria_valuetext, ATTR_BYPASSOBJ } }; 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; +}
--- a/accessible/src/base/nsARIAMap.h +++ b/accessible/src/base/nsARIAMap.h @@ -40,16 +40,17 @@ #ifndef _nsARIAMap_H_ #define _nsARIAMap_H_ #include "ARIAStateMap.h" #include "mozilla/a11y/Role.h" class nsIAtom; class nsIContent; +class nsINode; //////////////////////////////////////////////////////////////////////////////// // Value constants /** * Used to define if role requires to expose nsIAccessibleValue. */ enum EValueRule @@ -206,28 +207,16 @@ struct nsRoleMapEntry /** * These are currently initialized (hardcoded) in nsARIAMap.cpp, * and provide the mappings for WAI-ARIA roles and properties using the * structs defined in this file. */ 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, * it is used for table cells that aren't contained by table. */ static nsRoleMapEntry gEmptyRoleMap; /** * State map of ARIA states applied to any accessible not depending on @@ -252,9 +241,27 @@ struct nsARIAMap while (mozilla::a11y::aria::MapToState(gWAIUnivStateMap[index], aElement, &state)) index++; return state; } }; +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
--- a/accessible/src/base/nsAccDocManager.cpp +++ b/accessible/src/base/nsAccDocManager.cpp @@ -36,16 +36,17 @@ * * ***** END LICENSE BLOCK ***** */ #include "nsAccDocManager.h" #include "nsAccessibilityService.h" #include "nsAccUtils.h" #include "nsApplicationAccessible.h" +#include "nsARIAMap.h" #include "nsRootAccessibleWrap.h" #include "States.h" #include "nsCURILoader.h" #include "nsDocShellLoadTypes.h" #include "nsIChannel.h" #include "nsIContentViewer.h" #include "nsIDOMDocument.h" @@ -397,17 +398,17 @@ nsAccDocManager::CreateDocOrRootAccessib if (!docAcc || !mDocAccessibleCache.Put(aDocument, docAcc)) return nsnull; // Initialize the document accessible. if (!docAcc->Init()) { docAcc->Shutdown(); return nsnull; } - docAcc->SetRoleMapEntry(nsAccUtils::GetRoleMapEntry(aDocument)); + docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument)); // Bind the document to the tree. if (isRootDoc) { nsAccessible* appAcc = nsAccessNode::GetApplicationAccessible(); if (!appAcc->AppendChild(docAcc)) { docAcc->Shutdown(); return nsnull; }
--- a/accessible/src/base/nsAccUtils.cpp +++ b/accessible/src/base/nsAccUtils.cpp @@ -169,17 +169,17 @@ nsAccUtils::SetLiveContainerAttributes(n // container-relevant attribute if (relevant.IsEmpty() && nsAccUtils::HasDefinedARIAToken(ancestor, nsGkAtoms::aria_relevant) && ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_relevant, relevant)) SetAccAttr(aAttributes, nsGkAtoms::containerRelevant, relevant); // 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, live); } else if (role) { GetLiveAttrValue(role->liveAttRule, live); } if (!live.IsEmpty()) { @@ -413,55 +413,16 @@ nsAccUtils::GetScreenCoordsForParent(nsA nsIFrame *parentFrame = parent->GetFrame(); if (!parentFrame) return nsIntPoint(0, 0); nsIntRect parentRect = parentFrame->GetScreenRectExternal(); 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) { for (PRUint32 i = 0; i < nsARIAMap::gWAIUnivAttrMapLength; i++) if (*nsARIAMap::gWAIUnivAttrMap[i].attributeName == aAtom) return nsARIAMap::gWAIUnivAttrMap[i].characteristics; return 0;
--- a/accessible/src/base/nsAccUtils.h +++ b/accessible/src/base/nsAccUtils.h @@ -245,26 +245,16 @@ public: /** * Returns coordinates relative screen for the parent of the given accessible. * * @param aAccessNode the accessible */ 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. */ static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role = nsIAccessibleRole::ROLE_NOTHING; if (aAcc) aAcc->GetRole(&role);
--- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -1070,22 +1070,22 @@ nsAccessibilityService::GetOrCreateAcces weakFrame->GetParent()).IsEmpty()) { if (aIsSubtreeHidden) *aIsSubtreeHidden = true; return nsnull; } 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). if (content->IsFocusable()) roleMapEntry = nsnull; else return nsnull; } @@ -1122,18 +1122,17 @@ nsAccessibilityService::GetOrCreateAcces if (role != roles::TABLE && role != roles::TREE_TABLE) roleMapEntry = &nsARIAMap::gEmptyRoleMap; } break; } #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"); #endif if (!roleMapEntry && !content->IsFocusable()) { // Table-related descendants of presentation table are also // presentation if they aren't focusable and have not explicit ARIA @@ -1662,17 +1661,17 @@ nsAccessibilityService::CreateHTMLAccess nsAccessible* accessible = new nsHTMLListAccessible(aContent, aDoc); NS_IF_ADDREF(accessible); return accessible; } 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); NS_IF_ADDREF(accessible); return accessible; } nsAccessible* accessible = new nsHTMLLinkAccessible(aContent, aDoc);
--- a/accessible/src/base/nsAccessible.h +++ b/accessible/src/base/nsAccessible.h @@ -271,17 +271,17 @@ public: /** * Set the ARIA role map entry for a new accessible. * For a newly created accessible, specify which role map entry should be used. * * @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. */ inline bool UpdateChildren() { InvalidateChildren(); return EnsureChildren(); @@ -831,18 +831,21 @@ protected: PRUint32 mFlags; nsAutoPtr<EmbeddedObjCollector> mEmbeddedObjCollector; PRInt32 mIndexOfEmbeddedChild; friend class EmbeddedObjCollector; nsAutoPtr<AccGroupInfo> 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, NS_ACCESSIBLE_IMPL_IID) /** * Represent key binding associated with accessible (such as access key and
--- a/accessible/src/base/nsDocAccessible.cpp +++ b/accessible/src/base/nsDocAccessible.cpp @@ -280,17 +280,17 @@ nsDocAccessible::SetRoleMapEntry(nsRoleM nsIDocument *parentDoc = mDocument->GetParentDocument(); if (!parentDoc) return; // No parent document for the root document // 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 } } void nsDocAccessible::Description(nsString& aDescription) { @@ -1693,17 +1693,17 @@ nsDocAccessible::RemoveDependentIDsFor(n bool nsDocAccessible::UpdateAccessibleOnAttrChange(dom::Element* aElement, nsIAtom* aAttribute) { if (aAttribute == nsGkAtoms::role) { // 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; } // Recreate the accessible when role is changed because we might require a // different accessible class for the new role or the accessible may expose // a different sets of interfaces (COM restriction). RecreateAccessible(aElement);
--- a/accessible/src/html/nsHTMLImageMapAccessible.cpp +++ b/accessible/src/html/nsHTMLImageMapAccessible.cpp @@ -138,17 +138,17 @@ nsHTMLImageMapAccessible::UpdateChildAre // Insert new areas into the tree. PRUint32 areaElmCount = imageMapObj->AreaCount(); for (PRUint32 idx = 0; idx < areaElmCount; idx++) { nsIContent* areaContent = imageMapObj->GetAreaAt(idx); nsAccessible* area = mChildren.SafeElementAt(idx); if (!area || area->GetContent() != areaContent) { nsRefPtr<nsAccessible> area = new nsHTMLAreaAccessible(areaContent, mDoc); - if (!mDoc->BindToDocument(area, nsAccUtils::GetRoleMapEntry(areaContent))) + if (!mDoc->BindToDocument(area, aria::GetRoleMap(areaContent))) break; if (!InsertChildAt(idx, area)) { mDoc->UnbindFromDocument(area); break; } if (aDoFireEvents) {