layout/xul/nsLeafBoxFrame.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     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/. */
     6 //
     7 // Eric Vaughan
     8 // Netscape Communications
     9 //
    10 // See documentation in associated header file
    11 //
    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>
    28 //
    29 // NS_NewLeafBoxFrame
    30 //
    31 // Creates a new Toolbar frame and returns it
    32 //
    33 nsIFrame*
    34 NS_NewLeafBoxFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
    35 {
    36   return new (aPresShell) nsLeafBoxFrame(aPresShell, aContext);
    37 }
    39 NS_IMPL_FRAMEARENA_HELPERS(nsLeafBoxFrame)
    41 nsLeafBoxFrame::nsLeafBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext)
    42     : nsLeafFrame(aContext)
    43 {
    44 }
    46 #ifdef DEBUG_LAYOUT
    47 void
    48 nsLeafBoxFrame::GetBoxName(nsAutoString& aName)
    49 {
    50    GetFrameName(aName);
    51 }
    52 #endif
    55 /**
    56  * Initialize us. This is a good time to get the alignment of the box
    57  */
    58 void
    59 nsLeafBoxFrame::Init(
    60               nsIContent*      aContent,
    61               nsIFrame*        aParent,
    62               nsIFrame*        aPrevInFlow)
    63 {
    64   nsLeafFrame::Init(aContent, aParent, aPrevInFlow);
    66   if (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER) {
    67     AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
    68   }
    70   UpdateMouseThrough();
    71 }
    73 nsresult
    74 nsLeafBoxFrame::AttributeChanged(int32_t aNameSpaceID,
    75                                  nsIAtom* aAttribute,
    76                                  int32_t aModType)
    77 {
    78   nsresult rv = nsLeafFrame::AttributeChanged(aNameSpaceID, aAttribute,
    79                                               aModType);
    81   if (aAttribute == nsGkAtoms::mousethrough) 
    82     UpdateMouseThrough();
    84   return rv;
    85 }
    87 void nsLeafBoxFrame::UpdateMouseThrough()
    88 {
    89   if (mContent) {
    90     static nsIContent::AttrValuesArray strings[] =
    91       {&nsGkAtoms::never, &nsGkAtoms::always, nullptr};
    92     switch (mContent->FindAttrValueIn(kNameSpaceID_None,
    93                                       nsGkAtoms::mousethrough,
    94                                       strings, eCaseMatters)) {
    95       case 0: AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); break;
    96       case 1: AddStateBits(NS_FRAME_MOUSE_THROUGH_ALWAYS); break;
    97       case 2: {
    98           RemoveStateBits(NS_FRAME_MOUSE_THROUGH_ALWAYS);
    99           RemoveStateBits(NS_FRAME_MOUSE_THROUGH_NEVER);
   100           break;
   101       }
   102     }
   103   }
   104 }
   106 void
   107 nsLeafBoxFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
   108                                  const nsRect&           aDirtyRect,
   109                                  const nsDisplayListSet& aLists)
   110 {
   111   // REVIEW: GetFrameForPoint used to not report events for the background
   112   // layer, whereas this code will put an event receiver for this frame in the
   113   // BlockBorderBackground() list. But I don't see any need to preserve
   114   // that anomalous behaviour. The important thing I'm preserving is that
   115   // leaf boxes continue to receive events in the foreground layer.
   116   DisplayBorderBackgroundOutline(aBuilder, aLists);
   118   if (!aBuilder->IsForEventDelivery() || !IsVisibleForPainting(aBuilder))
   119     return;
   121   aLists.Content()->AppendNewToTop(new (aBuilder)
   122     nsDisplayEventReceiver(aBuilder, this));
   123 }
   125 /* virtual */ nscoord
   126 nsLeafBoxFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
   127 {
   128   nscoord result;
   129   DISPLAY_MIN_WIDTH(this, result);
   130   nsBoxLayoutState state(PresContext(), aRenderingContext);
   131   nsSize minSize = GetMinSize(state);
   133   // GetMinSize returns border-box width, and we want to return content
   134   // width.  Since Reflow uses the reflow state's border and padding, we
   135   // actually just want to subtract what GetMinSize added, which is the
   136   // result of GetBorderAndPadding.
   137   nsMargin bp;
   138   GetBorderAndPadding(bp);
   140   result = minSize.width - bp.LeftRight();
   142   return result;
   143 }
   145 /* virtual */ nscoord
   146 nsLeafBoxFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
   147 {
   148   nscoord result;
   149   DISPLAY_PREF_WIDTH(this, result);
   150   nsBoxLayoutState state(PresContext(), aRenderingContext);
   151   nsSize prefSize = GetPrefSize(state);
   153   // GetPrefSize returns border-box width, and we want to return content
   154   // width.  Since Reflow uses the reflow state's border and padding, we
   155   // actually just want to subtract what GetPrefSize added, which is the
   156   // result of GetBorderAndPadding.
   157   nsMargin bp;
   158   GetBorderAndPadding(bp);
   160   result = prefSize.width - bp.LeftRight();
   162   return result;
   163 }
   165 nscoord
   166 nsLeafBoxFrame::GetIntrinsicWidth()
   167 {
   168   // No intrinsic width
   169   return 0;
   170 }
   172 nsSize
   173 nsLeafBoxFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
   174                                 nsSize aCBSize, nscoord aAvailableWidth,
   175                                 nsSize aMargin, nsSize aBorder,
   176                                 nsSize aPadding, bool aShrinkWrap)
   177 {
   178   // Important: NOT calling our direct superclass here!
   179   return nsFrame::ComputeAutoSize(aRenderingContext, aCBSize, aAvailableWidth,
   180                                   aMargin, aBorder, aPadding, aShrinkWrap);
   181 }
   183 nsresult
   184 nsLeafBoxFrame::Reflow(nsPresContext*   aPresContext,
   185                      nsHTMLReflowMetrics&     aDesiredSize,
   186                      const nsHTMLReflowState& aReflowState,
   187                      nsReflowStatus&          aStatus)
   188 {
   189   // This is mostly a copy of nsBoxFrame::Reflow().
   190   // We aren't able to share an implementation because of the frame
   191   // class hierarchy.  If you make changes here, please keep
   192   // nsBoxFrame::Reflow in sync.
   194   DO_GLOBAL_REFLOW_COUNT("nsLeafBoxFrame");
   195   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
   197   NS_ASSERTION(aReflowState.ComputedWidth() >=0 &&
   198                aReflowState.ComputedHeight() >= 0, "Computed Size < 0");
   200 #ifdef DO_NOISY_REFLOW
   201   printf("\n-------------Starting LeafBoxFrame Reflow ----------------------------\n");
   202   printf("%p ** nsLBF::Reflow %d R: ", this, myCounter++);
   203   switch (aReflowState.reason) {
   204     case eReflowReason_Initial:
   205       printf("Ini");break;
   206     case eReflowReason_Incremental:
   207       printf("Inc");break;
   208     case eReflowReason_Resize:
   209       printf("Rsz");break;
   210     case eReflowReason_StyleChange:
   211       printf("Sty");break;
   212     case eReflowReason_Dirty:
   213       printf("Drt ");
   214       break;
   215     default:printf("<unknown>%d", aReflowState.reason);break;
   216   }
   218   printSize("AW", aReflowState.AvailableWidth());
   219   printSize("AH", aReflowState.AvailableHeight());
   220   printSize("CW", aReflowState.ComputedWidth());
   221   printSize("CH", aReflowState.ComputedHeight());
   223   printf(" *\n");
   225 #endif
   227   aStatus = NS_FRAME_COMPLETE;
   229   // create the layout state
   230   nsBoxLayoutState state(aPresContext, aReflowState.rendContext);
   232   nsSize computedSize(aReflowState.ComputedWidth(),aReflowState.ComputedHeight());
   234   nsMargin m;
   235   m = aReflowState.ComputedPhysicalBorderPadding();
   237   //GetBorderAndPadding(m);
   239   // this happens sometimes. So lets handle it gracefully.
   240   if (aReflowState.ComputedHeight() == 0) {
   241     nsSize minSize = GetMinSize(state);
   242     computedSize.height = minSize.height - m.top - m.bottom;
   243   }
   245   nsSize prefSize(0,0);
   247   // if we are told to layout intrinic then get our preferred size.
   248   if (computedSize.width == NS_INTRINSICSIZE || computedSize.height == NS_INTRINSICSIZE) {
   249      prefSize = GetPrefSize(state);
   250      nsSize minSize = GetMinSize(state);
   251      nsSize maxSize = GetMaxSize(state);
   252      prefSize = BoundsCheck(minSize, prefSize, maxSize);
   253   }
   255   // get our desiredSize
   256   if (aReflowState.ComputedWidth() == NS_INTRINSICSIZE) {
   257     computedSize.width = prefSize.width;
   258   } else {
   259     computedSize.width += m.left + m.right;
   260   }
   262   if (aReflowState.ComputedHeight() == NS_INTRINSICSIZE) {
   263     computedSize.height = prefSize.height;
   264   } else {
   265     computedSize.height += m.top + m.bottom;
   266   }
   268   // handle reflow state min and max sizes
   269   // XXXbz the width handling here seems to be wrong, since
   270   // mComputedMin/MaxWidth is a content-box size, whole
   271   // computedSize.width is a border-box size...
   272   if (computedSize.width > aReflowState.ComputedMaxWidth())
   273     computedSize.width = aReflowState.ComputedMaxWidth();
   275   if (computedSize.width < aReflowState.ComputedMinWidth())
   276     computedSize.width = aReflowState.ComputedMinWidth();
   278   // Now adjust computedSize.height for our min and max computed
   279   // height.  The only problem is that those are content-box sizes,
   280   // while computedSize.height is a border-box size.  So subtract off
   281   // m.TopBottom() before adjusting, then readd it.
   282   computedSize.height = std::max(0, computedSize.height - m.TopBottom());
   283   computedSize.height = NS_CSS_MINMAX(computedSize.height,
   284                                       aReflowState.ComputedMinHeight(),
   285                                       aReflowState.ComputedMaxHeight());
   286   computedSize.height += m.TopBottom();
   288   nsRect r(mRect.x, mRect.y, computedSize.width, computedSize.height);
   290   SetBounds(state, r);
   292   // layout our children
   293   Layout(state);
   295   // ok our child could have gotten bigger. So lets get its bounds
   296   aDesiredSize.Width() = mRect.width;
   297   aDesiredSize.Height() = mRect.height;
   298   aDesiredSize.SetTopAscent(GetBoxAscent(state));
   300   // the overflow rect is set in SetBounds() above
   301   aDesiredSize.mOverflowAreas = GetOverflowAreas();
   303 #ifdef DO_NOISY_REFLOW
   304   {
   305     printf("%p ** nsLBF(done) W:%d H:%d  ", this, aDesiredSize.Width(), aDesiredSize.Height());
   307     if (maxElementWidth) {
   308       printf("MW:%d\n", *maxElementWidth); 
   309     } else {
   310       printf("MW:?\n"); 
   311     }
   313   }
   314 #endif
   316   return NS_OK;
   317 }
   319 #ifdef DEBUG_FRAME_DUMP
   320 nsresult
   321 nsLeafBoxFrame::GetFrameName(nsAString& aResult) const
   322 {
   323   return MakeFrameName(NS_LITERAL_STRING("LeafBox"), aResult);
   324 }
   325 #endif
   327 nsIAtom*
   328 nsLeafBoxFrame::GetType() const
   329 {
   330   return nsGkAtoms::leafBoxFrame;
   331 }
   333 nsresult
   334 nsLeafBoxFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
   335 {
   336   MarkIntrinsicWidthsDirty();
   337   return nsLeafFrame::CharacterDataChanged(aInfo);
   338 }
   340 /* virtual */ nsSize
   341 nsLeafBoxFrame::GetPrefSize(nsBoxLayoutState& aState)
   342 {
   343     return nsBox::GetPrefSize(aState);
   344 }
   346 /* virtual */ nsSize
   347 nsLeafBoxFrame::GetMinSize(nsBoxLayoutState& aState)
   348 {
   349     return nsBox::GetMinSize(aState);
   350 }
   352 /* virtual */ nsSize
   353 nsLeafBoxFrame::GetMaxSize(nsBoxLayoutState& aState)
   354 {
   355     return nsBox::GetMaxSize(aState);
   356 }
   358 /* virtual */ nscoord
   359 nsLeafBoxFrame::GetFlex(nsBoxLayoutState& aState)
   360 {
   361     return nsBox::GetFlex(aState);
   362 }
   364 /* virtual */ nscoord
   365 nsLeafBoxFrame::GetBoxAscent(nsBoxLayoutState& aState)
   366 {
   367     return nsBox::GetBoxAscent(aState);
   368 }
   370 /* virtual */ void
   371 nsLeafBoxFrame::MarkIntrinsicWidthsDirty()
   372 {
   373   // Don't call base class method, since everything it does is within an
   374   // IsBoxWrapped check.
   375 }
   377 NS_IMETHODIMP
   378 nsLeafBoxFrame::DoLayout(nsBoxLayoutState& aState)
   379 {
   380     return nsBox::DoLayout(aState);
   381 }

mercurial