layout/xul/nsPopupSetFrame.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/xul/nsPopupSetFrame.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,160 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsPopupSetFrame.h"
    1.10 +#include "nsGkAtoms.h"
    1.11 +#include "nsCOMPtr.h"
    1.12 +#include "nsIContent.h"
    1.13 +#include "nsPresContext.h"
    1.14 +#include "nsStyleContext.h"
    1.15 +#include "nsBoxLayoutState.h"
    1.16 +#include "nsIScrollableFrame.h"
    1.17 +#include "nsIRootBox.h"
    1.18 +#include "nsMenuPopupFrame.h"
    1.19 +
    1.20 +nsIFrame*
    1.21 +NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    1.22 +{
    1.23 +  return new (aPresShell) nsPopupSetFrame (aPresShell, aContext);
    1.24 +}
    1.25 +
    1.26 +NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame)
    1.27 +
    1.28 +void
    1.29 +nsPopupSetFrame::Init(nsIContent*      aContent,
    1.30 +                      nsIFrame*        aParent,
    1.31 +                      nsIFrame*        aPrevInFlow)
    1.32 +{
    1.33 +  nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
    1.34 +
    1.35 +  // Normally the root box is our grandparent, but in case of wrapping
    1.36 +  // it can be our great-grandparent.
    1.37 +  nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
    1.38 +  if (rootBox) {
    1.39 +    rootBox->SetPopupSetFrame(this);
    1.40 +  }
    1.41 +}
    1.42 +
    1.43 +nsIAtom*
    1.44 +nsPopupSetFrame::GetType() const
    1.45 +{
    1.46 +  return nsGkAtoms::popupSetFrame;
    1.47 +}
    1.48 +
    1.49 +nsresult
    1.50 +nsPopupSetFrame::AppendFrames(ChildListID     aListID,
    1.51 +                              nsFrameList&    aFrameList)
    1.52 +{
    1.53 +  if (aListID == kPopupList) {
    1.54 +    AddPopupFrameList(aFrameList);
    1.55 +    return NS_OK;
    1.56 +  }
    1.57 +  return nsBoxFrame::AppendFrames(aListID, aFrameList);
    1.58 +}
    1.59 +
    1.60 +nsresult
    1.61 +nsPopupSetFrame::RemoveFrame(ChildListID     aListID,
    1.62 +                             nsIFrame*       aOldFrame)
    1.63 +{
    1.64 +  if (aListID == kPopupList) {
    1.65 +    RemovePopupFrame(aOldFrame);
    1.66 +    return NS_OK;
    1.67 +  }
    1.68 +  return nsBoxFrame::RemoveFrame(aListID, aOldFrame);
    1.69 +}
    1.70 +
    1.71 +nsresult
    1.72 +nsPopupSetFrame::InsertFrames(ChildListID     aListID,
    1.73 +                              nsIFrame*       aPrevFrame,
    1.74 +                              nsFrameList&    aFrameList)
    1.75 +{
    1.76 +  if (aListID == kPopupList) {
    1.77 +    AddPopupFrameList(aFrameList);
    1.78 +    return NS_OK;
    1.79 +  }
    1.80 +  return nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
    1.81 +}
    1.82 +
    1.83 +nsresult
    1.84 +nsPopupSetFrame::SetInitialChildList(ChildListID     aListID,
    1.85 +                                     nsFrameList&    aChildList)
    1.86 +{
    1.87 +  if (aListID == kPopupList) {
    1.88 +    NS_ASSERTION(mPopupList.IsEmpty(),
    1.89 +                 "SetInitialChildList on non-empty child list");
    1.90 +    AddPopupFrameList(aChildList);
    1.91 +    return NS_OK;
    1.92 +  }
    1.93 +  return nsBoxFrame::SetInitialChildList(aListID, aChildList);
    1.94 +}
    1.95 +
    1.96 +const nsFrameList&
    1.97 +nsPopupSetFrame::GetChildList(ChildListID aListID) const
    1.98 +{
    1.99 +  if (kPopupList == aListID) {
   1.100 +    return mPopupList;
   1.101 +  }
   1.102 +  return nsBoxFrame::GetChildList(aListID);
   1.103 +}
   1.104 +
   1.105 +void
   1.106 +nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const
   1.107 +{
   1.108 +  nsBoxFrame::GetChildLists(aLists);
   1.109 +  mPopupList.AppendIfNonempty(aLists, kPopupList);
   1.110 +}
   1.111 +
   1.112 +void
   1.113 +nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
   1.114 +{
   1.115 +  mPopupList.DestroyFramesFrom(aDestructRoot);
   1.116 +
   1.117 +  // Normally the root box is our grandparent, but in case of wrapping
   1.118 +  // it can be our great-grandparent.
   1.119 +  nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
   1.120 +  if (rootBox) {
   1.121 +    rootBox->SetPopupSetFrame(nullptr);
   1.122 +  }
   1.123 +
   1.124 +  nsBoxFrame::DestroyFrom(aDestructRoot);
   1.125 +}
   1.126 +
   1.127 +NS_IMETHODIMP
   1.128 +nsPopupSetFrame::DoLayout(nsBoxLayoutState& aState)
   1.129 +{
   1.130 +  // lay us out
   1.131 +  nsresult rv = nsBoxFrame::DoLayout(aState);
   1.132 +
   1.133 +  // lay out all of our currently open popups.
   1.134 +  for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
   1.135 +    nsMenuPopupFrame* popupChild = static_cast<nsMenuPopupFrame*>(e.get());
   1.136 +    popupChild->LayoutPopup(aState, nullptr, nullptr, false);
   1.137 +  }
   1.138 +
   1.139 +  return rv;
   1.140 +}
   1.141 +
   1.142 +void
   1.143 +nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup)
   1.144 +{
   1.145 +  NS_PRECONDITION((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
   1.146 +                  aPopup->GetType() == nsGkAtoms::menuPopupFrame,
   1.147 +                  "removing wrong type of frame in popupset's ::popupList");
   1.148 +
   1.149 +  mPopupList.DestroyFrame(aPopup);
   1.150 +}
   1.151 +
   1.152 +void
   1.153 +nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
   1.154 +{
   1.155 +#ifdef DEBUG
   1.156 +  for (nsFrameList::Enumerator e(aPopupFrameList); !e.AtEnd(); e.Next()) {
   1.157 +    NS_ASSERTION((e.get()->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
   1.158 +                 e.get()->GetType() == nsGkAtoms::menuPopupFrame,
   1.159 +                 "adding wrong type of frame in popupset's ::popupList");
   1.160 +  }
   1.161 +#endif
   1.162 +  mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
   1.163 +}

mercurial