michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "AccIterator.h" michael@0: michael@0: #include "AccGroupInfo.h" michael@0: #ifdef MOZ_XUL michael@0: #include "XULTreeAccessible.h" michael@0: #endif michael@0: michael@0: #include "mozilla/dom/Element.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::a11y; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // AccIterator michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: AccIterator::AccIterator(Accessible* aAccessible, michael@0: filters::FilterFuncPtr aFilterFunc) : michael@0: mFilterFunc(aFilterFunc) michael@0: { michael@0: mState = new IteratorState(aAccessible); michael@0: } michael@0: michael@0: AccIterator::~AccIterator() michael@0: { michael@0: while (mState) { michael@0: IteratorState *tmp = mState; michael@0: mState = tmp->mParentState; michael@0: delete tmp; michael@0: } michael@0: } michael@0: michael@0: Accessible* michael@0: AccIterator::Next() michael@0: { michael@0: while (mState) { michael@0: Accessible* child = mState->mParent->GetChildAt(mState->mIndex++); michael@0: if (!child) { michael@0: IteratorState* tmp = mState; michael@0: mState = mState->mParentState; michael@0: delete tmp; michael@0: michael@0: continue; michael@0: } michael@0: michael@0: uint32_t result = mFilterFunc(child); michael@0: if (result & filters::eMatch) michael@0: return child; michael@0: michael@0: if (!(result & filters::eSkipSubtree)) { michael@0: IteratorState* childState = new IteratorState(child, mState); michael@0: mState = childState; michael@0: } michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // nsAccIterator::IteratorState michael@0: michael@0: AccIterator::IteratorState::IteratorState(Accessible* aParent, michael@0: IteratorState *mParentState) : michael@0: mParent(aParent), mIndex(0), mParentState(mParentState) michael@0: { michael@0: } michael@0: michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // RelatedAccIterator michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: RelatedAccIterator:: michael@0: RelatedAccIterator(DocAccessible* aDocument, nsIContent* aDependentContent, michael@0: nsIAtom* aRelAttr) : michael@0: mDocument(aDocument), mRelAttr(aRelAttr), mProviders(nullptr), michael@0: mBindingParent(nullptr), mIndex(0) michael@0: { michael@0: mBindingParent = aDependentContent->GetBindingParent(); michael@0: nsIAtom* IDAttr = mBindingParent ? michael@0: nsGkAtoms::anonid : aDependentContent->GetIDAttributeName(); michael@0: michael@0: nsAutoString id; michael@0: if (aDependentContent->GetAttr(kNameSpaceID_None, IDAttr, id)) michael@0: mProviders = mDocument->mDependentIDsHash.Get(id); michael@0: } michael@0: michael@0: Accessible* michael@0: RelatedAccIterator::Next() michael@0: { michael@0: if (!mProviders) michael@0: return nullptr; michael@0: michael@0: while (mIndex < mProviders->Length()) { michael@0: DocAccessible::AttrRelProvider* provider = (*mProviders)[mIndex++]; michael@0: michael@0: // Return related accessible for the given attribute and if the provider michael@0: // content is in the same binding in the case of XBL usage. michael@0: if (provider->mRelAttr == mRelAttr) { michael@0: nsIContent* bindingParent = provider->mContent->GetBindingParent(); michael@0: bool inScope = mBindingParent == bindingParent || michael@0: mBindingParent == provider->mContent; michael@0: michael@0: if (inScope) { michael@0: Accessible* related = mDocument->GetAccessible(provider->mContent); michael@0: if (related) michael@0: return related; michael@0: michael@0: // If the document content is pointed by relation then return the document michael@0: // itself. michael@0: if (provider->mContent == mDocument->GetContent()) michael@0: return mDocument; michael@0: } michael@0: } michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // HTMLLabelIterator michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: HTMLLabelIterator:: michael@0: HTMLLabelIterator(DocAccessible* aDocument, const Accessible* aAccessible, michael@0: LabelFilter aFilter) : michael@0: mRelIter(aDocument, aAccessible->GetContent(), nsGkAtoms::_for), michael@0: mAcc(aAccessible), mLabelFilter(aFilter) michael@0: { michael@0: } michael@0: michael@0: Accessible* michael@0: HTMLLabelIterator::Next() michael@0: { michael@0: // Get either