LCOV - code coverage report
Current view: top level - layout/generic - nsFrame.h (source / functions) Hit Total Coverage
Test: output.info Lines: 10 26 38.5 %
Date: 2018-08-07 16:42:27 Functions: 0 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             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /* base class of all rendering objects */
       8             : 
       9             : #ifndef nsFrame_h___
      10             : #define nsFrame_h___
      11             : 
      12             : #include "mozilla/Attributes.h"
      13             : #include "mozilla/EventForwards.h"
      14             : #include "mozilla/Likely.h"
      15             : #include "nsBox.h"
      16             : #include "mozilla/Logging.h"
      17             : 
      18             : #include "nsIPresShell.h"
      19             : #include "mozilla/ReflowInput.h"
      20             : #include "nsHTMLParts.h"
      21             : #include "nsISelectionDisplay.h"
      22             : 
      23             : namespace mozilla {
      24             : enum class TableSelection : uint32_t;
      25             : } // namespace mozilla
      26             : 
      27             : /**
      28             :  * nsFrame logging constants. We redefine the nspr
      29             :  * PRLogModuleInfo.level field to be a bitfield.  Each bit controls a
      30             :  * specific type of logging. Each logging operation has associated
      31             :  * inline methods defined below.
      32             :  *
      33             :  * Due to the redefinition of the level field we cannot use MOZ_LOG directly
      34             :  * as that will cause assertions due to invalid log levels.
      35             :  */
      36             : #define NS_FRAME_TRACE_CALLS        0x1
      37             : #define NS_FRAME_TRACE_PUSH_PULL    0x2
      38             : #define NS_FRAME_TRACE_CHILD_REFLOW 0x4
      39             : #define NS_FRAME_TRACE_NEW_FRAMES   0x8
      40             : 
      41             : #define NS_FRAME_LOG_TEST(_lm,_bit) (int(((mozilla::LogModule*)_lm)->Level()) & (_bit))
      42             : 
      43             : #ifdef DEBUG
      44             : #define NS_FRAME_LOG(_bit,_args)                                \
      45             :   PR_BEGIN_MACRO                                                \
      46             :     if (NS_FRAME_LOG_TEST(nsFrame::sFrameLogModule,_bit)) {  \
      47             :       printf_stderr _args; \
      48             :     }                                                           \
      49             :   PR_END_MACRO
      50             : #else
      51             : #define NS_FRAME_LOG(_bit,_args)
      52             : #endif
      53             : 
      54             : // XXX Need to rework this so that logging is free when it's off
      55             : #ifdef DEBUG
      56             : #define NS_FRAME_TRACE_IN(_method) Trace(_method, true)
      57             : 
      58             : #define NS_FRAME_TRACE_OUT(_method) Trace(_method, false)
      59             : 
      60             : // XXX remove me
      61             : #define NS_FRAME_TRACE_MSG(_bit,_args)                          \
      62             :   PR_BEGIN_MACRO                                                \
      63             :     if (NS_FRAME_LOG_TEST(nsFrame::sFrameLogModule,_bit)) {  \
      64             :       TraceMsg _args;                                           \
      65             :     }                                                           \
      66             :   PR_END_MACRO
      67             : 
      68             : #define NS_FRAME_TRACE(_bit,_args)                              \
      69             :   PR_BEGIN_MACRO                                                \
      70             :     if (NS_FRAME_LOG_TEST(nsFrame::sFrameLogModule,_bit)) {  \
      71             :       TraceMsg _args;                                           \
      72             :     }                                                           \
      73             :   PR_END_MACRO
      74             : 
      75             : #define NS_FRAME_TRACE_REFLOW_IN(_method) Trace(_method, true)
      76             : 
      77             : #define NS_FRAME_TRACE_REFLOW_OUT(_method, _status) \
      78             :   Trace(_method, false, _status)
      79             : 
      80             : #else
      81             : #define NS_FRAME_TRACE(_bits,_args)
      82             : #define NS_FRAME_TRACE_IN(_method)
      83             : #define NS_FRAME_TRACE_OUT(_method)
      84             : #define NS_FRAME_TRACE_MSG(_bits,_args)
      85             : #define NS_FRAME_TRACE_REFLOW_IN(_method)
      86             : #define NS_FRAME_TRACE_REFLOW_OUT(_method, _status)
      87             : #endif
      88             : 
      89             : // Frame allocation boilerplate macros. Every subclass of nsFrame must
      90             : // either use NS_{DECL,IMPL}_FRAMEARENA_HELPERS pair for allocating
      91             : // memory correctly, or use NS_DECL_ABSTRACT_FRAME to declare a frame
      92             : // class abstract and stop it from being instantiated. If a frame class
      93             : // without its own operator new and GetFrameId gets instantiated, the
      94             : // per-frame recycler lists in nsPresArena will not work correctly,
      95             : // with potentially catastrophic consequences (not enough memory is
      96             : // allocated for a frame object).
      97             : 
      98             : #define NS_DECL_FRAMEARENA_HELPERS(class)                           \
      99             :   NS_DECL_QUERYFRAME_TARGET(class)                                  \
     100             :   static constexpr nsIFrame::ClassID kClassID = nsIFrame::ClassID::class##_id;  \
     101             :   void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE;      \
     102             :   nsQueryFrame::FrameIID GetFrameId() override MOZ_MUST_OVERRIDE {  \
     103             :     return nsQueryFrame::class##_id;                                \
     104             :   }
     105             : 
     106             : #define NS_IMPL_FRAMEARENA_HELPERS(class)                         \
     107             :   void* class::operator new(size_t sz, nsIPresShell* aShell)      \
     108             :   { return aShell->AllocateFrame(nsQueryFrame::class##_id, sz); } \
     109             : 
     110             : #define NS_DECL_ABSTRACT_FRAME(class)                                   \
     111             :   void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE = delete; \
     112             :   virtual nsQueryFrame::FrameIID GetFrameId() override MOZ_MUST_OVERRIDE = 0;
     113             : 
     114             : //----------------------------------------------------------------------
     115             : 
     116             : struct nsBoxLayoutMetrics;
     117             : struct nsRect;
     118             : 
     119             : /**
     120             :  * Implementation of a simple frame that's not splittable and has no
     121             :  * child frames.
     122             :  *
     123             :  * Sets the NS_FRAME_SYNCHRONIZE_FRAME_AND_VIEW bit, so the default
     124             :  * behavior is to keep the frame and view position and size in sync.
     125             :  */
     126             : class nsFrame : public nsBox
     127             : {
     128             : public:
     129             :   /**
     130             :    * Create a new "empty" frame that maps a given piece of content into a
     131             :    * 0,0 area.
     132             :    */
     133             :   friend nsIFrame* NS_NewEmptyFrame(nsIPresShell* aShell,
     134             :                                     ComputedStyle* aStyle);
     135             : 
     136             : private:
     137             :   // Left undefined; nsFrame objects are never allocated from the heap.
     138             :   void* operator new(size_t sz) CPP_THROW_NEW;
     139             : 
     140             : protected:
     141             :   // Overridden to prevent the global delete from being called, since
     142             :   // the memory came out of an arena instead of the heap.
     143             :   //
     144             :   // Ideally this would be private and undefined, like the normal
     145             :   // operator new.  Unfortunately, the C++ standard requires an
     146             :   // overridden operator delete to be accessible to any subclass that
     147             :   // defines a virtual destructor, so we can only make it protected;
     148             :   // worse, some C++ compilers will synthesize calls to this function
     149             :   // from the "deleting destructors" that they emit in case of
     150             :   // delete-expressions, so it can't even be undefined.
     151             :   void operator delete(void* aPtr, size_t sz);
     152             : 
     153             : public:
     154             : 
     155             :   // nsQueryFrame
     156             :   NS_DECL_QUERYFRAME
     157             :   NS_DECL_QUERYFRAME_TARGET(nsFrame)
     158           0 :   virtual nsQueryFrame::FrameIID GetFrameId() MOZ_MUST_OVERRIDE {
     159           0 :     return kFrameIID;
     160             :   }
     161             :   void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE;
     162             : 
     163             :   // nsIFrame
     164             :   void Init(nsIContent*       aContent,
     165             :             nsContainerFrame* aParent,
     166             :             nsIFrame*         aPrevInFlow) override;
     167             :   void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override;
     168             :   ComputedStyle* GetAdditionalComputedStyle(int32_t aIndex) const override;
     169             :   void SetAdditionalComputedStyle(int32_t aIndex,
     170             :                                   ComputedStyle* aComputedStyle) override;
     171             :   nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override;
     172             :   const nsFrameList& GetChildList(ChildListID aListID) const override;
     173             :   void GetChildLists(nsTArray<ChildList>* aLists) const override;
     174             : 
     175             :   nsresult HandleEvent(nsPresContext* aPresContext,
     176             :                        mozilla::WidgetGUIEvent* aEvent,
     177             :                        nsEventStatus* aEventStatus) override;
     178             :   nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent,
     179             :                               nsIContent** aContent) override;
     180             :   nsresult GetCursor(const nsPoint&    aPoint,
     181             :                      nsIFrame::Cursor& aCursor) override;
     182             : 
     183             :   nsresult GetPointFromOffset(int32_t  inOffset,
     184             :                               nsPoint* outPoint) override;
     185             :   nsresult GetCharacterRectsInRange(int32_t aInOffset,
     186             :                                     int32_t aLength,
     187             :                                     nsTArray<nsRect>& aOutRect) override;
     188             : 
     189             :   nsresult GetChildFrameContainingOffset(int32_t    inContentOffset,
     190             :                                          bool       inHint,
     191             :                                          int32_t*   outFrameContentOffset,
     192             :                                          nsIFrame** outChildFrame) override;
     193             : 
     194             :   static nsresult GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
     195             :                                                  nsPeekOffsetStruct *aPos,
     196             :                                                  nsIFrame *aBlockFrame,
     197             :                                                  int32_t aLineStart,
     198             :                                                  int8_t aOutSideLimit);
     199             : 
     200             :   nsresult CharacterDataChanged(const CharacterDataChangeInfo& aInfo) override;
     201             :   nsresult AttributeChanged(int32_t  aNameSpaceID,
     202             :                             nsAtom* aAttribute,
     203             :                             int32_t aModType) override;
     204             :   nsSplittableType GetSplittableType() const override;
     205             :   nsIFrame* GetPrevContinuation() const override;
     206             :   void SetPrevContinuation(nsIFrame*) override;
     207             :   nsIFrame* GetNextContinuation() const override;
     208             :   void SetNextContinuation(nsIFrame*) override;
     209             :   nsIFrame* GetPrevInFlowVirtual() const override;
     210             :   void SetPrevInFlow(nsIFrame*) override;
     211             :   nsIFrame* GetNextInFlowVirtual() const override;
     212             :   void SetNextInFlow(nsIFrame*) override;
     213             : 
     214             :   nsresult GetSelectionController(nsPresContext *aPresContext,
     215             :                                   nsISelectionController **aSelCon) override;
     216             : 
     217             :   FrameSearchResult PeekOffsetNoAmount(bool aForward,
     218             :                                        int32_t* aOffset) override;
     219             :   FrameSearchResult
     220             :   PeekOffsetCharacter(bool aForward, int32_t* aOffset,
     221             :                       PeekOffsetCharacterOptions aOptions =
     222             :                                 PeekOffsetCharacterOptions()) override;
     223             :   FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace,
     224             :                                    bool aIsKeyboardSelect,
     225             :                                    int32_t* aOffset,
     226             :                                    PeekWordState *aState) override;
     227             :   /**
     228             :    * Check whether we should break at a boundary between punctuation and
     229             :    * non-punctuation. Only call it at a punctuation boundary
     230             :    * (i.e. exactly one of the previous and next characters are punctuation).
     231             :    * @param aForward true if we're moving forward in content order
     232             :    * @param aPunctAfter true if the next character is punctuation
     233             :    * @param aWhitespaceAfter true if the next character is whitespace
     234             :    */
     235             :   bool BreakWordBetweenPunctuation(const PeekWordState* aState,
     236             :                                    bool aForward,
     237             :                                    bool aPunctAfter, bool aWhitespaceAfter,
     238             :                                    bool aIsKeyboardSelect);
     239             : 
     240             :   nsresult CheckVisibility(nsPresContext* aContext,
     241             :                            int32_t aStartIndex, int32_t aEndIndex,
     242             :                            bool aRecurse, bool *aFinished,
     243             :                            bool *_retval) override;
     244             : 
     245             :   nsresult GetOffsets(int32_t &aStart, int32_t &aEnd) const override;
     246             :   void ChildIsDirty(nsIFrame* aChild) override;
     247             : 
     248             : #ifdef ACCESSIBILITY
     249             :   mozilla::a11y::AccType AccessibleType() override;
     250             : #endif
     251             : 
     252           0 :   ComputedStyle* GetParentComputedStyle(nsIFrame** aProviderFrame) const override {
     253           0 :     return DoGetParentComputedStyle(aProviderFrame);
     254             :   }
     255             : 
     256             :   /**
     257             :    * Do the work for getting the parent ComputedStyle frame so that
     258             :    * other frame's |GetParentComputedStyle| methods can call this
     259             :    * method on *another* frame.  (This function handles out-of-flow
     260             :    * frames by using the frame manager's placeholder map and it also
     261             :    * handles block-within-inline and generated content wrappers.)
     262             :    *
     263             :    * @param aProviderFrame (out) the frame associated with the returned value
     264             :    *   or null if the ComputedStyle is for display:contents content.
     265             :    * @return The ComputedStyle that should be the parent of this frame's
     266             :    *   ComputedStyle.  Null is permitted, and means that this frame's
     267             :    *   ComputedStyle should be the root of the ComputedStyle tree.
     268             :    */
     269             :   ComputedStyle* DoGetParentComputedStyle(nsIFrame** aProviderFrame) const;
     270             : 
     271             :   bool IsEmpty() override;
     272             :   bool IsSelfEmpty() override;
     273             : 
     274             :   void MarkIntrinsicISizesDirty() override;
     275             :   nscoord GetMinISize(gfxContext *aRenderingContext) override;
     276             :   nscoord GetPrefISize(gfxContext *aRenderingContext) override;
     277             :   void AddInlineMinISize(gfxContext *aRenderingContext,
     278             :                          InlineMinISizeData *aData) override;
     279             :   void AddInlinePrefISize(gfxContext *aRenderingContext,
     280             :                           InlinePrefISizeData *aData) override;
     281             :   IntrinsicISizeOffsetData
     282             :   IntrinsicISizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) override;
     283             :   mozilla::IntrinsicSize GetIntrinsicSize() override;
     284             :   nsSize GetIntrinsicRatio() override;
     285             : 
     286             :   mozilla::LogicalSize
     287             :   ComputeSize(gfxContext*                 aRenderingContext,
     288             :               mozilla::WritingMode        aWM,
     289             :               const mozilla::LogicalSize& aCBSize,
     290             :               nscoord                     aAvailableISize,
     291             :               const mozilla::LogicalSize& aMargin,
     292             :               const mozilla::LogicalSize& aBorder,
     293             :               const mozilla::LogicalSize& aPadding,
     294             :               ComputeSizeFlags            aFlags) override;
     295             : 
     296             :   /**
     297             :    * Calculate the used values for 'width' and 'height' for a replaced element.
     298             :    *   http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
     299             :    */
     300             :   mozilla::LogicalSize
     301             :   ComputeSizeWithIntrinsicDimensions(
     302             :               gfxContext*                   aRenderingContext,
     303             :               mozilla::WritingMode          aWM,
     304             :               const mozilla::IntrinsicSize& aIntrinsicSize,
     305             :               nsSize                        aIntrinsicRatio,
     306             :               const mozilla::LogicalSize&   aCBSize,
     307             :               const mozilla::LogicalSize&   aMargin,
     308             :               const mozilla::LogicalSize&   aBorder,
     309             :               const mozilla::LogicalSize&   aPadding,
     310             :               ComputeSizeFlags              aFlags);
     311             : 
     312             :   // Compute tight bounds assuming this frame honours its border, background
     313             :   // and outline, its children's tight bounds, and nothing else.
     314             :   nsRect ComputeSimpleTightBounds(mozilla::gfx::DrawTarget* aDrawTarget) const;
     315             : 
     316             :   /**
     317             :    * A helper, used by |nsFrame::ComputeSize| (for frames that need to
     318             :    * override only this part of ComputeSize), that computes the size
     319             :    * that should be returned when 'width', 'height', and
     320             :    * min/max-width/height are all 'auto' or equivalent.
     321             :    *
     322             :    * In general, frames that can accept any computed width/height should
     323             :    * override only ComputeAutoSize, and frames that cannot do so need to
     324             :    * override ComputeSize to enforce their width/height invariants.
     325             :    *
     326             :    * Implementations may optimize by returning a garbage width if
     327             :    * StylePosition()->mWidth.GetUnit() != eStyleUnit_Auto, and
     328             :    * likewise for height, since in such cases the result is guaranteed
     329             :    * to be unused.
     330             :    */
     331             :   virtual mozilla::LogicalSize
     332             :   ComputeAutoSize(gfxContext*                 aRenderingContext,
     333             :                   mozilla::WritingMode        aWM,
     334             :                   const mozilla::LogicalSize& aCBSize,
     335             :                   nscoord                     aAvailableISize,
     336             :                   const mozilla::LogicalSize& aMargin,
     337             :                   const mozilla::LogicalSize& aBorder,
     338             :                   const mozilla::LogicalSize& aPadding,
     339             :                   ComputeSizeFlags            aFlags);
     340             : 
     341             :   /**
     342             :    * Utility function for ComputeAutoSize implementations.  Return
     343             :    * max(GetMinISize(), min(aISizeInCB, GetPrefISize()))
     344             :    */
     345             :   nscoord ShrinkWidthToFit(gfxContext*         aRenderingContext,
     346             :                            nscoord             aISizeInCB,
     347             :                            ComputeSizeFlags    aFlags);
     348             : 
     349             :   /**
     350             :    * Calculates the size of this frame after reflowing (calling Reflow on, and
     351             :    * updating the size and position of) its children, as necessary.  The
     352             :    * calculated size is returned to the caller via the ReflowOutput
     353             :    * outparam.  (The caller is responsible for setting the actual size and
     354             :    * position of this frame.)
     355             :    *
     356             :    * A frame's children must _all_ be reflowed if the frame is dirty (the
     357             :    * NS_FRAME_IS_DIRTY bit is set on it).  Otherwise, individual children
     358             :    * must be reflowed if they are dirty or have the NS_FRAME_HAS_DIRTY_CHILDREN
     359             :    * bit set on them.  Otherwise, whether children need to be reflowed depends
     360             :    * on the frame's type (it's up to individual Reflow methods), and on what
     361             :    * has changed.  For example, a change in the width of the frame may require
     362             :    * all of its children to be reflowed (even those without dirty bits set on
     363             :    * them), whereas a change in its height might not.
     364             :    * (ReflowInput::ShouldReflowAllKids may be helpful in deciding whether
     365             :    * to reflow all the children, but for some frame types it might result in
     366             :    * over-reflow.)
     367             :    *
     368             :    * Note: if it's only the overflow rect(s) of a frame that need to be
     369             :    * updated, then UpdateOverflow should be called instead of Reflow.
     370             :    */
     371             :   void Reflow(nsPresContext*     aPresContext,
     372             :               ReflowOutput&      aDesiredSize,
     373             :               const ReflowInput& aReflowInput,
     374             :               nsReflowStatus&    aStatus) override;
     375             :   void DidReflow(nsPresContext*     aPresContext,
     376             :                  const ReflowInput* aReflowInput) override;
     377             : 
     378             :   /**
     379             :    * NOTE: aStatus is assumed to be already-initialized. The reflow statuses of
     380             :    * any reflowed absolute children will be merged into aStatus; aside from
     381             :    * that, this method won't modify aStatus.
     382             :    */
     383             :   void ReflowAbsoluteFrames(nsPresContext*     aPresContext,
     384             :                             ReflowOutput&      aDesiredSize,
     385             :                             const ReflowInput& aReflowInput,
     386             :                             nsReflowStatus&    aStatus,
     387             :                             bool               aConstrainBSize = true);
     388             :   void FinishReflowWithAbsoluteFrames(nsPresContext*     aPresContext,
     389             :                                       ReflowOutput&      aDesiredSize,
     390             :                                       const ReflowInput& aReflowInput,
     391             :                                       nsReflowStatus&    aStatus,
     392             :                                       bool aConstrainBSize = true);
     393             : 
     394             :   /*
     395             :    * If this frame is dirty, marks all absolutely-positioned children of this
     396             :    * frame dirty. If this frame isn't dirty, or if there are no
     397             :    * absolutely-positioned children, does nothing.
     398             :    *
     399             :    * It's necessary to use PushDirtyBitToAbsoluteFrames() when you plan to
     400             :    * reflow this frame's absolutely-positioned children after the dirty bit on
     401             :    * this frame has already been cleared, which prevents ReflowInput from
     402             :    * propagating the dirty bit normally. This situation generally only arises
     403             :    * when a multipass layout algorithm is used.
     404             :    */
     405             :   void PushDirtyBitToAbsoluteFrames();
     406             : 
     407             :   bool CanContinueTextRun() const override;
     408             : 
     409             :   bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
     410             : 
     411             :   void UnionChildOverflow(nsOverflowAreas& aOverflowAreas) override;
     412             : 
     413             :   // Selection Methods
     414             : 
     415             :   NS_IMETHOD HandlePress(nsPresContext* aPresContext,
     416             :                          mozilla::WidgetGUIEvent* aEvent,
     417             :                          nsEventStatus* aEventStatus);
     418             : 
     419             :   NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext,
     420             :                                  mozilla::WidgetGUIEvent* aEvent,
     421             :                                  nsEventStatus* aEventStatus,
     422             :                                  bool aControlHeld);
     423             : 
     424             :   NS_IMETHOD HandleDrag(nsPresContext* aPresContext,
     425             :                         mozilla::WidgetGUIEvent* aEvent,
     426             :                         nsEventStatus* aEventStatus);
     427             : 
     428             :   NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
     429             :                            mozilla::WidgetGUIEvent* aEvent,
     430             :                            nsEventStatus* aEventStatus);
     431             : 
     432             :   enum { SELECT_ACCUMULATE = 0x01 };
     433             : 
     434             :   nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack,
     435             :                                   nsSelectionAmount aAmountForward,
     436             :                                   int32_t aStartPos,
     437             :                                   bool aJumpLines,
     438             :                                   uint32_t aSelectFlags);
     439             : 
     440             :   nsresult SelectByTypeAtPoint(nsPresContext* aPresContext,
     441             :                                const nsPoint& aPoint,
     442             :                                nsSelectionAmount aBeginAmountType,
     443             :                                nsSelectionAmount aEndAmountType,
     444             :                                uint32_t aSelectFlags);
     445             : 
     446             :   // Helper for GetContentAndOffsetsFromPoint; calculation of content offsets
     447             :   // in this function assumes there is no child frame that can be targeted.
     448             :   virtual ContentOffsets CalcContentOffsetsFromFramePoint(const nsPoint& aPoint);
     449             : 
     450             :   // Box layout methods
     451             :   nsSize GetXULPrefSize(nsBoxLayoutState& aBoxLayoutState) override;
     452             :   nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
     453             :   nsSize GetXULMaxSize(nsBoxLayoutState& aBoxLayoutState) override;
     454             :   nscoord GetXULFlex() override;
     455             :   nscoord GetXULBoxAscent(nsBoxLayoutState& aBoxLayoutState) override;
     456             : 
     457             :   // We compute and store the HTML content's overflow area. So don't
     458             :   // try to compute it in the box code.
     459           0 :   bool ComputesOwnOverflowArea() override { return true; }
     460             : 
     461             :   //--------------------------------------------------
     462             :   // Additional methods
     463             : 
     464             :   // Helper function that tests if the frame tree is too deep; if it is
     465             :   // it marks the frame as "unflowable", zeroes out the metrics, sets
     466             :   // the reflow status, and returns true. Otherwise, the frame is
     467             :   // unmarked "unflowable" and the metrics and reflow status are not
     468             :   // touched and false is returned.
     469             :   bool IsFrameTreeTooDeep(const ReflowInput& aReflowInput,
     470             :                             ReflowOutput& aMetrics,
     471             :                             nsReflowStatus& aStatus);
     472             : 
     473             :   // Incorporate the child overflow areas into aOverflowAreas.
     474             :   // If the child does not have a overflow, use the child area.
     475             :   void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas,
     476             :                              nsIFrame* aChildFrame);
     477             : 
     478             :   /**
     479             :    * @return true if we should avoid a page/column break in this frame.
     480             :    */
     481             :   bool ShouldAvoidBreakInside(const ReflowInput& aReflowInput) const;
     482             : 
     483             : #ifdef DEBUG
     484             :   /**
     485             :    * Tracing method that writes a method enter/exit routine to the
     486             :    * nspr log using the nsIFrame log module. The tracing is only
     487             :    * done when the NS_FRAME_TRACE_CALLS bit is set in the log module's
     488             :    * level field.
     489             :    */
     490             :   void Trace(const char* aMethod, bool aEnter);
     491             :   void Trace(const char* aMethod, bool aEnter, const nsReflowStatus& aStatus);
     492             :   void TraceMsg(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
     493             : 
     494             :   // Helper function that verifies that each frame in the list has the
     495             :   // NS_FRAME_IS_DIRTY bit set
     496             :   static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
     497             : 
     498             :   // Display Reflow Debugging
     499             :   static void* DisplayReflowEnter(nsPresContext*          aPresContext,
     500             :                                   nsIFrame*                aFrame,
     501             :                                   const ReflowInput& aReflowInput);
     502             :   static void* DisplayLayoutEnter(nsIFrame* aFrame);
     503             :   static void* DisplayIntrinsicISizeEnter(nsIFrame* aFrame,
     504             :                                           const char* aType);
     505             :   static void* DisplayIntrinsicSizeEnter(nsIFrame* aFrame,
     506             :                                          const char* aType);
     507             :   static void DisplayReflowExit(nsPresContext* aPresContext,
     508             :                                 nsIFrame* aFrame,
     509             :                                 ReflowOutput& aMetrics,
     510             :                                 const nsReflowStatus& aStatus,
     511             :                                 void* aFrameTreeNode);
     512             :   static void DisplayLayoutExit(nsIFrame* aFrame,
     513             :                                  void* aFrameTreeNode);
     514             :   static void DisplayIntrinsicISizeExit(nsIFrame* aFrame,
     515             :                                          const char* aType,
     516             :                                          nscoord aResult,
     517             :                                          void* aFrameTreeNode);
     518             :   static void DisplayIntrinsicSizeExit(nsIFrame* aFrame,
     519             :                                         const char* aType,
     520             :                                         nsSize aResult,
     521             :                                         void* aFrameTreeNode);
     522             : 
     523             :   static void DisplayReflowStartup();
     524             :   static void DisplayReflowShutdown();
     525             : #endif
     526             : 
     527             :   /**
     528             :    * Adds display items for standard CSS background if necessary.
     529             :    * Does not check IsVisibleForPainting.
     530             :    * @param aForceBackground draw the background even if the frame
     531             :    * background style appears to have no background --- this is useful
     532             :    * for frames that might receive a propagated background via
     533             :    * nsCSSRendering::FindBackground
     534             :    * @return whether a themed background item was created.
     535             :    */
     536             :   bool DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
     537             :                                       const nsDisplayListSet& aLists,
     538             :                                       bool aForceBackground);
     539             :   /**
     540             :    * Adds display items for standard CSS borders, background and outline for
     541             :    * for this frame, as necessary. Checks IsVisibleForPainting and won't
     542             :    * display anything if the frame is not visible.
     543             :    * @param aForceBackground draw the background even if the frame
     544             :    * background style appears to have no background --- this is useful
     545             :    * for frames that might receive a propagated background via
     546             :    * nsCSSRendering::FindBackground
     547             :    */
     548             :   void DisplayBorderBackgroundOutline(nsDisplayListBuilder*   aBuilder,
     549             :                                       const nsDisplayListSet& aLists,
     550             :                                       bool aForceBackground = false);
     551             :   /**
     552             :    * Add a display item for the CSS outline. Does not check visibility.
     553             :    */
     554             :   void DisplayOutlineUnconditional(nsDisplayListBuilder*   aBuilder,
     555             :                                    const nsDisplayListSet& aLists);
     556             :   /**
     557             :    * Add a display item for the CSS outline, after calling
     558             :    * IsVisibleForPainting to confirm we are visible.
     559             :    */
     560             :   void DisplayOutline(nsDisplayListBuilder*   aBuilder,
     561             :                       const nsDisplayListSet& aLists);
     562             : 
     563             :   /**
     564             :    * Adjust the given parent frame to the right ComputedStyle parent frame for
     565             :    * the child, given the pseudo-type of the prospective child.  This handles
     566             :    * things like walking out of table pseudos and so forth.
     567             :    *
     568             :    * @param aProspectiveParent what GetParent() on the child returns.
     569             :    *                           Must not be null.
     570             :    * @param aChildPseudo the child's pseudo type, if any.
     571             :    */
     572             :   static nsIFrame*
     573             :   CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsAtom* aChildPseudo);
     574             : 
     575             : protected:
     576             :   // Protected constructor and destructor
     577             :   nsFrame(ComputedStyle* aStyle, ClassID aID);
     578           0 :   explicit nsFrame(ComputedStyle* aStyle)
     579           0 :     : nsFrame(aStyle, ClassID::nsFrame_id) {}
     580             :   virtual ~nsFrame();
     581             : 
     582             :   /**
     583             :    * To be called by |BuildDisplayLists| of this class or derived classes to add
     584             :    * a translucent overlay if this frame's content is selected.
     585             :    * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
     586             :    * which kind of content this is for
     587             :    */
     588             :   void DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
     589             :       nsDisplayList* aList, uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
     590             : 
     591             :   int16_t DisplaySelection(nsPresContext* aPresContext, bool isOkToTurnOn = false);
     592             : 
     593             :   // Style post processing hook
     594             :   void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
     595             : 
     596             : public:
     597             :   /**
     598             :    * Helper method to create a view for a frame.  Only used by a few sub-classes
     599             :    * that need a view.
     600             :    */
     601             :   void CreateView();
     602             : 
     603             :   //given a frame five me the first/last leaf available
     604             :   //XXX Robert O'Callahan wants to move these elsewhere
     605             :   static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
     606             :   static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
     607             : 
     608             :   // Return the line number of the aFrame, and (optionally) the containing block
     609             :   // frame.
     610             :   // If aScrollLock is true, don't break outside scrollframes when looking for a
     611             :   // containing block frame.
     612             :   static int32_t GetLineNumber(nsIFrame *aFrame,
     613             :                                bool aLockScroll,
     614             :                                nsIFrame** aContainingBlock = nullptr);
     615             : 
     616             :   /**
     617             :    * Returns true if aFrame should apply overflow clipping.
     618             :    */
     619           0 :   static bool ShouldApplyOverflowClipping(const nsIFrame* aFrame,
     620             :                                           const nsStyleDisplay* aDisp)
     621             :   {
     622             :     // clip overflow:-moz-hidden-unscrollable, except for nsListControlFrame,
     623             :     // which is an nsHTMLScrollFrame.
     624           0 :     if (MOZ_UNLIKELY(aDisp->mOverflowX == NS_STYLE_OVERFLOW_CLIP &&
     625             :                      !aFrame->IsListControlFrame())) {
     626             :       return true;
     627             :     }
     628             : 
     629             :     // contain: paint, which we should interpret as -moz-hidden-unscrollable
     630             :     // by default.
     631         996 :     if (aDisp->IsContainPaint()) {
     632             :       return true;
     633             :     }
     634             : 
     635             :     // and overflow:hidden that we should interpret as -moz-hidden-unscrollable
     636           0 :     if (aDisp->mOverflowX == NS_STYLE_OVERFLOW_HIDDEN &&
     637             :         aDisp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) {
     638             :       // REVIEW: these are the frame types that set up clipping.
     639           0 :       mozilla::LayoutFrameType type = aFrame->Type();
     640           0 :       if (type == mozilla::LayoutFrameType::Table ||
     641          84 :           type == mozilla::LayoutFrameType::TableCell ||
     642          84 :           type == mozilla::LayoutFrameType::BCTableCell ||
     643           0 :           type == mozilla::LayoutFrameType::SVGOuterSVG ||
     644           0 :           type == mozilla::LayoutFrameType::SVGInnerSVG ||
     645         168 :           type == mozilla::LayoutFrameType::SVGSymbol ||
     646          84 :           type == mozilla::LayoutFrameType::SVGForeignObject) {
     647             :         return true;
     648             :       }
     649          84 :       if (aFrame->IsFrameOfType(nsIFrame::eReplacedContainsBlock)) {
     650          16 :         if (type == mozilla::LayoutFrameType::TextInput) {
     651             :           // It always has an anonymous scroll frame that handles any overflow.
     652             :           return false;
     653             :         }
     654          16 :         return true;
     655             :       }
     656             :     }
     657             : 
     658           0 :     if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     659             :       return false;
     660             :     }
     661             : 
     662             :     // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW
     663             :     // set, then we want to clip our overflow.
     664        1857 :     return (aFrame->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW) != 0 &&
     665         969 :            aFrame->PresContext()->IsPaginated() && aFrame->IsBlockFrame();
     666             :   }
     667             : 
     668             :   nsILineIterator* GetLineIterator() override;
     669             : 
     670             : protected:
     671             : 
     672             :   // Test if we are selecting a table object:
     673             :   //  Most table/cell selection requires that Ctrl (Cmd on Mac) key is down
     674             :   //   during a mouse click or drag. Exception is using Shift+click when
     675             :   //   already in "table/cell selection mode" to extend a block selection
     676             :   //  Get the parent content node and offset of the frame
     677             :   //   of the enclosing cell or table (if not inside a cell)
     678             :   //  aTarget tells us what table element to select (currently only cell and table supported)
     679             :   //  (enums for this are defined in nsIFrame.h)
     680             :   nsresult GetDataForTableSelection(const nsFrameSelection* aFrameSelection,
     681             :                                     nsIPresShell* aPresShell,
     682             :                                     mozilla::WidgetMouseEvent* aMouseEvent,
     683             :                                     nsIContent** aParentContent,
     684             :                                     int32_t* aContentOffset,
     685             :                                     mozilla::TableSelection* aTarget);
     686             : 
     687             :   // Fills aCursor with the appropriate information from ui
     688             :   static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui,
     689             :                                              nsIFrame::Cursor& aCursor);
     690             :   NS_IMETHOD DoXULLayout(nsBoxLayoutState& aBoxLayoutState) override;
     691             : 
     692             :   nsBoxLayoutMetrics* BoxMetrics() const;
     693             : 
     694             :   // Fire DOM event. If no aContent argument use frame's mContent.
     695             :   void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr);
     696             : 
     697             : private:
     698             :   void BoxReflow(nsBoxLayoutState& aState,
     699             :                  nsPresContext*    aPresContext,
     700             :                  ReflowOutput&     aDesiredSize,
     701             :                  gfxContext*       aRenderingContext,
     702             :                  nscoord aX,
     703             :                  nscoord aY,
     704             :                  nscoord aWidth,
     705             :                  nscoord aHeight,
     706             :                  bool aMoveFrame = true);
     707             : 
     708             :   NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
     709             : 
     710             :   // Returns true if this frame has any kind of CSS animations.
     711             :   bool HasCSSAnimations();
     712             : 
     713             :   // Returns true if this frame has any kind of CSS transitions.
     714             :   bool HasCSSTransitions();
     715             : 
     716             : public:
     717             : 
     718             : #ifdef DEBUG_FRAME_DUMP
     719             :   /**
     720             :    * Get a printable from of the name of the frame type.
     721             :    * XXX This should be eliminated and we use GetType() instead...
     722             :    */
     723             :   nsresult GetFrameName(nsAString& aResult) const override;
     724             :   nsresult MakeFrameName(const nsAString& aKind, nsAString& aResult) const;
     725             :   // Helper function to return the index in parent of the frame's content
     726             :   // object. Returns -1 on error or if the frame doesn't have a content object
     727             :   static int32_t ContentIndexInContainer(const nsIFrame* aFrame);
     728             : #endif
     729             : 
     730             : #ifdef DEBUG
     731             :   static mozilla::LazyLogModule sFrameLogModule;
     732             : 
     733             :   // Show frame borders when rendering
     734             :   static void ShowFrameBorders(bool aEnable);
     735             :   static bool GetShowFrameBorders();
     736             : 
     737             :   // Show frame border of event target
     738             :   static void ShowEventTargetFrameBorder(bool aEnable);
     739             :   static bool GetShowEventTargetFrameBorder();
     740             : #endif
     741             : 
     742           0 :   static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
     743             :                                const nsDisplayList& aList,
     744             :                                bool aDumpHtml = false)
     745             :   {
     746             :     std::stringstream ss;
     747             :     PrintDisplayList(aBuilder, aList, ss, aDumpHtml);
     748             :     fprintf_stderr(stderr, "%s", ss.str().c_str());
     749             :   }
     750             :   static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
     751             :                                const nsDisplayList& aList,
     752             :                                std::stringstream& aStream,
     753             :                                bool aDumpHtml = false);
     754             :   static void PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
     755             :                                   const nsDisplayListSet& aList,
     756             :                                   std::stringstream& aStream,
     757             :                                   bool aDumpHtml = false);
     758             : 
     759             : };
     760             : 
     761             : // Start Display Reflow Debugging
     762             : #ifdef DEBUG
     763             : 
     764             :   struct DR_cookie {
     765             :     DR_cookie(nsPresContext*          aPresContext,
     766             :               nsIFrame*                aFrame,
     767             :               const mozilla::ReflowInput& aReflowInput,
     768             :               mozilla::ReflowOutput&     aMetrics,
     769             :               nsReflowStatus&          aStatus);
     770             :     ~DR_cookie();
     771             :     void Change() const;
     772             : 
     773             :     nsPresContext*          mPresContext;
     774             :     nsIFrame*                mFrame;
     775             :     const mozilla::ReflowInput& mReflowInput;
     776             :     mozilla::ReflowOutput&     mMetrics;
     777             :     nsReflowStatus&          mStatus;
     778             :     void*                    mValue;
     779             :   };
     780             : 
     781             :   struct DR_layout_cookie {
     782             :     explicit DR_layout_cookie(nsIFrame* aFrame);
     783             :     ~DR_layout_cookie();
     784             : 
     785             :     nsIFrame* mFrame;
     786             :     void* mValue;
     787             :   };
     788             : 
     789             :   struct DR_intrinsic_width_cookie {
     790             :     DR_intrinsic_width_cookie(nsIFrame* aFrame, const char* aType,
     791             :                               nscoord& aResult);
     792             :     ~DR_intrinsic_width_cookie();
     793             : 
     794             :     nsIFrame* mFrame;
     795             :     const char* mType;
     796             :     nscoord& mResult;
     797             :     void* mValue;
     798             :   };
     799             : 
     800             :   struct DR_intrinsic_size_cookie {
     801             :     DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType,
     802             :                              nsSize& aResult);
     803             :     ~DR_intrinsic_size_cookie();
     804             : 
     805             :     nsIFrame* mFrame;
     806             :     const char* mType;
     807             :     nsSize& mResult;
     808             :     void* mValue;
     809             :   };
     810             : 
     811             :   struct DR_init_constraints_cookie {
     812             :     DR_init_constraints_cookie(nsIFrame* aFrame, mozilla::ReflowInput* aState,
     813             :                                nscoord aCBWidth, nscoord aCBHeight,
     814             :                                const nsMargin* aBorder,
     815             :                                const nsMargin* aPadding);
     816             :     ~DR_init_constraints_cookie();
     817             : 
     818             :     nsIFrame* mFrame;
     819             :     mozilla::ReflowInput* mState;
     820             :     void* mValue;
     821             :   };
     822             : 
     823             :   struct DR_init_offsets_cookie {
     824             :     DR_init_offsets_cookie(nsIFrame* aFrame, mozilla::SizeComputationInput* aState,
     825             :                            nscoord aPercentBasis,
     826             :                            mozilla::WritingMode aCBWritingMode,
     827             :                            const nsMargin* aBorder,
     828             :                            const nsMargin* aPadding);
     829             :     ~DR_init_offsets_cookie();
     830             : 
     831             :     nsIFrame* mFrame;
     832             :     mozilla::SizeComputationInput* mState;
     833             :     void* mValue;
     834             :   };
     835             : 
     836             :   struct DR_init_type_cookie {
     837             :     DR_init_type_cookie(nsIFrame* aFrame, mozilla::ReflowInput* aState);
     838             :     ~DR_init_type_cookie();
     839             : 
     840             :     nsIFrame* mFrame;
     841             :     mozilla::ReflowInput* mState;
     842             :     void* mValue;
     843             :   };
     844             : 
     845             : #define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) \
     846             :   DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status);
     847             : #define DISPLAY_REFLOW_CHANGE() \
     848             :   dr_cookie.Change();
     849             : #define DISPLAY_LAYOUT(dr_frame) \
     850             :   DR_layout_cookie dr_cookie(dr_frame);
     851             : #define DISPLAY_MIN_WIDTH(dr_frame, dr_result) \
     852             :   DR_intrinsic_width_cookie dr_cookie(dr_frame, "Min", dr_result)
     853             : #define DISPLAY_PREF_WIDTH(dr_frame, dr_result) \
     854             :   DR_intrinsic_width_cookie dr_cookie(dr_frame, "Pref", dr_result)
     855             : #define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
     856             :   DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
     857             : #define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
     858             :   DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
     859             : #define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
     860             :   DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
     861             : #define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh,       \
     862             :                                  dr_bdr, dr_pad)                           \
     863             :   DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
     864             :                                        dr_bdr, dr_pad)
     865             : #define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr,      \
     866             :                              dr_pad)                                          \
     867             :   DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_pb, dr_cbwm,        \
     868             :                              dr_bdr, dr_pad)
     869             : #define DISPLAY_INIT_TYPE(dr_frame, dr_result) \
     870             :   DR_init_type_cookie dr_cookie(dr_frame, dr_result)
     871             : 
     872             : #else
     873             : 
     874             : #define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status)
     875             : #define DISPLAY_REFLOW_CHANGE()
     876             : #define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO
     877             : #define DISPLAY_MIN_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
     878             : #define DISPLAY_PREF_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
     879             : #define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
     880             : #define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
     881             : #define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
     882             : #define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh,       \
     883             :                                  dr_bdr, dr_pad)                           \
     884             :   PR_BEGIN_MACRO PR_END_MACRO
     885             : #define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_pb, dr_cbwm, dr_bdr,      \
     886             :                              dr_pad)                                          \
     887             :   PR_BEGIN_MACRO PR_END_MACRO
     888             : #define DISPLAY_INIT_TYPE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
     889             : 
     890             : #endif
     891             : // End Display Reflow Debugging
     892             : 
     893             : // similar to NS_ENSURE_TRUE but with no return value
     894             : #define ENSURE_TRUE(x)                                        \
     895             :   PR_BEGIN_MACRO                                              \
     896             :     if (!(x)) {                                               \
     897             :        NS_WARNING("ENSURE_TRUE(" #x ") failed");              \
     898             :        return;                                                \
     899             :     }                                                         \
     900             :   PR_END_MACRO
     901             : #endif /* nsFrame_h___ */

Generated by: LCOV version 1.13-14-ga5dd952