LCOV - code coverage report
Current view: top level - layout/xul - nsLeafBoxFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 93 112 83.0 %
Date: 2017-07-14 16:53:18 Functions: 17 20 85.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; 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 "nsLeafBoxFrame.h"
      14             : #include "nsBoxFrame.h"
      15             : #include "nsCOMPtr.h"
      16             : #include "nsGkAtoms.h"
      17             : #include "nsPresContext.h"
      18             : #include "nsStyleContext.h"
      19             : #include "nsIContent.h"
      20             : #include "nsNameSpaceManager.h"
      21             : #include "nsBoxLayoutState.h"
      22             : #include "nsWidgetsCID.h"
      23             : #include "nsViewManager.h"
      24             : #include "nsContainerFrame.h"
      25             : #include "nsDisplayList.h"
      26             : #include <algorithm>
      27             : 
      28             : using namespace mozilla;
      29             : 
      30             : //
      31             : // NS_NewLeafBoxFrame
      32             : //
      33             : // Creates a new Toolbar frame and returns it
      34             : //
      35             : nsIFrame*
      36          17 : NS_NewLeafBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
      37             : {
      38          17 :   return new (aPresShell) nsLeafBoxFrame(aContext);
      39             : }
      40             : 
      41          17 : NS_IMPL_FRAMEARENA_HELPERS(nsLeafBoxFrame)
      42             : 
      43             : #ifdef DEBUG_LAYOUT
      44             : void
      45             : nsLeafBoxFrame::GetBoxName(nsAutoString& aName)
      46             : {
      47             :    GetFrameName(aName);
      48             : }
      49             : #endif
      50             : 
      51             : 
      52             : /**
      53             :  * Initialize us. This is a good time to get the alignment of the box
      54             :  */
      55             : void
      56          90 : nsLeafBoxFrame::Init(nsIContent*       aContent,
      57             :                      nsContainerFrame* aParent,
      58             :                      nsIFrame*         aPrevInFlow)
      59             : {
      60          90 :   nsLeafFrame::Init(aContent, aParent, aPrevInFlow);
      61             : 
      62          90 :   if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
      63          90 :     AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
      64             :   }
      65             : 
      66          90 :   UpdateMouseThrough();
      67          90 : }
      68             : 
      69             : nsresult
      70          10 : nsLeafBoxFrame::AttributeChanged(int32_t aNameSpaceID,
      71             :                                  nsIAtom* aAttribute,
      72             :                                  int32_t aModType)
      73             : {
      74          10 :   nsresult rv = nsLeafFrame::AttributeChanged(aNameSpaceID, aAttribute,
      75          10 :                                               aModType);
      76             : 
      77          10 :   if (aAttribute == nsGkAtoms::mousethrough)
      78           0 :     UpdateMouseThrough();
      79             : 
      80          10 :   return rv;
      81             : }
      82             : 
      83          90 : void nsLeafBoxFrame::UpdateMouseThrough()
      84             : {
      85          90 :   if (mContent) {
      86             :     static nsIContent::AttrValuesArray strings[] =
      87             :       {&nsGkAtoms::never, &nsGkAtoms::always, nullptr};
      88         180 :     switch (mContent->FindAttrValueIn(kNameSpaceID_None,
      89             :                                       nsGkAtoms::mousethrough,
      90          90 :                                       strings, eCaseMatters)) {
      91           0 :       case 0: AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); break;
      92           1 :       case 1: AddStateBits(NS_FRAME_MOUSE_THROUGH_ALWAYS); break;
      93             :       case 2: {
      94           0 :           RemoveStateBits(NS_FRAME_MOUSE_THROUGH_ALWAYS);
      95           0 :           RemoveStateBits(NS_FRAME_MOUSE_THROUGH_NEVER);
      96           0 :           break;
      97             :       }
      98             :     }
      99             :   }
     100          90 : }
     101             : 
     102             : void
     103         376 : nsLeafBoxFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     104             :                                  const nsRect&           aDirtyRect,
     105             :                                  const nsDisplayListSet& aLists)
     106             : {
     107             :   // REVIEW: GetFrameForPoint used to not report events for the background
     108             :   // layer, whereas this code will put an event receiver for this frame in the
     109             :   // BlockBorderBackground() list. But I don't see any need to preserve
     110             :   // that anomalous behaviour. The important thing I'm preserving is that
     111             :   // leaf boxes continue to receive events in the foreground layer.
     112         376 :   DisplayBorderBackgroundOutline(aBuilder, aLists);
     113             : 
     114         376 :   if (!aBuilder->IsForEventDelivery() || !IsVisibleForPainting(aBuilder))
     115         376 :     return;
     116             : 
     117           0 :   aLists.Content()->AppendNewToTop(new (aBuilder)
     118           0 :     nsDisplayEventReceiver(aBuilder, this));
     119             : }
     120             : 
     121             : /* virtual */ nscoord
     122          20 : nsLeafBoxFrame::GetMinISize(gfxContext *aRenderingContext)
     123             : {
     124             :   nscoord result;
     125          40 :   DISPLAY_MIN_WIDTH(this, result);
     126          40 :   nsBoxLayoutState state(PresContext(), aRenderingContext);
     127             : 
     128          20 :   WritingMode wm = GetWritingMode();
     129          20 :   LogicalSize minSize(wm, GetXULMinSize(state));
     130             : 
     131             :   // GetXULMinSize returns border-box size, and we want to return content
     132             :   // inline-size.  Since Reflow uses the reflow state's border and padding, we
     133             :   // actually just want to subtract what GetXULMinSize added, which is the
     134             :   // result of GetXULBorderAndPadding.
     135          20 :   nsMargin bp;
     136          20 :   GetXULBorderAndPadding(bp);
     137             : 
     138          20 :   result = minSize.ISize(wm) - LogicalMargin(wm, bp).IStartEnd(wm);
     139             : 
     140          40 :   return result;
     141             : }
     142             : 
     143             : /* virtual */ nscoord
     144          18 : nsLeafBoxFrame::GetPrefISize(gfxContext *aRenderingContext)
     145             : {
     146             :   nscoord result;
     147          36 :   DISPLAY_PREF_WIDTH(this, result);
     148          36 :   nsBoxLayoutState state(PresContext(), aRenderingContext);
     149             : 
     150          18 :   WritingMode wm = GetWritingMode();
     151          18 :   LogicalSize prefSize(wm, GetXULPrefSize(state));
     152             : 
     153             :   // GetXULPrefSize returns border-box size, and we want to return content
     154             :   // inline-size.  Since Reflow uses the reflow state's border and padding, we
     155             :   // actually just want to subtract what GetXULPrefSize added, which is the
     156             :   // result of GetXULBorderAndPadding.
     157          18 :   nsMargin bp;
     158          18 :   GetXULBorderAndPadding(bp);
     159             : 
     160          18 :   result = prefSize.ISize(wm) - LogicalMargin(wm, bp).IStartEnd(wm);
     161             : 
     162          36 :   return result;
     163             : }
     164             : 
     165             : nscoord
     166           0 : nsLeafBoxFrame::GetIntrinsicISize()
     167             : {
     168             :   // No intrinsic width
     169           0 :   return 0;
     170             : }
     171             : 
     172             : LogicalSize
     173          12 : nsLeafBoxFrame::ComputeAutoSize(gfxContext*         aRenderingContext,
     174             :                                 WritingMode         aWM,
     175             :                                 const LogicalSize&  aCBSize,
     176             :                                 nscoord             aAvailableISize,
     177             :                                 const LogicalSize&  aMargin,
     178             :                                 const LogicalSize&  aBorder,
     179             :                                 const LogicalSize&  aPadding,
     180             :                                 ComputeSizeFlags    aFlags)
     181             : {
     182             :   // Important: NOT calling our direct superclass here!
     183             :   return nsFrame::ComputeAutoSize(aRenderingContext, aWM,
     184             :                                   aCBSize, aAvailableISize,
     185          12 :                                   aMargin, aBorder, aPadding, aFlags);
     186             : }
     187             : 
     188             : void
     189          12 : nsLeafBoxFrame::Reflow(nsPresContext*   aPresContext,
     190             :                      ReflowOutput&     aDesiredSize,
     191             :                      const ReflowInput& aReflowInput,
     192             :                      nsReflowStatus&          aStatus)
     193             : {
     194             :   // This is mostly a copy of nsBoxFrame::Reflow().
     195             :   // We aren't able to share an implementation because of the frame
     196             :   // class hierarchy.  If you make changes here, please keep
     197             :   // nsBoxFrame::Reflow in sync.
     198             : 
     199          12 :   MarkInReflow();
     200          12 :   DO_GLOBAL_REFLOW_COUNT("nsLeafBoxFrame");
     201          24 :   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
     202             : 
     203          12 :   NS_ASSERTION(aReflowInput.ComputedWidth() >=0 &&
     204             :                aReflowInput.ComputedHeight() >= 0, "Computed Size < 0");
     205             : 
     206             : #ifdef DO_NOISY_REFLOW
     207             :   printf("\n-------------Starting LeafBoxFrame Reflow ----------------------------\n");
     208             :   printf("%p ** nsLBF::Reflow %d R: ", this, myCounter++);
     209             :   switch (aReflowInput.reason) {
     210             :     case eReflowReason_Initial:
     211             :       printf("Ini");break;
     212             :     case eReflowReason_Incremental:
     213             :       printf("Inc");break;
     214             :     case eReflowReason_Resize:
     215             :       printf("Rsz");break;
     216             :     case eReflowReason_StyleChange:
     217             :       printf("Sty");break;
     218             :     case eReflowReason_Dirty:
     219             :       printf("Drt ");
     220             :       break;
     221             :     default:printf("<unknown>%d", aReflowInput.reason);break;
     222             :   }
     223             : 
     224             :   printSize("AW", aReflowInput.AvailableWidth());
     225             :   printSize("AH", aReflowInput.AvailableHeight());
     226             :   printSize("CW", aReflowInput.ComputedWidth());
     227             :   printSize("CH", aReflowInput.ComputedHeight());
     228             : 
     229             :   printf(" *\n");
     230             : 
     231             : #endif
     232             : 
     233          12 :   aStatus.Reset();
     234             : 
     235             :   // create the layout state
     236          24 :   nsBoxLayoutState state(aPresContext, aReflowInput.mRenderingContext);
     237             : 
     238          12 :   nsSize computedSize(aReflowInput.ComputedWidth(),aReflowInput.ComputedHeight());
     239             : 
     240          12 :   nsMargin m;
     241          12 :   m = aReflowInput.ComputedPhysicalBorderPadding();
     242             : 
     243             :   //GetXULBorderAndPadding(m);
     244             : 
     245             :   // this happens sometimes. So lets handle it gracefully.
     246          12 :   if (aReflowInput.ComputedHeight() == 0) {
     247           0 :     nsSize minSize = GetXULMinSize(state);
     248           0 :     computedSize.height = minSize.height - m.top - m.bottom;
     249             :   }
     250             : 
     251          12 :   nsSize prefSize(0,0);
     252             : 
     253             :   // if we are told to layout intrinic then get our preferred size.
     254          12 :   if (computedSize.width == NS_INTRINSICSIZE || computedSize.height == NS_INTRINSICSIZE) {
     255           2 :      prefSize = GetXULPrefSize(state);
     256           2 :      nsSize minSize = GetXULMinSize(state);
     257           2 :      nsSize maxSize = GetXULMaxSize(state);
     258           2 :      prefSize = BoundsCheck(minSize, prefSize, maxSize);
     259             :   }
     260             : 
     261             :   // get our desiredSize
     262          12 :   if (aReflowInput.ComputedWidth() == NS_INTRINSICSIZE) {
     263           0 :     computedSize.width = prefSize.width;
     264             :   } else {
     265          12 :     computedSize.width += m.left + m.right;
     266             :   }
     267             : 
     268          12 :   if (aReflowInput.ComputedHeight() == NS_INTRINSICSIZE) {
     269           2 :     computedSize.height = prefSize.height;
     270             :   } else {
     271          10 :     computedSize.height += m.top + m.bottom;
     272             :   }
     273             : 
     274             :   // handle reflow state min and max sizes
     275             :   // XXXbz the width handling here seems to be wrong, since
     276             :   // mComputedMin/MaxWidth is a content-box size, whole
     277             :   // computedSize.width is a border-box size...
     278          12 :   if (computedSize.width > aReflowInput.ComputedMaxWidth())
     279           0 :     computedSize.width = aReflowInput.ComputedMaxWidth();
     280             : 
     281          12 :   if (computedSize.width < aReflowInput.ComputedMinWidth())
     282           0 :     computedSize.width = aReflowInput.ComputedMinWidth();
     283             : 
     284             :   // Now adjust computedSize.height for our min and max computed
     285             :   // height.  The only problem is that those are content-box sizes,
     286             :   // while computedSize.height is a border-box size.  So subtract off
     287             :   // m.TopBottom() before adjusting, then readd it.
     288          12 :   computedSize.height = std::max(0, computedSize.height - m.TopBottom());
     289          12 :   computedSize.height = NS_CSS_MINMAX(computedSize.height,
     290             :                                       aReflowInput.ComputedMinHeight(),
     291             :                                       aReflowInput.ComputedMaxHeight());
     292          12 :   computedSize.height += m.TopBottom();
     293             : 
     294          24 :   nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height);
     295             : 
     296          12 :   SetXULBounds(state, r);
     297             : 
     298             :   // layout our children
     299          12 :   XULLayout(state);
     300             : 
     301             :   // ok our child could have gotten bigger. So lets get its bounds
     302          12 :   aDesiredSize.Width() = mRect.width;
     303          12 :   aDesiredSize.Height() = mRect.height;
     304          12 :   aDesiredSize.SetBlockStartAscent(GetXULBoxAscent(state));
     305             : 
     306             :   // the overflow rect is set in SetXULBounds() above
     307          12 :   aDesiredSize.mOverflowAreas = GetOverflowAreas();
     308             : 
     309             : #ifdef DO_NOISY_REFLOW
     310             :   {
     311             :     printf("%p ** nsLBF(done) W:%d H:%d  ", this, aDesiredSize.Width(), aDesiredSize.Height());
     312             : 
     313             :     if (maxElementWidth) {
     314             :       printf("MW:%d\n", *maxElementWidth);
     315             :     } else {
     316             :       printf("MW:?\n");
     317             :     }
     318             : 
     319             :   }
     320             : #endif
     321          12 : }
     322             : 
     323             : #ifdef DEBUG_FRAME_DUMP
     324             : nsresult
     325           0 : nsLeafBoxFrame::GetFrameName(nsAString& aResult) const
     326             : {
     327           0 :   return MakeFrameName(NS_LITERAL_STRING("LeafBox"), aResult);
     328             : }
     329             : #endif
     330             : 
     331             : nsresult
     332           0 : nsLeafBoxFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
     333             : {
     334           0 :   MarkIntrinsicISizesDirty();
     335           0 :   return nsLeafFrame::CharacterDataChanged(aInfo);
     336             : }
     337             : 
     338             : /* virtual */ nsSize
     339          67 : nsLeafBoxFrame::GetXULPrefSize(nsBoxLayoutState& aState)
     340             : {
     341          67 :     return nsBox::GetXULPrefSize(aState);
     342             : }
     343             : 
     344             : /* virtual */ nsSize
     345         109 : nsLeafBoxFrame::GetXULMinSize(nsBoxLayoutState& aState)
     346             : {
     347         109 :     return nsBox::GetXULMinSize(aState);
     348             : }
     349             : 
     350             : /* virtual */ nsSize
     351         860 : nsLeafBoxFrame::GetXULMaxSize(nsBoxLayoutState& aState)
     352             : {
     353         860 :     return nsBox::GetXULMaxSize(aState);
     354             : }
     355             : 
     356             : /* virtual */ nscoord
     357         218 : nsLeafBoxFrame::GetXULFlex()
     358             : {
     359         218 :     return nsBox::GetXULFlex();
     360             : }
     361             : 
     362             : /* virtual */ nscoord
     363          82 : nsLeafBoxFrame::GetXULBoxAscent(nsBoxLayoutState& aState)
     364             : {
     365          82 :     return nsBox::GetXULBoxAscent(aState);
     366             : }
     367             : 
     368             : /* virtual */ void
     369         162 : nsLeafBoxFrame::MarkIntrinsicISizesDirty()
     370             : {
     371             :   // Don't call base class method, since everything it does is within an
     372             :   // IsXULBoxWrapped check.
     373         162 : }
     374             : 
     375             : NS_IMETHODIMP
     376         165 : nsLeafBoxFrame::DoXULLayout(nsBoxLayoutState& aState)
     377             : {
     378         165 :     return nsBox::DoXULLayout(aState);
     379             : }

Generated by: LCOV version 1.13