layout/xul/nsDeckFrame.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 //
     7 // Eric Vaughan
     8 // Netscape Communications
     9 //
    10 // See documentation in associated header file
    11 //
    13 #include "nsDeckFrame.h"
    14 #include "nsStyleContext.h"
    15 #include "nsPresContext.h"
    16 #include "nsIContent.h"
    17 #include "nsCOMPtr.h"
    18 #include "nsNameSpaceManager.h"
    19 #include "nsGkAtoms.h"
    20 #include "nsHTMLParts.h"
    21 #include "nsIPresShell.h"
    22 #include "nsCSSRendering.h"
    23 #include "nsViewManager.h"
    24 #include "nsBoxLayoutState.h"
    25 #include "nsStackLayout.h"
    26 #include "nsDisplayList.h"
    27 #include "nsContainerFrame.h"
    29 #ifdef ACCESSIBILITY
    30 #include "nsAccessibilityService.h"
    31 #endif
    33 nsIFrame*
    34 NS_NewDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    35 {
    36   return new (aPresShell) nsDeckFrame(aPresShell, aContext);
    37 }
    39 NS_IMPL_FRAMEARENA_HELPERS(nsDeckFrame)
    41 NS_QUERYFRAME_HEAD(nsDeckFrame)
    42   NS_QUERYFRAME_ENTRY(nsDeckFrame)
    43 NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
    46 nsDeckFrame::nsDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    47   : nsBoxFrame(aPresShell, aContext), mIndex(0)
    48 {
    49   nsCOMPtr<nsBoxLayout> layout;
    50   NS_NewStackLayout(aPresShell, layout);
    51   SetLayoutManager(layout);
    52 }
    54 nsIAtom*
    55 nsDeckFrame::GetType() const
    56 {
    57   return nsGkAtoms::deckFrame;
    58 }
    60 nsresult
    61 nsDeckFrame::AttributeChanged(int32_t         aNameSpaceID,
    62                               nsIAtom*        aAttribute,
    63                               int32_t         aModType)
    64 {
    65   nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
    66                                              aModType);
    69    // if the index changed hide the old element and make the new element visible
    70   if (aAttribute == nsGkAtoms::selectedIndex) {
    71     IndexChanged();
    72   }
    74   return rv;
    75 }
    77 void
    78 nsDeckFrame::Init(nsIContent*     aContent,
    79                   nsIFrame*       aParent,
    80                   nsIFrame*       aPrevInFlow)
    81 {
    82   nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
    84   mIndex = GetSelectedIndex();
    85 }
    87 void
    88 nsDeckFrame::HideBox(nsIFrame* aBox)
    89 {
    90   nsIPresShell::ClearMouseCapture(aBox);
    91 }
    93 void
    94 nsDeckFrame::IndexChanged()
    95 {
    96   //did the index change?
    97   int32_t index = GetSelectedIndex();
    98   if (index == mIndex)
    99     return;
   101   // redraw
   102   InvalidateFrame();
   104   // hide the currently showing box
   105   nsIFrame* currentBox = GetSelectedBox();
   106   if (currentBox) // only hide if it exists
   107     HideBox(currentBox);
   109   mIndex = index;
   111 #ifdef ACCESSIBILITY
   112   nsAccessibilityService* accService = GetAccService();
   113   if (accService) {
   114     accService->DeckPanelSwitched(PresContext()->GetPresShell(), mContent,
   115                                   currentBox, GetSelectedBox());
   116   }
   117 #endif
   118 }
   120 int32_t
   121 nsDeckFrame::GetSelectedIndex()
   122 {
   123   // default index is 0
   124   int32_t index = 0;
   126   // get the index attribute
   127   nsAutoString value;
   128   if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::selectedIndex, value))
   129   {
   130     nsresult error;
   132     // convert it to an integer
   133     index = value.ToInteger(&error);
   134   }
   136   return index;
   137 }
   139 nsIFrame* 
   140 nsDeckFrame::GetSelectedBox()
   141 {
   142   return (mIndex >= 0) ? mFrames.FrameAt(mIndex) : nullptr; 
   143 }
   145 void
   146 nsDeckFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
   147                               const nsRect&           aDirtyRect,
   148                               const nsDisplayListSet& aLists)
   149 {
   150   // if a tab is hidden all its children are too.
   151   if (!StyleVisibility()->mVisible)
   152     return;
   154   nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
   155 }
   157 void
   158 nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
   159                                          const nsRect&           aDirtyRect,
   160                                          const nsDisplayListSet& aLists)
   161 {
   162   // only paint the selected box
   163   nsIFrame* box = GetSelectedBox();
   164   if (!box)
   165     return;
   167   // Putting the child in the background list. This is a little weird but
   168   // it matches what we were doing before.
   169   nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds());
   170   BuildDisplayListForChild(aBuilder, box, aDirtyRect, set);
   171 }
   173 NS_IMETHODIMP
   174 nsDeckFrame::DoLayout(nsBoxLayoutState& aState)
   175 {
   176   // Make sure we tweak the state so it does not resize our children.
   177   // We will do that.
   178   uint32_t oldFlags = aState.LayoutFlags();
   179   aState.SetLayoutFlags(NS_FRAME_NO_SIZE_VIEW | NS_FRAME_NO_VISIBILITY);
   181   // do a normal layout
   182   nsresult rv = nsBoxFrame::DoLayout(aState);
   184   // run though each child. Hide all but the selected one
   185   nsIFrame* box = GetChildBox();
   187   nscoord count = 0;
   188   while (box) 
   189   {
   190     // make collapsed children not show up
   191     if (count != mIndex) 
   192       HideBox(box);
   194     box = box->GetNextBox();
   195     count++;
   196   }
   198   aState.SetLayoutFlags(oldFlags);
   200   return rv;
   201 }

mercurial