bool DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, uint64_t aParentID, bool aCreating) { // We do not use GetAccessible here because we want to be sure to not get the // document it self. ProxyEntry* e = mAccessibles.GetEntry(aParentID); if (!e) return false; ProxyAccessible* outerDoc = e->mProxy; MOZ_ASSERT(outerDoc); // OuterDocAccessibles are expected to only have a document as a child. // However for compatibility we tolerate replacing one document with another // here. if (outerDoc->ChildrenCount() > 1 || (outerDoc->ChildrenCount() == 1 && !outerDoc->ChildAt(0)->IsDoc())) { return false; } aChildDoc->mParent = outerDoc; outerDoc->SetChildDoc(aChildDoc); mChildDocs.AppendElement(aChildDoc); aChildDoc->mParentDoc = this; if (aCreating) { ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT); } return true; }
ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, uint64_t aParentID, bool aCreating) { // We do not use GetAccessible here because we want to be sure to not get the // document it self. ProxyEntry* e = mAccessibles.GetEntry(aParentID); if (!e) { return IPC_FAIL(this, "binding to nonexistant proxy!"); } ProxyAccessible* outerDoc = e->mProxy; MOZ_ASSERT(outerDoc); // OuterDocAccessibles are expected to only have a document as a child. // However for compatibility we tolerate replacing one document with another // here. if (outerDoc->ChildrenCount() > 1 || (outerDoc->ChildrenCount() == 1 && !outerDoc->ChildAt(0)->IsDoc())) { return IPC_FAIL(this, "binding to proxy that can't be a outerDoc!"); } aChildDoc->SetParent(outerDoc); outerDoc->SetChildDoc(aChildDoc); mChildDocs.AppendElement(aChildDoc->mActorID); aChildDoc->mParentDoc = mActorID; if (aCreating) { ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT); } return IPC_OK(); }
bool DocAccessibleParent::RecvShowEvent(const ShowEventData& aData, const bool& aFromUser) { if (mShutdown) return true; MOZ_DIAGNOSTIC_ASSERT(CheckDocTree()); if (aData.NewTree().IsEmpty()) { NS_ERROR("no children being added"); return false; } ProxyAccessible* parent = GetAccessible(aData.ID()); // XXX This should really never happen, but sometimes we fail to fire the // required show events. if (!parent) { NS_ERROR("adding child to unknown accessible"); return true; } uint32_t newChildIdx = aData.Idx(); if (newChildIdx > parent->ChildrenCount()) { NS_ERROR("invalid index to add child at"); return true; } uint32_t consumed = AddSubtree(parent, aData.NewTree(), 0, newChildIdx); MOZ_ASSERT(consumed == aData.NewTree().Length()); // XXX This shouldn't happen, but if we failed to add children then the below // is pointless and can crash. if (!consumed) { return true; } #ifdef DEBUG for (uint32_t i = 0; i < consumed; i++) { uint64_t id = aData.NewTree()[i].ID(); MOZ_ASSERT(mAccessibles.GetEntry(id)); } #endif MOZ_DIAGNOSTIC_ASSERT(CheckDocTree()); ProxyAccessible* target = parent->ChildAt(newChildIdx); ProxyShowHideEvent(target, parent, true, aFromUser); if (!nsCoreUtils::AccEventObserversExist()) { return true; } uint32_t type = nsIAccessibleEvent::EVENT_SHOW; xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target); xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this); nsIDOMNode* node = nullptr; RefPtr<xpcAccEvent> event = new xpcAccEvent(type, xpcAcc, doc, node, aFromUser); nsCoreUtils::DispatchAccEvent(Move(event)); return true; }