LCOV - code coverage report
Current view: top level - layout/generic - BRFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 60 94 63.8 %
Date: 2017-07-14 16:53:18 Functions: 11 18 61.1 %
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             : /* rendering object for HTML <br> elements */
       7             : 
       8             : #include "gfxContext.h"
       9             : #include "nsCOMPtr.h"
      10             : #include "nsContainerFrame.h"
      11             : #include "nsFontMetrics.h"
      12             : #include "nsFrame.h"
      13             : #include "nsPresContext.h"
      14             : #include "nsLineLayout.h"
      15             : #include "nsStyleConsts.h"
      16             : #include "nsGkAtoms.h"
      17             : #include "nsLayoutUtils.h"
      18             : 
      19             : //FOR SELECTION
      20             : #include "nsIContent.h"
      21             : //END INCLUDES FOR SELECTION
      22             : 
      23             : using namespace mozilla;
      24             : 
      25             : namespace mozilla {
      26             : 
      27             : class BRFrame final : public nsFrame
      28             : {
      29             : public:
      30          41 :   NS_DECL_FRAMEARENA_HELPERS(BRFrame)
      31             : 
      32             :   friend nsIFrame* ::NS_NewBRFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
      33             : 
      34             :   virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint) override;
      35             : 
      36             :   virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) override;
      37             :   virtual FrameSearchResult
      38             :   PeekOffsetCharacter(bool aForward, int32_t* aOffset,
      39             :                       PeekOffsetCharacterOptions aOptions =
      40             :                         PeekOffsetCharacterOptions()) override;
      41             :   virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace,
      42             :                               bool aIsKeyboardSelect, int32_t* aOffset,
      43             :                               PeekWordState* aState) override;
      44             : 
      45             :   virtual void Reflow(nsPresContext* aPresContext,
      46             :                           ReflowOutput& aDesiredSize,
      47             :                           const ReflowInput& aReflowInput,
      48             :                           nsReflowStatus& aStatus) override;
      49             :   virtual void AddInlineMinISize(gfxContext *aRenderingContext,
      50             :                                  InlineMinISizeData *aData) override;
      51             :   virtual void AddInlinePrefISize(gfxContext *aRenderingContext,
      52             :                                   InlinePrefISizeData *aData) override;
      53             :   virtual nscoord GetMinISize(gfxContext *aRenderingContext) override;
      54             :   virtual nscoord GetPrefISize(gfxContext *aRenderingContext) override;
      55             :   virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
      56             : 
      57          79 :   virtual bool IsFrameOfType(uint32_t aFlags) const override
      58             :   {
      59          79 :     return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced |
      60          79 :                                              nsIFrame::eLineParticipant));
      61             :   }
      62             : 
      63             : #ifdef ACCESSIBILITY
      64             :   virtual mozilla::a11y::AccType AccessibleType() override;
      65             : #endif
      66             : 
      67             : protected:
      68           2 :   explicit BRFrame(nsStyleContext* aContext)
      69           2 :     : nsFrame(aContext, kClassID)
      70           2 :     , mAscent(NS_INTRINSIC_WIDTH_UNKNOWN)
      71           2 :   {}
      72             : 
      73             :   virtual ~BRFrame();
      74             : 
      75             :   nscoord mAscent;
      76             : };
      77             : 
      78             : } // namespace mozilla
      79             : 
      80             : nsIFrame*
      81           2 : NS_NewBRFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      82             : {
      83           2 :   return new (aPresShell) BRFrame(aContext);
      84             : }
      85             : 
      86           2 : NS_IMPL_FRAMEARENA_HELPERS(BRFrame)
      87             : 
      88           2 : BRFrame::~BRFrame()
      89             : {
      90           2 : }
      91             : 
      92             : void
      93           9 : BRFrame::Reflow(nsPresContext* aPresContext,
      94             :                 ReflowOutput& aMetrics,
      95             :                 const ReflowInput& aReflowInput,
      96             :                 nsReflowStatus& aStatus)
      97             : {
      98           9 :   MarkInReflow();
      99           9 :   DO_GLOBAL_REFLOW_COUNT("BRFrame");
     100          18 :   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
     101           9 :   WritingMode wm = aReflowInput.GetWritingMode();
     102           9 :   LogicalSize finalSize(wm);
     103           9 :   finalSize.BSize(wm) = 0; // BR frames with block size 0 are ignored in quirks
     104             :                            // mode by nsLineLayout::VerticalAlignFrames .
     105             :                            // However, it's not always 0.  See below.
     106           9 :   finalSize.ISize(wm) = 0;
     107           9 :   aMetrics.SetBlockStartAscent(0);
     108             : 
     109             :   // Only when the BR is operating in a line-layout situation will it
     110             :   // behave like a BR. Additionally, we suppress breaks from BR inside
     111             :   // of ruby frames. To determine if we're inside ruby, we have to rely
     112             :   // on the *parent's* ShouldSuppressLineBreak() method, instead of our
     113             :   // own, because we may have custom "display" value that makes our
     114             :   // ShouldSuppressLineBreak() return false.
     115           9 :   nsLineLayout* ll = aReflowInput.mLineLayout;
     116           9 :   if (ll && !GetParent()->StyleContext()->ShouldSuppressLineBreak()) {
     117             :     // Note that the compatibility mode check excludes AlmostStandards
     118             :     // mode, since this is the inline box model.  See bug 161691.
     119           9 :     if ( ll->LineIsEmpty() ||
     120           0 :          aPresContext->CompatibilityMode() == eCompatibility_FullStandards ) {
     121             :       // The line is logically empty; any whitespace is trimmed away.
     122             :       //
     123             :       // If this frame is going to terminate the line we know
     124             :       // that nothing else will go on the line. Therefore, in this
     125             :       // case, we provide some height for the BR frame so that it
     126             :       // creates some vertical whitespace.  It's necessary to use the
     127             :       // line-height rather than the font size because the
     128             :       // quirks-mode fix that doesn't apply the block's min
     129             :       // line-height makes this necessary to make BR cause a line
     130             :       // of the full line-height
     131             : 
     132             :       // We also do this in strict mode because BR should act like a
     133             :       // normal inline frame.  That line-height is used is important
     134             :       // here for cases where the line-height is less than 1.
     135             :       RefPtr<nsFontMetrics> fm =
     136          18 :         nsLayoutUtils::GetInflatedFontMetricsForFrame(this);
     137           9 :       if (fm) {
     138           9 :         nscoord logicalHeight = aReflowInput.CalcLineHeight();
     139           9 :         finalSize.BSize(wm) = logicalHeight;
     140           9 :         aMetrics.SetBlockStartAscent(nsLayoutUtils::GetCenteredFontBaseline(
     141          18 :                                        fm, logicalHeight, wm.IsLineInverted()));
     142             :       }
     143             :       else {
     144           0 :         aMetrics.SetBlockStartAscent(aMetrics.BSize(wm) = 0);
     145             :       }
     146             : 
     147             :       // XXX temporary until I figure out a better solution; see the
     148             :       // code in nsLineLayout::VerticalAlignFrames that zaps minY/maxY
     149             :       // if the width is zero.
     150             :       // XXX This also fixes bug 10036!
     151             :       // Warning: nsTextControlFrame::CalculateSizeStandard depends on
     152             :       // the following line, see bug 228752.
     153             :       // The code below in AddInlinePrefISize also adds 1 appunit to width
     154           9 :       finalSize.ISize(wm) = 1;
     155             :     }
     156             : 
     157             :     // Return our reflow status
     158           9 :     StyleClear breakType = aReflowInput.mStyleDisplay->PhysicalBreakType(wm);
     159           9 :     if (StyleClear::None == breakType) {
     160           9 :       breakType = StyleClear::Line;
     161             :     }
     162             : 
     163           9 :     aStatus.Reset();
     164           9 :     aStatus.SetInlineLineBreakAfter(breakType);
     165           9 :     ll->SetLineEndsInBR(true);
     166             :   }
     167             :   else {
     168           0 :     aStatus.Reset();
     169             :   }
     170             : 
     171           9 :   aMetrics.SetSize(wm, finalSize);
     172           9 :   aMetrics.SetOverflowAreasToDesiredBounds();
     173             : 
     174           9 :   mAscent = aMetrics.BlockStartAscent();
     175             : 
     176           9 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics);
     177           9 : }
     178             : 
     179             : /* virtual */ void
     180           2 : BRFrame::AddInlineMinISize(gfxContext *aRenderingContext,
     181             :                            nsIFrame::InlineMinISizeData *aData)
     182             : {
     183           2 :   if (!GetParent()->StyleContext()->ShouldSuppressLineBreak()) {
     184           2 :     aData->ForceBreak();
     185             :   }
     186           2 : }
     187             : 
     188             : /* virtual */ void
     189           2 : BRFrame::AddInlinePrefISize(gfxContext *aRenderingContext,
     190             :                             nsIFrame::InlinePrefISizeData *aData)
     191             : {
     192           2 :   if (!GetParent()->StyleContext()->ShouldSuppressLineBreak()) {
     193             :     // Match the 1 appunit width assigned in the Reflow method above
     194           2 :     aData->mCurrentLine += 1;
     195           2 :     aData->ForceBreak();
     196             :   }
     197           2 : }
     198             : 
     199             : /* virtual */ nscoord
     200           9 : BRFrame::GetMinISize(gfxContext *aRenderingContext)
     201             : {
     202           9 :   nscoord result = 0;
     203          18 :   DISPLAY_MIN_WIDTH(this, result);
     204          18 :   return result;
     205             : }
     206             : 
     207             : /* virtual */ nscoord
     208           9 : BRFrame::GetPrefISize(gfxContext *aRenderingContext)
     209             : {
     210           9 :   nscoord result = 0;
     211          18 :   DISPLAY_PREF_WIDTH(this, result);
     212          18 :   return result;
     213             : }
     214             : 
     215             : nscoord
     216           0 : BRFrame::GetLogicalBaseline(mozilla::WritingMode aWritingMode) const
     217             : {
     218           0 :   return mAscent;
     219             : }
     220             : 
     221           0 : nsIFrame::ContentOffsets BRFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoint)
     222             : {
     223           0 :   ContentOffsets offsets;
     224           0 :   offsets.content = mContent->GetParent();
     225           0 :   if (offsets.content) {
     226           0 :     offsets.offset = offsets.content->IndexOf(mContent);
     227           0 :     offsets.secondaryOffset = offsets.offset;
     228           0 :     offsets.associate = CARET_ASSOCIATE_AFTER;
     229             :   }
     230           0 :   return offsets;
     231             : }
     232             : 
     233             : nsIFrame::FrameSearchResult
     234           0 : BRFrame::PeekOffsetNoAmount(bool aForward, int32_t* aOffset)
     235             : {
     236           0 :   NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
     237           0 :   int32_t startOffset = *aOffset;
     238             :   // If we hit the end of a BR going backwards, go to its beginning and stay there.
     239           0 :   if (!aForward && startOffset != 0) {
     240           0 :     *aOffset = 0;
     241           0 :     return FOUND;
     242             :   }
     243             :   // Otherwise, stop if we hit the beginning, continue (forward) if we hit the end.
     244           0 :   return (startOffset == 0) ? FOUND : CONTINUE;
     245             : }
     246             : 
     247             : nsIFrame::FrameSearchResult
     248           0 : BRFrame::PeekOffsetCharacter(bool aForward, int32_t* aOffset,
     249             :                              PeekOffsetCharacterOptions aOptions)
     250             : {
     251           0 :   NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
     252             :   // Keep going. The actual line jumping will stop us.
     253           0 :   return CONTINUE;
     254             : }
     255             : 
     256             : nsIFrame::FrameSearchResult
     257           0 : BRFrame::PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
     258             :                         int32_t* aOffset, PeekWordState* aState)
     259             : {
     260           0 :   NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
     261             :   // Keep going. The actual line jumping will stop us.
     262           0 :   return CONTINUE;
     263             : }
     264             : 
     265             : #ifdef ACCESSIBILITY
     266             : a11y::AccType
     267           0 : BRFrame::AccessibleType()
     268             : {
     269           0 :   nsIContent *parent = mContent->GetParent();
     270           0 :   if (parent && parent->IsRootOfNativeAnonymousSubtree() &&
     271           0 :       parent->GetChildCount() == 1) {
     272             :     // This <br> is the only node in a text control, therefore it is the hacky
     273             :     // "bogus node" used when there is no text in the control
     274           0 :     return a11y::eNoType;
     275             :   }
     276             : 
     277             :   // Trailing HTML br element don't play any difference. We don't need to expose
     278             :   // it to AT (see bug https://bugzilla.mozilla.org/show_bug.cgi?id=899433#c16
     279             :   // for details).
     280           0 :   if (!mContent->GetNextSibling() && !GetNextSibling()) {
     281           0 :     return a11y::eNoType;
     282             :   }
     283             : 
     284           0 :   return a11y::eHTMLBRType;
     285             : }
     286             : #endif
     287             : 

Generated by: LCOV version 1.13