Bug 390280. Add missing ARIA roles. r=ginn.chen, a=dsicore
authoraaronleventhal@moonset.net
Fri, 03 Aug 2007 19:15:52 -0700
changeset 4270 1db1f95bd7f0557722ae53bc167e84e03603df7a
parent 4269 6e90163c5f070208e457240fe977ff6a5f9e7957
child 4271 1b0570522baddc692a7e01cc742a432d476a520e
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersginn.chen, dsicore
bugs390280
milestone1.9a8pre
Bug 390280. Add missing ARIA roles. r=ginn.chen, a=dsicore
accessible/public/nsIAccessibleRole.idl
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/atk/nsAccessibleWrap.h
accessible/src/atk/nsMaiInterfaceComponent.cpp
accessible/src/atk/nsRoleMap.h
accessible/src/base/nsARIAMap.cpp
accessible/src/base/nsAccessibilityService.h
accessible/src/html/nsHTMLImageAccessible.cpp
accessible/src/mac/nsAccessibleWrap.h
accessible/src/mac/nsRoleMap.h
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/msaa/nsAccessibleWrap.h
accessible/src/msaa/nsRoleMap.h
--- a/accessible/public/nsIAccessibleRole.idl
+++ b/accessible/public/nsIAccessibleRole.idl
@@ -39,17 +39,17 @@
 #include "nsISupports.idl"
 
 /**
  * Defines cross platform (Gecko) roles.
  *
  * @note - When adding a new role, be sure to also add it to nsRoleMap.h for
  *         each platform.
  */
-[scriptable, uuid(d6d73bc4-0fe9-46a1-a8dd-6d93b041e54b)]
+[scriptable, uuid(31685b85-36a3-448c-99ed-b034a198e303)]
 interface nsIAccessibleRole : nsISupports
 {
   /**
    * Used when accessible hans't strong defined role.
    */
   const unsigned long ROLE_NOTHING = 0;
 
   /**
@@ -739,14 +739,19 @@ interface nsIAccessibleRole : nsISupport
   const unsigned long ROLE_COMBOBOX_LIST = 114;
 
   /**
    * A item of list that is shown by combobox;
    */
   const unsigned long ROLE_COMBOBOX_LISTITEM = 115;
 
   /**
+   * An image map -- has child links representing the areas
+   */
+  const unsigned long ROLE_IMAGE_MAP = 116;
+  
+  /**
    * It's not role actually. This contanst is important to help ensure
    * nsRoleMap's are synchronized.
    */
-  const unsigned long ROLE_LAST_ENTRY = 116;
+  const unsigned long ROLE_LAST_ENTRY = 117;
 };
 
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -422,93 +422,95 @@ nsAccessibleWrap::CreateMaiInterfaces(vo
     PRUint8 actionCount = 0;
     nsresult rv = GetNumActions(&actionCount);
     if (NS_SUCCEEDED(rv) && actionCount > 0) {
        interfacesBits |= 1 << MAI_INTERFACE_ACTION; 
     }
 
     PRUint32 accRole;
     GetRole(&accRole);
-
+  
     //nsIAccessibleText
     nsCOMPtr<nsIAccessibleText> accessInterfaceText;
     QueryInterface(NS_GET_IID(nsIAccessibleText),
                    getter_AddRefs(accessInterfaceText));
     if (accessInterfaceText) {
         interfacesBits |= 1 << MAI_INTERFACE_TEXT;
     }
 
     //nsIAccessibleEditableText
     nsCOMPtr<nsIAccessibleEditableText> accessInterfaceEditableText;
     QueryInterface(NS_GET_IID(nsIAccessibleEditableText),
                    getter_AddRefs(accessInterfaceEditableText));
     if (accessInterfaceEditableText) {
         interfacesBits |= 1 << MAI_INTERFACE_EDITABLE_TEXT;
     }
 
-    //nsIAccessibleSelection
-    nsCOMPtr<nsIAccessibleSelectable> accessInterfaceSelection;
-    QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
-                   getter_AddRefs(accessInterfaceSelection));
-    if (accessInterfaceSelection) {
-        interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
-    }
-
     //nsIAccessibleValue
     nsCOMPtr<nsIAccessibleValue> accessInterfaceValue;
     QueryInterface(NS_GET_IID(nsIAccessibleValue),
                    getter_AddRefs(accessInterfaceValue));
     if (accessInterfaceValue) {
        interfacesBits |= 1 << MAI_INTERFACE_VALUE; 
     }
 
-    //nsIAccessibleHypertext
-    PRInt32 linkCount = 0;
-    nsCOMPtr<nsIAccessibleHyperText> accessInterfaceHypertext;
-    QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
-                   getter_AddRefs(accessInterfaceHypertext));
-    if (accessInterfaceHypertext) {
-        nsresult rv = accessInterfaceHypertext->GetLinks(&linkCount);
-        if (NS_SUCCEEDED(rv) && (linkCount > 0)) {
-            interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT;
-        }
-    }
-
-    //nsIAccessibleHyperLink
-    nsCOMPtr<nsIAccessibleHyperLink> accessInterfaceHyperlink;
-    QueryInterface(NS_GET_IID(nsIAccessibleHyperLink),
-                   getter_AddRefs(accessInterfaceHyperlink));
-    if (accessInterfaceHyperlink) {
-       interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
-    }
-
-    //nsIAccessibleTable
-    nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
-    QueryInterface(NS_GET_IID(nsIAccessibleTable),
-                   getter_AddRefs(accessInterfaceTable));
-    if (accessInterfaceTable) {
-        interfacesBits |= 1 << MAI_INTERFACE_TABLE;
-    }
-
     //nsIAccessibleDocument
     nsCOMPtr<nsIAccessibleDocument> accessInterfaceDocument;
     QueryInterface(NS_GET_IID(nsIAccessibleDocument),
                               getter_AddRefs(accessInterfaceDocument));
     if (accessInterfaceDocument) {
         interfacesBits |= 1 << MAI_INTERFACE_DOCUMENT;
     }
 
     //nsIAccessibleImage
     nsCOMPtr<nsIAccessibleImage> accessInterfaceImage;
     QueryInterface(NS_GET_IID(nsIAccessibleImage),
                               getter_AddRefs(accessInterfaceImage));
     if (accessInterfaceImage) {
         interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
     }
 
+    //nsIAccessibleHyperLink
+    nsCOMPtr<nsIAccessibleHyperLink> accessInterfaceHyperlink;
+    QueryInterface(NS_GET_IID(nsIAccessibleHyperLink),
+                   getter_AddRefs(accessInterfaceHyperlink));
+    if (accessInterfaceHyperlink) {
+       interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
+    }
+
+    if (!MustPrune(this)) {  // These interfaces require children
+      //nsIAccessibleHypertext
+      PRInt32 linkCount = 0;
+      nsCOMPtr<nsIAccessibleHyperText> accessInterfaceHypertext;
+      QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
+                     getter_AddRefs(accessInterfaceHypertext));
+      if (accessInterfaceHypertext) {
+          nsresult rv = accessInterfaceHypertext->GetLinks(&linkCount);
+          if (NS_SUCCEEDED(rv) && (linkCount > 0)) {
+              interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT;
+          }
+      }
+
+      //nsIAccessibleTable
+      nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
+      QueryInterface(NS_GET_IID(nsIAccessibleTable),
+                     getter_AddRefs(accessInterfaceTable));
+      if (accessInterfaceTable) {
+          interfacesBits |= 1 << MAI_INTERFACE_TABLE;
+      }
+      
+      //nsIAccessibleSelection
+      nsCOMPtr<nsIAccessibleSelectable> accessInterfaceSelection;
+      QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
+                     getter_AddRefs(accessInterfaceSelection));
+      if (accessInterfaceSelection) {
+          interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
+      }
+    }
+
     return interfacesBits;
 }
 
 static GType
 GetMaiAtkType(PRUint16 interfacesBits)
 {
     GType type;
     static const GTypeInfo tinfo = {
@@ -867,17 +869,17 @@ getParentCB(AtkObject *aAtkObj)
     }
     return aAtkObj->accessible_parent;
 }
 
 gint
 getChildCountCB(AtkObject *aAtkObj)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
-    if (!accWrap) {
+    if (!accWrap || nsAccessibleWrap::MustPrune(accWrap)) {
         return 0;
     }
 
     PRInt32 count = 0;
     nsCOMPtr<nsIAccessibleHyperText> hyperText;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
     if (hyperText) {
         // If HyperText, then number of links matches number of children
@@ -901,17 +903,17 @@ refChildCB(AtkObject *aAtkObj, gint aChi
       return nsnull;
     }
 
     // XXX Fix this so it is not O(n^2) to walk through the children!
     // Either we can cache the last accessed child so that we can just GetNextSibling()
     // or we should cache an array of children in each nsAccessible
     // (instead of mNextSibling on the children)
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
-    if (!accWrap) {
+    if (!accWrap || nsAccessibleWrap::MustPrune(accWrap)) {
         return nsnull;
     }
 
     nsresult rv;
     nsCOMPtr<nsIAccessible> accChild;
     nsCOMPtr<nsIAccessibleHyperText> hyperText;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
     if (hyperText) {
@@ -1546,8 +1548,13 @@ nsAccessibleWrap::FireAtkShowHideEvent(n
                           "children_changed::remove",
                           indexInParent,
                           aObject,
                           NULL);
 
     return NS_OK;
 }
 
+PRBool nsAccessibleWrap::MustPrune(nsIAccessible *aAccessible)
+{
+  PRUint32 role = Role(aAccessible);
+  return role == nsIAccessibleRole::ROLE_GRAPHIC;
+}
--- a/accessible/src/atk/nsAccessibleWrap.h
+++ b/accessible/src/atk/nsAccessibleWrap.h
@@ -122,13 +122,16 @@ protected:
                                      AtkObject *aObject);
     nsresult FireAtkPropChangedEvent(nsIAccessibleEvent *aEvent,
                                      AtkObject *aObject);
     nsresult FireAtkShowHideEvent(nsIAccessibleEvent *aEvent,
                                   AtkObject *aObject, PRBool aIsAdded);
 
     AtkObject *mAtkObject;
 
+    // Should this accessible be allowed to have any ATK children
+    static PRBool MustPrune(nsIAccessible *aAccessible);
+
 private:
     PRUint16 CreateMaiInterfaces(void);
 };
 
 #endif /* __NS_ACCESSIBLE_WRAP_H__ */
--- a/accessible/src/atk/nsMaiInterfaceComponent.cpp
+++ b/accessible/src/atk/nsMaiInterfaceComponent.cpp
@@ -64,17 +64,17 @@ componentInterfaceInitCB(AtkComponentIfa
 }
 
 AtkObject *
 refAccessibleAtPointCB(AtkComponent *aComponent,
                        gint aAccX, gint aAccY,
                        AtkCoordType aCoordType)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
-    if (!accWrap)
+    if (!accWrap || nsAccessibleWrap::MustPrune(accWrap))
         return nsnull;
 
     // or ATK_XY_SCREEN  what is definition this in nsIAccessible ???
     if (aCoordType == ATK_XY_WINDOW) {
         /* deal with the coord type */
     }
 
     nsCOMPtr<nsIAccessible> pointAcc;
--- a/accessible/src/atk/nsRoleMap.h
+++ b/accessible/src/atk/nsRoleMap.h
@@ -157,11 +157,12 @@ static const PRUint32 atkRoleMap[] = {
     ATK_ROLE_REDUNDANT_OBJECT,    // nsIAccessibleRole::ROLE_REDUNDANT_OBJECT     108
     ATK_ROLE_FORM,                // nsIAccessibleRole::ROLE_FORM                 109
     ATK_ROLE_INPUT_METHOD_WINDOW, // nsIAccessibleRole::ROLE_IME                  110
     ATK_ROLE_APPLICATION,         // nsIAccessibleRole::ROLE_APP_ROOT             111
     ATK_ROLE_MENU,                // nsIAccessibleRole::ROLE_PARENT_MENUITEM      112
     ATK_ROLE_CALENDAR,            // nsIAccessibleRole::ROLE_CALENDAR             113
     ATK_ROLE_MENU,                // nsIAccessibleRole::ROLE_COMBOBOX_LIST        114
     ATK_ROLE_MENU_ITEM,           // nsIAccessibleRole::ROLE_COMBOBOX_LISTITEM    115
+    ATK_ROLE_IMAGE,               // nsIAccessibleRole::ROLE_IMAGE_MAP            116
     kROLE_ATK_LAST_ENTRY          // nsIAccessibleRole::ROLE_LAST_ENTRY
 };
 
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -95,16 +95,18 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
   {"gridcell", nsIAccessibleRole::ROLE_CELL, eNameOkFromChildren, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
             {"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED},
             {"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
             {"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
   {"group", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
+  {"heading", nsIAccessibleRole::ROLE_HEADING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
+  {"img", nsIAccessibleRole::ROLE_GRAPHIC, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"label", nsIAccessibleRole::ROLE_LABEL, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
   {"link", nsIAccessibleRole::ROLE_LINK, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_LINKED,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
   {"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
             {"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
   {"listbox", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
@@ -138,30 +140,32 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
             {"checked", "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
   {"progressbar", nsIAccessibleRole::ROLE_PROGRESSBAR, eNameLabelOrTitle, eHasValueMinMax, nsIAccessibleStates::STATE_READONLY,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
   {"radio", nsIAccessibleRole::ROLE_RADIOBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED}, kEndEntry},
   {"radiogroup", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
+  {"region", nsIAccessibleRole::ROLE_PANE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"row", nsIAccessibleRole::ROLE_ROW, eNameOkFromChildren, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
             {"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
             {"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
             {"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED}, kEndEntry},
   {"rowheader", nsIAccessibleRole::ROLE_ROWHEADER, eNameOkFromChildren, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
             {"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
   {"secret", nsIAccessibleRole::ROLE_PASSWORD_TEXT, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_PROTECTED,
             // Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aaa:multiline
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
+  {"section", nsIAccessibleRole::ROLE_SECTION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"separator", nsIAccessibleRole::ROLE_SEPARATOR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"slider", nsIAccessibleRole::ROLE_SLIDER, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
   {"spinbutton", nsIAccessibleRole::ROLE_SPINBUTTON, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
   {"status", nsIAccessibleRole::ROLE_STATUSBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
@@ -170,16 +174,17 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
   {"tablist", nsIAccessibleRole::ROLE_PAGETABLIST, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"tabpanel", nsIAccessibleRole::ROLE_PROPERTYPAGE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"textbox", nsIAccessibleRole::ROLE_ENTRY, eNameLabelOrTitle, eNoValue, kNoReqStates,
             // Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aaa:multiline
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
   {"toolbar", nsIAccessibleRole::ROLE_TOOLBAR, eNameLabelOrTitle, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
+  {"tooltip", nsIAccessibleRole::ROLE_TOOLTIP, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
   {"tree", nsIAccessibleRole::ROLE_OUTLINE, eNameLabelOrTitle, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
             {"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
   {"treegrid", nsIAccessibleRole::ROLE_TREE_TABLE, eNameLabelOrTitle, eNoValue, kNoReqStates,
             {"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
             {"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
             {"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -163,17 +163,18 @@ static const char kRoleNames[][20] = {
   "section",             //ROLE_SECTION
   "redundant object",    //ROLE_REDUNDANT_OBJECT
   "form",                //ROLE_FORM
   "ime",                 //ROLE_IME
   "app root",            //ROLE_APP_ROOT
   "parent menuitem",     //ROLE_PARENT_MENUITEM
   "calendar",            //ROLE_CALENDAR
   "combobox list",       //ROLE_COMBOBOX_LIST
-  "combobox listitem"    //ROLE_COMBOBOX_LISTITEM
+  "combobox listitem",   //ROLE_COMBOBOX_LISTITEM
+  "image map"            //ROLE_IMAGE_MAP
 };
 
 class nsAccessibilityService : public nsIAccessibilityService, 
                                public nsIObserver,
                                public nsIWebProgressListener,
                                public nsSupportsWeakReference
 {
 public:
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -139,17 +139,20 @@ NS_IMETHODIMP nsHTMLImageAccessible::Get
   }
 
   return NS_OK;
 }
 
 /* wstring getRole (); */
 NS_IMETHODIMP nsHTMLImageAccessible::GetRole(PRUint32 *_retval)
 {
-  *_retval = nsIAccessibleRole::ROLE_GRAPHIC;
+  PRInt32 numChildren;
+  GetChildCount(&numChildren);
+  *_retval = (numChildren > 0) ? nsIAccessibleRole::ROLE_IMAGE_MAP :
+                                 nsIAccessibleRole::ROLE_GRAPHIC;
   return NS_OK;
 }
 
 
 already_AddRefed<nsIAccessible>
 nsHTMLImageAccessible::GetAreaAccessible(PRInt32 aAreaNum)
 {
   if (!mMapElement)
--- a/accessible/src/mac/nsAccessibleWrap.h
+++ b/accessible/src/mac/nsAccessibleWrap.h
@@ -76,23 +76,25 @@ class nsAccessibleWrap : public nsAccess
     
     virtual nsresult Shutdown ();
     virtual nsresult InvalidateChildren ();
 
     NS_IMETHOD FireAccessibleEvent(nsIAccessibleEvent *aEvent);
 
     // we'll flatten buttons and checkboxes. usually they have a text node
     // child, that is their title. Works in conjunction with IsPruned() below.
+    // XXX There is no IsPruned() method, so what does that comment mean?
     PRBool IsFlat() {
       PRUint32 role = Role(this);
       return (role == nsIAccessibleRole::ROLE_CHECKBUTTON ||
               role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
               role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
               role == nsIAccessibleRole::ROLE_SPLITBUTTON ||
-              role == nsIAccessibleRole::ROLE_ENTRY);
+              role == nsIAccessibleRole::ROLE_ENTRY ||
+              role == nsIAccessibleRole::ROLE_IMAGE);
     }
     
     // ignored means that the accessible might still have children, but is not displayed
     // to the user. it also has no native accessible object represented for it.
     PRBool IsIgnored();
     
     PRInt32 GetUnignoredChildCount(PRBool aDeepCount);
     
--- a/accessible/src/mac/nsRoleMap.h
+++ b/accessible/src/mac/nsRoleMap.h
@@ -153,10 +153,11 @@ static const NSString* AXRoles [] = {
   NSAccessibilityUnknownRole,                   // ROLE_REDUNDANT_OBJECT
   NSAccessibilityGroupRole,                     // ROLE_FORM
   NSAccessibilityUnknownRole,                   // ROLE_IME
   NSAccessibilityUnknownRole,                   // ROLE_APP_ROOT. unused on OS X
   NSAccessibilityMenuItemRole,                  // ROLE_PARENT_MENUITEM
   NSAccessibilityGroupRole,                     // ROLE_CALENDAR
   NSAccessibilityMenuRole,                      // ROLE_COMBOBOX_LIST
   NSAccessibilityMenuItemRole,                  // ROLE_COMBOBOX_LISTITEM
+  NSAccessibilityImageRole,                     // ROLE_IMAGE_MAP
   @"ROLE_LAST_ENTRY"                            // ROLE_LAST_ENTRY. bogus role that will never be shown (just marks the end of this array)!
 };
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1707,8 +1707,18 @@ void nsAccessibleWrap::UpdateSystemCaret
     ::ShowCaret(caretWnd);
     RECT windowRect;
     ::GetWindowRect(caretWnd, &windowRect);
     ::SetCaretPos(caretRect.x - windowRect.left, caretRect.y - windowRect.top);
     ::DeleteObject(caretBitMap);
   }
 }
 
+PRBool nsAccessibleWrap::MustPrune(nsIAccessible *aAccessible)
+{ 
+  PRUint32 role = Role(aAccessible);
+  return role == nsIAccessibleRole::ROLE_MENUITEM || 
+         role == nsIAccessibleRole::ROLE_ENTRY ||
+         role == nsIAccessibleRole::ROLE_PASSWORD_TEXT ||
+         role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
+         role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
+         role == nsIAccessibleRole::ROLE_GRAPHIC;
+}
--- a/accessible/src/msaa/nsAccessibleWrap.h
+++ b/accessible/src/msaa/nsAccessibleWrap.h
@@ -318,24 +318,17 @@ class nsAccessibleWrap : public nsAccess
 
 protected:
   // mEnumVARIANTPosition not the current accessible's position, but a "cursor" of 
   // where we are in the current list of children, with respect to
   // nsIEnumVariant::Reset(), Skip() and Next().
   PRUint16 mEnumVARIANTPosition;
 
   // Should this accessible be allowed to have any MSAA children
-  static PRBool MustPrune(nsIAccessible *accessible)
-  { 
-    PRUint32 role = Role(accessible);
-    return role == nsIAccessibleRole::ROLE_MENUITEM || 
-           role == nsIAccessibleRole::ROLE_ENTRY ||
-           role == nsIAccessibleRole::ROLE_PASSWORD_TEXT ||
-           role == nsIAccessibleRole::ROLE_PUSHBUTTON;
-  }
+  static PRBool MustPrune(nsIAccessible *aAccessible);
 
   enum navRelations {
     NAVRELATION_CONTROLLED_BY = 0x1000,
     NAVRELATION_CONTROLLER_FOR = 0x1001,
     NAVRELATION_LABEL_FOR = 0x1002,
     NAVRELATION_LABELLED_BY = 0x1003,
     NAVRELATION_MEMBER_OF = 0x1004,
     NAVRELATION_NODE_CHILD_OF = 0x1005,
--- a/accessible/src/msaa/nsRoleMap.h
+++ b/accessible/src/msaa/nsRoleMap.h
@@ -417,12 +417,15 @@ static const WindowsRoleMapItem gWindows
   { ROLE_SYSTEM_CLIENT, ROLE_SYSTEM_CLIENT },
 
   // nsIAccessibleRole::ROLE_COMBOBOX_LIST
   { ROLE_SYSTEM_LIST, ROLE_SYSTEM_LIST },
 
   // nsIAccessibleRole::ROLE_COMBOBOX_LISTITEM
   { ROLE_SYSTEM_LISTITEM, ROLE_SYSTEM_LISTITEM },
 
+  // nsIAccessibleRole::ROLE_IMAGE_MAP
+  { ROLE_SYSTEM_GRAPHIC, ROLE_SYSTEM_GRAPHIC },
+
   // nsIAccessibleRole::ROLE_LAST_ENTRY
   { ROLE_WINDOWS_LAST_ENTRY, ROLE_WINDOWS_LAST_ENTRY }
 };