layout/generic/nsFrame.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 /* base class of all rendering objects */
     8 #ifndef nsFrame_h___
     9 #define nsFrame_h___
    11 #include "mozilla/Attributes.h"
    12 #include "mozilla/EventForwards.h"
    13 #include "mozilla/Likely.h"
    14 #include "nsBox.h"
    15 #include "prlog.h"
    17 #include "nsIPresShell.h"
    18 #include "nsHTMLReflowState.h"
    19 #include "nsHTMLParts.h"
    20 #include "nsISelectionDisplay.h"
    22 /**
    23  * nsFrame logging constants. We redefine the nspr
    24  * PRLogModuleInfo.level field to be a bitfield.  Each bit controls a
    25  * specific type of logging. Each logging operation has associated
    26  * inline methods defined below.
    27  */
    28 #define NS_FRAME_TRACE_CALLS        0x1
    29 #define NS_FRAME_TRACE_PUSH_PULL    0x2
    30 #define NS_FRAME_TRACE_CHILD_REFLOW 0x4
    31 #define NS_FRAME_TRACE_NEW_FRAMES   0x8
    33 #define NS_FRAME_LOG_TEST(_lm,_bit) (int((_lm)->level) & (_bit))
    35 #ifdef DEBUG
    36 #define NS_FRAME_LOG(_bit,_args)                                \
    37   PR_BEGIN_MACRO                                                \
    38     if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) {  \
    39       PR_LogPrint _args;                                        \
    40     }                                                           \
    41   PR_END_MACRO
    42 #else
    43 #define NS_FRAME_LOG(_bit,_args)
    44 #endif
    46 // XXX Need to rework this so that logging is free when it's off
    47 #ifdef DEBUG
    48 #define NS_FRAME_TRACE_IN(_method) Trace(_method, true)
    50 #define NS_FRAME_TRACE_OUT(_method) Trace(_method, false)
    52 // XXX remove me
    53 #define NS_FRAME_TRACE_MSG(_bit,_args)                          \
    54   PR_BEGIN_MACRO                                                \
    55     if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) {  \
    56       TraceMsg _args;                                           \
    57     }                                                           \
    58   PR_END_MACRO
    60 #define NS_FRAME_TRACE(_bit,_args)                              \
    61   PR_BEGIN_MACRO                                                \
    62     if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) {  \
    63       TraceMsg _args;                                           \
    64     }                                                           \
    65   PR_END_MACRO
    67 #define NS_FRAME_TRACE_REFLOW_IN(_method) Trace(_method, true)
    69 #define NS_FRAME_TRACE_REFLOW_OUT(_method, _status) \
    70   Trace(_method, false, _status)
    72 #else
    73 #define NS_FRAME_TRACE(_bits,_args)
    74 #define NS_FRAME_TRACE_IN(_method)
    75 #define NS_FRAME_TRACE_OUT(_method)
    76 #define NS_FRAME_TRACE_MSG(_bits,_args)
    77 #define NS_FRAME_TRACE_REFLOW_IN(_method)
    78 #define NS_FRAME_TRACE_REFLOW_OUT(_method, _status)
    79 #endif
    81 // Frame allocation boilerplate macros.  Every subclass of nsFrame
    82 // must define its own operator new and GetAllocatedSize.  If they do
    83 // not, the per-frame recycler lists in nsPresArena will not work
    84 // correctly, with potentially catastrophic consequences (not enough
    85 // memory is allocated for a frame object).
    87 #define NS_DECL_FRAMEARENA_HELPERS                                \
    88   void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE;    \
    89   virtual nsQueryFrame::FrameIID GetFrameId() MOZ_MUST_OVERRIDE;
    91 #define NS_IMPL_FRAMEARENA_HELPERS(class)                         \
    92   void* class::operator new(size_t sz, nsIPresShell* aShell)      \
    93   { return aShell->AllocateFrame(nsQueryFrame::class##_id, sz); } \
    94   nsQueryFrame::FrameIID class::GetFrameId()                      \
    95   { return nsQueryFrame::class##_id; }
    97 //----------------------------------------------------------------------
    99 struct nsBoxLayoutMetrics;
   100 class nsDisplayBackgroundImage;
   101 struct nsRect;
   103 /**
   104  * Implementation of a simple frame that's not splittable and has no
   105  * child frames.
   106  *
   107  * Sets the NS_FRAME_SYNCHRONIZE_FRAME_AND_VIEW bit, so the default
   108  * behavior is to keep the frame and view position and size in sync.
   109  */
   110 class nsFrame : public nsBox
   111 {
   112 public:
   113   /**
   114    * Create a new "empty" frame that maps a given piece of content into a
   115    * 0,0 area.
   116    */
   117   friend nsIFrame* NS_NewEmptyFrame(nsIPresShell* aShell,
   118                                     nsStyleContext* aContext);
   120 private:
   121   // Left undefined; nsFrame objects are never allocated from the heap.
   122   void* operator new(size_t sz) CPP_THROW_NEW;
   124 protected:
   125   // Overridden to prevent the global delete from being called, since
   126   // the memory came out of an arena instead of the heap.
   127   //
   128   // Ideally this would be private and undefined, like the normal
   129   // operator new.  Unfortunately, the C++ standard requires an
   130   // overridden operator delete to be accessible to any subclass that
   131   // defines a virtual destructor, so we can only make it protected;
   132   // worse, some C++ compilers will synthesize calls to this function
   133   // from the "deleting destructors" that they emit in case of
   134   // delete-expressions, so it can't even be undefined.
   135   void operator delete(void* aPtr, size_t sz);
   137 public:
   139   // nsQueryFrame
   140   NS_DECL_QUERYFRAME
   141   NS_DECL_FRAMEARENA_HELPERS
   143   // nsIFrame
   144   virtual void Init(nsIContent*      aContent,
   145                     nsIFrame*        aParent,
   146                     nsIFrame*        asPrevInFlow) MOZ_OVERRIDE;
   147   virtual nsresult  SetInitialChildList(ChildListID  aListID,
   148                                         nsFrameList& aChildList) MOZ_OVERRIDE;
   149   virtual nsresult  AppendFrames(ChildListID     aListID,
   150                                  nsFrameList&    aFrameList) MOZ_OVERRIDE;
   151   virtual nsresult  InsertFrames(ChildListID     aListID,
   152                                  nsIFrame*       aPrevFrame,
   153                                  nsFrameList&    aFrameList) MOZ_OVERRIDE;
   154   virtual nsresult  RemoveFrame(ChildListID     aListID,
   155                                 nsIFrame*       aOldFrame) MOZ_OVERRIDE;
   156   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   157   virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
   158   virtual void SetAdditionalStyleContext(int32_t aIndex,
   159                                          nsStyleContext* aStyleContext) MOZ_OVERRIDE;
   160   virtual void SetParent(nsIFrame* aParent) MOZ_OVERRIDE;
   161   virtual nscoord GetBaseline() const MOZ_OVERRIDE;
   162   virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
   163   virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
   165   virtual nsresult  HandleEvent(nsPresContext* aPresContext, 
   166                                 mozilla::WidgetGUIEvent* aEvent,
   167                                 nsEventStatus* aEventStatus) MOZ_OVERRIDE;
   168   virtual nsresult  GetContentForEvent(mozilla::WidgetEvent* aEvent,
   169                                        nsIContent** aContent) MOZ_OVERRIDE;
   170   virtual nsresult  GetCursor(const nsPoint&    aPoint,
   171                               nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
   173   virtual nsresult  GetPointFromOffset(int32_t  inOffset,
   174                                        nsPoint* outPoint) MOZ_OVERRIDE;
   176   virtual nsresult  GetChildFrameContainingOffset(int32_t    inContentOffset,
   177                                                   bool       inHint,
   178                                                   int32_t*   outFrameContentOffset,
   179                                                   nsIFrame** outChildFrame) MOZ_OVERRIDE;
   181   static nsresult  GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
   182                                         nsPeekOffsetStruct *aPos, 
   183                                         nsIFrame *aBlockFrame, 
   184                                         int32_t aLineStart, 
   185                                         int8_t aOutSideLimit
   186                                         );
   188   virtual nsresult  CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE;
   189   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
   190                                      nsIAtom*        aAttribute,
   191                                      int32_t         aModType) MOZ_OVERRIDE;
   192   virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
   193   virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE;
   194   virtual void SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE;
   195   virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE;
   196   virtual void SetNextContinuation(nsIFrame*) MOZ_OVERRIDE;
   197   virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE;
   198   virtual void SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE;
   199   virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE;
   200   virtual void SetNextInFlow(nsIFrame*) MOZ_OVERRIDE;
   201   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   203   virtual nsresult  IsSelectable(bool* aIsSelectable, uint8_t* aSelectStyle) const MOZ_OVERRIDE;
   205   virtual nsresult  GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon) MOZ_OVERRIDE;
   207   virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
   208   virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
   209                                      bool aRespectClusters = true) MOZ_OVERRIDE;
   210   virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
   211                                 int32_t* aOffset, PeekWordState *aState) MOZ_OVERRIDE;
   212   /**
   213    * Check whether we should break at a boundary between punctuation and
   214    * non-punctuation. Only call it at a punctuation boundary
   215    * (i.e. exactly one of the previous and next characters are punctuation).
   216    * @param aForward true if we're moving forward in content order
   217    * @param aPunctAfter true if the next character is punctuation
   218    * @param aWhitespaceAfter true if the next character is whitespace
   219    */
   220   bool BreakWordBetweenPunctuation(const PeekWordState* aState,
   221                                      bool aForward,
   222                                      bool aPunctAfter, bool aWhitespaceAfter,
   223                                      bool aIsKeyboardSelect);
   225   virtual nsresult  CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) MOZ_OVERRIDE;
   227   virtual nsresult  GetOffsets(int32_t &aStart, int32_t &aEnd) const MOZ_OVERRIDE;
   228   virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
   230 #ifdef ACCESSIBILITY
   231   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
   232 #endif
   234   virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE {
   235     return DoGetParentStyleContextFrame();
   236   }
   238   /**
   239    * Do the work for getting the parent style context frame so that
   240    * other frame's |GetParentStyleContextFrame| methods can call this
   241    * method on *another* frame.  (This function handles out-of-flow
   242    * frames by using the frame manager's placeholder map and it also
   243    * handles block-within-inline and generated content wrappers.)
   244    */
   245   nsIFrame* DoGetParentStyleContextFrame() const;
   247   virtual bool IsEmpty() MOZ_OVERRIDE;
   248   virtual bool IsSelfEmpty() MOZ_OVERRIDE;
   250   virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE;
   251   virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   252   virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
   253   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
   254                                  InlineMinWidthData *aData) MOZ_OVERRIDE;
   255   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
   256                                   InlinePrefWidthData *aData) MOZ_OVERRIDE;
   257   virtual IntrinsicWidthOffsetData
   258     IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
   259   virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
   260   virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
   262   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
   263                              nsSize aCBSize, nscoord aAvailableWidth,
   264                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
   265                              uint32_t aFlags) MOZ_OVERRIDE;
   267   // Compute tight bounds assuming this frame honours its border, background
   268   // and outline, its children's tight bounds, and nothing else.
   269   nsRect ComputeSimpleTightBounds(gfxContext* aContext) const;
   271   /**
   272    * A helper, used by |nsFrame::ComputeSize| (for frames that need to
   273    * override only this part of ComputeSize), that computes the size
   274    * that should be returned when 'width', 'height', and
   275    * min/max-width/height are all 'auto' or equivalent.
   276    *
   277    * In general, frames that can accept any computed width/height should
   278    * override only ComputeAutoSize, and frames that cannot do so need to
   279    * override ComputeSize to enforce their width/height invariants.
   280    *
   281    * Implementations may optimize by returning a garbage width if
   282    * StylePosition()->mWidth.GetUnit() != eStyleUnit_Auto, and
   283    * likewise for height, since in such cases the result is guaranteed
   284    * to be unused.
   285    */
   286   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
   287                                  nsSize aCBSize, nscoord aAvailableWidth,
   288                                  nsSize aMargin, nsSize aBorder,
   289                                  nsSize aPadding, bool aShrinkWrap);
   291   /**
   292    * Utility function for ComputeAutoSize implementations.  Return
   293    * max(GetMinWidth(), min(aWidthInCB, GetPrefWidth()))
   294    */
   295   nscoord ShrinkWidthToFit(nsRenderingContext *aRenderingContext,
   296                            nscoord aWidthInCB);
   298   virtual nsresult  WillReflow(nsPresContext* aPresContext) MOZ_OVERRIDE;
   299   /**
   300    * Calculates the size of this frame after reflowing (calling Reflow on, and
   301    * updating the size and position of) its children, as necessary.  The
   302    * calculated size is returned to the caller via the nsHTMLReflowMetrics
   303    * outparam.  (The caller is responsible for setting the actual size and
   304    * position of this frame.)
   305    *
   306    * A frame's children must _all_ be reflowed if the frame is dirty (the
   307    * NS_FRAME_IS_DIRTY bit is set on it).  Otherwise, individual children
   308    * must be reflowed if they are dirty or have the NS_FRAME_HAS_DIRTY_CHILDREN
   309    * bit set on them.  Otherwise, whether children need to be reflowed depends
   310    * on the frame's type (it's up to individual Reflow methods), and on what
   311    * has changed.  For example, a change in the width of the frame may require
   312    * all of its children to be reflowed (even those without dirty bits set on
   313    * them), whereas a change in its height might not.
   314    * (nsHTMLReflowState::ShouldReflowAllKids may be helpful in deciding whether
   315    * to reflow all the children, but for some frame types it might result in
   316    * over-reflow.)
   317    *
   318    * Note: if it's only the overflow rect(s) of a frame that need to be
   319    * updated, then UpdateOverflow should be called instead of Reflow.
   320    */
   321   virtual nsresult  Reflow(nsPresContext*           aPresContext,
   322                            nsHTMLReflowMetrics&     aDesiredSize,
   323                            const nsHTMLReflowState& aReflowState,
   324                            nsReflowStatus&          aStatus) MOZ_OVERRIDE;
   325   virtual nsresult  DidReflow(nsPresContext*           aPresContext,
   326                               const nsHTMLReflowState* aReflowState,
   327                               nsDidReflowStatus        aStatus) MOZ_OVERRIDE;
   329   /**
   330    * NOTE: aStatus is assumed to be already-initialized. The reflow statuses of
   331    * any reflowed absolute children will be merged into aStatus; aside from
   332    * that, this method won't modify aStatus.
   333    */
   334   void ReflowAbsoluteFrames(nsPresContext*           aPresContext,
   335                             nsHTMLReflowMetrics&     aDesiredSize,
   336                             const nsHTMLReflowState& aReflowState,
   337                             nsReflowStatus&          aStatus,
   338                             bool                     aConstrainHeight = true);
   339   void FinishReflowWithAbsoluteFrames(nsPresContext*           aPresContext,
   340                                       nsHTMLReflowMetrics&     aDesiredSize,
   341                                       const nsHTMLReflowState& aReflowState,
   342                                       nsReflowStatus&          aStatus,
   343                                       bool                     aConstrainHeight = true);
   344   virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
   346   virtual bool UpdateOverflow() MOZ_OVERRIDE;
   348   // Selection Methods
   350   NS_IMETHOD HandlePress(nsPresContext* aPresContext,
   351                          mozilla::WidgetGUIEvent* aEvent,
   352                          nsEventStatus* aEventStatus);
   354   NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext,
   355                                  mozilla::WidgetGUIEvent* aEvent,
   356                                  nsEventStatus* aEventStatus,
   357                                  bool aControlHeld);
   359   NS_IMETHOD HandleDrag(nsPresContext* aPresContext,
   360                         mozilla::WidgetGUIEvent* aEvent,
   361                         nsEventStatus* aEventStatus);
   363   NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
   364                            mozilla::WidgetGUIEvent* aEvent,
   365                            nsEventStatus* aEventStatus);
   367   enum { SELECT_ACCUMULATE = 0x01 };
   369   nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack,
   370                                   nsSelectionAmount aAmountForward,
   371                                   int32_t aStartPos,
   372                                   nsPresContext* aPresContext,
   373                                   bool aJumpLines,
   374                                   uint32_t aSelectFlags);
   376   nsresult SelectByTypeAtPoint(nsPresContext* aPresContext,
   377                                const nsPoint& aPoint,
   378                                nsSelectionAmount aBeginAmountType,
   379                                nsSelectionAmount aEndAmountType,
   380                                uint32_t aSelectFlags);
   382   // Helper for GetContentAndOffsetsFromPoint; calculation of content offsets
   383   // in this function assumes there is no child frame that can be targeted.
   384   virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
   386   // Box layout methods
   387   virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   388   virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   389   virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   390   virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   391   virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   393   // We compute and store the HTML content's overflow area. So don't
   394   // try to compute it in the box code.
   395   virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; }
   397   //--------------------------------------------------
   398   // Additional methods
   400   // Helper function that tests if the frame tree is too deep; if it is
   401   // it marks the frame as "unflowable", zeroes out the metrics, sets
   402   // the reflow status, and returns true. Otherwise, the frame is
   403   // unmarked "unflowable" and the metrics and reflow status are not
   404   // touched and false is returned.
   405   bool IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
   406                             nsHTMLReflowMetrics& aMetrics,
   407                             nsReflowStatus& aStatus);
   409   // Incorporate the child overflow areas into aOverflowAreas.
   410   // If the child does not have a overflow, use the child area.
   411   void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas,
   412                              nsIFrame* aChildFrame);
   414   /**
   415    * @return true if we should avoid a page/column break in this frame.
   416    */
   417   bool ShouldAvoidBreakInside(const nsHTMLReflowState& aReflowState) const {
   418     return !aReflowState.mFlags.mIsTopOfPage &&
   419            NS_STYLE_PAGE_BREAK_AVOID == StyleDisplay()->mBreakInside &&
   420            !GetPrevInFlow();
   421   }
   423 #ifdef DEBUG
   424   /**
   425    * Tracing method that writes a method enter/exit routine to the
   426    * nspr log using the nsIFrame log module. The tracing is only
   427    * done when the NS_FRAME_TRACE_CALLS bit is set in the log module's
   428    * level field.
   429    */
   430   void Trace(const char* aMethod, bool aEnter);
   431   void Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus);
   432   void TraceMsg(const char* fmt, ...);
   434   // Helper function that verifies that each frame in the list has the
   435   // NS_FRAME_IS_DIRTY bit set
   436   static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
   438   static void XMLQuote(nsString& aString);
   440   /**
   441    * Dump out the "base classes" regression data. This should dump
   442    * out the interior data, not the "frame" XML container. And it
   443    * should call the base classes same named method before doing
   444    * anything specific in a derived class. This means that derived
   445    * classes need not override DumpRegressionData unless they need
   446    * some custom behavior that requires changing how the outer "frame"
   447    * XML container is dumped.
   448    */
   449   virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent);
   451   // Display Reflow Debugging 
   452   static void* DisplayReflowEnter(nsPresContext*          aPresContext,
   453                                   nsIFrame*                aFrame,
   454                                   const nsHTMLReflowState& aReflowState);
   455   static void* DisplayLayoutEnter(nsIFrame* aFrame);
   456   static void* DisplayIntrinsicWidthEnter(nsIFrame* aFrame,
   457                                           const char* aType);
   458   static void* DisplayIntrinsicSizeEnter(nsIFrame* aFrame,
   459                                          const char* aType);
   460   static void  DisplayReflowExit(nsPresContext*      aPresContext,
   461                                  nsIFrame*            aFrame,
   462                                  nsHTMLReflowMetrics& aMetrics,
   463                                  uint32_t             aStatus,
   464                                  void*                aFrameTreeNode);
   465   static void  DisplayLayoutExit(nsIFrame* aFrame,
   466                                  void* aFrameTreeNode);
   467   static void  DisplayIntrinsicWidthExit(nsIFrame* aFrame,
   468                                          const char* aType,
   469                                          nscoord aResult,
   470                                          void* aFrameTreeNode);
   471   static void  DisplayIntrinsicSizeExit(nsIFrame* aFrame,
   472                                         const char* aType,
   473                                         nsSize aResult,
   474                                         void* aFrameTreeNode);
   476   static void DisplayReflowStartup();
   477   static void DisplayReflowShutdown();
   478 #endif
   480   /**
   481    * Adds display items for standard CSS background if necessary.
   482    * Does not check IsVisibleForPainting.
   483    * @param aForceBackground draw the background even if the frame
   484    * background style appears to have no background --- this is useful
   485    * for frames that might receive a propagated background via
   486    * nsCSSRendering::FindBackground
   487    * @return whether a themed background item was created.
   488    */
   489   bool DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
   490                                       const nsDisplayListSet& aLists,
   491                                       bool aForceBackground);
   492   /**
   493    * Adds display items for standard CSS borders, background and outline for
   494    * for this frame, as necessary. Checks IsVisibleForPainting and won't
   495    * display anything if the frame is not visible.
   496    * @param aForceBackground draw the background even if the frame
   497    * background style appears to have no background --- this is useful
   498    * for frames that might receive a propagated background via
   499    * nsCSSRendering::FindBackground
   500    */
   501   void DisplayBorderBackgroundOutline(nsDisplayListBuilder*   aBuilder,
   502                                       const nsDisplayListSet& aLists,
   503                                       bool aForceBackground = false);
   504   /**
   505    * Add a display item for the CSS outline. Does not check visibility.
   506    */
   507   void DisplayOutlineUnconditional(nsDisplayListBuilder*   aBuilder,
   508                                    const nsDisplayListSet& aLists);
   509   /**
   510    * Add a display item for the CSS outline, after calling
   511    * IsVisibleForPainting to confirm we are visible.
   512    */
   513   void DisplayOutline(nsDisplayListBuilder*   aBuilder,
   514                       const nsDisplayListSet& aLists);
   516   /**
   517    * Adjust the given parent frame to the right style context parent frame for
   518    * the child, given the pseudo-type of the prospective child.  This handles
   519    * things like walking out of table pseudos and so forth.
   520    *
   521    * @param aProspectiveParent what GetParent() on the child returns.
   522    *                           Must not be null.
   523    * @param aChildPseudo the child's pseudo type, if any.
   524    */
   525   static nsIFrame*
   526   CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsIAtom* aChildPseudo);
   528 protected:
   529   // Protected constructor and destructor
   530   nsFrame(nsStyleContext* aContext);
   531   virtual ~nsFrame();
   533   /**
   534    * To be called by |BuildDisplayLists| of this class or derived classes to add
   535    * a translucent overlay if this frame's content is selected.
   536    * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
   537    * which kind of content this is for
   538    */
   539   void DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
   540       nsDisplayList* aList, uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
   542   int16_t DisplaySelection(nsPresContext* aPresContext, bool isOkToTurnOn = false);
   544   // Style post processing hook
   545   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
   547 public:
   548   //given a frame five me the first/last leaf available
   549   //XXX Robert O'Callahan wants to move these elsewhere
   550   static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
   551   static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
   553   // Return the line number of the aFrame, and (optionally) the containing block
   554   // frame.
   555   // If aScrollLock is true, don't break outside scrollframes when looking for a
   556   // containing block frame.
   557   static int32_t GetLineNumber(nsIFrame *aFrame,
   558                                bool aLockScroll,
   559                                nsIFrame** aContainingBlock = nullptr);
   561   /**
   562    * Returns true if aFrame should apply overflow clipping.
   563    */
   564   static bool ShouldApplyOverflowClipping(const nsIFrame* aFrame,
   565                                           const nsStyleDisplay* aDisp)
   566   {
   567     // clip overflow:-moz-hidden-unscrollable ...
   568     if (MOZ_UNLIKELY(aDisp->mOverflowX == NS_STYLE_OVERFLOW_CLIP)) {
   569       return true;
   570     }
   572     // and overflow:hidden that we should interpret as -moz-hidden-unscrollable
   573     if (aDisp->mOverflowX == NS_STYLE_OVERFLOW_HIDDEN &&
   574         aDisp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) {
   575       // REVIEW: these are the frame types that set up clipping.
   576       nsIAtom* type = aFrame->GetType();
   577       if (type == nsGkAtoms::tableFrame ||
   578           type == nsGkAtoms::tableCellFrame ||
   579           type == nsGkAtoms::bcTableCellFrame ||
   580           type == nsGkAtoms::svgOuterSVGFrame ||
   581           type == nsGkAtoms::svgInnerSVGFrame ||
   582           type == nsGkAtoms::svgForeignObjectFrame) {
   583         return true;
   584       }
   585       if (aFrame->IsFrameOfType(nsIFrame::eReplacedContainsBlock)) {
   586         if (type == nsGkAtoms::textInputFrame) {
   587           // It always has an anonymous scroll frame that handles any overflow.
   588           return false;
   589         }
   590         return true;
   591       }
   592     }
   594     if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
   595       return false;
   596     }
   598     // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW
   599     // set, then we want to clip our overflow.
   600     return
   601       (aFrame->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW) != 0 &&
   602       aFrame->PresContext()->IsPaginated() &&
   603       aFrame->GetType() == nsGkAtoms::blockFrame;
   604   }
   606 protected:
   608   // Test if we are selecting a table object:
   609   //  Most table/cell selection requires that Ctrl (Cmd on Mac) key is down 
   610   //   during a mouse click or drag. Exception is using Shift+click when
   611   //   already in "table/cell selection mode" to extend a block selection
   612   //  Get the parent content node and offset of the frame 
   613   //   of the enclosing cell or table (if not inside a cell)
   614   //  aTarget tells us what table element to select (currently only cell and table supported)
   615   //  (enums for this are defined in nsIFrame.h)
   616   NS_IMETHOD GetDataForTableSelection(const nsFrameSelection* aFrameSelection,
   617                                       nsIPresShell* aPresShell,
   618                                       mozilla::WidgetMouseEvent* aMouseEvent,
   619                                       nsIContent** aParentContent,
   620                                       int32_t* aContentOffset,
   621                                       int32_t* aTarget);
   623   // Fills aCursor with the appropriate information from ui
   624   static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui,
   625                                              nsIFrame::Cursor& aCursor);
   626   NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
   628 #ifdef DEBUG_LAYOUT
   629   virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE;
   630 #endif
   632   void InitBoxMetrics(bool aClear);
   633   nsBoxLayoutMetrics* BoxMetrics() const;
   635   // Fire DOM event. If no aContent argument use frame's mContent.
   636   void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr);
   638 private:
   639   nsresult BoxReflow(nsBoxLayoutState& aState,
   640                      nsPresContext*    aPresContext,
   641                      nsHTMLReflowMetrics&     aDesiredSize,
   642                      nsRenderingContext* aRenderingContext,
   643                      nscoord aX,
   644                      nscoord aY,
   645                      nscoord aWidth,
   646                      nscoord aHeight,
   647                      bool aMoveFrame = true);
   649   NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
   651   virtual nsILineIterator* GetLineIterator() MOZ_OVERRIDE;
   653 #ifdef DEBUG_FRAME_DUMP
   654 public:
   655   /**
   656    * Get a printable from of the name of the frame type.
   657    * XXX This should be eliminated and we use GetType() instead...
   658    */
   659   virtual nsresult  GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
   660   nsresult MakeFrameName(const nsAString& aKind, nsAString& aResult) const;
   661   // Helper function to return the index in parent of the frame's content
   662   // object. Returns -1 on error or if the frame doesn't have a content object
   663   static int32_t ContentIndexInContainer(const nsIFrame* aFrame);
   664 #endif
   666 #ifdef DEBUG
   667 public:
   668   /**
   669    * Return the state bits that are relevant to regression tests (that
   670    * is, those bits which indicate a real difference when they differ
   671    */
   672   virtual nsFrameState  GetDebugStateBits() const MOZ_OVERRIDE;
   673   /**
   674    * Called to dump out regression data that describes the layout
   675    * of the frame and its children, and so on. The format of the
   676    * data is dictated to be XML (using a specific DTD); the
   677    * specific kind of data dumped is up to the frame itself, with
   678    * the caveat that some base types are defined.
   679    * For more information, see XXX.
   680    */
   681   virtual nsresult  DumpRegressionData(nsPresContext* aPresContext,
   682                                        FILE* out, int32_t aIndent) MOZ_OVERRIDE;
   684   /**
   685    * See if style tree verification is enabled. To enable style tree
   686    * verification add "styleverifytree:1" to your NSPR_LOG_MODULES
   687    * environment variable (any non-zero debug level will work). Or,
   688    * call SetVerifyStyleTreeEnable with true.
   689    */
   690   static bool GetVerifyStyleTreeEnable();
   692   /**
   693    * Set the verify-style-tree enable flag.
   694    */
   695   static void SetVerifyStyleTreeEnable(bool aEnabled);
   697   /**
   698    * The frame class and related classes share an nspr log module
   699    * for logging frame activity.
   700    *
   701    * Note: the log module is created during library initialization which
   702    * means that you cannot perform logging before then.
   703    */
   704   static PRLogModuleInfo* GetLogModuleInfo();
   706   // Show frame borders when rendering
   707   static void ShowFrameBorders(bool aEnable);
   708   static bool GetShowFrameBorders();
   710   // Show frame border of event target
   711   static void ShowEventTargetFrameBorder(bool aEnable);
   712   static bool GetShowEventTargetFrameBorder();
   714 #endif
   715 #ifdef MOZ_DUMP_PAINTING
   716 public:
   718   static void PrintDisplayItem(nsDisplayListBuilder* aBuilder,
   719                                nsDisplayItem* aItem,
   720                                FILE* aFile = stdout,
   721                                bool aDumpSublist = false,
   722                                bool aDumpHtml = false);
   724   static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
   725                                const nsDisplayList& aList,
   726                                FILE* aFile = stdout,
   727                                bool aDumpHtml = false);
   728   static void PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
   729                                   const nsDisplayListSet& aList,
   730                                   FILE* aFile = stdout,
   731                                   bool aDumpHtml = false);
   733 #endif
   734 };
   736 // Start Display Reflow Debugging
   737 #ifdef DEBUG
   739   struct DR_cookie {
   740     DR_cookie(nsPresContext*          aPresContext,
   741               nsIFrame*                aFrame, 
   742               const nsHTMLReflowState& aReflowState,
   743               nsHTMLReflowMetrics&     aMetrics,
   744               nsReflowStatus&          aStatus);     
   745     ~DR_cookie();
   746     void Change() const;
   748     nsPresContext*          mPresContext;
   749     nsIFrame*                mFrame;
   750     const nsHTMLReflowState& mReflowState;
   751     nsHTMLReflowMetrics&     mMetrics;
   752     nsReflowStatus&          mStatus;    
   753     void*                    mValue;
   754   };
   756   struct DR_layout_cookie {
   757     DR_layout_cookie(nsIFrame* aFrame);
   758     ~DR_layout_cookie();
   760     nsIFrame* mFrame;
   761     void* mValue;
   762   };
   764   struct DR_intrinsic_width_cookie {
   765     DR_intrinsic_width_cookie(nsIFrame* aFrame, const char* aType,
   766                               nscoord& aResult);
   767     ~DR_intrinsic_width_cookie();
   769     nsIFrame* mFrame;
   770     const char* mType;
   771     nscoord& mResult;
   772     void* mValue;
   773   };
   775   struct DR_intrinsic_size_cookie {
   776     DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType,
   777                              nsSize& aResult);
   778     ~DR_intrinsic_size_cookie();
   780     nsIFrame* mFrame;
   781     const char* mType;
   782     nsSize& mResult;
   783     void* mValue;
   784   };
   786   struct DR_init_constraints_cookie {
   787     DR_init_constraints_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState,
   788                                nscoord aCBWidth, nscoord aCBHeight,
   789                                const nsMargin* aBorder,
   790                                const nsMargin* aPadding);
   791     ~DR_init_constraints_cookie();
   793     nsIFrame* mFrame;
   794     nsHTMLReflowState* mState;
   795     void* mValue;
   796   };
   798   struct DR_init_offsets_cookie {
   799     DR_init_offsets_cookie(nsIFrame* aFrame, nsCSSOffsetState* aState,
   800                            nscoord aHorizontalPercentBasis,
   801                            nscoord aVerticalPercentBasis,
   802                            const nsMargin* aBorder,
   803                            const nsMargin* aPadding);
   804     ~DR_init_offsets_cookie();
   806     nsIFrame* mFrame;
   807     nsCSSOffsetState* mState;
   808     void* mValue;
   809   };
   811   struct DR_init_type_cookie {
   812     DR_init_type_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState);
   813     ~DR_init_type_cookie();
   815     nsIFrame* mFrame;
   816     nsHTMLReflowState* mState;
   817     void* mValue;
   818   };
   820 #define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) \
   821   DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status); 
   822 #define DISPLAY_REFLOW_CHANGE() \
   823   dr_cookie.Change();
   824 #define DISPLAY_LAYOUT(dr_frame) \
   825   DR_layout_cookie dr_cookie(dr_frame); 
   826 #define DISPLAY_MIN_WIDTH(dr_frame, dr_result) \
   827   DR_intrinsic_width_cookie dr_cookie(dr_frame, "Min", dr_result)
   828 #define DISPLAY_PREF_WIDTH(dr_frame, dr_result) \
   829   DR_intrinsic_width_cookie dr_cookie(dr_frame, "Pref", dr_result)
   830 #define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
   831   DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
   832 #define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
   833   DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
   834 #define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
   835   DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
   836 #define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh,       \
   837                                  dr_bdr, dr_pad)                           \
   838   DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
   839                                        dr_bdr, dr_pad)
   840 #define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad)  \
   841   DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad)
   842 #define DISPLAY_INIT_TYPE(dr_frame, dr_result) \
   843   DR_init_type_cookie dr_cookie(dr_frame, dr_result)
   845 #else
   847 #define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) 
   848 #define DISPLAY_REFLOW_CHANGE() 
   849 #define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO
   850 #define DISPLAY_MIN_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
   851 #define DISPLAY_PREF_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
   852 #define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
   853 #define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
   854 #define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
   855 #define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh,       \
   856                                  dr_bdr, dr_pad)                           \
   857   PR_BEGIN_MACRO PR_END_MACRO
   858 #define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad)  \
   859   PR_BEGIN_MACRO PR_END_MACRO
   860 #define DISPLAY_INIT_TYPE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
   862 #endif
   863 // End Display Reflow Debugging
   865 // similar to NS_ENSURE_TRUE but with no return value
   866 #define ENSURE_TRUE(x)                                        \
   867   PR_BEGIN_MACRO                                              \
   868     if (!(x)) {                                               \
   869        NS_WARNING("ENSURE_TRUE(" #x ") failed");              \
   870        return;                                                \
   871     }                                                         \
   872   PR_END_MACRO
   873 #endif /* nsFrame_h___ */

mercurial