diff --git a/mozilla/accessible/public/nsIAccessible.idl b/mozilla/accessible/public/nsIAccessible.idl index d98116d34cf..48e7c9aa788 100644 --- a/mozilla/accessible/public/nsIAccessible.idl +++ b/mozilla/accessible/public/nsIAccessible.idl @@ -73,6 +73,9 @@ interface nsIAccessible : nsISupports nsIDOMNode accGetDOMNode(); + // Used by Accessible implementation to save data and speed up accessibility tree walking + [noscript] void CacheOptimizations(in nsIAccessible aParent, in PRInt32 aSiblingIndex, in nsIDOMNodeList aSiblingList); + // MSAA State flags - used for bitfield. More than 1 allowed. const unsigned long STATE_UNAVAILABLE = 0x00000001; // Disabled, maps to opposite of Java ENABLED, Gnome/ATK SENSITIVE? const unsigned long STATE_SELECTED = 0x00000002; diff --git a/mozilla/accessible/src/base/nsAccessibilityService.cpp b/mozilla/accessible/src/base/nsAccessibilityService.cpp index a7bf43919dd..05a8503f8fb 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.cpp +++ b/mozilla/accessible/src/base/nsAccessibilityService.cpp @@ -68,6 +68,7 @@ #include "nsIDOMXULCheckboxElement.h" #include "nsXULFormControlAccessible.h" #include "nsXULTextAccessible.h" +#include "nsString.h" // IFrame #include "nsIDocShell.h" @@ -75,7 +76,6 @@ //-------------------- - nsAccessibilityService::nsAccessibilityService() { NS_INIT_REFCNT(); @@ -563,44 +563,6 @@ nsAccessibilityService::CreateHTMLIFrameAccessible(nsIDOMNode* aDOMNode, nsISupp return NS_ERROR_FAILURE; } -//----------------------------------------------------------------------- - // This method finds the content node in the parent document - // corresponds to the docshell - // This code is copied and pasted from nsEventStateManager.cpp - // Is also inefficient - better solution should come along as part of - // Bug 85602: "FindContentForDocShell walks entire content tree" - // Hopefully there will be a better method soon, with a public interface - - nsIContent* - nsAccessibilityService::FindContentForDocShell(nsIPresShell* aPresShell, - nsIContent* aContent, - nsIDocShell* aDocShell) - { - NS_ASSERTION(aPresShell, "Pointer is null!"); - NS_ASSERTION(aDocShell, "Pointer is null!"); - NS_ASSERTION(aContent, "Pointer is null!"); - - nsCOMPtr supps; - aPresShell->GetSubShellFor(aContent, getter_AddRefs(supps)); - if (supps) { - nsCOMPtr docShell(do_QueryInterface(supps)); - if (docShell.get() == aDocShell) - return aContent; - } - - // walk children content - PRInt32 count; - aContent->ChildCount(count); - for (PRInt32 i=0;i child; - aContent->ChildAt(i, *getter_AddRefs(child)); - nsIContent* foundContent = FindContentForDocShell(aPresShell, child, aDocShell); - if (foundContent != nsnull) { - return foundContent; - } - } - return nsnull; - } void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell **aOwnerShell, nsIContent **aOwnerContent) { @@ -612,9 +574,9 @@ void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell presContext->GetContainer(getter_AddRefs(pcContainer)); if (!pcContainer) return; - nsCOMPtr docShell(do_QueryInterface(pcContainer)); + nsCOMPtr docShellSupports(do_QueryInterface(pcContainer)); - nsCOMPtr treeItem(do_QueryInterface(docShell)); + nsCOMPtr treeItem(do_QueryInterface(pcContainer)); if (!treeItem) return; @@ -640,9 +602,10 @@ void nsAccessibilityService::GetOwnerFor(nsIPresShell *aPresShell, nsIPresShell nsCOMPtr rootContent; parentDoc->GetRootContent(getter_AddRefs(rootContent)); - - nsIContent *tempContent; - tempContent = FindContentForDocShell(parentPresShell, rootContent, docShell); + + nsCOMPtr tempContent; + parentPresShell->FindContentForShell(docShellSupports, getter_AddRefs(tempContent)); + if (tempContent) { *aOwnerContent = tempContent; *aOwnerShell = parentPresShell; @@ -663,8 +626,8 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode, if (!aNode) return NS_ERROR_NULL_POINTER; - // ---- Is it a XUL element? -- they impl nsIAccessibleProvider via XBL nsCOMPtr newAcc; + nsCOMPtr accProv(do_QueryInterface(aNode)); if (accProv) { accProv->GetAccessible(getter_AddRefs(newAcc)); @@ -710,8 +673,25 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode, nsCOMPtr ownerShell; nsCOMPtr ownerContent; GetOwnerFor(shell, getter_AddRefs(ownerShell), getter_AddRefs(ownerContent)); - shell = ownerShell; - content = ownerContent; + if (content) { + shell = ownerShell; + content = ownerContent; + } + else { + doc->GetRootContent(getter_AddRefs(content)); + nsIFrame* frame = nsnull; + shell->GetPrimaryFrameFor(content, &frame); + if (!frame) + return NS_ERROR_FAILURE; + nsCOMPtr presContext; + shell->GetPresContext(getter_AddRefs(presContext)); + CreateRootAccessible(presContext, frame, getter_AddRefs(newAcc)); + *_retval = newAcc; + NS_ADDREF(*_retval); + + return NS_OK; + + } } // ---- If still no nsIContent, return ---- diff --git a/mozilla/accessible/src/base/nsAccessibilityService.h b/mozilla/accessible/src/base/nsAccessibilityService.h index b67c21c64aa..ce8d9a85cca 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.h +++ b/mozilla/accessible/src/base/nsAccessibilityService.h @@ -71,4 +71,4 @@ private: }; -#endif /* __nsIccessibilityService_h__ */ +#endif /* __nsIAccessibilityService_h__ */ diff --git a/mozilla/accessible/src/base/nsAccessible.cpp b/mozilla/accessible/src/base/nsAccessible.cpp index e171f3643ff..3a3cf244e17 100644 --- a/mozilla/accessible/src/base/nsAccessible.cpp +++ b/mozilla/accessible/src/base/nsAccessible.cpp @@ -78,6 +78,7 @@ #include "nsIStyleContext.h" #include "nsStyleConsts.h" #include "nsReadableUtils.h" +#include "nsIBindingManager.h" // IFrame Helpers #include "nsIDocShell.h" @@ -100,330 +101,330 @@ static gnsAccessibles = 0; static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); + + /** This class is used to walk the DOM tree. It skips * everything but nodes that either implement nsIAccessible * or have primary frames that implement "GetAccessible" */ -class nsDOMTreeWalker { -public: - nsDOMTreeWalker(nsIWeakReference* aShell, nsIDOMNode* aContent); - PRBool GetNextSibling(); - PRBool GetPreviousSibling(); - PRBool GetParent(); - PRBool GetFirstChild(); - PRBool GetLastChild(); - PRBool GetChildBefore(nsIDOMNode* aParent, nsIDOMNode* aChild); - PRInt32 GetCount(); - PRBool GetAccessible(); - - nsCOMPtr mPresShell; - nsCOMPtr mAccessible; - nsCOMPtr mDOMNode; - nsCOMPtr mAccService; +struct WalkState { + nsCOMPtr accessible; + nsCOMPtr domNode; + nsCOMPtr siblingList; + PRInt32 siblingIndex; // Holds a state flag or an index into the siblingList + WalkState *prevState; }; + +class nsAccessibleTreeWalker { +public: + nsAccessibleTreeWalker(nsIWeakReference* aShell, nsIDOMNode* aContent, + PRInt32 aCachedSiblingIndex, nsIDOMNodeList *aCachedSiblingList); + ~nsAccessibleTreeWalker(); -nsDOMTreeWalker::nsDOMTreeWalker(nsIWeakReference* aPresShell, nsIDOMNode* aNode) + NS_IMETHOD GetNextSibling(); + NS_IMETHOD GetPreviousSibling(); + NS_IMETHOD GetParent(); + NS_IMETHOD GetFirstChild(); + NS_IMETHOD GetLastChild(); + PRInt32 GetChildCount(); + WalkState mState; + +protected: + NS_IMETHOD GetChildBefore(nsIDOMNode* aParent, nsIDOMNode* aChild); + PRBool GetAccessible(); + NS_IMETHOD GetFullTreeParentNode(nsIDOMNode *aChildNode, nsIDOMNode **aParentNodeOut); + GetSiblings(nsIDOMNode *aOneOfTheSiblings); + GetKids(nsIDOMNode *aParent); + + ClearState(); + NS_IMETHOD PushState(); + NS_IMETHOD PopState(); + + nsCOMPtr mPresShell; + nsCOMPtr mAccService; + nsCOMPtr mBindingManager; +}; + +nsAccessibleTreeWalker::nsAccessibleTreeWalker(nsIWeakReference* aPresShell, nsIDOMNode* aNode, PRInt32 aSiblingIndex, nsIDOMNodeList *aSiblingList): + mPresShell(aPresShell), mAccService(do_GetService("@mozilla.org/accessibilityService;1")) { - mDOMNode = aNode; - mAccessible = nsnull; - mPresShell = aPresShell; - mAccService = do_GetService("@mozilla.org/accessibilityService;1"); + mState.domNode = aNode; + mState.siblingIndex = aSiblingIndex; + mState.prevState = nsnull; + mState.siblingList = aSiblingList; + + NS_ASSERTION((aSiblingIndex >= 0) == (aSiblingList != nsnull), "Cached sibling list and sibling index not in sync."); + + nsCOMPtr shell(do_QueryReferent(mPresShell)); + if (shell) { + nsCOMPtr doc; + shell->GetDocument(getter_AddRefs(doc)); + doc->GetBindingManager(getter_AddRefs(mBindingManager)); + } + MOZ_COUNT_CTOR(nsAccessibleTreeWalker); } - -PRBool nsDOMTreeWalker::GetParent() +nsAccessibleTreeWalker::~nsAccessibleTreeWalker() { - if (!mDOMNode) - { - mAccessible = nsnull; - return PR_FALSE; - } + // Clear state stack from memory + while (NS_SUCCEEDED(PopState())) + /* do nothing */ ; + MOZ_COUNT_DTOR(nsAccessibleTreeWalker); +} - // do we already have an accessible? Ask it. - if (mAccessible) - { - nsCOMPtr acc; - nsresult rv = mAccessible->GetAccParent(getter_AddRefs(acc)); - if (NS_SUCCEEDED(rv) && acc) { - mAccessible = acc; - acc->AccGetDOMNode(getter_AddRefs(mDOMNode)); - return PR_TRUE; +// GetFullParentNode gets the parent node in the deep tree +// This might not be the DOM parent in cases where was used in an XBL binding. +// In that case, this returns the parent in the XBL'ized tree. + +NS_IMETHODIMP nsAccessibleTreeWalker::GetFullTreeParentNode(nsIDOMNode *aChildNode, nsIDOMNode **aParentNodeOut) +{ + nsCOMPtr childContent(do_QueryInterface(aChildNode)); + nsCOMPtr bindingParentContent; + nsCOMPtr parentNode; + + if (mState.prevState) + parentNode = mState.prevState->domNode; + else { + if (mBindingManager) { + mBindingManager->GetInsertionParent(childContent, getter_AddRefs(bindingParentContent)); + if (bindingParentContent) + parentNode = do_QueryInterface(bindingParentContent); } + + if (!parentNode) + aChildNode->GetParentNode(getter_AddRefs(parentNode)); } - nsCOMPtr parent; - mDOMNode->GetParentNode(getter_AddRefs(parent)); + if (parentNode) { + *aParentNodeOut = parentNode; + NS_ADDREF(*aParentNodeOut); + return NS_OK; + } + return NS_ERROR_FAILURE; +} - // if no parent then we hit the root - // we want to return the accessible outside of us. So walk out of - // the document if we can - if (!parent) { - nsCOMPtr presShell(do_QueryReferent(mPresShell)); - if (presShell) { - nsCOMPtr parentPresShell; - nsCOMPtr content; - if (NS_SUCCEEDED(nsAccessible::GetParentPresShellAndContent(presShell, - getter_AddRefs(parentPresShell), - getter_AddRefs(content)))) { - nsIFrame* frame; - parentPresShell->GetPrimaryFrameFor(content, &frame); - if (frame) { - nsCOMPtr accessible; +nsAccessibleTreeWalker::GetKids(nsIDOMNode *aParentNode) +{ + nsCOMPtr content(do_QueryInterface(aParentNode)); - frame->GetAccessible(getter_AddRefs(accessible)); + mState.siblingIndex = eSiblingsWalkNormalDOM; // Default value - indicates no sibling list - if (!accessible) - accessible = do_QueryInterface(content); - if (accessible) { - nsCOMPtr wr(do_GetWeakReference(parentPresShell)); - accessible->AccGetDOMNode(getter_AddRefs(mDOMNode)); - mAccessible = accessible; - mPresShell = wr; - return PR_TRUE; - } - } + if (content && mBindingManager) { + mBindingManager->GetXBLChildNodesFor(content, getter_AddRefs(mState.siblingList)); // returns null if no anon nodes + if (mState.siblingList) + mState.siblingIndex = 0; // Indicates our index into the sibling list + } +} + +nsAccessibleTreeWalker::GetSiblings(nsIDOMNode *aOneOfTheSiblings) +{ + nsCOMPtr node; + + mState.siblingIndex = eSiblingsWalkNormalDOM; // Default value + + if (NS_SUCCEEDED(GetFullTreeParentNode(aOneOfTheSiblings, getter_AddRefs(node)))) { + GetKids(node); + if (mState.siblingList) { // Init index by seeing how far we are into list + while (NS_SUCCEEDED(mState.siblingList->Item(mState.siblingIndex, getter_AddRefs(node))) && node != mState.domNode) { + NS_ASSERTION(node, "Something is terribly wrong - the child is not in it's parent's children!"); + ++mState.siblingIndex; } - mAccessible = new nsRootAccessible(mPresShell); - mAccessible->AccGetDOMNode(getter_AddRefs(mDOMNode)); - return PR_TRUE; - } - - mAccessible = nsnull; - mDOMNode = nsnull; - return PR_FALSE; - } - - mDOMNode = parent; - if (GetAccessible()) - return PR_TRUE; - - return GetParent(); -} - - -PRBool nsDOMTreeWalker::GetNextSibling() -{ - //printf("Get next\n"); - - if (!mDOMNode) - { - mAccessible = nsnull; - return PR_FALSE; - } - - // do we already have an accessible? Ask it. - if (mAccessible) - { - nsCOMPtr acc; - nsresult rv = mAccessible->GetAccNextSibling(getter_AddRefs(acc)); - if (NS_SUCCEEDED(rv) && acc) { - mAccessible = acc; - acc->AccGetDOMNode(getter_AddRefs(mDOMNode)); - return PR_TRUE; } } +} + +NS_IMETHODIMP nsAccessibleTreeWalker::GetParent() +{ + nsCOMPtr parent; + + while (NS_SUCCEEDED(GetFullTreeParentNode(mState.domNode, getter_AddRefs(parent)))) { + if (NS_FAILED(PopState())) { + ClearState(); + mState.domNode = parent; + GetAccessible(); + } + if (mState.accessible) + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP nsAccessibleTreeWalker::PopState() +{ + if (mState.prevState) { + WalkState *toBeDeleted = mState.prevState; + mState = *mState.prevState; // deep copy + delete toBeDeleted; + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsAccessibleTreeWalker::ClearState() +{ + mState.siblingList = nsnull; + mState.accessible = nsnull; + mState.domNode = nsnull; + mState.siblingIndex = eSiblingsUninitialized; +} + +NS_IMETHODIMP nsAccessibleTreeWalker::PushState() +{ + // Duplicate mState and put right before end; reset mState; make mState the new end of the stack + WalkState* nextToLastState= new WalkState(); + if (!nextToLastState) + return NS_ERROR_FAILURE; + *nextToLastState = mState; // Deep copy - copy contents of struct to new state that will be added to end of our stack + ClearState(); + mState.prevState = nextToLastState; // Link to previous state + return NS_OK; +} + +NS_IMETHODIMP nsAccessibleTreeWalker::GetNextSibling() +{ + // Make sure mState.siblingIndex and mState.siblingList are initialized + if (mState.siblingIndex == eSiblingsUninitialized) + GetSiblings(mState.domNode); // get next sibling nsCOMPtr next; - mDOMNode->GetNextSibling(getter_AddRefs(next)); - - // if failed - if (!next) - { - // do we already have an accessible? Ask it. - if (mAccessible) - { - nsCOMPtr acc; - nsresult rv = mAccessible->GetAccParent(getter_AddRefs(acc)); - // if there is a parent then this is the last child. - if (NS_SUCCEEDED(rv)) { - mAccessible = nsnull; - mDOMNode = nsnull; - return PR_FALSE; + + while (PR_TRUE) { + if (mState.siblingIndex == eSiblingsWalkNormalDOM) + mState.domNode->GetNextSibling(getter_AddRefs(next)); + else + mState.siblingList->Item(++mState.siblingIndex, getter_AddRefs(next)); + + if (!next) { // Done with siblings + // if no DOM parent or DOM parent is accessible fail + nsCOMPtr parent; + if (NS_FAILED(GetFullTreeParentNode(mState.domNode, getter_AddRefs(parent)))) + break; // Failed - can't get parent node, we're at the top + + if (NS_FAILED(PopState())) { // Use parent - go up in stack + ClearState(); + mState.domNode = parent; } - } + if (mState.siblingIndex == eSiblingsUninitialized) + GetSiblings(mState.domNode); - // if parent has content - nsCOMPtr parent; - mDOMNode->GetParentNode(getter_AddRefs(parent)); - - // if no parent fail - if (!parent) { - mAccessible = nsnull; - mDOMNode = nsnull; - return PR_FALSE; + if (GetAccessible()) + break; // Failed - anything after this in the tree is in a new group of siblings } + else { + // if next is accessible, use it + mState.domNode = next; + if (GetAccessible()) + return NS_OK; - // fail if we reach a parent that is accessible - mDOMNode = parent; - if (GetAccessible()) - { - // fail - mAccessible = nsnull; - mDOMNode = nsnull; - return PR_FALSE; - } else { - // next on parent - mDOMNode = parent; - return GetNextSibling(); + // otherwise call first on next + mState.domNode = next; + if (NS_SUCCEEDED(GetFirstChild())) + return NS_OK; + + // If no results, keep recursiom going - call next on next + mState.domNode = next; } } - - // if next has content - mDOMNode = next; - if (GetAccessible()) - return PR_TRUE; - - // if next doesn't have node - - // call first on next - mDOMNode = next; - if (GetFirstChild()) - return PR_TRUE; - - // call next on next - mDOMNode = next; - return GetNextSibling(); + return NS_ERROR_FAILURE; } - -PRBool nsDOMTreeWalker::GetFirstChild() +NS_IMETHODIMP nsAccessibleTreeWalker::GetFirstChild() { + if (!mState.domNode) + return NS_ERROR_FAILURE; - if (!mDOMNode) - { - mAccessible = nsnull; - return PR_FALSE; + nsCOMPtr next, parent(mState.domNode); + + PushState(); // Save old state + + GetKids(parent); // Side effects change our state + + if (mState.siblingIndex == eSiblingsWalkNormalDOM) // Indicates we must use normal DOM calls to traverse here + parent->GetFirstChild(getter_AddRefs(next)); + else // Use the sibling list - there are anonymous content nodes in here + mState.siblingList->Item(0, getter_AddRefs(next)); + + // Recursive loop: depth first search for first accessible child + while (next) { + mState.domNode = next; + if (GetAccessible() || NS_SUCCEEDED(GetFirstChild())) + return NS_OK; + if (mState.siblingIndex == eSiblingsWalkNormalDOM) // Indicates we must use normal DOM calls to traverse here + mState.domNode->GetNextSibling(getter_AddRefs(next)); + else + mState.siblingList->Item(++mState.siblingIndex, getter_AddRefs(next)); } - // do we already have an accessible? Ask it. - if (mAccessible) - { - nsCOMPtr acc; - nsresult rv = mAccessible->GetAccFirstChild(getter_AddRefs(acc)); - if (NS_SUCCEEDED(rv) && acc) { - mAccessible = acc; - acc->AccGetDOMNode(getter_AddRefs(mDOMNode)); - return PR_TRUE; - } - } - - // get first child - nsCOMPtr child; - mDOMNode->GetFirstChild(getter_AddRefs(child)); - - while(child) - { - mDOMNode = child; - // if the child has a content node done - if (GetAccessible()) - return PR_TRUE; - else if (GetFirstChild()) // otherwise try first child - return PR_TRUE; - - // get next sibling - nsCOMPtr next; - child->GetNextSibling(getter_AddRefs(next)); - - child = next; - } - - // fail - mAccessible = nsnull; - mDOMNode = nsnull; - return PR_FALSE; + PopState(); // Return to previous state + return NS_ERROR_FAILURE; } - -PRBool nsDOMTreeWalker::GetChildBefore(nsIDOMNode* aParent, nsIDOMNode* aChild) +NS_IMETHODIMP nsAccessibleTreeWalker::GetChildBefore(nsIDOMNode* aParent, nsIDOMNode* aChild) { + mState.domNode = aParent; - mDOMNode = aParent; + if (!mState.domNode || NS_FAILED(GetFirstChild()) || mState.domNode == aChild) + return NS_ERROR_FAILURE; // if the first child is us, then we fail, because there is no child before the first - if (!mDOMNode) - { - mAccessible = nsnull; - return PR_FALSE; + nsCOMPtr prevDOMNode(mState.domNode); + nsCOMPtr prevAccessible(mState.accessible); + + while (mState.domNode && NS_SUCCEEDED(GetNextSibling()) && mState.domNode == aChild) { + prevDOMNode = mState.domNode; + prevAccessible = mState.accessible; } - GetFirstChild(); + mState.accessible = prevAccessible; + mState.domNode = prevDOMNode; - // if the child is not us - if (mDOMNode == aChild) { - mAccessible = nsnull; - mDOMNode = nsnull; - return PR_FALSE; - } - - nsCOMPtr prev(mDOMNode); - nsCOMPtr prevAccessible(mAccessible); - - while(mDOMNode) - { - GetNextSibling(); - - if (mDOMNode == aChild) - break; - - prev = mDOMNode; - prevAccessible = mAccessible; - } - - mAccessible = prevAccessible; - mDOMNode = prev; - - return PR_TRUE; + return NS_OK; } -PRBool nsDOMTreeWalker::GetPreviousSibling() +NS_IMETHODIMP nsAccessibleTreeWalker::GetPreviousSibling() { - nsCOMPtr child(mDOMNode); - GetParent(); - - return GetChildBefore(mDOMNode, child); + nsCOMPtr child(mState.domNode); + nsresult rv = GetParent(); + if (NS_SUCCEEDED(rv)) + rv = GetChildBefore(mState.domNode, child); + return rv; } -PRBool nsDOMTreeWalker::GetLastChild() +NS_IMETHODIMP nsAccessibleTreeWalker::GetLastChild() { - return GetChildBefore(mDOMNode, nsnull); + return GetChildBefore(mState.domNode, nsnull); } - -PRInt32 nsDOMTreeWalker::GetCount() +PRInt32 nsAccessibleTreeWalker::GetChildCount() { - - nsCOMPtr node(mDOMNode); - nsCOMPtr a(mAccessible); - - GetFirstChild(); - PRInt32 count = 0; - while(mDOMNode) - { - count++; - GetNextSibling(); - } - mDOMNode = node; - mAccessible = a; + if (NS_SUCCEEDED(GetFirstChild())) { + do { + ++count; // This loop always iterates at least once + } + while (NS_SUCCEEDED(GetNextSibling())); + } return count; } + /** - * If the DOM node's frame has and accessible or the DOMNode + * If the DOM node's frame has an accessible or the DOMNode * itself implements nsIAccessible return it. */ -PRBool nsDOMTreeWalker::GetAccessible() +PRBool nsAccessibleTreeWalker::GetAccessible() { - mAccessible = nsnull; + mState.accessible = nsnull; return (mAccService && - NS_SUCCEEDED(mAccService->GetAccessibleFor(mDOMNode, getter_AddRefs(mAccessible))) && - mAccessible); + NS_SUCCEEDED(mAccService->GetAccessibleFor(mState.domNode, getter_AddRefs(mState.accessible))) && + mState.accessible); } @@ -434,25 +435,10 @@ PRBool nsDOMTreeWalker::GetAccessible() //-------------------------`---------------------------- // construction //----------------------------------------------------- -nsAccessible::nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) +nsAccessible::nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): mDOMNode(aNode), mPresShell(aShell), mSiblingIndex(eSiblingsUninitialized) { NS_INIT_REFCNT(); - // get frame and node - mDOMNode = aNode; - mPresShell = aShell; - - nsCOMPtr document; - nsCOMPtr content(do_QueryInterface(mDOMNode)); - if (content) - content->GetDocument(*getter_AddRefs(document)); - if (document) { - nsCOMPtr ourGlobal; - document->GetScriptGlobalObject(getter_AddRefs(ourGlobal)); - nsCOMPtr ourWindow(do_QueryInterface(ourGlobal)); - if(ourWindow) - ourWindow->GetRootFocusController(getter_AddRefs(mFocusController)); - } #ifdef NS_DEBUG_X { nsCOMPtr shell(do_QueryReferent(aShell)); @@ -495,101 +481,101 @@ NS_IMETHODIMP nsAccessible::GetAccName(nsAWritableString& _retval) return NS_ERROR_FAILURE; } +NS_IMETHODIMP nsAccessible::CacheOptimizations(nsIAccessible *aParent, PRInt32 aSiblingIndex, nsIDOMNodeList *aSiblingList) +{ + if (aParent) + mParent = aParent; + mSiblingIndex = aSiblingIndex; + mSiblingList = aSiblingList; + return NS_OK; +} + NS_IMETHODIMP nsAccessible::GetAccParent(nsIAccessible ** aAccParent) { - nsCOMPtr context; - GetPresContext(context); - - nsDOMTreeWalker walker(mPresShell, mDOMNode); - if (walker.GetParent()) { - *aAccParent = walker.mAccessible; + if (mParent) { + *aAccParent = mParent; NS_ADDREF(*aAccParent); return NS_OK; } *aAccParent = nsnull; + nsAccessibleTreeWalker walker(mPresShell, mDOMNode, mSiblingIndex, mSiblingList); + if (NS_SUCCEEDED(walker.GetParent())) { + *aAccParent = mParent = walker.mState.accessible; + NS_ADDREF(*aAccParent); + } + return NS_OK; } /* readonly attribute nsIAccessible accNextSibling; */ NS_IMETHODIMP nsAccessible::GetAccNextSibling(nsIAccessible * *aAccNextSibling) { - nsDOMTreeWalker walker(mPresShell, mDOMNode); - - walker.GetNextSibling(); - - if (walker.mAccessible && walker.mDOMNode) - { - *aAccNextSibling = walker.mAccessible; - NS_ADDREF(*aAccNextSibling); - return NS_OK; - } - *aAccNextSibling = nsnull; + nsAccessibleTreeWalker walker(mPresShell, mDOMNode, mSiblingIndex, mSiblingList); + + if (NS_SUCCEEDED(walker.GetNextSibling())) { + *aAccNextSibling = walker.mState.accessible; + NS_ADDREF(*aAccNextSibling); + mSiblingList = walker.mState.siblingList; + (*aAccNextSibling)->CacheOptimizations(mParent, walker.mState.siblingIndex, mSiblingList); + } + return NS_OK; } /* readonly attribute nsIAccessible accPreviousSibling; */ NS_IMETHODIMP nsAccessible::GetAccPreviousSibling(nsIAccessible * *aAccPreviousSibling) { - // failed? Lets do some default behavior - nsDOMTreeWalker walker(mPresShell, mDOMNode); - walker.GetPreviousSibling(); - - if (walker.mAccessible && walker.mDOMNode) - { - *aAccPreviousSibling = walker.mAccessible; - NS_ADDREF(*aAccPreviousSibling); - return NS_OK; - } - *aAccPreviousSibling = nsnull; + nsAccessibleTreeWalker walker(mPresShell, mDOMNode, mSiblingIndex, mSiblingList); + if (NS_SUCCEEDED(walker.GetPreviousSibling())) { + *aAccPreviousSibling = walker.mState.accessible; + NS_ADDREF(*aAccPreviousSibling); + mSiblingList = walker.mState.siblingList; + (*aAccPreviousSibling)->CacheOptimizations(mParent, walker.mState.siblingIndex, mSiblingList); + } + return NS_OK; } /* readonly attribute nsIAccessible accFirstChild; */ NS_IMETHODIMP nsAccessible::GetAccFirstChild(nsIAccessible * *aAccFirstChild) { - nsDOMTreeWalker walker(mPresShell, mDOMNode); - walker.GetFirstChild(); - - if (walker.mAccessible && walker.mDOMNode) - { - *aAccFirstChild = walker.mAccessible; - NS_ADDREF(*aAccFirstChild); - return NS_OK; - } - *aAccFirstChild = nsnull; + nsAccessibleTreeWalker walker(mPresShell, mDOMNode, mSiblingIndex, mSiblingList); + if (NS_SUCCEEDED(walker.GetFirstChild())) { + *aAccFirstChild = walker.mState.accessible; + NS_ADDREF(*aAccFirstChild); + (*aAccFirstChild)->CacheOptimizations(this, walker.mState.siblingIndex, walker.mState.siblingList); + } + return NS_OK; } /* readonly attribute nsIAccessible accFirstChild; */ NS_IMETHODIMP nsAccessible::GetAccLastChild(nsIAccessible * *aAccLastChild) { - nsDOMTreeWalker walker(mPresShell, mDOMNode); - walker.GetLastChild(); - - if (walker.mAccessible && walker.mDOMNode) - { - *aAccLastChild = walker.mAccessible; - NS_ADDREF(*aAccLastChild); - return NS_OK; - } - *aAccLastChild = nsnull; + nsAccessibleTreeWalker walker(mPresShell, mDOMNode, mSiblingIndex, mSiblingList); + if (NS_SUCCEEDED(walker.GetLastChild())) { + *aAccLastChild = walker.mState.accessible; + NS_ADDREF(*aAccLastChild); + (*aAccLastChild)->CacheOptimizations(this, walker.mState.siblingIndex, walker.mState.siblingList); + } + return NS_OK; } /* readonly attribute long accChildCount; */ NS_IMETHODIMP nsAccessible::GetAccChildCount(PRInt32 *aAccChildCount) { - nsDOMTreeWalker walker(mPresShell, mDOMNode); - *aAccChildCount = walker.GetCount(); + nsAccessibleTreeWalker walker(mPresShell, mDOMNode, mSiblingIndex, mSiblingList); + *aAccChildCount = walker.GetChildCount(); return NS_OK; } @@ -669,6 +655,34 @@ PRBool nsAccessible::IsEntirelyVisible() return isVisible; } +NS_IMETHODIMP nsAccessible::GetFocusedElement(nsIDOMElement **aFocusedElement) +{ + nsCOMPtr focusController; + nsCOMPtr document; + nsCOMPtr content(do_QueryInterface(mDOMNode)); + if (content) + content->GetDocument(*getter_AddRefs(document)); + + if (document) { + nsCOMPtr ourGlobal; + document->GetScriptGlobalObject(getter_AddRefs(ourGlobal)); + nsCOMPtr ourWindow(do_QueryInterface(ourGlobal)); + if (ourWindow) + ourWindow->GetRootFocusController(getter_AddRefs(focusController)); + } + + if (focusController) { + nsCOMPtr focusedElement; + focusController->GetFocusedElement(getter_AddRefs(focusedElement)); + *aFocusedElement = focusedElement; + if (focusedElement) { + NS_ADDREF(*aFocusedElement); + return NS_OK; + } + } + return NS_ERROR_FAILURE; +} + /* readonly attribute wstring accState; */ NS_IMETHODIMP nsAccessible::GetAccState(PRUint32 *aAccState) { @@ -678,12 +692,9 @@ NS_IMETHODIMP nsAccessible::GetAccState(PRUint32 *aAccState) nsCOMPtr currElement(do_QueryInterface(mDOMNode)); if (currElement) { *aAccState |= STATE_FOCUSABLE; - if (mFocusController) { - nsCOMPtr focusedElement; - rv = mFocusController->GetFocusedElement(getter_AddRefs(focusedElement)); - if (NS_SUCCEEDED(rv) && focusedElement == currElement) - *aAccState |= STATE_FOCUSED; - } + nsCOMPtr focusedElement; + if (NS_SUCCEEDED(GetFocusedElement(getter_AddRefs(focusedElement))) && focusedElement == currElement) + *aAccState |= STATE_FOCUSED; } // Check if STATE_OFFSCREEN bitflag should be turned on for this object @@ -697,12 +708,9 @@ NS_IMETHODIMP nsAccessible::GetAccState(PRUint32 *aAccState) NS_IMETHODIMP nsAccessible::GetAccFocused(nsIAccessible * *aAccFocused) { nsCOMPtr focusedElement; - if (mFocusController) { - mFocusController->GetFocusedElement(getter_AddRefs(focusedElement)); - } - nsIFrame *frame = nsnull; - if (focusedElement) { + + if (NS_SUCCEEDED(GetFocusedElement(getter_AddRefs(focusedElement)))) { nsCOMPtr shell(do_QueryReferent(mPresShell)); if (!shell) { *aAccFocused = nsnull; @@ -752,7 +760,6 @@ NS_IMETHODIMP nsAccessible::AccGetAt(PRInt32 tx, PRInt32 ty, nsIAccessible **_re child = next; } - *_retval = this; NS_ADDREF(this); return NS_OK; @@ -769,23 +776,6 @@ NS_IMETHODIMP nsAccessible::AccGetDOMNode(nsIDOMNode **_retval) return NS_OK; } -nsresult nsAccessible::GetDocShellFromPS(nsIPresShell* aPresShell, nsIDocShell** aDocShell) -{ - *aDocShell = nsnull; - if (aPresShell) { - nsCOMPtr doc; - aPresShell->GetDocument(getter_AddRefs(doc)); - if (doc) { - nsCOMPtr scriptObj; - doc->GetScriptGlobalObject(getter_AddRefs(scriptObj)); - if (scriptObj) { - scriptObj->GetDocShell(aDocShell); - return *aDocShell != nsnull?NS_OK:NS_ERROR_FAILURE; - } - } - } - return NS_ERROR_FAILURE; -} //------------------------------------------------------- // This gets ref counted copies of the PresShell, PresContext, @@ -817,137 +807,6 @@ nsAccessible::GetDocShellObjects(nsIDocShell* aDocShell, //------------------------------------------------------- // -nsresult -nsAccessible::GetDocShells(nsIPresShell* aPresShell, - nsIDocShell** aDocShell, - nsIDocShell** aParentDocShell) -{ - NS_ENSURE_ARG_POINTER(aPresShell); - NS_ENSURE_ARG_POINTER(aDocShell); - NS_ENSURE_ARG_POINTER(aParentDocShell); - - *aDocShell = nsnull; - - // Start by finding our PresShell and from that - // we get our nsIDocShell in order to walk the DocShell tree - if (NS_SUCCEEDED(GetDocShellFromPS(aPresShell, aDocShell))) { - // Now that we have the DocShell QI - // it to a tree item to find it's parent - nsCOMPtr docShell = *aDocShell; - nsCOMPtr item(do_QueryInterface(docShell)); - if (item) { - nsCOMPtr itemParent; - item->GetParent(getter_AddRefs(itemParent)); - // QI to get the WebShell for the parent document - nsCOMPtr pDocShell(do_QueryInterface(itemParent)); - if (pDocShell) { - *aParentDocShell = pDocShell.get(); - NS_ADDREF(*aParentDocShell); - return NS_OK; - } - } - } - - NS_IF_RELEASE(*aDocShell); - return NS_ERROR_FAILURE; -} - -//------------------------------------------------------- -// -nsresult -nsAccessible::GetParentPresShellAndContent(nsIPresShell* aPresShell, - nsIPresShell** aParentPresShell, - nsIContent** aSubShellContent) -{ - NS_ENSURE_ARG_POINTER(aPresShell); - NS_ENSURE_ARG_POINTER(aParentPresShell); - NS_ENSURE_ARG_POINTER(aSubShellContent); - - *aParentPresShell = nsnull; - *aSubShellContent = nsnull; - - nsCOMPtr docShell; - nsCOMPtr parentDocShell; - if (NS_FAILED(GetDocShells(aPresShell, - getter_AddRefs(docShell), - getter_AddRefs(parentDocShell)))) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr parentPresContext; - nsCOMPtr parentRootContent; - if (NS_FAILED(GetDocShellObjects(parentDocShell, - aParentPresShell, - getter_AddRefs(parentPresContext), - getter_AddRefs(parentRootContent)))) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr webShell(do_QueryInterface(docShell)); - if (FindContentForWebShell(*aParentPresShell, parentRootContent, - webShell, aSubShellContent)) { - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - -PRBool -nsAccessible::FindContentForWebShell(nsIPresShell* aParentPresShell, - nsIContent* aParentContent, - nsIWebShell* aWebShell, - nsIContent** aFoundContent) -{ - NS_ASSERTION(aWebShell, "Pointer is null!"); - NS_ASSERTION(aParentPresShell, "Pointer is null!"); - NS_ASSERTION(aParentContent, "Pointer is null!"); - NS_ASSERTION(aFoundContent, "Pointer is null!"); - - nsCOMPtr iFrame(do_QueryInterface(aParentContent)); - nsCOMPtr frame(do_QueryInterface(aParentContent)); -#ifdef NS_DEBUG_X - { - printf("** FindContent - Content %p",aParentContent); - nsIFrame* frame; - aParentPresShell->GetPrimaryFrameFor(aParentContent, &frame); - if (frame) { - char * name; - GetNameForFrame(frame, &name); - printf(" [%s]", name?name:""); - if (name) nsMemory::Free(name); - } - printf("\n"); - } -#endif - - if (iFrame || frame) { - //printf("********* Found IFrame %p\n", aParentContent); - nsCOMPtr supps; - aParentPresShell->GetSubShellFor(aParentContent, getter_AddRefs(supps)); - if (supps) { - nsCOMPtr webShell(do_QueryInterface(supps)); - //printf("********* Checking %p == %p (parent)\n", webShell.get(), aWebShell); - if (webShell.get() == aWebShell) { - //printf("********* Found WebShell %p \n", aWebShell); - *aFoundContent = aParentContent; - NS_ADDREF(aParentContent); - return PR_TRUE; - } - } - } - - // walk children content - PRInt32 count; - aParentContent->ChildCount(count); - for (PRInt32 i=0;iChildAt(i, child); - if (FindContentForWebShell(aParentPresShell, child, aWebShell, aFoundContent)) { - return PR_TRUE; - } - } - return PR_FALSE; -} // Calculate a frame's position in screen coordinates nsresult @@ -1177,6 +1036,10 @@ NS_IMETHODIMP nsAccessible::AccGetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, nsRect unionRectTwips; nsIFrame* aRelativeFrame = nsnull; GetBounds(unionRectTwips, &aRelativeFrame); // Unions up all primary frames for this node and all siblings after it + if (!aRelativeFrame) { + *x = *y = *width = *height = 0; + return NS_ERROR_FAILURE; + } *x = NSTwipsToIntPixels(unionRectTwips.x, t2p); *y = NSTwipsToIntPixels(unionRectTwips.y, t2p); diff --git a/mozilla/accessible/src/base/nsAccessible.h b/mozilla/accessible/src/base/nsAccessible.h index 41a3cdf5835..44ed93d349f 100644 --- a/mozilla/accessible/src/base/nsAccessible.h +++ b/mozilla/accessible/src/base/nsAccessible.h @@ -50,6 +50,8 @@ #include "nsPoint.h" #include "nsRect.h" #include "nsWeakReference.h" +#include "nsIDOMNodeList.h" +#include "nsIBindingManager.h" #define ACCESSIBLE_BUNDLE_URL "chrome://global/locale/accessible.properties" @@ -58,6 +60,8 @@ class nsIDocShell; class nsIFrame; class nsIWebShell; +enum { eSiblingsUninitialized = -1, eSiblingsWalkNormalDOM = -2}; // Used in sibling index field as flags + class nsAccessible : public nsGenericAccessible { public: @@ -84,7 +88,6 @@ public: virtual void GetListAtomForFrame(nsIFrame* aFrame, nsIAtom*& aList) { aList = nsnull; } // Helper Routines for Sub-Docs - static nsresult GetDocShellFromPS(nsIPresShell* aPresShell, nsIDocShell** aDocShell); static nsresult GetDocShellObjects(nsIDocShell* aDocShell, nsIPresShell** aPresShell, nsIPresContext** aPresContext, @@ -122,11 +125,15 @@ protected: NS_IMETHOD AppendFlatStringFromSubtree(nsIContent *aContent, nsAWritableString *aFlatString); NS_IMETHOD AppendFlatStringFromContentNode(nsIContent *aContent, nsAWritableString *aFlatString); NS_IMETHOD AppendStringWithSpaces(nsAWritableString *aFlatString, nsAReadableString& textEquivalent); + NS_IMETHOD GetFocusedElement(nsIDOMElement **aFocusedElement); + NS_IMETHOD CacheOptimizations(nsIAccessible *aParent, PRInt32 aSiblingIndex, nsIDOMNodeList *aSiblingList); // Data Members nsCOMPtr mDOMNode; nsCOMPtr mPresShell; - nsCOMPtr mFocusController; + nsCOMPtr mParent; + nsCOMPtr mSiblingList; // If some of our computed siblings are anonymous content nodes, cache node list + PRInt32 mSiblingIndex; // Cache where we are in list of kids that we got from nsIBindingManager::GetContentList(parentContent) }; #endif diff --git a/mozilla/accessible/src/base/nsGenericAccessible.cpp b/mozilla/accessible/src/base/nsGenericAccessible.cpp index 86805d4b76d..5207bd3f657 100644 --- a/mozilla/accessible/src/base/nsGenericAccessible.cpp +++ b/mozilla/accessible/src/base/nsGenericAccessible.cpp @@ -237,4 +237,7 @@ NS_IMETHODIMP nsGenericAccessible::AccGetDOMNode(nsIDOMNode **_retval) return NS_ERROR_NOT_IMPLEMENTED; } - +NS_IMETHODIMP nsGenericAccessible::CacheOptimizations(nsIAccessible *aParent, PRInt32 aSiblingIndex, nsIDOMNodeList *aSiblingList) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/mozilla/accessible/src/base/nsRootAccessible.cpp b/mozilla/accessible/src/base/nsRootAccessible.cpp index 0c96a1e009c..1ead4178766 100644 --- a/mozilla/accessible/src/base/nsRootAccessible.cpp +++ b/mozilla/accessible/src/base/nsRootAccessible.cpp @@ -73,6 +73,7 @@ #include "nsIWebProgress.h" #include "nsCURILoader.h" #include "nsIInterfaceRequestorUtils.h" +#include "nsIScriptGlobalObject.h" NS_INTERFACE_MAP_BEGIN(nsRootAccessible) @@ -496,7 +497,7 @@ NS_IMETHODIMP nsDocAccessibleMixin::GetURL(nsAWritableString& aURL) NS_ASSERTION(presShell,"Shell is gone!!! What are we doing here?"); nsCOMPtr docShell; - nsAccessible::GetDocShellFromPS(presShell, getter_AddRefs(docShell)); + GetDocShellFromPS(presShell, getter_AddRefs(docShell)); nsCOMPtr webNav(do_GetInterface(docShell)); nsXPIDLCString theURL; @@ -565,3 +566,21 @@ NS_IMETHODIMP nsDocAccessibleMixin::GetDocument(nsIDocument **doc) } +NS_IMETHODIMP nsDocAccessibleMixin::GetDocShellFromPS(nsIPresShell* aPresShell, nsIDocShell** aDocShell) +{ + *aDocShell = nsnull; + if (aPresShell) { + nsCOMPtr doc; + aPresShell->GetDocument(getter_AddRefs(doc)); + if (doc) { + nsCOMPtr scriptObj; + doc->GetScriptGlobalObject(getter_AddRefs(scriptObj)); + if (scriptObj) { + scriptObj->GetDocShell(aDocShell); + if (*aDocShell) + return NS_OK; + } + } + } + return NS_ERROR_FAILURE; +} diff --git a/mozilla/accessible/src/base/nsRootAccessible.h b/mozilla/accessible/src/base/nsRootAccessible.h index 6d3acba2138..f194b938cdd 100644 --- a/mozilla/accessible/src/base/nsRootAccessible.h +++ b/mozilla/accessible/src/base/nsRootAccessible.h @@ -59,10 +59,11 @@ class nsDocAccessibleMixin nsDocAccessibleMixin(nsIDocument *doc); nsDocAccessibleMixin(nsIWeakReference *aShell); virtual ~nsDocAccessibleMixin(); - + NS_DECL_NSIACCESSIBLEDOCUMENT protected: + NS_IMETHOD GetDocShellFromPS(nsIPresShell* aPresShell, nsIDocShell** aDocShell); PRBool mTopLevelDocument; nsCOMPtr mDocument; }; diff --git a/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.cpp b/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.cpp index bc3ce7c96eb..57aff07d098 100644 --- a/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.cpp +++ b/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.cpp @@ -40,16 +40,9 @@ #include "nsCOMPtr.h" #include "nsIDocument.h" #include "nsIPresShell.h" -#include "nsIPresContext.h" #include "nsIContent.h" #include "nsIFrame.h" -#include "nsIDocShell.h" -#include "nsIWebShell.h" -#include "nsIDocShellTreeItem.h" -#include "nsIXULDocument.h" #include "nsIDOMDocument.h" -#include "nsIDOMDocumentType.h" -#include "nsINameSpaceManager.h" #include "nsReadableUtils.h" NS_INTERFACE_MAP_BEGIN(nsHTMLIFrameRootAccessible) @@ -162,9 +155,8 @@ NS_IMETHODIMP nsHTMLIFrameAccessible::GetDocument(nsIDocument **doc) // construction //----------------------------------------------------- nsHTMLIFrameRootAccessible::nsHTMLIFrameRootAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): - nsRootAccessible(aShell) + mOuterNode(aNode), nsRootAccessible(aShell) { - mRealDOMNode = aNode; } //----------------------------------------------------- @@ -174,113 +166,42 @@ nsHTMLIFrameRootAccessible::~nsHTMLIFrameRootAccessible() { } +nsHTMLIFrameRootAccessible::Init() +{ + if (!mOuterAccessible) { + nsCOMPtr domDoc; + mOuterNode->GetOwnerDocument(getter_AddRefs(domDoc)); + nsCOMPtr doc(do_QueryInterface(domDoc)); + if (doc) { + nsCOMPtr parentShell; + doc->GetShellAt(0, getter_AddRefs(parentShell)); + if (parentShell) { + nsCOMPtr content(do_QueryInterface(mOuterNode)); + nsIFrame* frame = nsnull; + parentShell->GetPrimaryFrameFor(content, &frame); + NS_ASSERTION(frame, "No outer frame."); + frame->GetAccessible(getter_AddRefs(mOuterAccessible)); + NS_ASSERTION(mOuterAccessible, "Something's wrong - there's no accessible for the outer parent of this frame."); + } + } + } +} /* readonly attribute nsIAccessible accParent; */ NS_IMETHODIMP nsHTMLIFrameRootAccessible::GetAccParent(nsIAccessible * *_retval) { - nsCOMPtr accessible; - if (NS_SUCCEEDED(GetHTMLIFrameAccessible(getter_AddRefs(accessible)))) - return accessible->GetAccParent(_retval); - - *_retval = nsnull; - return NS_OK; + Init(); + return mOuterAccessible->GetAccParent(_retval); } /* nsIAccessible getAccNextSibling (); */ NS_IMETHODIMP nsHTMLIFrameRootAccessible::GetAccNextSibling(nsIAccessible **_retval) { - nsCOMPtr accessible; - - if (NS_SUCCEEDED(GetHTMLIFrameAccessible(getter_AddRefs(accessible)))) - return accessible->GetAccNextSibling(_retval); - - *_retval = nsnull; - return NS_ERROR_FAILURE; + Init(); + return mOuterAccessible->GetAccNextSibling(_retval); } - /* nsIAccessible getAccPreviousSibling (); */ NS_IMETHODIMP nsHTMLIFrameRootAccessible::GetAccPreviousSibling(nsIAccessible **_retval) { - nsCOMPtr accessible; - - if (NS_SUCCEEDED(GetHTMLIFrameAccessible(getter_AddRefs(accessible)))) - return accessible->GetAccPreviousSibling(_retval); - - *_retval = nsnull; - return NS_ERROR_FAILURE; + Init(); + return mOuterAccessible->GetAccPreviousSibling(_retval); } - -NS_IMETHODIMP nsHTMLIFrameRootAccessible::GetHTMLIFrameAccessible(nsIAccessible** aAcc) -{ - // Start by finding our PresShell and from that - // we get our nsIDocShell in order to walk the DocShell tree - nsCOMPtr presShell(do_QueryReferent(mPresShell)); - if (!presShell) { - *aAcc = nsnull; - return NS_ERROR_FAILURE; - } - - nsCOMPtr docShell; - if (NS_SUCCEEDED(GetDocShellFromPS(presShell, getter_AddRefs(docShell)))) { - // Now that we have the DocShell QI - // it to a tree item to find it's parent - nsCOMPtr item(do_QueryInterface(docShell)); - if (item) { - nsCOMPtr itemParent; - item->GetParent(getter_AddRefs(itemParent)); - // QI to get the WebShell for the parent document - nsCOMPtr parentDocShell(do_QueryInterface(itemParent)); - if (parentDocShell) { - // Get the PresShell/Content and - // Root Content Node of the parent document - nsCOMPtr parentPresShell; - nsCOMPtr parentPresContext; - nsCOMPtr rootContent; - if (NS_SUCCEEDED(GetDocShellObjects(parentDocShell, - getter_AddRefs(parentPresShell), - getter_AddRefs(parentPresContext), - getter_AddRefs(rootContent)))) { - // QI the DocShell (of this sub-doc) to a webshell - nsCOMPtr webShell(do_QueryInterface(docShell)); - if (webShell && parentPresShell && parentPresContext && rootContent) { - // Now, find the Content in the parent document - // that represents this sub-doc, - // we do that matching webshells - nsCOMPtr content; - if (FindContentForWebShell(parentPresShell, - rootContent, - webShell, - getter_AddRefs(content))) { - // OK, we found the content node in the parent doc - // that corresponds to this sub-doc - // Get the frame for that content - nsCOMPtr wr = do_GetWeakReference(parentPresShell); - nsIFrame* frame = nsnull; - parentPresShell->GetPrimaryFrameFor(content, &frame); -#ifdef NS_DEBUG_X - printf("** Found: Con:%p Fr:%p", content, frame); - char * name; - if (GetNameForFrame(frame, &name)) { - printf(" Name:[%s]", name); - nsMemory::Free(name); - } - printf("\n"); -#endif - - - nsCOMPtr node(do_QueryInterface(content)); - nsCOMPtr acc(do_QueryInterface(frame)); - - *aAcc = acc; - NS_IF_ADDREF(*aAcc); - - return NS_OK; - } - } - } - } - } - } - - return NS_ERROR_FAILURE; -} - diff --git a/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.h b/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.h index 44978c5ab5b..c566bae09bf 100644 --- a/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.h +++ b/mozilla/accessible/src/html/nsHTMLIFrameRootAccessible.h @@ -87,8 +87,14 @@ class nsHTMLIFrameRootAccessible : public nsRootAccessible NS_IMETHOD GetAccPreviousSibling(nsIAccessible **_retval); protected: - NS_IMETHOD GetHTMLIFrameAccessible(nsIAccessible** aAcc); - nsCOMPtr mRealDOMNode; + Init(); + + // In these variable names, "outer" relates to the nsHTMLIFrameAccessible, as opposed to the + // nsHTMLIFrameRootAccessible which is "inner". + // The outer node is a or