diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 2b9ed7b0a8b..fa55ada34e6 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -559,15 +559,6 @@ nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell, document->RecreateAccessible(aContent); } -// nsAccessibilityService protected -nsAccessible * -nsAccessibilityService::GetCachedAccessible(nsINode *aNode, - nsIWeakReference *aWeakShell) -{ - nsDocAccessible *docAccessible = GetDocAccessible(aNode->GetOwnerDoc()); - return docAccessible ? docAccessible->GetCachedAccessible(aNode) : nsnull; -} - //////////////////////////////////////////////////////////////////////////////// // nsIAccessibleRetrieval @@ -783,7 +774,7 @@ nsAccessibilityService::GetAccessibleInShell(nsINode* aNode, return nsnull; nsCOMPtr weakShell(do_GetWeakReference(aPresShell)); - return GetAccessibleByRule(aNode, weakShell, eGetAccForNode); + return GetAccessibleInWeakShell(aNode, weakShell); } //////////////////////////////////////////////////////////////////////////////// @@ -792,33 +783,20 @@ nsAccessibilityService::GetAccessibleInShell(nsINode* aNode, nsAccessible* nsAccessibilityService::GetAccessible(nsINode* aNode) { - if (aNode) { - nsCOMPtr weakShell(nsCoreUtils::GetWeakShellFor(aNode)); - if (weakShell) - return GetAccessibleByRule(aNode, weakShell, eGetAccForNode); - } - return nsnull; + nsDocAccessible* document = GetDocAccessible(aNode->GetOwnerDoc()); + return document ? document->GetCachedAccessible(aNode) : nsnull; } nsAccessible* -nsAccessibilityService::GetCachedAccessibleOrContainer(nsINode* aNode) +nsAccessibilityService::GetAccessibleOrContainer(nsINode* aNode, + nsIWeakReference* aWeakShell) { - if (!aNode) + if (!aNode || !aNode->IsInDoc()) return nsnull; - nsIDocument *document = aNode->GetCurrentDoc(); - if (!document) - return nsnull; - - nsIPresShell *presShell = document->GetShell(); - if (!presShell) - return nsnull; - - nsINode *currNode = aNode; - nsCOMPtr weakShell(do_GetWeakReference(presShell)); - - nsAccessible *accessible = nsnull; - while (!(accessible = GetCachedAccessible(currNode, weakShell)) && + nsINode* currNode = aNode; + nsAccessible* accessible = nsnull; + while (!(accessible = GetAccessibleInWeakShell(currNode, aWeakShell)) && (currNode = currNode->GetNodeParent())); return accessible; @@ -861,7 +839,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode, *aIsSubtreeHidden = false; // Check to see if we already have an accessible for this node in the cache. - nsAccessible *cachedAccessible = GetCachedAccessible(aNode, aWeakShell); + nsAccessible* cachedAccessible = GetAccessibleInWeakShell(aNode, aWeakShell); if (cachedAccessible) { NS_ADDREF(cachedAccessible); return cachedAccessible; @@ -1237,69 +1215,6 @@ nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent) nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_relevant); } -nsAccessible* -nsAccessibilityService::GetAccessibleByRule(nsINode* aNode, - nsIWeakReference* aWeakShell, - EWhatAccToGet aWhatToGet) -{ - if (!aNode || !aWeakShell) - return nsnull; - - if (aWhatToGet & eGetAccForNode) { - nsAccessible* cachedAcc = GetCachedAccessible(aNode, aWeakShell); - if (cachedAcc && (cachedAcc->IsBoundToParent() || cachedAcc->IsDocument())) - return cachedAcc; - } - - // Go up looking for the nearest accessible container having cached children. - nsTArray nodes; - - nsINode* node = aNode; - nsAccessible* cachedAcc = nsnull; - while ((node = node->GetNodeParent())) { - cachedAcc = GetCachedAccessible(node, aWeakShell); - if (cachedAcc && cachedAcc->IsBoundToParent()) - break; - - nodes.AppendElement(node); - } - - // Node is not in accessible document. - if (!cachedAcc) - return nsnull; - - // If children of the cached accessible weren't initialized then go down to - // the given node and create accessible tree. - nsAccessible* containerAcc = cachedAcc; - if (!cachedAcc->AreChildrenCached()) { - cachedAcc->EnsureChildren(); - for (PRInt32 idx = nodes.Length() - 1; idx >= 0; idx--) { - cachedAcc = GetCachedAccessible(nodes[idx], aWeakShell); - if (cachedAcc) { - cachedAcc->EnsureChildren(); - containerAcc = cachedAcc; - } - } - } - - // If the given node is accessible then it should be cached at this point. - // Exception is an area element because area and imagemap nodes aren't in - // the same parent chain. - cachedAcc = GetCachedAccessible(aNode, aWeakShell); - if (!cachedAcc && aNode->IsElement()) { - nsIFrame* frame = aNode->AsElement()->GetPrimaryFrame(); - if (frame && frame->GetContent() != aNode) - cachedAcc = GetAreaAccessible(frame, aNode, aWeakShell, &containerAcc); - } - - if ((aWhatToGet & eGetAccForNode) && cachedAcc) - return cachedAcc; - else if (aWhatToGet & eGetAccForContainer) - return containerAcc; - - return nsnull; -} - nsAccessible* nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame, nsINode* aAreaNode, @@ -1317,8 +1232,8 @@ nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame, // Try to get image map accessible from the global cache or create it // if failed. - nsRefPtr image = GetCachedAccessible(aImageFrame->GetContent(), - aWeakShell); + nsRefPtr image = + GetAccessibleInWeakShell(aImageFrame->GetContent(), aWeakShell); if (!image) { image = CreateHTMLImageAccessible(aImageFrame->GetContent(), aImageFrame->PresContext()->PresShell()); @@ -1341,7 +1256,7 @@ nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame, // that they should be available in global cache. image->EnsureChildren(); - return GetCachedAccessible(aAreaNode, aWeakShell); + return GetAccessibleInWeakShell(aAreaNode, aWeakShell); } already_AddRefed diff --git a/accessible/src/base/nsAccessibilityService.h b/accessible/src/base/nsAccessibilityService.h index 137d5362192..4f156c6f0af 100644 --- a/accessible/src/base/nsAccessibilityService.h +++ b/accessible/src/base/nsAccessibilityService.h @@ -163,57 +163,27 @@ public: inline nsAccessible* GetAccessibleInWeakShell(nsINode* aNode, nsIWeakReference* aWeakShell) { - return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNode); + // XXX: weak shell is ignored until multiple shell documents are supported. + return GetAccessible(aNode); } /** * Return an accessible for the given DOM node or container accessible if * the node is not accessible. */ - inline nsAccessible* GetAccessibleOrContainer(nsINode* aNode, - nsIWeakReference* aWeakShell) - { - return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNodeOrContainer); - } + nsAccessible* GetAccessibleOrContainer(nsINode* aNode, + nsIWeakReference* aWeakShell); /** * Return a container accessible for the given DOM node. */ inline nsAccessible* GetContainerAccessible(nsINode* aNode, nsIWeakReference* aWeakShell) - { - return GetAccessibleByRule(aNode, aWeakShell, eGetAccForContainer); - } - - /** - * Return cached accessible for the given DOM node or cached container - * accessible if there's no cached accessible for the given node. - */ - nsAccessible* GetCachedAccessibleOrContainer(nsINode* aNode); - - /** - * Return the first cached accessible parent of a DOM node. - * - * @param aDOMNode [in] the DOM node to get an accessible for - */ - inline nsAccessible* GetCachedContainerAccessible(nsINode *aNode) { return aNode ? - GetCachedAccessibleOrContainer(aNode->GetNodeParent()) : nsnull; + GetAccessibleOrContainer(aNode->GetNodeParent(), aWeakShell) : nsnull; } -protected: - /** - * Return an accessible for the DOM node in the given presentation shell if - * the accessible already exists, otherwise null. - * - * @param aNode [in] the DOM node to get an access node for - * @param aPresShell [in] the presentation shell which contains layout info - * for the DOM node - */ - nsAccessible *GetCachedAccessible(nsINode *aNode, - nsIWeakReference *aShell); - private: // nsAccessibilityService creation is controlled by friend // NS_GetAccessibilityService, keep constructors private. @@ -232,19 +202,6 @@ private: */ void Shutdown(); - enum EWhatAccToGet { - eGetAccForNode = 0x1, - eGetAccForContainer = 0x2, - eGetAccForNodeOrContainer = eGetAccForNode | eGetAccForContainer - }; - - /** - * Return accessible or accessible container for the given node in presshell. - */ - nsAccessible* GetAccessibleByRule(nsINode* aNode, - nsIWeakReference* aWeakShell, - EWhatAccToGet aWhatToGet); - /** * Return accessible for HTML area element associated with an image map. * diff --git a/accessible/src/base/nsAccessible.h b/accessible/src/base/nsAccessible.h index 034b522c391..651115f2d5e 100644 --- a/accessible/src/base/nsAccessible.h +++ b/accessible/src/base/nsAccessible.h @@ -225,6 +225,15 @@ public: */ virtual void SetRoleMapEntry(nsRoleMapEntry *aRoleMapEntry); + /** + * Update the children cache. + */ + inline bool UpdateChildren() + { + InvalidateChildren(); + return EnsureChildren(); + } + /** * Cache children if necessary. Return true if the accessible is defunct. */ diff --git a/accessible/src/base/nsDocAccessible.cpp b/accessible/src/base/nsDocAccessible.cpp index e1527d633ac..aac9bbc4de3 100644 --- a/accessible/src/base/nsDocAccessible.cpp +++ b/accessible/src/base/nsDocAccessible.cpp @@ -1390,7 +1390,7 @@ nsDocAccessible::ContentInserted(nsIContent* aContainerNode, // Update the whole tree of this document accessible when the container is // null (document element is inserted or removed). nsAccessible* container = aContainerNode ? - GetAccService()->GetCachedAccessibleOrContainer(aContainerNode) : + GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) : this; mNotificationController->ScheduleContentInsertion(container, @@ -1406,7 +1406,7 @@ nsDocAccessible::ContentRemoved(nsIContent* aContainerNode, // Update the whole tree of this document accessible when the container is // null (document element is removed). nsAccessible* container = aContainerNode ? - GetAccService()->GetCachedAccessibleOrContainer(aContainerNode) : + GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) : this; UpdateTree(container, aChildNode, PR_FALSE); @@ -1452,7 +1452,7 @@ nsDocAccessible::RecreateAccessible(nsINode* aNode) } // Get new accessible and fire show event. - parent->InvalidateChildren(); + parent->UpdateChildren(); nsAccessible* newAccessible = GetAccService()->GetAccessibleInWeakShell(aNode, mWeakShell); @@ -1492,12 +1492,11 @@ nsDocAccessible::NotifyOfCachingEnd(nsAccessible* aAccessible) for (PRUint32 idx = 0; idx < mInvalidationList.Length(); idx++) { nsIContent* content = mInvalidationList[idx]; nsAccessible* container = - GetAccService()->GetCachedContainerAccessible(content); - container->InvalidateChildren(); + GetAccService()->GetContainerAccessible(content, mWeakShell); // Make sure we keep children updated. While we're inside of caching loop // then we must exist it with cached children. - container->EnsureChildren(); + container->UpdateChildren(); } mInvalidationList.Clear(); @@ -1860,16 +1859,14 @@ nsDocAccessible::ProcessContentInserted(nsAccessible* aContainer, // accessibles into accessible tree. We need to invalidate children even // there's no inserted accessibles in the end because accessible children // are created while parent recaches child accessibles. - aContainer->InvalidateChildren(); + aContainer->UpdateChildren(); // The container might be changed, for example, because of the subsequent // overlapping content insertion (i.e. other content was inserted between this // inserted content and its container or the content was reinserted into // different container of unrelated part of tree). These cases result in // double processing, however generated events are coalesced and we don't - // harm an AT. On the another hand container can be different because direct - // container wasn't cached yet when we handled content insertion notification - // and therefore we can't ignore the case when container has been changed. + // harm an AT. // Theoretically the element might be not in tree at all at this point what // means there's no container. for (PRUint32 idx = 0; idx < aInsertedContent->Length(); idx++) { @@ -1945,9 +1942,7 @@ nsDocAccessible::UpdateTreeInternal(nsAccessible* aContainer, if (aIsInsert && !node->GetPrimaryFrame()) continue; - nsAccessible* accessible = aIsInsert ? - GetAccService()->GetAccessibleInWeakShell(node, mWeakShell) : - GetCachedAccessible(node); + nsAccessible* accessible = GetCachedAccessible(node); if (!accessible) { updateFlags |= UpdateTreeInternal(aContainer, node->GetFirstChild(),