static void FindBodyContent(nsIContent* aParent, nsIContent** aResult) { if (aParent->Tag() == nsGkAtoms::listboxbody) { *aResult = aParent; NS_IF_ADDREF(*aResult); } else { nsCOMPtr<nsIDOMNodeList> kids; aParent->OwnerDoc()->BindingManager()->GetXBLChildNodesFor(aParent, getter_AddRefs(kids)); if (!kids) return; uint32_t i; kids->GetLength(&i); // start from the end, cuz we're smart and we know the listboxbody is probably at the end while (i > 0) { nsCOMPtr<nsIDOMNode> childNode; kids->Item(--i, getter_AddRefs(childNode)); nsCOMPtr<nsIContent> childContent(do_QueryInterface(childNode)); FindBodyContent(childContent, aResult); if (*aResult) break; } } }
nsListBoxBodyFrame* ListBoxObject::GetListBoxBody(bool aFlush) { if (mListBoxBody) { return mListBoxBody; } nsIPresShell* shell = GetPresShell(false); if (!shell) { return nullptr; } nsIFrame* frame = aFlush ? GetFrame(false) /* does Flush_Frames */ : mContent->GetPrimaryFrame(); if (!frame) { return nullptr; } // Iterate over our content model children looking for the body. nsCOMPtr<nsIContent> content = FindBodyContent(frame->GetContent()); if (!content) { return nullptr; } // this frame will be a nsGFXScrollFrame frame = content->GetPrimaryFrame(); if (!frame) { return nullptr; } nsIScrollableFrame* scrollFrame = do_QueryFrame(frame); if (!scrollFrame) { return nullptr; } // this frame will be the one we want nsIFrame* yeahBaby = scrollFrame->GetScrolledFrame(); if (!yeahBaby) { return nullptr; } // It's a frame. Refcounts are irrelevant. nsListBoxBodyFrame* listBoxBody = do_QueryFrame(yeahBaby); NS_ENSURE_TRUE(listBoxBody && listBoxBody->SetBoxObject(this), nullptr); mListBoxBody = listBoxBody; return mListBoxBody; }
static nsIContent* FindBodyContent(nsIContent* aParent) { if (aParent->IsXULElement(nsGkAtoms::listboxbody)) { return aParent; } mozilla::dom::FlattenedChildIterator iter(aParent); for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { nsIContent* result = FindBodyContent(child); if (result) { return result; } } return nullptr; }
nsListBoxBodyFrame* nsListBoxObject::GetListBoxBody(PRBool aFlush) { if (mListBoxBody) { return mListBoxBody; } nsIPresShell* shell = GetPresShell(PR_FALSE); if (!shell) { return nsnull; } nsIFrame* frame = aFlush ? GetFrame(PR_FALSE) /* does Flush_Frames */ : shell->GetPrimaryFrameFor(mContent); if (!frame) return nsnull; // Iterate over our content model children looking for the body. nsCOMPtr<nsIContent> content; FindBodyContent(frame->GetContent(), getter_AddRefs(content)); // this frame will be a nsGFXScrollFrame frame = shell->GetPrimaryFrameFor(content); if (!frame) return nsnull; nsIScrollableFrame* scrollFrame = do_QueryFrame(frame); if (!scrollFrame) return nsnull; // this frame will be the one we want nsIFrame* yeahBaby = scrollFrame->GetScrolledFrame(); if (!yeahBaby) return nsnull; // It's a frame. Refcounts are irrelevant. nsListBoxBodyFrame* listBoxBody = do_QueryFrame(yeahBaby); NS_ENSURE_TRUE(listBoxBody && listBoxBody->SetBoxObject(this), nsnull); mListBoxBody = listBoxBody; return mListBoxBody; }