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