uint32_t DocAccessibleParent::AddSubtree(ProxyAccessible* aParent, const nsTArray<a11y::AccessibleData>& aNewTree, uint32_t aIdx, uint32_t aIdxInParent) { if (aNewTree.Length() <= aIdx) { NS_ERROR("bad index in serialized tree!"); return 0; } const AccessibleData& newChild = aNewTree[aIdx]; if (newChild.Role() > roles::LAST_ROLE) { NS_ERROR("invalid role"); return 0; } if (mAccessibles.Contains(newChild.ID())) { NS_ERROR("ID already in use"); return 0; } auto role = static_cast<a11y::role>(newChild.Role()); ProxyAccessible* newProxy = new ProxyAccessible(newChild.ID(), aParent, this, role, newChild.Interfaces()); aParent->AddChildAt(aIdxInParent, newProxy); mAccessibles.PutEntry(newChild.ID())->mProxy = newProxy; ProxyCreated(newProxy, newChild.Interfaces()); #if defined(XP_WIN) WrapperFor(newProxy)->SetID(newChild.MsaaID()); #endif uint32_t accessibles = 1; uint32_t kids = newChild.ChildrenCount(); for (uint32_t i = 0; i < kids; i++) { uint32_t consumed = AddSubtree(newProxy, aNewTree, aIdx + accessibles, i); if (!consumed) return 0; accessibles += consumed; } MOZ_ASSERT(newProxy->ChildrenCount() == kids); return accessibles; }
bool ProxyAccessible::GetCOMInterface(void** aOutAccessible) const { if (!aOutAccessible) { return false; } if (!mCOMProxy && mSafeToRecurse) { // See if we can lazily obtain a COM proxy AccessibleWrap* wrap = WrapperFor(this); bool isDefunct = false; ProxyAccessible* thisPtr = const_cast<ProxyAccessible*>(this); // NB: Don't pass CHILDID_SELF here, use the absolute MSAA ID. Otherwise // GetIAccessibleFor will recurse into this function and we will just // overflow the stack. VARIANT realId = {{{VT_I4}}}; realId.ulVal = wrap->GetExistingID(); thisPtr->mCOMProxy = wrap->GetIAccessibleFor(realId, &isDefunct); } RefPtr<IAccessible> addRefed = mCOMProxy; addRefed.forget(aOutAccessible); return !!mCOMProxy; }