mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 1249730 - make TreeWalker bi-directional, r=yzen
This commit is contained in:
parent
a7ff33a68b
commit
2e774e974c
@ -58,8 +58,57 @@ TreeWalker::~TreeWalker()
|
||||
MOZ_COUNT_DTOR(TreeWalker);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TreeWalker: private
|
||||
bool
|
||||
TreeWalker::Seek(nsIContent* aChildNode)
|
||||
{
|
||||
MOZ_ASSERT(aChildNode, "Child cannot be null");
|
||||
|
||||
mPhase = eAtStart;
|
||||
mStateStack.Clear();
|
||||
mARIAOwnsIdx = 0;
|
||||
|
||||
nsIContent* childNode = nullptr;
|
||||
nsINode* parentNode = aChildNode;
|
||||
do {
|
||||
childNode = parentNode->AsContent();
|
||||
parentNode = childNode->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) &&
|
||||
(mChildFilter & nsIContent::eAllButXBL) ?
|
||||
childNode->GetParentNode() : childNode->GetFlattenedTreeParent();
|
||||
|
||||
if (!parentNode || !parentNode->IsElement()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If ARIA owned child.
|
||||
Accessible* child = mDoc->GetAccessible(childNode);
|
||||
if (child && child->IsRelocated()) {
|
||||
if (child->Parent() != mContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Accessible* ownedChild = nullptr;
|
||||
while ((ownedChild = mDoc->ARIAOwnedAt(mContext, mARIAOwnsIdx++)) &&
|
||||
ownedChild != child);
|
||||
|
||||
MOZ_ASSERT(ownedChild, "A child has to be in ARIA owned elements");
|
||||
mPhase = eAtARIAOwns;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Look in DOM.
|
||||
dom::AllChildrenIterator* iter = PrependState(parentNode->AsElement(), true);
|
||||
if (!iter->Seek(childNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parentNode == mAnchorNode) {
|
||||
mPhase = eAtDOM;
|
||||
return true;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Accessible*
|
||||
TreeWalker::Next()
|
||||
|
@ -49,6 +49,12 @@ public:
|
||||
|
||||
~TreeWalker();
|
||||
|
||||
/**
|
||||
* Clears the tree walker state and resets it to the given child within
|
||||
* the anchor.
|
||||
*/
|
||||
bool Seek(nsIContent* aChildNode);
|
||||
|
||||
/**
|
||||
* Return the next/prev accessible.
|
||||
*
|
||||
@ -59,13 +65,17 @@ public:
|
||||
Accessible* Next();
|
||||
Accessible* Prev();
|
||||
|
||||
Accessible* Context() const { return mContext; }
|
||||
DocAccessible* Document() const { return mDoc; }
|
||||
|
||||
private:
|
||||
TreeWalker();
|
||||
TreeWalker(const TreeWalker&);
|
||||
TreeWalker& operator =(const TreeWalker&);
|
||||
|
||||
/**
|
||||
* Create new state for the given node and push it on top of stack.
|
||||
* Create new state for the given node and push it on top of stack / at bottom
|
||||
* of stack.
|
||||
*
|
||||
* @note State stack is used to navigate up/down the DOM subtree during
|
||||
* accessible children search.
|
||||
@ -76,6 +86,12 @@ private:
|
||||
return mStateStack.AppendElement(
|
||||
dom::AllChildrenIterator(aContent, mChildFilter, aStartAtBeginning));
|
||||
}
|
||||
dom::AllChildrenIterator* PrependState(nsIContent* aContent,
|
||||
bool aStartAtBeginning)
|
||||
{
|
||||
return mStateStack.InsertElementAt(0,
|
||||
dom::AllChildrenIterator(aContent, mChildFilter, aStartAtBeginning));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop state from stack.
|
||||
|
Loading…
Reference in New Issue
Block a user