Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/xul/nsPopupSetFrame.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "nsPopupSetFrame.h"
8
#include "nsGkAtoms.h"
9
#include "nsCOMPtr.h"
10
#include "nsIContent.h"
11
#include "nsPresContext.h"
12
#include "mozilla/ComputedStyle.h"
13
#include "nsBoxLayoutState.h"
14
#include "nsIScrollableFrame.h"
15
#include "nsIPopupContainer.h"
16
#include "nsMenuPopupFrame.h"
17
18
typedef mozilla::ComputedStyle ComputedStyle;
19
20
nsIFrame*
21
NS_NewPopupSetFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle)
22
0
{
23
0
  return new (aPresShell) nsPopupSetFrame(aStyle);
24
0
}
25
26
NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame)
27
28
void
29
nsPopupSetFrame::Init(nsIContent*       aContent,
30
                      nsContainerFrame* aParent,
31
                      nsIFrame*         aPrevInFlow)
32
0
{
33
0
  nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
34
0
35
0
  // Normally the root box is our grandparent, but in case of wrapping
36
0
  // it can be our great-grandparent.
37
0
  nsIPopupContainer *popupContainer =
38
0
    nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
39
0
  if (popupContainer) {
40
0
    popupContainer->SetPopupSetFrame(this);
41
0
  }
42
0
}
43
44
void
45
nsPopupSetFrame::AppendFrames(ChildListID     aListID,
46
                              nsFrameList&    aFrameList)
47
0
{
48
0
  if (aListID == kPopupList) {
49
0
    AddPopupFrameList(aFrameList);
50
0
    return;
51
0
  }
52
0
  nsBoxFrame::AppendFrames(aListID, aFrameList);
53
0
}
54
55
void
56
nsPopupSetFrame::RemoveFrame(ChildListID     aListID,
57
                             nsIFrame*       aOldFrame)
58
0
{
59
0
  if (aListID == kPopupList) {
60
0
    RemovePopupFrame(aOldFrame);
61
0
    return;
62
0
  }
63
0
  nsBoxFrame::RemoveFrame(aListID, aOldFrame);
64
0
}
65
66
void
67
nsPopupSetFrame::InsertFrames(ChildListID     aListID,
68
                              nsIFrame*       aPrevFrame,
69
                              nsFrameList&    aFrameList)
70
0
{
71
0
  if (aListID == kPopupList) {
72
0
    AddPopupFrameList(aFrameList);
73
0
    return;
74
0
  }
75
0
  nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
76
0
}
77
78
void
79
nsPopupSetFrame::SetInitialChildList(ChildListID     aListID,
80
                                     nsFrameList&    aChildList)
81
0
{
82
0
  if (aListID == kPopupList) {
83
0
    NS_ASSERTION(mPopupList.IsEmpty(),
84
0
                 "SetInitialChildList on non-empty child list");
85
0
    AddPopupFrameList(aChildList);
86
0
    return;
87
0
  }
88
0
  nsBoxFrame::SetInitialChildList(aListID, aChildList);
89
0
}
90
91
const nsFrameList&
92
nsPopupSetFrame::GetChildList(ChildListID aListID) const
93
0
{
94
0
  if (kPopupList == aListID) {
95
0
    return mPopupList;
96
0
  }
97
0
  return nsBoxFrame::GetChildList(aListID);
98
0
}
99
100
void
101
nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const
102
0
{
103
0
  nsBoxFrame::GetChildLists(aLists);
104
0
  mPopupList.AppendIfNonempty(aLists, kPopupList);
105
0
}
106
107
void
108
nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
109
0
{
110
0
  mPopupList.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
111
0
112
0
  // Normally the root box is our grandparent, but in case of wrapping
113
0
  // it can be our great-grandparent.
114
0
  nsIPopupContainer *popupContainer =
115
0
    nsIPopupContainer::GetPopupContainer(PresContext()->GetPresShell());
116
0
  if (popupContainer) {
117
0
    popupContainer->SetPopupSetFrame(nullptr);
118
0
  }
119
0
120
0
  nsBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
121
0
}
122
123
NS_IMETHODIMP
124
nsPopupSetFrame::DoXULLayout(nsBoxLayoutState& aState)
125
0
{
126
0
  // lay us out
127
0
  nsresult rv = nsBoxFrame::DoXULLayout(aState);
128
0
129
0
  // lay out all of our currently open popups.
130
0
  for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
131
0
    nsMenuPopupFrame* popupChild = static_cast<nsMenuPopupFrame*>(e.get());
132
0
    popupChild->LayoutPopup(aState, nullptr, nullptr, false);
133
0
  }
134
0
135
0
  return rv;
136
0
}
137
138
void
139
nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup)
140
0
{
141
0
  MOZ_ASSERT((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
142
0
             aPopup->IsMenuPopupFrame(),
143
0
             "removing wrong type of frame in popupset's ::popupList");
144
0
145
0
  mPopupList.DestroyFrame(aPopup);
146
0
}
147
148
void
149
nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
150
0
{
151
#ifdef DEBUG
152
  for (nsFrameList::Enumerator e(aPopupFrameList); !e.AtEnd(); e.Next()) {
153
    NS_ASSERTION((e.get()->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
154
                 e.get()->IsMenuPopupFrame(),
155
                 "adding wrong type of frame in popupset's ::popupList");
156
  }
157
#endif
158
  mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
159
0
}