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_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
;
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 void* operator new(size_t, nsIPresShell
*) MOZ_MUST_OVERRIDE
;
142 virtual nsQueryFrame::FrameIID
GetFrameId() MOZ_MUST_OVERRIDE
;
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
,
169 int32_t* outFrameContentOffset
,
170 nsIFrame
** outChildFrame
) MOZ_OVERRIDE
;
172 static nsresult
GetNextPrevLineFromeBlockFrame(nsPresContext
* aPresContext
,
173 nsPeekOffsetStruct
*aPos
,
174 nsIFrame
*aBlockFrame
,
179 virtual nsresult
CharacterDataChanged(CharacterDataChangeInfo
* aInfo
) MOZ_OVERRIDE
;
180 virtual nsresult
AttributeChanged(int32_t aNameSpaceID
,
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
,
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
;
222 virtual mozilla::a11y::AccType
AccessibleType() MOZ_OVERRIDE
;
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
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
,
299 * Utility function for ComputeAutoSize implementations. Return
300 * max(GetMinISize(), min(aWidthInCB, GetPrefISize()))
302 nscoord
ShrinkWidthToFit(nsRenderingContext
*aRenderingContext
,
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
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
;
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
,
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
,
393 nsPresContext
* aPresContext
,
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
&&
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
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
,
475 const nsHTMLReflowState
& aReflowState
);
476 static void* DisplayLayoutEnter(nsIFrame
* aFrame
);
477 static void* DisplayIntrinsicISizeEnter(nsIFrame
* aFrame
,
479 static void* DisplayIntrinsicSizeEnter(nsIFrame
* aFrame
,
481 static void DisplayReflowExit(nsPresContext
* aPresContext
,
483 nsHTMLReflowMetrics
& aMetrics
,
485 void* aFrameTreeNode
);
486 static void DisplayLayoutExit(nsIFrame
* aFrame
,
487 void* aFrameTreeNode
);
488 static void DisplayIntrinsicISizeExit(nsIFrame
* aFrame
,
491 void* aFrameTreeNode
);
492 static void DisplayIntrinsicSizeExit(nsIFrame
* aFrame
,
495 void* aFrameTreeNode
);
497 static void DisplayReflowStartup();
498 static void DisplayReflowShutdown();
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.
544 * @param aChildPseudo the child's pseudo type, if any.
547 CorrectStyleParentFrame(nsIFrame
* aProspectiveParent
, nsIAtom
* aChildPseudo
);
550 // Protected constructor and destructor
551 explicit nsFrame(nsStyleContext
* aContext
);
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
;
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
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
,
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
)) {
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
) {
606 if (aFrame
->IsFrameOfType(nsIFrame::eReplacedContainsBlock
)) {
607 if (type
== nsGkAtoms::textInputFrame
) {
608 // It always has an anonymous scroll frame that handles any overflow.
615 if ((aFrame
->GetStateBits() & NS_FRAME_SVG_LAYOUT
)) {
619 // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW
620 // set, then we want to clip our overflow.
622 (aFrame
->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW
) != 0 &&
623 aFrame
->PresContext()->IsPaginated() &&
624 aFrame
->GetType() == nsGkAtoms::blockFrame
;
627 virtual nsILineIterator
* GetLineIterator() MOZ_OVERRIDE
;
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
,
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
;
652 virtual void GetBoxName(nsAutoString
& aName
) MOZ_OVERRIDE
;
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);
661 void BoxReflow(nsBoxLayoutState
& aState
,
662 nsPresContext
* aPresContext
,
663 nsHTMLReflowMetrics
& aDesiredSize
,
664 nsRenderingContext
* aRenderingContext
,
669 bool aMoveFrame
= true);
671 NS_IMETHODIMP
RefreshSizeCache(nsBoxLayoutState
& aState
);
673 #ifdef DEBUG_FRAME_DUMP
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
);
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();
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
767 DR_cookie(nsPresContext
* aPresContext
,
769 const nsHTMLReflowState
& aReflowState
,
770 nsHTMLReflowMetrics
& aMetrics
,
771 nsReflowStatus
& aStatus
);
775 nsPresContext
* mPresContext
;
777 const nsHTMLReflowState
& mReflowState
;
778 nsHTMLReflowMetrics
& mMetrics
;
779 nsReflowStatus
& mStatus
;
783 struct DR_layout_cookie
{
784 explicit DR_layout_cookie(nsIFrame
* aFrame
);
791 struct DR_intrinsic_width_cookie
{
792 DR_intrinsic_width_cookie(nsIFrame
* aFrame
, const char* aType
,
794 ~DR_intrinsic_width_cookie();
802 struct DR_intrinsic_size_cookie
{
803 DR_intrinsic_size_cookie(nsIFrame
* aFrame
, const char* aType
,
805 ~DR_intrinsic_size_cookie();
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();
821 nsHTMLReflowState
* mState
;
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();
834 nsCSSOffsetState
* mState
;
838 struct DR_init_type_cookie
{
839 DR_init_type_cookie(nsIFrame
* aFrame
, nsHTMLReflowState
* aState
);
840 ~DR_init_type_cookie();
843 nsHTMLReflowState
* mState
;
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() \
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, \
865 DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \
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)
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, \
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
890 // End Display Reflow Debugging
892 // similar to NS_ENSURE_TRUE but with no return value
893 #define ENSURE_TRUE(x) \
896 NS_WARNING("ENSURE_TRUE(" #x ") failed"); \
900 #endif /* nsFrame_h___ */