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
--- 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,