diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index 32cf2a0c3c05..3d018fdd2f25 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -605,18 +605,6 @@ nsAccessible::GetChildren(nsIArray **aOutChildren) return NS_OK; } -nsIAccessible *nsAccessible::NextChild(nsCOMPtr& aAccessible) -{ - nsCOMPtr nextChild; - if (!aAccessible) { - GetFirstChild(getter_AddRefs(nextChild)); - } - else { - aAccessible->GetNextSibling(getter_AddRefs(nextChild)); - } - return (aAccessible = nextChild); -} - PRBool nsAccessible::GetAllowsAnonChildAccessibles() { @@ -931,8 +919,10 @@ nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, PRBool aDeepestChild, // where layout won't walk into things for us, such as image map areas and // sub documents (XXX: subdocuments should be handled by methods of // nsOuterDocAccessibles). - nsCOMPtr child; - while (NextChild(child)) { + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessible *child = GetChildAt(childIdx); + PRInt32 childX, childY, childWidth, childHeight; child->GetBounds(&childX, &childY, &childWidth, &childHeight); if (aX >= childX && aX < childX + childWidth && @@ -2994,7 +2984,7 @@ void nsAccessible::TestChildCache(nsAccessible *aCachedChild) { #ifdef DEBUG - PRUint32 childCount = mChildren.Length(); + PRInt32 childCount = mChildren.Length(); if (childCount == 0) { NS_ASSERTION(!mAreChildrenInitialized, "No children but initialized!"); return; diff --git a/accessible/src/base/nsAccessible.h b/accessible/src/base/nsAccessible.h index a601b28b9c16..491ed06370f8 100644 --- a/accessible/src/base/nsAccessible.h +++ b/accessible/src/base/nsAccessible.h @@ -350,10 +350,6 @@ protected: // helper method to verify frames static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut); static nsresult GetTranslatedString(const nsAString& aKey, nsAString& aStringOut); - - // 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). - nsIAccessible *NextChild(nsCOMPtr& aAccessible); already_AddRefed GetNextWithState(nsIAccessible *aStart, PRUint32 matchState); diff --git a/accessible/src/html/nsHyperTextAccessible.cpp b/accessible/src/html/nsHyperTextAccessible.cpp index 0411a09265df..6f74af77e763 100644 --- a/accessible/src/html/nsHyperTextAccessible.cpp +++ b/accessible/src/html/nsHyperTextAccessible.cpp @@ -322,23 +322,24 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset, *aEndAcc = nsnull; nsIntRect unionRect; - nsCOMPtr accessible, lastAccessible; + nsAccessible *lastAccessible = nsnull; gfxSkipChars skipChars; gfxSkipCharsIterator iter; // Loop through children and collect valid offsets, text and bounds - // depending on what we need for out parameters - while (NextChild(accessible)) { - lastAccessible = accessible; - nsRefPtr accessNode = nsAccUtils::QueryAccessNode(accessible); + // depending on what we need for out parameters. + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessible *childAcc = mChildren[childIdx]; + lastAccessible = childAcc; - nsIFrame *frame = accessNode->GetFrame(); + nsIFrame *frame = childAcc->GetFrame(); if (!frame) { continue; } nsIFrame *primaryFrame = frame; - if (nsAccUtils::IsText(accessible)) { + if (nsAccUtils::IsText(childAcc)) { // We only need info up to rendered offset -- that is what we're // converting to content offset PRInt32 substringEndOffset = -1; @@ -357,7 +358,7 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset, if (substringEndOffset < 0) { // XXX for non-textframe text like list bullets, // should go away after list bullet rewrite - substringEndOffset = nsAccUtils::TextLength(accessible); + substringEndOffset = nsAccUtils::TextLength(childAcc); } if (startOffset < substringEndOffset) { // Our start is within this substring @@ -378,7 +379,7 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset, if (aEndFrame) { *aEndFrame = frame; // We ended in the current frame if (aEndAcc) - NS_ADDREF(*aEndAcc = accessible); + NS_ADDREF(*aEndAcc = childAcc); } if (substringEndOffset > endOffset) { // Need to stop before the end of the available text @@ -392,9 +393,8 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset, *aText += '*'; // Show *'s only for password text } else { - nsRefPtr acc(nsAccUtils::QueryAccessible(accessible)); - acc->AppendTextTo(*aText, startOffset, - substringEndOffset - startOffset); + childAcc->AppendTextTo(*aText, startOffset, + substringEndOffset - startOffset); } } if (aBoundsRect) { // Caller wants the bounds of the text @@ -406,7 +406,7 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset, startFrame = frame; aStartOffset = startOffset; if (aStartAcc) - NS_ADDREF(*aStartAcc = accessible); + NS_ADDREF(*aStartAcc = childAcc); } // We already started copying in this accessible's string, // for the next accessible we'll start at offset 0 @@ -448,7 +448,7 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset, startFrame = frame; aStartOffset = 0; if (aStartAcc) - NS_ADDREF(*aStartAcc = accessible); + NS_ADDREF(*aStartAcc = childAcc); } } -- endOffset; @@ -483,15 +483,17 @@ NS_IMETHODIMP nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndO */ NS_IMETHODIMP nsHyperTextAccessible::GetCharacterCount(PRInt32 *aCharacterCount) { + NS_ENSURE_ARG_POINTER(aCharacterCount); *aCharacterCount = 0; - if (!mDOMNode) { + + if (IsDefunct()) return NS_ERROR_FAILURE; - } - nsCOMPtr accessible; + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessible *childAcc = mChildren[childIdx]; - while (NextChild(accessible)) { - PRInt32 textLength = nsAccUtils::TextLength(accessible); + PRInt32 textLength = nsAccUtils::TextLength(childAcc); NS_ENSURE_TRUE(textLength >= 0, nsnull); *aCharacterCount += textLength; } @@ -596,15 +598,19 @@ nsresult nsHyperTextAccessible::DOMPointToHypertextOffset(nsIDOMNode* aNode, PRI } descendantAccessible = GetFirstAvailableAccessible(findNode); } + // From the descendant, go up and get the immediate child of this hypertext - nsCOMPtr childAccessible; - while (descendantAccessible) { - nsCOMPtr parentAccessible; - descendantAccessible->GetParent(getter_AddRefs(parentAccessible)); - if (this == parentAccessible) { - childAccessible = descendantAccessible; + nsRefPtr childAccAtOffset; + nsRefPtr descendantAcc = + nsAccUtils::QueryObject(descendantAccessible); + + while (descendantAcc) { + nsRefPtr parentAcc = descendantAcc->GetParent(); + if (parentAcc == this) { + childAccAtOffset = descendantAcc; break; } + // This offset no longer applies because the passed-in text object is not a child // of the hypertext. This happens when there are nested hypertexts, e.g. //
abc

def

ghi
@@ -622,29 +628,40 @@ nsresult nsHyperTextAccessible::DOMPointToHypertextOffset(nsIDOMNode* aNode, PRI // Make sure the offset lands on the embedded object character in order to indicate // the true inner offset is inside the subtree for that link addTextOffset = - (nsAccUtils::TextLength(descendantAccessible) == static_cast(addTextOffset)) ? 1 : 0; + (nsAccUtils::TextLength(descendantAcc) == static_cast(addTextOffset)) ? 1 : 0; } - descendantAccessible = parentAccessible; - } + + descendantAcc.swap(parentAcc); + } // Loop through, adding offsets until we reach childAccessible // If childAccessible is null we will end up adding up the entire length of // the hypertext, which is good -- it just means our offset node // came after the last accessible child's node - nsCOMPtr accessible; - while (NextChild(accessible) && accessible != childAccessible) { - PRInt32 textLength = nsAccUtils::TextLength(accessible); + PRInt32 childCount = GetChildCount(); + + PRInt32 childIdx = 0; + nsAccessible *childAcc = nsnull; + for (; childIdx < childCount; childIdx++) { + childAcc = mChildren[childIdx]; + if (childAcc == childAccAtOffset) + break; + + PRInt32 textLength = nsAccUtils::TextLength(childAcc); NS_ENSURE_TRUE(textLength >= 0, nsnull); *aHyperTextOffset += textLength; } - if (accessible) { + + if (childIdx < childCount) { *aHyperTextOffset += addTextOffset; - NS_ASSERTION(accessible == childAccessible, "These should be equal whenever we exit loop and accessible != nsnull"); + NS_ASSERTION(childAcc == childAccAtOffset, + "These should be equal whenever we exit loop and childAcc != nsnull"); + if (aFinalAccessible && - (NextChild(accessible) || - static_cast(addTextOffset) < nsAccUtils::TextLength(childAccessible))) { + (childIdx < childCount - 1 || + static_cast(addTextOffset) < nsAccUtils::TextLength(childAccAtOffset))) { // If not at end of last text node, we will return the accessible we were in - NS_ADDREF(*aFinalAccessible = childAccessible); + NS_ADDREF(*aFinalAccessible = childAccAtOffset); } } @@ -1277,13 +1294,12 @@ nsHyperTextAccessible::GetOffsetAtPoint(PRInt32 aX, PRInt32 aY, // We have an point in an accessible child of this, now we need to add up the // offsets before it to what we already have - nsCOMPtr accessible; PRInt32 offset = 0; + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessible *childAcc = mChildren[childIdx]; - while (NextChild(accessible)) { - nsRefPtr accessNode = nsAccUtils::QueryAccessNode(accessible); - - nsIFrame *primaryFrame = accessNode->GetFrame(); + nsIFrame *primaryFrame = childAcc->GetFrame(); NS_ENSURE_TRUE(primaryFrame, NS_ERROR_FAILURE); nsIFrame *frame = primaryFrame; @@ -1311,7 +1327,7 @@ nsHyperTextAccessible::GetOffsetAtPoint(PRInt32 aX, PRInt32 aY, } frame = frame->GetNextContinuation(); } - PRInt32 textLength = nsAccUtils::TextLength(accessible); + PRInt32 textLength = nsAccUtils::TextLength(childAcc); NS_ENSURE_TRUE(textLength >= 0, NS_ERROR_FAILURE); offset += textLength; } @@ -1325,14 +1341,13 @@ nsHyperTextAccessible::GetLinkCount(PRInt32 *aLinkCount) { NS_ENSURE_ARG_POINTER(aLinkCount); *aLinkCount = 0; - if (!mDOMNode) { + if (IsDefunct()) return NS_ERROR_FAILURE; - } - nsCOMPtr accessible; - - while (NextChild(accessible)) { - if (nsAccUtils::IsEmbeddedObject(accessible)) + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessible *childAcc = mChildren[childIdx]; + if (nsAccUtils::IsEmbeddedObject(childAcc)) ++*aLinkCount; } return NS_OK; @@ -1349,10 +1364,12 @@ nsHyperTextAccessible::GetLink(PRInt32 aLinkIndex, nsIAccessibleHyperLink **aLin return NS_ERROR_FAILURE; PRInt32 linkIndex = aLinkIndex; - nsCOMPtr accessible; - while (NextChild(accessible)) { - if (nsAccUtils::IsEmbeddedObject(accessible) && linkIndex-- == 0) - return CallQueryInterface(accessible, aLink); + + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessible *childAcc = mChildren[childIdx]; + if (nsAccUtils::IsEmbeddedObject(childAcc) && linkIndex-- == 0) + return CallQueryInterface(childAcc, aLink); } return NS_ERROR_INVALID_ARG; @@ -1364,19 +1381,21 @@ nsHyperTextAccessible::GetLinkIndex(PRInt32 aCharIndex, PRInt32 *aLinkIndex) NS_ENSURE_ARG_POINTER(aLinkIndex); *aLinkIndex = -1; // API says this magic value means 'not found' + if (IsDefunct()) + return NS_ERROR_FAILURE; + PRInt32 characterCount = 0; PRInt32 linkIndex = 0; - if (!mDOMNode) { - return NS_ERROR_FAILURE; - } - nsCOMPtr accessible; + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; + childIdx < childCount && characterCount <= aCharIndex; childIdx++) { + nsAccessible *childAcc = mChildren[childIdx]; - while (NextChild(accessible) && characterCount <= aCharIndex) { - PRUint32 role = nsAccUtils::Role(accessible); + PRUint32 role = nsAccUtils::Role(childAcc); if (role == nsIAccessibleRole::ROLE_TEXT_LEAF || role == nsIAccessibleRole::ROLE_STATICTEXT) { - PRInt32 textLength = nsAccUtils::TextLength(accessible); + PRInt32 textLength = nsAccUtils::TextLength(childAcc); NS_ENSURE_TRUE(textLength >= 0, NS_ERROR_FAILURE); characterCount += textLength; } diff --git a/accessible/src/mac/nsAccessibleWrap.mm b/accessible/src/mac/nsAccessibleWrap.mm index b1b470615d4e..9092d189ed7a 100644 --- a/accessible/src/mac/nsAccessibleWrap.mm +++ b/accessible/src/mac/nsAccessibleWrap.mm @@ -185,7 +185,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent) return NS_OK; nsCOMPtr accessible; - nsresult rv = aEvent->GetAccessible(getter_AddRefs(accessible)); + aEvent->GetAccessible(getter_AddRefs(accessible)); NS_ENSURE_STATE(accessible); mozAccessible *nativeAcc = nil; @@ -227,35 +227,34 @@ nsAccessibleWrap::GetUnignoredChildCount(PRBool aDeepCount) // if we're flat, we have no children. if (nsAccUtils::MustPrune(this)) return 0; - - PRInt32 childCount = 0; - GetChildCount(&childCount); - - nsCOMPtr curAcc; - - while (NextChild(curAcc)) { - nsAccessibleWrap *childWrap = static_cast(curAcc.get()); - + + PRInt32 resultChildCount = 0; + + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessibleWrap *childAcc = + static_cast(GetChildAt(childIdx)); + // if the current child is not ignored, count it. - if (!childWrap->IsIgnored()) - ++childCount; - + if (!childAcc->IsIgnored()) + ++resultChildCount; + // if it's flat, we don't care to inspect its children. - if (nsAccUtils::MustPrune(childWrap)) + if (nsAccUtils::MustPrune(childAcc)) continue; - + if (aDeepCount) { // recursively count the unignored children of our children since it's a deep count. - childCount += childWrap->GetUnignoredChildCount(PR_TRUE); + resultChildCount += childAcc->GetUnignoredChildCount(PR_TRUE); } else { // no deep counting, but if the child is ignored, we want to substitute it for its // children. - if (childWrap->IsIgnored()) - childCount += childWrap->GetUnignoredChildCount(PR_FALSE); + if (childAcc->IsIgnored()) + resultChildCount += childAcc->GetUnignoredChildCount(PR_FALSE); } } - return childCount; + return resultChildCount; } // if we for some reason have no native accessible, we should be skipped over (and traversed) @@ -269,19 +268,20 @@ nsAccessibleWrap::IsIgnored() void nsAccessibleWrap::GetUnignoredChildren(nsTArray > &aChildrenArray) { - nsCOMPtr curAcc; - // we're flat; there are no children. if (nsAccUtils::MustPrune(this)) return; - - while (NextChild(curAcc)) { - nsAccessibleWrap *childWrap = static_cast(curAcc.get()); - if (childWrap->IsIgnored()) { + + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessibleWrap *childAcc = + static_cast(GetChildAt(childIdx)); + + if (childAcc->IsIgnored()) { // element is ignored, so try adding its children as substitutes, if it has any. - if (!nsAccUtils::MustPrune(childWrap)) { + if (!nsAccUtils::MustPrune(childAcc)) { nsTArray > children; - childWrap->GetUnignoredChildren(children); + childAcc->GetUnignoredChildren(children); if (!children.IsEmpty()) { // add the found unignored descendants to the array. aChildrenArray.AppendElements(children); @@ -289,7 +289,7 @@ nsAccessibleWrap::GetUnignoredChildren(nsTArray > &aC } } else // simply add the element, since it's not ignored. - aChildrenArray.AppendElement(childWrap); + aChildrenArray.AppendElement(childAcc); } } diff --git a/accessible/src/xul/nsXULFormControlAccessible.cpp b/accessible/src/xul/nsXULFormControlAccessible.cpp index baccd89ad9dd..a8de7b21f52f 100644 --- a/accessible/src/xul/nsXULFormControlAccessible.cpp +++ b/accessible/src/xul/nsXULFormControlAccessible.cpp @@ -492,20 +492,21 @@ nsXULGroupboxAccessible::GetRelationByType(PRUint32 aRelationType, // The label for xul:groupbox is generated from xul:label that is // inside the anonymous content of the xul:caption. // The xul:label has an accessible object but the xul:caption does not - nsCOMPtr testLabelAccessible; - while (NextChild(testLabelAccessible)) { - if (nsAccUtils::Role(testLabelAccessible) == nsIAccessibleRole::ROLE_LABEL) { + PRInt32 childCount = GetChildCount(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsAccessible *childAcc = GetChildAt(childIdx); + if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_LABEL) { // Ensure that it's our label // XXX: we'll fail if group accessible expose more than one relation // targets. nsCOMPtr testGroupboxAccessible = - nsRelUtils::GetRelatedAccessible(testLabelAccessible, + nsRelUtils::GetRelatedAccessible(childAcc, nsIAccessibleRelation::RELATION_LABEL_FOR); if (testGroupboxAccessible == this) { // The