LCOV - code coverage report
Current view: top level - layout/xul - nsDeckFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 49 83 59.0 %
Date: 2017-07-14 16:53:18 Functions: 11 14 78.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : //
       7             : // Eric Vaughan
       8             : // Netscape Communications
       9             : //
      10             : // See documentation in associated header file
      11             : //
      12             : 
      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"
      28             : #include "nsContentUtils.h"
      29             : 
      30             : #ifdef ACCESSIBILITY
      31             : #include "nsAccessibilityService.h"
      32             : #endif
      33             : 
      34             : nsIFrame*
      35           4 : NS_NewDeckFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      36             : {
      37           4 :   return new (aPresShell) nsDeckFrame(aContext);
      38             : }
      39             : 
      40           4 : NS_IMPL_FRAMEARENA_HELPERS(nsDeckFrame)
      41             : 
      42         201 : NS_QUERYFRAME_HEAD(nsDeckFrame)
      43          12 :   NS_QUERYFRAME_ENTRY(nsDeckFrame)
      44         189 : NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
      45             : 
      46           4 : nsDeckFrame::nsDeckFrame(nsStyleContext* aContext)
      47             :   : nsBoxFrame(aContext, kClassID)
      48           4 :   , mIndex(0)
      49             : {
      50           8 :   nsCOMPtr<nsBoxLayout> layout;
      51           4 :   NS_NewStackLayout(layout);
      52           4 :   SetXULLayoutManager(layout);
      53           4 : }
      54             : 
      55             : nsresult
      56           1 : nsDeckFrame::AttributeChanged(int32_t         aNameSpaceID,
      57             :                               nsIAtom*        aAttribute,
      58             :                               int32_t         aModType)
      59             : {
      60           1 :   nsresult rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
      61           1 :                                              aModType);
      62             : 
      63             : 
      64             :    // if the index changed hide the old element and make the new element visible
      65           1 :   if (aAttribute == nsGkAtoms::selectedIndex) {
      66           0 :     IndexChanged();
      67             :   }
      68             : 
      69           1 :   return rv;
      70             : }
      71             : 
      72             : void
      73           4 : nsDeckFrame::Init(nsIContent*       aContent,
      74             :                   nsContainerFrame* aParent,
      75             :                   nsIFrame*         aPrevInFlow)
      76             : {
      77           4 :   nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
      78             : 
      79           4 :   mIndex = GetSelectedIndex();
      80           4 : }
      81             : 
      82             : void
      83           0 : nsDeckFrame::HideBox(nsIFrame* aBox)
      84             : {
      85           0 :   nsIPresShell::ClearMouseCapture(aBox);
      86           0 : }
      87             : 
      88             : void
      89           0 : nsDeckFrame::IndexChanged()
      90             : {
      91             :   //did the index change?
      92           0 :   int32_t index = GetSelectedIndex();
      93           0 :   if (index == mIndex)
      94           0 :     return;
      95             : 
      96             :   // redraw
      97           0 :   InvalidateFrame();
      98             : 
      99             :   // hide the currently showing box
     100           0 :   nsIFrame* currentBox = GetSelectedBox();
     101           0 :   if (currentBox) // only hide if it exists
     102           0 :     HideBox(currentBox);
     103             : 
     104           0 :   mIndex = index;
     105             : 
     106             : #ifdef ACCESSIBILITY
     107           0 :   nsAccessibilityService* accService = GetAccService();
     108           0 :   if (accService) {
     109           0 :     accService->DeckPanelSwitched(PresContext()->GetPresShell(), mContent,
     110           0 :                                   currentBox, GetSelectedBox());
     111             :   }
     112             : #endif
     113             : 
     114             :   // Force any popups that might be anchored on elements within hidden
     115             :   // box to update.
     116           0 :   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     117           0 :   if (pm && currentBox) {
     118           0 :     pm->UpdatePopupPositions(currentBox->PresContext()->RefreshDriver());
     119             :   }
     120             : }
     121             : 
     122             : int32_t
     123           4 : nsDeckFrame::GetSelectedIndex()
     124             : {
     125             :   // default index is 0
     126           4 :   int32_t index = 0;
     127             : 
     128             :   // get the index attribute
     129           8 :   nsAutoString value;
     130           4 :   if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::selectedIndex, value))
     131             :   {
     132             :     nsresult error;
     133             : 
     134             :     // convert it to an integer
     135           2 :     index = value.ToInteger(&error);
     136             :   }
     137             : 
     138           8 :   return index;
     139             : }
     140             : 
     141             : nsIFrame*
     142         111 : nsDeckFrame::GetSelectedBox()
     143             : {
     144         111 :   return (mIndex >= 0) ? mFrames.FrameAt(mIndex) : nullptr;
     145             : }
     146             : 
     147             : void
     148          99 : nsDeckFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     149             :                               const nsRect&           aDirtyRect,
     150             :                               const nsDisplayListSet& aLists)
     151             : {
     152             :   // if a tab is hidden all its children are too.
     153          99 :   if (!StyleVisibility()->mVisible)
     154           0 :     return;
     155             : 
     156          99 :   nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
     157             : }
     158             : 
     159             : void
     160           0 : nsDeckFrame::RemoveFrame(ChildListID aListID,
     161             :                          nsIFrame* aOldFrame)
     162             : {
     163           0 :   nsIFrame* currentFrame = GetSelectedBox();
     164           0 :   if (currentFrame &&
     165           0 :       aOldFrame &&
     166             :       currentFrame != aOldFrame) {
     167             :     // If the frame we're removing is at an index that's less
     168             :     // than mIndex, that means we're going to be shifting indexes
     169             :     // by 1.
     170             :     //
     171             :     // We attempt to keep the same child displayed by automatically
     172             :     // updating our internal notion of the current index.
     173           0 :     int32_t removedIndex = mFrames.IndexOf(aOldFrame);
     174           0 :     MOZ_ASSERT(removedIndex >= 0,
     175             :                "A deck child was removed that was not in mFrames.");
     176           0 :     if (removedIndex < mIndex) {
     177           0 :       mIndex--;
     178             :       // This is going to cause us to handle the index change in IndexedChanged,
     179             :       // but since the new index will match mIndex, it's essentially a noop.
     180             :       nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
     181           0 :         mContent, nsGkAtoms::selectedIndex, mIndex));
     182             :     }
     183             :   }
     184           0 :   nsBoxFrame::RemoveFrame(aListID, aOldFrame);
     185           0 : }
     186             : 
     187             : void
     188          99 : nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
     189             :                                          const nsRect&           aDirtyRect,
     190             :                                          const nsDisplayListSet& aLists)
     191             : {
     192             :   // only paint the selected box
     193          99 :   nsIFrame* box = GetSelectedBox();
     194          99 :   if (!box)
     195           0 :     return;
     196             : 
     197             :   // Putting the child in the background list. This is a little weird but
     198             :   // it matches what we were doing before.
     199          99 :   nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds());
     200          99 :   BuildDisplayListForChild(aBuilder, box, aDirtyRect, set);
     201             : }
     202             : 
     203             : NS_IMETHODIMP
     204          30 : nsDeckFrame::DoXULLayout(nsBoxLayoutState& aState)
     205             : {
     206             :   // Make sure we tweak the state so it does not resize our children.
     207             :   // We will do that.
     208          30 :   uint32_t oldFlags = aState.LayoutFlags();
     209          30 :   aState.SetLayoutFlags(NS_FRAME_NO_SIZE_VIEW | NS_FRAME_NO_VISIBILITY);
     210             : 
     211             :   // do a normal layout
     212          30 :   nsresult rv = nsBoxFrame::DoXULLayout(aState);
     213             : 
     214             :   // run though each child. Hide all but the selected one
     215          30 :   nsIFrame* box = nsBox::GetChildXULBox(this);
     216             : 
     217          30 :   nscoord count = 0;
     218          90 :   while (box)
     219             :   {
     220             :     // make collapsed children not show up
     221          30 :     if (count != mIndex)
     222           0 :       HideBox(box);
     223             : 
     224          30 :     box = GetNextXULBox(box);
     225          30 :     count++;
     226             :   }
     227             : 
     228          30 :   aState.SetLayoutFlags(oldFlags);
     229             : 
     230          30 :   return rv;
     231             : }
     232             : 

Generated by: LCOV version 1.13