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 */
11 #include "mozilla/Attributes.h"
12 #include "mozilla/EventForwards.h"
13 #include "mozilla/Likely.h"
17 #include "nsIPresShell.h"
18 #include "nsHTMLReflowState.h"
19 #include "nsHTMLParts.h"
20 #include "nsISelectionDisplay.h"
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))
36 #define NS_FRAME_LOG(_bit,_args) \
38 if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \
43 #define NS_FRAME_LOG(_bit,_args)
46 // XXX Need to rework this so that logging is free when it's off
48 #define NS_FRAME_TRACE_IN(_method) Trace(_method, true)
50 #define NS_FRAME_TRACE_OUT(_method) Trace(_method, false)
53 #define NS_FRAME_TRACE_MSG(_bit,_args) \
55 if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \
60 #define NS_FRAME_TRACE(_bit,_args) \
62 if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \
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)
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)
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
;
104 * Implementation of a simple frame that's not splittable and has no
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
114 * Create a new "empty" frame that maps a given piece of content into a
117 friend nsIFrame
* NS_NewEmptyFrame(nsIPresShell
* aShell
,
118 nsStyleContext
* aContext
);
121 // Left undefined; nsFrame objects are never allocated from the heap.
122 void* operator new(size_t sz
) CPP_THROW_NEW
;
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
);
141 NS_DECL_FRAMEARENA_HELPERS
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
,
168 int32_t* outFrameContentOffset
,
169 nsIFrame
** outChildFrame
) MOZ_OVERRIDE
;
171 static nsresult
GetNextPrevLineFromeBlockFrame(nsPresContext
* aPresContext
,
172 nsPeekOffsetStruct
*aPos
,
173 nsIFrame
*aBlockFrame
,
178 virtual nsresult
CharacterDataChanged(CharacterDataChangeInfo
* aInfo
) MOZ_OVERRIDE
;
179 virtual nsresult
AttributeChanged(int32_t aNameSpaceID
,
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
,
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
;
221 virtual mozilla::a11y::AccType
AccessibleType() MOZ_OVERRIDE
;
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
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
,
292 * Utility function for ComputeAutoSize implementations. Return
293 * max(GetMinISize(), min(aWidthInCB, GetPrefISize()))
295 nscoord
ShrinkWidthToFit(nsRenderingContext
*aRenderingContext
,
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
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
;
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
,
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
,
386 nsPresContext
* aPresContext
,
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
&&
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
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
,
468 const nsHTMLReflowState
& aReflowState
);
469 static void* DisplayLayoutEnter(nsIFrame
* aFrame
);
470 static void* DisplayIntrinsicISizeEnter(nsIFrame
* aFrame
,
472 static void* DisplayIntrinsicSizeEnter(nsIFrame
* aFrame
,
474 static void DisplayReflowExit(nsPresContext
* aPresContext
,
476 nsHTMLReflowMetrics
& aMetrics
,
478 void* aFrameTreeNode
);
479 static void DisplayLayoutExit(nsIFrame
* aFrame
,
480 void* aFrameTreeNode
);
481 static void DisplayIntrinsicISizeExit(nsIFrame
* aFrame
,
484 void* aFrameTreeNode
);
485 static void DisplayIntrinsicSizeExit(nsIFrame
* aFrame
,
488 void* aFrameTreeNode
);
490 static void DisplayReflowStartup();
491 static void DisplayReflowShutdown();
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.
537 * @param aChildPseudo the child's pseudo type, if any.
540 CorrectStyleParentFrame(nsIFrame
* aProspectiveParent
, nsIAtom
* aChildPseudo
);
543 // Protected constructor and destructor
544 explicit nsFrame(nsStyleContext
* aContext
);
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
;
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
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
,
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
)) {
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
) {
599 if (aFrame
->IsFrameOfType(nsIFrame::eReplacedContainsBlock
)) {
600 if (type
== nsGkAtoms::textInputFrame
) {
601 // It always has an anonymous scroll frame that handles any overflow.
608 if ((aFrame
->GetStateBits() & NS_FRAME_SVG_LAYOUT
)) {
612 // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW
613 // set, then we want to clip our overflow.
615 (aFrame
->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW
) != 0 &&
616 aFrame
->PresContext()->IsPaginated() &&
617 aFrame
->GetType() == nsGkAtoms::blockFrame
;
620 virtual nsILineIterator
* GetLineIterator() MOZ_OVERRIDE
;
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
,
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
;
645 virtual void GetBoxName(nsAutoString
& aName
) MOZ_OVERRIDE
;
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);
654 void BoxReflow(nsBoxLayoutState
& aState
,
655 nsPresContext
* aPresContext
,
656 nsHTMLReflowMetrics
& aDesiredSize
,
657 nsRenderingContext
* aRenderingContext
,
662 bool aMoveFrame
= true);
664 NS_IMETHODIMP
RefreshSizeCache(nsBoxLayoutState
& aState
);
666 #ifdef DEBUG_FRAME_DUMP
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
);
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();
728 #ifdef MOZ_DUMP_PAINTING
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);
757 // Start Display Reflow Debugging
761 DR_cookie(nsPresContext
* aPresContext
,
763 const nsHTMLReflowState
& aReflowState
,
764 nsHTMLReflowMetrics
& aMetrics
,
765 nsReflowStatus
& aStatus
);
769 nsPresContext
* mPresContext
;
771 const nsHTMLReflowState
& mReflowState
;
772 nsHTMLReflowMetrics
& mMetrics
;
773 nsReflowStatus
& mStatus
;
777 struct DR_layout_cookie
{
778 explicit DR_layout_cookie(nsIFrame
* aFrame
);
785 struct DR_intrinsic_width_cookie
{
786 DR_intrinsic_width_cookie(nsIFrame
* aFrame
, const char* aType
,
788 ~DR_intrinsic_width_cookie();
796 struct DR_intrinsic_size_cookie
{
797 DR_intrinsic_size_cookie(nsIFrame
* aFrame
, const char* aType
,
799 ~DR_intrinsic_size_cookie();
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();
815 nsHTMLReflowState
* mState
;
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();
828 nsCSSOffsetState
* mState
;
832 struct DR_init_type_cookie
{
833 DR_init_type_cookie(nsIFrame
* aFrame
, nsHTMLReflowState
* aState
);
834 ~DR_init_type_cookie();
837 nsHTMLReflowState
* mState
;
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() \
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, \
859 DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
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)
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, \
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
884 // End Display Reflow Debugging
886 // similar to NS_ENSURE_TRUE but with no return value
887 #define ENSURE_TRUE(x) \
890 NS_WARNING("ENSURE_TRUE(" #x ") failed"); \
894 #endif /* nsFrame_h___ */