mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 573469 - part3, speed up HasRelatedContent, r=davidb, sr=neil, a=final+
This commit is contained in:
parent
cff1891508
commit
3f6f6cc71f
@ -844,15 +844,11 @@ static PRBool HasRelatedContent(nsIContent *aContent)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIAtom *relationAttrs[] = {nsAccessibilityAtoms::aria_labelledby,
|
||||
nsAccessibilityAtoms::aria_describedby,
|
||||
nsAccessibilityAtoms::aria_owns,
|
||||
nsAccessibilityAtoms::aria_controls,
|
||||
nsAccessibilityAtoms::aria_flowto};
|
||||
if (nsCoreUtils::FindNeighbourPointingToNode(aContent, relationAttrs,
|
||||
NS_ARRAY_LENGTH(relationAttrs))) {
|
||||
// If the given ID is referred by relation attribute then create an accessible
|
||||
// for it. Take care of HTML elements only for now.
|
||||
if (aContent->IsHTML() &&
|
||||
nsAccUtils::GetDocAccessibleFor(aContent)->IsDependentID(id))
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsIContent *ancestorContent = aContent;
|
||||
while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
|
||||
|
@ -3190,8 +3190,17 @@ nsAccessible::EnsureChildren()
|
||||
|
||||
// State is embedded children until text leaf accessible is appended.
|
||||
mChildrenFlags = eEmbeddedChildren; // Prevent reentry
|
||||
|
||||
// Notify the document about caching status.
|
||||
nsDocAccessible* document = GetDocAccessible();
|
||||
if (document)
|
||||
document->NotifyOfCachingStart(this);
|
||||
|
||||
CacheChildren();
|
||||
|
||||
if (document)
|
||||
document->NotifyOfCachingEnd(this);
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1152,25 +1152,29 @@ IDRefsIterator::NextElem()
|
||||
if (id.IsEmpty())
|
||||
break;
|
||||
|
||||
if (mXBLDocument) {
|
||||
// If content is anonymous subtree then use "anonid" attribute to get
|
||||
// elements, otherwise search elements in DOM by ID attribute.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> refElm;
|
||||
mXBLDocument->GetAnonymousElementByAttribute(mBindingParent,
|
||||
NS_LITERAL_STRING("anonid"),
|
||||
id,
|
||||
getter_AddRefs(refElm));
|
||||
nsCOMPtr<nsIContent> refContent = do_QueryInterface(refElm);
|
||||
if (refContent)
|
||||
return refContent;
|
||||
|
||||
} else {
|
||||
nsIContent* refContent = mDocument->GetElementById(id);
|
||||
if (refContent)
|
||||
return refContent;
|
||||
}
|
||||
nsIContent* refContent = GetElem(id);
|
||||
if (refContent)
|
||||
return refContent;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
IDRefsIterator::GetElem(const nsDependentSubstring& aID)
|
||||
{
|
||||
if (mXBLDocument) {
|
||||
// If content is anonymous subtree then use "anonid" attribute to get
|
||||
// elements, otherwise search elements in DOM by ID attribute.
|
||||
|
||||
nsCOMPtr<nsIDOMElement> refElm;
|
||||
mXBLDocument->GetAnonymousElementByAttribute(mBindingParent,
|
||||
NS_LITERAL_STRING("anonid"),
|
||||
aID,
|
||||
getter_AddRefs(refElm));
|
||||
nsCOMPtr<nsIContent> refContent = do_QueryInterface(refElm);
|
||||
return refContent;
|
||||
}
|
||||
|
||||
return mDocument->GetElementById(aID);
|
||||
}
|
||||
|
@ -525,6 +525,11 @@ public:
|
||||
*/
|
||||
nsIContent* NextElem();
|
||||
|
||||
/**
|
||||
* Return the element with the given ID.
|
||||
*/
|
||||
nsIContent* GetElem(const nsDependentSubstring& aID);
|
||||
|
||||
private:
|
||||
nsString mIDs;
|
||||
nsAString::index_type mCurrIdx;
|
||||
|
@ -103,7 +103,8 @@ nsDocAccessible::
|
||||
nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
|
||||
nsIWeakReference *aShell) :
|
||||
nsHyperTextAccessibleWrap(aRootContent, aShell),
|
||||
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE)
|
||||
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE),
|
||||
mCacheRoot(nsnull), mIsPostCacheProcessing(PR_FALSE)
|
||||
{
|
||||
mDependentIDsHash.Init();
|
||||
// XXX aaronl should we use an algorithm for the initial cache size?
|
||||
@ -1588,6 +1589,39 @@ nsDocAccessible::RecreateAccessible(nsINode* aNode)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::NotifyOfCachingStart(nsAccessible* aAccessible)
|
||||
{
|
||||
if (!mCacheRoot)
|
||||
mCacheRoot = aAccessible;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::NotifyOfCachingEnd(nsAccessible* aAccessible)
|
||||
{
|
||||
if (mCacheRoot == aAccessible && !mIsPostCacheProcessing) {
|
||||
// Allow invalidation list insertions while container children are recached.
|
||||
mIsPostCacheProcessing = PR_TRUE;
|
||||
|
||||
// Invalidate children of container accessible for each element in
|
||||
// invalidation list.
|
||||
for (PRUint32 idx = 0; idx < mInvalidationList.Length(); idx++) {
|
||||
nsIContent* content = mInvalidationList[idx];
|
||||
nsAccessible* container =
|
||||
GetAccService()->GetCachedContainerAccessible(content);
|
||||
container->InvalidateChildren();
|
||||
|
||||
// Make sure we keep children updated. While we're inside of caching loop
|
||||
// then we must exist it with cached children.
|
||||
container->EnsureChildren();
|
||||
}
|
||||
mInvalidationList.Clear();
|
||||
|
||||
mCacheRoot = nsnull;
|
||||
mIsPostCacheProcessing = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected members
|
||||
|
||||
@ -1620,8 +1654,18 @@ nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
|
||||
if (providers) {
|
||||
AttrRelProvider* provider =
|
||||
new AttrRelProvider(relAttr, aRelProvider->GetContent());
|
||||
if (provider)
|
||||
if (provider) {
|
||||
providers->AppendElement(provider);
|
||||
|
||||
// We've got here during the children caching. If the referenced
|
||||
// content is not accessible then store it to pend its container
|
||||
// children invalidation (this happens immediately after the caching
|
||||
// is finished).
|
||||
nsIContent* dependentContent = iter.GetElem(id);
|
||||
if (dependentContent && !GetCachedAccessible(dependentContent)) {
|
||||
mInvalidationList.AppendElement(dependentContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,6 +212,16 @@ public:
|
||||
*/
|
||||
nsAccessible* GetCachedAccessibleByUniqueIDInSubtree(void* aUniqueID);
|
||||
|
||||
/**
|
||||
* Return true if the given ID is referred by relation attribute.
|
||||
*
|
||||
* @note Different elements may share the same ID if they are hosted inside
|
||||
* XBL bindings. Be careful the result of this method may be senseless
|
||||
* while it's called for XUL elements (where XBL is used widely).
|
||||
*/
|
||||
PRBool IsDependentID(const nsAString& aID) const
|
||||
{ return mDependentIDsHash.Get(aID, nsnull); }
|
||||
|
||||
/**
|
||||
* Initialize the newly created accessible and put it into document caches.
|
||||
*
|
||||
@ -243,6 +253,17 @@ public:
|
||||
*/
|
||||
void RecreateAccessible(nsINode* aNode);
|
||||
|
||||
/**
|
||||
* Used to notify the document that the accessible caching is started or
|
||||
* finished.
|
||||
*
|
||||
* While children are cached we may encounter the case there's no accessible
|
||||
* for referred content by related accessible. Keep the caching root and
|
||||
* these related nodes to invalidate their containers after root caching.
|
||||
*/
|
||||
void NotifyOfCachingStart(nsAccessible* aAccessible);
|
||||
void NotifyOfCachingEnd(nsAccessible* aAccessible);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||
@ -409,6 +430,17 @@ protected:
|
||||
nsClassHashtable<nsStringHashKey, AttrRelProviderArray> mDependentIDsHash;
|
||||
|
||||
friend class RelatedAccIterator;
|
||||
|
||||
/**
|
||||
* Used for our caching algorithm. We store the root of the tree that needs
|
||||
* caching, the list of nodes that should be invalidated, and whether we are
|
||||
* processing the invalidation list.
|
||||
*
|
||||
* @see NotifyOfCachingStart/NotifyOfCachingEnd
|
||||
*/
|
||||
nsAccessible* mCacheRoot;
|
||||
nsTArray<nsIContent*> mInvalidationList;
|
||||
PRBool mIsPostCacheProcessing;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
|
||||
|
Loading…
Reference in New Issue
Block a user