layout/xul/nsPopupSetFrame.cpp

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

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 }

mercurial