LCOV - code coverage report
Current view: top level - layout/forms - nsProgressFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 126 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
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             : #include "nsProgressFrame.h"
       7             : 
       8             : #include "nsIContent.h"
       9             : #include "nsPresContext.h"
      10             : #include "nsGkAtoms.h"
      11             : #include "nsNameSpaceManager.h"
      12             : #include "nsIDocument.h"
      13             : #include "nsIPresShell.h"
      14             : #include "nsNodeInfoManager.h"
      15             : #include "nsContentCreatorFunctions.h"
      16             : #include "nsContentUtils.h"
      17             : #include "nsFormControlFrame.h"
      18             : #include "nsFontMetrics.h"
      19             : #include "mozilla/dom/Element.h"
      20             : #include "mozilla/dom/HTMLProgressElement.h"
      21             : #include "nsContentList.h"
      22             : #include "nsCSSPseudoElements.h"
      23             : #include "nsStyleSet.h"
      24             : #include "mozilla/StyleSetHandle.h"
      25             : #include "mozilla/StyleSetHandleInlines.h"
      26             : #include "nsThemeConstants.h"
      27             : #include <algorithm>
      28             : 
      29             : using namespace mozilla;
      30             : using namespace mozilla::dom;
      31             : 
      32             : nsIFrame*
      33           0 : NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      34             : {
      35           0 :   return new (aPresShell) nsProgressFrame(aContext);
      36             : }
      37             : 
      38           0 : NS_IMPL_FRAMEARENA_HELPERS(nsProgressFrame)
      39             : 
      40           0 : nsProgressFrame::nsProgressFrame(nsStyleContext* aContext)
      41             :   : nsContainerFrame(aContext, kClassID)
      42           0 :   , mBarDiv(nullptr)
      43             : {
      44           0 : }
      45             : 
      46           0 : nsProgressFrame::~nsProgressFrame()
      47             : {
      48           0 : }
      49             : 
      50             : void
      51           0 : nsProgressFrame::DestroyFrom(nsIFrame* aDestructRoot)
      52             : {
      53           0 :   NS_ASSERTION(!GetPrevContinuation(),
      54             :                "nsProgressFrame should not have continuations; if it does we "
      55             :                "need to call RegUnregAccessKey only for the first.");
      56           0 :   nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
      57           0 :   nsContentUtils::DestroyAnonymousContent(&mBarDiv);
      58           0 :   nsContainerFrame::DestroyFrom(aDestructRoot);
      59           0 : }
      60             : 
      61             : nsresult
      62           0 : nsProgressFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
      63             : {
      64             :   // Create the progress bar div.
      65           0 :   nsCOMPtr<nsIDocument> doc = mContent->GetComposedDoc();
      66           0 :   mBarDiv = doc->CreateHTMLElement(nsGkAtoms::div);
      67             : 
      68             :   // Associate ::-moz-progress-bar pseudo-element to the anonymous child.
      69           0 :   mBarDiv->SetPseudoElementType(CSSPseudoElementType::mozProgressBar);
      70             : 
      71           0 :   if (!aElements.AppendElement(mBarDiv)) {
      72           0 :     return NS_ERROR_OUT_OF_MEMORY;
      73             :   }
      74             : 
      75           0 :   return NS_OK;
      76             : }
      77             : 
      78             : void
      79           0 : nsProgressFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
      80             :                                           uint32_t aFilter)
      81             : {
      82           0 :   if (mBarDiv) {
      83           0 :     aElements.AppendElement(mBarDiv);
      84             :   }
      85           0 : }
      86             : 
      87           0 : NS_QUERYFRAME_HEAD(nsProgressFrame)
      88           0 :   NS_QUERYFRAME_ENTRY(nsProgressFrame)
      89           0 :   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
      90           0 : NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
      91             : 
      92             : 
      93             : void
      94           0 : nsProgressFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
      95             :                                   const nsRect&           aDirtyRect,
      96             :                                   const nsDisplayListSet& aLists)
      97             : {
      98           0 :   BuildDisplayListForInline(aBuilder, aDirtyRect, aLists);
      99           0 : }
     100             : 
     101             : void
     102           0 : nsProgressFrame::Reflow(nsPresContext*           aPresContext,
     103             :                         ReflowOutput&     aDesiredSize,
     104             :                         const ReflowInput& aReflowInput,
     105             :                         nsReflowStatus&          aStatus)
     106             : {
     107           0 :   MarkInReflow();
     108           0 :   DO_GLOBAL_REFLOW_COUNT("nsProgressFrame");
     109           0 :   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
     110             : 
     111           0 :   NS_ASSERTION(mBarDiv, "Progress bar div must exist!");
     112           0 :   NS_ASSERTION(PrincipalChildList().GetLength() == 1 &&
     113             :                PrincipalChildList().FirstChild() == mBarDiv->GetPrimaryFrame(),
     114             :                "unexpected child frames");
     115           0 :   NS_ASSERTION(!GetPrevContinuation(),
     116             :                "nsProgressFrame should not have continuations; if it does we "
     117             :                "need to call RegUnregAccessKey only for the first.");
     118             : 
     119           0 :   if (mState & NS_FRAME_FIRST_REFLOW) {
     120           0 :     nsFormControlFrame::RegUnRegAccessKey(this, true);
     121             :   }
     122             : 
     123           0 :   aDesiredSize.SetSize(aReflowInput.GetWritingMode(),
     124           0 :                        aReflowInput.ComputedSizeWithBorderPadding());
     125           0 :   aDesiredSize.SetOverflowAreasToDesiredBounds();
     126             : 
     127           0 :   for (auto childFrame : PrincipalChildList()) {
     128           0 :     ReflowChildFrame(childFrame, aPresContext, aReflowInput, aStatus);
     129           0 :     ConsiderChildOverflow(aDesiredSize.mOverflowAreas, childFrame);
     130             :   }
     131             : 
     132           0 :   FinishAndStoreOverflow(&aDesiredSize);
     133             : 
     134           0 :   aStatus.Reset();
     135             : 
     136           0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
     137           0 : }
     138             : 
     139             : void
     140           0 : nsProgressFrame::ReflowChildFrame(nsIFrame*          aChild,
     141             :                                   nsPresContext*     aPresContext,
     142             :                                   const ReflowInput& aReflowInput,
     143             :                                   nsReflowStatus&    aStatus)
     144             : {
     145           0 :   bool vertical = ResolvedOrientationIsVertical();
     146           0 :   WritingMode wm = aChild->GetWritingMode();
     147           0 :   LogicalSize availSize = aReflowInput.ComputedSize(wm);
     148           0 :   availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     149           0 :   ReflowInput reflowInput(aPresContext, aReflowInput, aChild, availSize);
     150           0 :   nscoord size = vertical ? aReflowInput.ComputedHeight()
     151           0 :                           : aReflowInput.ComputedWidth();
     152           0 :   nscoord xoffset = aReflowInput.ComputedPhysicalBorderPadding().left;
     153           0 :   nscoord yoffset = aReflowInput.ComputedPhysicalBorderPadding().top;
     154             : 
     155           0 :   double position = static_cast<HTMLProgressElement*>(mContent)->Position();
     156             : 
     157             :   // Force the bar's size to match the current progress.
     158             :   // When indeterminate, the progress' size will be 100%.
     159           0 :   if (position >= 0.0) {
     160           0 :     size *= position;
     161             :   }
     162             : 
     163           0 :   if (!vertical && (wm.IsVertical() ? wm.IsVerticalRL() : !wm.IsBidiLTR())) {
     164           0 :     xoffset += aReflowInput.ComputedWidth() - size;
     165             :   }
     166             : 
     167             :   // The bar size is fixed in these cases:
     168             :   // - the progress position is determined: the bar size is fixed according
     169             :   //   to it's value.
     170             :   // - the progress position is indeterminate and the bar appearance should be
     171             :   //   shown as native: the bar size is forced to 100%.
     172             :   // Otherwise (when the progress is indeterminate and the bar appearance isn't
     173             :   // native), the bar size isn't fixed and can be set by the author.
     174           0 :   if (position != -1 || ShouldUseNativeStyle()) {
     175           0 :     if (vertical) {
     176             :       // We want the bar to begin at the bottom.
     177           0 :       yoffset += aReflowInput.ComputedHeight() - size;
     178             : 
     179           0 :       size -= reflowInput.ComputedPhysicalMargin().TopBottom() +
     180           0 :               reflowInput.ComputedPhysicalBorderPadding().TopBottom();
     181           0 :       size = std::max(size, 0);
     182           0 :       reflowInput.SetComputedHeight(size);
     183             :     } else {
     184           0 :       size -= reflowInput.ComputedPhysicalMargin().LeftRight() +
     185           0 :               reflowInput.ComputedPhysicalBorderPadding().LeftRight();
     186           0 :       size = std::max(size, 0);
     187           0 :       reflowInput.SetComputedWidth(size);
     188             :     }
     189           0 :   } else if (vertical) {
     190             :     // For vertical progress bars, we need to position the bar specificly when
     191             :     // the width isn't constrained (position == -1 and !ShouldUseNativeStyle())
     192             :     // because aReflowInput.ComputedHeight() - size == 0.
     193           0 :     yoffset += aReflowInput.ComputedHeight() - reflowInput.ComputedHeight();
     194             :   }
     195             : 
     196           0 :   xoffset += reflowInput.ComputedPhysicalMargin().left;
     197           0 :   yoffset += reflowInput.ComputedPhysicalMargin().top;
     198             : 
     199           0 :   ReflowOutput barDesiredSize(aReflowInput);
     200           0 :   ReflowChild(aChild, aPresContext, barDesiredSize, reflowInput, xoffset,
     201           0 :               yoffset, 0, aStatus);
     202             :   FinishReflowChild(aChild, aPresContext, barDesiredSize, &reflowInput,
     203           0 :                     xoffset, yoffset, 0);
     204           0 : }
     205             : 
     206             : nsresult
     207           0 : nsProgressFrame::AttributeChanged(int32_t  aNameSpaceID,
     208             :                                   nsIAtom* aAttribute,
     209             :                                   int32_t  aModType)
     210             : {
     211           0 :   NS_ASSERTION(mBarDiv, "Progress bar div must exist!");
     212             : 
     213           0 :   if (aNameSpaceID == kNameSpaceID_None &&
     214           0 :       (aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::max)) {
     215           0 :     auto shell = PresContext()->PresShell();
     216           0 :     for (auto childFrame : PrincipalChildList()) {
     217             :       shell->FrameNeedsReflow(childFrame, nsIPresShell::eResize,
     218           0 :                               NS_FRAME_IS_DIRTY);
     219             :     }
     220           0 :     InvalidateFrame();
     221             :   }
     222             : 
     223           0 :   return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
     224             : }
     225             : 
     226             : LogicalSize
     227           0 : nsProgressFrame::ComputeAutoSize(gfxContext*         aRenderingContext,
     228             :                                  WritingMode         aWM,
     229             :                                  const LogicalSize&  aCBSize,
     230             :                                  nscoord             aAvailableISize,
     231             :                                  const LogicalSize&  aMargin,
     232             :                                  const LogicalSize&  aBorder,
     233             :                                  const LogicalSize&  aPadding,
     234             :                                  ComputeSizeFlags    aFlags)
     235             : {
     236           0 :   const WritingMode wm = GetWritingMode();
     237           0 :   LogicalSize autoSize(wm);
     238           0 :   autoSize.BSize(wm) = autoSize.ISize(wm) =
     239           0 :     NSToCoordRound(StyleFont()->mFont.size *
     240           0 :                    nsLayoutUtils::FontSizeInflationFor(this)); // 1em
     241             : 
     242           0 :   if (ResolvedOrientationIsVertical() == wm.IsVertical()) {
     243           0 :     autoSize.ISize(wm) *= 10; // 10em
     244             :   } else {
     245           0 :     autoSize.BSize(wm) *= 10; // 10em
     246             :   }
     247             : 
     248           0 :   return autoSize.ConvertTo(aWM, wm);
     249             : }
     250             : 
     251             : nscoord
     252           0 : nsProgressFrame::GetMinISize(gfxContext *aRenderingContext)
     253             : {
     254             :   RefPtr<nsFontMetrics> fontMet =
     255           0 :     nsLayoutUtils::GetFontMetricsForFrame(this, 1.0f);
     256             : 
     257           0 :   nscoord minISize = fontMet->Font().size; // 1em
     258             : 
     259           0 :   if (ResolvedOrientationIsVertical() == GetWritingMode().IsVertical()) {
     260             :     // The orientation is inline
     261           0 :     minISize *= 10; // 10em
     262             :   }
     263             : 
     264           0 :   return minISize;
     265             : }
     266             : 
     267             : nscoord
     268           0 : nsProgressFrame::GetPrefISize(gfxContext *aRenderingContext)
     269             : {
     270           0 :   return GetMinISize(aRenderingContext);
     271             : }
     272             : 
     273             : bool
     274           0 : nsProgressFrame::ShouldUseNativeStyle() const
     275             : {
     276           0 :   nsIFrame* barFrame = PrincipalChildList().FirstChild();
     277             : 
     278             :   // Use the native style if these conditions are satisfied:
     279             :   // - both frames use the native appearance;
     280             :   // - neither frame has author specified rules setting the border or the
     281             :   //   background.
     282           0 :   return StyleDisplay()->mAppearance == NS_THEME_PROGRESSBAR &&
     283           0 :          !PresContext()->HasAuthorSpecifiedRules(this,
     284           0 :                                                  NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND) &&
     285           0 :          barFrame &&
     286           0 :          barFrame->StyleDisplay()->mAppearance == NS_THEME_PROGRESSCHUNK &&
     287           0 :          !PresContext()->HasAuthorSpecifiedRules(barFrame,
     288           0 :                                                  NS_AUTHOR_SPECIFIED_BORDER | NS_AUTHOR_SPECIFIED_BACKGROUND);
     289             : }
     290             : 
     291             : Element*
     292           0 : nsProgressFrame::GetPseudoElement(CSSPseudoElementType aType)
     293             : {
     294           0 :   if (aType == CSSPseudoElementType::mozProgressBar) {
     295           0 :     return mBarDiv;
     296             :   }
     297             : 
     298           0 :   return nsContainerFrame::GetPseudoElement(aType);
     299             : }

Generated by: LCOV version 1.13