Bumping manifests a=b2g-bump
[gecko.git] / layout / generic / nsFrame.h
blob0f69001cb4428d552fb05c6ac817cf2e7594f730
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.
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;
104 * Implementation of a simple frame that's not splittable and has no
105 * child frames.
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.
110 class nsFrame : public nsBox
112 public:
114 * Create a new "empty" frame that maps a given piece of content into a
115 * 0,0 area.
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.
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 nsContainerFrame* aParent,
146 nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
147 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
148 virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
149 virtual void SetAdditionalStyleContext(int32_t aIndex,
150 nsStyleContext* aStyleContext) MOZ_OVERRIDE;
151 virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
152 virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
153 virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
155 virtual nsresult HandleEvent(nsPresContext* aPresContext,
156 mozilla::WidgetGUIEvent* aEvent,
157 nsEventStatus* aEventStatus) MOZ_OVERRIDE;
158 virtual nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent,
159 nsIContent** aContent) MOZ_OVERRIDE;
160 virtual nsresult GetCursor(const nsPoint& aPoint,
161 nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
163 virtual nsresult GetPointFromOffset(int32_t inOffset,
164 nsPoint* outPoint) MOZ_OVERRIDE;
166 virtual nsresult GetChildFrameContainingOffset(int32_t inContentOffset,
167 bool inHint,
168 int32_t* outFrameContentOffset,
169 nsIFrame** outChildFrame) MOZ_OVERRIDE;
171 static nsresult GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
172 nsPeekOffsetStruct *aPos,
173 nsIFrame *aBlockFrame,
174 int32_t aLineStart,
175 int8_t aOutSideLimit
178 virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE;
179 virtual nsresult AttributeChanged(int32_t aNameSpaceID,
180 nsIAtom* aAttribute,
181 int32_t aModType) MOZ_OVERRIDE;
182 virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
183 virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE;
184 virtual void SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE;
185 virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE;
186 virtual void SetNextContinuation(nsIFrame*) MOZ_OVERRIDE;
187 virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE;
188 virtual void SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE;
189 virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE;
190 virtual void SetNextInFlow(nsIFrame*) MOZ_OVERRIDE;
191 virtual nsIAtom* GetType() const MOZ_OVERRIDE;
193 virtual nsresult IsSelectable(bool* aIsSelectable, uint8_t* aSelectStyle) const MOZ_OVERRIDE;
195 virtual nsresult GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon) MOZ_OVERRIDE;
197 virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
198 virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
199 bool aRespectClusters = true) MOZ_OVERRIDE;
200 virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
201 int32_t* aOffset, PeekWordState *aState) MOZ_OVERRIDE;
203 * Check whether we should break at a boundary between punctuation and
204 * non-punctuation. Only call it at a punctuation boundary
205 * (i.e. exactly one of the previous and next characters are punctuation).
206 * @param aForward true if we're moving forward in content order
207 * @param aPunctAfter true if the next character is punctuation
208 * @param aWhitespaceAfter true if the next character is whitespace
210 bool BreakWordBetweenPunctuation(const PeekWordState* aState,
211 bool aForward,
212 bool aPunctAfter, bool aWhitespaceAfter,
213 bool aIsKeyboardSelect);
215 virtual nsresult CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) MOZ_OVERRIDE;
217 virtual nsresult GetOffsets(int32_t &aStart, int32_t &aEnd) const MOZ_OVERRIDE;
218 virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
220 #ifdef ACCESSIBILITY
221 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
222 #endif
224 virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE {
225 return DoGetParentStyleContextFrame();
229 * Do the work for getting the parent style context frame so that
230 * other frame's |GetParentStyleContextFrame| methods can call this
231 * method on *another* frame. (This function handles out-of-flow
232 * frames by using the frame manager's placeholder map and it also
233 * handles block-within-inline and generated content wrappers.)
235 nsIFrame* DoGetParentStyleContextFrame() const;
237 virtual bool IsEmpty() MOZ_OVERRIDE;
238 virtual bool IsSelfEmpty() MOZ_OVERRIDE;
240 virtual void MarkIntrinsicISizesDirty() MOZ_OVERRIDE;
241 virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
242 virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
243 virtual void AddInlineMinISize(nsRenderingContext *aRenderingContext,
244 InlineMinISizeData *aData) MOZ_OVERRIDE;
245 virtual void AddInlinePrefISize(nsRenderingContext *aRenderingContext,
246 InlinePrefISizeData *aData) MOZ_OVERRIDE;
247 virtual IntrinsicISizeOffsetData
248 IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
249 virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
250 virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
252 virtual mozilla::LogicalSize
253 ComputeSize(nsRenderingContext *aRenderingContext,
254 mozilla::WritingMode aWritingMode,
255 const mozilla::LogicalSize& aCBSize,
256 nscoord aAvailableISize,
257 const mozilla::LogicalSize& aMargin,
258 const mozilla::LogicalSize& aBorder,
259 const mozilla::LogicalSize& aPadding,
260 uint32_t aFlags) MOZ_OVERRIDE;
262 // Compute tight bounds assuming this frame honours its border, background
263 // and outline, its children's tight bounds, and nothing else.
264 nsRect ComputeSimpleTightBounds(gfxContext* aContext) const;
267 * A helper, used by |nsFrame::ComputeSize| (for frames that need to
268 * override only this part of ComputeSize), that computes the size
269 * that should be returned when 'width', 'height', and
270 * min/max-width/height are all 'auto' or equivalent.
272 * In general, frames that can accept any computed width/height should
273 * override only ComputeAutoSize, and frames that cannot do so need to
274 * override ComputeSize to enforce their width/height invariants.
276 * Implementations may optimize by returning a garbage width if
277 * StylePosition()->mWidth.GetUnit() != eStyleUnit_Auto, and
278 * likewise for height, since in such cases the result is guaranteed
279 * to be unused.
281 virtual mozilla::LogicalSize
282 ComputeAutoSize(nsRenderingContext *aRenderingContext,
283 mozilla::WritingMode aWritingMode,
284 const mozilla::LogicalSize& aCBSize,
285 nscoord aAvailableISize,
286 const mozilla::LogicalSize& aMargin,
287 const mozilla::LogicalSize& aBorder,
288 const mozilla::LogicalSize& aPadding,
289 bool aShrinkWrap);
292 * Utility function for ComputeAutoSize implementations. Return
293 * max(GetMinISize(), min(aWidthInCB, GetPrefISize()))
295 nscoord ShrinkWidthToFit(nsRenderingContext *aRenderingContext,
296 nscoord aWidthInCB);
298 virtual void WillReflow(nsPresContext* aPresContext) MOZ_OVERRIDE;
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.)
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.)
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.
321 virtual void Reflow(nsPresContext* aPresContext,
322 nsHTMLReflowMetrics& aDesiredSize,
323 const nsHTMLReflowState& aReflowState,
324 nsReflowStatus& aStatus) MOZ_OVERRIDE;
325 virtual void DidReflow(nsPresContext* aPresContext,
326 const nsHTMLReflowState* aReflowState,
327 nsDidReflowStatus aStatus) MOZ_OVERRIDE;
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.
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);
346 * If this frame is dirty, marks all absolutely-positioned children of this
347 * frame dirty. If this frame isn't dirty, or if there are no
348 * absolutely-positioned children, does nothing.
350 * It's necessary to use PushDirtyBitToAbsoluteFrames() when you plan to
351 * reflow this frame's absolutely-positioned children after the dirty bit on
352 * this frame has already been cleared, which prevents nsHTMLReflowState from
353 * propagating the dirty bit normally. This situation generally only arises
354 * when a multipass layout algorithm is used.
356 void PushDirtyBitToAbsoluteFrames();
358 virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
360 virtual bool UpdateOverflow() MOZ_OVERRIDE;
362 // Selection Methods
364 NS_IMETHOD HandlePress(nsPresContext* aPresContext,
365 mozilla::WidgetGUIEvent* aEvent,
366 nsEventStatus* aEventStatus);
368 NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext,
369 mozilla::WidgetGUIEvent* aEvent,
370 nsEventStatus* aEventStatus,
371 bool aControlHeld);
373 NS_IMETHOD HandleDrag(nsPresContext* aPresContext,
374 mozilla::WidgetGUIEvent* aEvent,
375 nsEventStatus* aEventStatus);
377 NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
378 mozilla::WidgetGUIEvent* aEvent,
379 nsEventStatus* aEventStatus);
381 enum { SELECT_ACCUMULATE = 0x01 };
383 nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack,
384 nsSelectionAmount aAmountForward,
385 int32_t aStartPos,
386 nsPresContext* aPresContext,
387 bool aJumpLines,
388 uint32_t aSelectFlags);
390 nsresult SelectByTypeAtPoint(nsPresContext* aPresContext,
391 const nsPoint& aPoint,
392 nsSelectionAmount aBeginAmountType,
393 nsSelectionAmount aEndAmountType,
394 uint32_t aSelectFlags);
396 // Helper for GetContentAndOffsetsFromPoint; calculation of content offsets
397 // in this function assumes there is no child frame that can be targeted.
398 virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
400 // Box layout methods
401 virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
402 virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
403 virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
404 virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
405 virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
407 // We compute and store the HTML content's overflow area. So don't
408 // try to compute it in the box code.
409 virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; }
411 //--------------------------------------------------
412 // Additional methods
414 // Helper function that tests if the frame tree is too deep; if it is
415 // it marks the frame as "unflowable", zeroes out the metrics, sets
416 // the reflow status, and returns true. Otherwise, the frame is
417 // unmarked "unflowable" and the metrics and reflow status are not
418 // touched and false is returned.
419 bool IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
420 nsHTMLReflowMetrics& aMetrics,
421 nsReflowStatus& aStatus);
423 // Incorporate the child overflow areas into aOverflowAreas.
424 // If the child does not have a overflow, use the child area.
425 void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas,
426 nsIFrame* aChildFrame);
429 * @return true if we should avoid a page/column break in this frame.
431 bool ShouldAvoidBreakInside(const nsHTMLReflowState& aReflowState) const {
432 return !aReflowState.mFlags.mIsTopOfPage &&
433 NS_STYLE_PAGE_BREAK_AVOID == StyleDisplay()->mBreakInside &&
434 !GetPrevInFlow();
437 #ifdef DEBUG
439 * Tracing method that writes a method enter/exit routine to the
440 * nspr log using the nsIFrame log module. The tracing is only
441 * done when the NS_FRAME_TRACE_CALLS bit is set in the log module's
442 * level field.
444 void Trace(const char* aMethod, bool aEnter);
445 void Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus);
446 void TraceMsg(const char* fmt, ...);
448 // Helper function that verifies that each frame in the list has the
449 // NS_FRAME_IS_DIRTY bit set
450 static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
452 static void XMLQuote(nsString& aString);
455 * Dump out the "base classes" regression data. This should dump
456 * out the interior data, not the "frame" XML container. And it
457 * should call the base classes same named method before doing
458 * anything specific in a derived class. This means that derived
459 * classes need not override DumpRegressionData unless they need
460 * some custom behavior that requires changing how the outer "frame"
461 * XML container is dumped.
463 virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent);
465 // Display Reflow Debugging
466 static void* DisplayReflowEnter(nsPresContext* aPresContext,
467 nsIFrame* aFrame,
468 const nsHTMLReflowState& aReflowState);
469 static void* DisplayLayoutEnter(nsIFrame* aFrame);
470 static void* DisplayIntrinsicISizeEnter(nsIFrame* aFrame,
471 const char* aType);
472 static void* DisplayIntrinsicSizeEnter(nsIFrame* aFrame,
473 const char* aType);
474 static void DisplayReflowExit(nsPresContext* aPresContext,
475 nsIFrame* aFrame,
476 nsHTMLReflowMetrics& aMetrics,
477 uint32_t aStatus,
478 void* aFrameTreeNode);
479 static void DisplayLayoutExit(nsIFrame* aFrame,
480 void* aFrameTreeNode);
481 static void DisplayIntrinsicISizeExit(nsIFrame* aFrame,
482 const char* aType,
483 nscoord aResult,
484 void* aFrameTreeNode);
485 static void DisplayIntrinsicSizeExit(nsIFrame* aFrame,
486 const char* aType,
487 nsSize aResult,
488 void* aFrameTreeNode);
490 static void DisplayReflowStartup();
491 static void DisplayReflowShutdown();
492 #endif
495 * Adds display items for standard CSS background if necessary.
496 * Does not check IsVisibleForPainting.
497 * @param aForceBackground draw the background even if the frame
498 * background style appears to have no background --- this is useful
499 * for frames that might receive a propagated background via
500 * nsCSSRendering::FindBackground
501 * @return whether a themed background item was created.
503 bool DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
504 const nsDisplayListSet& aLists,
505 bool aForceBackground);
507 * Adds display items for standard CSS borders, background and outline for
508 * for this frame, as necessary. Checks IsVisibleForPainting and won't
509 * display anything if the frame is not visible.
510 * @param aForceBackground draw the background even if the frame
511 * background style appears to have no background --- this is useful
512 * for frames that might receive a propagated background via
513 * nsCSSRendering::FindBackground
515 void DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
516 const nsDisplayListSet& aLists,
517 bool aForceBackground = false);
519 * Add a display item for the CSS outline. Does not check visibility.
521 void DisplayOutlineUnconditional(nsDisplayListBuilder* aBuilder,
522 const nsDisplayListSet& aLists);
524 * Add a display item for the CSS outline, after calling
525 * IsVisibleForPainting to confirm we are visible.
527 void DisplayOutline(nsDisplayListBuilder* aBuilder,
528 const nsDisplayListSet& aLists);
531 * Adjust the given parent frame to the right style context parent frame for
532 * the child, given the pseudo-type of the prospective child. This handles
533 * things like walking out of table pseudos and so forth.
535 * @param aProspectiveParent what GetParent() on the child returns.
536 * Must not be null.
537 * @param aChildPseudo the child's pseudo type, if any.
539 static nsIFrame*
540 CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsIAtom* aChildPseudo);
542 protected:
543 // Protected constructor and destructor
544 explicit nsFrame(nsStyleContext* aContext);
545 virtual ~nsFrame();
548 * To be called by |BuildDisplayLists| of this class or derived classes to add
549 * a translucent overlay if this frame's content is selected.
550 * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
551 * which kind of content this is for
553 void DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
554 nsDisplayList* aList, uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
556 int16_t DisplaySelection(nsPresContext* aPresContext, bool isOkToTurnOn = false);
558 // Style post processing hook
559 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
561 public:
562 //given a frame five me the first/last leaf available
563 //XXX Robert O'Callahan wants to move these elsewhere
564 static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
565 static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
567 // Return the line number of the aFrame, and (optionally) the containing block
568 // frame.
569 // If aScrollLock is true, don't break outside scrollframes when looking for a
570 // containing block frame.
571 static int32_t GetLineNumber(nsIFrame *aFrame,
572 bool aLockScroll,
573 nsIFrame** aContainingBlock = nullptr);
576 * Returns true if aFrame should apply overflow clipping.
578 static bool ShouldApplyOverflowClipping(const nsIFrame* aFrame,
579 const nsStyleDisplay* aDisp)
581 // clip overflow:-moz-hidden-unscrollable ...
582 if (MOZ_UNLIKELY(aDisp->mOverflowX == NS_STYLE_OVERFLOW_CLIP)) {
583 return true;
586 // and overflow:hidden that we should interpret as -moz-hidden-unscrollable
587 if (aDisp->mOverflowX == NS_STYLE_OVERFLOW_HIDDEN &&
588 aDisp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) {
589 // REVIEW: these are the frame types that set up clipping.
590 nsIAtom* type = aFrame->GetType();
591 if (type == nsGkAtoms::tableFrame ||
592 type == nsGkAtoms::tableCellFrame ||
593 type == nsGkAtoms::bcTableCellFrame ||
594 type == nsGkAtoms::svgOuterSVGFrame ||
595 type == nsGkAtoms::svgInnerSVGFrame ||
596 type == nsGkAtoms::svgForeignObjectFrame) {
597 return true;
599 if (aFrame->IsFrameOfType(nsIFrame::eReplacedContainsBlock)) {
600 if (type == nsGkAtoms::textInputFrame) {
601 // It always has an anonymous scroll frame that handles any overflow.
602 return false;
604 return true;
608 if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
609 return false;
612 // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW
613 // set, then we want to clip our overflow.
614 return
615 (aFrame->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW) != 0 &&
616 aFrame->PresContext()->IsPaginated() &&
617 aFrame->GetType() == nsGkAtoms::blockFrame;
620 virtual nsILineIterator* GetLineIterator() MOZ_OVERRIDE;
622 protected:
624 // Test if we are selecting a table object:
625 // Most table/cell selection requires that Ctrl (Cmd on Mac) key is down
626 // during a mouse click or drag. Exception is using Shift+click when
627 // already in "table/cell selection mode" to extend a block selection
628 // Get the parent content node and offset of the frame
629 // of the enclosing cell or table (if not inside a cell)
630 // aTarget tells us what table element to select (currently only cell and table supported)
631 // (enums for this are defined in nsIFrame.h)
632 NS_IMETHOD GetDataForTableSelection(const nsFrameSelection* aFrameSelection,
633 nsIPresShell* aPresShell,
634 mozilla::WidgetMouseEvent* aMouseEvent,
635 nsIContent** aParentContent,
636 int32_t* aContentOffset,
637 int32_t* aTarget);
639 // Fills aCursor with the appropriate information from ui
640 static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui,
641 nsIFrame::Cursor& aCursor);
642 NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
644 #ifdef DEBUG_LAYOUT
645 virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE;
646 #endif
648 nsBoxLayoutMetrics* BoxMetrics() const;
650 // Fire DOM event. If no aContent argument use frame's mContent.
651 void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr);
653 private:
654 void BoxReflow(nsBoxLayoutState& aState,
655 nsPresContext* aPresContext,
656 nsHTMLReflowMetrics& aDesiredSize,
657 nsRenderingContext* aRenderingContext,
658 nscoord aX,
659 nscoord aY,
660 nscoord aWidth,
661 nscoord aHeight,
662 bool aMoveFrame = true);
664 NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
666 #ifdef DEBUG_FRAME_DUMP
667 public:
669 * Get a printable from of the name of the frame type.
670 * XXX This should be eliminated and we use GetType() instead...
672 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
673 nsresult MakeFrameName(const nsAString& aKind, nsAString& aResult) const;
674 // Helper function to return the index in parent of the frame's content
675 // object. Returns -1 on error or if the frame doesn't have a content object
676 static int32_t ContentIndexInContainer(const nsIFrame* aFrame);
677 #endif
679 #ifdef DEBUG
680 public:
682 * Return the state bits that are relevant to regression tests (that
683 * is, those bits which indicate a real difference when they differ
685 virtual nsFrameState GetDebugStateBits() const MOZ_OVERRIDE;
687 * Called to dump out regression data that describes the layout
688 * of the frame and its children, and so on. The format of the
689 * data is dictated to be XML (using a specific DTD); the
690 * specific kind of data dumped is up to the frame itself, with
691 * the caveat that some base types are defined.
692 * For more information, see XXX.
694 virtual nsresult DumpRegressionData(nsPresContext* aPresContext,
695 FILE* out, int32_t aIndent) MOZ_OVERRIDE;
698 * See if style tree verification is enabled. To enable style tree
699 * verification add "styleverifytree:1" to your NSPR_LOG_MODULES
700 * environment variable (any non-zero debug level will work). Or,
701 * call SetVerifyStyleTreeEnable with true.
703 static bool GetVerifyStyleTreeEnable();
706 * Set the verify-style-tree enable flag.
708 static void SetVerifyStyleTreeEnable(bool aEnabled);
711 * The frame class and related classes share an nspr log module
712 * for logging frame activity.
714 * Note: the log module is created during library initialization which
715 * means that you cannot perform logging before then.
717 static PRLogModuleInfo* GetLogModuleInfo();
719 // Show frame borders when rendering
720 static void ShowFrameBorders(bool aEnable);
721 static bool GetShowFrameBorders();
723 // Show frame border of event target
724 static void ShowEventTargetFrameBorder(bool aEnable);
725 static bool GetShowEventTargetFrameBorder();
727 #endif
728 #ifdef MOZ_DUMP_PAINTING
729 public:
731 static void PrintDisplayItem(nsDisplayListBuilder* aBuilder,
732 nsDisplayItem* aItem,
733 std::stringstream& aStream,
734 bool aDumpSublist = false,
735 bool aDumpHtml = false);
737 static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
738 const nsDisplayList& aList,
739 bool aDumpHtml = false)
741 std::stringstream ss;
742 PrintDisplayList(aBuilder, aList, ss, aDumpHtml);
743 fprintf_stderr(stderr, "%s", ss.str().c_str());
745 static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
746 const nsDisplayList& aList,
747 std::stringstream& aStream,
748 bool aDumpHtml = false);
749 static void PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
750 const nsDisplayListSet& aList,
751 std::stringstream& aStream,
752 bool aDumpHtml = false);
754 #endif
757 // Start Display Reflow Debugging
758 #ifdef DEBUG
760 struct DR_cookie {
761 DR_cookie(nsPresContext* aPresContext,
762 nsIFrame* aFrame,
763 const nsHTMLReflowState& aReflowState,
764 nsHTMLReflowMetrics& aMetrics,
765 nsReflowStatus& aStatus);
766 ~DR_cookie();
767 void Change() const;
769 nsPresContext* mPresContext;
770 nsIFrame* mFrame;
771 const nsHTMLReflowState& mReflowState;
772 nsHTMLReflowMetrics& mMetrics;
773 nsReflowStatus& mStatus;
774 void* mValue;
777 struct DR_layout_cookie {
778 explicit DR_layout_cookie(nsIFrame* aFrame);
779 ~DR_layout_cookie();
781 nsIFrame* mFrame;
782 void* mValue;
785 struct DR_intrinsic_width_cookie {
786 DR_intrinsic_width_cookie(nsIFrame* aFrame, const char* aType,
787 nscoord& aResult);
788 ~DR_intrinsic_width_cookie();
790 nsIFrame* mFrame;
791 const char* mType;
792 nscoord& mResult;
793 void* mValue;
796 struct DR_intrinsic_size_cookie {
797 DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType,
798 nsSize& aResult);
799 ~DR_intrinsic_size_cookie();
801 nsIFrame* mFrame;
802 const char* mType;
803 nsSize& mResult;
804 void* mValue;
807 struct DR_init_constraints_cookie {
808 DR_init_constraints_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState,
809 nscoord aCBWidth, nscoord aCBHeight,
810 const nsMargin* aBorder,
811 const nsMargin* aPadding);
812 ~DR_init_constraints_cookie();
814 nsIFrame* mFrame;
815 nsHTMLReflowState* mState;
816 void* mValue;
819 struct DR_init_offsets_cookie {
820 DR_init_offsets_cookie(nsIFrame* aFrame, nsCSSOffsetState* aState,
821 nscoord aHorizontalPercentBasis,
822 nscoord aVerticalPercentBasis,
823 const nsMargin* aBorder,
824 const nsMargin* aPadding);
825 ~DR_init_offsets_cookie();
827 nsIFrame* mFrame;
828 nsCSSOffsetState* mState;
829 void* mValue;
832 struct DR_init_type_cookie {
833 DR_init_type_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState);
834 ~DR_init_type_cookie();
836 nsIFrame* mFrame;
837 nsHTMLReflowState* mState;
838 void* mValue;
841 #define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) \
842 DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status);
843 #define DISPLAY_REFLOW_CHANGE() \
844 dr_cookie.Change();
845 #define DISPLAY_LAYOUT(dr_frame) \
846 DR_layout_cookie dr_cookie(dr_frame);
847 #define DISPLAY_MIN_WIDTH(dr_frame, dr_result) \
848 DR_intrinsic_width_cookie dr_cookie(dr_frame, "Min", dr_result)
849 #define DISPLAY_PREF_WIDTH(dr_frame, dr_result) \
850 DR_intrinsic_width_cookie dr_cookie(dr_frame, "Pref", dr_result)
851 #define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
852 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
853 #define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
854 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
855 #define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
856 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
857 #define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, \
858 dr_bdr, dr_pad) \
859 DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
860 dr_bdr, dr_pad)
861 #define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) \
862 DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad)
863 #define DISPLAY_INIT_TYPE(dr_frame, dr_result) \
864 DR_init_type_cookie dr_cookie(dr_frame, dr_result)
866 #else
868 #define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status)
869 #define DISPLAY_REFLOW_CHANGE()
870 #define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO
871 #define DISPLAY_MIN_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
872 #define DISPLAY_PREF_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
873 #define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
874 #define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
875 #define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
876 #define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, \
877 dr_bdr, dr_pad) \
878 PR_BEGIN_MACRO PR_END_MACRO
879 #define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) \
880 PR_BEGIN_MACRO PR_END_MACRO
881 #define DISPLAY_INIT_TYPE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
883 #endif
884 // End Display Reflow Debugging
886 // similar to NS_ENSURE_TRUE but with no return value
887 #define ENSURE_TRUE(x) \
888 PR_BEGIN_MACRO \
889 if (!(x)) { \
890 NS_WARNING("ENSURE_TRUE(" #x ") failed"); \
891 return; \
893 PR_END_MACRO
894 #endif /* nsFrame_h___ */