Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsPopupSetFrame.h"
7 #include "nsGkAtoms.h"
8 #include "nsCOMPtr.h"
9 #include "nsIContent.h"
10 #include "nsPresContext.h"
11 #include "nsStyleContext.h"
12 #include "nsBoxLayoutState.h"
13 #include "nsIScrollableFrame.h"
14 #include "nsIRootBox.h"
15 #include "nsMenuPopupFrame.h"
17 nsIFrame*
18 NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
19 {
20 return new (aPresShell) nsPopupSetFrame (aPresShell, aContext);
21 }
23 NS_IMPL_FRAMEARENA_HELPERS(nsPopupSetFrame)
25 void
26 nsPopupSetFrame::Init(nsIContent* aContent,
27 nsIFrame* aParent,
28 nsIFrame* aPrevInFlow)
29 {
30 nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
32 // Normally the root box is our grandparent, but in case of wrapping
33 // it can be our great-grandparent.
34 nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
35 if (rootBox) {
36 rootBox->SetPopupSetFrame(this);
37 }
38 }
40 nsIAtom*
41 nsPopupSetFrame::GetType() const
42 {
43 return nsGkAtoms::popupSetFrame;
44 }
46 nsresult
47 nsPopupSetFrame::AppendFrames(ChildListID aListID,
48 nsFrameList& aFrameList)
49 {
50 if (aListID == kPopupList) {
51 AddPopupFrameList(aFrameList);
52 return NS_OK;
53 }
54 return nsBoxFrame::AppendFrames(aListID, aFrameList);
55 }
57 nsresult
58 nsPopupSetFrame::RemoveFrame(ChildListID aListID,
59 nsIFrame* aOldFrame)
60 {
61 if (aListID == kPopupList) {
62 RemovePopupFrame(aOldFrame);
63 return NS_OK;
64 }
65 return nsBoxFrame::RemoveFrame(aListID, aOldFrame);
66 }
68 nsresult
69 nsPopupSetFrame::InsertFrames(ChildListID aListID,
70 nsIFrame* aPrevFrame,
71 nsFrameList& aFrameList)
72 {
73 if (aListID == kPopupList) {
74 AddPopupFrameList(aFrameList);
75 return NS_OK;
76 }
77 return nsBoxFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
78 }
80 nsresult
81 nsPopupSetFrame::SetInitialChildList(ChildListID aListID,
82 nsFrameList& aChildList)
83 {
84 if (aListID == kPopupList) {
85 NS_ASSERTION(mPopupList.IsEmpty(),
86 "SetInitialChildList on non-empty child list");
87 AddPopupFrameList(aChildList);
88 return NS_OK;
89 }
90 return nsBoxFrame::SetInitialChildList(aListID, aChildList);
91 }
93 const nsFrameList&
94 nsPopupSetFrame::GetChildList(ChildListID aListID) const
95 {
96 if (kPopupList == aListID) {
97 return mPopupList;
98 }
99 return nsBoxFrame::GetChildList(aListID);
100 }
102 void
103 nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const
104 {
105 nsBoxFrame::GetChildLists(aLists);
106 mPopupList.AppendIfNonempty(aLists, kPopupList);
107 }
109 void
110 nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
111 {
112 mPopupList.DestroyFramesFrom(aDestructRoot);
114 // Normally the root box is our grandparent, but in case of wrapping
115 // it can be our great-grandparent.
116 nsIRootBox *rootBox = nsIRootBox::GetRootBox(PresContext()->GetPresShell());
117 if (rootBox) {
118 rootBox->SetPopupSetFrame(nullptr);
119 }
121 nsBoxFrame::DestroyFrom(aDestructRoot);
122 }
124 NS_IMETHODIMP
125 nsPopupSetFrame::DoLayout(nsBoxLayoutState& aState)
126 {
127 // lay us out
128 nsresult rv = nsBoxFrame::DoLayout(aState);
130 // lay out all of our currently open popups.
131 for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
132 nsMenuPopupFrame* popupChild = static_cast<nsMenuPopupFrame*>(e.get());
133 popupChild->LayoutPopup(aState, nullptr, nullptr, false);
134 }
136 return rv;
137 }
139 void
140 nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup)
141 {
142 NS_PRECONDITION((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
143 aPopup->GetType() == nsGkAtoms::menuPopupFrame,
144 "removing wrong type of frame in popupset's ::popupList");
146 mPopupList.DestroyFrame(aPopup);
147 }
149 void
150 nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
151 {
152 #ifdef DEBUG
153 for (nsFrameList::Enumerator e(aPopupFrameList); !e.AtEnd(); e.Next()) {
154 NS_ASSERTION((e.get()->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
155 e.get()->GetType() == nsGkAtoms::menuPopupFrame,
156 "adding wrong type of frame in popupset's ::popupList");
157 }
158 #endif
159 mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
160 }