1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/generic/nsFrame.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,873 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* base class of all rendering objects */ 1.10 + 1.11 +#ifndef nsFrame_h___ 1.12 +#define nsFrame_h___ 1.13 + 1.14 +#include "mozilla/Attributes.h" 1.15 +#include "mozilla/EventForwards.h" 1.16 +#include "mozilla/Likely.h" 1.17 +#include "nsBox.h" 1.18 +#include "prlog.h" 1.19 + 1.20 +#include "nsIPresShell.h" 1.21 +#include "nsHTMLReflowState.h" 1.22 +#include "nsHTMLParts.h" 1.23 +#include "nsISelectionDisplay.h" 1.24 + 1.25 +/** 1.26 + * nsFrame logging constants. We redefine the nspr 1.27 + * PRLogModuleInfo.level field to be a bitfield. Each bit controls a 1.28 + * specific type of logging. Each logging operation has associated 1.29 + * inline methods defined below. 1.30 + */ 1.31 +#define NS_FRAME_TRACE_CALLS 0x1 1.32 +#define NS_FRAME_TRACE_PUSH_PULL 0x2 1.33 +#define NS_FRAME_TRACE_CHILD_REFLOW 0x4 1.34 +#define NS_FRAME_TRACE_NEW_FRAMES 0x8 1.35 + 1.36 +#define NS_FRAME_LOG_TEST(_lm,_bit) (int((_lm)->level) & (_bit)) 1.37 + 1.38 +#ifdef DEBUG 1.39 +#define NS_FRAME_LOG(_bit,_args) \ 1.40 + PR_BEGIN_MACRO \ 1.41 + if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \ 1.42 + PR_LogPrint _args; \ 1.43 + } \ 1.44 + PR_END_MACRO 1.45 +#else 1.46 +#define NS_FRAME_LOG(_bit,_args) 1.47 +#endif 1.48 + 1.49 +// XXX Need to rework this so that logging is free when it's off 1.50 +#ifdef DEBUG 1.51 +#define NS_FRAME_TRACE_IN(_method) Trace(_method, true) 1.52 + 1.53 +#define NS_FRAME_TRACE_OUT(_method) Trace(_method, false) 1.54 + 1.55 +// XXX remove me 1.56 +#define NS_FRAME_TRACE_MSG(_bit,_args) \ 1.57 + PR_BEGIN_MACRO \ 1.58 + if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \ 1.59 + TraceMsg _args; \ 1.60 + } \ 1.61 + PR_END_MACRO 1.62 + 1.63 +#define NS_FRAME_TRACE(_bit,_args) \ 1.64 + PR_BEGIN_MACRO \ 1.65 + if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \ 1.66 + TraceMsg _args; \ 1.67 + } \ 1.68 + PR_END_MACRO 1.69 + 1.70 +#define NS_FRAME_TRACE_REFLOW_IN(_method) Trace(_method, true) 1.71 + 1.72 +#define NS_FRAME_TRACE_REFLOW_OUT(_method, _status) \ 1.73 + Trace(_method, false, _status) 1.74 + 1.75 +#else 1.76 +#define NS_FRAME_TRACE(_bits,_args) 1.77 +#define NS_FRAME_TRACE_IN(_method) 1.78 +#define NS_FRAME_TRACE_OUT(_method) 1.79 +#define NS_FRAME_TRACE_MSG(_bits,_args) 1.80 +#define NS_FRAME_TRACE_REFLOW_IN(_method) 1.81 +#define NS_FRAME_TRACE_REFLOW_OUT(_method, _status) 1.82 +#endif 1.83 + 1.84 +// Frame allocation boilerplate macros. Every subclass of nsFrame 1.85 +// must define its own operator new and GetAllocatedSize. If they do 1.86 +// not, the per-frame recycler lists in nsPresArena will not work 1.87 +// correctly, with potentially catastrophic consequences (not enough 1.88 +// memory is allocated for a frame object). 1.89 + 1.90 +#define NS_DECL_FRAMEARENA_HELPERS \ 1.91 + void* operator new(size_t, nsIPresShell*) MOZ_MUST_OVERRIDE; \ 1.92 + virtual nsQueryFrame::FrameIID GetFrameId() MOZ_MUST_OVERRIDE; 1.93 + 1.94 +#define NS_IMPL_FRAMEARENA_HELPERS(class) \ 1.95 + void* class::operator new(size_t sz, nsIPresShell* aShell) \ 1.96 + { return aShell->AllocateFrame(nsQueryFrame::class##_id, sz); } \ 1.97 + nsQueryFrame::FrameIID class::GetFrameId() \ 1.98 + { return nsQueryFrame::class##_id; } 1.99 + 1.100 +//---------------------------------------------------------------------- 1.101 + 1.102 +struct nsBoxLayoutMetrics; 1.103 +class nsDisplayBackgroundImage; 1.104 +struct nsRect; 1.105 + 1.106 +/** 1.107 + * Implementation of a simple frame that's not splittable and has no 1.108 + * child frames. 1.109 + * 1.110 + * Sets the NS_FRAME_SYNCHRONIZE_FRAME_AND_VIEW bit, so the default 1.111 + * behavior is to keep the frame and view position and size in sync. 1.112 + */ 1.113 +class nsFrame : public nsBox 1.114 +{ 1.115 +public: 1.116 + /** 1.117 + * Create a new "empty" frame that maps a given piece of content into a 1.118 + * 0,0 area. 1.119 + */ 1.120 + friend nsIFrame* NS_NewEmptyFrame(nsIPresShell* aShell, 1.121 + nsStyleContext* aContext); 1.122 + 1.123 +private: 1.124 + // Left undefined; nsFrame objects are never allocated from the heap. 1.125 + void* operator new(size_t sz) CPP_THROW_NEW; 1.126 + 1.127 +protected: 1.128 + // Overridden to prevent the global delete from being called, since 1.129 + // the memory came out of an arena instead of the heap. 1.130 + // 1.131 + // Ideally this would be private and undefined, like the normal 1.132 + // operator new. Unfortunately, the C++ standard requires an 1.133 + // overridden operator delete to be accessible to any subclass that 1.134 + // defines a virtual destructor, so we can only make it protected; 1.135 + // worse, some C++ compilers will synthesize calls to this function 1.136 + // from the "deleting destructors" that they emit in case of 1.137 + // delete-expressions, so it can't even be undefined. 1.138 + void operator delete(void* aPtr, size_t sz); 1.139 + 1.140 +public: 1.141 + 1.142 + // nsQueryFrame 1.143 + NS_DECL_QUERYFRAME 1.144 + NS_DECL_FRAMEARENA_HELPERS 1.145 + 1.146 + // nsIFrame 1.147 + virtual void Init(nsIContent* aContent, 1.148 + nsIFrame* aParent, 1.149 + nsIFrame* asPrevInFlow) MOZ_OVERRIDE; 1.150 + virtual nsresult SetInitialChildList(ChildListID aListID, 1.151 + nsFrameList& aChildList) MOZ_OVERRIDE; 1.152 + virtual nsresult AppendFrames(ChildListID aListID, 1.153 + nsFrameList& aFrameList) MOZ_OVERRIDE; 1.154 + virtual nsresult InsertFrames(ChildListID aListID, 1.155 + nsIFrame* aPrevFrame, 1.156 + nsFrameList& aFrameList) MOZ_OVERRIDE; 1.157 + virtual nsresult RemoveFrame(ChildListID aListID, 1.158 + nsIFrame* aOldFrame) MOZ_OVERRIDE; 1.159 + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; 1.160 + virtual nsStyleContext* GetAdditionalStyleContext(int32_t aIndex) const MOZ_OVERRIDE; 1.161 + virtual void SetAdditionalStyleContext(int32_t aIndex, 1.162 + nsStyleContext* aStyleContext) MOZ_OVERRIDE; 1.163 + virtual void SetParent(nsIFrame* aParent) MOZ_OVERRIDE; 1.164 + virtual nscoord GetBaseline() const MOZ_OVERRIDE; 1.165 + virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE; 1.166 + virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE; 1.167 + 1.168 + virtual nsresult HandleEvent(nsPresContext* aPresContext, 1.169 + mozilla::WidgetGUIEvent* aEvent, 1.170 + nsEventStatus* aEventStatus) MOZ_OVERRIDE; 1.171 + virtual nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent, 1.172 + nsIContent** aContent) MOZ_OVERRIDE; 1.173 + virtual nsresult GetCursor(const nsPoint& aPoint, 1.174 + nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; 1.175 + 1.176 + virtual nsresult GetPointFromOffset(int32_t inOffset, 1.177 + nsPoint* outPoint) MOZ_OVERRIDE; 1.178 + 1.179 + virtual nsresult GetChildFrameContainingOffset(int32_t inContentOffset, 1.180 + bool inHint, 1.181 + int32_t* outFrameContentOffset, 1.182 + nsIFrame** outChildFrame) MOZ_OVERRIDE; 1.183 + 1.184 + static nsresult GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext, 1.185 + nsPeekOffsetStruct *aPos, 1.186 + nsIFrame *aBlockFrame, 1.187 + int32_t aLineStart, 1.188 + int8_t aOutSideLimit 1.189 + ); 1.190 + 1.191 + virtual nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) MOZ_OVERRIDE; 1.192 + virtual nsresult AttributeChanged(int32_t aNameSpaceID, 1.193 + nsIAtom* aAttribute, 1.194 + int32_t aModType) MOZ_OVERRIDE; 1.195 + virtual nsSplittableType GetSplittableType() const MOZ_OVERRIDE; 1.196 + virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE; 1.197 + virtual void SetPrevContinuation(nsIFrame*) MOZ_OVERRIDE; 1.198 + virtual nsIFrame* GetNextContinuation() const MOZ_OVERRIDE; 1.199 + virtual void SetNextContinuation(nsIFrame*) MOZ_OVERRIDE; 1.200 + virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE; 1.201 + virtual void SetPrevInFlow(nsIFrame*) MOZ_OVERRIDE; 1.202 + virtual nsIFrame* GetNextInFlowVirtual() const MOZ_OVERRIDE; 1.203 + virtual void SetNextInFlow(nsIFrame*) MOZ_OVERRIDE; 1.204 + virtual nsIAtom* GetType() const MOZ_OVERRIDE; 1.205 + 1.206 + virtual nsresult IsSelectable(bool* aIsSelectable, uint8_t* aSelectStyle) const MOZ_OVERRIDE; 1.207 + 1.208 + virtual nsresult GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon) MOZ_OVERRIDE; 1.209 + 1.210 + virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE; 1.211 + virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset, 1.212 + bool aRespectClusters = true) MOZ_OVERRIDE; 1.213 + virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect, 1.214 + int32_t* aOffset, PeekWordState *aState) MOZ_OVERRIDE; 1.215 + /** 1.216 + * Check whether we should break at a boundary between punctuation and 1.217 + * non-punctuation. Only call it at a punctuation boundary 1.218 + * (i.e. exactly one of the previous and next characters are punctuation). 1.219 + * @param aForward true if we're moving forward in content order 1.220 + * @param aPunctAfter true if the next character is punctuation 1.221 + * @param aWhitespaceAfter true if the next character is whitespace 1.222 + */ 1.223 + bool BreakWordBetweenPunctuation(const PeekWordState* aState, 1.224 + bool aForward, 1.225 + bool aPunctAfter, bool aWhitespaceAfter, 1.226 + bool aIsKeyboardSelect); 1.227 + 1.228 + virtual nsresult CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) MOZ_OVERRIDE; 1.229 + 1.230 + virtual nsresult GetOffsets(int32_t &aStart, int32_t &aEnd) const MOZ_OVERRIDE; 1.231 + virtual void ChildIsDirty(nsIFrame* aChild) MOZ_OVERRIDE; 1.232 + 1.233 +#ifdef ACCESSIBILITY 1.234 + virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; 1.235 +#endif 1.236 + 1.237 + virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE { 1.238 + return DoGetParentStyleContextFrame(); 1.239 + } 1.240 + 1.241 + /** 1.242 + * Do the work for getting the parent style context frame so that 1.243 + * other frame's |GetParentStyleContextFrame| methods can call this 1.244 + * method on *another* frame. (This function handles out-of-flow 1.245 + * frames by using the frame manager's placeholder map and it also 1.246 + * handles block-within-inline and generated content wrappers.) 1.247 + */ 1.248 + nsIFrame* DoGetParentStyleContextFrame() const; 1.249 + 1.250 + virtual bool IsEmpty() MOZ_OVERRIDE; 1.251 + virtual bool IsSelfEmpty() MOZ_OVERRIDE; 1.252 + 1.253 + virtual void MarkIntrinsicWidthsDirty() MOZ_OVERRIDE; 1.254 + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; 1.255 + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; 1.256 + virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext, 1.257 + InlineMinWidthData *aData) MOZ_OVERRIDE; 1.258 + virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext, 1.259 + InlinePrefWidthData *aData) MOZ_OVERRIDE; 1.260 + virtual IntrinsicWidthOffsetData 1.261 + IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; 1.262 + virtual mozilla::IntrinsicSize GetIntrinsicSize() MOZ_OVERRIDE; 1.263 + virtual nsSize GetIntrinsicRatio() MOZ_OVERRIDE; 1.264 + 1.265 + virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext, 1.266 + nsSize aCBSize, nscoord aAvailableWidth, 1.267 + nsSize aMargin, nsSize aBorder, nsSize aPadding, 1.268 + uint32_t aFlags) MOZ_OVERRIDE; 1.269 + 1.270 + // Compute tight bounds assuming this frame honours its border, background 1.271 + // and outline, its children's tight bounds, and nothing else. 1.272 + nsRect ComputeSimpleTightBounds(gfxContext* aContext) const; 1.273 + 1.274 + /** 1.275 + * A helper, used by |nsFrame::ComputeSize| (for frames that need to 1.276 + * override only this part of ComputeSize), that computes the size 1.277 + * that should be returned when 'width', 'height', and 1.278 + * min/max-width/height are all 'auto' or equivalent. 1.279 + * 1.280 + * In general, frames that can accept any computed width/height should 1.281 + * override only ComputeAutoSize, and frames that cannot do so need to 1.282 + * override ComputeSize to enforce their width/height invariants. 1.283 + * 1.284 + * Implementations may optimize by returning a garbage width if 1.285 + * StylePosition()->mWidth.GetUnit() != eStyleUnit_Auto, and 1.286 + * likewise for height, since in such cases the result is guaranteed 1.287 + * to be unused. 1.288 + */ 1.289 + virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext, 1.290 + nsSize aCBSize, nscoord aAvailableWidth, 1.291 + nsSize aMargin, nsSize aBorder, 1.292 + nsSize aPadding, bool aShrinkWrap); 1.293 + 1.294 + /** 1.295 + * Utility function for ComputeAutoSize implementations. Return 1.296 + * max(GetMinWidth(), min(aWidthInCB, GetPrefWidth())) 1.297 + */ 1.298 + nscoord ShrinkWidthToFit(nsRenderingContext *aRenderingContext, 1.299 + nscoord aWidthInCB); 1.300 + 1.301 + virtual nsresult WillReflow(nsPresContext* aPresContext) MOZ_OVERRIDE; 1.302 + /** 1.303 + * Calculates the size of this frame after reflowing (calling Reflow on, and 1.304 + * updating the size and position of) its children, as necessary. The 1.305 + * calculated size is returned to the caller via the nsHTMLReflowMetrics 1.306 + * outparam. (The caller is responsible for setting the actual size and 1.307 + * position of this frame.) 1.308 + * 1.309 + * A frame's children must _all_ be reflowed if the frame is dirty (the 1.310 + * NS_FRAME_IS_DIRTY bit is set on it). Otherwise, individual children 1.311 + * must be reflowed if they are dirty or have the NS_FRAME_HAS_DIRTY_CHILDREN 1.312 + * bit set on them. Otherwise, whether children need to be reflowed depends 1.313 + * on the frame's type (it's up to individual Reflow methods), and on what 1.314 + * has changed. For example, a change in the width of the frame may require 1.315 + * all of its children to be reflowed (even those without dirty bits set on 1.316 + * them), whereas a change in its height might not. 1.317 + * (nsHTMLReflowState::ShouldReflowAllKids may be helpful in deciding whether 1.318 + * to reflow all the children, but for some frame types it might result in 1.319 + * over-reflow.) 1.320 + * 1.321 + * Note: if it's only the overflow rect(s) of a frame that need to be 1.322 + * updated, then UpdateOverflow should be called instead of Reflow. 1.323 + */ 1.324 + virtual nsresult Reflow(nsPresContext* aPresContext, 1.325 + nsHTMLReflowMetrics& aDesiredSize, 1.326 + const nsHTMLReflowState& aReflowState, 1.327 + nsReflowStatus& aStatus) MOZ_OVERRIDE; 1.328 + virtual nsresult DidReflow(nsPresContext* aPresContext, 1.329 + const nsHTMLReflowState* aReflowState, 1.330 + nsDidReflowStatus aStatus) MOZ_OVERRIDE; 1.331 + 1.332 + /** 1.333 + * NOTE: aStatus is assumed to be already-initialized. The reflow statuses of 1.334 + * any reflowed absolute children will be merged into aStatus; aside from 1.335 + * that, this method won't modify aStatus. 1.336 + */ 1.337 + void ReflowAbsoluteFrames(nsPresContext* aPresContext, 1.338 + nsHTMLReflowMetrics& aDesiredSize, 1.339 + const nsHTMLReflowState& aReflowState, 1.340 + nsReflowStatus& aStatus, 1.341 + bool aConstrainHeight = true); 1.342 + void FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext, 1.343 + nsHTMLReflowMetrics& aDesiredSize, 1.344 + const nsHTMLReflowState& aReflowState, 1.345 + nsReflowStatus& aStatus, 1.346 + bool aConstrainHeight = true); 1.347 + virtual bool CanContinueTextRun() const MOZ_OVERRIDE; 1.348 + 1.349 + virtual bool UpdateOverflow() MOZ_OVERRIDE; 1.350 + 1.351 + // Selection Methods 1.352 + 1.353 + NS_IMETHOD HandlePress(nsPresContext* aPresContext, 1.354 + mozilla::WidgetGUIEvent* aEvent, 1.355 + nsEventStatus* aEventStatus); 1.356 + 1.357 + NS_IMETHOD HandleMultiplePress(nsPresContext* aPresContext, 1.358 + mozilla::WidgetGUIEvent* aEvent, 1.359 + nsEventStatus* aEventStatus, 1.360 + bool aControlHeld); 1.361 + 1.362 + NS_IMETHOD HandleDrag(nsPresContext* aPresContext, 1.363 + mozilla::WidgetGUIEvent* aEvent, 1.364 + nsEventStatus* aEventStatus); 1.365 + 1.366 + NS_IMETHOD HandleRelease(nsPresContext* aPresContext, 1.367 + mozilla::WidgetGUIEvent* aEvent, 1.368 + nsEventStatus* aEventStatus); 1.369 + 1.370 + enum { SELECT_ACCUMULATE = 0x01 }; 1.371 + 1.372 + nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack, 1.373 + nsSelectionAmount aAmountForward, 1.374 + int32_t aStartPos, 1.375 + nsPresContext* aPresContext, 1.376 + bool aJumpLines, 1.377 + uint32_t aSelectFlags); 1.378 + 1.379 + nsresult SelectByTypeAtPoint(nsPresContext* aPresContext, 1.380 + const nsPoint& aPoint, 1.381 + nsSelectionAmount aBeginAmountType, 1.382 + nsSelectionAmount aEndAmountType, 1.383 + uint32_t aSelectFlags); 1.384 + 1.385 + // Helper for GetContentAndOffsetsFromPoint; calculation of content offsets 1.386 + // in this function assumes there is no child frame that can be targeted. 1.387 + virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint); 1.388 + 1.389 + // Box layout methods 1.390 + virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; 1.391 + virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; 1.392 + virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; 1.393 + virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; 1.394 + virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; 1.395 + 1.396 + // We compute and store the HTML content's overflow area. So don't 1.397 + // try to compute it in the box code. 1.398 + virtual bool ComputesOwnOverflowArea() MOZ_OVERRIDE { return true; } 1.399 + 1.400 + //-------------------------------------------------- 1.401 + // Additional methods 1.402 + 1.403 + // Helper function that tests if the frame tree is too deep; if it is 1.404 + // it marks the frame as "unflowable", zeroes out the metrics, sets 1.405 + // the reflow status, and returns true. Otherwise, the frame is 1.406 + // unmarked "unflowable" and the metrics and reflow status are not 1.407 + // touched and false is returned. 1.408 + bool IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState, 1.409 + nsHTMLReflowMetrics& aMetrics, 1.410 + nsReflowStatus& aStatus); 1.411 + 1.412 + // Incorporate the child overflow areas into aOverflowAreas. 1.413 + // If the child does not have a overflow, use the child area. 1.414 + void ConsiderChildOverflow(nsOverflowAreas& aOverflowAreas, 1.415 + nsIFrame* aChildFrame); 1.416 + 1.417 + /** 1.418 + * @return true if we should avoid a page/column break in this frame. 1.419 + */ 1.420 + bool ShouldAvoidBreakInside(const nsHTMLReflowState& aReflowState) const { 1.421 + return !aReflowState.mFlags.mIsTopOfPage && 1.422 + NS_STYLE_PAGE_BREAK_AVOID == StyleDisplay()->mBreakInside && 1.423 + !GetPrevInFlow(); 1.424 + } 1.425 + 1.426 +#ifdef DEBUG 1.427 + /** 1.428 + * Tracing method that writes a method enter/exit routine to the 1.429 + * nspr log using the nsIFrame log module. The tracing is only 1.430 + * done when the NS_FRAME_TRACE_CALLS bit is set in the log module's 1.431 + * level field. 1.432 + */ 1.433 + void Trace(const char* aMethod, bool aEnter); 1.434 + void Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus); 1.435 + void TraceMsg(const char* fmt, ...); 1.436 + 1.437 + // Helper function that verifies that each frame in the list has the 1.438 + // NS_FRAME_IS_DIRTY bit set 1.439 + static void VerifyDirtyBitSet(const nsFrameList& aFrameList); 1.440 + 1.441 + static void XMLQuote(nsString& aString); 1.442 + 1.443 + /** 1.444 + * Dump out the "base classes" regression data. This should dump 1.445 + * out the interior data, not the "frame" XML container. And it 1.446 + * should call the base classes same named method before doing 1.447 + * anything specific in a derived class. This means that derived 1.448 + * classes need not override DumpRegressionData unless they need 1.449 + * some custom behavior that requires changing how the outer "frame" 1.450 + * XML container is dumped. 1.451 + */ 1.452 + virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent); 1.453 + 1.454 + // Display Reflow Debugging 1.455 + static void* DisplayReflowEnter(nsPresContext* aPresContext, 1.456 + nsIFrame* aFrame, 1.457 + const nsHTMLReflowState& aReflowState); 1.458 + static void* DisplayLayoutEnter(nsIFrame* aFrame); 1.459 + static void* DisplayIntrinsicWidthEnter(nsIFrame* aFrame, 1.460 + const char* aType); 1.461 + static void* DisplayIntrinsicSizeEnter(nsIFrame* aFrame, 1.462 + const char* aType); 1.463 + static void DisplayReflowExit(nsPresContext* aPresContext, 1.464 + nsIFrame* aFrame, 1.465 + nsHTMLReflowMetrics& aMetrics, 1.466 + uint32_t aStatus, 1.467 + void* aFrameTreeNode); 1.468 + static void DisplayLayoutExit(nsIFrame* aFrame, 1.469 + void* aFrameTreeNode); 1.470 + static void DisplayIntrinsicWidthExit(nsIFrame* aFrame, 1.471 + const char* aType, 1.472 + nscoord aResult, 1.473 + void* aFrameTreeNode); 1.474 + static void DisplayIntrinsicSizeExit(nsIFrame* aFrame, 1.475 + const char* aType, 1.476 + nsSize aResult, 1.477 + void* aFrameTreeNode); 1.478 + 1.479 + static void DisplayReflowStartup(); 1.480 + static void DisplayReflowShutdown(); 1.481 +#endif 1.482 + 1.483 + /** 1.484 + * Adds display items for standard CSS background if necessary. 1.485 + * Does not check IsVisibleForPainting. 1.486 + * @param aForceBackground draw the background even if the frame 1.487 + * background style appears to have no background --- this is useful 1.488 + * for frames that might receive a propagated background via 1.489 + * nsCSSRendering::FindBackground 1.490 + * @return whether a themed background item was created. 1.491 + */ 1.492 + bool DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder, 1.493 + const nsDisplayListSet& aLists, 1.494 + bool aForceBackground); 1.495 + /** 1.496 + * Adds display items for standard CSS borders, background and outline for 1.497 + * for this frame, as necessary. Checks IsVisibleForPainting and won't 1.498 + * display anything if the frame is not visible. 1.499 + * @param aForceBackground draw the background even if the frame 1.500 + * background style appears to have no background --- this is useful 1.501 + * for frames that might receive a propagated background via 1.502 + * nsCSSRendering::FindBackground 1.503 + */ 1.504 + void DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder, 1.505 + const nsDisplayListSet& aLists, 1.506 + bool aForceBackground = false); 1.507 + /** 1.508 + * Add a display item for the CSS outline. Does not check visibility. 1.509 + */ 1.510 + void DisplayOutlineUnconditional(nsDisplayListBuilder* aBuilder, 1.511 + const nsDisplayListSet& aLists); 1.512 + /** 1.513 + * Add a display item for the CSS outline, after calling 1.514 + * IsVisibleForPainting to confirm we are visible. 1.515 + */ 1.516 + void DisplayOutline(nsDisplayListBuilder* aBuilder, 1.517 + const nsDisplayListSet& aLists); 1.518 + 1.519 + /** 1.520 + * Adjust the given parent frame to the right style context parent frame for 1.521 + * the child, given the pseudo-type of the prospective child. This handles 1.522 + * things like walking out of table pseudos and so forth. 1.523 + * 1.524 + * @param aProspectiveParent what GetParent() on the child returns. 1.525 + * Must not be null. 1.526 + * @param aChildPseudo the child's pseudo type, if any. 1.527 + */ 1.528 + static nsIFrame* 1.529 + CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsIAtom* aChildPseudo); 1.530 + 1.531 +protected: 1.532 + // Protected constructor and destructor 1.533 + nsFrame(nsStyleContext* aContext); 1.534 + virtual ~nsFrame(); 1.535 + 1.536 + /** 1.537 + * To be called by |BuildDisplayLists| of this class or derived classes to add 1.538 + * a translucent overlay if this frame's content is selected. 1.539 + * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying 1.540 + * which kind of content this is for 1.541 + */ 1.542 + void DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder, 1.543 + nsDisplayList* aList, uint16_t aContentType = nsISelectionDisplay::DISPLAY_FRAMES); 1.544 + 1.545 + int16_t DisplaySelection(nsPresContext* aPresContext, bool isOkToTurnOn = false); 1.546 + 1.547 + // Style post processing hook 1.548 + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; 1.549 + 1.550 +public: 1.551 + //given a frame five me the first/last leaf available 1.552 + //XXX Robert O'Callahan wants to move these elsewhere 1.553 + static void GetLastLeaf(nsPresContext* aPresContext, nsIFrame **aFrame); 1.554 + static void GetFirstLeaf(nsPresContext* aPresContext, nsIFrame **aFrame); 1.555 + 1.556 + // Return the line number of the aFrame, and (optionally) the containing block 1.557 + // frame. 1.558 + // If aScrollLock is true, don't break outside scrollframes when looking for a 1.559 + // containing block frame. 1.560 + static int32_t GetLineNumber(nsIFrame *aFrame, 1.561 + bool aLockScroll, 1.562 + nsIFrame** aContainingBlock = nullptr); 1.563 + 1.564 + /** 1.565 + * Returns true if aFrame should apply overflow clipping. 1.566 + */ 1.567 + static bool ShouldApplyOverflowClipping(const nsIFrame* aFrame, 1.568 + const nsStyleDisplay* aDisp) 1.569 + { 1.570 + // clip overflow:-moz-hidden-unscrollable ... 1.571 + if (MOZ_UNLIKELY(aDisp->mOverflowX == NS_STYLE_OVERFLOW_CLIP)) { 1.572 + return true; 1.573 + } 1.574 + 1.575 + // and overflow:hidden that we should interpret as -moz-hidden-unscrollable 1.576 + if (aDisp->mOverflowX == NS_STYLE_OVERFLOW_HIDDEN && 1.577 + aDisp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) { 1.578 + // REVIEW: these are the frame types that set up clipping. 1.579 + nsIAtom* type = aFrame->GetType(); 1.580 + if (type == nsGkAtoms::tableFrame || 1.581 + type == nsGkAtoms::tableCellFrame || 1.582 + type == nsGkAtoms::bcTableCellFrame || 1.583 + type == nsGkAtoms::svgOuterSVGFrame || 1.584 + type == nsGkAtoms::svgInnerSVGFrame || 1.585 + type == nsGkAtoms::svgForeignObjectFrame) { 1.586 + return true; 1.587 + } 1.588 + if (aFrame->IsFrameOfType(nsIFrame::eReplacedContainsBlock)) { 1.589 + if (type == nsGkAtoms::textInputFrame) { 1.590 + // It always has an anonymous scroll frame that handles any overflow. 1.591 + return false; 1.592 + } 1.593 + return true; 1.594 + } 1.595 + } 1.596 + 1.597 + if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) { 1.598 + return false; 1.599 + } 1.600 + 1.601 + // If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW 1.602 + // set, then we want to clip our overflow. 1.603 + return 1.604 + (aFrame->GetStateBits() & NS_BLOCK_CLIP_PAGINATED_OVERFLOW) != 0 && 1.605 + aFrame->PresContext()->IsPaginated() && 1.606 + aFrame->GetType() == nsGkAtoms::blockFrame; 1.607 + } 1.608 + 1.609 +protected: 1.610 + 1.611 + // Test if we are selecting a table object: 1.612 + // Most table/cell selection requires that Ctrl (Cmd on Mac) key is down 1.613 + // during a mouse click or drag. Exception is using Shift+click when 1.614 + // already in "table/cell selection mode" to extend a block selection 1.615 + // Get the parent content node and offset of the frame 1.616 + // of the enclosing cell or table (if not inside a cell) 1.617 + // aTarget tells us what table element to select (currently only cell and table supported) 1.618 + // (enums for this are defined in nsIFrame.h) 1.619 + NS_IMETHOD GetDataForTableSelection(const nsFrameSelection* aFrameSelection, 1.620 + nsIPresShell* aPresShell, 1.621 + mozilla::WidgetMouseEvent* aMouseEvent, 1.622 + nsIContent** aParentContent, 1.623 + int32_t* aContentOffset, 1.624 + int32_t* aTarget); 1.625 + 1.626 + // Fills aCursor with the appropriate information from ui 1.627 + static void FillCursorInformationFromStyle(const nsStyleUserInterface* ui, 1.628 + nsIFrame::Cursor& aCursor); 1.629 + NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; 1.630 + 1.631 +#ifdef DEBUG_LAYOUT 1.632 + virtual void GetBoxName(nsAutoString& aName) MOZ_OVERRIDE; 1.633 +#endif 1.634 + 1.635 + void InitBoxMetrics(bool aClear); 1.636 + nsBoxLayoutMetrics* BoxMetrics() const; 1.637 + 1.638 + // Fire DOM event. If no aContent argument use frame's mContent. 1.639 + void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr); 1.640 + 1.641 +private: 1.642 + nsresult BoxReflow(nsBoxLayoutState& aState, 1.643 + nsPresContext* aPresContext, 1.644 + nsHTMLReflowMetrics& aDesiredSize, 1.645 + nsRenderingContext* aRenderingContext, 1.646 + nscoord aX, 1.647 + nscoord aY, 1.648 + nscoord aWidth, 1.649 + nscoord aHeight, 1.650 + bool aMoveFrame = true); 1.651 + 1.652 + NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState); 1.653 + 1.654 + virtual nsILineIterator* GetLineIterator() MOZ_OVERRIDE; 1.655 + 1.656 +#ifdef DEBUG_FRAME_DUMP 1.657 +public: 1.658 + /** 1.659 + * Get a printable from of the name of the frame type. 1.660 + * XXX This should be eliminated and we use GetType() instead... 1.661 + */ 1.662 + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; 1.663 + nsresult MakeFrameName(const nsAString& aKind, nsAString& aResult) const; 1.664 + // Helper function to return the index in parent of the frame's content 1.665 + // object. Returns -1 on error or if the frame doesn't have a content object 1.666 + static int32_t ContentIndexInContainer(const nsIFrame* aFrame); 1.667 +#endif 1.668 + 1.669 +#ifdef DEBUG 1.670 +public: 1.671 + /** 1.672 + * Return the state bits that are relevant to regression tests (that 1.673 + * is, those bits which indicate a real difference when they differ 1.674 + */ 1.675 + virtual nsFrameState GetDebugStateBits() const MOZ_OVERRIDE; 1.676 + /** 1.677 + * Called to dump out regression data that describes the layout 1.678 + * of the frame and its children, and so on. The format of the 1.679 + * data is dictated to be XML (using a specific DTD); the 1.680 + * specific kind of data dumped is up to the frame itself, with 1.681 + * the caveat that some base types are defined. 1.682 + * For more information, see XXX. 1.683 + */ 1.684 + virtual nsresult DumpRegressionData(nsPresContext* aPresContext, 1.685 + FILE* out, int32_t aIndent) MOZ_OVERRIDE; 1.686 + 1.687 + /** 1.688 + * See if style tree verification is enabled. To enable style tree 1.689 + * verification add "styleverifytree:1" to your NSPR_LOG_MODULES 1.690 + * environment variable (any non-zero debug level will work). Or, 1.691 + * call SetVerifyStyleTreeEnable with true. 1.692 + */ 1.693 + static bool GetVerifyStyleTreeEnable(); 1.694 + 1.695 + /** 1.696 + * Set the verify-style-tree enable flag. 1.697 + */ 1.698 + static void SetVerifyStyleTreeEnable(bool aEnabled); 1.699 + 1.700 + /** 1.701 + * The frame class and related classes share an nspr log module 1.702 + * for logging frame activity. 1.703 + * 1.704 + * Note: the log module is created during library initialization which 1.705 + * means that you cannot perform logging before then. 1.706 + */ 1.707 + static PRLogModuleInfo* GetLogModuleInfo(); 1.708 + 1.709 + // Show frame borders when rendering 1.710 + static void ShowFrameBorders(bool aEnable); 1.711 + static bool GetShowFrameBorders(); 1.712 + 1.713 + // Show frame border of event target 1.714 + static void ShowEventTargetFrameBorder(bool aEnable); 1.715 + static bool GetShowEventTargetFrameBorder(); 1.716 + 1.717 +#endif 1.718 +#ifdef MOZ_DUMP_PAINTING 1.719 +public: 1.720 + 1.721 + static void PrintDisplayItem(nsDisplayListBuilder* aBuilder, 1.722 + nsDisplayItem* aItem, 1.723 + FILE* aFile = stdout, 1.724 + bool aDumpSublist = false, 1.725 + bool aDumpHtml = false); 1.726 + 1.727 + static void PrintDisplayList(nsDisplayListBuilder* aBuilder, 1.728 + const nsDisplayList& aList, 1.729 + FILE* aFile = stdout, 1.730 + bool aDumpHtml = false); 1.731 + static void PrintDisplayListSet(nsDisplayListBuilder* aBuilder, 1.732 + const nsDisplayListSet& aList, 1.733 + FILE* aFile = stdout, 1.734 + bool aDumpHtml = false); 1.735 + 1.736 +#endif 1.737 +}; 1.738 + 1.739 +// Start Display Reflow Debugging 1.740 +#ifdef DEBUG 1.741 + 1.742 + struct DR_cookie { 1.743 + DR_cookie(nsPresContext* aPresContext, 1.744 + nsIFrame* aFrame, 1.745 + const nsHTMLReflowState& aReflowState, 1.746 + nsHTMLReflowMetrics& aMetrics, 1.747 + nsReflowStatus& aStatus); 1.748 + ~DR_cookie(); 1.749 + void Change() const; 1.750 + 1.751 + nsPresContext* mPresContext; 1.752 + nsIFrame* mFrame; 1.753 + const nsHTMLReflowState& mReflowState; 1.754 + nsHTMLReflowMetrics& mMetrics; 1.755 + nsReflowStatus& mStatus; 1.756 + void* mValue; 1.757 + }; 1.758 + 1.759 + struct DR_layout_cookie { 1.760 + DR_layout_cookie(nsIFrame* aFrame); 1.761 + ~DR_layout_cookie(); 1.762 + 1.763 + nsIFrame* mFrame; 1.764 + void* mValue; 1.765 + }; 1.766 + 1.767 + struct DR_intrinsic_width_cookie { 1.768 + DR_intrinsic_width_cookie(nsIFrame* aFrame, const char* aType, 1.769 + nscoord& aResult); 1.770 + ~DR_intrinsic_width_cookie(); 1.771 + 1.772 + nsIFrame* mFrame; 1.773 + const char* mType; 1.774 + nscoord& mResult; 1.775 + void* mValue; 1.776 + }; 1.777 + 1.778 + struct DR_intrinsic_size_cookie { 1.779 + DR_intrinsic_size_cookie(nsIFrame* aFrame, const char* aType, 1.780 + nsSize& aResult); 1.781 + ~DR_intrinsic_size_cookie(); 1.782 + 1.783 + nsIFrame* mFrame; 1.784 + const char* mType; 1.785 + nsSize& mResult; 1.786 + void* mValue; 1.787 + }; 1.788 + 1.789 + struct DR_init_constraints_cookie { 1.790 + DR_init_constraints_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState, 1.791 + nscoord aCBWidth, nscoord aCBHeight, 1.792 + const nsMargin* aBorder, 1.793 + const nsMargin* aPadding); 1.794 + ~DR_init_constraints_cookie(); 1.795 + 1.796 + nsIFrame* mFrame; 1.797 + nsHTMLReflowState* mState; 1.798 + void* mValue; 1.799 + }; 1.800 + 1.801 + struct DR_init_offsets_cookie { 1.802 + DR_init_offsets_cookie(nsIFrame* aFrame, nsCSSOffsetState* aState, 1.803 + nscoord aHorizontalPercentBasis, 1.804 + nscoord aVerticalPercentBasis, 1.805 + const nsMargin* aBorder, 1.806 + const nsMargin* aPadding); 1.807 + ~DR_init_offsets_cookie(); 1.808 + 1.809 + nsIFrame* mFrame; 1.810 + nsCSSOffsetState* mState; 1.811 + void* mValue; 1.812 + }; 1.813 + 1.814 + struct DR_init_type_cookie { 1.815 + DR_init_type_cookie(nsIFrame* aFrame, nsHTMLReflowState* aState); 1.816 + ~DR_init_type_cookie(); 1.817 + 1.818 + nsIFrame* mFrame; 1.819 + nsHTMLReflowState* mState; 1.820 + void* mValue; 1.821 + }; 1.822 + 1.823 +#define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) \ 1.824 + DR_cookie dr_cookie(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status); 1.825 +#define DISPLAY_REFLOW_CHANGE() \ 1.826 + dr_cookie.Change(); 1.827 +#define DISPLAY_LAYOUT(dr_frame) \ 1.828 + DR_layout_cookie dr_cookie(dr_frame); 1.829 +#define DISPLAY_MIN_WIDTH(dr_frame, dr_result) \ 1.830 + DR_intrinsic_width_cookie dr_cookie(dr_frame, "Min", dr_result) 1.831 +#define DISPLAY_PREF_WIDTH(dr_frame, dr_result) \ 1.832 + DR_intrinsic_width_cookie dr_cookie(dr_frame, "Pref", dr_result) 1.833 +#define DISPLAY_PREF_SIZE(dr_frame, dr_result) \ 1.834 + DR_intrinsic_size_cookie dr_cookie(dr_frame, "Pref", dr_result) 1.835 +#define DISPLAY_MIN_SIZE(dr_frame, dr_result) \ 1.836 + DR_intrinsic_size_cookie dr_cookie(dr_frame, "Min", dr_result) 1.837 +#define DISPLAY_MAX_SIZE(dr_frame, dr_result) \ 1.838 + DR_intrinsic_size_cookie dr_cookie(dr_frame, "Max", dr_result) 1.839 +#define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, \ 1.840 + dr_bdr, dr_pad) \ 1.841 + DR_init_constraints_cookie dr_cookie(dr_frame, dr_state, dr_cbw, dr_cbh, \ 1.842 + dr_bdr, dr_pad) 1.843 +#define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) \ 1.844 + DR_init_offsets_cookie dr_cookie(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) 1.845 +#define DISPLAY_INIT_TYPE(dr_frame, dr_result) \ 1.846 + DR_init_type_cookie dr_cookie(dr_frame, dr_result) 1.847 + 1.848 +#else 1.849 + 1.850 +#define DISPLAY_REFLOW(dr_pres_context, dr_frame, dr_rf_state, dr_rf_metrics, dr_rf_status) 1.851 +#define DISPLAY_REFLOW_CHANGE() 1.852 +#define DISPLAY_LAYOUT(dr_frame) PR_BEGIN_MACRO PR_END_MACRO 1.853 +#define DISPLAY_MIN_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO 1.854 +#define DISPLAY_PREF_WIDTH(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO 1.855 +#define DISPLAY_PREF_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO 1.856 +#define DISPLAY_MIN_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO 1.857 +#define DISPLAY_MAX_SIZE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO 1.858 +#define DISPLAY_INIT_CONSTRAINTS(dr_frame, dr_state, dr_cbw, dr_cbh, \ 1.859 + dr_bdr, dr_pad) \ 1.860 + PR_BEGIN_MACRO PR_END_MACRO 1.861 +#define DISPLAY_INIT_OFFSETS(dr_frame, dr_state, dr_hpb, dr_vpb, dr_bdr, dr_pad) \ 1.862 + PR_BEGIN_MACRO PR_END_MACRO 1.863 +#define DISPLAY_INIT_TYPE(dr_frame, dr_result) PR_BEGIN_MACRO PR_END_MACRO 1.864 + 1.865 +#endif 1.866 +// End Display Reflow Debugging 1.867 + 1.868 +// similar to NS_ENSURE_TRUE but with no return value 1.869 +#define ENSURE_TRUE(x) \ 1.870 + PR_BEGIN_MACRO \ 1.871 + if (!(x)) { \ 1.872 + NS_WARNING("ENSURE_TRUE(" #x ") failed"); \ 1.873 + return; \ 1.874 + } \ 1.875 + PR_END_MACRO 1.876 +#endif /* nsFrame_h___ */