2010-02-21 00:55:04 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-02-21 00:55:04 +00:00
|
|
|
|
|
|
|
#include "nsAccTreeWalker.h"
|
|
|
|
|
2012-05-29 01:18:45 +00:00
|
|
|
#include "Accessible.h"
|
2010-02-21 00:55:04 +00:00
|
|
|
#include "nsAccessibilityService.h"
|
2012-05-27 09:01:40 +00:00
|
|
|
#include "DocAccessible.h"
|
2010-02-21 00:55:04 +00:00
|
|
|
|
2010-06-08 16:39:58 +00:00
|
|
|
#include "nsINodeList.h"
|
|
|
|
|
2010-02-21 00:55:04 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// WalkState
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
struct WalkState
|
|
|
|
{
|
|
|
|
WalkState(nsIContent *aContent) :
|
|
|
|
content(aContent), childIdx(0), prevState(nsnull) {}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
nsCOMPtr<nsINodeList> childList;
|
|
|
|
PRUint32 childIdx;
|
|
|
|
WalkState *prevState;
|
|
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccTreeWalker
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
nsAccTreeWalker::
|
2012-05-27 09:01:40 +00:00
|
|
|
nsAccTreeWalker(DocAccessible* aDoc, nsIContent* aContent,
|
2011-09-29 06:19:26 +00:00
|
|
|
bool aWalkAnonContent, bool aWalkCache) :
|
2012-02-09 16:49:17 +00:00
|
|
|
mDoc(aDoc), mWalkCache(aWalkCache), mState(nsnull)
|
2010-02-21 00:55:04 +00:00
|
|
|
{
|
|
|
|
NS_ASSERTION(aContent, "No node for the accessible tree walker!");
|
|
|
|
|
|
|
|
if (aContent)
|
|
|
|
mState = new WalkState(aContent);
|
|
|
|
|
2010-10-15 15:34:35 +00:00
|
|
|
mChildFilter = aWalkAnonContent ? nsIContent::eAllChildren :
|
2010-02-21 00:55:04 +00:00
|
|
|
nsIContent::eAllButXBL;
|
|
|
|
|
2010-10-15 15:34:35 +00:00
|
|
|
mChildFilter |= nsIContent::eSkipPlaceholderContent;
|
|
|
|
|
2010-02-21 00:55:04 +00:00
|
|
|
MOZ_COUNT_CTOR(nsAccTreeWalker);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAccTreeWalker::~nsAccTreeWalker()
|
|
|
|
{
|
|
|
|
// Clear state stack from memory
|
|
|
|
while (mState)
|
|
|
|
PopState();
|
|
|
|
|
|
|
|
MOZ_COUNT_DTOR(nsAccTreeWalker);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// nsAccTreeWalker: private
|
|
|
|
|
2012-05-29 01:18:45 +00:00
|
|
|
Accessible*
|
2011-03-31 09:30:58 +00:00
|
|
|
nsAccTreeWalker::NextChildInternal(bool aNoWalkUp)
|
2010-02-21 00:55:04 +00:00
|
|
|
{
|
|
|
|
if (!mState || !mState->content)
|
|
|
|
return nsnull;
|
|
|
|
|
|
|
|
if (!mState->childList)
|
2010-10-15 15:34:35 +00:00
|
|
|
mState->childList = mState->content->GetChildren(mChildFilter);
|
2010-02-21 00:55:04 +00:00
|
|
|
|
|
|
|
PRUint32 length = 0;
|
|
|
|
if (mState->childList)
|
|
|
|
mState->childList->GetLength(&length);
|
|
|
|
|
2010-02-21 01:31:07 +00:00
|
|
|
while (mState->childIdx < length) {
|
2010-02-21 00:55:04 +00:00
|
|
|
nsIContent* childNode = mState->childList->GetNodeAt(mState->childIdx);
|
|
|
|
mState->childIdx++;
|
|
|
|
|
2010-11-13 17:49:26 +00:00
|
|
|
bool isSubtreeHidden = false;
|
2012-05-29 01:18:45 +00:00
|
|
|
Accessible* accessible = mWalkCache ? mDoc->GetAccessible(childNode) :
|
2012-02-09 16:49:17 +00:00
|
|
|
GetAccService()->GetOrCreateAccessible(childNode, mDoc, &isSubtreeHidden);
|
2010-02-21 00:55:04 +00:00
|
|
|
|
|
|
|
if (accessible)
|
2011-03-31 09:30:58 +00:00
|
|
|
return accessible;
|
2010-02-21 00:55:04 +00:00
|
|
|
|
|
|
|
// Walk down into subtree to find accessibles.
|
2010-11-13 17:49:26 +00:00
|
|
|
if (!isSubtreeHidden) {
|
2010-02-21 00:55:04 +00:00
|
|
|
if (!PushState(childNode))
|
|
|
|
break;
|
|
|
|
|
2011-03-31 09:30:58 +00:00
|
|
|
accessible = NextChildInternal(true);
|
2010-02-21 00:55:04 +00:00
|
|
|
if (accessible)
|
2011-03-31 09:30:58 +00:00
|
|
|
return accessible;
|
2010-02-21 00:55:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No more children, get back to the parent.
|
|
|
|
PopState();
|
|
|
|
|
2011-03-31 09:30:58 +00:00
|
|
|
return aNoWalkUp ? nsnull : NextChildInternal(false);
|
2010-02-21 00:55:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsAccTreeWalker::PopState()
|
|
|
|
{
|
|
|
|
WalkState* prevToLastState = mState->prevState;
|
|
|
|
delete mState;
|
|
|
|
mState = prevToLastState;
|
|
|
|
}
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2010-02-21 00:55:04 +00:00
|
|
|
nsAccTreeWalker::PushState(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
WalkState* nextToLastState = new WalkState(aContent);
|
|
|
|
if (!nextToLastState)
|
2011-10-17 14:59:28 +00:00
|
|
|
return false;
|
2010-02-21 00:55:04 +00:00
|
|
|
|
|
|
|
nextToLastState->prevState = mState;
|
|
|
|
mState = nextToLastState;
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
return true;
|
2010-02-21 00:55:04 +00:00
|
|
|
}
|