Bug 390154. Prune subtrees consistently across platform accessibility APIs for a number of widgets that we will impose a 'must be leaf' rule, to simplify compatibility across a number of assistive technologies which expect that. r=ginn.chen, a=dsicore
authoraaronleventhal@moonset.net
Wed, 15 Aug 2007 14:02:31 -0700
changeset 4685 1bd41e8f7d319b6103c08730cd5c5acac75bd894
parent 4684 dd803b0224d3ecc5e5cea859803a9eaa239755d2
child 4686 63d6d60758296328de3fe31f40579fa4071a3174
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersginn, dsicore
bugs390154
milestone1.9a8pre
Bug 390154. Prune subtrees consistently across platform accessibility APIs for a number of widgets that we will impose a 'must be leaf' rule, to simplify compatibility across a number of assistive technologies which expect that. r=ginn.chen, a=dsicore
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/atk/nsAccessibleWrap.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/mac/nsAccessibleWrap.h
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/msaa/nsAccessibleWrap.h
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -1545,13 +1545,8 @@ 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
@@ -110,19 +110,16 @@ public:
     void SetMaiHyperlink(MaiHyperlink* aMaiHyperlink);
 
     static const char * ReturnString(nsAString &aString) {
       static nsCString returnedString;
       returnedString = NS_ConvertUTF16toUTF8(aString);
       return returnedString.get();
     }
 
-    // Should this accessible be allowed to have any ATK children
-    static PRBool MustPrune(nsIAccessible *aAccessible);
-
 protected:
     nsresult FireAtkStateChangeEvent(nsIAccessibleEvent *aEvent,
                                      AtkObject *aObject);
     nsresult FireAtkTextChangedEvent(nsIAccessibleEvent *aEvent,
                                      AtkObject *aObject);
     nsresult FireAtkPropChangedEvent(nsIAccessibleEvent *aEvent,
                                      AtkObject *aObject);
     nsresult FireAtkShowHideEvent(nsIAccessibleEvent *aEvent,
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -3268,8 +3268,21 @@ nsAccessible::GetAttrValue(PRUint32 aNam
   PRInt32 result = NS_OK;
   nsAutoString value;
   if (content->GetAttr(aNameSpaceID, aName, value) && !value.IsEmpty())
     *aValue = value.ToFloat(&result);
 
   return result;
 }
 
+PRBool nsAccessible::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 ||
+         role == nsIAccessibleRole::ROLE_SLIDER ||
+         role == nsIAccessibleRole::ROLE_PROGRESSBAR ||
+         role == nsIAccessibleRole::ROLE_SEPARATOR;
+}
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -150,23 +150,27 @@ public:
   static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
   static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state; aAcc->GetFinalState(&state, nsnull); return state; }
   static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role; aAcc->GetFinalRole(&role); return role; }
   static PRBool IsText(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role == nsIAccessibleRole::ROLE_TEXT_LEAF || role == nsIAccessibleRole::ROLE_STATICTEXT; }
   static PRBool IsEmbeddedObject(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role != nsIAccessibleRole::ROLE_TEXT_LEAF && role != nsIAccessibleRole::ROLE_WHITESPACE && role != nsIAccessibleRole::ROLE_STATICTEXT; }
   static PRInt32 TextLength(nsIAccessible *aAccessible); // Returns -1 on failure
   static PRBool IsLeaf(nsIAccessible *aAcc) { PRInt32 numChildren; aAcc->GetChildCount(&numChildren); return numChildren > 0; }
   static PRBool IsNodeRelevant(nsIDOMNode *aNode); // Is node something that could have an attached accessible
+  /**
+   * When exposing to platform accessibility APIs, should the children be pruned off?
+   */
+  static PRBool MustPrune(nsIAccessible *aAccessible);
   
   already_AddRefed<nsIAccessible> GetParent() {
     nsIAccessible *parent = nsnull;
     GetParent(&parent);
     return parent;
   }
-
+  
 protected:
   PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);
   virtual nsIFrame* GetBoundsFrame();
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
   PRBool IsVisible(PRBool *aIsOffscreen); 
 
   // Relation helpers
   nsresult GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName);
--- a/accessible/src/mac/nsAccessibleWrap.h
+++ b/accessible/src/mac/nsAccessibleWrap.h
@@ -73,29 +73,16 @@ class nsAccessibleWrap : public nsAccess
     
     // returns a pointer to the native window for this accessible tree.
     void GetNativeWindow (void **aOutNativeWindow);
     
     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_GRAPHIC);
-    }
     
     // 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);
     
     PRBool HasPopup () {
@@ -114,20 +101,21 @@ class nsAccessibleWrap : public nsAccess
       // we don't create a native object if we're child of a "flat" accessible; for example, on OS X buttons 
       // shouldn't have any children, because that makes the OS confused. 
       //
       // to maintain a scripting environment where the XPCOM accessible hierarchy look the same 
       // on all platforms, we still let the C++ objects be created though.
       
       nsCOMPtr<nsIAccessible> curParent = GetParent();
       while (curParent) {
-        nsAccessibleWrap *ancestorWrap = static_cast<nsAccessibleWrap*>((nsIAccessible*)curParent.get());
-        if (ancestorWrap->IsFlat())
+        if (MustPrune(curParent))
           return PR_TRUE;
-        curParent = static_cast<nsAccessibleWrap*>((nsIAccessible*)curParent.get())->GetParent();
+        nsCOMPtr<nsIAccessible> newParent;
+        curParent->GetParent(getter_AddRefs(newParent));
+        curParent.swap(newParent);
       }
       // no parent was flat
       return PR_FALSE;
     }
 
     // Wrapper around our native object.
     AccessibleWrapper *mNativeWrapper;
 };
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1710,19 +1710,8 @@ void nsAccessibleWrap::UpdateSystemCaret
   if (::CreateCaret(caretWnd, caretBitMap, 1, caretRect.height)) {  // Also destroys the last caret
     ::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
@@ -317,19 +317,16 @@ class nsAccessibleWrap : public nsAccess
   static IDispatch *NativeAccessible(nsIAccessible *aXPAccessible);
 
 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 *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,
     NAVRELATION_FLOWS_TO = 0x1006,