This commit is contained in:
Alexander Surkov 2009-11-20 00:35:38 +08:00
Родитель 9dcab1cde9
Коммит 4d4bdb7fa1
54 изменённых файлов: 1519 добавлений и 1998 удалений

Просмотреть файл

@ -647,7 +647,8 @@ nsApplicationAccessibleWrap::AddRootAccessible(nsIAccessible *aRootAccWrap)
AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap); AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
atk_object_set_parent(atkAccessible, mAtkObject); atk_object_set_parent(atkAccessible, mAtkObject);
PRUint32 count = mChildren.Count(); PRUint32 count = 0;
mChildren->GetLength(&count);
g_signal_emit_by_name(mAtkObject, "children_changed::add", count - 1, g_signal_emit_by_name(mAtkObject, "children_changed::add", count - 1,
atkAccessible, NULL); atkAccessible, NULL);
@ -669,27 +670,36 @@ nsApplicationAccessibleWrap::RemoveRootAccessible(nsIAccessible *aRootAccWrap)
{ {
NS_ENSURE_ARG_POINTER(aRootAccWrap); NS_ENSURE_ARG_POINTER(aRootAccWrap);
PRInt32 index = mChildren.IndexOf(aRootAccWrap); PRUint32 index = 0;
nsresult rv = NS_ERROR_FAILURE;
// we must use weak ref to get the index
nsCOMPtr<nsIWeakReference> weakPtr = do_GetWeakReference(aRootAccWrap);
rv = mChildren->IndexOf(0, weakPtr, &index);
AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap); AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
atk_object_set_parent(atkAccessible, NULL); atk_object_set_parent(atkAccessible, NULL);
g_signal_emit_by_name(mAtkObject, "children_changed::remove", index, g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
atkAccessible, NULL); atkAccessible, NULL);
nsresult rv = nsApplicationAccessible::RemoveRootAccessible(aRootAccWrap);
#ifdef MAI_LOGGING #ifdef MAI_LOGGING
PRUint32 count = mChildren.Count(); PRUint32 count = 0;
mChildren->GetLength(&count);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
rv = mChildren->RemoveElementAt(index);
MAI_LOG_DEBUG(("\nRemove RootAcc=%p, count=%d\n", MAI_LOG_DEBUG(("\nRemove RootAcc=%p, count=%d\n",
(void*)aRootAccWrap, (count-1))); (void*)aRootAccWrap, (count-1)));
} }
else else
MAI_LOG_DEBUG(("\nFail to Remove RootAcc=%p, count=%d\n", MAI_LOG_DEBUG(("\nFail to Remove RootAcc=%p, count=%d\n",
(void*)aRootAccWrap, count)); (void*)aRootAccWrap, count));
#endif #else
NS_ENSURE_SUCCESS(rv, rv);
rv = mChildren->RemoveElementAt(index);
#endif
InvalidateChildren();
return rv; return rv;
} }

Просмотреть файл

@ -149,12 +149,14 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsAccessible, nsAccessNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsAccessible, nsAccessNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mChildren) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNextSibling)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsAccessible, nsAccessNode) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsAccessible, nsAccessNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChildren) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNextSibling)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(nsAccessible, nsAccessNode) NS_IMPL_ADDREF_INHERITED(nsAccessible, nsAccessNode)
@ -227,8 +229,8 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
} }
nsAccessible::nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): nsAccessNodeWrap(aNode, aShell), nsAccessible::nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): nsAccessNodeWrap(aNode, aShell),
mParent(nsnull), mRoleMapEntry(nsnull), mParent(nsnull), mFirstChild(nsnull), mNextSibling(nsnull), mRoleMapEntry(nsnull),
mAreChildrenInitialized(PR_FALSE) mAccChildCount(eChildCountUninitialized)
{ {
#ifdef NS_DEBUG_X #ifdef NS_DEBUG_X
{ {
@ -480,9 +482,39 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
return NS_OK; return NS_OK;
} }
void
nsAccessible::SetParent(nsIAccessible *aParent)
{
if (mParent != aParent) {
// Adopt a child -- we allow this now. the new parent
// may be a dom node which wasn't previously accessible but now is.
// The old parent's children now need to be invalidated, since
// it no longer owns the child, the new parent does
nsRefPtr<nsAccessible> oldParent = nsAccUtils::QueryAccessible(mParent);
if (oldParent)
oldParent->InvalidateChildren();
}
mParent = aParent;
}
void
nsAccessible::SetFirstChild(nsIAccessible *aFirstChild)
{
mFirstChild = aFirstChild;
}
void
nsAccessible::SetNextSibling(nsIAccessible *aNextSibling)
{
mNextSibling = aNextSibling;
}
nsresult nsresult
nsAccessible::Shutdown() nsAccessible::Shutdown()
{ {
mNextSibling = nsnull;
// Invalidate the child count and pointers to other accessibles, also make // Invalidate the child count and pointers to other accessibles, also make
// sure none of its children point to this parent // sure none of its children point to this parent
InvalidateChildren(); InvalidateChildren();
@ -495,112 +527,198 @@ nsAccessible::Shutdown()
return nsAccessNodeWrap::Shutdown(); return nsAccessNodeWrap::Shutdown();
} }
void
nsAccessible::InvalidateChildren()
{
// Document has transformed, reset our invalid children and child count
// Reset the sibling pointers, they will be set up again the next time
// CacheChildren() is called.
// Note: we don't want to start creating accessibles at this point,
// so don't use GetNextSibling() here. (bug 387252)
nsRefPtr<nsAccessible> child = nsAccUtils::QueryAccessible(mFirstChild);
while (child) {
child->mParent = nsnull;
nsCOMPtr<nsIAccessible> next = child->mNextSibling;
child->mNextSibling = nsnull;
child = nsAccUtils::QueryAccessible(next);
}
mAccChildCount = eChildCountUninitialized;
mFirstChild = nsnull;
}
NS_IMETHODIMP NS_IMETHODIMP
nsAccessible::GetParent(nsIAccessible **aParent) nsAccessible::GetParent(nsIAccessible **aParent)
{ {
NS_ENSURE_ARG_POINTER(aParent); if (IsDefunct())
return NS_ERROR_FAILURE;
NS_IF_ADDREF(*aParent = GetParent()); nsCOMPtr<nsIAccessible> cachedParent = GetCachedParent();
return *aParent ? NS_OK : NS_ERROR_FAILURE; if (cachedParent) {
cachedParent.swap(*aParent);
return NS_OK;
}
nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE);
return docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE, aParent);
}
already_AddRefed<nsIAccessible>
nsAccessible::GetCachedParent()
{
if (IsDefunct())
return nsnull;
nsCOMPtr<nsIAccessible> cachedParent = mParent;
return cachedParent.forget();
}
already_AddRefed<nsIAccessible>
nsAccessible::GetCachedFirstChild()
{
if (IsDefunct())
return nsnull;
nsCOMPtr<nsIAccessible> cachedFirstChild = mFirstChild;
return cachedFirstChild.forget();
} }
/* readonly attribute nsIAccessible nextSibling; */ /* readonly attribute nsIAccessible nextSibling; */
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetNextSibling(nsIAccessible * *aNextSibling)
nsAccessible::GetNextSibling(nsIAccessible **aNextSibling) {
{ *aNextSibling = nsnull;
NS_ENSURE_ARG_POINTER(aNextSibling); if (!mWeakShell) {
// This node has been shut down
return NS_ERROR_FAILURE;
}
if (!mParent) {
nsCOMPtr<nsIAccessible> parent(GetParent());
if (parent) {
PRInt32 numChildren;
parent->GetChildCount(&numChildren); // Make sure we cache all of the children
}
}
nsresult rv = NS_OK; if (mNextSibling || !mParent) {
NS_IF_ADDREF(*aNextSibling = GetSiblingAtOffset(1, &rv)); // If no parent, don't try to calculate a new sibling
return rv; // It either means we're at the root or shutting down the parent
NS_IF_ADDREF(*aNextSibling = mNextSibling);
return NS_OK;
}
return NS_ERROR_FAILURE;
} }
/* readonly attribute nsIAccessible previousSibling; */ /* readonly attribute nsIAccessible previousSibling; */
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetPreviousSibling(nsIAccessible * *aPreviousSibling)
nsAccessible::GetPreviousSibling(nsIAccessible * *aPreviousSibling)
{ {
NS_ENSURE_ARG_POINTER(aPreviousSibling); *aPreviousSibling = nsnull;
nsresult rv = NS_OK; if (!mWeakShell) {
NS_IF_ADDREF(*aPreviousSibling = GetSiblingAtOffset(-1, &rv)); // This node has been shut down
return rv; return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIAccessible> parent;
if (NS_FAILED(GetParent(getter_AddRefs(parent))) || !parent) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIAccessible> testAccessible, prevSibling;
parent->GetFirstChild(getter_AddRefs(testAccessible));
while (testAccessible && this != testAccessible) {
prevSibling = testAccessible;
prevSibling->GetNextSibling(getter_AddRefs(testAccessible));
}
if (!prevSibling) {
return NS_ERROR_FAILURE;
}
NS_ADDREF(*aPreviousSibling = prevSibling);
return NS_OK;
} }
/* readonly attribute nsIAccessible firstChild; */ /* readonly attribute nsIAccessible firstChild; */
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetFirstChild(nsIAccessible * *aFirstChild)
nsAccessible::GetFirstChild(nsIAccessible **aFirstChild) {
{ if (gIsCacheDisabled) {
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
if (gIsCacheDisabled)
InvalidateChildren(); InvalidateChildren();
}
PRInt32 numChildren;
GetChildCount(&numChildren); // Make sure we cache all of the children
PRInt32 childCount = GetChildCount(); #ifdef DEBUG
NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE); nsRefPtr<nsAccessible> firstChild(nsAccUtils::QueryAccessible(mFirstChild));
if (firstChild) {
nsCOMPtr<nsIAccessible> realParent = firstChild->GetCachedParent();
NS_ASSERTION(!realParent || realParent == this,
"Two accessibles have the same first child accessible.");
}
#endif
if (childCount > 0) NS_IF_ADDREF(*aFirstChild = mFirstChild);
NS_ADDREF(*aFirstChild = GetChildAt(0));
return NS_OK; return NS_OK;
} }
/* readonly attribute nsIAccessible lastChild; */ /* readonly attribute nsIAccessible lastChild; */
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetLastChild(nsIAccessible * *aLastChild)
nsAccessible::GetLastChild(nsIAccessible **aLastChild) {
{ GetChildAt(-1, aLastChild);
NS_ENSURE_ARG_POINTER(aLastChild);
*aLastChild = nsnull;
PRInt32 childCount = GetChildCount();
NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE);
NS_IF_ADDREF(*aLastChild = GetChildAt(childCount - 1));
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild)
nsAccessible::GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild)
{ {
NS_ENSURE_ARG_POINTER(aChild); // aChildNum is a zero-based index
*aChild = nsnull;
PRInt32 childCount = GetChildCount(); PRInt32 numChildren;
NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE); GetChildCount(&numChildren);
// If child index is negative, then return last child. // If no children or aChildNum is larger than numChildren, return null
// XXX: do we really need this? if (aChildNum >= numChildren || numChildren == 0 || !mWeakShell) {
if (aChildIndex < 0) *aChild = nsnull;
aChildIndex = childCount - 1; return NS_ERROR_FAILURE;
// If aChildNum is less than zero, set aChild to last index
} else if (aChildNum < 0) {
aChildNum = numChildren - 1;
}
nsIAccessible* child = GetChildAt(aChildIndex); nsCOMPtr<nsIAccessible> current(mFirstChild), nextSibling;
if (!child) PRInt32 index = 0;
return NS_ERROR_INVALID_ARG;
while (current) {
nextSibling = current;
if (++index > aChildNum) {
break;
}
nextSibling->GetNextSibling(getter_AddRefs(current));
}
NS_IF_ADDREF(*aChild = nextSibling);
NS_ADDREF(*aChild = child);
return NS_OK; return NS_OK;
} }
// readonly attribute nsIArray children; // readonly attribute nsIArray children;
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetChildren(nsIArray **aOutChildren)
nsAccessible::GetChildren(nsIArray **aOutChildren)
{ {
NS_ENSURE_ARG_POINTER(aOutChildren);
*aOutChildren = nsnull; *aOutChildren = nsnull;
nsCOMPtr<nsIMutableArray> children = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (!children)
return NS_ERROR_FAILURE;
PRInt32 childCount = GetChildCount(); nsCOMPtr<nsIAccessible> curChild;
NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE); while (NextChild(curChild)) {
children->AppendElement(curChild, PR_FALSE);
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> children =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsIAccessible* child = GetChildAt(childIdx);
children->AppendElement(child, PR_FALSE);
} }
NS_ADDREF(*aOutChildren = children); NS_ADDREF(*aOutChildren = children);
return NS_OK; return NS_OK;
} }
@ -617,6 +735,39 @@ nsIAccessible *nsAccessible::NextChild(nsCOMPtr<nsIAccessible>& aAccessible)
return (aAccessible = nextChild); return (aAccessible = nextChild);
} }
void nsAccessible::CacheChildren()
{
if (!mWeakShell) {
// This node has been shut down
mAccChildCount = eChildCountUninitialized;
return;
}
if (mAccChildCount == eChildCountUninitialized) {
mAccChildCount = 0;// Prevent reentry
PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles();
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren);
// Seed the frame hint early while we're still on a container node.
// This is better than doing the GetPrimaryFrameFor() later on
// a text node, because text nodes aren't in the frame map.
walker.mState.frame = GetFrame();
nsRefPtr<nsAccessible> prevAcc;
PRInt32 childCount = 0;
walker.GetFirstChild();
SetFirstChild(walker.mState.accessible);
while (walker.mState.accessible) {
++ childCount;
prevAcc = nsAccUtils::QueryAccessible(walker.mState.accessible);
prevAcc->SetParent(this);
walker.GetNextSibling();
prevAcc->SetNextSibling(walker.mState.accessible);
}
mAccChildCount = childCount;
}
}
PRBool PRBool
nsAccessible::GetAllowsAnonChildAccessibles() nsAccessible::GetAllowsAnonChildAccessibles()
{ {
@ -624,23 +775,73 @@ nsAccessible::GetAllowsAnonChildAccessibles()
} }
/* readonly attribute long childCount; */ /* readonly attribute long childCount; */
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetChildCount(PRInt32 *aAccChildCount)
nsAccessible::GetChildCount(PRInt32 *aChildCount)
{ {
NS_ENSURE_ARG_POINTER(aChildCount); CacheChildren();
*aAccChildCount = mAccChildCount;
*aChildCount = GetChildCount(); return NS_OK;
return *aChildCount != -1 ? NS_OK : NS_ERROR_FAILURE;
} }
/* readonly attribute long indexInParent; */ /* readonly attribute long indexInParent; */
NS_IMETHODIMP NS_IMETHODIMP nsAccessible::GetIndexInParent(PRInt32 *aIndexInParent)
nsAccessible::GetIndexInParent(PRInt32 *aIndexInParent)
{ {
NS_ENSURE_ARG_POINTER(aIndexInParent); *aIndexInParent = -1;
if (!mWeakShell) {
return NS_ERROR_FAILURE;
}
*aIndexInParent = GetIndexInParent(); nsCOMPtr<nsIAccessible> parent;
return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE; GetParent(getter_AddRefs(parent));
if (!parent) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIAccessible> sibling;
parent->GetFirstChild(getter_AddRefs(sibling));
if (!sibling) {
return NS_ERROR_FAILURE;
}
*aIndexInParent = 0;
while (sibling != this) {
NS_ASSERTION(sibling, "Never ran into the same child that we started from");
if (!sibling)
return NS_ERROR_FAILURE;
++*aIndexInParent;
nsCOMPtr<nsIAccessible> tempAccessible;
sibling->GetNextSibling(getter_AddRefs(tempAccessible));
sibling = tempAccessible;
}
return NS_OK;
}
void
nsAccessible::TestChildCache(nsIAccessible *aCachedChild)
{
#ifdef DEBUG_A11Y
// All cached accessible nodes should be in the parent
// It will assert if not all the children were created
// when they were first cached, and no invalidation
// ever corrected parent accessible's child cache.
if (mAccChildCount <= 0)
return;
nsCOMPtr<nsIAccessible> sibling = mFirstChild;
while (sibling != aCachedChild) {
NS_ASSERTION(sibling, "[TestChildCache] Never ran into the same child that we started from");
if (!sibling)
return;
nsCOMPtr<nsIAccessible> tempAccessible;
sibling->GetNextSibling(getter_AddRefs(tempAccessible));
sibling = tempAccessible;
}
#endif
} }
nsresult nsAccessible::GetTranslatedString(const nsAString& aKey, nsAString& aStringOut) nsresult nsAccessible::GetTranslatedString(const nsAString& aKey, nsAString& aStringOut)
@ -2912,247 +3113,8 @@ nsAccessible::GetNameInternal(nsAString& aName)
return NS_OK; return NS_OK;
} }
void
nsAccessible::SetParent(nsIAccessible *aParent)
{
NS_PRECONDITION(aParent, "This method isn't used to set null parent!");
if (mParent && mParent != aParent) {
// Adopt a child -- we allow this now. the new parent
// may be a dom node which wasn't previously accessible but now is.
// The old parent's children now need to be invalidated, since
// it no longer owns the child, the new parent does
NS_ASSERTION(PR_FALSE, "Adopting child!");
nsRefPtr<nsAccessible> oldParent = nsAccUtils::QueryAccessible(mParent);
if (oldParent)
oldParent->InvalidateChildren();
}
mParent = aParent;
}
void
nsAccessible::InvalidateChildren()
{
PRInt32 childCount = mChildren.Count();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsRefPtr<nsAccessible> child =
nsAccUtils::QueryObject<nsAccessible>(mChildren.ObjectAt(childIdx));
child->mParent = nsnull;
}
mChildren.Clear();
mAreChildrenInitialized = PR_FALSE;
}
nsIAccessible*
nsAccessible::GetParent()
{
if (IsDefunct())
return nsnull;
if (mParent)
return mParent;
nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
NS_ASSERTION(docAccessible, "No document accessible for valid accessible!");
if (!docAccessible)
return nsnull;
nsCOMPtr<nsIAccessible> parent;
docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE,
getter_AddRefs(parent));
#ifdef DEBUG
nsRefPtr<nsAccessible> parentAcc = nsAccUtils::QueryAccessible(parent);
NS_ASSERTION(!parentAcc->IsDefunct(), "Defunct parent!");
parentAcc->EnsureChildren();
if (parent != mParent)
NS_WARNING("Bad accessible tree!");
#endif
return parent;
}
nsIAccessible*
nsAccessible::GetChildAt(PRUint32 aIndex)
{
if (EnsureChildren())
return nsnull;
nsIAccessible *child = mChildren.SafeObjectAt(aIndex);
if (!child)
return nsnull;
#ifdef DEBUG
nsRefPtr<nsAccessible> childAcc = nsAccUtils::QueryAccessible(child);
nsCOMPtr<nsIAccessible> realParent = childAcc->mParent;
NS_ASSERTION(!realParent || realParent == this,
"Two accessibles have the same first child accessible!");
#endif
return child;
}
PRInt32
nsAccessible::GetChildCount()
{
return EnsureChildren() ? -1 : mChildren.Count();
}
PRInt32
nsAccessible::GetIndexOf(nsIAccessible *aChild)
{
return EnsureChildren() ? -1 : mChildren.IndexOf(aChild);
}
PRInt32
nsAccessible::GetIndexInParent()
{
nsIAccessible *parent = GetParent();
if (!parent)
return -1;
nsRefPtr<nsAccessible> parentAcc =
nsAccUtils::QueryObject<nsAccessible>(parent);
return parentAcc->GetIndexOf(this);
}
already_AddRefed<nsIAccessible>
nsAccessible::GetCachedParent()
{
if (IsDefunct())
return nsnull;
nsCOMPtr<nsIAccessible> cachedParent = mParent;
return cachedParent.forget();
}
already_AddRefed<nsIAccessible>
nsAccessible::GetCachedFirstChild()
{
if (IsDefunct())
return nsnull;
nsCOMPtr<nsIAccessible> cachedFirstChild = GetChildAt(0);
return cachedFirstChild.forget();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsAccessible protected methods // nsAccessible private methods
void
nsAccessible::CacheChildren()
{
PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles();
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren);
// Seed the frame hint early while we're still on a container node.
// This is better than doing the GetPrimaryFrameFor() later on
// a text node, because text nodes aren't in the frame map.
walker.mState.frame = GetFrame();
walker.GetFirstChild();
while (walker.mState.accessible) {
mChildren.AppendObject(walker.mState.accessible);
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
acc->SetParent(this);
walker.GetNextSibling();
}
}
void
nsAccessible::TestChildCache(nsIAccessible *aCachedChild)
{
#ifdef DEBUG_A11Y
// All cached accessible nodes should be in the parent
// It will assert if not all the children were created
// when they were first cached, and no invalidation
// ever corrected parent accessible's child cache.
PRUint32 childCount = mChildren.Count();
if (childCount == 0) {
NS_ASSERTION(mAreChildrenInitialized,
"Children are stored but not initailzied!");
return;
}
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsIAccessible *child = GetChildAt(childIdx);
if (child == aCachedChild)
break;
}
NS_ASSERTION(child == aCachedChild,
"[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");
#endif
}
PRBool
nsAccessible::EnsureChildren()
{
if (IsDefunct()) {
mAreChildrenInitialized = PR_FALSE;
return PR_TRUE;
}
if (mAreChildrenInitialized)
return PR_FALSE;
mAreChildrenInitialized = PR_TRUE; // Prevent reentry
CacheChildren();
return PR_FALSE;
}
nsIAccessible*
nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
{
if (IsDefunct()) {
if (aError)
*aError = NS_ERROR_FAILURE;
return nsnull;
}
nsIAccessible *parent = GetParent();
if (!parent) {
if (aError)
*aError = NS_ERROR_UNEXPECTED;
return nsnull;
}
nsRefPtr<nsAccessible> parentAcc =
nsAccUtils::QueryObject<nsAccessible>(parent);
PRInt32 indexInParent = parentAcc->GetIndexOf(this);
if (indexInParent == -1) {
if (aError)
*aError = NS_ERROR_UNEXPECTED;
return nsnull;
}
if (aError) {
PRInt32 childCount = parentAcc->GetChildCount();
if (indexInParent + aOffset >= childCount) {
*aError = NS_OK; // fail peacefully
return nsnull;
}
}
nsIAccessible *child = parentAcc->GetChildAt(indexInParent + aOffset);
if (aError && !child)
*aError = NS_ERROR_UNEXPECTED;
return child;
}
already_AddRefed<nsIAccessible> already_AddRefed<nsIAccessible>
nsAccessible::GetFirstAvailableAccessible(nsIDOMNode *aStartNode) nsAccessible::GetFirstAvailableAccessible(nsIDOMNode *aStartNode)

Просмотреть файл

@ -103,11 +103,11 @@ private:
#define NS_ACCESSIBLE_IMPL_CID \ #define NS_ACCESSIBLE_IMPL_CID \
{ /* 07c5a6d6-4e87-4b57-8613-4c39e1b5150a */ \ { /* 53cfa871-be42-47fc-b416-0033653b3151 */ \
0x07c5a6d6, \ 0x53cfa871, \
0x4e87, \ 0xbe42, \
0x4b57, \ 0x47fc, \
{ 0x86, 0x13, 0x4c, 0x39, 0xe1, 0xb5, 0x15, 0x0a } \ { 0xb4, 0x16, 0x00, 0x33, 0x65, 0x3b, 0x31, 0x51 } \
} }
class nsAccessible : public nsAccessNodeWrap, class nsAccessible : public nsAccessNodeWrap,
@ -199,7 +199,22 @@ public:
nsIAccessible **aChild); nsIAccessible **aChild);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Initializing methods // Initializing and cache methods
/**
* Set accessible parent.
*/
void SetParent(nsIAccessible *aParent);
/**
* Set first accessible child.
*/
void SetFirstChild(nsIAccessible *aFirstChild);
/**
* Set next sibling accessible.
*/
void SetNextSibling(nsIAccessible *aNextSibling);
/** /**
* Set the ARIA role map entry for a new accessible. * Set the ARIA role map entry for a new accessible.
@ -211,45 +226,10 @@ public:
virtual void SetRoleMapEntry(nsRoleMapEntry *aRoleMapEntry); virtual void SetRoleMapEntry(nsRoleMapEntry *aRoleMapEntry);
/** /**
* Set accessible parent. * Set the child count to -1 (unknown) and null out cached child pointers
*/
void SetParent(nsIAccessible *aParent);
/**
* Set the child count to -1 (unknown) and null out cached child pointers.
* Should be called when accessible tree is changed because document has
* transformed.
*/ */
virtual void InvalidateChildren(); virtual void InvalidateChildren();
//////////////////////////////////////////////////////////////////////////////
// Accessible tree traverse methods
/**
* Return parent accessible.
*/
virtual nsIAccessible* GetParent();
/**
* Return child accessible at the given index.
*/
virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
/**
* Return child accessible count.
*/
virtual PRInt32 GetChildCount();
/**
* Return index of the given child accessible.
*/
virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
/**
* Return index in parent accessible.
*/
PRInt32 GetIndexInParent();
/** /**
* Return parent accessible only if cached. * Return parent accessible only if cached.
*/ */
@ -260,8 +240,13 @@ public:
*/ */
already_AddRefed<nsIAccessible> GetCachedFirstChild(); already_AddRefed<nsIAccessible> GetCachedFirstChild();
/**
* Assert if child not in parent's cache.
*/
void TestChildCache(nsIAccessible *aCachedChild);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Miscellaneous methods // Miscellaneous methods.
/** /**
* Fire accessible event. * Fire accessible event.
@ -284,41 +269,22 @@ public:
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset, virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
PRUint32 aLength); PRUint32 aLength);
//////////////////////////////////////////////////////////////////////////////
// Helper methods
already_AddRefed<nsIAccessible> GetParent() {
nsIAccessible *parent = nsnull;
GetParent(&parent);
return parent;
}
protected: protected:
//////////////////////////////////////////////////////////////////////////////
// Initializing, cache and tree traverse methods
/**
* Cache accessible children.
*/
virtual void CacheChildren();
/**
* Assert if child not in parent's cache.
*/
void TestChildCache(nsIAccessible *aCachedChild);
/**
* Cache children if necessary. Return true if the accessible is defunct.
*/
PRBool EnsureChildren();
/**
* Return sibling accessible at the given offset.
*/
virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
nsresult* aError = nsnull);
//////////////////////////////////////////////////////////////////////////////
// Miscellaneous helpers
virtual nsIFrame* GetBoundsFrame(); virtual nsIFrame* GetBoundsFrame();
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame); virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
PRBool IsVisible(PRBool *aIsOffscreen); PRBool IsVisible(PRBool *aIsOffscreen);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Name helpers // Name helpers.
/** /**
* Compute the name of HTML node. * Compute the name of HTML node.
@ -334,6 +300,25 @@ protected:
static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut); static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut);
static nsresult GetTranslatedString(const nsAString& aKey, nsAString& aStringOut); static nsresult GetTranslatedString(const nsAString& aKey, nsAString& aStringOut);
/**
* Walk into subtree and calculate the string which is used as the accessible
* name or description.
*
* @param aContent [in] traversed content
* @param aFlatString [in, out] result string
* @param aIsRootHidden [in] specifies whether root content (we started to
* traverse from) is hidden, in this case the result
* string is calculated from hidden children
* (this is used when hidden root content is explicitly
* specified as label or description by author)
*/
nsresult AppendFlatStringFromSubtreeRecurse(nsIContent *aContent,
nsAString *aFlatString,
PRBool aIsRootHidden);
// Helpers for dealing with children
virtual void CacheChildren();
// nsCOMPtr<>& is useful here, because getter_AddRefs() nulls the comptr's value, and NextChild // nsCOMPtr<>& is useful here, because getter_AddRefs() nulls the comptr's value, and NextChild
// depends on the passed-in comptr being null or already set to a child (finding the next sibling). // depends on the passed-in comptr being null or already set to a child (finding the next sibling).
nsIAccessible *NextChild(nsCOMPtr<nsIAccessible>& aAccessible); nsIAccessible *NextChild(nsCOMPtr<nsIAccessible>& aAccessible);
@ -451,10 +436,11 @@ protected:
// Data Members // Data Members
nsCOMPtr<nsIAccessible> mParent; nsCOMPtr<nsIAccessible> mParent;
nsCOMArray<nsIAccessible> mChildren; nsCOMPtr<nsIAccessible> mFirstChild;
PRBool mAreChildrenInitialized; nsCOMPtr<nsIAccessible> mNextSibling;
nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
PRInt32 mAccChildCount;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessible, NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessible,

Просмотреть файл

@ -42,22 +42,64 @@
#include "nsApplicationAccessible.h" #include "nsApplicationAccessible.h"
#include "nsAccessibilityService.h"
#include "nsIComponentManager.h" #include "nsIComponentManager.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
nsApplicationAccessible::nsApplicationAccessible() : nsApplicationAccessible::nsApplicationAccessible():
nsAccessibleWrap(nsnull, nsnull) nsAccessibleWrap(nsnull, nsnull), mChildren(nsnull)
{ {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsISupports // nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(nsApplicationAccessible, nsAccessible) NS_IMPL_CYCLE_COLLECTION_CLASS(nsApplicationAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsApplicationAccessible,
nsAccessible)
nsCOMPtr<nsISimpleEnumerator> enumerator;
tmp->mChildren->Enumerate(getter_AddRefs(enumerator));
nsCOMPtr<nsIWeakReference> childWeakRef;
nsCOMPtr<nsIAccessible> accessible;
PRBool hasMoreElements;
while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements))
&& hasMoreElements) {
enumerator->GetNext(getter_AddRefs(childWeakRef));
accessible = do_QueryReferent(childWeakRef);
if (accessible) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsApplicationAccessible child");
cb.NoteXPCOMChild(accessible);
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsApplicationAccessible,
nsAccessible)
tmp->mChildren->Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsApplicationAccessible)
NS_INTERFACE_MAP_END_INHERITING(nsAccessible)
NS_IMPL_ADDREF_INHERITED(nsApplicationAccessible, nsAccessible)
NS_IMPL_RELEASE_INHERITED(nsApplicationAccessible, nsAccessible)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsIAccessNode
nsresult
nsApplicationAccessible::Init()
{
nsresult rv;
mChildren = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
return rv;
}
// nsIAccessible // nsIAccessible
NS_IMETHODIMP NS_IMETHODIMP
@ -88,67 +130,19 @@ nsApplicationAccessible::GetName(nsAString& aName)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsresult
nsApplicationAccessible::GetDescription(nsAString& aValue) nsApplicationAccessible::GetRoleInternal(PRUint32 *aRole)
{ {
aValue.Truncate(); *aRole = nsIAccessibleRole::ROLE_APP_ROOT;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsApplicationAccessible::GetRole(PRUint32 *aRole) nsApplicationAccessible::GetRole(PRUint32 *aRole)
{ {
NS_ENSURE_ARG_POINTER(aRole);
return GetRoleInternal(aRole); return GetRoleInternal(aRole);
} }
NS_IMETHODIMP
nsApplicationAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
{
NS_ENSURE_ARG_POINTER(aState);
*aState = 0;
if (aExtraState)
*aExtraState = 0;
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetParent(nsIAccessible **aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessNode public methods
PRBool
nsApplicationAccessible::IsDefunct()
{
return nsAccessibilityService::gIsShutdown;
}
nsresult
nsApplicationAccessible::Init()
{
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessible public methods
nsresult
nsApplicationAccessible::GetRoleInternal(PRUint32 *aRole)
{
*aRole = nsIAccessibleRole::ROLE_APP_ROOT;
return NS_OK;
}
nsresult nsresult
nsApplicationAccessible::GetStateInternal(PRUint32 *aState, nsApplicationAccessible::GetStateInternal(PRUint32 *aState,
PRUint32 *aExtraState) PRUint32 *aExtraState)
@ -160,59 +154,124 @@ nsApplicationAccessible::GetStateInternal(PRUint32 *aState,
return NS_OK; return NS_OK;
} }
nsIAccessible* NS_IMETHODIMP
nsApplicationAccessible::GetParent() nsApplicationAccessible::GetParent(nsIAccessible **aParent)
{ {
return nsnull; *aParent = nsnull;
return NS_OK;
} }
void NS_IMETHODIMP
nsApplicationAccessible::InvalidateChildren() nsApplicationAccessible::GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild)
{ {
// Do nothing because application children are kept updated by NS_ENSURE_ARG_POINTER(aChild);
// AddRootAccessible() and RemoveRootAccessible() method calls. *aChild = nsnull;
PRUint32 count = 0;
nsresult rv = NS_OK;
if (mChildren) {
rv = mChildren->GetLength(&count);
NS_ENSURE_SUCCESS(rv, rv);
}
if (aChildNum >= static_cast<PRInt32>(count) || count == 0)
return NS_ERROR_INVALID_ARG;
if (aChildNum < 0)
aChildNum = count - 1;
nsCOMPtr<nsIWeakReference> childWeakRef;
rv = mChildren->QueryElementAt(aChildNum, NS_GET_IID(nsIWeakReference),
getter_AddRefs(childWeakRef));
NS_ENSURE_SUCCESS(rv, rv);
if (childWeakRef) {
nsCOMPtr<nsIAccessible> childAcc(do_QueryReferent(childWeakRef));
NS_IF_ADDREF(*aChild = childAcc);
}
return NS_OK;
} }
//////////////////////////////////////////////////////////////////////////////// NS_IMETHODIMP
// nsAccessible protected methods nsApplicationAccessible::GetNextSibling(nsIAccessible **aNextSibling)
{
NS_ENSURE_ARG_POINTER(aNextSibling);
*aNextSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling)
{
NS_ENSURE_ARG_POINTER(aPreviousSibling);
*aPreviousSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetIndexInParent(PRInt32 *aIndexInParent)
{
NS_ENSURE_ARG_POINTER(aIndexInParent);
*aIndexInParent = -1;
return NS_OK;
}
void void
nsApplicationAccessible::CacheChildren() nsApplicationAccessible::CacheChildren()
{ {
// Nothing to do. Children are keeped up to dated by Add/RemoveRootAccessible if (!mChildren) {
// method calls. mAccChildCount = eChildCountUninitialized;
} return;
nsIAccessible*
nsApplicationAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
{
if (IsDefunct()) {
if (aError)
*aError = NS_ERROR_FAILURE;
return nsnull;
} }
if (aError) if (mAccChildCount == eChildCountUninitialized) {
*aError = NS_OK; // fail peacefully mAccChildCount = 0;// Prevent reentry
nsCOMPtr<nsISimpleEnumerator> enumerator;
mChildren->Enumerate(getter_AddRefs(enumerator));
return nsnull; nsCOMPtr<nsIWeakReference> childWeakRef;
nsCOMPtr<nsIAccessible> accessible;
nsRefPtr<nsAccessible> prevAcc;
PRBool hasMoreElements;
while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) &&
hasMoreElements) {
enumerator->GetNext(getter_AddRefs(childWeakRef));
accessible = do_QueryReferent(childWeakRef);
if (accessible) {
if (prevAcc)
prevAcc->SetNextSibling(accessible);
else
SetFirstChild(accessible);
prevAcc = nsAccUtils::QueryAccessible(accessible);
prevAcc->SetParent(this);
}
}
PRUint32 count = 0;
mChildren->GetLength(&count);
mAccChildCount = static_cast<PRInt32>(count);
}
} }
//////////////////////////////////////////////////////////////////////////////// // nsApplicationAccessible
// Public methods
nsresult nsresult
nsApplicationAccessible::AddRootAccessible(nsIAccessible *aRootAccessible) nsApplicationAccessible::AddRootAccessible(nsIAccessible *aRootAccessible)
{ {
NS_ENSURE_ARG_POINTER(aRootAccessible); NS_ENSURE_ARG_POINTER(aRootAccessible);
if (!mChildren.AppendObject(aRootAccessible)) // add by weak reference
return NS_ERROR_FAILURE; nsresult rv = mChildren->AppendElement(aRootAccessible, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsAccessible> rootAcc = nsAccUtils::QueryAccessible(aRootAccessible);
rootAcc->SetParent(this);
InvalidateChildren();
return NS_OK; return NS_OK;
} }
@ -221,8 +280,17 @@ nsApplicationAccessible::RemoveRootAccessible(nsIAccessible *aRootAccessible)
{ {
NS_ENSURE_ARG_POINTER(aRootAccessible); NS_ENSURE_ARG_POINTER(aRootAccessible);
// It's not needed to void root accessible parent because this method is PRUint32 index = 0;
// called on root accessible shutdown and its parent will be cleared
// properly. // we must use weak ref to get the index
return mChildren.RemoveObject(aRootAccessible) ? NS_OK : NS_ERROR_FAILURE; nsCOMPtr<nsIWeakReference> weakPtr = do_GetWeakReference(aRootAccessible);
nsresult rv = mChildren->IndexOf(0, weakPtr, &index);
NS_ENSURE_SUCCESS(rv, rv);
rv = mChildren->RemoveElementAt(index);
NS_ENSURE_SUCCESS(rv, rv);
InvalidateChildren();
return NS_OK;
} }

Просмотреть файл

@ -63,36 +63,34 @@ public:
// nsISupports // nsISupports
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsApplicationAccessible,
// nsIAccessible nsAccessible)
NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetDescription(nsAString& aValue);
NS_IMETHOD GetRole(PRUint32 *aRole);
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
NS_IMETHOD GetParent(nsIAccessible **aAccessible);
// nsAccessNode // nsAccessNode
virtual PRBool IsDefunct();
virtual nsresult Init(); virtual nsresult Init();
// nsIAccessible
NS_IMETHOD GetName(nsAString & aName);
NS_IMETHOD GetRole(PRUint32 *aRole);
NS_IMETHOD GetParent(nsIAccessible * *aParent);
NS_IMETHOD GetNextSibling(nsIAccessible * *aNextSibling);
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
NS_IMETHOD GetIndexInParent(PRInt32 *aIndexInParent);
NS_IMETHOD GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild);
// nsAccessible // nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
virtual void InvalidateChildren();
// nsApplicationAccessible // nsApplicationAccessible
virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap); virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap);
virtual nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap); virtual nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap);
protected: protected:
// nsAccessible // nsAccessible
virtual void CacheChildren(); virtual void CacheChildren();
virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
nsresult *aError = nsnull); nsCOMPtr<nsIMutableArray> mChildren;
}; };
#endif #endif

Просмотреть файл

@ -65,9 +65,7 @@ nsAccessibleWrap(aNode, aShell)
NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, nsAccessible) NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, nsAccessible)
//////////////////////////////////////////////////////////////////////////////// // nsAccessible::GetChildAtPoint()
// nsLeafAccessible: nsAccessible public
nsresult nsresult
nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild, PRBool aDeepestChild,
@ -78,13 +76,12 @@ nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
return NS_OK; return NS_OK;
} }
//////////////////////////////////////////////////////////////////////////////// // nsAccessible::CacheChildren()
// nsLeafAccessible: nsAccessible private
void void
nsLeafAccessible::CacheChildren() nsLeafAccessible::CacheChildren()
{ {
// No children for leaf accessible. // No children for leaf accessible.
mAccChildCount = IsDefunct() ? eChildCountUninitialized : 0;
} }

Просмотреть файл

@ -1027,7 +1027,7 @@ nsCoreUtils::GetLastSensibleColumn(nsITreeBoxObject *aTree)
} }
PRUint32 PRUint32
nsCoreUtils::GetSensibleColumnCount(nsITreeBoxObject *aTree) nsCoreUtils::GetSensiblecolumnCount(nsITreeBoxObject *aTree)
{ {
PRUint32 count = 0; PRUint32 count = 0;

Просмотреть файл

@ -413,7 +413,7 @@ public:
/** /**
* Return sensible columns count for the given tree box object. * Return sensible columns count for the given tree box object.
*/ */
static PRUint32 GetSensibleColumnCount(nsITreeBoxObject *aTree); static PRUint32 GetSensiblecolumnCount(nsITreeBoxObject *aTree);
/** /**
* Return sensible column at the given index for the given tree box object. * Return sensible column at the given index for the given tree box object.

Просмотреть файл

@ -73,16 +73,16 @@
#include "nsIXULDocument.h" #include "nsIXULDocument.h"
#endif #endif
//////////////////////////////////////////////////////////////////////////////// //=============================//
// Static member initialization // nsDocAccessible //
//=============================//
PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0; PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0;
nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull; nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
//-----------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// // construction
// Constructor/desctructor //-----------------------------------------------------
nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell): nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull), nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull),
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE), mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE),
@ -129,13 +129,15 @@ nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell)
} }
} }
//-----------------------------------------------------
// destruction
//-----------------------------------------------------
nsDocAccessible::~nsDocAccessible() nsDocAccessible::~nsDocAccessible()
{ {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsISupports // nsDocAccessible. nsISupports
static PLDHashOperator static PLDHashOperator
ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode, ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
@ -180,10 +182,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsHyperTextAccessible)
NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible) NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible)
NS_IMPL_RELEASE_INHERITED(nsDocAccessible, nsHyperTextAccessible) NS_IMPL_RELEASE_INHERITED(nsDocAccessible, nsHyperTextAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
NS_IMETHODIMP NS_IMETHODIMP
nsDocAccessible::GetName(nsAString& aName) nsDocAccessible::GetName(nsAString& aName)
{ {
@ -206,7 +204,6 @@ nsDocAccessible::GetName(nsAString& aName)
return rv; return rv;
} }
// nsAccessible public method
nsresult nsresult
nsDocAccessible::GetRoleInternal(PRUint32 *aRole) nsDocAccessible::GetRoleInternal(PRUint32 *aRole)
{ {
@ -245,7 +242,6 @@ nsDocAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK; return NS_OK;
} }
// nsAccessible public method
void void
nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry) nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
{ {
@ -286,7 +282,6 @@ nsDocAccessible::GetDescription(nsAString& aDescription)
return NS_OK; return NS_OK;
} }
// nsAccessible public method
nsresult nsresult
nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState) nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
{ {
@ -337,7 +332,6 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
return NS_OK; return NS_OK;
} }
// nsAccessible public method
nsresult nsresult
nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState) nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
{ {
@ -402,9 +396,7 @@ NS_IMETHODIMP nsDocAccessible::TakeFocus()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// ------- nsIAccessibleDocument Methods (5) ---------------
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleDocument
NS_IMETHODIMP nsDocAccessible::GetURL(nsAString& aURL) NS_IMETHODIMP nsDocAccessible::GetURL(nsAString& aURL)
{ {
@ -507,7 +499,6 @@ NS_IMETHODIMP nsDocAccessible::GetDocument(nsIDOMDocument **aDOMDoc)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// nsIAccessibleHyperText method
NS_IMETHODIMP nsDocAccessible::GetAssociatedEditor(nsIEditor **aEditor) NS_IMETHODIMP nsDocAccessible::GetAssociatedEditor(nsIEditor **aEditor)
{ {
NS_ENSURE_ARG_POINTER(aEditor); NS_ENSURE_ARG_POINTER(aEditor);
@ -566,7 +557,6 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod
return NS_OK; return NS_OK;
} }
// nsDocAccessible public method
void void
nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode) nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
{ {
@ -584,7 +574,6 @@ nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode); PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode);
} }
// nsDocAccessible public method
void void
nsDocAccessible::RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode) nsDocAccessible::RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode)
{ {
@ -596,8 +585,31 @@ nsDocAccessible::RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode)
mAccessNodeCache.Remove(uniqueID); mAccessNodeCache.Remove(uniqueID);
} }
//////////////////////////////////////////////////////////////////////////////// NS_IMETHODIMP nsDocAccessible::GetParent(nsIAccessible **aParent)
// nsAccessNode {
// Hook up our new accessible with our parent
*aParent = nsnull;
NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
if (!mParent) {
nsIDocument *parentDoc = mDocument->GetParentDocument();
NS_ENSURE_TRUE(parentDoc, NS_ERROR_FAILURE);
nsIContent *ownerContent = parentDoc->FindContentForSubDocument(mDocument);
nsCOMPtr<nsIDOMNode> ownerNode(do_QueryInterface(ownerContent));
if (ownerNode) {
nsCOMPtr<nsIAccessibilityService> accService =
do_GetService("@mozilla.org/accessibilityService;1");
if (accService) {
// XXX aaronl: ideally we would traverse the presshell chain
// Since there's no easy way to do that, we cheat and use
// the document hierarchy. GetAccessibleFor() is bad because
// it doesn't support our concept of multiple presshells per doc.
// It should be changed to use GetAccessibleInWeakShell()
accService->GetAccessibleFor(ownerNode, getter_AddRefs(mParent));
}
}
}
return mParent ? nsAccessible::GetParent(aParent) : NS_ERROR_FAILURE;
}
nsresult nsresult
nsDocAccessible::Init() nsDocAccessible::Init()
@ -606,7 +618,8 @@ nsDocAccessible::Init()
AddEventListeners(); AddEventListeners();
GetParent(); // Ensure outer doc mParent accessible. nsCOMPtr<nsIAccessible> parentAccessible; // Ensure outer doc mParent accessible
GetParent(getter_AddRefs(parentAccessible));
nsresult rv = nsHyperTextAccessibleWrap::Init(); nsresult rv = nsHyperTextAccessibleWrap::Init();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -667,7 +680,6 @@ nsDocAccessible::Shutdown()
return NS_OK; return NS_OK;
} }
// nsDocAccessible protected member
void nsDocAccessible::ShutdownChildDocuments(nsIDocShellTreeItem *aStart) void nsDocAccessible::ShutdownChildDocuments(nsIDocShellTreeItem *aStart)
{ {
nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aStart)); nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aStart));
@ -713,7 +725,6 @@ nsDocAccessible::IsDefunct()
return !mDocument; return !mDocument;
} }
// nsDocAccessible protected member
void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame) void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
{ {
*aRelativeFrame = GetFrame(); *aRelativeFrame = GetFrame();
@ -757,7 +768,7 @@ void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
} }
} }
// nsDocAccessible protected member
nsresult nsDocAccessible::AddEventListeners() nsresult nsDocAccessible::AddEventListeners()
{ {
// 1) Set up scroll position listener // 1) Set up scroll position listener
@ -803,7 +814,6 @@ nsresult nsDocAccessible::AddEventListeners()
return NS_OK; return NS_OK;
} }
// nsDocAccessible protected member
nsresult nsDocAccessible::RemoveEventListeners() nsresult nsDocAccessible::RemoveEventListeners()
{ {
// Remove listeners associated with content documents // Remove listeners associated with content documents
@ -850,7 +860,6 @@ nsresult nsDocAccessible::RemoveEventListeners()
return NS_OK; return NS_OK;
} }
// nsDocAccessible public member
void void
nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType) nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
{ {
@ -880,7 +889,8 @@ nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
if (isFinished) { if (isFinished) {
// Need to wait until scrollable view is available // Need to wait until scrollable view is available
AddScrollListener(); AddScrollListener();
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(GetParent())); nsCOMPtr<nsIAccessible> parent(nsAccessible::GetParent());
nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(parent));
if (acc) { if (acc) {
// Make the parent forget about the old document as a child // Make the parent forget about the old document as a child
acc->InvalidateChildren(); acc->InvalidateChildren();
@ -944,7 +954,6 @@ void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure)
} }
} }
// nsDocAccessible protected member
void nsDocAccessible::AddScrollListener() void nsDocAccessible::AddScrollListener()
{ {
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell)); nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
@ -961,7 +970,6 @@ void nsDocAccessible::AddScrollListener()
scrollableView->AddScrollPositionListener(this); scrollableView->AddScrollPositionListener(this);
} }
// nsDocAccessible protected member
void nsDocAccessible::RemoveScrollListener() void nsDocAccessible::RemoveScrollListener()
{ {
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell)); nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
@ -978,9 +986,6 @@ void nsDocAccessible::RemoveScrollListener()
scrollableView->RemoveScrollPositionListener(this); scrollableView->RemoveScrollPositionListener(this);
} }
////////////////////////////////////////////////////////////////////////////////
// nsIScrollPositionListener
NS_IMETHODIMP nsDocAccessible::ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY) NS_IMETHODIMP nsDocAccessible::ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY)
{ {
return NS_OK; return NS_OK;
@ -1007,9 +1012,6 @@ NS_IMETHODIMP nsDocAccessible::ScrollPositionDidChange(nsIScrollableView *aScrol
return NS_OK; return NS_OK;
} }
////////////////////////////////////////////////////////////////////////////////
// nsIObserver
NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic, NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData) const PRUnichar *aData)
{ {
@ -1024,7 +1026,7 @@ NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic
return NS_OK; return NS_OK;
} }
//////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// nsIDocumentObserver // nsIDocumentObserver
NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsDocAccessible) NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsDocAccessible)
@ -1060,7 +1062,7 @@ nsDocAccessible::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
} }
} }
// nsDocAccessible protected member
void void
nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute) nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute)
{ {
@ -1211,7 +1213,6 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
} }
} }
// nsDocAccessible protected member
void void
nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute) nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
{ {
@ -1361,7 +1362,6 @@ void nsDocAccessible::ContentAppended(nsIDocument *aDocument,
} }
} }
void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument, void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1, nsIContent* aContent1,
nsIContent* aContent2, nsIContent* aContent2,
@ -1417,45 +1417,6 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent)
{ {
} }
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
nsIAccessible*
nsDocAccessible::GetParent()
{
if (IsDefunct())
return nsnull;
if (mParent)
return mParent;
nsIDocument* parentDoc = mDocument->GetParentDocument();
if (!parentDoc)
return nsnull;
nsIContent* ownerContent = parentDoc->FindContentForSubDocument(mDocument);
nsCOMPtr<nsIDOMNode> ownerNode(do_QueryInterface(ownerContent));
if (ownerNode) {
nsCOMPtr<nsIAccessibilityService> accService = GetAccService();
if (accService) {
// XXX aaronl: ideally we would traverse the presshell chain. Since
// there's no easy way to do that, we cheat and use the document
// hierarchy. GetAccessibleFor() is bad because it doesn't support our
// concept of multiple presshells per doc.
// It should be changed to use GetAccessibleInWeakShell()
accService->GetAccessibleFor(ownerNode, getter_AddRefs(mParent));
}
}
NS_ASSERTION(mParent, "No parent for not root document accessible!");
return mParent;
}
////////////////////////////////////////////////////////////////////////////////
// Protected members
void void
nsDocAccessible::FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible) nsDocAccessible::FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible)
{ {
@ -1610,8 +1571,7 @@ nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessibl
return event; return event;
} }
// nsDocAccessible public member
nsresult nsresult
nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType, nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType,
nsIDOMNode *aDOMNode, nsIDOMNode *aDOMNode,
@ -1625,7 +1585,6 @@ nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType,
return FireDelayedAccessibleEvent(event); return FireDelayedAccessibleEvent(event);
} }
// nsDocAccessible public member
nsresult nsresult
nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent) nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent)
{ {
@ -1994,7 +1953,6 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
mAccessNodeCache.Remove(uniqueID); mAccessNodeCache.Remove(uniqueID);
} }
// nsDocAccessible public member
void void
nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
PRUint32 aChangeType) PRUint32 aChangeType)
@ -2222,7 +2180,6 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
FireDelayedAccessibleEvent(reorderEvent); FireDelayedAccessibleEvent(reorderEvent);
} }
// nsIAccessibleDocument method
NS_IMETHODIMP NS_IMETHODIMP
nsDocAccessible::GetAccessibleInParentChain(nsIDOMNode *aNode, nsDocAccessible::GetAccessibleInParentChain(nsIDOMNode *aNode,
PRBool aCanCreate, PRBool aCanCreate,

Просмотреть файл

@ -87,6 +87,7 @@ public:
NS_IMETHOD GetDescription(nsAString& aDescription); NS_IMETHOD GetDescription(nsAString& aDescription);
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes); NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild); NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD TakeFocus(void); NS_IMETHOD TakeFocus(void);
// nsIScrollPositionListener // nsIScrollPositionListener
@ -110,9 +111,7 @@ public:
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry); virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
virtual nsIAccessible* GetParent();
// nsIAccessibleText // nsIAccessibleText
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor); NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);

Просмотреть файл

@ -99,11 +99,25 @@ nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
return NS_OK; return NS_OK;
} }
void void nsOuterDocAccessible::CacheChildren()
nsOuterDocAccessible::CacheChildren() {
{ // An outer doc accessible usually has 1 nsDocAccessible child,
// An outer doc accessible usually has 1 nsDocAccessible child, but could have // but could have none if we can't get to the inner documnet
// none if we can't get to the inner documnet. if (!mWeakShell) {
mAccChildCount = eChildCountUninitialized;
return; // This outer doc node has been shut down
}
if (mAccChildCount != eChildCountUninitialized) {
return;
}
InvalidateChildren();
mAccChildCount = 0;
// In these variable names, "outer" relates to the nsOuterDocAccessible
// as opposed to the nsDocAccessibleWrap which is "inner".
// The outer node is a something like a <browser>, <frame>, <iframe>, <page> or
// <editor> tag, whereas the inner node corresponds to the inner document root.
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode)); nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
NS_ASSERTION(content, "No nsIContent for <browser>/<iframe>/<editor> dom node"); NS_ASSERTION(content, "No nsIContent for <browser>/<iframe>/<editor> dom node");
@ -120,15 +134,18 @@ nsOuterDocAccessible::CacheChildren()
} }
nsCOMPtr<nsIAccessible> innerAccessible; nsCOMPtr<nsIAccessible> innerAccessible;
nsCOMPtr<nsIAccessibilityService> accService = GetAccService(); nsCOMPtr<nsIAccessibilityService> accService =
do_GetService("@mozilla.org/accessibilityService;1");
accService->GetAccessibleFor(innerNode, getter_AddRefs(innerAccessible)); accService->GetAccessibleFor(innerNode, getter_AddRefs(innerAccessible));
nsRefPtr<nsAccessible> innerAcc(nsAccUtils::QueryAccessible(innerAccessible)); nsRefPtr<nsAccessible> innerAcc(nsAccUtils::QueryAccessible(innerAccessible));
if (!innerAcc) if (!innerAcc)
return; return;
// Success getting inner document as first child -- now we cache it. // Success getting inner document as first child -- now we cache it.
mChildren.AppendObject(innerAccessible); mAccChildCount = 1;
SetFirstChild(innerAccessible); // weak ref
innerAcc->SetParent(this); innerAcc->SetParent(this);
innerAcc->SetNextSibling(nsnull);
} }
nsresult nsresult

Просмотреть файл

@ -42,14 +42,8 @@
#include "nsAccessibleWrap.h" #include "nsAccessibleWrap.h"
#include "nsIAccessible.h" #include "nsIAccessible.h"
/** class nsIWeakReference;
* Used for <browser>, <frame>, <iframe>, <page> or editor> elements.
*
* In these variable names, "outer" relates to the nsOuterDocAccessible as
* opposed to the nsDocAccessibleWrap which is "inner". The outer node is
* a something like tags listed above, whereas the inner node corresponds to
* the inner document root.
*/
class nsOuterDocAccessible : public nsAccessibleWrap class nsOuterDocAccessible : public nsAccessibleWrap
{ {
// XXX: why is it private? // XXX: why is it private?
@ -76,7 +70,7 @@ public:
protected: protected:
// nsAccessible // nsAccessible
virtual void CacheChildren(); void CacheChildren();
}; };
#endif #endif

Просмотреть файл

@ -84,9 +84,6 @@
#include "nsIXULWindow.h" #include "nsIXULWindow.h"
#endif #endif
////////////////////////////////////////////////////////////////////////////////
// nsISupports
// Expanded version of NS_IMPL_ISUPPORTS_INHERITED2 // Expanded version of NS_IMPL_ISUPPORTS_INHERITED2
// so we can QI directly to concrete nsRootAccessible // so we can QI directly to concrete nsRootAccessible
NS_IMPL_QUERY_HEAD(nsRootAccessible) NS_IMPL_QUERY_HEAD(nsRootAccessible)
@ -99,21 +96,21 @@ NS_IMPL_QUERY_TAIL_INHERITING(nsDocAccessible)
NS_IMPL_ADDREF_INHERITED(nsRootAccessible, nsDocAccessible) NS_IMPL_ADDREF_INHERITED(nsRootAccessible, nsDocAccessible)
NS_IMPL_RELEASE_INHERITED(nsRootAccessible, nsDocAccessible) NS_IMPL_RELEASE_INHERITED(nsRootAccessible, nsDocAccessible)
//////////////////////////////////////////////////////////////////////////////// //-----------------------------------------------------
// Constructor/desctructor // construction
//-----------------------------------------------------
nsRootAccessible::nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell): nsRootAccessible::nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
nsDocAccessibleWrap(aDOMNode, aShell) nsDocAccessibleWrap(aDOMNode, aShell)
{ {
} }
//-----------------------------------------------------
// destruction
//-----------------------------------------------------
nsRootAccessible::~nsRootAccessible() nsRootAccessible::~nsRootAccessible()
{ {
} }
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
/* readonly attribute AString name; */ /* readonly attribute AString name; */
NS_IMETHODIMP NS_IMETHODIMP
nsRootAccessible::GetName(nsAString& aName) nsRootAccessible::GetName(nsAString& aName)
@ -135,6 +132,21 @@ nsRootAccessible::GetName(nsAString& aName)
return document->GetTitle(aName); return document->GetTitle(aName);
} }
/* readonly attribute nsIAccessible accParent; */
NS_IMETHODIMP nsRootAccessible::GetParent(nsIAccessible * *aParent)
{
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nsnull;
if (!mParent) {
nsRefPtr<nsApplicationAccessibleWrap> root = GetApplicationAccessible();
mParent = root;
}
NS_IF_ADDREF(*aParent = mParent);
return NS_OK;
}
/* readonly attribute unsigned long accRole; */ /* readonly attribute unsigned long accRole; */
nsresult nsresult
nsRootAccessible::GetRoleInternal(PRUint32 *aRole) nsRootAccessible::GetRoleInternal(PRUint32 *aRole)
@ -160,7 +172,6 @@ nsRootAccessible::GetRoleInternal(PRUint32 *aRole)
return nsDocAccessibleWrap::GetRoleInternal(aRole); return nsDocAccessibleWrap::GetRoleInternal(aRole);
} }
// nsRootAccessible protected member
#ifdef MOZ_XUL #ifdef MOZ_XUL
PRUint32 nsRootAccessible::GetChromeFlags() PRUint32 nsRootAccessible::GetChromeFlags()
{ {
@ -570,8 +581,7 @@ void nsRootAccessible::FireCurrentFocusEvent()
} }
} }
//////////////////////////////////////////////////////////////////////////////// // --------------- nsIDOMEventListener Methods (3) ------------------------
// nsIDOMEventListener
NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent) NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
{ {
@ -585,8 +595,6 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
return HandleEventWithTarget(aEvent, targetNode); return HandleEventWithTarget(aEvent, targetNode);
} }
// nsRootAccessible protected member
nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent, nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
nsIDOMNode* aTargetNode) nsIDOMNode* aTargetNode)
{ {
@ -938,9 +946,6 @@ void nsRootAccessible::FireFocusCallback(nsITimer *aTimer, void *aClosure)
rootAccessible->FireCurrentFocusEvent(); rootAccessible->FireCurrentFocusEvent();
} }
////////////////////////////////////////////////////////////////////////////////
// nsAccessNode
nsresult nsresult
nsRootAccessible::Init() nsRootAccessible::Init()
{ {
@ -975,7 +980,6 @@ nsRootAccessible::Shutdown()
return nsDocAccessibleWrap::Shutdown(); return nsDocAccessibleWrap::Shutdown();
} }
// nsRootAccessible protected member
already_AddRefed<nsIDocShellTreeItem> already_AddRefed<nsIDocShellTreeItem>
nsRootAccessible::GetContentDocShell(nsIDocShellTreeItem *aStart) nsRootAccessible::GetContentDocShell(nsIDocShellTreeItem *aStart)
{ {
@ -1032,7 +1036,6 @@ nsRootAccessible::GetContentDocShell(nsIDocShellTreeItem *aStart)
return nsnull; return nsnull;
} }
// nsIAccessible method
NS_IMETHODIMP NS_IMETHODIMP
nsRootAccessible::GetRelationByType(PRUint32 aRelationType, nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation) nsIAccessibleRelation **aRelation)
@ -1059,20 +1062,6 @@ nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
return NS_OK; return NS_OK;
} }
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
nsIAccessible*
nsRootAccessible::GetParent()
{
// Parent has been setted in nsApplicationAccesible::AddRootAccessible()
// when root accessible was intialized.
return mParent;
}
////////////////////////////////////////////////////////////////////////////////
// nsDocAccessible
void void
nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType) nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
{ {
@ -1095,9 +1084,6 @@ nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED); aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
} }
////////////////////////////////////////////////////////////////////////////////
// Protected members
nsresult nsresult
nsRootAccessible::HandlePopupShownEvent(nsIAccessible *aAccessible) nsRootAccessible::HandlePopupShownEvent(nsIAccessible *aAccessible)
{ {

Просмотреть файл

@ -74,6 +74,7 @@ public:
// nsIAccessible // nsIAccessible
NS_IMETHOD GetName(nsAString& aName); NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetParent(nsIAccessible * *aParent);
NS_IMETHOD GetRelationByType(PRUint32 aRelationType, NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation); nsIAccessibleRelation **aRelation);
@ -87,7 +88,6 @@ public:
// nsAccessible // nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
// nsDocAccessible // nsDocAccessible
virtual void FireDocLoadEvents(PRUint32 aEventType); virtual void FireDocLoadEvents(PRUint32 aEventType);

Просмотреть файл

@ -70,4 +70,5 @@ void
nsTextAccessible::CacheChildren() nsTextAccessible::CacheChildren()
{ {
// No children for text accessible. // No children for text accessible.
mAccChildCount = IsDefunct() ? eChildCountUninitialized : 0;
} }

Просмотреть файл

@ -155,4 +155,5 @@ void
nsHTMLAreaAccessible::CacheChildren() nsHTMLAreaAccessible::CacheChildren()
{ {
// No children for aria accessible. // No children for aria accessible.
mAccChildCount = IsDefunct() ? eChildCountUninitialized : 0;
} }

Просмотреть файл

@ -155,28 +155,42 @@ nsHTMLImageAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK; return NS_OK;
} }
void void nsHTMLImageAccessible::CacheChildren()
nsHTMLImageAccessible::CacheChildren()
{ {
if (!mWeakShell) {
// This node has been shut down
mAccChildCount = eChildCountUninitialized;
return;
}
if (mAccChildCount != eChildCountUninitialized) {
return;
}
mAccChildCount = 0;
nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection(); nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
if (!mapAreas) if (!mapAreas)
return; return;
PRUint32 areaCount = 0; PRUint32 numMapAreas;
mapAreas->GetLength(&areaCount); mapAreas->GetLength(&numMapAreas);
PRInt32 childCount = 0;
nsCOMPtr<nsIAccessible> areaAccessible; nsCOMPtr<nsIAccessible> areaAccessible;
nsRefPtr<nsAccessible> areaAcc; nsRefPtr<nsAccessible> prevAcc;
while (childCount < (PRInt32)numMapAreas &&
(areaAccessible = GetAreaAccessible(mapAreas, childCount)) != nsnull) {
if (prevAcc)
prevAcc->SetNextSibling(areaAccessible);
else
SetFirstChild(areaAccessible);
for (PRUint32 areaIdx = 0; areaIdx < areaCount; areaIdx++) { ++ childCount;
areaAccessible = GetAreaAccessible(mapAreas, areaIdx);
if (!areaAccessible)
return;
mChildren.AppendObject(areaAccessible); prevAcc = nsAccUtils::QueryAccessible(areaAccessible);
areaAcc = nsAccUtils::QueryObject<nsAccessible>(areaAccessible); prevAcc->SetParent(this);
areaAcc->SetParent(this);
} }
mAccChildCount = childCount;
} }
NS_IMETHODIMP NS_IMETHODIMP

Просмотреть файл

@ -83,7 +83,6 @@ protected:
// nsAccessible // nsAccessible
virtual void CacheChildren(); virtual void CacheChildren();
// nsHTMLImageAccessible
already_AddRefed<nsIDOMHTMLCollection> GetAreaCollection(); already_AddRefed<nsIDOMHTMLCollection> GetAreaCollection();
already_AddRefed<nsIAccessible> already_AddRefed<nsIAccessible>
GetAreaAccessible(nsIDOMHTMLCollection* aAreaNodes, PRInt32 aAreaNum); GetAreaAccessible(nsIDOMHTMLCollection* aAreaNodes, PRInt32 aAreaNum);

Просмотреть файл

@ -305,9 +305,7 @@ NS_IMETHODIMP nsHTMLSelectableAccessible::SelectAllSelection(PRBool *_retval)
/** First, the common widgets */ /** First, the common widgets */
/** ------------------------------------------------------ */ /** ------------------------------------------------------ */
//////////////////////////////////////////////////////////////////////////////// /** ----- nsHTMLSelectListAccessible ----- */
// nsHTMLSelectListAccessible
////////////////////////////////////////////////////////////////////////////////
/** Default Constructor */ /** Default Constructor */
nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIDOMNode* aDOMNode, nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIDOMNode* aDOMNode,
@ -316,9 +314,11 @@ nsHTMLSelectListAccessible::nsHTMLSelectListAccessible(nsIDOMNode* aDOMNode,
{ {
} }
//////////////////////////////////////////////////////////////////////////////// /**
// nsHTMLSelectListAccessible: nsAccessible public * As a nsHTMLSelectListAccessible we can have the following states:
* nsIAccessibleStates::STATE_MULTISELECTABLE
* nsIAccessibleStates::STATE_EXTSELECTABLE
*/
nsresult nsresult
nsHTMLSelectListAccessible::GetStateInternal(PRUint32 *aState, nsHTMLSelectListAccessible::GetStateInternal(PRUint32 *aState,
PRUint32 *aExtraState) PRUint32 *aExtraState)
@ -327,10 +327,6 @@ nsHTMLSelectListAccessible::GetStateInternal(PRUint32 *aState,
aExtraState); aExtraState);
NS_ENSURE_A11Y_SUCCESS(rv, rv); NS_ENSURE_A11Y_SUCCESS(rv, rv);
// As a nsHTMLSelectListAccessible we can have the following states:
// nsIAccessibleStates::STATE_MULTISELECTABLE
// nsIAccessibleStates::STATE_EXTSELECTABLE
nsCOMPtr<nsIDOMHTMLSelectElement> select (do_QueryInterface(mDOMNode)); nsCOMPtr<nsIDOMHTMLSelectElement> select (do_QueryInterface(mDOMNode));
if (select) { if (select) {
if (*aState & nsIAccessibleStates::STATE_FOCUSED) { if (*aState & nsIAccessibleStates::STATE_FOCUSED) {
@ -364,63 +360,109 @@ nsHTMLSelectListAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK; return NS_OK;
} }
//////////////////////////////////////////////////////////////////////////////// already_AddRefed<nsIAccessible>
// nsHTMLSelectListAccessible: nsAccessible protected nsHTMLSelectListAccessible::AccessibleForOption(nsIAccessibilityService *aAccService,
nsIContent *aContent,
void nsIAccessible *aLastGoodAccessible,
nsHTMLSelectListAccessible::CacheChildren() PRInt32 *aChildCount)
{ {
// Cache accessibles for <optgroup> and <option> DOM decendents as children, nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(aContent));
// as well as the accessibles for them. Avoid whitespace text nodes. We want NS_ASSERTION(domNode, "DOM node is null");
// to count all the <optgroup>s and <option>s as children because we want // Accessibility service will initialize & cache any accessibles created
// a flat tree under the Select List. nsCOMPtr<nsIAccessible> accessible;
aAccService->GetAccessibleInWeakShell(domNode, mWeakShell, getter_AddRefs(accessible));
nsCOMPtr<nsIContent> selectContent(do_QueryInterface(mDOMNode)); nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(accessible));
CacheOptSiblings(selectContent); if (!acc)
return nsnull;
++ *aChildCount;
acc->SetParent(this);
nsRefPtr<nsAccessible> prevAcc =
nsAccUtils::QueryAccessible(aLastGoodAccessible);
if (prevAcc)
prevAcc->SetNextSibling(accessible);
if (!mFirstChild)
mFirstChild = accessible;
return accessible.forget();
} }
//////////////////////////////////////////////////////////////////////////////// already_AddRefed<nsIAccessible>
// nsHTMLSelectListAccessible protected nsHTMLSelectListAccessible::CacheOptSiblings(nsIAccessibilityService *aAccService,
nsIContent *aParentContent,
void nsIAccessible *aLastGoodAccessible,
nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent) PRInt32 *aChildCount)
{ {
// Recursive helper for CacheChildren()
PRUint32 numChildren = aParentContent->GetChildCount(); PRUint32 numChildren = aParentContent->GetChildCount();
nsCOMPtr<nsIAccessible> lastGoodAccessible(aLastGoodAccessible);
nsCOMPtr<nsIAccessible> newAccessible;
for (PRUint32 count = 0; count < numChildren; count ++) { for (PRUint32 count = 0; count < numChildren; count ++) {
nsIContent *childContent = aParentContent->GetChildAt(count); nsIContent *childContent = aParentContent->GetChildAt(count);
if (!childContent->IsHTML()) { if (!childContent->IsHTML()) {
continue; continue;
} }
nsCOMPtr<nsIAtom> tag = childContent->Tag(); nsCOMPtr<nsIAtom> tag = childContent->Tag();
if (tag == nsAccessibilityAtoms::option || if (tag == nsAccessibilityAtoms::option || tag == nsAccessibilityAtoms::optgroup) {
tag == nsAccessibilityAtoms::optgroup) { newAccessible = AccessibleForOption(aAccService,
childContent,
// Get an accessible for option or optgroup and cache it. lastGoodAccessible,
nsCOMPtr<nsIDOMNode> childNode(do_QueryInterface(childContent)); aChildCount);
if (newAccessible) {
nsCOMPtr<nsIAccessible> accessible; lastGoodAccessible = newAccessible;
GetAccService()->GetAccessibleInWeakShell(childNode, mWeakShell, }
getter_AddRefs(accessible)); if (tag == nsAccessibilityAtoms::optgroup) {
if (accessible) { newAccessible = CacheOptSiblings(aAccService, childContent,
mChildren.AppendObject(accessible); lastGoodAccessible, aChildCount);
if (newAccessible) {
nsRefPtr<nsAccessible> acc = lastGoodAccessible = newAccessible;
nsAccUtils::QueryObject<nsAccessible>(accessible); }
acc->SetParent(this);
} }
// Deep down into optgroup element.
if (tag == nsAccessibilityAtoms::optgroup)
CacheOptSiblings(childContent);
} }
} }
if (lastGoodAccessible) {
nsRefPtr<nsAccessible> lastAcc =
nsAccUtils::QueryAccessible(lastGoodAccessible);
lastAcc->SetNextSibling(nsnull);
}
return lastGoodAccessible.forget();
} }
/**
* Cache the children and child count of a Select List Accessible. We want to count
* all the <optgroup>s and <option>s as children because we want a
* flat tree under the Select List.
*/
//////////////////////////////////////////////////////////////////////////////// void nsHTMLSelectListAccessible::CacheChildren()
// nsHTMLSelectOptionAccessible {
//////////////////////////////////////////////////////////////////////////////// // Cache the number of <optgroup> and <option> DOM decendents,
// as well as the accessibles for them. Avoid whitespace text nodes.
nsCOMPtr<nsIContent> selectContent(do_QueryInterface(mDOMNode));
nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1"));
if (!selectContent || !accService) {
mAccChildCount = eChildCountUninitialized;
return;
}
if (mAccChildCount != eChildCountUninitialized) {
return;
}
mAccChildCount = 0; // Avoid reentry
PRInt32 childCount = 0;
nsCOMPtr<nsIAccessible> lastGoodAccessible =
CacheOptSiblings(accService, selectContent, nsnull, &childCount);
mAccChildCount = childCount;
}
/** ----- nsHTMLSelectOptionAccessible ----- */
/** Default Constructor */ /** Default Constructor */
nsHTMLSelectOptionAccessible::nsHTMLSelectOptionAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): nsHTMLSelectOptionAccessible::nsHTMLSelectOptionAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
@ -843,9 +885,7 @@ nsIContent* nsHTMLSelectOptionAccessible::GetSelectState(PRUint32* aState,
return nsnull; return nsnull;
} }
//////////////////////////////////////////////////////////////////////////////// /** ----- nsHTMLSelectOptGroupAccessible ----- */
// nsHTMLSelectOptGroupAccessible
////////////////////////////////////////////////////////////////////////////////
/** Default Constructor */ /** Default Constructor */
nsHTMLSelectOptGroupAccessible::nsHTMLSelectOptGroupAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): nsHTMLSelectOptGroupAccessible::nsHTMLSelectOptGroupAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
@ -889,26 +929,29 @@ NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetNumActions(PRUint8 *_retval)
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
//////////////////////////////////////////////////////////////////////////////// void nsHTMLSelectOptGroupAccessible::CacheChildren()
// nsHTMLSelectOptGroupAccessible: nsAccessible protected
void
nsHTMLSelectOptGroupAccessible::CacheChildren()
{ {
// XXX To do (bug 378612) - create text child for the anonymous attribute if (!mWeakShell) {
// content, so that nsIAccessibleText is supported for the <optgroup> as it is // This node has been shut down
// for an <option>. Attribute content is what layout creates for mAccChildCount = eChildCountUninitialized;
// the label="foo" on the <optgroup>. See eStyleContentType_Attr and return;
// CreateAttributeContent() in nsCSSFrameConstructor }
if (mAccChildCount == eChildCountUninitialized) {
// XXX To do (bug 378612) - create text child for the anonymous attribute content, so that
// nsIAccessibleText is supported for the <optgroup> as it is for an <option>
// Attribute content is what layout creates for the label="foo" on the <optgroup>
// See eStyleContentType_Attr and CreateAttributeContent() in nsCSSFrameConstructor
mAccChildCount = 0;
SetFirstChild(nsnull);
}
} }
/** ------------------------------------------------------ */ /** ------------------------------------------------------ */
/** Finally, the Combobox widgets */ /** Finally, the Combobox widgets */
/** ------------------------------------------------------ */ /** ------------------------------------------------------ */
//////////////////////////////////////////////////////////////////////////////// /** ----- nsHTMLComboboxAccessible ----- */
// nsHTMLComboboxAccessible
////////////////////////////////////////////////////////////////////////////////
nsHTMLComboboxAccessible::nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): nsHTMLComboboxAccessible::nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
nsAccessibleWrap(aDOMNode, aShell) nsAccessibleWrap(aDOMNode, aShell)
@ -923,32 +966,46 @@ nsHTMLComboboxAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK; return NS_OK;
} }
void void nsHTMLComboboxAccessible::CacheChildren()
nsHTMLComboboxAccessible::CacheChildren()
{ {
nsIFrame* frame = GetFrame(); if (!mWeakShell) {
if (!frame) // This node has been shut down
mAccChildCount = eChildCountUninitialized;
return; return;
nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
if (!comboFrame)
return;
nsIFrame *listFrame = comboFrame->GetDropDown();
if (!listFrame)
return;
if (!mListAccessible) {
mListAccessible =
new nsHTMLComboboxListAccessible(mParent, mDOMNode, mWeakShell);
if (!mListAccessible)
return;
mListAccessible->Init();
} }
mChildren.AppendObject(mListAccessible); if (mAccChildCount == eChildCountUninitialized) {
mListAccessible->SetParent(this); mAccChildCount = 0;
nsIFrame *frame = GetFrame();
if (!frame) {
return;
}
nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
if (!comboFrame) {
return;
}
nsIFrame *listFrame = comboFrame->GetDropDown();
if (!listFrame) {
return;
}
if (!mListAccessible) {
mListAccessible =
new nsHTMLComboboxListAccessible(mParent, mDOMNode, mWeakShell);
if (!mListAccessible)
return;
mListAccessible->Init();
}
SetFirstChild(mListAccessible);
mListAccessible->SetParent(this);
mListAccessible->SetNextSibling(nsnull);
++ mAccChildCount; // List accessible child successfully added
}
} }
nsresult nsresult
@ -1097,7 +1154,6 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::GetActionName(PRUint8 aIndex, nsAString&
return NS_OK; return NS_OK;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsHTMLComboboxListAccessible // nsHTMLComboboxListAccessible
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1149,6 +1205,13 @@ nsHTMLComboboxListAccessible::GetStateInternal(PRUint32 *aState,
return NS_OK; return NS_OK;
} }
/** Return our cached parent */
NS_IMETHODIMP nsHTMLComboboxListAccessible::GetParent(nsIAccessible **aParent)
{
NS_IF_ADDREF(*aParent = mParent);
return NS_OK;
}
NS_IMETHODIMP nsHTMLComboboxListAccessible::GetUniqueID(void **aUniqueID) NS_IMETHODIMP nsHTMLComboboxListAccessible::GetUniqueID(void **aUniqueID)
{ {
// Since mDOMNode is same for all tree item, use |this| pointer as the unique Id // Since mDOMNode is same for all tree item, use |this| pointer as the unique Id
@ -1164,10 +1227,11 @@ void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBo
{ {
*aBoundingFrame = nsnull; *aBoundingFrame = nsnull;
nsCOMPtr<nsIAccessible> comboAccessible = GetParent(); nsCOMPtr<nsIAccessible> comboAccessible;
if (!comboAccessible) GetParent(getter_AddRefs(comboAccessible));
if (!comboAccessible) {
return; return;
}
if (0 == (nsAccUtils::State(comboAccessible) & nsIAccessibleStates::STATE_COLLAPSED)) { if (0 == (nsAccUtils::State(comboAccessible) & nsIAccessibleStates::STATE_COLLAPSED)) {
nsHTMLSelectListAccessible::GetBoundsRect(aBounds, aBoundingFrame); nsHTMLSelectListAccessible::GetBoundsRect(aBounds, aBoundingFrame);
return; return;
@ -1195,10 +1259,3 @@ void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBo
*aBoundingFrame = frame->GetParent(); *aBoundingFrame = frame->GetParent();
aBounds = (*aBoundingFrame)->GetRect(); aBounds = (*aBoundingFrame)->GetRect();
} }
// nsHTMLComboboxListAccessible. nsAccessible public mehtod
nsIAccessible*
nsHTMLComboboxListAccessible::GetParent()
{
return mParent;
}

Просмотреть файл

@ -130,16 +130,18 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
protected: protected:
void CacheChildren();
// nsAccessible already_AddRefed<nsIAccessible>
virtual void CacheChildren(); AccessibleForOption(nsIAccessibilityService *aAccService,
nsIContent *aContent,
// nsHTMLSelectListAccessible nsIAccessible *aLastGoodAccessible,
PRInt32 *aChildCount);
/** already_AddRefed<nsIAccessible>
* Recursive helper for CacheChildren(). CacheOptSiblings(nsIAccessibilityService *aAccService,
*/ nsIContent *aParentContent,
void CacheOptSiblings(nsIContent *aParentContent); nsIAccessible *aLastGoodAccessible,
PRInt32 *aChildCount);
}; };
/* /*
@ -199,8 +201,7 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
protected: protected:
// nsAccessible void CacheChildren();
virtual void CacheChildren();
}; };
/** ------------------------------------------------------ */ /** ------------------------------------------------------ */
@ -235,10 +236,8 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
protected: protected:
// nsAccessible void CacheChildren();
virtual void CacheChildren();
// nsHTMLComboboxAccessible
already_AddRefed<nsIAccessible> GetFocusedOptionAccessible(); already_AddRefed<nsIAccessible> GetFocusedOptionAccessible();
private: private:
@ -260,6 +259,7 @@ public:
virtual ~nsHTMLComboboxListAccessible() {} virtual ~nsHTMLComboboxListAccessible() {}
// nsIAccessible // nsIAccessible
NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD GetUniqueID(void **aUniqueID); NS_IMETHOD GetUniqueID(void **aUniqueID);
// nsAccessNode // nsAccessNode
@ -268,7 +268,6 @@ public:
// nsAccessible // nsAccessible
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame); virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
virtual nsIAccessible* GetParent();
}; };
#endif #endif

Просмотреть файл

@ -455,27 +455,47 @@ NS_IMPL_ISUPPORTS_INHERITED2(nsHTMLTableAccessible, nsAccessible,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsHTMLTableAccessible: nsAccessible implementation // nsHTMLTableAccessible: nsAccessible implementation
void void nsHTMLTableAccessible::CacheChildren()
nsHTMLTableAccessible::CacheChildren()
{ {
nsAccessible::CacheChildren(); if (!mWeakShell) {
// This node has been shut down
mAccChildCount = eChildCountUninitialized;
return;
}
if (mAccChildCount == eChildCountUninitialized) {
nsAccessible::CacheChildren();
nsCOMPtr<nsIAccessible> captionAccessible;
while (NextChild(captionAccessible)) {
if (nsAccUtils::Role(captionAccessible) == nsIAccessibleRole::ROLE_CAPTION) {
nsCOMPtr<nsIAccessible> captionParentAccessible;
captionAccessible->GetParent(getter_AddRefs(captionParentAccessible));
if (captionParentAccessible != this) {
NS_WARNING("Should not happen: parser ensures caption is the table's child, not the tbody's");
return;
}
nsCOMPtr<nsIAccessible> beforeCaptionAccessible;
captionAccessible->GetPreviousSibling(getter_AddRefs(beforeCaptionAccessible));
if (beforeCaptionAccessible) {
// Move caption accessible so that it's the first child
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryAccessible(beforeCaptionAccessible);
// Move caption accessible so that it's the first child. nsCOMPtr<nsIAccessible> afterCaptionAccessible;
PRInt32 length = mChildren.Count(); captionAccessible->GetNextSibling(getter_AddRefs(afterCaptionAccessible));
for (PRInt32 idx = 0; idx < length; idx++) { acc->SetNextSibling(afterCaptionAccessible);
// Check for the first caption, because nsAccessibilityService ensures we
// don't create accessibles for the other captions, since only the first is
// actually visible.
nsIAccessible* child = mChildren.ObjectAt(idx); GetFirstChild(getter_AddRefs(afterCaptionAccessible));
if (nsAccUtils::Role(child) == nsIAccessibleRole::ROLE_CAPTION) { SetFirstChild(captionAccessible);
if (idx == 0)
acc = nsAccUtils::QueryAccessible(captionAccessible);
acc->SetNextSibling(afterCaptionAccessible);
}
// Don't check for more captions, because nsAccessibilityService ensures
// we don't create accessibles for the other captions, since only the
// first is actually visible
break; break;
}
nsCOMPtr<nsIAccessible> tmp = mChildren.ObjectAt(0);
mChildren.ReplaceObjectAt(child, 0);
mChildren.ReplaceObjectAt(tmp, idx);
break;
} }
} }
} }

Просмотреть файл

@ -263,19 +263,20 @@ NS_IMETHODIMP nsHTMLLIAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *wid
return NS_OK; return NS_OK;
} }
//////////////////////////////////////////////////////////////////////////////// void nsHTMLLIAccessible::CacheChildren()
// nsHTMLLIAccessible: nsAccessible protected
void
nsHTMLLIAccessible::CacheChildren()
{ {
if (mBulletAccessible) { if (!mWeakShell || mAccChildCount != eChildCountUninitialized) {
mChildren.AppendObject(mBulletAccessible); return;
mBulletAccessible->SetParent(this);
} }
// Cache children from subtree.
nsAccessibleWrap::CacheChildren(); nsAccessibleWrap::CacheChildren();
if (mBulletAccessible) {
mBulletAccessible->SetNextSibling(mFirstChild);
mBulletAccessible->SetParent(this);
SetFirstChild(mBulletAccessible);
++ mAccChildCount;
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -331,6 +332,15 @@ nsHTMLListBulletAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraS
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsHTMLListBulletAccessible::GetParent(nsIAccessible **aParent)
{
NS_ENSURE_ARG_POINTER(aParent);
NS_IF_ADDREF(*aParent = mParent);
return NS_OK;
}
nsresult nsresult
nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
PRUint32 aLength) PRUint32 aLength)
@ -343,12 +353,6 @@ nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset
return NS_OK; return NS_OK;
} }
nsIAccessible*
nsHTMLListBulletAccessible::GetParent()
{
return mParent;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsHTMLListAccessible // nsHTMLListAccessible
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -106,6 +106,7 @@ public:
// nsIAccessible // nsIAccessible
NS_IMETHOD GetName(nsAString& aName); NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetParent(nsIAccessible **aParent);
// nsAccessNode // nsAccessNode
virtual nsresult Shutdown(); virtual nsresult Shutdown();
@ -116,8 +117,6 @@ public:
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset, virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
PRUint32 aLength); PRUint32 aLength);
virtual nsIAccessible* GetParent();
protected: protected:
// XXX: Ideally we'd get the bullet text directly from the bullet frame via // XXX: Ideally we'd get the bullet text directly from the bullet frame via
// nsBulletFrame::GetListItemText(), but we'd need an interface for getting // nsBulletFrame::GetListItemText(), but we'd need an interface for getting
@ -162,10 +161,8 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
protected: protected:
// nsAccessible void CacheChildren(); // Include bullet accessible
virtual void CacheChildren();
private:
nsRefPtr<nsHTMLListBulletAccessible> mBulletAccessible; nsRefPtr<nsHTMLListBulletAccessible> mBulletAccessible;
}; };

Просмотреть файл

@ -201,44 +201,49 @@ nsHyperTextAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
return NS_OK; return NS_OK;
} }
void void nsHyperTextAccessible::CacheChildren()
nsHyperTextAccessible::CacheChildren()
{ {
PRUint32 role; if (!mWeakShell) {
GetRoleInternal(&role); // This node has been shut down
if (role != nsIAccessibleRole::ROLE_ENTRY && mAccChildCount = eChildCountUninitialized;
role != nsIAccessibleRole::ROLE_PASSWORD_TEXT) {
nsAccessible::CacheChildren();
return; return;
} }
nsCOMPtr<nsIEditor> editor; // Special case for text entry fields, go directly to editor's root for children
GetAssociatedEditor(getter_AddRefs(editor)); if (mAccChildCount == eChildCountUninitialized) {
if (!editor) { PRUint32 role;
nsAccessible::CacheChildren(); GetRoleInternal(&role);
return; if (role != nsIAccessibleRole::ROLE_ENTRY && role != nsIAccessibleRole::ROLE_PASSWORD_TEXT) {
} nsAccessible::CacheChildren();
return;
}
nsCOMPtr<nsIEditor> editor;
GetAssociatedEditor(getter_AddRefs(editor));
if (!editor) {
nsAccessible::CacheChildren();
return;
}
mAccChildCount = 0; // Avoid reentry
nsCOMPtr<nsIDOMElement> editorRoot;
editor->GetRootElement(getter_AddRefs(editorRoot));
nsCOMPtr<nsIDOMNode> editorRootDOMNode = do_QueryInterface(editorRoot);
if (!editorRootDOMNode) {
return;
}
nsAccessibleTreeWalker walker(mWeakShell, editorRootDOMNode, PR_TRUE);
nsRefPtr<nsAccessible> prevAcc;
PRInt32 childCount = 0;
walker.GetFirstChild();
SetFirstChild(walker.mState.accessible);
// Special case for text entry fields, go directly to editor's root for while (walker.mState.accessible) {
// children. ++ childCount;
prevAcc = nsAccUtils::QueryAccessible(walker.mState.accessible);
nsCOMPtr<nsIDOMElement> editorRoot; prevAcc->SetParent(this);
editor->GetRootElement(getter_AddRefs(editorRoot)); walker.GetNextSibling();
nsCOMPtr<nsIDOMNode> editorRootDOMNode = do_QueryInterface(editorRoot); prevAcc->SetNextSibling(walker.mState.accessible);
if (!editorRootDOMNode) }
return; mAccChildCount = childCount;
nsAccessibleTreeWalker walker(mWeakShell, editorRootDOMNode, PR_TRUE);
walker.GetFirstChild();
while (walker.mState.accessible) {
mChildren.AppendObject(walker.mState.accessible);
nsRefPtr<nsAccessible> acc =
nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
acc->SetParent(this);
walker.GetNextSibling();
} }
} }
@ -861,11 +866,10 @@ nsHyperTextAccessible::GetRelativeOffset(nsIPresShell *aPresShell,
hyperTextOffset = 0; hyperTextOffset = 0;
} }
else if (aAmount == eSelectBeginLine) { else if (aAmount == eSelectBeginLine) {
nsIAccessible *firstChild = mChildren.SafeObjectAt(0);
// For line selection with needsStart, set start of line exactly to line break // For line selection with needsStart, set start of line exactly to line break
if (pos.mContentOffset == 0 && firstChild && if (pos.mContentOffset == 0 && mFirstChild &&
nsAccUtils::Role(firstChild) == nsIAccessibleRole::ROLE_STATICTEXT && nsAccUtils::Role(mFirstChild) == nsIAccessibleRole::ROLE_STATICTEXT &&
nsAccUtils::TextLength(firstChild) == hyperTextOffset) { nsAccUtils::TextLength(mFirstChild) == hyperTextOffset) {
// XXX Bullet hack -- we should remove this once list bullets use anonymous content // XXX Bullet hack -- we should remove this once list bullets use anonymous content
hyperTextOffset = 0; hyperTextOffset = 0;
} }

Просмотреть файл

@ -86,6 +86,7 @@ public:
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes); virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
void CacheChildren();
// Convert content offset to rendered text offset // Convert content offset to rendered text offset
static nsresult ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset, static nsresult ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
@ -154,12 +155,6 @@ public:
PRInt32 *aEndOffset); PRInt32 *aEndOffset);
protected: protected:
// nsAccessible
virtual void CacheChildren();
// nsHyperTextAccessible
/* /*
* This does the work for nsIAccessibleText::GetText[At|Before|After]Offset * This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
* @param aType, eGetBefore, eGetAt, eGetAfter * @param aType, eGetBefore, eGetAt, eGetAfter

Просмотреть файл

@ -1105,23 +1105,28 @@ __try {
if (mEnumVARIANTPosition == kIEnumVariantDisconnected) if (mEnumVARIANTPosition == kIEnumVariantDisconnected)
return CO_E_OBJNOTCONNECTED; return CO_E_OBJNOTCONNECTED;
PRUint32 numElementsFetched = 0; nsCOMPtr<nsIAccessible> traversedAcc;
for (; numElementsFetched < aNumElementsRequested; nsresult rv = GetChildAt(mEnumVARIANTPosition, getter_AddRefs(traversedAcc));
numElementsFetched++, mEnumVARIANTPosition++) { if (!traversedAcc)
return S_FALSE;
nsIAccessible* accessible = GetChildAt(mEnumVARIANTPosition); for (PRUint32 i = 0; i < aNumElementsRequested; i++) {
if (!accessible) VariantInit(&aPVar[i]);
aPVar[i].pdispVal = NativeAccessible(traversedAcc);
aPVar[i].vt = VT_DISPATCH;
(*aNumElementsFetched)++;
nsCOMPtr<nsIAccessible> nextAcc;
traversedAcc->GetNextSibling(getter_AddRefs(nextAcc));
if (!nextAcc)
break; break;
VariantInit(&aPVar[numElementsFetched]); traversedAcc = nextAcc;
aPVar[numElementsFetched].pdispVal = NativeAccessible(accessible);
aPVar[numElementsFetched].vt = VT_DISPATCH;
} }
(*aNumElementsFetched) = numElementsFetched; mEnumVARIANTPosition += *aNumElementsFetched;
return (*aNumElementsFetched) < aNumElementsRequested ? S_FALSE : S_OK;
return numElementsFetched < aNumElementsRequested ? S_FALSE : S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { } } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL; return E_FAIL;

Просмотреть файл

@ -49,9 +49,6 @@ nsHTMLWin32ObjectOwnerAccessible::
nsAccessibleWrap(aNode, aShell) nsAccessibleWrap(aNode, aShell)
{ {
mHwnd = aHwnd; mHwnd = aHwnd;
// Our only child is a nsHTMLWin32ObjectAccessible object.
mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -65,6 +62,50 @@ nsHTMLWin32ObjectOwnerAccessible::Shutdown()
return NS_OK; return NS_OK;
} }
////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectOwnerAccessible: nsIAccessible implementation
NS_IMETHODIMP
nsHTMLWin32ObjectOwnerAccessible::GetFirstChild(nsIAccessible **aFirstChild)
{
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
// Our only child is a nsHTMLWin32ObjectAccessible object.
if (!mNativeAccessible) {
if (!mHwnd)
return NS_OK;
mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd);
NS_ENSURE_TRUE(mNativeAccessible, NS_ERROR_OUT_OF_MEMORY);
SetFirstChild(mNativeAccessible);
}
*aFirstChild = mNativeAccessible;
NS_IF_ADDREF(*aFirstChild);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLWin32ObjectOwnerAccessible::GetLastChild(nsIAccessible **aLastChild)
{
return GetFirstChild(aLastChild);
}
NS_IMETHODIMP
nsHTMLWin32ObjectOwnerAccessible::GetChildCount(PRInt32 *aChildCount)
{
NS_ENSURE_ARG_POINTER(aChildCount);
nsCOMPtr<nsIAccessible> onlyChild;
GetFirstChild(getter_AddRefs(onlyChild));
*aChildCount = onlyChild ? 1 : 0;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectOwnerAccessible: nsAccessible implementation // nsHTMLWin32ObjectOwnerAccessible: nsAccessible implementation
@ -93,21 +134,6 @@ nsHTMLWin32ObjectOwnerAccessible::GetStateInternal(PRUint32 *aState,
return rv; return rv;
} }
////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectOwnerAccessible: nsAccessible protected implementation
void
nsHTMLWin32ObjectOwnerAccessible::CacheChildren()
{
if (mNativeAccessible) {
mChildren.AppendObject(mNativeAccessible);
nsRefPtr<nsAccessible> nativeAcc =
nsAccUtils::QueryObject<nsAccessible>(mNativeAccessible);
nativeAcc->SetParent(this);
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsHTMLWin32ObjectAccessible // nsHTMLWin32ObjectAccessible

Просмотреть файл

@ -56,6 +56,11 @@ public:
nsHTMLWin32ObjectOwnerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, void* aHwnd); nsHTMLWin32ObjectOwnerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, void* aHwnd);
virtual ~nsHTMLWin32ObjectOwnerAccessible() {} virtual ~nsHTMLWin32ObjectOwnerAccessible() {}
// nsIAccessible
NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
NS_IMETHOD GetChildCount(PRInt32 *aChildCount); // Zero or one child
// nsAccessNode // nsAccessNode
virtual nsresult Shutdown(); virtual nsresult Shutdown();
@ -64,10 +69,6 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
protected: protected:
// nsAccessible
virtual void CacheChildren();
void* mHwnd; void* mHwnd;
nsCOMPtr<nsIAccessible> mNativeAccessible; nsCOMPtr<nsIAccessible> mNativeAccessible;
}; };

Просмотреть файл

@ -105,6 +105,16 @@ nsXFormsAccessible::GetBoundChildElementValue(const nsAString& aTagName,
void void
nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode) nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
{ {
if (!mWeakShell) {
// This node has been shut down
mAccChildCount = eChildCountUninitialized;
return;
}
if (mAccChildCount != eChildCountUninitialized)
return;
mAccChildCount = 0; // Avoid reentry
nsIAccessibilityService *accService = GetAccService(); nsIAccessibilityService *accService = GetAccService();
if (!accService) if (!accService)
return; return;
@ -123,7 +133,7 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
children->GetLength(&length); children->GetLength(&length);
nsCOMPtr<nsIAccessible> accessible; nsCOMPtr<nsIAccessible> accessible;
nsRefPtr<nsAccessible> acc; nsRefPtr<nsAccessible> currAccessible, prevAccessible;
PRUint32 childLength = 0; PRUint32 childLength = 0;
for (PRUint32 index = 0; index < length; index++) { for (PRUint32 index = 0; index < length; index++) {
@ -133,13 +143,22 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
continue; continue;
accService->GetAttachedAccessibleFor(child, getter_AddRefs(accessible)); accService->GetAttachedAccessibleFor(child, getter_AddRefs(accessible));
if (!accessible) currAccessible = nsAccUtils::QueryAccessible(accessible);
if (!currAccessible)
continue; continue;
mChildren.AppendObject(accessible); if (childLength == 0)
acc = nsAccUtils::QueryObject<nsAccessible>(accessible); SetFirstChild(accessible);
acc->SetParent(this);
currAccessible->SetParent(this);
if (prevAccessible) {
prevAccessible->SetNextSibling(accessible);
}
currAccessible.swap(prevAccessible);
childLength++;
} }
mAccChildCount = childLength;
} }
// nsIAccessible // nsIAccessible

Просмотреть файл

@ -211,10 +211,7 @@ public:
// nsAccessible // nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
void CacheChildren();
protected:
// nsAccessible
virtual void CacheChildren();
}; };
@ -230,10 +227,7 @@ public:
// nsAccessible // nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
void CacheChildren();
protected:
// nsAccessible
virtual void CacheChildren();
}; };

Просмотреть файл

@ -98,8 +98,7 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
protected: protected:
// nsAccessible void CacheChildren();
virtual void CacheChildren();
}; };
#endif #endif

Просмотреть файл

@ -166,6 +166,16 @@ nsXULColorPickerAccessible::GetRoleInternal(PRUint32 *aRole)
void void
nsXULColorPickerAccessible::CacheChildren() nsXULColorPickerAccessible::CacheChildren()
{ {
if (IsDefunct()) {
mAccChildCount = eChildCountUninitialized;
return; // This outer doc node has been shut down
}
if (mAccChildCount != eChildCountUninitialized)
return;
mAccChildCount = 0; // Avoid reentry
nsCOMPtr<nsIAccessible> menupopupAccessible; nsCOMPtr<nsIAccessible> menupopupAccessible;
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE); nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
walker.GetFirstChild(); walker.GetFirstChild();
@ -173,17 +183,23 @@ nsXULColorPickerAccessible::CacheChildren()
while (walker.mState.accessible) { while (walker.mState.accessible) {
PRUint32 role = nsAccUtils::Role(walker.mState.accessible); PRUint32 role = nsAccUtils::Role(walker.mState.accessible);
// Get an accessbile for menupopup or panel elements.
if (role == nsIAccessibleRole::ROLE_ALERT) { if (role == nsIAccessibleRole::ROLE_ALERT) {
mChildren.AppendObject(walker.mState.accessible); // Get an accessbile for menupopup or panel elements.
menupopupAccessible = walker.mState.accessible;
nsRefPtr<nsAccessible> menupopupAcc = break;
nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
menupopupAcc->SetParent(this);
return;
} }
walker.GetNextSibling(); walker.GetNextSibling();
} }
if (!menupopupAccessible)
return;
SetFirstChild(menupopupAccessible);
nsRefPtr<nsAccessible> menupopupAcc =
nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
menupopupAcc->SetParent(this);
mAccChildCount++;
} }

Просмотреть файл

@ -186,61 +186,78 @@ nsXULButtonAccessible::CacheChildren()
// buttons can have button (@type="menu-button") and popup accessibles // buttons can have button (@type="menu-button") and popup accessibles
// (@type="menu-button" or @type="menu"). // (@type="menu-button" or @type="menu").
// XXX: no children until the button is menu button. Probably it's not if (!mWeakShell) {
// totally correct but in general AT wants to have leaf buttons. mAccChildCount = eChildCountUninitialized;
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode)); return; // This outer doc node has been shut down
}
if (mAccChildCount == eChildCountUninitialized) {
mAccChildCount = 0; // Avoid reentry
PRBool isMenu = content->AttrValueIs(kNameSpaceID_None, SetFirstChild(nsnull);
nsAccessibilityAtoms::type,
nsAccessibilityAtoms::menu,
eCaseMatters);
PRBool isMenuButton = isMenu ? // XXX: no children until the button is menu button. Probably it's not
PR_FALSE : // totally correct but in general AT wants to have leaf buttons.
content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type, nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
nsAccessibilityAtoms::menuButton, eCaseMatters);
if (!isMenu && !isMenuButton) PRBool isMenu = content->AttrValueIs(kNameSpaceID_None,
return; nsAccessibilityAtoms::type,
nsAccessibilityAtoms::menu,
eCaseMatters);
nsCOMPtr<nsIAccessible> buttonAccessible; PRBool isMenuButton = isMenu ?
nsCOMPtr<nsIAccessible> menupopupAccessible; PR_FALSE :
content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
nsAccessibilityAtoms::menuButton, eCaseMatters);
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE); if (!isMenu && !isMenuButton)
walker.GetFirstChild(); return;
while (walker.mState.accessible) { nsCOMPtr<nsIAccessible> buttonAccessible;
PRUint32 role = nsAccUtils::Role(walker.mState.accessible); nsCOMPtr<nsIAccessible> menupopupAccessible;
if (role == nsIAccessibleRole::ROLE_MENUPOPUP) { nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
// Get an accessbile for menupopup or panel elements. walker.GetFirstChild();
menupopupAccessible = walker.mState.accessible;
} else if (isMenuButton && role == nsIAccessibleRole::ROLE_PUSHBUTTON) { while (walker.mState.accessible) {
// Button type="menu-button" contains a real button. Get an accessible PRUint32 role = nsAccUtils::Role(walker.mState.accessible);
// for it. Ignore dropmarker button what is placed as a last child.
buttonAccessible = walker.mState.accessible; if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
break; // Get an accessbile for menupopup or panel elements.
menupopupAccessible = walker.mState.accessible;
} else if (isMenuButton && role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
// Button type="menu-button" contains a real button. Get an accessible
// for it. Ignore dropmarker button what is placed as a last child.
buttonAccessible = walker.mState.accessible;
break;
}
walker.GetNextSibling();
} }
walker.GetNextSibling(); if (!menupopupAccessible)
} return;
if (!menupopupAccessible) SetFirstChild(menupopupAccessible);
return;
mChildren.AppendObject(menupopupAccessible); nsRefPtr<nsAccessible> menupopupAcc =
nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
menupopupAcc->SetParent(this);
nsRefPtr<nsAccessible> menupopupAcc = mAccChildCount++;
nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
menupopupAcc->SetParent(this);
if (buttonAccessible) { if (buttonAccessible) {
mChildren.AppendObject(buttonAccessible); if (menupopupAcc)
menupopupAcc->SetNextSibling(buttonAccessible);
else
SetFirstChild(buttonAccessible);
nsRefPtr<nsAccessible> buttonAcc = nsRefPtr<nsAccessible> buttonAcc =
nsAccUtils::QueryObject<nsAccessible>(buttonAccessible); nsAccUtils::QueryObject<nsAccessible>(buttonAccessible);
buttonAcc->SetParent(this); buttonAcc->SetParent(this);
mAccChildCount++;
}
} }
} }

Просмотреть файл

@ -76,7 +76,7 @@ public:
protected: protected:
// nsAccessible // nsAccessible
virtual void CacheChildren(); void CacheChildren();
// nsXULButtonAccessible // nsXULButtonAccessible
PRBool ContainsMenu(); PRBool ContainsMenu();

Просмотреть файл

@ -236,6 +236,15 @@ nsXULTabBoxAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK; return NS_OK;
} }
#ifdef NEVER
/** 2 children, tabs, tabpanels */
NS_IMETHODIMP nsXULTabBoxAccessible::GetChildCount(PRInt32 *_retval)
{
*_retval = 2;
return NS_OK;
}
#endif
/** /**
* XUL Tabs - the s really stands for strip. this is a collection of tab objects * XUL Tabs - the s really stands for strip. this is a collection of tab objects
*/ */

Просмотреть файл

@ -220,6 +220,83 @@ nsXULTreeAccessible::GetRoleInternal(PRUint32 *aRole)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeAccessible: nsIAccessible implementation // nsXULTreeAccessible: nsIAccessible implementation
NS_IMETHODIMP
nsXULTreeAccessible::GetFirstChild(nsIAccessible **aFirstChild)
{
nsAccessible::GetFirstChild(aFirstChild);
// in normal case, tree's first child should be treecols, if it is not here,
// use the first row as tree's first child
if (*aFirstChild == nsnull) {
if (IsDefunct())
return NS_ERROR_FAILURE;
PRInt32 rowCount;
mTreeView->GetRowCount(&rowCount);
if (rowCount > 0)
GetTreeItemAccessible(0, aFirstChild);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeAccessible::GetLastChild(nsIAccessible **aLastChild)
{
NS_ENSURE_ARG_POINTER(aLastChild);
*aLastChild = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
PRInt32 rowCount = 0;
mTreeView->GetRowCount(&rowCount);
if (rowCount > 0) {
GetTreeItemAccessible(rowCount - 1, aLastChild);
if (*aLastChild)
return NS_OK;
}
// If there is not any rows, use treecols as tree's last child.
return nsAccessible::GetLastChild(aLastChild);
}
NS_IMETHODIMP
nsXULTreeAccessible::GetChildCount(PRInt32 *aChildCount)
{
// tree's children count is row count + treecols count.
if (IsDefunct())
return NS_ERROR_FAILURE;
nsAccessible::GetChildCount(aChildCount);
if (*aChildCount != eChildCountUninitialized) {
PRInt32 rowCount = 0;
mTreeView->GetRowCount(&rowCount);
*aChildCount += rowCount;
}
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeAccessible::GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild)
{
NS_ENSURE_ARG_POINTER(aChild);
*aChild = nsnull;
PRInt32 childCount = 0;
nsresult rv = nsAccessible::GetChildCount(&childCount);
NS_ENSURE_SUCCESS(rv, rv);
if (aChildIndex < childCount)
return nsAccessible::GetChildAt(aChildIndex, aChild);
GetTreeItemAccessible(aChildIndex - childCount, aChild);
return *aChild ? NS_OK : NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXULTreeAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) nsXULTreeAccessible::GetFocusedChild(nsIAccessible **aFocusedChild)
{ {
@ -458,56 +535,6 @@ nsXULTreeAccessible::SelectAllSelection(PRBool *aIsMultiSelectable)
return NS_OK; return NS_OK;
} }
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeAccessible: nsAccessible implementation
nsIAccessible*
nsXULTreeAccessible::GetChildAt(PRUint32 aIndex)
{
PRInt32 childCount = nsAccessible::GetChildCount();
if (childCount == -1)
return nsnull;
if (static_cast<PRInt32>(aIndex) < childCount)
return nsAccessible::GetChildAt(aIndex);
nsCOMPtr<nsIAccessible> child;
GetTreeItemAccessible(aIndex - childCount, getter_AddRefs(child));
return child;
}
PRInt32
nsXULTreeAccessible::GetChildCount()
{
// tree's children count is row count + treecols count.
PRInt32 childCount = nsAccessible::GetChildCount();
if (childCount == -1)
return -1;
PRInt32 rowCount = 0;
mTreeView->GetRowCount(&rowCount);
childCount += rowCount;
return childCount;
}
PRInt32
nsXULTreeAccessible::GetIndexOf(nsIAccessible *aChild)
{
if (IsDefunct())
return -1;
nsRefPtr<nsXULTreeItemAccessibleBase> item =
nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(aChild);
// If the given child is not treeitem then it should be treecols accessible.
if (!item)
return nsAccessible::GetIndexOf(aChild);
return nsAccessible::GetChildCount() + item->GetRowIndex();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeAccessible: public implementation // nsXULTreeAccessible: public implementation
@ -747,6 +774,67 @@ nsXULTreeItemAccessibleBase::GetUniqueID(void **aUniqueID)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeItemAccessibleBase: nsIAccessible implementation // nsXULTreeItemAccessibleBase: nsIAccessible implementation
NS_IMETHODIMP
nsXULTreeItemAccessibleBase::GetParent(nsIAccessible **aParent)
{
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
if (mParent) {
*aParent = mParent;
NS_ADDREF(*aParent);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeItemAccessibleBase::GetNextSibling(nsIAccessible **aNextSibling)
{
NS_ENSURE_ARG_POINTER(aNextSibling);
*aNextSibling = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsRefPtr<nsXULTreeAccessible> treeAcc =
nsAccUtils::QueryAccessibleTree(mParent);
NS_ENSURE_STATE(treeAcc);
PRInt32 rowCount = 0;
mTreeView->GetRowCount(&rowCount);
if (mRow + 1 >= rowCount)
return NS_OK;
treeAcc->GetTreeItemAccessible(mRow + 1, aNextSibling);
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeItemAccessibleBase::GetPreviousSibling(nsIAccessible **aPreviousSibling)
{
NS_ENSURE_ARG_POINTER(aPreviousSibling);
*aPreviousSibling = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsRefPtr<nsXULTreeAccessible> treeAcc =
nsAccUtils::QueryAccessibleTree(mParent);
NS_ENSURE_STATE(treeAcc);
// Get previous row accessible or tree columns accessible.
if (mRow > 0)
treeAcc->GetTreeItemAccessible(mRow - 1, aPreviousSibling);
else
treeAcc->GetFirstChild(aPreviousSibling);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXULTreeItemAccessibleBase::GetFocusedChild(nsIAccessible **aFocusedChild) nsXULTreeItemAccessibleBase::GetFocusedChild(nsIAccessible **aFocusedChild)
{ {
@ -960,7 +1048,7 @@ nsXULTreeItemAccessibleBase::Shutdown()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeItemAccessibleBase: nsAccessible public methods // nsXULTreeItemAccessibleBase: nsAccessible implementation
nsresult nsresult
nsXULTreeItemAccessibleBase::GetAttributesInternal(nsIPersistentProperties *aAttributes) nsXULTreeItemAccessibleBase::GetAttributesInternal(nsIPersistentProperties *aAttributes)
@ -1070,14 +1158,8 @@ nsXULTreeItemAccessibleBase::GetStateInternal(PRUint32 *aState,
return NS_OK; return NS_OK;
} }
nsIAccessible*
nsXULTreeItemAccessibleBase::GetParent()
{
return IsDefunct() ? nsnull : mParent;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeItemAccessibleBase: nsAccessible protected methods // nsXULTreeItemAccessibleBase: protected implementation
void void
nsXULTreeItemAccessibleBase::DispatchClickEvent(nsIContent *aContent, nsXULTreeItemAccessibleBase::DispatchClickEvent(nsIContent *aContent,
@ -1108,41 +1190,6 @@ nsXULTreeItemAccessibleBase::DispatchClickEvent(nsIContent *aContent,
nsCoreUtils::DispatchClickEvent(mTree, mRow, column, pseudoElm); nsCoreUtils::DispatchClickEvent(mTree, mRow, column, pseudoElm);
} }
nsIAccessible*
nsXULTreeItemAccessibleBase::GetSiblingAtOffset(PRInt32 aOffset,
nsresult* aError)
{
if (mRow + aOffset < 0)
return nsAccessible::GetSiblingAtOffset(mRow + aOffset, aError);
if (IsDefunct()) {
if (aError)
*aError = NS_ERROR_FAILURE;
return nsnull;
}
if (aError)
*aError = NS_OK; // fail peacefully
nsRefPtr<nsXULTreeAccessible> treeAcc =
nsAccUtils::QueryAccessibleTree(mParent);
if (!treeAcc)
return nsnull;
PRInt32 rowCount = 0;
mTreeView->GetRowCount(&rowCount);
if (mRow + aOffset >= rowCount)
return nsnull;
nsCOMPtr<nsIAccessible> sibling;
treeAcc->GetTreeItemAccessible(mRow + aOffset, getter_AddRefs(sibling));
return sibling;
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeItemAccessibleBase: protected implementation
PRBool PRBool
nsXULTreeItemAccessibleBase::IsExpandable() nsXULTreeItemAccessibleBase::IsExpandable()
{ {
@ -1183,6 +1230,33 @@ nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeItemAccessible: nsIAccessible implementation // nsXULTreeItemAccessible: nsIAccessible implementation
NS_IMETHODIMP
nsXULTreeItemAccessible::GetFirstChild(nsIAccessible **aFirstChild)
{
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeItemAccessible::GetLastChild(nsIAccessible **aLastChild)
{
NS_ENSURE_ARG_POINTER(aLastChild);
*aLastChild = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeItemAccessible::GetChildCount(PRInt32 *aChildCount)
{
NS_ENSURE_ARG_POINTER(aChildCount);
*aChildCount = 0;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXULTreeItemAccessible::GetName(nsAString& aName) nsXULTreeItemAccessible::GetName(nsAString& aName)
{ {
@ -1264,14 +1338,6 @@ nsXULTreeItemAccessible::RowInvalidated(PRInt32 aStartColIdx,
} }
} }
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeItemAccessible: nsAccessible protected implementation
void
nsXULTreeItemAccessible::CacheChildren()
{
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeColumnsAccessible // nsXULTreeColumnsAccessible
@ -1283,22 +1349,11 @@ nsXULTreeColumnsAccessible::
{ {
} }
nsIAccessible* NS_IMETHODIMP
nsXULTreeColumnsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsXULTreeColumnsAccessible::GetNextSibling(nsIAccessible **aNextSibling)
nsresult* aError)
{ {
if (aOffset < 0) NS_ENSURE_ARG_POINTER(aNextSibling);
return nsXULColumnsAccessible::GetSiblingAtOffset(aOffset, aError); *aNextSibling = nsnull;
if (IsDefunct()) {
if (aError)
*aError = NS_ERROR_FAILURE;
return nsnull;
}
if (aError)
*aError = NS_OK; // fail peacefully
nsCOMPtr<nsITreeBoxObject> tree; nsCOMPtr<nsITreeBoxObject> tree;
nsCOMPtr<nsITreeView> treeView; nsCOMPtr<nsITreeView> treeView;
@ -1309,19 +1364,16 @@ nsXULTreeColumnsAccessible::GetSiblingAtOffset(PRInt32 aOffset,
if (treeView) { if (treeView) {
PRInt32 rowCount = 0; PRInt32 rowCount = 0;
treeView->GetRowCount(&rowCount); treeView->GetRowCount(&rowCount);
if (rowCount > 0 && aOffset <= rowCount) { if (rowCount > 0) {
nsRefPtr<nsXULTreeAccessible> treeAcc = nsRefPtr<nsXULTreeAccessible> treeAcc =
nsAccUtils::QueryAccessibleTree(mParent); nsAccUtils::QueryAccessibleTree(mParent);
NS_ENSURE_STATE(treeAcc);
if (treeAcc) { treeAcc->GetTreeItemAccessible(0, aNextSibling);
nsCOMPtr<nsIAccessible> sibling;
treeAcc->GetTreeItemAccessible(aOffset - 1, getter_AddRefs(sibling));
return sibling;
}
} }
} }
} }
return nsnull; return NS_OK;
} }

Просмотреть файл

@ -73,6 +73,12 @@ public:
// nsIAccessible // nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue); NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
NS_IMETHOD GetChildCount(PRInt32 *aChildCount);
NS_IMETHOD GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild); NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
// nsIAccessibleSelectable // nsIAccessibleSelectable
@ -89,10 +95,6 @@ public:
PRBool aDeepestChild, PRBool aDeepestChild,
nsIAccessible **aChild); nsIAccessible **aChild);
virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
virtual PRInt32 GetChildCount();
virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
// nsXULTreeAccessible // nsXULTreeAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID)
@ -176,6 +178,10 @@ public:
NS_IMETHOD GetUniqueID(void **aUniqueID); NS_IMETHOD GetUniqueID(void **aUniqueID);
// nsIAccessible // nsIAccessible
NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild); NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY, NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
@ -198,16 +204,10 @@ public:
// nsAccessible // nsAccessible
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes); virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
// nsXULTreeItemAccessibleBase // nsXULTreeItemAccessibleBase
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)
/**
* Return row index associated with the accessible.
*/
PRInt32 GetRowIndex() const { return mRow; }
/** /**
* Return cell accessible for the given column. If XUL tree accessible is not * Return cell accessible for the given column. If XUL tree accessible is not
* accessible table then return null. * accessible table then return null.
@ -226,8 +226,6 @@ protected:
// nsAccessible // nsAccessible
virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex); virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
nsresult* aError = nsnull);
// nsXULTreeItemAccessibleBase // nsXULTreeItemAccessibleBase
@ -255,6 +253,11 @@ public:
nsIAccessible *aParent, nsITreeBoxObject *aTree, nsIAccessible *aParent, nsITreeBoxObject *aTree,
nsITreeView *aTreeView, PRInt32 aRow); nsITreeView *aTreeView, PRInt32 aRow);
// nsIAccessible
NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
NS_IMETHOD GetChildCount(PRInt32 *aChildCount);
NS_IMETHOD GetName(nsAString& aName); NS_IMETHOD GetName(nsAString& aName);
// nsAccessNode // nsAccessNode
@ -269,11 +272,6 @@ public:
virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx); virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
protected: protected:
// nsAccessible
virtual void CacheChildren();
// nsXULTreeItemAccessible
nsCOMPtr<nsITreeColumn> mColumn; nsCOMPtr<nsITreeColumn> mColumn;
nsString mCachedName; nsString mCachedName;
}; };
@ -287,10 +285,8 @@ class nsXULTreeColumnsAccessible : public nsXULColumnsAccessible
public: public:
nsXULTreeColumnsAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); nsXULTreeColumnsAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
protected: // nsIAccessible
NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
// nsAccessible
nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError = nsnull);
}; };
#endif #endif

Просмотреть файл

@ -95,15 +95,15 @@ nsXULTreeGridAccessible::GetSummary(nsAString &aSummary)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsXULTreeGridAccessible::GetColumnCount(PRInt32 *aColumnCount) nsXULTreeGridAccessible::GetColumnCount(PRInt32 *acolumnCount)
{ {
NS_ENSURE_ARG_POINTER(aColumnCount); NS_ENSURE_ARG_POINTER(acolumnCount);
*aColumnCount = 0; *acolumnCount = 0;
if (IsDefunct()) if (IsDefunct())
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
*aColumnCount = nsCoreUtils::GetSensibleColumnCount(mTree); *acolumnCount = nsCoreUtils::GetSensiblecolumnCount(mTree);
return NS_OK; return NS_OK;
} }
@ -635,6 +635,77 @@ NS_IMPL_ADDREF_INHERITED(nsXULTreeGridRowAccessible,
NS_IMPL_RELEASE_INHERITED(nsXULTreeGridRowAccessible, NS_IMPL_RELEASE_INHERITED(nsXULTreeGridRowAccessible,
nsXULTreeItemAccessibleBase) nsXULTreeItemAccessibleBase)
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridRowAccessible: nsIAccessible implementation
NS_IMETHODIMP
nsXULTreeGridRowAccessible::GetFirstChild(nsIAccessible **aFirstChild)
{
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree);
NS_ASSERTION(column, "No column for table grid!");
if (!column)
return NS_ERROR_FAILURE;
GetCellAccessible(column, aFirstChild);
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridRowAccessible::GetLastChild(nsIAccessible **aLastChild)
{
NS_ENSURE_ARG_POINTER(aLastChild);
*aLastChild = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetLastSensibleColumn(mTree);
NS_ASSERTION(column, "No column for table grid!");
if (!column)
return NS_ERROR_FAILURE;
GetCellAccessible(column, aLastChild);
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridRowAccessible::GetChildCount(PRInt32 *aChildCount)
{
NS_ENSURE_ARG_POINTER(aChildCount);
*aChildCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
*aChildCount = nsCoreUtils::GetSensiblecolumnCount(mTree);
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridRowAccessible::GetChildAt(PRInt32 aChildIndex,
nsIAccessible **aChild)
{
NS_ENSURE_ARG_POINTER(aChild);
*aChild = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeColumn> column =
nsCoreUtils::GetSensibleColumnAt(mTree, aChildIndex);
if (!column)
return NS_ERROR_INVALID_ARG;
GetCellAccessible(column, aChild);
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridRowAccessible: nsAccessNode implementation // nsXULTreeGridRowAccessible: nsAccessNode implementation
@ -689,43 +760,6 @@ nsXULTreeGridRowAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
return NS_OK; return NS_OK;
} }
nsIAccessible*
nsXULTreeGridRowAccessible::GetChildAt(PRUint32 aIndex)
{
if (IsDefunct())
return nsnull;
nsCOMPtr<nsITreeColumn> column =
nsCoreUtils::GetSensibleColumnAt(mTree, aIndex);
if (!column)
return nsnull;
nsCOMPtr<nsIAccessible> cell;
GetCellAccessible(column, getter_AddRefs(cell));
return cell;
}
PRInt32
nsXULTreeGridRowAccessible::GetChildCount()
{
if (IsDefunct())
return -1;
return nsCoreUtils::GetSensibleColumnCount(mTree);
}
PRInt32
nsXULTreeGridRowAccessible::GetIndexOf(nsIAccessible *aChild)
{
if (IsDefunct())
return -1;
nsRefPtr<nsXULTreeGridCellAccessible> cell =
nsAccUtils::QueryObject<nsXULTreeGridCellAccessible>(aChild);
return cell ? cell->GetColumnIndex() : -1;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridRowAccessible: nsXULTreeItemAccessibleBase implementation // nsXULTreeGridRowAccessible: nsXULTreeItemAccessibleBase implementation
@ -784,13 +818,6 @@ nsXULTreeGridRowAccessible::RowInvalidated(PRInt32 aStartColIdx,
} }
} }
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridRowAccessible: nsAccessible protected implementation
void
nsXULTreeGridRowAccessible::CacheChildren()
{
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible // nsXULTreeGridCellAccessible
@ -830,6 +857,64 @@ nsXULTreeGridCellAccessible::GetUniqueID(void **aUniqueID)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: nsIAccessible implementation // nsXULTreeGridCellAccessible: nsIAccessible implementation
NS_IMETHODIMP
nsXULTreeGridCellAccessible::GetParent(nsIAccessible **aParent)
{
NS_ENSURE_ARG_POINTER(aParent);
*aParent = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
if (mParent) {
*aParent = mParent;
NS_ADDREF(*aParent);
}
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridCellAccessible::GetNextSibling(nsIAccessible **aNextSibling)
{
NS_ENSURE_ARG_POINTER(aNextSibling);
*aNextSibling = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeColumn> nextColumn =
nsCoreUtils::GetNextSensibleColumn(mColumn);
if (!nextColumn)
return NS_OK;
nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(mParent);
rowAcc->GetCellAccessible(nextColumn, aNextSibling);
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridCellAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling)
{
NS_ENSURE_ARG_POINTER(aPreviousSibling);
*aPreviousSibling = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeColumn> nextColumn =
nsCoreUtils::GetPreviousSensibleColumn(mColumn);
if (!nextColumn)
return NS_OK;
nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(mParent);
rowAcc->GetCellAccessible(nextColumn, aPreviousSibling);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXULTreeGridCellAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) nsXULTreeGridCellAccessible::GetFocusedChild(nsIAccessible **aFocusedChild)
{ {
@ -1134,7 +1219,7 @@ nsXULTreeGridCellAccessible::Init()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: nsAccessible public implementation // nsXULTreeGridCellAccessible: nsAccessible implementation
nsresult nsresult
nsXULTreeGridCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes) nsXULTreeGridCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
@ -1222,12 +1307,6 @@ nsXULTreeGridCellAccessible::GetStateInternal(PRUint32 *aStates,
return NS_OK; return NS_OK;
} }
nsIAccessible*
nsXULTreeGridCellAccessible::GetParent()
{
return IsDefunct() ? nsnull : mParent;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: public implementation // nsXULTreeGridCellAccessible: public implementation
@ -1273,46 +1352,7 @@ nsXULTreeGridCellAccessible::CellInvalidated()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: nsAccessible protected implementation // nsXULTreeGridCellAccessible: protected implementation
nsIAccessible*
nsXULTreeGridCellAccessible::GetSiblingAtOffset(PRInt32 aOffset,
nsresult* aError)
{
if (IsDefunct()) {
if (aError)
*aError = NS_ERROR_FAILURE;
return nsnull;
}
if (aError)
*aError = NS_OK; // fail peacefully
nsCOMPtr<nsITreeColumn> columnAtOffset(mColumn), column;
if (aOffset < 0) {
for (PRInt32 index = aOffset; index < 0 && columnAtOffset; index++) {
column = nsCoreUtils::GetPreviousSensibleColumn(columnAtOffset);
column.swap(columnAtOffset);
}
} else {
for (PRInt32 index = aOffset; index > 0 && columnAtOffset; index--) {
column = nsCoreUtils::GetNextSensibleColumn(columnAtOffset);
column.swap(columnAtOffset);
}
}
if (!columnAtOffset)
return nsnull;
nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(mParent);
nsCOMPtr<nsIAccessible> sibling;
rowAcc->GetCellAccessible(columnAtOffset, getter_AddRefs(sibling));
return sibling;
}
void void
nsXULTreeGridCellAccessible::DispatchClickEvent(nsIContent *aContent, nsXULTreeGridCellAccessible::DispatchClickEvent(nsIContent *aContent,
@ -1324,9 +1364,6 @@ nsXULTreeGridCellAccessible::DispatchClickEvent(nsIContent *aContent,
nsCoreUtils::DispatchClickEvent(mTree, mRow, mColumn); nsCoreUtils::DispatchClickEvent(mTree, mRow, mColumn);
} }
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: protected implementation
PRBool PRBool
nsXULTreeGridCellAccessible::IsEditable() const nsXULTreeGridCellAccessible::IsEditable() const
{ {

Просмотреть файл

@ -86,6 +86,12 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeGridRowAccessible, NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeGridRowAccessible,
nsAccessible) nsAccessible)
// nsIAccessible
NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
NS_IMETHOD GetChildCount(PRInt32 *aChildCount);
NS_IMETHOD GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild);
// nsAccessNode // nsAccessNode
virtual nsresult Shutdown(); virtual nsresult Shutdown();
@ -95,20 +101,11 @@ public:
PRBool aDeepestChild, PRBool aDeepestChild,
nsIAccessible **aChild); nsIAccessible **aChild);
virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
virtual PRInt32 GetChildCount();
virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
// nsXULTreeItemAccessibleBase // nsXULTreeItemAccessibleBase
virtual void GetCellAccessible(nsITreeColumn *aColumn, nsIAccessible **aCell); virtual void GetCellAccessible(nsITreeColumn *aColumn, nsIAccessible **aCell);
virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx); virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
protected: protected:
// nsAccessible
virtual void CacheChildren();
// nsXULTreeItemAccessibleBase
nsAccessNodeHashtable mAccessNodeCache; nsAccessNodeHashtable mAccessNodeCache;
}; };
@ -142,6 +139,10 @@ public:
NS_IMETHOD GetUniqueID(void **aUniqueID); NS_IMETHOD GetUniqueID(void **aUniqueID);
// nsIAccessible // nsIAccessible
NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPrevSibling);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild); NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
NS_IMETHOD GetName(nsAString& aName); NS_IMETHOD GetName(nsAString& aName);
@ -164,8 +165,6 @@ public:
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsIAccessible* GetParent();
// nsXULTreeGridCellAccessible // nsXULTreeGridCellAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
@ -182,8 +181,6 @@ public:
protected: protected:
// nsAccessible // nsAccessible
virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
nsresult* aError = nsnull);
virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex); virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
// nsXULTreeGridCellAccessible // nsXULTreeGridCellAccessible

Просмотреть файл

@ -108,13 +108,14 @@ _TEST_FILES =\
test_groupattrs.xul \ test_groupattrs.xul \
test_groupattrs.html \ test_groupattrs.html \
test_invalidate_accessnode.html \ test_invalidate_accessnode.html \
test_invalidate_elmli.html \
test_name.html \ test_name.html \
test_name.xul \ test_name.xul \
test_name_button.html \ test_name_button.html \
test_name_link.html \ test_name_link.html \
test_name_markup.html \ test_name_markup.html \
test_name_nsApplicationAcc.html \
test_name_nsRootAcc.xul \ test_name_nsRootAcc.xul \
test_nsIAccessible_applicationAccessible.html \
$(warning test_nsIAccessible_comboboxes.xul temporarily disabled) \ $(warning test_nsIAccessible_comboboxes.xul temporarily disabled) \
test_nsIAccessible_selects.html \ test_nsIAccessible_selects.html \
test_nsIAccessible_focus.html \ test_nsIAccessible_focus.html \

Просмотреть файл

@ -270,35 +270,6 @@ function getRootAccessible(aAccOrElmOrID)
return null; return null;
} }
/**
* Return application accessible.
*/
function getApplicationAccessible()
{
var acc = getAccessible(document), parent = null;
while (acc) {
try {
parent = acc.parent;
} catch (e) {
ok(false, "Can't get a parent for " + prettyName(acc));
return null;
}
if (!parent) {
if (acc.role == ROLE_APP_ROOT)
return acc;
ok(false, "No application accessible!");
return null;
}
acc = parent;
}
return null;
}
/** /**
* Run through accessible tree of the given identifier so that we ensure * Run through accessible tree of the given identifier so that we ensure
* accessible tree is created. * accessible tree is created.
@ -385,12 +356,6 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree)
try { parent = child.parent; } catch (e) {} try { parent = child.parent; } catch (e) {}
is(parent, acc, "Wrong parent of " + prettyName(child)); is(parent, acc, "Wrong parent of " + prettyName(child));
// nsIAccessible::indexInParent
var indexInParent = -1;
try { indexInParent = child.indexInParent; } catch(e) {}
is(indexInParent, i,
"Wrong index in parent of " + prettyName(child));
// nsIAccessible::nextSibling // nsIAccessible::nextSibling
var expectedNextSibling = (i < childCount - 1) ? var expectedNextSibling = (i < childCount - 1) ?
children.queryElementAt(i + 1, nsIAccessible) : null; children.queryElementAt(i + 1, nsIAccessible) : null;
@ -414,84 +379,6 @@ function testAccessibleTree(aAccOrElmOrID, aAccTree)
} }
} }
/**
* Test accessible tree for defunct accessible.
*
* @param aAcc [in] the defunct accessible
* @param aNodeOrId [in] the DOM node identifier for the defunct accessible
*/
function testDefunctAccessible(aAcc, aNodeOrId)
{
if (aNodeOrId)
ok(!isAccessible(aNodeOrId),
"Accessible for " + aNodeOrId + " wasn't properly shut down!");
var msg = " doesn't fail for shut down accessible " + prettyName(aNodeOrId) + "!";
// firstChild
var success = false;
try {
aAcc.firstChild;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE)
}
ok(success, "firstChild" + msg);
// lastChild
success = false;
try {
aAcc.lastChild;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE)
}
ok(success, "lastChild" + msg);
// childCount
success = false;
try {
aAcc.childCount;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE)
}
ok(success, "childCount" + msg);
// children
success = false;
try {
aAcc.children;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE)
}
ok(success, "children" + msg);
// nextSibling
success = false;
try {
aAcc.nextSibling;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE);
}
ok(success, "nextSibling" + msg);
// previousSibling
success = false;
try {
aAcc.previousSibling;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE);
}
ok(success, "previousSibling" + msg);
// parent
success = false;
try {
aAcc.parent;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE);
}
ok(success, "parent" + msg);
}
/** /**
* Convert role to human readable string. * Convert role to human readable string.

Просмотреть файл

@ -8,7 +8,6 @@ const ROLE_AUTOCOMPLETE = nsIAccessibleRole.ROLE_AUTOCOMPLETE;
const ROLE_BUTTONDROPDOWNGRID = nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID; const ROLE_BUTTONDROPDOWNGRID = nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID;
const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION; const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION;
const ROLE_CELL = nsIAccessibleRole.ROLE_CELL; const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
const ROLE_CHECKBUTTON = nsIAccessibleRole.ROLE_CHECKBUTTON;
const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW; const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX; const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST; const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
@ -41,11 +40,9 @@ const ROLE_PARENT_MENUITEM = nsIAccessibleRole.ROLE_PARENT_MENUITEM;
const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT; const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR; const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON; const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
const ROLE_RADIOBUTTON = nsIAccessibleRole.ROLE_RADIOBUTTON;
const ROLE_ROW = nsIAccessibleRole.ROLE_ROW; const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER; const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER;
const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION; const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION;
const ROLE_SEPARATOR = nsIAccessibleRole.ROLE_SEPARATOR;
const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER; const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
const ROLE_STATICTEXT = nsIAccessibleRole.ROLE_STATICTEXT; const ROLE_STATICTEXT = nsIAccessibleRole.ROLE_STATICTEXT;
const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE; const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
@ -53,7 +50,6 @@ const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF; const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON; const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
const ROLE_TREE_TABLE = nsIAccessibleRole.ROLE_TREE_TABLE; const ROLE_TREE_TABLE = nsIAccessibleRole.ROLE_TREE_TABLE;
const ROLE_WHITESPACE = nsIAccessibleRole.ROLE_WHITESPACE;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Public methods // Public methods

Просмотреть файл

@ -47,12 +47,7 @@
var docAcc = getAccessible(document); var docAcc = getAccessible(document);
while (docAcc) { while (docAcc) {
this.mRootAcc = docAcc; this.mRootAcc = docAcc;
try { docAcc = docAcc.parent;
docAcc = docAcc.parent;
} catch (e) {
ok(false, "Can't get parent for " + prettyName(docAcc));
throw e;
}
} }
this.eventSeq = [ this.eventSeq = [

Просмотреть файл

@ -23,6 +23,47 @@
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Helpers // Helpers
function testDefunctAccessible(aAcc, aNodeOrId)
{
if (aNodeOrId)
ok(!isAccessible(aNodeOrId),
"Accessible for " + aNodeOrId + " wasn't properly shut down!");
ok(!aAcc.firstChild, "There is first child for shut down accessible!");
ok(!aAcc.lastChild, "There is last child for shut down accessible!");
ok(!aAcc.children.length, "There are children for shut down accessible!");
// nextSibling
var success = false;
try {
aAcc.nextSibling;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE);
}
ok(success, "There is next sibling for shut down accessible!");
// previousSibling
var success = false;
try {
aAcc.previousSibling;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE);
}
ok(success, "There is previous sibling for shut down accessible!");
// parent
var success = false;
try {
aAcc.parent;
} catch (e) {
success = (e.result == Components.results.NS_ERROR_FAILURE);
}
ok(success, "There is parent for shut down accessible!");
}
function testLiAccessibleTree() function testLiAccessibleTree()
{ {
// Test accessible tree. // Test accessible tree.
@ -60,14 +101,12 @@
this.onProcessed = function hideProcessor_onProcessed() this.onProcessed = function hideProcessor_onProcessed()
{ {
window.setTimeout( window.setTimeout(
function(aLiAcc, aLiNode, aBulletAcc) function(aArg1, aArg2)
{ {
testDefunctAccessible(aLiAcc, aLiNode); testDefunctAccessible(aArg1, aArg2);
testDefunctAccessible(aBulletAcc);
gSequence.processNext(); gSequence.processNext();
}, },
0, this.li, this.liNode, this.bullet 0, this.li, this.liNode
); );
} }
}; };

Просмотреть файл

@ -7,20 +7,22 @@
<script type="application/javascript" <script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script> src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" <script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js">
</script>
<script type="application/javascript" <script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script> src="chrome://mochikit/content/a11y/accessible/common.js" ></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript"> <script type="application/javascript">
function doTest() function doTest()
{ {
var accessible = getApplicationAccessible(); var accessible = getAccessible(document);
while (accessible && accessible.parent) {
accessible = accessible.parent;
}
if (!accessible) { if (!accessible) {
SimpleTest.finish(); SimpleTest.finish();
return; return;
} }
var bundleServ = Components.classes["@mozilla.org/intl/stringbundle;1"] var bundleServ = Components.classes["@mozilla.org/intl/stringbundle;1"]

Просмотреть файл

@ -50,18 +50,10 @@ _TEST_FILES =\
test_colorpicker.xul \ test_colorpicker.xul \
test_combobox.xul \ test_combobox.xul \
test_filectrl.html \ test_filectrl.html \
test_formctrl.html \
test_formctrl.xul \
test_groupbox.xul \
test_iframe.html \
test_img.html \
test_list.html \
test_list_invalidate.html \
test_media.html \ test_media.html \
test_menu.xul \ test_menu.xul \
test_select.html \ test_select.html \
test_tree.xul \ test_tree.xul \
test_txtcntr.html \
test_txtctrl.html \ test_txtctrl.html \
$(NULL) $(NULL)

Просмотреть файл

@ -1,83 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>HTML form controls tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript">
function doTest()
{
// input@type="checkbox"
var accTree = {
role: ROLE_CHECKBUTTON,
children: [ ]
};
testAccessibleTree("checkbox", accTree);
// input@type="radio"
accTree = {
role: ROLE_RADIOBUTTON,
children: [ ]
};
testAccessibleTree("radio", accTree);
// input@type="button" and button
accTree = {
role: ROLE_PUSHBUTTON,
children: [ ]
};
testAccessibleTree("btn1", accTree);
// button
accTree = {
role: ROLE_PUSHBUTTON,
children: [
{
role: ROLE_TEXT_LEAF
}
]
};
testAccessibleTree("btn2", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Fix O(n^2) access to all the children of a container"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045">
Mozilla Bug 342045
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<input type="checkbox" id="checkbox">
<input type="radio" id="radio">
<input type="button" value="button" id="btn1">
<button id="btn2">button</button>
</body>
</html>

Просмотреть файл

@ -1,83 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Accessible XUL checkbox and radio hierarchy tests">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
function doTest()
{
// checkbox
var accTree = {
role: ROLE_CHECKBUTTON,
children: [ ]
};
testAccessibleTree("checkbox", accTree);
// radiogroup
accTree = {
role: ROLE_GROUPING,
children: [
{
role: ROLE_RADIOBUTTON,
children: [ ]
},
{
role: ROLE_RADIOBUTTON,
children: [ ]
}
]
};
testAccessibleTree("radiogroup", accTree);
SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045"
title="Fix O(n^2) access to all the children of a container">
Mozilla Bug 342045
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<checkbox id="checkbox" label="checkbox"/>
<radiogroup id="radiogroup">
<radio label="radio1"/>
<radio label="radio2"/>
</radiogroup>
</vbox>
</hbox>
</window>

Просмотреть файл

@ -1,73 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Accessible XUL groupbox hierarchy tests">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
function doTest()
{
accTree = {
role: ROLE_GROUPING,
children: [
{
role: ROLE_LABEL,
children: [ ]
},
{
role: ROLE_CHECKBUTTON,
children: [ ]
}
]
};
testAccessibleTree("groupbox", accTree);
SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045"
title="Fix O(n^2) access to all the children of a container">
Mozilla Bug 342045
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<groupbox id="groupbox">
<caption label="Some caption" />
<checkbox label="some checkbox label" />
</groupbox>
</vbox>
</hbox>
</window>

Просмотреть файл

@ -1,54 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Outer document accessible tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript">
function doTest()
{
var accTree = {
role: ROLE_INTERNAL_FRAME,
children: [
{
role: ROLE_DOCUMENT
}
]
};
testAccessibleTree("iframe", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Fix O(n^2) access to all the children of a container"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045">
Mozilla Bug 342045
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<iframe id="iframe" src="about:mozilla">
</body>
</html>

Просмотреть файл

@ -1,79 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>HTML img tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript">
function doTest()
{
// image map
var accTree = {
role: ROLE_IMAGE_MAP,
children: [
{
role: ROLE_LINK,
children: []
},
{
role: ROLE_LINK,
children: []
}
]
};
testAccessibleTree("imgmap", accTree);
// img
accTree = {
role: ROLE_GRAPHIC,
children: []
};
testAccessibleTree("img", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Fix O(n^2) access to all the children of a container"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045">
Mozilla Bug 342045
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<map name="atoz_map">
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
coords="17,0,30,14" alt="b" shape="rect">
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
coords="0,0,13,14" alt="a" shape="rect">
</map>
<img id="imgmap" width="447" height="15"
usemap="#atoz_map"
src="chrome://mochikit/content/a11y/accessible/letters.gif">
<img id="img" src="chrome://mochikit/content/a11y/accessible/moz.png">
</body>
</html>

Просмотреть файл

@ -1,105 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>HTML ul/li element tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript">
function listItemTree(aBulletText, aName, aSubtree)
{
var obj = {
role: ROLE_LISTITEM,
children: [
{
role: ROLE_STATICTEXT,
name: aBulletText
},
{
role: ROLE_TEXT_LEAF,
name: aName
}
]
};
if (aSubtree)
obj.children.push(aSubtree);
return obj;
}
function doTest()
{
var bulletText = String.fromCharCode(0x2022) + " ";
// list1
var accTree = {
role: ROLE_LIST,
children: [
new listItemTree(bulletText, "Oranges"),
new listItemTree(bulletText, "Apples"),
new listItemTree(bulletText, "Bananas")
]
};
testAccessibleTree("list1", accTree);
// list2
accTree = {
role: ROLE_LIST,
children: [
new listItemTree("1. ", "Oranges"),
new listItemTree("2. ", "Apples"),
new listItemTree("3. ", "Bananas", accTree)
]
};
testAccessibleTree("list2", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Fix O(n^2) access to all the children of a container"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045">
Mozilla Bug 342045
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<ul id="list1">
<li id="li1">Oranges</li>
<li id="li2">Apples</li>
<li id="li3">Bananas</li>
</ul>
<ol id="list2">
<li id="li4">Oranges</li>
<li id="li5">Apples</li>
<li id="li6">Bananas<ul>
<li id="n_li4">Oranges</li>
<li id="n_li5">Apples</li>
<li id="n_li6">Bananas</li>
</ul>
</li>
</ol>
</body>
</html>

Просмотреть файл

@ -1,102 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>HTML text containers tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript">
function doTest()
{
var accTree = {
role: ROLE_SECTION,
children: [
{ // text child
role: ROLE_TEXT_LEAF,
children: []
}
]
};
testAccessibleTree("c1", accTree);
testAccessibleTree("c2", accTree);
accTree = {
role: ROLE_SECTION,
children: [
{
role: ROLE_TEXT_LEAF,
name: "Hello1"
},
{
role: ROLE_WHITESPACE
},
{
role: ROLE_TEXT_LEAF,
name: "Hello2"
},
{
role: ROLE_SEPARATOR
},
{
role: ROLE_TEXT_LEAF,
name: "Hello3 "
},
{
role: ROLE_PARAGRAPH,
children: [
{
role: ROLE_TEXT_LEAF,
name: "Hello4 "
}
]
}
]
};
testAccessibleTree("c3", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="overflowed content doesn't expose child text accessibles"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=489306">Mozilla Bug 489306</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="c1" style="width: 100px; height: 100px; overflow: auto;">
1hellohello 2hellohello 3hellohello 4hellohello 5hellohello 6hellohello 7hellohello
</div>
<div id="c2">
1hellohello 2hellohello 3hellohello 4hellohello 5hellohello 6hellohello 7hellohello
</div>
<div id="c3">
Hello1<br>
Hello2<hr>
Hello3
<p>
Hello4
</p>
</div>
</body>
</html>

Просмотреть файл

@ -2,9 +2,8 @@
<html> <html>
<head> <head>
<title>HTML text controls tests</title> <title>HTML text containers tests</title>
<link rel="stylesheet" type="text/css" <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript" <script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script> src="chrome://mochikit/content/MochiKit/packed.js"></script>
@ -19,58 +18,17 @@
<script type="application/javascript"> <script type="application/javascript">
function doTest() function doTest()
{ {
// editable div
var accTree = { var accTree = {
role: ROLE_SECTION, role: ROLE_SECTION,
children: [ children: [
{ // text child { // text child
role: ROLE_TEXT_LEAF, role: ROLE_TEXT_LEAF
children: []
} }
] ]
}; };
testAccessibleTree("txc1", accTree); testAccessibleTree("c1", accTree);
testAccessibleTree("c2", accTree);
// input@type="text"
accTree = {
role: ROLE_ENTRY,
children: [
{ // text child
role: ROLE_TEXT_LEAF,
children: []
}
]
};
testAccessibleTree("txc2", accTree);
// textarea
accTree = {
role: ROLE_ENTRY,
children: [
{
role: ROLE_TEXT_LEAF // hello1 text
},
{
role: ROLE_WHITESPACE
},
{
role: ROLE_TEXT_LEAF, // hello2 text
},
{
role: ROLE_WHITESPACE
},
{
role: ROLE_TEXT_LEAF, // whitepsace text
},
{
role: ROLE_WHITESPACE
}
]
};
testAccessibleTree("txc3", accTree);
SimpleTest.finish(); SimpleTest.finish();
} }
@ -89,14 +47,11 @@
<pre id="test"> <pre id="test">
</pre> </pre>
<div id="txc1" contentEditable="true"> <div id="c1" style="width: 100px; height: 100px; overflow: auto;">
1hellohello 1hellohello 2hellohello 3hellohello 4hellohello 5hellohello 6hellohello 7hellohello
</div>
<div id="c2">
1hellohello 2hellohello 3hellohello 4hellohello 5hellohello 6hellohello 7hellohello
</div> </div>
<input id="txc2" value="hello">
<textarea id="txc3">
hello1
hello2
</textarea>
</body> </body>
</html> </html>