123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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/. */
- #include "nsPopupSetFrame.h"
- #include "nsGkAtoms.h"
- #include "nsCOMPtr.h"
- #include "nsIContent.h"
- #include "nsPresContext.h"
- #include "nsStyleContext.h"
- #include "nsBoxLayoutState.h"
- #include "nsIScrollableFrame.h"
- #include "nsIRootBox.h"
- #include "nsMenuPopupFrame.h"
- nsIFrame*
- NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
- {
- return new (aPresShell) nsPopupSetFrame(aContext);
- }
- NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame)
- void
- nsPopupSetFrame::Init(nsIContent* aContent,
- nsContainerFrame* aParent,
- nsIFrame* aPrevInFlow)
- {
- nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
- // Normally the root box is our grandparent, but in case of wrapping
- // it can be our great-grandparent.
- nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
- if (rootBox) {
- rootBox->SetPopupSetFrame(this);
- }
- }
- nsIAtom*
- nsPopupSetFrame::GetType() const
- {
- return nsGkAtoms::popupSetFrame;
- }
- void
- nsPopupSetFrame::AppendFrames(ChildListID aListID,
- nsFrameList& aFrameList)
- {
- if (aListID == kPopupList) {
- AddPopupFrameList(aFrameList);
- return;
- }
- nsBoxFrame::AppendFrames(aListID, aFrameList);
- }
- void
- nsPopupSetFrame::RemoveFrame(ChildListID aListID,
- nsIFrame* aOldFrame)
- {
- if (aListID == kPopupList) {
- RemovePopupFrame(aOldFrame);
- return;
- }
- nsBoxFrame::RemoveFrame(aListID, aOldFrame);
- }
- void
- nsPopupSetFrame::InsertFrames(ChildListID aListID,
- nsIFrame* aPrevFrame,
- nsFrameList& aFrameList)
- {
- if (aListID == kPopupList) {
- AddPopupFrameList(aFrameList);
- return;
- }
- nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
- }
- void
- nsPopupSetFrame::SetInitialChildList(ChildListID aListID,
- nsFrameList& aChildList)
- {
- if (aListID == kPopupList) {
- NS_ASSERTION(mPopupList.IsEmpty(),
- "SetInitialChildList on non-empty child list");
- AddPopupFrameList(aChildList);
- return;
- }
- nsBoxFrame::SetInitialChildList(aListID, aChildList);
- }
- const nsFrameList&
- nsPopupSetFrame::GetChildList(ChildListID aListID) const
- {
- if (kPopupList == aListID) {
- return mPopupList;
- }
- return nsBoxFrame::GetChildList(aListID);
- }
- void
- nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const
- {
- nsBoxFrame::GetChildLists(aLists);
- mPopupList.AppendIfNonempty(aLists, kPopupList);
- }
- void
- nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
- {
- mPopupList.DestroyFramesFrom(aDestructRoot);
- // Normally the root box is our grandparent, but in case of wrapping
- // it can be our great-grandparent.
- nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
- if (rootBox) {
- rootBox->SetPopupSetFrame(nullptr);
- }
- nsBoxFrame::DestroyFrom(aDestructRoot);
- }
- NS_IMETHODIMP
- nsPopupSetFrame::DoXULLayout(nsBoxLayoutState& aState)
- {
- // lay us out
- nsresult rv = nsBoxFrame::DoXULLayout(aState);
- // lay out all of our currently open popups.
- for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
- nsMenuPopupFrame* popupChild = static_cast<nsMenuPopupFrame*>(e.get());
- popupChild->LayoutPopup(aState, nullptr, nullptr, false);
- }
- return rv;
- }
- void
- nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup)
- {
- NS_PRECONDITION((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
- aPopup->GetType() == nsGkAtoms::menuPopupFrame,
- "removing wrong type of frame in popupset's ::popupList");
- mPopupList.DestroyFrame(aPopup);
- }
- void
- nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
- {
- #ifdef DEBUG
- for (nsFrameList::Enumerator e(aPopupFrameList); !e.AtEnd(); e.Next()) {
- NS_ASSERTION((e.get()->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
- e.get()->GetType() == nsGkAtoms::menuPopupFrame,
- "adding wrong type of frame in popupset's ::popupList");
- }
- #endif
- mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
- }
|