Bumping manifests a=b2g-bump
[gecko.git] / layout / generic / nsFrame.h
blob13e3fda702dc94fbd49eb61dd108cb079ce680d9
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_OVERRIDE 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 void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE;
142 virtual nsQueryFrame::FrameIID GetFrameId() MOZ_MUST_OVERRIDE;
144 // nsIFrame
145 virtual void Init(nsIContent* aContent,
146 nsContainerFrame* aParent,
147 nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
148 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
149 virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE;
150 virtual void SetAdditionalStyleContext(int32_t aIndex,
151 nsStyleContext* aStyleContext) MOZ_OVERRIDE;
152 virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const MOZ_OVERRIDE;
153 virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
154 virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
156 virtual nsresult HandleEvent(nsPresContext* aPresContext,
157 mozilla::WidgetGUIEvent* aEvent,
158 nsEventStatus* aEventStatus) MOZ_OVERRIDE;
159 virtual nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent,
160 nsIContent** aContent) MOZ_OVERRIDE;
161 virtual nsresult GetCursor(const nsPoint& aPoint,
162 nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
164 virtual nsresult GetPointFromOffset(int32_t inOffset,
165 nsPoint* outPoint) MOZ_OVERRIDE;
167 virtual nsresult GetChildFrameContainingOffset(int32_t inContentOffset,
168 bool inHint,
169 int32_t* outFrameContentOffset,
170 nsIFrame** outChildFrame) MOZ_OVERRIDE;
172 static nsresult GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
173 nsPeekOffsetStruct *aPos,
174 nsIFrame *aBlockFrame,
175 int32_t aLineStart,
176 int8_t aOutSideLimit
179 virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE;
180 virtual nsresult AttributeChanged(int32_t aNameSpaceID,
181 nsIAtom* aAttribute,
182 int32_t aModType) MOZ_OVERRIDE;
183 virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE;
184 virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE;
185 virtual void SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE;
186 virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE;
187 virtual void SetNextContinuation(nsIFrame*) MOZ_OVERRIDE;
188 virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE;
189 virtual void SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE;
190 virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE;
191 virtual void SetNextInFlow(nsIFrame*) MOZ_OVERRIDE;
192 virtual nsIAtom* GetType() const MOZ_OVERRIDE;
194 virtual nsresult IsSelectable(bool* aIsSelectable, uint8_t* aSelectStyle) const MOZ_OVERRIDE;
196 virtual nsresult GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon) MOZ_OVERRIDE;
198 virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
199 virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
200 bool aRespectClusters = true) MOZ_OVERRIDE;
201 virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
202 int32_t* aOffset, PeekWordState *aState) MOZ_OVERRIDE;
204 * Check whether we should break at a boundary between punctuation and
205 * non-punctuation. Only call it at a punctuation boundary
206 * (i.e. exactly one of the previous and next characters are punctuation).
207 * @param aForward true if we're moving forward in content order
208 * @param aPunctAfter true if the next character is punctuation
209 * @param aWhitespaceAfter true if the next character is whitespace
211 bool BreakWordBetweenPunctuation(const PeekWordState* aState,
212 bool aForward,
213 bool aPunctAfter, bool aWhitespaceAfter,
214 bool aIsKeyboardSelect);
216 virtual nsresult CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) MOZ_OVERRIDE;
218 virtual nsresult GetOffsets(int32_t &aStart, int32_t &aEnd) const MOZ_OVERRIDE;
219 virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE;
221 #ifdef ACCESSIBILITY
222 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
223 #endif
225 virtual nsStyleContext* GetParentStyleContext(nsIFrame** aProviderFrame) const MOZ_OVERRIDE {
226 return DoGetParentStyleContext(aProviderFrame);
230 * Do the work for getting the parent style context frame so that
231 * other frame's |GetParentStyleContext| methods can call this
232 * method on *another* frame. (This function handles out-of-flow
233 * frames by using the frame manager's placeholder map and it also
234 * handles block-within-inline and generated content wrappers.)
236 * @param aProviderFrame (out) the frame associated with the returned value
237 * or null if the style context is for display:contents content.
238 * @return The style context that should be the parent of this frame's
239 * style context. Null is permitted, and means that this frame's
240 * style context should be the root of the style context tree.
242 nsStyleContext* DoGetParentStyleContext(nsIFrame** aProviderFrame) const;
244 virtual bool IsEmpty() MOZ_OVERRIDE;
245 virtual bool IsSelfEmpty() MOZ_OVERRIDE;
247 virtual void MarkIntrinsicISizesDirty() MOZ_OVERRIDE;
248 virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
249 virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
250 virtual void AddInlineMinISize(nsRenderingContext *aRenderingContext,
251 InlineMinISizeData *aData) MOZ_OVERRIDE;
252 virtual void AddInlinePrefISize(nsRenderingContext *aRenderingContext,
253 InlinePrefISizeData *aData) MOZ_OVERRIDE;
254 virtual IntrinsicISizeOffsetData
255 IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
256 virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE;
257 virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE;
259 virtual mozilla::LogicalSize
260 ComputeSize(nsRenderingContext *aRenderingContext,
261 mozilla::WritingMode aWritingMode,
262 const mozilla::LogicalSize& aCBSize,
263 nscoord aAvailableISize,
264 const mozilla::LogicalSize& aMargin,
265 const mozilla::LogicalSize& aBorder,
266 const mozilla::LogicalSize& aPadding,
267 ComputeSizeFlags aFlags) MOZ_OVERRIDE;
269 // Compute tight bounds assuming this frame honours its border, background
270 // and outline, its children's tight bounds, and nothing else.
271 nsRect ComputeSimpleTightBounds(gfxContext* aContext) const;
274 * A helper, used by |nsFrame::ComputeSize| (for frames that need to
275 * override only this part of ComputeSize), that computes the size
276 * that should be returned when 'width', 'height', and
277 * min/max-width/height are all 'auto' or equivalent.
279 * In general, frames that can accept any computed width/height should
280 * override only ComputeAutoSize, and frames that cannot do so need to
281 * override ComputeSize to enforce their width/height invariants.
283 * Implementations may optimize by returning a garbage width if
284 * StylePosition()->mWidth.GetUnit() != eStyleUnit_Auto, and
285 * likewise for height, since in such cases the result is guaranteed
286 * to be unused.
288 virtual mozilla::LogicalSize
289 ComputeAutoSize(nsRenderingContext *aRenderingContext,
290 mozilla::WritingMode aWritingMode,
291 const mozilla::LogicalSize& aCBSize,
292 nscoord aAvailableISize,
293 const mozilla::LogicalSize& aMargin,
294 const mozilla::LogicalSize& aBorder,
295 const mozilla::LogicalSize& aPadding,
296 bool aShrinkWrap);
299 * Utility function for ComputeAutoSize implementations. Return
300 * max(GetMinISize(), min(aWidthInCB, GetPrefISize()))
302 nscoord ShrinkWidthToFit(nsRenderingContext *aRenderingContext,
303 nscoord aWidthInCB);
305 virtual void WillReflow(nsPresContext* aPresContext) MOZ_OVERRIDE;
307 * Calculates the size of this frame after reflowing (calling Reflow on, and
308 * updating the size and position of) its children, as necessary. The
309 * calculated size is returned to the caller via the nsHTMLReflowMetrics
310 * outparam. (The caller is responsible for setting the actual size and
311 * position of this frame.)
313 * A frame's children must _all_ be reflowed if the frame is dirty (the
314 * NS_FRAME_IS_DIRTY bit is set on it). Otherwise, individual children
315 * must be reflowed if they are dirty or have the NS_FRAME_HAS_DIRTY_CHILDREN
316 * bit set on them. Otherwise, whether children need to be reflowed depends
317 * on the frame's type (it's up to individual Reflow methods), and on what
318 * has changed. For example, a change in the width of the frame may require
319 * all of its children to be reflowed (even those without dirty bits set on
320 * them), whereas a change in its height might not.
321 * (nsHTMLReflowState::ShouldReflowAllKids may be helpful in deciding whether
322 * to reflow all the children, but for some frame types it might result in
323 * over-reflow.)
325 * Note: if it's only the overflow rect(s) of a frame that need to be
326 * updated, then UpdateOverflow should be called instead of Reflow.
328 virtual void Reflow(nsPresContext* aPresContext,
329 nsHTMLReflowMetrics& aDesiredSize,
330 const nsHTMLReflowState& aReflowState,
331 nsReflowStatus& aStatus) MOZ_OVERRIDE;
332 virtual void DidReflow(nsPresContext* aPresContext,
333 const nsHTMLReflowState* aReflowState,
334 nsDidReflowStatus aStatus) MOZ_OVERRIDE;
337 * NOTE: aStatus is assumed to be already-initialized. The reflow statuses of
338 * any reflowed absolute children will be merged into aStatus; aside from
339 * that, this method won't modify aStatus.
341 void ReflowAbsoluteFrames(nsPresContext* aPresContext,
342 nsHTMLReflowMetrics& aDesiredSize,
343 const nsHTMLReflowState& aReflowState,
344 nsReflowStatus& aStatus,
345 bool aConstrainHeight = true);
346 void FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext,
347 nsHTMLReflowMetrics& aDesiredSize,
348 const nsHTMLReflowState& aReflowState,
349 nsReflowStatus& aStatus,
350 bool aConstrainHeight = true);
353 * If this frame is dirty, marks all absolutely-positioned children of this
354 * frame dirty. If this frame isn't dirty, or if there are no
355 * absolutely-positioned children, does nothing.
357 * It's necessary to use PushDirtyBitToAbsoluteFrames() when you plan to
358 * reflow this frame's absolutely-positioned children after the dirty bit on
359 * this frame has already been cleared, which prevents nsHTMLReflowState from
360 * propagating the dirty bit normally. This situation generally only arises
361 * when a multipass layout algorithm is used.
363 void PushDirtyBitToAbsoluteFrames();
365 virtual bool CanContinueTextRun() const MOZ_OVERRIDE;
367 virtual bool UpdateOverflow() MOZ_OVERRIDE;
369 // Selection Methods
371 NS_IMETHOD HandlePress(nsPresContext* aPresContext,
372 mozilla::WidgetGUIEvent* aEvent,
373 nsEventStatus* aEventStatus);
375 NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext,
376 mozilla::WidgetGUIEvent* aEvent,
377 nsEventStatus* aEventStatus,
378 bool aControlHeld);
380 NS_IMETHOD HandleDrag(nsPresContext* aPresContext,
381 mozilla::WidgetGUIEvent* aEvent,
382 nsEventStatus* aEventStatus);
384 NS_IMETHOD HandleRelease(nsPresContext* aPresContext,
385 mozilla::WidgetGUIEvent* aEvent,
386 nsEventStatus* aEventStatus);
388 enum { SELECT_ACCUMULATE = 0x01 };
390 nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack,
391 nsSelectionAmount aAmountForward,
392 int32_t aStartPos,
393 nsPresContext* aPresContext,
394 bool aJumpLines,
395 uint32_t aSelectFlags);
397 nsresult SelectByTypeAtPoint(nsPresContext* aPresContext,
398 const nsPoint& aPoint,
399 nsSelectionAmount aBeginAmountType,
400 nsSelectionAmount aEndAmountType,
401 uint32_t aSelectFlags);
403 // Helper for GetContentAndOffsetsFromPoint; calculation of content offsets
404 // in this function assumes there is no child frame that can be targeted.
405 virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
407 // Box layout methods
408 virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
409 virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
410 virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
411 virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
412 virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
414 // We compute and store the HTML content's overflow area. So don't
415 // try to compute it in the box code.
416 virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; }
418 //--------------------------------------------------
419 // Additional methods
421 // Helper function that tests if the frame tree is too deep; if it is
422 // it marks the frame as "unflowable", zeroes out the metrics, sets
423 // the reflow status, and returns true. Otherwise, the frame is
424 // unmarked "unflowable" and the metrics and reflow status are not
425 // touched and false is returned.
426 bool IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
427 nsHTMLReflowMetrics& aMetrics,
428 nsReflowStatus& aStatus);
430 // Incorporate the child overflow areas into aOverflowAreas.
431 // If the child does not have a overflow, use the child area.
432 void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas,
433 nsIFrame* aChildFrame);
436 * @return true if we should avoid a page/column break in this frame.
438 bool ShouldAvoidBreakInside(const nsHTMLReflowState& aReflowState) const {
439 return !aReflowState.mFlags.mIsTopOfPage &&
440 NS_STYLE_PAGE_BREAK_AVOID == StyleDisplay()->mBreakInside &&
441 !GetPrevInFlow();
444 #ifdef DEBUG
446 * Tracing method that writes a method enter/exit routine to the
447 * nspr log using the nsIFrame log module. The tracing is only
448 * done when the NS_FRAME_TRACE_CALLS bit is set in the log module's
449 * level field.
451 void Trace(const char* aMethod, bool aEnter);
452 void Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus);
453 void TraceMsg(const char* fmt, ...);
455 // Helper function that verifies that each frame in the list has the
456 // NS_FRAME_IS_DIRTY bit set
457 static void VerifyDirtyBitSet(const nsFrameList& aFrameList);
459 static void XMLQuote(nsString& aString);
462 * Dump out the "base classes" regression data. This should dump
463 * out the interior data, not the "frame" XML container. And it
464 * should call the base classes same named method before doing
465 * anything specific in a derived class. This means that derived
466 * classes need not override DumpRegressionData unless they need
467 * some custom behavior that requires changing how the outer "frame"
468 * XML container is dumped.
470 virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent);
472 // Display Reflow Debugging
473 static void* DisplayReflowEnter(nsPresContext* aPresContext,
474 nsIFrame* aFrame,
475 const nsHTMLReflowState& aReflowState);
476 static void* DisplayLayoutEnter(nsIFrame* aFrame);
477 static void* DisplayIntrinsicISizeEnter(nsIFrame* aFrame,
478 const char* aType);
479 static void* DisplayIntrinsicSizeEnter(nsIFrame* aFrame,
480 const char* aType);
481 static void DisplayReflowExit(nsPresContext* aPresContext,
482 nsIFrame* aFrame,
483 nsHTMLReflowMetrics& aMetrics,
484 uint32_t aStatus,
485 void* aFrameTreeNode);
486 static void DisplayLayoutExit(nsIFrame* aFrame,
487 void* aFrameTreeNode);
488 static void DisplayIntrinsicISizeExit(nsIFrame* aFrame,
489 const char* aType,
490 nscoord aResult,
491 void* aFrameTreeNode);
492 static void DisplayIntrinsicSizeExit(nsIFrame* aFrame,
493 const char* aType,
494 nsSize aResult,
495 void* aFrameTreeNode);
497 static void DisplayReflowStartup();
498 static void DisplayReflowShutdown();
499 #endif
502 * Adds display items for standard CSS background if necessary.
503 * Does not check IsVisibleForPainting.
504 * @param aForceBackground draw the background even if the frame
505 * background style appears to have no background --- this is useful
506 * for frames that might receive a propagated background via
507 * nsCSSRendering::FindBackground
508 * @return whether a themed background item was created.
510 bool DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
511 const nsDisplayListSet& aLists,
512 bool aForceBackground);
514 * Adds display items for standard CSS borders, background and outline for
515 * for this frame, as necessary. Checks IsVisibleForPainting and won't
516 * display anything if the frame is not visible.
517 * @param aForceBackground draw the background even if the frame
518 * background style appears to have no background --- this is useful
519 * for frames that might receive a propagated background via
520 * nsCSSRendering::FindBackground
522 void DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
523 const nsDisplayListSet& aLists,
524 bool aForceBackground = false);
526 * Add a display item for the CSS outline. Does not check visibility.
528 void DisplayOutlineUnconditional(nsDisplayListBuilder* aBuilder,
529 const nsDisplayListSet& aLists);
531 * Add a display item for the CSS outline, after calling
532 * IsVisibleForPainting to confirm we are visible.
534 void DisplayOutline(nsDisplayListBuilder* aBuilder,
535 const nsDisplayListSet& aLists);
538 * Adjust the given parent frame to the right style context parent frame for
539 * the child, given the pseudo-type of the prospective child. This handles
540 * things like walking out of table pseudos and so forth.
542 * @param aProspectiveParent what GetParent() on the child returns.
543 * Must not be null.
544 * @param aChildPseudo the child's pseudo type, if any.
546 static nsIFrame*
547 CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsIAtom* aChildPseudo);
549 protected:
550 // Protected constructor and destructor
551 explicit nsFrame(nsStyleContext* aContext);
552 virtual ~nsFrame();
555 * To be called by |BuildDisplayLists| of this class or derived classes to add
556 * a translucent overlay if this frame's content is selected.
557 * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
558 * which kind of content this is for
560 void DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
561 nsDisplayList* aList, uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
563 int16_t DisplaySelection(nsPresContext* aPresContext, bool isOkToTurnOn = false);
565 // Style post processing hook
566 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
568 public:
569 //given a frame five me the first/last leaf available
570 //XXX Robert O'Callahan wants to move these elsewhere
571 static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
572 static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame);
574 // Return the line number of the aFrame, and (optionally) the containing block
575 // frame.
576 // If aScrollLock is true, don't break outside scrollframes when looking for a
577 // containing block frame.
578 static int32_t GetLineNumber(nsIFrame *aFrame,
579 bool aLockScroll,
580 nsIFrame** aContainingBlock = nullptr);
583 * Returns true if aFrame should apply overflow clipping.
585 static bool ShouldApplyOverflowClipping(const nsIFrame* aFrame,
586 const nsStyleDisplay* aDisp)
588 // clip overflow:-moz-hidden-unscrollable ...
589 if (MOZ_UNLIKELY(aDisp->mOverflowX == NS_STYLE_OVERFLOW_CLIP)) {
590 return true;
593 // and overflow:hidden that we should interpret as -moz-hidden-unscrollable
594 if (aDisp->mOverflowX == NS_STYLE_OVERFLOW_HIDDEN &&
595 aDisp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) {
596 // REVIEW: these are the frame types that set up clipping.
597 nsIAtom* type = aFrame->GetType();
598 if (type == nsGkAtoms::tableFrame ||
599 type == nsGkAtoms::tableCellFrame ||
600 type == nsGkAtoms::bcTableCellFrame ||
601 type == nsGkAtoms::svgOuterSVGFrame ||
602 type == nsGkAtoms::svgInnerSVGFrame ||
603 type == nsGkAtoms::svgForeignObjectFrame) {
604 return true;
606 if (aFrame->IsFrameOfType(nsIFrame::eReplacedContainsBlock)) {
607 if (type == nsGkAtoms::textInputFrame) {
608 // It always has an anonymous scroll frame that handles any overflow.
609 return false;
611 return true;
615 if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
616 return false;
619 // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW
620 // set, then we want to clip our overflow.
621 return
622 (aFrame->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW) != 0 &&
623 aFrame->PresContext()->IsPaginated() &&
624 aFrame->GetType() == nsGkAtoms::blockFrame;
627 virtual nsILineIterator* GetLineIterator() MOZ_OVERRIDE;
629 protected:
631 // Test if we are selecting a table object:
632 // Most table/cell selection requires that Ctrl (Cmd on Mac) key is down
633 // during a mouse click or drag. Exception is using Shift+click when
634 // already in "table/cell selection mode" to extend a block selection
635 // Get the parent content node and offset of the frame
636 // of the enclosing cell or table (if not inside a cell)
637 // aTarget tells us what table element to select (currently only cell and table supported)
638 // (enums for this are defined in nsIFrame.h)
639 NS_IMETHOD GetDataForTableSelection(const nsFrameSelection* aFrameSelection,
640 nsIPresShell* aPresShell,
641 mozilla::WidgetMouseEvent* aMouseEvent,
642 nsIContent** aParentContent,
643 int32_t* aContentOffset,
644 int32_t* aTarget);
646 // Fills aCursor with the appropriate information from ui
647 static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui,
648 nsIFrame::Cursor& aCursor);
649 NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
651 #ifdef DEBUG_LAYOUT
652 virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE;
653 #endif
655 nsBoxLayoutMetrics* BoxMetrics() const;
657 // Fire DOM event. If no aContent argument use frame's mContent.
658 void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr);
660 private:
661 void BoxReflow(nsBoxLayoutState& aState,
662 nsPresContext* aPresContext,
663 nsHTMLReflowMetrics& aDesiredSize,
664 nsRenderingContext* aRenderingContext,
665 nscoord aX,
666 nscoord aY,
667 nscoord aWidth,
668 nscoord aHeight,
669 bool aMoveFrame = true);
671 NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState);
673 #ifdef DEBUG_FRAME_DUMP
674 public:
676 * Get a printable from of the name of the frame type.
677 * XXX This should be eliminated and we use GetType() instead...
679 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
680 nsresult MakeFrameName(const nsAString& aKind, nsAString& aResult) const;
681 // Helper function to return the index in parent of the frame's content
682 // object. Returns -1 on error or if the frame doesn't have a content object
683 static int32_t ContentIndexInContainer(const nsIFrame* aFrame);
684 #endif
686 #ifdef DEBUG
687 public:
689 * Return the state bits that are relevant to regression tests (that
690 * is, those bits which indicate a real difference when they differ
692 virtual nsFrameState GetDebugStateBits() const MOZ_OVERRIDE;
694 * Called to dump out regression data that describes the layout
695 * of the frame and its children, and so on. The format of the
696 * data is dictated to be XML (using a specific DTD); the
697 * specific kind of data dumped is up to the frame itself, with
698 * the caveat that some base types are defined.
699 * For more information, see XXX.
701 virtual nsresult DumpRegressionData(nsPresContext* aPresContext,
702 FILE* out, int32_t aIndent) MOZ_OVERRIDE;
705 * See if style tree verification is enabled. To enable style tree
706 * verification add "styleverifytree:1" to your NSPR_LOG_MODULES
707 * environment variable (any non-zero debug level will work). Or,
708 * call SetVerifyStyleTreeEnable with true.
710 static bool GetVerifyStyleTreeEnable();
713 * Set the verify-style-tree enable flag.
715 static void SetVerifyStyleTreeEnable(bool aEnabled);
718 * The frame class and related classes share an nspr log module
719 * for logging frame activity.
721 * Note: the log module is created during library initialization which
722 * means that you cannot perform logging before then.
724 static PRLogModuleInfo* GetLogModuleInfo();
726 // Show frame borders when rendering
727 static void ShowFrameBorders(bool aEnable);
728 static bool GetShowFrameBorders();
730 // Show frame border of event target
731 static void ShowEventTargetFrameBorder(bool aEnable);
732 static bool GetShowEventTargetFrameBorder();
734 #endif
736 public:
738 static void PrintDisplayItem(nsDisplayListBuilder* aBuilder,
739 nsDisplayItem* aItem,
740 std::stringstream& aStream,
741 bool aDumpSublist = false,
742 bool aDumpHtml = false);
744 static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
745 const nsDisplayList& aList,
746 bool aDumpHtml = false)
748 std::stringstream ss;
749 PrintDisplayList(aBuilder, aList, ss, aDumpHtml);
750 fprintf_stderr(stderr, "%s", ss.str().c_str());
752 static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
753 const nsDisplayList& aList,
754 std::stringstream& aStream,
755 bool aDumpHtml = false);
756 static void PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
757 const nsDisplayListSet& aList,
758 std::stringstream& aStream,
759 bool aDumpHtml = false);
763 // Start Display Reflow Debugging
764 #ifdef DEBUG
766 struct DR_cookie {
767 DR_cookie(nsPresContext* aPresContext,
768 nsIFrame* aFrame,
769 const nsHTMLReflowState& aReflowState,
770 nsHTMLReflowMetrics& aMetrics,
771 nsReflowStatus& aStatus);
772 ~DR_cookie();
773 void Change() const;
775 nsPresContext* mPresContext;
776 nsIFrame* mFrame;
777 const nsHTMLReflowState& mReflowState;
778 nsHTMLReflowMetrics& mMetrics;
779 nsReflowStatus& mStatus;
780 void* mValue;
783 struct DR_layout_cookie {
784 explicit DR_layout_cookie(nsIFrame* aFrame);
785 ~DR_layout_cookie();
787 nsIFrame* mFrame;
788 void* mValue;
791 struct DR_intrinsic_width_cookie {
792 DR_intrinsic_width_cookie(nsIFrame* aFrame, const char* aType,
793 nscoord& aResult);
794 ~DR_intrinsic_width_cookie();
796 nsIFrame* mFrame;
797 const char* mType;
798 nscoord& mResult;
799 void* mValue;
802 struct DR_intrinsic_size_cookie {
803 DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType,
804 nsSize& aResult);
805 ~DR_intrinsic_size_cookie();
807 nsIFrame* mFrame;
808 const char* mType;
809 nsSize& mResult;
810 void* mValue;
813 struct DR_init_constraints_cookie {
814 DR_init_constraints_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState,
815 nscoord aCBWidth, nscoord aCBHeight,
816 const nsMargin* aBorder,
817 const nsMargin* aPadding);
818 ~DR_init_constraints_cookie();
820 nsIFrame* mFrame;
821 nsHTMLReflowState* mState;
822 void* mValue;
825 struct DR_init_offsets_cookie {
826 DR_init_offsets_cookie(nsIFrame* aFrame, nsCSSOffsetState* aState,
827 nscoord aHorizontalPercentBasis,
828 nscoord aVerticalPercentBasis,
829 const nsMargin* aBorder,
830 const nsMargin* aPadding);
831 ~DR_init_offsets_cookie();
833 nsIFrame* mFrame;
834 nsCSSOffsetState* mState;
835 void* mValue;
838 struct DR_init_type_cookie {
839 DR_init_type_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState);
840 ~DR_init_type_cookie();
842 nsIFrame* mFrame;
843 nsHTMLReflowState* mState;
844 void* mValue;
847 #define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) \
848 DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status);
849 #define DISPLAY_REFLOW_CHANGE() \
850 dr_cookie.Change();
851 #define DISPLAY_LAYOUT(dr_frame) \
852 DR_layout_cookie dr_cookie(dr_frame);
853 #define DISPLAY_MIN_WIDTH(dr_frame, dr_result) \
854 DR_intrinsic_width_cookie dr_cookie(dr_frame, "Min", dr_result)
855 #define DISPLAY_PREF_WIDTH(dr_frame, dr_result) \
856 DR_intrinsic_width_cookie dr_cookie(dr_frame, "Pref", dr_result)
857 #define DISPLAY_PREF_SIZE(dr_frame, dr_result) \
858 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result)
859 #define DISPLAY_MIN_SIZE(dr_frame, dr_result) \
860 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result)
861 #define DISPLAY_MAX_SIZE(dr_frame, dr_result) \
862 DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result)
863 #define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, \
864 dr_bdr, dr_pad) \
865 DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
866 dr_bdr, dr_pad)
867 #define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) \
868 DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad)
869 #define DISPLAY_INIT_TYPE(dr_frame, dr_result) \
870 DR_init_type_cookie dr_cookie(dr_frame, dr_result)
872 #else
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_hpb, dr_vpb, dr_bdr, dr_pad) \
886 PR_BEGIN_MACRO PR_END_MACRO
887 #define DISPLAY_INIT_TYPE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO
889 #endif
890 // End Display Reflow Debugging
892 // similar to NS_ENSURE_TRUE but with no return value
893 #define ENSURE_TRUE(x) \
894 PR_BEGIN_MACRO \
895 if (!(x)) { \
896 NS_WARNING("ENSURE_TRUE(" #x ") failed"); \
897 return; \
899 PR_END_MACRO
900 #endif /* nsFrame_h___ */