Bug 574454 - Cleanup nsNativeThemeWin's GetMinimumWidgetSize a bit. r=roc.
[mozilla-central.git] / layout / generic / nsIFrame.h
blobf1eca31f1094d99557fae0860de99e3b58e64aac
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=78: */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/I
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 /* interface for all rendering objects */
41 #ifndef nsIFrame_h___
42 #define nsIFrame_h___
44 /* nsIFrame is in the process of being deCOMtaminated, i.e., this file is eventually
45 going to be eliminated, and all callers will use nsFrame instead. At the moment
46 we're midway through this process, so you will see inlined functions and member
47 variables in this file. -dwh */
49 #include <stdio.h>
50 #include "nsQueryFrame.h"
51 #include "nsEvent.h"
52 #include "nsStyleStruct.h"
53 #include "nsStyleContext.h"
54 #include "nsIContent.h"
55 #include "nsHTMLReflowMetrics.h"
56 #include "gfxMatrix.h"
57 #include "nsFrameList.h"
58 #include "nsAlgorithm.h"
59 #include "FramePropertyTable.h"
61 /**
62 * New rules of reflow:
63 * 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
64 * (no separate pass over the tree)
65 * 2. it's the parent frame's responsibility to size/position the child's view (not
66 * the child frame's responsibility as it is today) during reflow (and before
67 * sending the DidReflow() notification)
68 * 3. positioning of child frames (and their views) is done on the way down the tree,
69 * and sizing of child frames (and their views) on the way back up
70 * 4. if you move a frame (outside of the reflow process, or after reflowing it),
71 * then you must make sure that its view (or its child frame's views) are re-positioned
72 * as well. It's reasonable to not position the view until after all reflowing the
73 * entire line, for example, but the frame should still be positioned and sized (and
74 * the view sized) during the reflow (i.e., before sending the DidReflow() notification)
75 * 5. the view system handles moving of widgets, i.e., it's not our problem
78 struct nsHTMLReflowState;
79 class nsHTMLReflowCommand;
81 class nsIAtom;
82 class nsPresContext;
83 class nsIPresShell;
84 class nsIRenderingContext;
85 class nsIView;
86 class nsIWidget;
87 class nsIDOMRange;
88 class nsISelectionController;
89 class nsBoxLayoutState;
90 class nsIBoxLayout;
91 class nsILineIterator;
92 #ifdef ACCESSIBILITY
93 class nsAccessible;
94 #endif
95 class nsDisplayListBuilder;
96 class nsDisplayListSet;
97 class nsDisplayList;
98 class gfxSkipChars;
99 class gfxSkipCharsIterator;
100 class gfxContext;
101 class nsLineList_iterator;
103 struct nsPeekOffsetStruct;
104 struct nsPoint;
105 struct nsRect;
106 struct nsSize;
107 struct nsMargin;
108 struct CharacterDataChangeInfo;
110 typedef class nsIFrame nsIBox;
113 * Indication of how the frame can be split. This is used when doing runaround
114 * of floats, and when pulling up child frames from a next-in-flow.
116 * The choices are splittable, not splittable at all, and splittable in
117 * a non-rectangular fashion. This last type only applies to block-level
118 * elements, and indicates whether splitting can be used when doing runaround.
119 * If you can split across page boundaries, but you expect each continuing
120 * frame to be the same width then return frSplittable and not
121 * frSplittableNonRectangular.
123 * @see #GetSplittableType()
125 typedef PRUint32 nsSplittableType;
127 #define NS_FRAME_NOT_SPLITTABLE 0 // Note: not a bit!
128 #define NS_FRAME_SPLITTABLE 0x1
129 #define NS_FRAME_SPLITTABLE_NON_RECTANGULAR 0x3
131 #define NS_FRAME_IS_SPLITTABLE(type)\
132 (0 != ((type) & NS_FRAME_SPLITTABLE))
134 #define NS_FRAME_IS_NOT_SPLITTABLE(type)\
135 (0 == ((type) & NS_FRAME_SPLITTABLE))
137 #define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN
139 //----------------------------------------------------------------------
142 * Frame state bits. Any bits not listed here are reserved for future
143 * extensions, but must be stored by the frames.
145 typedef PRUint64 nsFrameState;
147 #define NS_FRAME_STATE_BIT(n_) (nsFrameState(1) << (n_))
149 #define NS_FRAME_IN_REFLOW NS_FRAME_STATE_BIT(0)
151 // This is only set during painting
152 #define NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO NS_FRAME_STATE_BIT(0)
154 // This bit is set when a frame is created. After it has been reflowed
155 // once (during the DidReflow with a finished state) the bit is
156 // cleared.
157 #define NS_FRAME_FIRST_REFLOW NS_FRAME_STATE_BIT(1)
159 // For a continuation frame, if this bit is set, then this a "fluid"
160 // continuation, i.e., across a line boundary. Otherwise it's a "hard"
161 // continuation, e.g. a bidi continuation.
162 #define NS_FRAME_IS_FLUID_CONTINUATION NS_FRAME_STATE_BIT(2)
164 // This bit is set whenever the frame has one or more associated
165 // container layers.
166 #define NS_FRAME_HAS_CONTAINER_LAYER NS_FRAME_STATE_BIT(3)
168 // If this bit is set, then a reference to the frame is being held
169 // elsewhere. The frame may want to send a notification when it is
170 // destroyed to allow these references to be cleared.
171 #define NS_FRAME_EXTERNAL_REFERENCE NS_FRAME_STATE_BIT(4)
173 // If this bit is set, this frame or one of its descendants has a
174 // percentage height that depends on an ancestor of this frame.
175 // (Or it did at one point in the past, since we don't necessarily clear
176 // the bit when it's no longer needed; it's an optimization.)
177 #define NS_FRAME_CONTAINS_RELATIVE_HEIGHT NS_FRAME_STATE_BIT(5)
179 // If this bit is set, then the frame corresponds to generated content
180 #define NS_FRAME_GENERATED_CONTENT NS_FRAME_STATE_BIT(6)
182 // If this bit is set the frame is a continuation that is holding overflow,
183 // i.e. it is a next-in-flow created to hold overflow after the box's
184 // height has ended. This means the frame should be a) at the top of the
185 // page and b) invisible: no borders, zero height, ignored in margin
186 // collapsing, etc. See nsContainerFrame.h
187 #define NS_FRAME_IS_OVERFLOW_CONTAINER NS_FRAME_STATE_BIT(7)
189 // If this bit is set, then the frame has been moved out of the flow,
190 // e.g., it is absolutely positioned or floated
191 #define NS_FRAME_OUT_OF_FLOW NS_FRAME_STATE_BIT(8)
193 // If this bit is set, then the frame reflects content that may be selected
194 #define NS_FRAME_SELECTED_CONTENT NS_FRAME_STATE_BIT(9)
196 // If this bit is set, then the frame is dirty and needs to be reflowed.
197 // This bit is set when the frame is first created.
198 // This bit is cleared by DidReflow after the required call to Reflow has
199 // finished.
200 // Do not set this bit yourself if you plan to pass the frame to
201 // nsIPresShell::FrameNeedsReflow. Pass the right arguments instead.
202 #define NS_FRAME_IS_DIRTY NS_FRAME_STATE_BIT(10)
204 // If this bit is set then the frame is too deep in the frame tree, and
205 // we'll stop updating it and its children, to prevent stack overflow
206 // and the like.
207 #define NS_FRAME_TOO_DEEP_IN_FRAME_TREE NS_FRAME_STATE_BIT(11)
209 // If this bit is set, either:
210 // 1. the frame has children that have either NS_FRAME_IS_DIRTY or
211 // NS_FRAME_HAS_DIRTY_CHILDREN, or
212 // 2. the frame has had descendants removed.
213 // It means that Reflow needs to be called, but that Reflow will not
214 // do as much work as it would if NS_FRAME_IS_DIRTY were set.
215 // This bit is cleared by DidReflow after the required call to Reflow has
216 // finished.
217 // Do not set this bit yourself if you plan to pass the frame to
218 // nsIPresShell::FrameNeedsReflow. Pass the right arguments instead.
219 #define NS_FRAME_HAS_DIRTY_CHILDREN NS_FRAME_STATE_BIT(12)
221 // If this bit is set, the frame has an associated view
222 #define NS_FRAME_HAS_VIEW NS_FRAME_STATE_BIT(13)
224 // If this bit is set, the frame was created from anonymous content.
225 #define NS_FRAME_INDEPENDENT_SELECTION NS_FRAME_STATE_BIT(14)
227 // If this bit is set, the frame is "special" (lame term, I know),
228 // which means that it is part of the mangled frame hierarchy that
229 // results when an inline has been split because of a nested block.
230 // See the comments in nsCSSFrameConstructor::ConstructInline for
231 // more details.
232 #define NS_FRAME_IS_SPECIAL NS_FRAME_STATE_BIT(15)
234 // If this bit is set, the frame may have a transform that it applies
235 // to its coordinate system (e.g. CSS transform, SVG foreignObject).
236 // This is used primarily in GetTransformMatrix to optimize for the
237 // common case.
238 // ALSO, if this bit is set, the frame's first-continuation may
239 // have an associated nsSVGRenderingObserverList.
240 #define NS_FRAME_MAY_BE_TRANSFORMED_OR_HAVE_RENDERING_OBSERVERS \
241 NS_FRAME_STATE_BIT(16)
243 #ifdef IBMBIDI
244 // If this bit is set, the frame itself is a bidi continuation,
245 // or is incomplete (its next sibling is a bidi continuation)
246 #define NS_FRAME_IS_BIDI NS_FRAME_STATE_BIT(17)
247 #endif
249 // If this bit is set the frame has descendant with a view
250 #define NS_FRAME_HAS_CHILD_WITH_VIEW NS_FRAME_STATE_BIT(18)
252 // If this bit is set, then reflow may be dispatched from the current
253 // frame instead of the root frame.
254 #define NS_FRAME_REFLOW_ROOT NS_FRAME_STATE_BIT(19)
256 // Bits 20-31 of the frame state are reserved for implementations.
257 #define NS_FRAME_IMPL_RESERVED nsFrameState(0xFFF00000)
259 // This bit is set on floats whose parent does not contain their
260 // placeholder. This can happen for two reasons: (1) the float was
261 // split, and this piece is the continuation, or (2) the entire float
262 // didn't fit on the page.
263 #define NS_FRAME_IS_PUSHED_FLOAT NS_FRAME_STATE_BIT(32)
265 // The lower 20 bits and upper 32 bits of the frame state are reserved
266 // by this API.
267 #define NS_FRAME_RESERVED ~NS_FRAME_IMPL_RESERVED
269 // Box layout bits
270 #define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
271 #define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)
273 // Helper macros
274 #define NS_SUBTREE_DIRTY(_frame) \
275 (((_frame)->GetStateBits() & \
276 (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0)
278 //----------------------------------------------------------------------
280 enum nsSelectionAmount {
281 eSelectCharacter = 0,
282 eSelectWord = 1,
283 eSelectLine = 2, //previous drawn line in flow.
284 eSelectBeginLine = 3,
285 eSelectEndLine = 4,
286 eSelectNoAmount = 5, //just bounce back current offset.
287 eSelectParagraph = 6 //select a "paragraph"
290 enum nsDirection {
291 eDirNext = 0,
292 eDirPrevious= 1
295 enum nsSpread {
296 eSpreadNone = 0,
297 eSpreadAcross = 1,
298 eSpreadDown = 2
301 // Carried out margin flags
302 #define NS_CARRIED_TOP_MARGIN_IS_AUTO 0x1
303 #define NS_CARRIED_BOTTOM_MARGIN_IS_AUTO 0x2
305 //----------------------------------------------------------------------
308 * Reflow status returned by the reflow methods. There are three
309 * completion statuses, represented by two bit flags.
311 * NS_FRAME_COMPLETE means the frame is fully complete.
313 * NS_FRAME_NOT_COMPLETE bit flag means the frame does not map all its
314 * content, and that the parent frame should create a continuing frame.
315 * If this bit isn't set it means the frame does map all its content.
316 * This bit is mutually exclusive with NS_FRAME_OVERFLOW_INCOMPLETE.
318 * NS_FRAME_OVERFLOW_INCOMPLETE bit flag means that the frame has
319 * overflow that is not complete, but its own box is complete.
320 * (This happens when content overflows a fixed-height box.)
321 * The reflower should place and size the frame and continue its reflow,
322 * but needs to create an overflow container as a continuation for this
323 * frame. See nsContainerFrame.h for more information.
324 * This bit is mutually exclusive with NS_FRAME_NOT_COMPLETE.
326 * Please use the SET macro for handling
327 * NS_FRAME_NOT_COMPLETE and NS_FRAME_OVERFLOW_INCOMPLETE.
329 * NS_FRAME_REFLOW_NEXTINFLOW bit flag means that the next-in-flow is
330 * dirty, and also needs to be reflowed. This status only makes sense
331 * for a frame that is not complete, i.e. you wouldn't set both
332 * NS_FRAME_COMPLETE and NS_FRAME_REFLOW_NEXTINFLOW.
334 * The low 8 bits of the nsReflowStatus are reserved for future extensions;
335 * the remaining 24 bits are zero (and available for extensions; however
336 * API's that accept/return nsReflowStatus must not receive/return any
337 * extension bits).
339 * @see #Reflow()
341 typedef PRUint32 nsReflowStatus;
343 #define NS_FRAME_COMPLETE 0 // Note: not a bit!
344 #define NS_FRAME_NOT_COMPLETE 0x1
345 #define NS_FRAME_REFLOW_NEXTINFLOW 0x2
346 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4
348 #define NS_FRAME_IS_COMPLETE(status) \
349 (0 == ((status) & NS_FRAME_NOT_COMPLETE))
351 #define NS_FRAME_IS_NOT_COMPLETE(status) \
352 (0 != ((status) & NS_FRAME_NOT_COMPLETE))
354 #define NS_FRAME_OVERFLOW_IS_INCOMPLETE(status) \
355 (0 != ((status) & NS_FRAME_OVERFLOW_INCOMPLETE))
357 #define NS_FRAME_IS_FULLY_COMPLETE(status) \
358 (NS_FRAME_IS_COMPLETE(status) && !NS_FRAME_OVERFLOW_IS_INCOMPLETE(status))
360 // These macros set or switch incompete statuses without touching th
361 // NS_FRAME_REFLOW_NEXTINFLOW bit.
362 #define NS_FRAME_SET_INCOMPLETE(status) \
363 status = (status & ~NS_FRAME_OVERFLOW_INCOMPLETE) | NS_FRAME_NOT_COMPLETE
365 #define NS_FRAME_SET_OVERFLOW_INCOMPLETE(status) \
366 status = (status & ~NS_FRAME_NOT_COMPLETE) | NS_FRAME_OVERFLOW_INCOMPLETE
368 // This macro tests to see if an nsReflowStatus is an error value
369 // or just a regular return value
370 #define NS_IS_REFLOW_ERROR(_status) (PRInt32(_status) < 0)
373 * Extensions to the reflow status bits defined by nsIFrameReflow
376 // This bit is set, when a break is requested. This bit is orthogonal
377 // to the nsIFrame::nsReflowStatus completion bits.
378 #define NS_INLINE_BREAK 0x0100
380 // When a break is requested, this bit when set indicates that the
381 // break should occur after the frame just reflowed; when the bit is
382 // clear the break should occur before the frame just reflowed.
383 #define NS_INLINE_BREAK_BEFORE 0x0000
384 #define NS_INLINE_BREAK_AFTER 0x0200
386 // The type of break requested can be found in these bits.
387 #define NS_INLINE_BREAK_TYPE_MASK 0xF000
389 // Set when a break was induced by completion of a first-letter
390 #define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000
392 //----------------------------------------
393 // Macros that use those bits
395 #define NS_INLINE_IS_BREAK(_status) \
396 (0 != ((_status) & NS_INLINE_BREAK))
398 #define NS_INLINE_IS_BREAK_AFTER(_status) \
399 (0 != ((_status) & NS_INLINE_BREAK_AFTER))
401 #define NS_INLINE_IS_BREAK_BEFORE(_status) \
402 (NS_INLINE_BREAK == ((_status) & (NS_INLINE_BREAK|NS_INLINE_BREAK_AFTER)))
404 #define NS_INLINE_GET_BREAK_TYPE(_status) (((_status) >> 12) & 0xF)
406 #define NS_INLINE_MAKE_BREAK_TYPE(_type) ((_type) << 12)
408 // Construct a line-break-before status. Note that there is no
409 // completion status for a line-break before because we *know* that
410 // the frame will be reflowed later and hence it's current completion
411 // status doesn't matter.
412 #define NS_INLINE_LINE_BREAK_BEFORE() \
413 (NS_INLINE_BREAK | NS_INLINE_BREAK_BEFORE | \
414 NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
416 // Take a completion status and add to it the desire to have a
417 // line-break after. For this macro we do need the completion status
418 // because the user of the status will need to know whether to
419 // continue the frame or not.
420 #define NS_INLINE_LINE_BREAK_AFTER(_completionStatus) \
421 ((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \
422 NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
424 // A frame is "truncated" if the part of the frame before the first
425 // possible break point was unable to fit in the available vertical
426 // space. Therefore, the entire frame should be moved to the next page.
427 // A frame that begins at the top of the page must never be "truncated".
428 // Doing so would likely cause an infinite loop.
429 #define NS_FRAME_TRUNCATED 0x0010
430 #define NS_FRAME_IS_TRUNCATED(status) \
431 (0 != ((status) & NS_FRAME_TRUNCATED))
432 #define NS_FRAME_SET_TRUNCATION(status, aReflowState, aMetrics) \
433 aReflowState.SetTruncated(aMetrics, &status);
435 // Merge the incompleteness, truncation and NS_FRAME_REFLOW_NEXTINFLOW
436 // status from aSecondary into aPrimary.
437 void NS_MergeReflowStatusInto(nsReflowStatus* aPrimary,
438 nsReflowStatus aSecondary);
440 //----------------------------------------------------------------------
443 * DidReflow status values.
445 typedef PRBool nsDidReflowStatus;
447 #define NS_FRAME_REFLOW_NOT_FINISHED PR_FALSE
448 #define NS_FRAME_REFLOW_FINISHED PR_TRUE
451 * The overflow rect may be stored as four 1-byte deltas each strictly
452 * LESS THAN 0xff, for the four edges of the rectangle, or the four bytes
453 * may be read as a single 32-bit "overflow-rect type" value including
454 * at least one 0xff byte as an indicator that the value does NOT
455 * represent four deltas.
456 * If all four deltas are zero, this means that no overflow rect has
457 * actually been set (this is the initial state of newly-created frames).
459 #define NS_FRAME_OVERFLOW_DELTA_MAX 0xfe // max delta we can store
461 #define NS_FRAME_OVERFLOW_NONE 0x00000000 // there is no overflow rect;
462 // code relies on this being
463 // the all-zero value
465 #define NS_FRAME_OVERFLOW_LARGE 0x000000ff // overflow is stored as a
466 // separate rect property
468 //----------------------------------------------------------------------
471 * A frame in the layout model. This interface is supported by all frame
472 * objects.
474 * Frames can have multiple child lists: the default unnamed child list
475 * (referred to as the <i>principal</i> child list, and additional named
476 * child lists. There is an ordering of frames within a child list, but
477 * there is no order defined between frames in different child lists of
478 * the same parent frame.
480 * Frames are NOT reference counted. Use the Destroy() member function
481 * to destroy a frame. The lifetime of the frame hierarchy is bounded by the
482 * lifetime of the presentation shell which owns the frames.
484 * nsIFrame is a private Gecko interface. If you are not Gecko then you
485 * should not use it. If you're not in layout, then you won't be able to
486 * link to many of the functions defined here. Too bad.
488 * If you're not in layout but you must call functions in here, at least
489 * restrict yourself to calling virtual methods, which won't hurt you as badly.
491 class nsIFrame : public nsQueryFrame
493 public:
494 typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor;
495 typedef mozilla::FrameProperties FrameProperties;
497 NS_DECL_QUERYFRAME_TARGET(nsIFrame)
499 nsPresContext* PresContext() const {
500 return GetStyleContext()->GetRuleNode()->GetPresContext();
504 * Called to initialize the frame. This is called immediately after creating
505 * the frame.
507 * If the frame is a continuing frame, then aPrevInFlow indicates the previous
508 * frame (the frame that was split).
510 * If you want a view associated with your frame, you should create the view
511 * now.
513 * @param aContent the content object associated with the frame
514 * @param aGeometricParent the geometric parent frame
515 * @param aContentParent the content parent frame
516 * @param aContext the style context associated with the frame
517 * @param aPrevInFlow the prev-in-flow frame
519 NS_IMETHOD Init(nsIContent* aContent,
520 nsIFrame* aParent,
521 nsIFrame* aPrevInFlow) = 0;
524 * Destroys this frame and each of its child frames (recursively calls
525 * Destroy() for each child). If this frame is a first-continuation, this
526 * also removes the frame from the primary frame man and clears undisplayed
527 * content for its content node.
528 * If the frame is a placeholder, it also ensures the out-of-flow frame's
529 * removal and destruction.
531 void Destroy() { DestroyFrom(this); }
533 protected:
535 * Implements Destroy(). Do not call this directly except from within a
536 * DestroyFrom() implementation.
537 * @param aDestructRoot is the root of the subtree being destroyed
539 virtual void DestroyFrom(nsIFrame* aDestructRoot) = 0;
540 friend class nsFrameList; // needed to pass aDestructRoot through to children
541 friend class nsLineBox; // needed to pass aDestructRoot through to children
542 public:
545 * Called to set the initial list of frames. This happens after the frame
546 * has been initialized.
548 * This is only called once for a given child list, and won't be called
549 * at all for child lists with no initial list of frames.
551 * @param aListName the name of the child list. A NULL pointer for the atom
552 * name means the unnamed principal child list
553 * @param aChildList list of child frames. Each of the frames has its
554 * NS_FRAME_IS_DIRTY bit set. Must not be empty.
555 * @return NS_ERROR_INVALID_ARG if there is no child list with the specified
556 * name,
557 * NS_ERROR_UNEXPECTED if the frame is an atomic frame or if the
558 * initial list of frames has already been set for that child list,
559 * NS_OK otherwise. In this case, SetInitialChildList empties out
560 * aChildList in the process of moving the frames over to its own
561 * child list.
562 * @see #Init()
564 NS_IMETHOD SetInitialChildList(nsIAtom* aListName,
565 nsFrameList& aChildList) = 0;
568 * This method is responsible for appending frames to the frame
569 * list. The implementation should append the frames to the specified
570 * child list and then generate a reflow command.
572 * @param aListName the name of the child list. A NULL pointer for the atom
573 * name means the unnamed principal child list
574 * @param aFrameList list of child frames to append. Each of the frames has
575 * its NS_FRAME_IS_DIRTY bit set. Must not be empty.
576 * @return NS_ERROR_INVALID_ARG if there is no child list with the specified
577 * name,
578 * NS_ERROR_UNEXPECTED if the frame is an atomic frame,
579 * NS_OK otherwise. In this case, AppendFrames empties out
580 * aChildList in the process of moving the frames over to its own
581 * child list.
583 NS_IMETHOD AppendFrames(nsIAtom* aListName,
584 nsFrameList& aFrameList) = 0;
587 * This method is responsible for inserting frames into the frame
588 * list. The implementation should insert the new frames into the specified
589 * child list and then generate a reflow command.
591 * @param aListName the name of the child list. A NULL pointer for the atom
592 * name means the unnamed principal child list
593 * @param aPrevFrame the frame to insert frames <b>after</b>
594 * @param aFrameList list of child frames to insert <b>after</b> aPrevFrame.
595 * Each of the frames has its NS_FRAME_IS_DIRTY bit set
596 * @return NS_ERROR_INVALID_ARG if there is no child list with the specified
597 * name,
598 * NS_ERROR_UNEXPECTED if the frame is an atomic frame,
599 * NS_OK otherwise. In this case, InsertFrames empties out
600 * aChildList in the process of moving the frames over to its own
601 * child list.
603 NS_IMETHOD InsertFrames(nsIAtom* aListName,
604 nsIFrame* aPrevFrame,
605 nsFrameList& aFrameList) = 0;
608 * This method is responsible for removing a frame in the frame
609 * list. The implementation should do something with the removed frame
610 * and then generate a reflow command. The implementation is responsible
611 * for destroying aOldFrame (the caller mustn't destroy aOldFrame).
613 * @param aListName the name of the child list. A NULL pointer for the atom
614 * name means the unnamed principal child list
615 * @param aOldFrame the frame to remove
616 * @return NS_ERROR_INVALID_ARG if there is no child list with the specified
617 * name,
618 * NS_ERROR_FAILURE if the child frame is not in the specified
619 * child list,
620 * NS_ERROR_UNEXPECTED if the frame is an atomic frame,
621 * NS_OK otherwise
623 NS_IMETHOD RemoveFrame(nsIAtom* aListName,
624 nsIFrame* aOldFrame) = 0;
627 * Get the content object associated with this frame. Does not add a reference.
629 nsIContent* GetContent() const { return mContent; }
632 * Get the frame that should be the parent for the frames of child elements
633 * May return nsnull during reflow
635 virtual nsIFrame* GetContentInsertionFrame() { return this; }
638 * Get the frame that should be scrolled if the content associated
639 * with this frame is targeted for scrolling. For frames implementing
640 * nsIScrollableFrame this will return the frame itself. For frames
641 * like nsTextControlFrame that contain a scrollframe, will return
642 * that scrollframe.
644 virtual nsIScrollableFrame* GetScrollTargetFrame() { return nsnull; }
647 * Get the offsets of the frame. most will be 0,0
650 NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end) const = 0;
653 * Reset the offsets when splitting frames during Bidi reordering
656 virtual void AdjustOffsetsForBidi(PRInt32 aStart, PRInt32 aEnd) {}
659 * Get the style context associated with this frame.
662 nsStyleContext* GetStyleContext() const { return mStyleContext; }
663 void SetStyleContext(nsStyleContext* aContext)
665 if (aContext != mStyleContext) {
666 nsStyleContext* oldStyleContext = mStyleContext;
667 mStyleContext = aContext;
668 if (aContext) {
669 aContext->AddRef();
670 DidSetStyleContext(oldStyleContext);
672 if (oldStyleContext)
673 oldStyleContext->Release();
677 void SetStyleContextWithoutNotification(nsStyleContext* aContext)
679 if (aContext != mStyleContext) {
680 if (mStyleContext)
681 mStyleContext->Release();
682 mStyleContext = aContext;
683 if (aContext) {
684 aContext->AddRef();
689 // Style post processing hook
690 // Attention: the old style context is the one we're forgetting,
691 // and hence possibly completely bogus for GetStyle* purposes.
692 // Use PeekStyleData instead.
693 virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) = 0;
696 * Get the style data associated with this frame. This returns a
697 * const style struct pointer that should never be modified. See
698 * |nsIStyleContext::GetStyleData| for more information.
700 * The use of the typesafe functions below is preferred to direct use
701 * of this function.
703 virtual const void* GetStyleDataExternal(nsStyleStructID aSID) const = 0;
706 * Define typesafe getter functions for each style struct by
707 * preprocessing the list of style structs. These functions are the
708 * preferred way to get style data. The macro creates functions like:
709 * const nsStyleBorder* GetStyleBorder();
710 * const nsStyleColor* GetStyleColor();
713 #ifdef _IMPL_NS_LAYOUT
714 #define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
715 const nsStyle##name_ * GetStyle##name_ () const { \
716 NS_ASSERTION(mStyleContext, "No style context found!"); \
717 return mStyleContext->GetStyle##name_ (); \
719 #else
720 #define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
721 const nsStyle##name_ * GetStyle##name_ () const { \
722 return static_cast<const nsStyle##name_*>( \
723 GetStyleDataExternal(eStyleStruct_##name_)); \
725 #endif
726 #include "nsStyleStructList.h"
727 #undef STYLE_STRUCT
729 #ifdef _IMPL_NS_LAYOUT
730 /** Also forward GetVisitedDependentColor to the style context */
731 nscolor GetVisitedDependentColor(nsCSSProperty aProperty)
732 { return mStyleContext->GetVisitedDependentColor(aProperty); }
733 #endif
736 * These methods are to access any additional style contexts that
737 * the frame may be holding. These are contexts that are children
738 * of the frame's primary context and are NOT used as style contexts
739 * for any child frames. These contexts also MUST NOT have any child
740 * contexts whatsoever. If you need to insert style contexts into the
741 * style tree, then you should create pseudo element frames to own them
742 * The indicies must be consecutive and implementations MUST return an
743 * NS_ERROR_INVALID_ARG if asked for an index that is out of range.
745 virtual nsStyleContext* GetAdditionalStyleContext(PRInt32 aIndex) const = 0;
747 virtual void SetAdditionalStyleContext(PRInt32 aIndex,
748 nsStyleContext* aStyleContext) = 0;
750 // returns GetStyleBorder()->mBoxShadow unless this frame is using
751 // -moz-appearance and is not chrome
752 nsCSSShadowArray* GetEffectiveBoxShadows();
755 * @return PR_FALSE if this frame definitely has no borders at all
757 PRBool HasBorder() const;
760 * Accessor functions for geometric parent
762 nsIFrame* GetParent() const { return mParent; }
763 NS_IMETHOD SetParent(const nsIFrame* aParent) { mParent = (nsIFrame*)aParent; return NS_OK; }
766 * Bounding rect of the frame. The values are in app units, and the origin is
767 * relative to the upper-left of the geometric parent. The size includes the
768 * content area, borders, and padding.
770 * Note: moving or sizing the frame does not affect the view's size or
771 * position.
773 nsRect GetRect() const { return mRect; }
774 nsPoint GetPosition() const { return nsPoint(mRect.x, mRect.y); }
775 nsSize GetSize() const { return nsSize(mRect.width, mRect.height); }
778 * When we change the size of the frame's border-box rect, we may need to
779 * reset the overflow rect if it was previously stored as deltas.
780 * (If it is currently a "large" overflow and could be re-packed as deltas,
781 * we don't bother as the cost of the allocation has already been paid.)
783 void SetRect(const nsRect& aRect) {
784 if (HasOverflowRect() && mOverflow.mType != NS_FRAME_OVERFLOW_LARGE) {
785 nsRect r = GetOverflowRect();
786 mRect = aRect;
787 SetOverflowRect(r);
788 } else {
789 mRect = aRect;
792 void SetSize(const nsSize& aSize) {
793 if (HasOverflowRect() && mOverflow.mType != NS_FRAME_OVERFLOW_LARGE) {
794 nsRect r = GetOverflowRect();
795 mRect.SizeTo(aSize);
796 SetOverflowRect(r);
797 } else {
798 mRect.SizeTo(aSize);
801 void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); }
804 * Return frame's computed offset due to relative positioning
806 nsPoint GetRelativeOffset(const nsStyleDisplay* aDisplay = nsnull) const;
808 virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
809 { return aChild->GetPosition(); }
811 nsPoint GetPositionIgnoringScrolling() {
812 return mParent ? mParent->GetPositionOfChildIgnoringScrolling(this)
813 : GetPosition();
816 static void DestroyRegion(void* aPropertyValue)
818 delete static_cast<nsRegion*>(aPropertyValue);
821 static void DestroyMargin(void* aPropertyValue)
823 delete static_cast<nsMargin*>(aPropertyValue);
826 static void DestroyRect(void* aPropertyValue)
828 delete static_cast<nsRect*>(aPropertyValue);
831 static void DestroyPoint(void* aPropertyValue)
833 delete static_cast<nsPoint*>(aPropertyValue);
836 #ifdef _MSC_VER
837 // XXX Workaround MSVC issue by making the static FramePropertyDescriptor
838 // non-const. See bug 555727.
839 #define NS_PROPERTY_DESCRIPTOR_CONST
840 #else
841 #define NS_PROPERTY_DESCRIPTOR_CONST const
842 #endif
844 #define NS_DECLARE_FRAME_PROPERTY(prop, dtor) \
845 static const FramePropertyDescriptor* prop() { \
846 static NS_PROPERTY_DESCRIPTOR_CONST FramePropertyDescriptor descriptor = { dtor, nsnull }; \
847 return &descriptor; \
849 // Don't use this unless you really know what you're doing!
850 #define NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(prop, dtor) \
851 static const FramePropertyDescriptor* prop() { \
852 static NS_PROPERTY_DESCRIPTOR_CONST FramePropertyDescriptor descriptor = { nsnull, dtor }; \
853 return &descriptor; \
856 NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialSibling, nsnull)
857 NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialPrevSibling, nsnull)
859 NS_DECLARE_FRAME_PROPERTY(ComputedOffsetProperty, DestroyPoint)
861 NS_DECLARE_FRAME_PROPERTY(OutlineInnerRectProperty, DestroyRect)
862 NS_DECLARE_FRAME_PROPERTY(PreEffectsBBoxProperty, DestroyRect)
863 NS_DECLARE_FRAME_PROPERTY(PreTransformBBoxProperty, DestroyRect)
865 NS_DECLARE_FRAME_PROPERTY(UsedMarginProperty, DestroyMargin)
866 NS_DECLARE_FRAME_PROPERTY(UsedPaddingProperty, DestroyMargin)
867 NS_DECLARE_FRAME_PROPERTY(UsedBorderProperty, DestroyMargin)
870 * Return the distance between the border edge of the frame and the
871 * margin edge of the frame. Like GetRect(), returns the dimensions
872 * as of the most recent reflow.
874 * This doesn't include any margin collapsing that may have occurred.
876 * It also treats 'auto' margins as zero, and treats any margins that
877 * should have been turned into 'auto' because of overconstraint as
878 * having their original values.
880 virtual nsMargin GetUsedMargin() const;
883 * Return the distance between the border edge of the frame (which is
884 * its rect) and the padding edge of the frame. Like GetRect(), returns
885 * the dimensions as of the most recent reflow.
887 * Note that this differs from GetStyleBorder()->GetBorder() in that
888 * this describes region of the frame's box, and
889 * GetStyleBorder()->GetBorder() describes a border. They differ only
890 * for tables, particularly border-collapse tables.
892 virtual nsMargin GetUsedBorder() const;
895 * Return the distance between the padding edge of the frame and the
896 * content edge of the frame. Like GetRect(), returns the dimensions
897 * as of the most recent reflow.
899 virtual nsMargin GetUsedPadding() const;
901 nsMargin GetUsedBorderAndPadding() const {
902 return GetUsedBorder() + GetUsedPadding();
906 * Apply the result of GetSkipSides() on this frame to an nsMargin by
907 * setting to zero any sides that are skipped.
909 void ApplySkipSides(nsMargin& aMargin) const;
912 * Like the frame's rect (see |GetRect|), which is the border rect,
913 * other rectangles of the frame, in app units, relative to the parent.
915 nsRect GetPaddingRect() const;
916 nsRect GetContentRect() const;
919 * Get the position of the frame's baseline, relative to the top of
920 * the frame (its top border edge). Only valid when Reflow is not
921 * needed and when the frame returned nsHTMLReflowMetrics::
922 * ASK_FOR_BASELINE as ascent in its reflow metrics.
924 virtual nscoord GetBaseline() const = 0;
927 * Used to iterate the list of additional child list names. Returns the atom
928 * name for the additional child list at the specified 0-based index, or a
929 * NULL pointer if there are no more named child lists.
931 * Note that the list is only the additional named child lists and does not
932 * include the unnamed principal child list.
934 virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const = 0;
937 * Get the specified child list.
939 * @param aListName the name of the child list. A NULL pointer for the atom
940 * name means the unnamed principal child list
941 * @return the child list. If this is an unknown list name, an empty list
942 * will be returned.
943 * @see #GetAdditionalListName()
945 // XXXbz if all our frame storage were actually backed by nsFrameList, we
946 // could make this return a const reference... nsBlockFrame is the only real
947 // culprit here. Make sure to assign the return value of this function into
948 // a |const nsFrameList&|, not an nsFrameList.
949 virtual nsFrameList GetChildList(nsIAtom* aListName) const = 0;
950 // XXXbz this method should go away
951 nsIFrame* GetFirstChild(nsIAtom* aListName) const {
952 return GetChildList(aListName).FirstChild();
954 // XXXmats this method should also go away then
955 nsIFrame* GetLastChild(nsIAtom* aListName) const {
956 return GetChildList(aListName).LastChild();
960 * Child frames are linked together in a doubly-linked list
962 nsIFrame* GetNextSibling() const { return mNextSibling; }
963 void SetNextSibling(nsIFrame* aNextSibling) {
964 NS_ASSERTION(this != aNextSibling, "Creating a circular frame list, this is very bad.");
965 if (mNextSibling && mNextSibling->GetPrevSibling() == this) {
966 mNextSibling->mPrevSibling = nsnull;
968 mNextSibling = aNextSibling;
969 if (mNextSibling) {
970 mNextSibling->mPrevSibling = this;
974 nsIFrame* GetPrevSibling() const { return mPrevSibling; }
977 * Builds the display lists for the content represented by this frame
978 * and its descendants. The background+borders of this element must
979 * be added first, before any other content.
981 * This should only be called by methods in nsFrame. Instead of calling this
982 * directly, call either BuildDisplayListForStackingContext or
983 * BuildDisplayListForChild.
985 * See nsDisplayList.h for more information about display lists.
987 * @param aDirtyRect content outside this rectangle can be ignored; the
988 * rectangle is in frame coordinates
990 NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
991 const nsRect& aDirtyRect,
992 const nsDisplayListSet& aLists) { return NS_OK; }
994 * Displays the caret onto the given display list builder. The caret is
995 * painted on top of the rest of the display list items.
997 * @param aDirtyRect is the dirty rectangle that we're repainting.
999 nsresult DisplayCaret(nsDisplayListBuilder* aBuilder,
1000 const nsRect& aDirtyRect,
1001 nsDisplayList* aList);
1004 * Get the preferred caret color at the offset.
1006 * @param aOffset is offset of the content.
1008 virtual nscolor GetCaretColorAt(PRInt32 aOffset);
1011 PRBool IsThemed(nsITheme::Transparency* aTransparencyState = nsnull) {
1012 return IsThemed(GetStyleDisplay(), aTransparencyState);
1014 PRBool IsThemed(const nsStyleDisplay* aDisp,
1015 nsITheme::Transparency* aTransparencyState = nsnull) {
1016 if (!aDisp->mAppearance)
1017 return PR_FALSE;
1018 nsPresContext* pc = PresContext();
1019 nsITheme *theme = pc->GetTheme();
1020 if(!theme || !theme->ThemeSupportsWidget(pc, this, aDisp->mAppearance))
1021 return PR_FALSE;
1022 if (aTransparencyState) {
1023 *aTransparencyState = theme->GetWidgetTransparency(this, aDisp->mAppearance);
1025 return PR_TRUE;
1029 * Builds a display list for the content represented by this frame,
1030 * treating this frame as the root of a stacking context.
1031 * @param aDirtyRect content outside this rectangle can be ignored; the
1032 * rectangle is in frame coordinates
1034 nsresult BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
1035 const nsRect& aDirtyRect,
1036 nsDisplayList* aList);
1039 * Clips the display items of aFromSet, putting the results in aToSet.
1040 * Only items corresponding to frames which are descendants of this frame
1041 * are clipped. In other words, descendant elements whose CSS boxes do not
1042 * have this frame as a container are not clipped. Also,
1043 * border/background/outline items for this frame are not clipped,
1044 * unless aClipBorderBackground is set to PR_TRUE. (We need this because
1045 * a scrollframe must overflow-clip its scrolled child's background/borders.)
1047 nsresult OverflowClip(nsDisplayListBuilder* aBuilder,
1048 const nsDisplayListSet& aFromSet,
1049 const nsDisplayListSet& aToSet,
1050 const nsRect& aClipRect,
1051 PRBool aClipBorderBackground = PR_FALSE,
1052 PRBool aClipAll = PR_FALSE);
1054 enum {
1055 DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT = 0x01,
1056 DISPLAY_CHILD_FORCE_STACKING_CONTEXT = 0x02,
1057 DISPLAY_CHILD_INLINE = 0x04
1060 * Adjusts aDirtyRect for the child's offset, checks that the dirty rect
1061 * actually intersects the child (or its descendants), calls BuildDisplayList
1062 * on the child if necessary, and puts things in the right lists if the child
1063 * is positioned.
1065 * @param aFlags combination of DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT,
1066 * DISPLAY_CHILD_FORCE_STACKING_CONTEXT and DISPLAY_CHILD_INLINE
1068 nsresult BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
1069 nsIFrame* aChild,
1070 const nsRect& aDirtyRect,
1071 const nsDisplayListSet& aLists,
1072 PRUint32 aFlags = 0);
1075 * Does this frame need a view?
1077 virtual PRBool NeedsView() { return PR_FALSE; }
1080 * Returns whether this frame has a transform matrix applied to it. This is true
1081 * if we have the -moz-transform property or if we're an SVGForeignObjectFrame.
1083 virtual PRBool IsTransformed() const;
1086 * Event handling of GUI events.
1088 * @param aEvent event structure describing the type of event and rge widget
1089 * where the event originated
1090 * The |point| member of this is in the coordinate system of the
1091 * view returned by GetOffsetFromView.
1092 * @param aEventStatus a return value indicating whether the event was handled
1093 * and whether default processing should be done
1095 * XXX From a frame's perspective it's unclear what the effect of the event status
1096 * is. Does it cause the event to continue propagating through the frame hierarchy
1097 * or is it just returned to the widgets?
1099 * @see nsGUIEvent
1100 * @see nsEventStatus
1102 NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
1103 nsGUIEvent* aEvent,
1104 nsEventStatus* aEventStatus) = 0;
1106 NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext,
1107 nsEvent* aEvent,
1108 nsIContent** aContent) = 0;
1110 // This structure keeps track of the content node and offsets associated with
1111 // a point; there is a primary and a secondary offset associated with any
1112 // point. The primary and secondary offsets differ when the point is over a
1113 // non-text object. The primary offset is the expected position of the
1114 // cursor calculated from a point; the secondary offset, when it is different,
1115 // indicates that the point is in the boundaries of some selectable object.
1116 // Note that the primary offset can be after the secondary offset; for places
1117 // that need the beginning and end of the object, the StartOffset and
1118 // EndOffset helpers can be used.
1119 struct NS_STACK_CLASS ContentOffsets {
1120 nsCOMPtr<nsIContent> content;
1121 PRBool IsNull() { return !content; }
1122 PRInt32 offset;
1123 PRInt32 secondaryOffset;
1124 // Helpers for places that need the ends of the offsets and expect them in
1125 // numerical order, as opposed to wanting the primary and secondary offsets
1126 PRInt32 StartOffset() { return NS_MIN(offset, secondaryOffset); }
1127 PRInt32 EndOffset() { return NS_MAX(offset, secondaryOffset); }
1128 // This boolean indicates whether the associated content is before or after
1129 // the offset; the most visible use is to allow the caret to know which line
1130 // to display on.
1131 PRBool associateWithNext;
1134 * This function calculates the content offsets for selection relative to
1135 * a point. Note that this should generally only be callled on the event
1136 * frame associated with an event because this function does not account
1137 * for frame lists other than the primary one.
1138 * @param aPoint point relative to this frame
1140 ContentOffsets GetContentOffsetsFromPoint(nsPoint aPoint,
1141 PRBool aIgnoreSelectionStyle = PR_FALSE);
1143 virtual ContentOffsets GetContentOffsetsFromPointExternal(nsPoint aPoint,
1144 PRBool aIgnoreSelectionStyle = PR_FALSE)
1145 { return GetContentOffsetsFromPoint(aPoint, aIgnoreSelectionStyle); }
1148 * This structure holds information about a cursor. mContainer represents a
1149 * loaded image that should be preferred. If it is not possible to use it, or
1150 * if it is null, mCursor should be used.
1152 struct NS_STACK_CLASS Cursor {
1153 nsCOMPtr<imgIContainer> mContainer;
1154 PRInt32 mCursor;
1155 PRBool mHaveHotspot;
1156 float mHotspotX, mHotspotY;
1159 * Get the cursor for a given frame.
1161 NS_IMETHOD GetCursor(const nsPoint& aPoint,
1162 Cursor& aCursor) = 0;
1165 * Get a point (in the frame's coordinate space) given an offset into
1166 * the content. This point should be on the baseline of text with
1167 * the correct horizontal offset
1169 NS_IMETHOD GetPointFromOffset(PRInt32 inOffset,
1170 nsPoint* outPoint) = 0;
1173 * Get the child frame of this frame which contains the given
1174 * content offset. outChildFrame may be this frame, or nsnull on return.
1175 * outContentOffset returns the content offset relative to the start
1176 * of the returned node. You can also pass a hint which tells the method
1177 * to stick to the end of the first found frame or the beginning of the
1178 * next in case the offset falls on a boundary.
1180 NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset,
1181 PRBool inHint,//false stick left
1182 PRInt32* outFrameContentOffset,
1183 nsIFrame* *outChildFrame) = 0;
1186 * Get the current frame-state value for this frame. aResult is
1187 * filled in with the state bits.
1189 nsFrameState GetStateBits() const { return mState; }
1192 * Update the current frame-state value for this frame.
1194 void AddStateBits(nsFrameState aBits) { mState |= aBits; }
1195 void RemoveStateBits(nsFrameState aBits) { mState &= ~aBits; }
1198 * This call is invoked on the primary frame for a character data content
1199 * node, when it is changed in the content tree.
1201 NS_IMETHOD CharacterDataChanged(CharacterDataChangeInfo* aInfo) = 0;
1204 * This call is invoked when the value of a content objects's attribute
1205 * is changed.
1206 * The first frame that maps that content is asked to deal
1207 * with the change by doing whatever is appropriate.
1209 * @param aNameSpaceID the namespace of the attribute
1210 * @param aAttribute the atom name of the attribute
1211 * @param aModType Whether or not the attribute was added, changed, or removed.
1212 * The constants are defined in nsIDOMMutationEvent.h.
1214 NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
1215 nsIAtom* aAttribute,
1216 PRInt32 aModType) = 0;
1219 * Return how your frame can be split.
1221 virtual nsSplittableType GetSplittableType() const = 0;
1224 * Continuation member functions
1226 virtual nsIFrame* GetPrevContinuation() const = 0;
1227 NS_IMETHOD SetPrevContinuation(nsIFrame*) = 0;
1228 virtual nsIFrame* GetNextContinuation() const = 0;
1229 NS_IMETHOD SetNextContinuation(nsIFrame*) = 0;
1230 virtual nsIFrame* GetFirstContinuation() const {
1231 return const_cast<nsIFrame*>(this);
1233 virtual nsIFrame* GetLastContinuation() const {
1234 return const_cast<nsIFrame*>(this);
1238 * GetTailContinuation gets the last non-overflow-container continuation
1239 * in the continuation chain, i.e. where the next sibling element
1240 * should attach).
1242 nsIFrame* GetTailContinuation();
1245 * Flow member functions
1247 virtual nsIFrame* GetPrevInFlowVirtual() const = 0;
1248 nsIFrame* GetPrevInFlow() const { return GetPrevInFlowVirtual(); }
1249 NS_IMETHOD SetPrevInFlow(nsIFrame*) = 0;
1251 virtual nsIFrame* GetNextInFlowVirtual() const = 0;
1252 nsIFrame* GetNextInFlow() const { return GetNextInFlowVirtual(); }
1253 NS_IMETHOD SetNextInFlow(nsIFrame*) = 0;
1256 * Return the first frame in our current flow.
1258 virtual nsIFrame* GetFirstInFlow() const {
1259 return const_cast<nsIFrame*>(this);
1263 * Return the last frame in our current flow.
1265 virtual nsIFrame* GetLastInFlow() const {
1266 return const_cast<nsIFrame*>(this);
1271 * Mark any stored intrinsic width information as dirty (requiring
1272 * re-calculation). Note that this should generally not be called
1273 * directly; nsPresShell::FrameNeedsReflow will call it instead.
1275 virtual void MarkIntrinsicWidthsDirty() = 0;
1278 * Get the intrinsic minimum width of the frame. This must be less
1279 * than or equal to the intrinsic width.
1281 * This is *not* affected by the CSS 'min-width', 'width', and
1282 * 'max-width' properties on this frame, but it is affected by the
1283 * values of those properties on this frame's descendants. (It may be
1284 * called during computation of the values of those properties, so it
1285 * cannot depend on any values in the nsStylePosition for this frame.)
1287 * The value returned should **NOT** include the space required for
1288 * padding and border.
1290 * Note that many frames will cache the result of this function call
1291 * unless MarkIntrinsicWidthsDirty is called.
1293 * It is not acceptable for a frame to mark itself dirty when this
1294 * method is called.
1296 * This method must not return a negative value.
1298 virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext) = 0;
1301 * Get the intrinsic width of the frame. This must be greater than or
1302 * equal to the intrinsic minimum width.
1304 * Otherwise, all the comments for |GetMinWidth| above apply.
1306 virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext) = 0;
1309 * |InlineIntrinsicWidth| represents the intrinsic width information
1310 * in inline layout. Code that determines the intrinsic width of a
1311 * region of inline layout accumulates the result into this structure.
1312 * This pattern is needed because we need to maintain state
1313 * information about whitespace (for both collapsing and trimming).
1315 struct InlineIntrinsicWidthData {
1316 InlineIntrinsicWidthData()
1317 : line(nsnull)
1318 , lineContainer(nsnull)
1319 , prevLines(0)
1320 , currentLine(0)
1321 , skipWhitespace(PR_TRUE)
1322 , trailingWhitespace(0)
1325 // The line. This may be null if the inlines are not associated with
1326 // a block or if we just don't know the line.
1327 const nsLineList_iterator* line;
1329 // The line container.
1330 nsIFrame* lineContainer;
1332 // The maximum intrinsic width for all previous lines.
1333 nscoord prevLines;
1335 // The maximum intrinsic width for the current line. At a line
1336 // break (mandatory for preferred width; allowed for minimum width),
1337 // the caller should call |Break()|.
1338 nscoord currentLine;
1340 // True if initial collapsable whitespace should be skipped. This
1341 // should be true at the beginning of a block, after hard breaks
1342 // and when the last text ended with whitespace.
1343 PRBool skipWhitespace;
1345 // This contains the width of the trimmable whitespace at the end of
1346 // |currentLine|; it is zero if there is no such whitespace.
1347 nscoord trailingWhitespace;
1349 // Floats encountered in the lines.
1350 nsTArray<nsIFrame*> floats;
1353 struct InlineMinWidthData : public InlineIntrinsicWidthData {
1354 InlineMinWidthData()
1355 : trailingTextFrame(nsnull)
1356 , atStartOfLine(PR_TRUE)
1359 // We need to distinguish forced and optional breaks for cases where the
1360 // current line total is negative. When it is, we need to ignore
1361 // optional breaks to prevent min-width from ending up bigger than
1362 // pref-width.
1363 void ForceBreak(nsIRenderingContext *aRenderingContext);
1364 void OptionallyBreak(nsIRenderingContext *aRenderingContext);
1366 // The last text frame processed so far in the current line, when
1367 // the last characters in that text frame are relevant for line
1368 // break opportunities.
1369 nsIFrame *trailingTextFrame;
1371 // Whether we're currently at the start of the line. If we are, we
1372 // can't break (for example, between the text-indent and the first
1373 // word).
1374 PRBool atStartOfLine;
1377 struct InlinePrefWidthData : public InlineIntrinsicWidthData {
1378 void ForceBreak(nsIRenderingContext *aRenderingContext);
1382 * Add the intrinsic minimum width of a frame in a way suitable for
1383 * use in inline layout to an |InlineIntrinsicWidthData| object that
1384 * represents the intrinsic width information of all the previous
1385 * frames in the inline layout region.
1387 * All *allowed* breakpoints within the frame determine what counts as
1388 * a line for the |InlineIntrinsicWidthData|. This means that
1389 * |aData->trailingWhitespace| will always be zero (unlike for
1390 * AddInlinePrefWidth).
1392 * All the comments for |GetMinWidth| apply, except that this function
1393 * is responsible for adding padding, border, and margin and for
1394 * considering the effects of 'width', 'min-width', and 'max-width'.
1396 * This may be called on any frame. Frames that do not participate in
1397 * line breaking can inherit the default implementation on nsFrame,
1398 * which calls |GetMinWidth|.
1400 virtual void
1401 AddInlineMinWidth(nsIRenderingContext *aRenderingContext,
1402 InlineMinWidthData *aData) = 0;
1405 * Add the intrinsic preferred width of a frame in a way suitable for
1406 * use in inline layout to an |InlineIntrinsicWidthData| object that
1407 * represents the intrinsic width information of all the previous
1408 * frames in the inline layout region.
1410 * All the comments for |AddInlineMinWidth| and |GetPrefWidth| apply,
1411 * except that this fills in an |InlineIntrinsicWidthData| structure
1412 * based on using all *mandatory* breakpoints within the frame.
1414 virtual void
1415 AddInlinePrefWidth(nsIRenderingContext *aRenderingContext,
1416 InlinePrefWidthData *aData) = 0;
1419 * Return the horizontal components of padding, border, and margin
1420 * that contribute to the intrinsic width that applies to the parent.
1422 struct IntrinsicWidthOffsetData {
1423 nscoord hPadding, hBorder, hMargin;
1424 float hPctPadding, hPctMargin;
1426 IntrinsicWidthOffsetData()
1427 : hPadding(0), hBorder(0), hMargin(0)
1428 , hPctPadding(0.0f), hPctMargin(0.0f)
1431 virtual IntrinsicWidthOffsetData
1432 IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext) = 0;
1435 * For replaced elements only. Gets the intrinsic dimensions of this element.
1436 * The dimensions may only be one of the following three types:
1438 * eStyleUnit_Coord - a length in app units
1439 * eStyleUnit_Percent - a percentage of the available space
1440 * eStyleUnit_None - the element has no intrinsic size in this dimension
1442 struct IntrinsicSize {
1443 nsStyleCoord width, height;
1445 IntrinsicSize()
1446 : width(eStyleUnit_None), height(eStyleUnit_None)
1448 IntrinsicSize(const IntrinsicSize& rhs)
1449 : width(rhs.width), height(rhs.height)
1451 IntrinsicSize& operator=(const IntrinsicSize& rhs) {
1452 width = rhs.width; height = rhs.height; return *this;
1455 virtual IntrinsicSize GetIntrinsicSize() = 0;
1458 * Get the intrinsic ratio of this element, or nsSize(0,0) if it has
1459 * no intrinsic ratio. The intrinsic ratio is the ratio of the
1460 * height/width of a box with an intrinsic size or the intrinsic
1461 * aspect ratio of a scalable vector image without an intrinsic size.
1463 * Either one of the sides may be zero, indicating a zero or infinite
1464 * ratio.
1466 virtual nsSize GetIntrinsicRatio() = 0;
1469 * Compute the size that a frame will occupy. Called while
1470 * constructing the nsHTMLReflowState to be used to Reflow the frame,
1471 * in order to fill its mComputedWidth and mComputedHeight member
1472 * variables.
1474 * The |height| member of the return value may be
1475 * NS_UNCONSTRAINEDSIZE, but the |width| member must not be.
1477 * Note that the reason that border and padding need to be passed
1478 * separately is so that the 'box-sizing' property can be handled.
1479 * Thus aMargin includes absolute positioning offsets as well.
1481 * @param aCBSize The size of the element's containing block. (Well,
1482 * the |height| component isn't really.)
1483 * @param aAvailableWidth The available width for 'auto' widths.
1484 * This is usually the same as aCBSize.width,
1485 * but differs in cases such as block
1486 * formatting context roots next to floats, or
1487 * in some cases of float reflow in quirks
1488 * mode.
1489 * @param aMargin The sum of the vertical / horizontal margins
1490 * ***AND*** absolute positioning offsets (top, right,
1491 * bottom, left) of the frame, including actual values
1492 * resulting from percentages and from the
1493 * "hypothetical box" for absolute positioning, but
1494 * not including actual values resulting from 'auto'
1495 * margins or ignored 'auto' values in absolute
1496 * positioning.
1497 * @param aBorder The sum of the vertical / horizontal border widths
1498 * of the frame.
1499 * @param aPadding The sum of the vertical / horizontal margins of
1500 * the frame, including actual values resulting from
1501 * percentages.
1502 * @param aShrinkWrap Whether the frame is in a context where
1503 * non-replaced blocks should shrink-wrap (e.g.,
1504 * it's floating, absolutely positioned, or
1505 * inline-block).
1507 virtual nsSize ComputeSize(nsIRenderingContext *aRenderingContext,
1508 nsSize aCBSize, nscoord aAvailableWidth,
1509 nsSize aMargin, nsSize aBorder, nsSize aPadding,
1510 PRBool aShrinkWrap) = 0;
1513 * Compute a tight bounding rectangle for the frame. This is a rectangle
1514 * that encloses the pixels that are actually drawn. We're allowed to be
1515 * conservative and currently we don't try very hard. The rectangle is
1516 * in appunits and relative to the origin of this frame.
1517 * @param aContext a rendering context that can be used if we need
1518 * to do measurement
1520 virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
1523 * Pre-reflow hook. Before a frame is reflowed this method will be called.
1524 * This call will always be invoked at least once before a subsequent Reflow
1525 * and DidReflow call. It may be called more than once, In general you will
1526 * receive on WillReflow notification before each Reflow request.
1528 * XXX Is this really the semantics we want? Because we have the NS_FRAME_IN_REFLOW
1529 * bit we can ensure we don't call it more than once...
1531 NS_IMETHOD WillReflow(nsPresContext* aPresContext) = 0;
1534 * The frame is given an available size and asked for its desired
1535 * size. This is the frame's opportunity to reflow its children.
1537 * If the frame has the NS_FRAME_IS_DIRTY bit set then it is
1538 * responsible for completely reflowing itself and all of its
1539 * descendants.
1541 * Otherwise, if the frame has the NS_FRAME_HAS_DIRTY_CHILDREN bit
1542 * set, then it is responsible for reflowing at least those
1543 * children that have NS_FRAME_HAS_DIRTY_CHILDREN or NS_FRAME_IS_DIRTY
1544 * set.
1546 * If a difference in available size from the previous reflow causes
1547 * the frame's size to change, it should reflow descendants as needed.
1549 * @param aReflowMetrics <i>out</i> parameter where you should return the
1550 * desired size and ascent/descent info. You should include any
1551 * space you want for border/padding in the desired size you return.
1553 * It's okay to return a desired size that exceeds the avail
1554 * size if that's the smallest you can be, i.e. it's your
1555 * minimum size.
1557 * For an incremental reflow you are responsible for invalidating
1558 * any area within your frame that needs repainting (including
1559 * borders). If your new desired size is different than your current
1560 * size, then your parent frame is responsible for making sure that
1561 * the difference between the two rects is repainted
1563 * @param aReflowState information about your reflow including the reason
1564 * for the reflow and the available space in which to lay out. Each
1565 * dimension of the available space can either be constrained or
1566 * unconstrained (a value of NS_UNCONSTRAINEDSIZE).
1568 * Note that the available space can be negative. In this case you
1569 * still must return an accurate desired size. If you're a container
1570 * you must <b>always</b> reflow at least one frame regardless of the
1571 * available space
1573 * @param aStatus a return value indicating whether the frame is complete
1574 * and whether the next-in-flow is dirty and needs to be reflowed
1576 NS_IMETHOD Reflow(nsPresContext* aPresContext,
1577 nsHTMLReflowMetrics& aReflowMetrics,
1578 const nsHTMLReflowState& aReflowState,
1579 nsReflowStatus& aStatus) = 0;
1582 * Post-reflow hook. After a frame is reflowed this method will be called
1583 * informing the frame that this reflow process is complete, and telling the
1584 * frame the status returned by the Reflow member function.
1586 * This call may be invoked many times, while NS_FRAME_IN_REFLOW is set, before
1587 * it is finally called once with a NS_FRAME_REFLOW_COMPLETE value. When called
1588 * with a NS_FRAME_REFLOW_COMPLETE value the NS_FRAME_IN_REFLOW bit in the
1589 * frame state will be cleared.
1591 * XXX This doesn't make sense. If the frame is reflowed but not complete, then
1592 * the status should be NS_FRAME_NOT_COMPLETE and not NS_FRAME_COMPLETE
1593 * XXX Don't we want the semantics to dictate that we only call this once for
1594 * a given reflow?
1596 NS_IMETHOD DidReflow(nsPresContext* aPresContext,
1597 const nsHTMLReflowState* aReflowState,
1598 nsDidReflowStatus aStatus) = 0;
1600 // XXX Maybe these three should be a separate interface?
1603 * Helper method used by block reflow to identify runs of text so
1604 * that proper word-breaking can be done.
1606 * @return
1607 * PR_TRUE if we can continue a "text run" through the frame. A
1608 * text run is text that should be treated contiguously for line
1609 * and word breaking.
1611 virtual PRBool CanContinueTextRun() const = 0;
1614 * Append the rendered text to the passed-in string.
1615 * The appended text will often not contain all the whitespace from source,
1616 * depending on whether the CSS rule "white-space: pre" is active for this frame.
1617 * if aStartOffset + aLength goes past end, or if aLength is not specified
1618 * then use the text up to the string's end.
1619 * Call this on the primary frame for a text node.
1620 * @param aAppendToString String to append text to, or null if text should not be returned
1621 * @param aSkipChars if aSkipIter is non-null, this must also be non-null.
1622 * This gets used as backing data for the iterator so it should outlive the iterator.
1623 * @param aSkipIter Where to fill in the gfxSkipCharsIterator info, or null if not needed by caller
1624 * @param aStartOffset Skipped (rendered text) start offset
1625 * @param aSkippedMaxLength Maximum number of characters to return
1626 * The iterator can be used to map content offsets to offsets in the returned string, or vice versa.
1628 virtual nsresult GetRenderedText(nsAString* aAppendToString = nsnull,
1629 gfxSkipChars* aSkipChars = nsnull,
1630 gfxSkipCharsIterator* aSkipIter = nsnull,
1631 PRUint32 aSkippedStartOffset = 0,
1632 PRUint32 aSkippedMaxLength = PR_UINT32_MAX)
1633 { return NS_ERROR_NOT_IMPLEMENTED; }
1636 * Accessor functions to get/set the associated view object
1638 * GetView returns non-null if and only if |HasView| returns true.
1640 PRBool HasView() const { return !!(mState & NS_FRAME_HAS_VIEW); }
1641 nsIView* GetView() const;
1642 virtual nsIView* GetViewExternal() const;
1643 nsresult SetView(nsIView* aView);
1646 * Find the closest view (on |this| or an ancestor).
1647 * If aOffset is non-null, it will be set to the offset of |this|
1648 * from the returned view.
1650 nsIView* GetClosestView(nsPoint* aOffset = nsnull) const;
1653 * Find the closest ancestor (excluding |this| !) that has a view
1655 nsIFrame* GetAncestorWithView() const;
1656 virtual nsIFrame* GetAncestorWithViewExternal() const;
1659 * Get the offset between the coordinate systems of |this| and aOther.
1660 * Adding the return value to a point in the coordinate system of |this|
1661 * will transform the point to the coordinate system of aOther.
1663 * aOther must be non-null.
1665 * This function is fastest when aOther is an ancestor of |this|.
1667 * This function _DOES NOT_ work across document boundaries.
1668 * Use this function only when |this| and aOther are in the same document.
1670 * NOTE: this actually returns the offset from aOther to |this|, but
1671 * that offset is added to transform _coordinates_ from |this| to
1672 * aOther.
1674 nsPoint GetOffsetTo(const nsIFrame* aOther) const;
1675 virtual nsPoint GetOffsetToExternal(const nsIFrame* aOther) const;
1678 * Get the offset between the coordinate systems of |this| and aOther
1679 * expressed in appunits per dev pixel of |this|' document. Adding the return
1680 * value to a point that is relative to the origin of |this| will make the
1681 * point relative to the origin of aOther but in the appunits per dev pixel
1682 * ratio of |this|.
1684 * aOther must be non-null.
1686 * This function is fastest when aOther is an ancestor of |this|.
1688 * This function works across document boundaries.
1690 * Because this function may cross document boundaries that have different
1691 * app units per dev pixel ratios it needs to be used very carefully.
1693 * NOTE: this actually returns the offset from aOther to |this|, but
1694 * that offset is added to transform _coordinates_ from |this| to
1695 * aOther.
1697 nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther) const;
1700 * Get the screen rect of the frame in pixels.
1701 * @return the pixel rect of the frame in screen coordinates.
1703 nsIntRect GetScreenRect() const;
1704 virtual nsIntRect GetScreenRectExternal() const;
1707 * Get the screen rect of the frame in app units.
1708 * @return the app unit rect of the frame in screen coordinates.
1710 nsRect GetScreenRectInAppUnits() const;
1711 virtual nsRect GetScreenRectInAppUnitsExternal() const;
1714 * Returns the offset from this frame to the closest geometric parent that
1715 * has a view. Also returns the containing view or null in case of error
1717 NS_IMETHOD GetOffsetFromView(nsPoint& aOffset,
1718 nsIView** aView) const = 0;
1721 * Returns true if and only if all views, from |GetClosestView| up to
1722 * the top of the view hierarchy are visible.
1724 virtual PRBool AreAncestorViewsVisible() const;
1727 * Returns the nearest widget containing this frame. If this frame has a
1728 * view and the view has a widget, then this frame's widget is
1729 * returned, otherwise this frame's geometric parent is checked
1730 * recursively upwards.
1731 * XXX virtual because gfx callers use it! (themes)
1733 virtual nsIWidget* GetNearestWidget() const;
1736 * Same as GetNearestWidget() above but uses an outparam to return the offset
1737 * of this frame to the returned widget expressed in appunits of |this| (the
1738 * widget might be in a different document with a different zoom).
1740 virtual nsIWidget* GetNearestWidget(nsPoint& aOffset) const;
1743 * Get the "type" of the frame. May return a NULL atom pointer
1745 * @see nsGkAtoms
1747 virtual nsIAtom* GetType() const = 0;
1750 * Returns a transformation matrix that converts points in this frame's coordinate space
1751 * to points in some ancestor frame's coordinate space. The frame decides which ancestor
1752 * it will use as a reference point. If this frame has no ancestor, aOutAncestor will be
1753 * set to null.
1755 * @param aOutAncestor [out] The ancestor frame the frame has chosen. If this frame has no
1756 * ancestor, aOutAncestor will be nsnull.
1757 * @return A gfxMatrix that converts points in this frame's coordinate space into
1758 * points in aOutAncestor's coordinate space.
1760 virtual gfxMatrix GetTransformMatrix(nsIFrame **aOutAncestor);
1763 * Bit-flags to pass to IsFrameOfType()
1765 enum {
1766 eMathML = 1 << 0,
1767 eSVG = 1 << 1,
1768 eSVGForeignObject = 1 << 2,
1769 eSVGContainer = 1 << 3,
1770 eSVGGeometry = 1 << 4,
1771 eSVGPaintServer = 1 << 5,
1772 eBidiInlineContainer = 1 << 6,
1773 // the frame is for a replaced element, such as an image
1774 eReplaced = 1 << 7,
1775 // Frame that contains a block but looks like a replaced element
1776 // from the outside
1777 eReplacedContainsBlock = 1 << 8,
1778 // A frame that participates in inline reflow, i.e., one that
1779 // requires nsHTMLReflowState::mLineLayout.
1780 eLineParticipant = 1 << 9,
1781 eXULBox = 1 << 10,
1782 eCanContainOverflowContainers = 1 << 11,
1783 eBlockFrame = 1 << 12,
1784 // If this bit is set, the frame doesn't allow ignorable whitespace as
1785 // children. For example, the whitespace between <table>\n<tr>\n<td>
1786 // will be excluded during the construction of children.
1787 eExcludesIgnorableWhitespace = 1 << 13,
1789 // These are to allow nsFrame::Init to assert that IsFrameOfType
1790 // implementations all call the base class method. They are only
1791 // meaningful in DEBUG builds.
1792 eDEBUGAllFrames = 1 << 30,
1793 eDEBUGNoFrames = 1 << 31
1797 * API for doing a quick check if a frame is of a given
1798 * type. Returns true if the frame matches ALL flags passed in.
1800 * Implementations should always override with inline virtual
1801 * functions that call the base class's IsFrameOfType method.
1803 virtual PRBool IsFrameOfType(PRUint32 aFlags) const
1805 #ifdef DEBUG
1806 return !(aFlags & ~(nsIFrame::eDEBUGAllFrames));
1807 #else
1808 return !aFlags;
1809 #endif
1813 * Is this frame a containing block for non-positioned elements?
1815 virtual PRBool IsContainingBlock() const = 0;
1818 * Is this frame a containing block for floating elements?
1819 * Note that very few frames are, so default to false.
1821 virtual PRBool IsFloatContainingBlock() const { return PR_FALSE; }
1824 * Is this a leaf frame? Frames that want the frame constructor to be able
1825 * to construct kids for them should return false, all others should return
1826 * true. Note that returning true here does not mean that the frame _can't_
1827 * have kids. It could still have kids created via
1828 * nsIAnonymousContentCreator. Returning true indicates that "normal"
1829 * (non-anonymous, XBL-bound, CSS generated content, etc) children should not
1830 * be constructed.
1832 virtual PRBool IsLeaf() const;
1835 * This must only be called on frames that are display roots (see
1836 * nsLayoutUtils::GetDisplayRootFrame). This causes all invalidates
1837 * reaching this frame to be performed asynchronously off an event,
1838 * instead of being applied to the widget immediately. Also,
1839 * invalidation of areas in aExcludeRegion is ignored completely
1840 * for invalidates with INVALIDATE_EXCLUDE_CURRENT_PAINT specified.
1841 * These can't be nested; two invocations of
1842 * BeginDeferringInvalidatesForDisplayRoot for a frame must have a
1843 * EndDeferringInvalidatesForDisplayRoot between them.
1845 void BeginDeferringInvalidatesForDisplayRoot(const nsRegion& aExcludeRegion);
1848 * Cancel the most recent BeginDeferringInvalidatesForDisplayRoot.
1850 void EndDeferringInvalidatesForDisplayRoot();
1853 * Mark this frame as using active layers. This marking will time out
1854 * after a short period. This call does no immediate invalidation,
1855 * but when the mark times out, we'll invalidate the frame's overflow
1856 * area.
1858 void MarkLayersActive();
1861 * Return true if this frame is marked as needing active layers.
1863 PRBool AreLayersMarkedActive();
1866 * @param aFlags see InvalidateInternal below
1868 void InvalidateWithFlags(const nsRect& aDamageRect, PRUint32 aFlags);
1871 * Invalidate part of the frame by asking the view manager to repaint.
1872 * aDamageRect is allowed to extend outside the frame's bounds. We'll do the right
1873 * thing.
1874 * We deliberately don't have an Invalidate() method that defaults to the frame's bounds.
1875 * We want all callers to *think* about what has changed in the frame and what area might
1876 * need to be repainted.
1878 * @param aDamageRect is in the frame's local coordinate space
1880 void Invalidate(const nsRect& aDamageRect)
1881 { return InvalidateWithFlags(aDamageRect, 0); }
1884 * As Invalidate above, except that this should be called when the
1885 * rendering that has changed is performed using layers so we can avoid
1886 * updating the contents of ThebesLayers.
1887 * @param aDisplayItemKey must not be zero; indicates the kind of display
1888 * item that is being invalidated.
1890 void InvalidateLayer(const nsRect& aDamageRect, PRUint32 aDisplayItemKey);
1893 * Helper function that can be overridden by frame classes. The rectangle
1894 * (plus aOffsetX/aOffsetY) is relative to this frame.
1896 * The offset is given as two coords rather than as an nsPoint because
1897 * gcc optimizes it better that way, in particular in the default
1898 * implementation that passes the area to the parent frame becomes a tail
1899 * call.
1901 * The default implementation will crash if the frame has no parent so
1902 * frames without parents MUST* override.
1904 * @param aForChild if the invalidation is coming from a child frame, this
1905 * is the frame; otherwise, this is null.
1906 * @param aFlags INVALIDATE_IMMEDIATE: repaint now if true, repaint later if false.
1907 * In case it's true, pending notifications will be flushed which
1908 * could cause frames to be deleted (including |this|).
1909 * @param aFlags INVALIDATE_CROSS_DOC: true if the invalidation
1910 * originated in a subdocument
1911 * @param aFlags INVALIDATE_REASON_SCROLL_BLIT: set if the invalidation
1912 * was really just the scroll machinery copying pixels from one
1913 * part of the window to another
1914 * @param aFlags INVALIDATE_REASON_SCROLL_REPAINT: set if the invalidation
1915 * was triggered by scrolling
1916 * @param aFlags INVALIDATE_NO_THEBES_LAYERS: don't invalidate the
1917 * ThebesLayers of any container layer owned by an ancestor. Set this
1918 * only if ThebesLayers definitely don't need to be updated.
1919 * @param aFlags INVALIDATE_EXCLUDE_CURRENT_PAINT: if the invalidation
1920 * occurs while we're painting (to be precise, while
1921 * BeginDeferringInvalidatesForDisplayRoot is active on the display root),
1922 * then invalidation in the current paint region is simply discarded.
1923 * Use this flag if areas that are being painted do not need
1924 * to be invalidated. By default, when this flag is not specified,
1925 * areas that are invalidated while currently being painted will be repainted
1926 * again.
1927 * This flag is useful when, during painting, FrameLayerBuilder discovers that
1928 * a region of the window needs to be drawn differently, and that region
1929 * may or may not be contained in the currently painted region.
1931 enum {
1932 INVALIDATE_IMMEDIATE = 0x01,
1933 INVALIDATE_CROSS_DOC = 0x02,
1934 INVALIDATE_REASON_SCROLL_BLIT = 0x04,
1935 INVALIDATE_REASON_SCROLL_REPAINT = 0x08,
1936 INVALIDATE_REASON_MASK = INVALIDATE_REASON_SCROLL_BLIT |
1937 INVALIDATE_REASON_SCROLL_REPAINT,
1938 INVALIDATE_NO_THEBES_LAYERS = 0x10,
1939 INVALIDATE_EXCLUDE_CURRENT_PAINT = 0x20
1941 virtual void InvalidateInternal(const nsRect& aDamageRect,
1942 nscoord aOffsetX, nscoord aOffsetY,
1943 nsIFrame* aForChild, PRUint32 aFlags);
1946 * Helper function that funnels an InvalidateInternal request up to the
1947 * parent. This function is used so that if MOZ_SVG is not defined, we still
1948 * have unified control paths in the InvalidateInternal chain.
1950 * @param aDamageRect The rect to invalidate.
1951 * @param aX The x offset from the origin of this frame to the rectangle.
1952 * @param aY The y offset from the origin of this frame to the rectangle.
1953 * @param aImmediate Whether to redraw immediately.
1954 * @return None, though this funnels the request up to the parent frame.
1956 void InvalidateInternalAfterResize(const nsRect& aDamageRect, nscoord aX,
1957 nscoord aY, PRUint32 aFlags);
1960 * Take two rectangles in the coordinate system of this frame which
1961 * have the same origin and invalidate the difference between them.
1962 * This is a helper method to be used when a frame is being resized.
1964 * @param aR1 the first rectangle
1965 * @param aR2 the second rectangle
1967 void InvalidateRectDifference(const nsRect& aR1, const nsRect& aR2);
1970 * Invalidate the overflow rect of this frame
1972 void InvalidateOverflowRect();
1975 * Computes a rect that encompasses everything that might be painted by
1976 * this frame. This includes this frame, all its descendent frames, this
1977 * frame's outline, and descentant frames' outline, but does not include
1978 * areas clipped out by the CSS "overflow" and "clip" properties.
1980 * HasOverflowRect() (below) will return PR_TRUE when this overflow rect
1981 * has been explicitly set, even if it matches mRect.
1982 * XXX Note: because of a space optimization using the formula above,
1983 * during reflow this function does not give accurate data if
1984 * FinishAndStoreOverflow has been called but mRect hasn't yet been
1985 * updated yet.
1987 * @return the rect relative to this frame's origin, but after
1988 * CSS transforms have been applied (i.e. not really this frame's coordinate
1989 * system, and may not contain the frame's border-box, e.g. if there
1990 * is a CSS transform scaling it down)
1992 nsRect GetOverflowRect() const;
1995 * Computes a rect that encompasses everything that might be painted by
1996 * this frame. This includes this frame, all its descendent frames, this
1997 * frame's outline, and descentant frames' outline, but does not include
1998 * areas clipped out by the CSS "overflow" and "clip" properties.
2000 * HasOverflowRect() (below) will return PR_TRUE when this overflow rect
2001 * is different from nsRect(0, 0, GetRect().width, GetRect().height).
2002 * XXX Note: because of a space optimization using the formula above,
2003 * during reflow this function does not give accurate data if
2004 * FinishAndStoreOverflow has been called but mRect hasn't yet been
2005 * updated yet.
2007 * @return the rect relative to the parent frame, in the parent frame's
2008 * coordinate system
2010 nsRect GetOverflowRectRelativeToParent() const;
2013 * Computes a rect that encompasses everything that might be painted by
2014 * this frame. This includes this frame, all its descendent frames, this
2015 * frame's outline, and descentant frames' outline, but does not include
2016 * areas clipped out by the CSS "overflow" and "clip" properties.
2018 * @return the rect relative to this frame, before any CSS transforms have
2019 * been applied, i.e. in this frame's coordinate system
2021 nsRect GetOverflowRectRelativeToSelf() const;
2024 * Store the overflow area in the frame's mOverflow.mDeltas fields or
2025 * as a frame property in the frame manager so that it can be retrieved
2026 * later without reflowing the frame.
2028 void FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize);
2030 void FinishAndStoreOverflow(nsHTMLReflowMetrics* aMetrics) {
2031 FinishAndStoreOverflow(&aMetrics->mOverflowArea, nsSize(aMetrics->width, aMetrics->height));
2035 * Returns whether the frame has an overflow rect that is different from
2036 * its border-box.
2038 PRBool HasOverflowRect() const {
2039 return mOverflow.mType != NS_FRAME_OVERFLOW_NONE;
2043 * Removes any stored overflow rect from the frame.
2045 void ClearOverflowRect();
2048 * Determine whether borders should not be painted on certain sides of the
2049 * frame.
2051 virtual PRIntn GetSkipSides() const { return 0; }
2053 /** Selection related calls
2055 /**
2056 * Called to set the selection status of the frame.
2058 * This must be called on the primary frame, but all continuations
2059 * will be affected the same way.
2061 * This sets or clears NS_FRAME_SELECTED_CONTENT for each frame in the
2062 * continuation chain, if the frames are currently selectable.
2063 * The frames are unconditionally invalidated, if this selection type
2064 * is supported at all.
2065 * @param aSelected is it selected?
2066 * @param aType the selection type of the selection that you are setting on the frame
2068 virtual void SetSelected(PRBool aSelected,
2069 SelectionType aType);
2071 NS_IMETHOD GetSelected(PRBool *aSelected) const = 0;
2074 * called to discover where this frame, or a parent frame has user-select style
2075 * applied, which affects that way that it is selected.
2077 * @param aIsSelectable out param. Set to true if the frame can be selected
2078 * (i.e. is not affected by user-select: none)
2079 * @param aSelectStyle out param. Returns the type of selection style found
2080 * (using values defined in nsStyleConsts.h).
2082 NS_IMETHOD IsSelectable(PRBool* aIsSelectable, PRUint8* aSelectStyle) const = 0;
2084 /**
2085 * Called to retrieve the SelectionController associated with the frame.
2086 * @param aSelCon will contain the selection controller associated with
2087 * the frame.
2089 NS_IMETHOD GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon) = 0;
2092 * Call to get nsFrameSelection for this frame.
2094 already_AddRefed<nsFrameSelection> GetFrameSelection();
2097 * GetConstFrameSelection returns an object which methods are safe to use for
2098 * example in nsIFrame code.
2100 const nsFrameSelection* GetConstFrameSelection();
2102 /** EndSelection related calls
2106 * called to find the previous/next character, word, or line returns the actual
2107 * nsIFrame and the frame offset. THIS DOES NOT CHANGE SELECTION STATE
2108 * uses frame's begin selection state to start. if no selection on this frame will
2109 * return NS_ERROR_FAILURE
2110 * @param aPOS is defined in nsFrameSelection
2112 NS_IMETHOD PeekOffset(nsPeekOffsetStruct *aPos);
2115 * called to find the previous/next selectable leaf frame.
2116 * @param aDirection [in] the direction to move in (eDirPrevious or eDirNext)
2117 * @param aVisual [in] whether bidi caret behavior is visual (PR_TRUE) or logical (PR_FALSE)
2118 * @param aJumpLines [in] whether to allow jumping across line boundaries
2119 * @param aScrollViewStop [in] whether to stop when reaching a scroll frame boundary
2120 * @param aOutFrame [out] the previous/next selectable leaf frame
2121 * @param aOutOffset [out] 0 indicates that we arrived at the beginning of the output frame;
2122 * -1 indicates that we arrived at its end.
2123 * @param aOutJumpedLine [out] whether this frame and the returned frame are on different lines
2125 nsresult GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
2126 PRBool aJumpLines, PRBool aScrollViewStop,
2127 nsIFrame** aOutFrame, PRInt32* aOutOffset, PRBool* aOutJumpedLine);
2130 * called to see if the children of the frame are visible from indexstart to index end.
2131 * this does not change any state. returns PR_TRUE only if the indexes are valid and any of
2132 * the children are visible. for textframes this index is the character index.
2133 * if aStart = aEnd result will be PR_FALSE
2134 * @param aStart start index of first child from 0-N (number of children)
2135 * @param aEnd end index of last child from 0-N
2136 * @param aRecurse should this frame talk to siblings to get to the contents other children?
2137 * @param aFinished did this frame have the aEndIndex? or is there more work to do
2138 * @param _retval return value true or false. false = range is not rendered.
2140 NS_IMETHOD CheckVisibility(nsPresContext* aContext, PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aRecurse, PRBool *aFinished, PRBool *_retval)=0;
2143 * Called to tell a frame that one of its child frames is dirty (i.e.,
2144 * has the NS_FRAME_IS_DIRTY *or* NS_FRAME_HAS_DIRTY_CHILDREN bit
2145 * set). This should always set the NS_FRAME_HAS_DIRTY_CHILDREN on
2146 * the frame, and may do other work.
2148 virtual void ChildIsDirty(nsIFrame* aChild) = 0;
2151 * Called to retrieve this frame's accessible.
2152 * If this frame implements Accessibility return a valid accessible
2153 * If not return NS_ERROR_NOT_IMPLEMENTED.
2154 * Note: nsAccessible must be refcountable. Do not implement directly on your frame
2155 * Use a mediatior of some kind.
2157 #ifdef ACCESSIBILITY
2158 virtual already_AddRefed<nsAccessible> CreateAccessible() = 0;
2159 #endif
2162 * Get the frame whose style context should be the parent of this
2163 * frame's style context (i.e., provide the parent style context).
2164 * This frame must either be an ancestor of this frame or a child. If
2165 * this frame returns a child frame, then the child frame must be sure
2166 * to return a grandparent or higher!
2168 * @param aPresContext: PresContext
2169 * @param aProviderFrame: The frame whose style context should be the
2170 * parent of this frame's style context. Null
2171 * is permitted, and means that this frame's
2172 * style context should be the root of the
2173 * style context tree.
2174 * @param aIsChild: True if |aProviderFrame| is set to a child
2175 * of this frame; false if it is an ancestor or
2176 * null.
2178 NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext,
2179 nsIFrame** aProviderFrame,
2180 PRBool* aIsChild) = 0;
2183 * Determines whether a frame is visible for painting;
2184 * taking into account whether it is painting a selection or printing.
2186 PRBool IsVisibleForPainting(nsDisplayListBuilder* aBuilder);
2188 * Determines whether a frame is visible for painting or collapsed;
2189 * taking into account whether it is painting a selection or printing,
2191 PRBool IsVisibleOrCollapsedForPainting(nsDisplayListBuilder* aBuilder);
2193 * As above, but slower because we have to recompute some stuff that
2194 * aBuilder already has.
2196 PRBool IsVisibleForPainting();
2198 * Check whether this frame is visible in the current selection. Returns
2199 * PR_TRUE if there is no current selection.
2201 PRBool IsVisibleInSelection(nsDisplayListBuilder* aBuilder);
2204 * Overridable function to determine whether this frame should be considered
2205 * "in" the given non-null aSelection for visibility purposes.
2207 virtual PRBool IsVisibleInSelection(nsISelection* aSelection);
2210 * Determines whether this frame is a pseudo stacking context, looking
2211 * only as style --- i.e., assuming that it's in-flow and not a replaced
2212 * element.
2214 PRBool IsPseudoStackingContextFromStyle() {
2215 const nsStyleDisplay* disp = GetStyleDisplay();
2216 return disp->mOpacity != 1.0f || disp->IsPositioned() || disp->IsFloating();
2219 virtual PRBool HonorPrintBackgroundSettings() { return PR_TRUE; }
2222 * Determine whether the frame is logically empty, which is roughly
2223 * whether the layout would be the same whether or not the frame is
2224 * present. Placeholder frames should return true. Block frames
2225 * should be considered empty whenever margins collapse through them,
2226 * even though those margins are relevant. Text frames containing
2227 * only whitespace that does not contribute to the height of the line
2228 * should return true.
2230 virtual PRBool IsEmpty() = 0;
2232 * Return the same as IsEmpty(). This may only be called after the frame
2233 * has been reflowed and before any further style or content changes.
2235 virtual PRBool CachedIsEmpty();
2237 * Determine whether the frame is logically empty, assuming that all
2238 * its children are empty.
2240 virtual PRBool IsSelfEmpty() = 0;
2243 * IsGeneratedContentFrame returns whether a frame corresponds to
2244 * generated content
2246 * @return whether the frame correspods to generated content
2248 PRBool IsGeneratedContentFrame() {
2249 return (mState & NS_FRAME_GENERATED_CONTENT) != 0;
2253 * IsPseudoFrame returns whether a frame is a pseudo frame (eg an
2254 * anonymous table-row frame created for a CSS table-cell without an
2255 * enclosing table-row.
2257 * @param aParentContent the content node corresponding to the parent frame
2258 * @return whether the frame is a pseudo frame
2260 PRBool IsPseudoFrame(nsIContent* aParentContent) {
2261 return mContent == aParentContent;
2264 FrameProperties Properties() const {
2265 return FrameProperties(PresContext()->PropertyTable(), this);
2268 NS_DECLARE_FRAME_PROPERTY(BaseLevelProperty, nsnull)
2269 NS_DECLARE_FRAME_PROPERTY(EmbeddingLevelProperty, nsnull)
2271 #define NS_GET_BASE_LEVEL(frame) \
2272 NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::BaseLevelProperty()))
2274 #define NS_GET_EMBEDDING_LEVEL(frame) \
2275 NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::EmbeddingLevelProperty()))
2278 * Return PR_TRUE if and only if this frame obeys visibility:hidden.
2279 * if it does not, then nsContainerFrame will hide its view even though
2280 * this means children can't be made visible again.
2282 virtual PRBool SupportsVisibilityHidden() { return PR_TRUE; }
2285 * Returns PR_TRUE if the frame is absolutely positioned and has a clip
2286 * rect set via the 'clip' property. If true, then we also set aRect
2287 * to the computed clip rect coordinates relative to this frame's origin.
2288 * aRect must not be null!
2290 PRBool GetAbsPosClipRect(const nsStyleDisplay* aDisp, nsRect* aRect,
2291 const nsSize& aSize);
2294 * Check if this frame is focusable and in the current tab order.
2295 * Tabbable is indicated by a nonnegative tabindex & is a subset of focusable.
2296 * For example, only the selected radio button in a group is in the
2297 * tab order, unless the radio group has no selection in which case
2298 * all of the visible, non-disabled radio buttons in the group are
2299 * in the tab order. On the other hand, all of the visible, non-disabled
2300 * radio buttons are always focusable via clicking or script.
2301 * Also, depending on the pref accessibility.tabfocus some widgets may be
2302 * focusable but removed from the tab order. This is the default on
2303 * Mac OS X, where fewer items are focusable.
2304 * @param [in, optional] aTabIndex the computed tab index
2305 * < 0 if not tabbable
2306 * == 0 if in normal tab order
2307 * > 0 can be tabbed to in the order specified by this value
2308 * @param [in, optional] aWithMouse, is this focus query for mouse clicking
2309 * @return whether the frame is focusable via mouse, kbd or script.
2311 virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull, PRBool aWithMouse = PR_FALSE);
2313 // BOX LAYOUT METHODS
2314 // These methods have been migrated from nsIBox and are in the process of
2315 // being refactored. DO NOT USE OUTSIDE OF XUL.
2316 PRBool IsBoxFrame() const
2318 return IsFrameOfType(nsIFrame::eXULBox);
2320 PRBool IsBoxWrapped() const
2321 { return (!IsBoxFrame() && mParent && mParent->IsBoxFrame()); }
2323 enum Halignment {
2324 hAlign_Left,
2325 hAlign_Right,
2326 hAlign_Center
2329 enum Valignment {
2330 vAlign_Top,
2331 vAlign_Middle,
2332 vAlign_BaseLine,
2333 vAlign_Bottom
2337 * This calculates the minimum size required for a box based on its state
2338 * @param[in] aBoxLayoutState The desired state to calculate for
2339 * @return The minimum size
2341 virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) = 0;
2344 * This calculates the preferred size of a box based on its state
2345 * @param[in] aBoxLayoutState The desired state to calculate for
2346 * @return The preferred size
2348 virtual nsSize GetPrefSize(nsBoxLayoutState& aBoxLayoutState) = 0;
2351 * This calculates the maximum size for a box based on its state
2352 * @param[in] aBoxLayoutState The desired state to calculate for
2353 * @return The maximum size
2355 virtual nsSize GetMaxSize(nsBoxLayoutState& aBoxLayoutState) = 0;
2358 * This returns the minimum size for the scroll area if this frame is
2359 * being scrolled. Usually it's (0,0).
2361 virtual nsSize GetMinSizeForScrollArea(nsBoxLayoutState& aBoxLayoutState) = 0;
2363 // Implemented in nsBox, used in nsBoxFrame
2364 PRUint32 GetOrdinal(nsBoxLayoutState& aBoxLayoutState);
2366 virtual nscoord GetFlex(nsBoxLayoutState& aBoxLayoutState) = 0;
2367 virtual nscoord GetBoxAscent(nsBoxLayoutState& aBoxLayoutState) = 0;
2368 virtual PRBool IsCollapsed(nsBoxLayoutState& aBoxLayoutState) = 0;
2369 // This does not alter the overflow area. If the caller is changing
2370 // the box size, the caller is responsible for updating the overflow
2371 // area. It's enough to just call Layout or SyncLayout on the
2372 // box. You can pass PR_TRUE to aRemoveOverflowArea as a
2373 // convenience.
2374 virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
2375 PRBool aRemoveOverflowArea = PR_FALSE)=0;
2376 NS_HIDDEN_(nsresult) Layout(nsBoxLayoutState& aBoxLayoutState);
2377 nsIBox* GetChildBox() const
2379 // box layout ends at box-wrapped frames, so don't allow these frames
2380 // to report child boxes.
2381 return IsBoxFrame() ? GetFirstChild(nsnull) : nsnull;
2383 nsIBox* GetNextBox() const
2385 return (mParent && mParent->IsBoxFrame()) ? mNextSibling : nsnull;
2387 nsIBox* GetParentBox() const
2389 return (mParent && mParent->IsBoxFrame()) ? mParent : nsnull;
2391 // Box methods. Note that these do NOT just get the CSS border, padding,
2392 // etc. They also talk to nsITheme.
2393 NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding);
2394 NS_IMETHOD GetBorder(nsMargin& aBorder)=0;
2395 NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding)=0;
2396 NS_IMETHOD GetMargin(nsMargin& aMargin)=0;
2397 NS_IMETHOD SetLayoutManager(nsIBoxLayout* aLayout)=0;
2398 NS_IMETHOD GetLayoutManager(nsIBoxLayout** aLayout)=0;
2399 NS_HIDDEN_(nsresult) GetClientRect(nsRect& aContentRect);
2401 // For nsSprocketLayout
2402 virtual Valignment GetVAlign() const = 0;
2403 virtual Halignment GetHAlign() const = 0;
2405 PRBool IsHorizontal() const { return (mState & NS_STATE_IS_HORIZONTAL) != 0; }
2406 PRBool IsNormalDirection() const { return (mState & NS_STATE_IS_DIRECTION_NORMAL) != 0; }
2408 NS_HIDDEN_(nsresult) Redraw(nsBoxLayoutState& aState, const nsRect* aRect = nsnull, PRBool aImmediate = PR_FALSE);
2409 NS_IMETHOD RelayoutChildAtOrdinal(nsBoxLayoutState& aState, nsIBox* aChild)=0;
2410 virtual PRBool GetMouseThrough() const = 0;
2412 #ifdef DEBUG_LAYOUT
2413 NS_IMETHOD SetDebug(nsBoxLayoutState& aState, PRBool aDebug)=0;
2414 NS_IMETHOD GetDebug(PRBool& aDebug)=0;
2416 NS_IMETHOD DumpBox(FILE* out)=0;
2417 #endif
2420 * @return PR_TRUE if this text frame ends with a newline character. It
2421 * should return PR_FALSE if this is not a text frame.
2423 virtual PRBool HasTerminalNewline() const;
2425 static PRBool AddCSSPrefSize(nsIBox* aBox, nsSize& aSize, PRBool& aWidth, PRBool& aHeightSet);
2426 static PRBool AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox,
2427 nsSize& aSize, PRBool& aWidth, PRBool& aHeightSet);
2428 static PRBool AddCSSMaxSize(nsIBox* aBox, nsSize& aSize, PRBool& aWidth, PRBool& aHeightSet);
2429 static PRBool AddCSSFlex(nsBoxLayoutState& aState, nsIBox* aBox, nscoord& aFlex);
2431 // END OF BOX LAYOUT METHODS
2432 // The above methods have been migrated from nsIBox and are in the process of
2433 // being refactored. DO NOT USE OUTSIDE OF XUL.
2436 * gets the first or last possible caret position within the frame
2438 * @param [in] aStart
2439 * true for getting the first possible caret position
2440 * false for getting the last possible caret position
2441 * @return The caret position in an nsPeekOffsetStruct (the
2442 * fields set are mResultContent and mContentOffset;
2443 * the returned value is a 'best effort' in case errors
2444 * are encountered rummaging through the frame.
2446 nsPeekOffsetStruct GetExtremeCaretPosition(PRBool aStart);
2449 * Same thing as nsFrame::CheckInvalidateSizeChange, but more flexible. The
2450 * implementation of this method must not depend on the mRect or
2451 * GetOverflowRect() of the frame! Note that it's safe to assume in this
2452 * method that the frame origin didn't change. If it did, whoever moved the
2453 * frame will invalidate as needed anyway.
2455 void CheckInvalidateSizeChange(const nsRect& aOldRect,
2456 const nsRect& aOldOverflowRect,
2457 const nsSize& aNewDesiredSize);
2460 * Get a line iterator for this frame, if supported.
2462 * @return nsnull if no line iterator is supported.
2463 * @note dispose the line iterator using nsILineIterator::DisposeLineIterator
2465 virtual nsILineIterator* GetLineIterator() = 0;
2468 * If this frame is a next-in-flow, and its prev-in-flow has something on its
2469 * overflow list, pull those frames into the child list of this one.
2471 virtual void PullOverflowsFromPrevInFlow() {}
2473 protected:
2474 // Members
2475 nsRect mRect;
2476 nsIContent* mContent;
2477 nsStyleContext* mStyleContext;
2478 nsIFrame* mParent;
2479 private:
2480 nsIFrame* mNextSibling; // doubly-linked list of frames
2481 nsIFrame* mPrevSibling; // Do not touch outside SetNextSibling!
2482 protected:
2483 nsFrameState mState;
2485 // When there is an overflow area only slightly larger than mRect,
2486 // we store a set of four 1-byte deltas from the edges of mRect
2487 // rather than allocating a whole separate rectangle property.
2488 // Note that these are unsigned values, all measured "outwards"
2489 // from the edges of mRect, so /mLeft/ and /mTop/ are reversed from
2490 // our normal coordinate system.
2491 // If mOverflow.mType == NS_FRAME_OVERFLOW_LARGE, then the
2492 // delta values are not meaningful and the overflow area is stored
2493 // as a separate rect property.
2494 union {
2495 PRUint32 mType;
2496 struct {
2497 PRUint8 mLeft;
2498 PRUint8 mTop;
2499 PRUint8 mRight;
2500 PRUint8 mBottom;
2501 } mDeltas;
2502 } mOverflow;
2504 // Helpers
2506 * For frames that have top-level windows (top-level viewports,
2507 * comboboxes, menupoups) this function will invalidate the window.
2509 void InvalidateRoot(const nsRect& aDamageRect, PRUint32 aFlags);
2512 * Gets the overflow area for any properties that are common to all types of frames
2513 * e.g. outlines.
2515 nsRect GetAdditionalOverflow(const nsRect& aOverflowArea, const nsSize& aNewSize,
2516 PRBool* aHasOutlineOrEffects);
2519 * Can we stop inside this frame when we're skipping non-rendered whitespace?
2520 * @param aForward [in] Are we moving forward (or backward) in content order.
2521 * @param aOffset [in/out] At what offset into the frame to start looking.
2522 * on output - what offset was reached (whether or not we found a place to stop).
2523 * @return PR_TRUE: An appropriate offset was found within this frame,
2524 * and is given by aOffset.
2525 * PR_FALSE: Not found within this frame, need to try the next frame.
2527 virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset) = 0;
2530 * Search the frame for the next character
2531 * @param aForward [in] Are we moving forward (or backward) in content order.
2532 * @param aOffset [in/out] At what offset into the frame to start looking.
2533 * on output - what offset was reached (whether or not we found a place to stop).
2534 * @return PR_TRUE: An appropriate offset was found within this frame,
2535 * and is given by aOffset.
2536 * PR_FALSE: Not found within this frame, need to try the next frame.
2538 virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset) = 0;
2541 * Search the frame for the next word boundary
2542 * @param aForward [in] Are we moving forward (or backward) in content order.
2543 * @param aWordSelectEatSpace [in] PR_TRUE: look for non-whitespace following
2544 * whitespace (in the direction of movement).
2545 * PR_FALSE: look for whitespace following non-whitespace (in the
2546 * direction of movement).
2547 * @param aIsKeyboardSelect [in] Was the action initiated by a keyboard operation?
2548 * If PR_TRUE, punctuation immediately following a word is considered part
2549 * of that word. Otherwise, a sequence of punctuation is always considered
2550 * as a word on its own.
2551 * @param aOffset [in/out] At what offset into the frame to start looking.
2552 * on output - what offset was reached (whether or not we found a place to stop).
2553 * @param aState [in/out] the state that is carried from frame to frame
2554 * @return PR_TRUE: An appropriate offset was found within this frame,
2555 * and is given by aOffset.
2556 * PR_FALSE: Not found within this frame, need to try the next frame.
2558 struct PeekWordState {
2559 // true when we're still at the start of the search, i.e., we can't return
2560 // this point as a valid offset!
2561 PRPackedBool mAtStart;
2562 // true when we've encountered at least one character of the pre-boundary type
2563 // (whitespace if aWordSelectEatSpace is true, non-whitespace otherwise)
2564 PRPackedBool mSawBeforeType;
2565 // true when the last character encountered was punctuation
2566 PRPackedBool mLastCharWasPunctuation;
2567 // true when the last character encountered was whitespace
2568 PRPackedBool mLastCharWasWhitespace;
2569 // true when we've seen non-punctuation since the last whitespace
2570 PRPackedBool mSeenNonPunctuationSinceWhitespace;
2571 // text that's *before* the current frame when aForward is true, *after*
2572 // the current frame when aForward is false. Only includes the text
2573 // on the current line.
2574 nsAutoString mContext;
2576 PeekWordState() : mAtStart(PR_TRUE), mSawBeforeType(PR_FALSE),
2577 mLastCharWasPunctuation(PR_FALSE), mLastCharWasWhitespace(PR_FALSE),
2578 mSeenNonPunctuationSinceWhitespace(PR_FALSE) {}
2579 void SetSawBeforeType() { mSawBeforeType = PR_TRUE; }
2580 void Update(PRBool aAfterPunctuation, PRBool aAfterWhitespace) {
2581 mLastCharWasPunctuation = aAfterPunctuation;
2582 mLastCharWasWhitespace = aAfterWhitespace;
2583 if (aAfterWhitespace) {
2584 mSeenNonPunctuationSinceWhitespace = PR_FALSE;
2585 } else if (!aAfterPunctuation) {
2586 mSeenNonPunctuationSinceWhitespace = PR_TRUE;
2588 mAtStart = PR_FALSE;
2591 virtual PRBool PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
2592 PRInt32* aOffset, PeekWordState* aState) = 0;
2595 * Search for the first paragraph boundary before or after the given position
2596 * @param aPos See description in nsFrameSelection.h. The following fields are
2597 * used by this method:
2598 * Input: mDirection
2599 * Output: mResultContent, mContentOffset
2601 nsresult PeekOffsetParagraph(nsPeekOffsetStruct *aPos);
2603 private:
2604 nsRect* GetOverflowAreaProperty(PRBool aCreateIfNecessary = PR_FALSE);
2605 void SetOverflowRect(const nsRect& aRect);
2606 nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther, const PRInt32 aAPD) const;
2608 #ifdef NS_DEBUG
2609 public:
2610 // Formerly nsIFrameDebug
2611 NS_IMETHOD List(FILE* out, PRInt32 aIndent) const = 0;
2612 NS_IMETHOD GetFrameName(nsAString& aResult) const = 0;
2613 NS_IMETHOD_(nsFrameState) GetDebugStateBits() const = 0;
2614 NS_IMETHOD DumpRegressionData(nsPresContext* aPresContext,
2615 FILE* out, PRInt32 aIndent) = 0;
2616 #endif
2619 //----------------------------------------------------------------------
2622 * nsWeakFrame can be used to keep a reference to a nsIFrame in a safe way.
2623 * Whenever an nsIFrame object is deleted, the nsWeakFrames pointing
2624 * to it will be cleared.
2626 * Create nsWeakFrame object when it is sure that nsIFrame object
2627 * is alive and after some operations which may destroy the nsIFrame
2628 * (for example any DOM modifications) use IsAlive() or GetFrame() methods to
2629 * check whether it is safe to continue to use the nsIFrame object.
2631 * @note The usage of this class should be kept to a minimum.
2634 class nsWeakFrame {
2635 public:
2636 nsWeakFrame() : mPrev(nsnull), mFrame(nsnull) { }
2638 nsWeakFrame(nsIFrame* aFrame) : mPrev(nsnull), mFrame(nsnull)
2640 Init(aFrame);
2643 nsWeakFrame& operator=(nsWeakFrame& aOther) {
2644 Init(aOther.GetFrame());
2645 return *this;
2648 nsWeakFrame& operator=(nsIFrame* aFrame) {
2649 Init(aFrame);
2650 return *this;
2653 nsIFrame* operator->()
2655 return mFrame;
2658 operator nsIFrame*()
2660 return mFrame;
2663 void Clear(nsIPresShell* aShell) {
2664 if (aShell) {
2665 aShell->RemoveWeakFrame(this);
2667 mFrame = nsnull;
2668 mPrev = nsnull;
2671 PRBool IsAlive() { return !!mFrame; }
2673 nsIFrame* GetFrame() { return mFrame; }
2675 nsWeakFrame* GetPreviousWeakFrame() { return mPrev; }
2677 void SetPreviousWeakFrame(nsWeakFrame* aPrev) { mPrev = aPrev; }
2679 ~nsWeakFrame()
2681 Clear(mFrame ? mFrame->PresContext()->GetPresShell() : nsnull);
2683 private:
2684 void InitInternal(nsIFrame* aFrame);
2686 void InitExternal(nsIFrame* aFrame) {
2687 Clear(mFrame ? mFrame->PresContext()->GetPresShell() : nsnull);
2688 mFrame = aFrame;
2689 if (mFrame) {
2690 nsIPresShell* shell = mFrame->PresContext()->GetPresShell();
2691 NS_WARN_IF_FALSE(shell, "Null PresShell in nsWeakFrame!");
2692 if (shell) {
2693 shell->AddWeakFrame(this);
2694 } else {
2695 mFrame = nsnull;
2700 void Init(nsIFrame* aFrame) {
2701 #ifdef _IMPL_NS_LAYOUT
2702 InitInternal(aFrame);
2703 #else
2704 InitExternal(aFrame);
2705 #endif
2708 nsWeakFrame* mPrev;
2709 nsIFrame* mFrame;
2712 inline void
2713 nsFrameList::Enumerator::Next()
2715 NS_ASSERTION(!AtEnd(), "Should have checked AtEnd()!");
2716 mFrame = mFrame->GetNextSibling();
2719 inline
2720 nsFrameList::FrameLinkEnumerator::
2721 FrameLinkEnumerator(const nsFrameList& aList, nsIFrame* aPrevFrame)
2722 : Enumerator(aList)
2724 mPrev = aPrevFrame;
2725 mFrame = aPrevFrame ? aPrevFrame->GetNextSibling() : aList.FirstChild();
2727 #endif /* nsIFrame_h___ */