Bug 478820 part 2. Reorganize ConstructFrameByDisplayType a bit in the tables depart...
[mozilla-central.git] / layout / base / nsCSSFrameConstructor.h
blob782cccf229723440e08b45b8b6eeb2eba8929add
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 * construction of a frame tree that is nearly isomorphic to the content
40 * tree and updating of that tree in response to dynamic changes
43 #ifndef nsCSSFrameConstructor_h___
44 #define nsCSSFrameConstructor_h___
46 #include "nsCOMPtr.h"
47 #include "nsILayoutHistoryState.h"
48 #include "nsIXBLService.h"
49 #include "nsQuoteList.h"
50 #include "nsCounterManager.h"
51 #include "nsDataHashtable.h"
52 #include "nsHashKeys.h"
53 #include "nsThreadUtils.h"
54 #include "nsPageContentFrame.h"
55 #include "nsIViewManager.h"
57 class nsIDocument;
58 struct nsFrameItems;
59 struct nsAbsoluteItems;
60 class nsStyleContext;
61 struct nsStyleContent;
62 struct nsStyleDisplay;
63 class nsIPresShell;
64 class nsFrameManager;
65 class nsIDOMHTMLSelectElement;
66 class nsPresContext;
67 class nsStyleChangeList;
68 class nsIFrame;
69 struct nsGenConInitializer;
70 class ChildIterator;
72 struct nsFindFrameHint
74 nsIFrame *mPrimaryFrameForPrevSibling; // weak ref to the primary frame for the content for which we need a frame
75 nsFindFrameHint() : mPrimaryFrameForPrevSibling(nsnull) { }
78 typedef void (nsLazyFrameConstructionCallback)
79 (nsIContent* aContent, nsIFrame* aFrame, void* aArg);
81 class nsFrameConstructorState;
82 class nsFrameConstructorSaveState;
84 class nsCSSFrameConstructor
86 public:
87 nsCSSFrameConstructor(nsIDocument *aDocument, nsIPresShell* aPresShell);
88 ~nsCSSFrameConstructor(void) {
89 NS_ASSERTION(mUpdateCount == 0, "Dying in the middle of our own update?");
90 NS_ASSERTION(mFocusSuppressCount == 0, "Focus suppression will be wrong");
93 // Maintain global objects - gXBLService
94 static nsIXBLService * GetXBLService();
95 static void ReleaseGlobals() { NS_IF_RELEASE(gXBLService); }
97 // get the alternate text for a content node
98 static void GetAlternateTextFor(nsIContent* aContent,
99 nsIAtom* aTag, // content object's tag
100 nsXPIDLString& aAltText);
101 private:
102 // These are not supported and are not implemented!
103 nsCSSFrameConstructor(const nsCSSFrameConstructor& aCopy);
104 nsCSSFrameConstructor& operator=(const nsCSSFrameConstructor& aCopy);
106 public:
107 // XXXbz this method needs to actually return errors!
108 nsresult ConstructRootFrame(nsIContent* aDocElement,
109 nsIFrame** aNewFrame);
111 nsresult ReconstructDocElementHierarchy();
113 nsresult ContentAppended(nsIContent* aContainer,
114 PRInt32 aNewIndexInContainer);
116 nsresult ContentInserted(nsIContent* aContainer,
117 nsIContent* aChild,
118 PRInt32 aIndexInContainer,
119 nsILayoutHistoryState* aFrameState);
121 nsresult ContentRemoved(nsIContent* aContainer,
122 nsIContent* aChild,
123 PRInt32 aIndexInContainer,
124 PRBool* aDidReconstruct);
126 nsresult CharacterDataChanged(nsIContent* aContent,
127 PRBool aAppend);
129 nsresult ContentStatesChanged(nsIContent* aContent1,
130 nsIContent* aContent2,
131 PRInt32 aStateMask);
133 // Process the children of aContent and indicate that frames should be
134 // created for them. This is used for lazily built content such as that
135 // inside popups so that it is only created when the popup is opened.
136 // If aIsSynch is true, this method constructs the frames synchronously.
137 // aCallback will be called with three arguments, the first is the value
138 // of aContent, the second is aContent's primary frame, and the third is
139 // the value of aArg.
140 // aCallback will always be called even if the children of aContent had
141 // been generated earlier.
142 nsresult AddLazyChildren(nsIContent* aContent,
143 nsLazyFrameConstructionCallback* aCallback,
144 void* aArg, PRBool aIsSynch = PR_FALSE);
146 // Should be called when a frame is going to be destroyed and
147 // WillDestroyFrameTree hasn't been called yet.
148 void NotifyDestroyingFrame(nsIFrame* aFrame);
150 nsresult AttributeChanged(nsIContent* aContent,
151 PRInt32 aNameSpaceID,
152 nsIAtom* aAttribute,
153 PRInt32 aModType,
154 PRUint32 aStateMask);
156 void BeginUpdate();
157 void EndUpdate();
158 void RecalcQuotesAndCounters();
160 void WillDestroyFrameTree(PRBool aDestroyingPresShell);
162 // Get an integer that increments every time there is a style change
163 // as a result of a change to the :hover content state.
164 PRUint32 GetHoverGeneration() const { return mHoverGeneration; }
166 // Note: It's the caller's responsibility to make sure to wrap a
167 // ProcessRestyledFrames call in a view update batch and a script blocker.
168 // This function does not call ProcessAttachedQueue() on the binding manager.
169 // If the caller wants that to happen synchronously, it needs to handle that
170 // itself.
171 nsresult ProcessRestyledFrames(nsStyleChangeList& aRestyleArray);
173 private:
175 // Note: It's the caller's responsibility to make sure to wrap a
176 // ProcessOneRestyle call in a view update batch.
177 // This function does not call ProcessAttachedQueue() on the binding manager.
178 // If the caller wants that to happen synchronously, it needs to handle that
179 // itself.
180 void ProcessOneRestyle(nsIContent* aContent, nsReStyleHint aRestyleHint,
181 nsChangeHint aChangeHint);
183 public:
184 // Restyling for a ContentInserted (notification after insertion) or
185 // for a CharacterDataChanged. |aContainer| must be non-null; when
186 // the container is null, no work is needed.
187 void RestyleForInsertOrChange(nsIContent* aContainer,
188 nsIContent* aChild);
189 // This would be the same as RestyleForInsertOrChange if we got the
190 // notification before the removal. However, we get it after, so we
191 // have to use the index. |aContainer| must be non-null; when the
192 // container is null, no work is needed.
193 void RestyleForRemove(nsIContent* aContainer, nsIContent* aOldChild,
194 PRInt32 aIndexInContainer);
195 // Same for a ContentAppended. |aContainer| must be non-null; when
196 // the container is null, no work is needed.
197 void RestyleForAppend(nsIContent* aContainer,
198 PRInt32 aNewIndexInContainer);
200 // Note: It's the caller's responsibility to make sure to wrap a
201 // ProcessPendingRestyles call in a view update batch and a script blocker.
202 // This function does not call ProcessAttachedQueue() on the binding manager.
203 // If the caller wants that to happen synchronously, it needs to handle that
204 // itself.
205 void ProcessPendingRestyles();
207 // Rebuilds all style data by throwing out the old rule tree and
208 // building a new one, and additionally applying aExtraHint (which
209 // must not contain nsChangeHint_ReconstructFrame) to the root frame.
210 void RebuildAllStyleData(nsChangeHint aExtraHint);
212 void PostRestyleEvent(nsIContent* aContent, nsReStyleHint aRestyleHint,
213 nsChangeHint aMinChangeHint);
214 private:
215 void PostRestyleEventInternal();
216 public:
219 * Asynchronously clear style data from the root frame downwards and ensure
220 * it will all be rebuilt. This is safe to call anytime; it will schedule
221 * a restyle and take effect next time style changes are flushed.
222 * This method is used to recompute the style data when some change happens
223 * outside of any style rules, like a color preference change or a change
224 * in a system font size, or to fix things up when an optimization in the
225 * style data has become invalid. We assume that the root frame will not
226 * need to be reframed.
228 void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint);
230 // Request to create a continuing frame
231 nsresult CreateContinuingFrame(nsPresContext* aPresContext,
232 nsIFrame* aFrame,
233 nsIFrame* aParentFrame,
234 nsIFrame** aContinuingFrame,
235 PRBool aIsFluid = PR_TRUE);
237 // Copy over fixed frames from aParentFrame's prev-in-flow
238 nsresult ReplicateFixedFrames(nsPageContentFrame* aParentFrame);
240 // Request to find the primary frame associated with a given content object.
241 // This is typically called by the pres shell when there is no mapping in
242 // the pres shell hash table
243 nsresult FindPrimaryFrameFor(nsFrameManager* aFrameManager,
244 nsIContent* aContent,
245 nsIFrame** aFrame,
246 nsFindFrameHint* aHint);
248 // Get the XBL insertion point for a child
249 nsresult GetInsertionPoint(nsIFrame* aParentFrame,
250 nsIContent* aChildContent,
251 nsIFrame** aInsertionPoint,
252 PRBool* aMultiple = nsnull);
254 nsresult CreateListBoxContent(nsPresContext* aPresContext,
255 nsIFrame* aParentFrame,
256 nsIFrame* aPrevFrame,
257 nsIContent* aChild,
258 nsIFrame** aResult,
259 PRBool aIsAppend,
260 PRBool aIsScrollbar,
261 nsILayoutHistoryState* aFrameState);
263 nsresult RemoveMappingsForFrameSubtree(nsIFrame* aRemovedFrame);
265 // GetInitialContainingBlock() is deprecated in favor of GetRootElementFrame();
266 // nsIFrame* GetInitialContainingBlock() { return mRootElementFrame; }
267 // This returns the outermost frame for the root element
268 nsIFrame* GetRootElementFrame() { return mRootElementFrame; }
269 // This returns the frame for the root element that does not
270 // have a psuedo-element style
271 nsIFrame* GetRootElementStyleFrame() { return mRootElementStyleFrame; }
272 nsIFrame* GetPageSequenceFrame() { return mPageSequenceFrame; }
274 // Get the frame that is the parent of the root element.
275 nsIFrame* GetDocElementContainingBlock()
276 { return mDocElementContainingBlock; }
278 // Returns true if we've torn down the frame tree.
279 // Usually this means we've started destroying the presentation, but
280 // we could also have mostly torn it down in preparation for
281 // reconstructing frames for the entire document.
282 PRBool IsDestroyingFrameTree() { return mIsDestroyingFrameTree; }
284 private:
286 nsresult ReconstructDocElementHierarchyInternal();
288 nsresult ReinsertContent(nsIContent* aContainer,
289 nsIContent* aChild);
291 nsresult ConstructPageFrame(nsIPresShell* aPresShell,
292 nsPresContext* aPresContext,
293 nsIFrame* aParentFrame,
294 nsIFrame* aPrevPageFrame,
295 nsIFrame*& aPageFrame,
296 nsIFrame*& aCanvasFrame);
298 void DoContentStateChanged(nsIContent* aContent,
299 PRInt32 aStateMask);
301 /* aMinHint is the minimal change that should be made to the element */
302 void RestyleElement(nsIContent* aContent,
303 nsIFrame* aPrimaryFrame,
304 nsChangeHint aMinHint);
306 void RestyleLaterSiblings(nsIContent* aContent);
308 nsresult InitAndRestoreFrame (const nsFrameConstructorState& aState,
309 nsIContent* aContent,
310 nsIFrame* aParentFrame,
311 nsIFrame* aPrevInFlow,
312 nsIFrame* aNewFrame,
313 PRBool aAllowCounters = PR_TRUE);
315 already_AddRefed<nsStyleContext>
316 ResolveStyleContext(nsIFrame* aParentFrame,
317 nsIContent* aContent);
319 nsresult ConstructFrame(nsFrameConstructorState& aState,
320 nsIContent* aContent,
321 nsIFrame* aParentFrame,
322 nsFrameItems& aFrameItems);
324 nsresult ConstructDocElementFrame(nsFrameConstructorState& aState,
325 nsIContent* aDocElement,
326 nsIFrame* aParentFrame,
327 nsIFrame** aNewFrame);
329 nsresult ConstructDocElementTableFrame(nsIContent* aDocElement,
330 nsIFrame* aParentFrame,
331 nsIFrame** aNewTableFrame,
332 nsFrameConstructorState& aState);
335 * CreateAttributeContent creates a single content/frame combination for an
336 * |attr(foo)| generated content.
338 * @param aParentContent the parent content for the generated content
339 * @param aParentFrame the parent frame for the generated frame
340 * @param aAttrNamespace the namespace of the attribute in question
341 * @param aAttrName the localname of the attribute
342 * @param aStyleContext the style context to use
343 * @param aGeneratedContent the array of generated content to append the
344 * created content to.
345 * @param [out] aNewContent the content node we create
346 * @param [out] aNewFrame the new frame we create
348 nsresult CreateAttributeContent(nsIContent* aParentContent,
349 nsIFrame* aParentFrame,
350 PRInt32 aAttrNamespace,
351 nsIAtom* aAttrName,
352 nsStyleContext* aStyleContext,
353 nsCOMArray<nsIContent>& aGeneratedContent,
354 nsIContent** aNewContent,
355 nsIFrame** aNewFrame);
358 * Create a text node containing the given string. If aText is non-null
359 * then we also set aText to the returned node.
361 already_AddRefed<nsIContent> CreateGenConTextNode(const nsString& aString,
362 nsCOMPtr<nsIDOMCharacterData>* aText,
363 nsGenConInitializer* aInitializer);
366 * Create a content node for the given generated content style.
367 * The caller takes care of making it SetNativeAnonymous, binding it
368 * to the document, and creating frames for it.
369 * @param aParentContent is the node that has the before/after style
370 * @param aStyleContext is the 'before' or 'after' pseudo-element
371 * style context
372 * @param aContentIndex is the index of the content item to create
374 already_AddRefed<nsIContent> CreateGeneratedContent(nsIContent* aParentContent,
375 nsStyleContext* aStyleContext,
376 PRUint32 aContentIndex);
378 void CreateGeneratedContentFrame(nsFrameConstructorState& aState,
379 nsIFrame* aFrame,
380 nsIContent* aContent,
381 nsStyleContext* aStyleContext,
382 nsIAtom* aPseudoElement,
383 nsFrameItems& aFrameItems);
385 // This method can change aFrameList: it can chop off the end and
386 // put it in a special sibling of aParentFrame. It can also change
387 // aState by moving some floats out of it.
388 nsresult AppendFrames(nsFrameConstructorState& aState,
389 nsIContent* aContainer,
390 nsIFrame* aParentFrame,
391 nsFrameItems& aFrameList,
392 nsIFrame* aAfterFrame);
394 // BEGIN TABLE SECTION
396 * ConstructTableFrame will construct the outer and inner table frames and
397 * return them. Unless aIsPseudo is PR_TRUE, it will put the inner frame in
398 * the child list of the outer frame, and will put any pseudo frames it had
399 * to create into aChildItems. The newly-created outer frame will either be
400 * in aChildItems or a descendant of a pseudo in aChildItems (unless it's
401 * positioned or floated, in which case its placeholder will be in
402 * aChildItems).
404 nsresult ConstructTableFrame(nsFrameConstructorState& aState,
405 nsIContent* aContent,
406 nsIFrame* aContentParent,
407 nsStyleContext* aStyleContext,
408 PRInt32 aNameSpaceID,
409 PRBool aIsPseudo,
410 nsFrameItems& aChildItems,
411 nsIFrame*& aNewOuterFrame,
412 nsIFrame*& aNewInnerFrame);
414 nsresult ConstructTableCaptionFrame(nsFrameConstructorState& aState,
415 nsIContent* aContent,
416 nsIFrame* aParent,
417 nsStyleContext* aStyleContext,
418 PRInt32 aNameSpaceID,
419 nsFrameItems& aChildItems,
420 nsIFrame*& aNewFrame,
421 PRBool* aHasPseudoParent);
423 nsresult ConstructTableRowGroupFrame(nsFrameConstructorState& aState,
424 nsIContent* aContent,
425 nsIFrame* aParent,
426 nsStyleContext* aStyleContext,
427 PRInt32 aNameSpaceID,
428 PRBool aIsPseudo,
429 nsFrameItems& aChildItems,
430 nsIFrame*& aNewFrame,
431 PRBool* aHasPseudoParent);
433 nsresult ConstructTableColGroupFrame(nsFrameConstructorState& aState,
434 nsIContent* aContent,
435 nsIFrame* aParent,
436 nsStyleContext* aStyleContext,
437 PRInt32 aNameSpaceID,
438 PRBool aIsPseudo,
439 nsFrameItems& aChildItems,
440 nsIFrame*& aNewFrame,
441 PRBool* aHasPseudoParent);
443 nsresult ConstructTableRowFrame(nsFrameConstructorState& aState,
444 nsIContent* aContent,
445 nsIFrame* aParent,
446 nsStyleContext* aStyleContext,
447 PRInt32 aNameSpaceID,
448 PRBool aIsPseudo,
449 nsFrameItems& aChildItems,
450 nsIFrame*& aNewFrame,
451 PRBool* aHasPseudoParent);
453 nsresult ConstructTableColFrame(nsFrameConstructorState& aState,
454 nsIContent* aContent,
455 nsIFrame* aParent,
456 nsStyleContext* aStyleContext,
457 PRInt32 aNameSpaceID,
458 PRBool aIsPseudo,
459 nsFrameItems& aChildItems,
460 nsIFrame*& aNewFrame,
461 PRBool* aHasPseudoParent);
463 nsresult ConstructTableCellFrame(nsFrameConstructorState& aState,
464 nsIContent* aContent,
465 nsIFrame* aParentFrame,
466 nsStyleContext* aStyleContext,
467 PRInt32 aNameSpaceID,
468 PRBool aIsPseudo,
469 nsFrameItems& aChildItems,
470 nsIFrame*& aNewCellOuterFrame,
471 nsIFrame*& aNewCellInnerFrame,
472 PRBool* aHasPseudoParent);
474 nsresult CreatePseudoTableFrame(PRInt32 aNameSpaceID,
475 nsFrameConstructorState& aState,
476 nsIFrame* aParentFrameIn = nsnull);
478 nsresult CreatePseudoRowGroupFrame(PRInt32 aNameSpaceID,
479 nsFrameConstructorState& aState,
480 nsIFrame* aParentFrameIn = nsnull);
482 nsresult CreatePseudoColGroupFrame(PRInt32 aNameSpaceID,
483 nsFrameConstructorState& aState,
484 nsIFrame* aParentFrameIn = nsnull);
486 nsresult CreatePseudoRowFrame(PRInt32 aNameSpaceID,
487 nsFrameConstructorState& aState,
488 nsIFrame* aParentFrameIn = nsnull);
490 nsresult CreatePseudoCellFrame(PRInt32 aNameSpaceID,
491 nsFrameConstructorState& aState,
492 nsIFrame* aParentFrameIn = nsnull);
494 nsresult GetPseudoTableFrame(PRInt32 aNameSpaceID,
495 nsFrameConstructorState& aState,
496 nsIFrame& aParentFrameIn);
498 nsresult GetPseudoColGroupFrame(PRInt32 aNameSpaceID,
499 nsFrameConstructorState& aState,
500 nsIFrame& aParentFrameIn);
502 nsresult GetPseudoRowGroupFrame(PRInt32 aNameSpaceID,
503 nsFrameConstructorState& aState,
504 nsIFrame& aParentFrameIn);
506 nsresult GetPseudoRowFrame(PRInt32 aNameSpaceID,
507 nsFrameConstructorState& aState,
508 nsIFrame& aParentFrameIn);
510 nsresult GetPseudoCellFrame(PRInt32 aNameSpaceID,
511 nsFrameConstructorState& aState,
512 nsIFrame& aParentFrameIn);
514 nsresult GetParentFrame(PRInt32 aNameSpaceID,
515 nsIFrame& aParentFrameIn,
516 nsIAtom* aChildFrameType,
517 nsFrameConstructorState& aState,
518 nsIFrame*& aParentFrame,
519 PRBool& aIsPseudoParent);
521 private:
522 /* A constructor function that just creates an nsIFrame object. The caller
523 is responsible for initializing the object, adding it to frame lists,
524 constructing frames for the children, etc.
526 @param nsIPresShell the presshell whose arena should be used to allocate
527 the frame.
528 @param nsStyleContext the style context to use for the frame. */
529 typedef nsIFrame* (* FrameCreationFunc)(nsIPresShell*, nsStyleContext*);
531 /* A function that can be used to get a FrameConstructionData. Such
532 a function is allowed to return null.
534 @param nsIContent the node for which the frame is being constructed.
535 @param nsStyleContext the style context to be used for the frame.
537 struct FrameConstructionData;
538 typedef const FrameConstructionData*
539 (* FrameConstructionDataGetter)(nsIContent*, nsStyleContext*);
541 /* A constructor function that's used for complicated construction tasks.
542 This is expected to create the new frame, initialize it, add whatever
543 needs to be added to aFrameItems (XXXbz is that really necessary? Could
544 caller add? Might there be cases when *aNewFrame or its placeholder is
545 not the thing that ends up in aFrameItems? If not, would it be safe to do
546 the add into the frame construction state after processing kids? Look
547 into this as a followup!), process children as needed, etc. It is NOT
548 expected to deal with the primary frame map.
550 @param aState the frame construction state to use.
551 @param aContent the content node to construct the frame for.
552 @param aParentFrame the frame to set as the parent of the
553 newly-constructed frame.
554 @param aTag the content's XBL-resolved tag.
555 @param aStyleContext the style context to use for the new frame.
556 @param aFrameItems the frame list to add the new frame (or its
557 placeholder) to.
558 @param aFrame out param handing out the frame that was constructed. This
559 frame is what the caller will add to the primary frame map.
561 typedef nsresult
562 (nsCSSFrameConstructor::* FrameFullConstructor)(nsFrameConstructorState& aState,
563 nsIContent* aContent,
564 nsIFrame* aParentFrame,
565 nsIAtom* aTag,
566 nsStyleContext* aStyleContext,
567 const nsStyleDisplay* aStyleDisplay,
568 nsFrameItems& aFrameItems,
569 nsIFrame** aFrame);
571 /* Bits that modify the way a FrameConstructionData is handled */
573 /* If the FCDATA_SKIP_FRAMEMAP bit is set, then the frame created should not
574 be added to the primary frame map. This flag should not be used with
575 FCDATA_MAY_NEED_SCROLLFRAME, since scrollframe construction will add to
576 the frame map. */
577 #define FCDATA_SKIP_FRAMEMAP 0x1
578 /* If the FCDATA_FUNC_IS_DATA_GETTER bit is set, then the mFunc of the
579 FrameConstructionData is a getter function that can be used to get the
580 actual FrameConstructionData to use. */
581 #define FCDATA_FUNC_IS_DATA_GETTER 0x2
582 /* If the FCDATA_FUNC_IS_FULL_CTOR bit is set, then the FrameConstructionData
583 has an mFullConstructor. In this case, there is no relevant mData or
584 mFunc */
585 #define FCDATA_FUNC_IS_FULL_CTOR 0x4
586 /* If FCDATA_DISALLOW_OUT_OF_FLOW is set, do not allow the frame to
587 float or be absolutely positioned. This cannot be used with
588 FCDATA_FUNC_IS_FULL_CTOR */
589 #define FCDATA_DISALLOW_OUT_OF_FLOW 0x8
590 /* If FCDATA_FORCE_NULL_ABSPOS_CONTAINER is set, make sure to push a
591 null absolute containing block before processing children for this
592 frame. If this is not set, the frame will be pushed as the
593 absolute containing block as needed, based on its style */
594 #define FCDATA_FORCE_NULL_ABSPOS_CONTAINER 0x10
595 #ifdef MOZ_MATHML
596 /* If FCDATA_WRAP_KIDS_IN_BLOCKS is set, the inline kids of the frame
597 will be wrapped in blocks. This is only usable for MathML at the
598 moment. */
599 #define FCDATA_WRAP_KIDS_IN_BLOCKS 0x20
600 #endif /* MOZ_MATHML */
601 /* If FCDATA_SUPPRESS_FRAME is set, no frame should be created for the
602 content. If this bit is set, nothing else in the struct needs to be
603 set. */
604 #define FCDATA_SUPPRESS_FRAME 0x40
605 /* If FCDATA_MAY_NEED_SCROLLFRAME is set, the new frame should be wrapped in
606 a scrollframe if its overflow type so requires. This flag should not be
607 used with FCDATA_SKIP_FRAMEMAP, since scrollframe construction will add to
608 the frame map. */
609 #define FCDATA_MAY_NEED_SCROLLFRAME 0x80
610 #ifdef MOZ_XUL
611 /* If FCDATA_IS_POPUP is set, the new frame is a XUL popup frame. These need
612 some really weird special handling. */
613 #define FCDATA_IS_POPUP 0x100
614 #endif /* MOZ_XUL */
615 /* If FCDATA_SKIP_ABSPOS_PUSH is set, don't push this frame as an
616 absolute containing block, no matter what its style says. */
617 #define FCDATA_SKIP_ABSPOS_PUSH 0x200
618 /* If FCDATA_FORCE_VIEW is set, then force creation of a view for the frame.
619 this is only used if a scrollframe is not created and a full constructor
620 isn't used, so this flag shouldn't be used with
621 FCDATA_MAY_NEED_SCROLLFRAME or FCDATA_FUNC_IS_FULL_CTOR. */
622 #define FCDATA_FORCE_VIEW 0x400
623 /* If FCDATA_DISALLOW_GENERATED_CONTENT is set, then don't allow generated
624 content when processing kids of this frame. This should not be used with
625 FCDATA_FUNC_IS_FULL_CTOR */
626 #define FCDATA_DISALLOW_GENERATED_CONTENT 0x800
628 /* Structure representing information about how a frame should be
629 constructed. */
630 struct FrameConstructionData {
631 // Flag bits that can modify the way the construction happens
632 PRUint32 mBits;
633 // We have exactly one of three types of functions, so use a union for
634 // better cache locality for the ones that aren't pointer-to-member. That
635 // one needs to be separate, because we can't cast between it and the
636 // others and hence wouldn't be able to initialize the union without a
637 // constructor and all the resulting generated code. See documentation
638 // above for FrameCreationFunc, FrameConstructionDataGetter, and
639 // FrameFullConstructor to see what the functions would do.
640 union Func {
641 FrameCreationFunc mCreationFunc;
642 FrameConstructionDataGetter mDataGetter;
643 } mFunc;
644 FrameFullConstructor mFullConstructor;
647 /* Structure representing a mapping of an atom to a FrameConstructionData.
648 This can be used with non-static atoms, assuming that the nsIAtom* is
649 stored somewhere that this struct can point to (that is, a static
650 nsIAtom*) and that it's allocated before the struct is ever used. */
651 struct FrameConstructionDataByTag {
652 // Pointer to nsIAtom* is used because we want to initialize this
653 // statically, so before our atom tables are set up.
654 const nsIAtom * const * const mTag;
655 const FrameConstructionData mData;
658 /* Structure representing a mapping of an integer to a
659 FrameConstructionData. There are no magic integer values here. */
660 struct FrameConstructionDataByInt {
661 /* Could be used for display or whatever else */
662 const PRInt32 mInt;
663 const FrameConstructionData mData;
666 /* A function that takes an integer, content, style context, and array of
667 FrameConstructionDataByInts and finds the appropriate frame construction
668 data to use and returns it. This can return null if none of the integers
669 match or if the matching integer has a FrameConstructionDataGetter that
670 returns null. */
671 static const FrameConstructionData*
672 FindDataByInt(PRInt32 aInt, nsIContent* aContent,
673 nsStyleContext* aStyleContext,
674 const FrameConstructionDataByInt* aDataPtr,
675 PRUint32 aDataLength);
677 /* A function that takes a tag, content, style context, and array of
678 FrameConstructionDataByTags and finds the appropriate frame construction
679 data to use and returns it. This can return null if none of the tags
680 match or if the matching tag has a FrameConstructionDataGetter that
681 returns null. */
682 static const FrameConstructionData*
683 FindDataByTag(nsIAtom* aTag, nsIContent* aContent,
684 nsStyleContext* aStyleContext,
685 const FrameConstructionDataByTag* aDataPtr,
686 PRUint32 aDataLength);
689 * Function to adjust aParentFrame and aFrameItems to deal with table
690 * pseudo-frames that may have to be inserted.
691 * @param aState the nsFrameConstructorState we're using.
692 * @param aChildContent the content node we want to construct a frame for
693 * @param aParentFrame the frame we think should be the parent. This will be
694 * adjusted to point to a pseudo-frame if needed.
695 * @param aFCData the FrameConstructionData that would be used for frame
696 * construction. If this is null, then frame construction will be
697 * done based on the CSS display value.
698 * @param aNameSpaceID namespace that will be used for frame construction
699 * @param aDisplay the display style struct for aChildContent
700 * @param aFrameItems the framelist we think we need to put the child frame
701 * into. If we have to construct pseudo-frames, we'll modify the
702 * pointer to point to the list the child frame should go into.
703 * @param aSaveState the nsFrameConstructorSaveState we can use for pushing a
704 * float containing block if we have to do it.
705 * @param aSuppressFrame whether we should not create a frame below this
706 * parent
707 * @param aCreatedPseudo whether we had to create a pseudo-parent
708 * @return NS_OK on success, NS_ERROR_OUT_OF_MEMORY and such as needed.
710 // XXXbz this function should really go away once we rework pseudo-frame
711 // handling to be better. This should simply be part of the job of
712 // GetGeometricParent, and stuff like the frameitems and parent frame should
713 // be kept track of in the state...
714 nsresult AdjustParentFrame(nsFrameConstructorState& aState,
715 nsIContent* aChildContent,
716 nsIFrame* & aParentFrame,
717 const FrameConstructionData* aFCData,
718 PRInt32 aNameSpaceID,
719 const nsStyleDisplay* aDisplay,
720 nsFrameItems* & aFrameItems,
721 nsFrameConstructorSaveState& aSaveState,
722 PRBool& aSuppressFrame,
723 PRBool& aCreatedPseudo);
725 // END TABLE SECTION
727 protected:
728 static nsresult CreatePlaceholderFrameFor(nsIPresShell* aPresShell,
729 nsIContent* aContent,
730 nsIFrame* aFrame,
731 nsStyleContext* aStyleContext,
732 nsIFrame* aParentFrame,
733 nsIFrame* aPrevInFlow,
734 nsIFrame** aPlaceholderFrame);
736 private:
737 // ConstructButtonFrame puts the new frame in aFrameItems and
738 // handles the kids of the button.
739 nsresult ConstructButtonFrame(nsFrameConstructorState& aState,
740 nsIContent* aContent,
741 nsIFrame* aParentFrame,
742 nsIAtom* aTag,
743 nsStyleContext* aStyleContext,
744 const nsStyleDisplay* aStyleDisplay,
745 nsFrameItems& aFrameItems,
746 nsIFrame** aNewFrame);
748 // ConstructSelectFrame puts the new frame in aFrameItems and
749 // handles the kids of the select.
750 nsresult ConstructSelectFrame(nsFrameConstructorState& aState,
751 nsIContent* aContent,
752 nsIFrame* aParentFrame,
753 nsIAtom* aTag,
754 nsStyleContext* aStyleContext,
755 const nsStyleDisplay* aStyleDisplay,
756 nsFrameItems& aFrameItems,
757 nsIFrame** aNewFrame);
759 // ConstructFieldSetFrame puts the new frame in aFrameItems and
760 // handles the kids of the fieldset
761 nsresult ConstructFieldSetFrame(nsFrameConstructorState& aState,
762 nsIContent* aContent,
763 nsIFrame* aParentFrame,
764 nsIAtom* aTag,
765 nsStyleContext* aStyleContext,
766 const nsStyleDisplay* aStyleDisplay,
767 nsFrameItems& aFrameItems,
768 nsIFrame** aNewFrame);
770 static const FrameConstructionData* FindTextData(nsIFrame* aParentFrame);
772 nsresult ConstructTextFrame(const FrameConstructionData* aData,
773 nsFrameConstructorState& aState,
774 nsIContent* aContent,
775 nsIFrame* aParentFrame,
776 nsStyleContext* aStyleContext,
777 nsFrameItems& aFrameItems,
778 PRBool aPseudoParent);
780 nsresult ConstructPageBreakFrame(nsFrameConstructorState& aState,
781 nsIContent* aContent,
782 nsIFrame* aParentFrame,
783 nsStyleContext* aStyleContext,
784 nsFrameItems& aFrameItems);
786 // Construct a page break frame if page-break-before:always is set in aStyleContext
787 // and add it to aFrameItems. Return true if page-break-after:always is set on aStyleContext.
788 // Don't do this for row groups, rows or cell, because tables handle those internally.
789 PRBool PageBreakBefore(nsFrameConstructorState& aState,
790 nsIContent* aContent,
791 nsIFrame* aParentFrame,
792 nsStyleContext* aStyleContext,
793 nsFrameItems& aFrameItems);
795 // Function to find FrameConstructionData for aContent. Will return
796 // null if aContent is not HTML.
797 static const FrameConstructionData* FindHTMLData(nsIContent* aContent,
798 nsIAtom* aTag,
799 PRInt32 aNameSpaceID,
800 nsIFrame* aParentFrame,
801 nsStyleContext* aStyleContext);
802 // HTML data-finding helper functions
803 static const FrameConstructionData*
804 FindImgData(nsIContent* aContent, nsStyleContext* aStyleContext);
805 static const FrameConstructionData*
806 FindImgControlData(nsIContent* aContent, nsStyleContext* aStyleContext);
807 static const FrameConstructionData*
808 FindInputData(nsIContent* aContent, nsStyleContext* aStyleContext);
809 static const FrameConstructionData*
810 FindObjectData(nsIContent* aContent, nsStyleContext* aStyleContext);
812 /* Construct a frame from the given FrameConstructionData. This function
813 will handle adding the frame to frame lists, processing children, adding
814 it to the primary frame map, and so forth.
816 @param aData the FrameConstructionData to use. Must not be null.
817 @param aState the frame construction state to use.
818 @param aContent the content node to construct the frame for.
819 @param aParentFrame the frame to set as the parent of the
820 newly-constructed frame.
821 @param aTag the content's XBL-resolved tag.
822 @param aNameSpaceID the content's XBL-resolved namespace ID.
823 @param aStyleContext the style context to use for the new frame.
824 @param aFrameItems the frame list to add the new frame (or its
825 placeholder) to.
826 @param aHasPseudoParent whether aParentFrame is a table pseudo-frame.
828 nsresult ConstructFrameFromData(const FrameConstructionData* aData,
829 nsFrameConstructorState& aState,
830 nsIContent* aContent,
831 nsIFrame* aParentFrame,
832 nsIAtom* aTag,
833 PRInt32 aNameSpaceID,
834 nsStyleContext* aStyleContext,
835 nsFrameItems& aFrameItems,
836 PRBool aHasPseudoParent);
838 nsresult ConstructFrameInternal( nsFrameConstructorState& aState,
839 nsIContent* aContent,
840 nsIFrame* aParentFrame,
841 nsIAtom* aTag,
842 PRInt32 aNameSpaceID,
843 nsStyleContext* aStyleContext,
844 nsFrameItems& aFrameItems,
845 PRBool aXBLBaseTag);
847 nsresult CreateAnonymousFrames(nsIAtom* aTag,
848 nsFrameConstructorState& aState,
849 nsIContent* aParent,
850 nsIFrame* aNewFrame,
851 nsFrameItems& aChildItems,
852 PRBool aIsRoot = PR_FALSE);
854 nsresult CreateAnonymousFrames(nsFrameConstructorState& aState,
855 nsIContent* aParent,
856 nsIFrame* aParentFrame,
857 nsFrameItems& aChildItems);
859 //MathML Mod - RBS
860 #ifdef MOZ_MATHML
862 * Takes the frames in aBlockItems and wraps them in a new anonymous block
863 * frame whose content is aContent and whose parent will be aParentFrame.
864 * The anonymous block is added to aNewItems and aBlockItems is cleared.
866 nsresult FlushAccumulatedBlock(nsFrameConstructorState& aState,
867 nsIContent* aContent,
868 nsIFrame* aParentFrame,
869 nsFrameItems* aBlockItems,
870 nsFrameItems* aNewItems);
872 // Function to find FrameConstructionData for aContent. Will return
873 // null if aContent is not MathML.
874 static const FrameConstructionData* FindMathMLData(nsIContent* aContent,
875 nsIAtom* aTag,
876 PRInt32 aNameSpaceID,
877 nsStyleContext* aStyleContext);
878 #endif
880 // Function to find FrameConstructionData for aContent. Will return
881 // null if aContent is not XUL.
882 static const FrameConstructionData* FindXULTagData(nsIContent* aContent,
883 nsIAtom* aTag,
884 PRInt32 aNameSpaceID,
885 nsStyleContext* aStyleContext);
886 // XUL data-finding helper functions and structures
887 #ifdef MOZ_XUL
888 static const FrameConstructionData*
889 FindPopupGroupData(nsIContent* aContent, nsStyleContext* aStyleContext);
890 // sXULTextBoxData used for both labels and descriptions
891 static const FrameConstructionData sXULTextBoxData;
892 static const FrameConstructionData*
893 FindXULLabelData(nsIContent* aContent, nsStyleContext* aStyleContext);
894 static const FrameConstructionData*
895 FindXULDescriptionData(nsIContent* aContent, nsStyleContext* aStyleContext);
896 #ifdef XP_MACOSX
897 static const FrameConstructionData*
898 FindXULMenubarData(nsIContent* aContent, nsStyleContext* aStyleContext);
899 #endif /* XP_MACOSX */
900 static const FrameConstructionData*
901 FindXULListBoxBodyData(nsIContent* aContent, nsStyleContext* aStyleContext);
902 static const FrameConstructionData*
903 FindXULListItemData(nsIContent* aContent, nsStyleContext* aStyleContext);
904 #endif /* MOZ_XUL */
906 // Function to find FrameConstructionData for aContent using one of the XUL
907 // display types. Will return null if aDisplay doesn't have a XUL display
908 // type. This function performs no other checks, so should only be called if
909 // we know for sure that the content is not something that should get a frame
910 // constructed by tag.
911 static const FrameConstructionData*
912 FindXULDisplayData(const nsStyleDisplay* aDisplay,
913 nsIContent* aContent,
914 nsStyleContext* aStyleContext);
916 // SVG - rods
917 #ifdef MOZ_SVG
918 static const FrameConstructionData* FindSVGData(nsIContent* aContent,
919 nsIAtom* aTag,
920 PRInt32 aNameSpaceID,
921 nsIFrame* aParentFrame,
922 nsStyleContext* aStyleContext);
924 nsresult ConstructSVGForeignObjectFrame(nsFrameConstructorState& aState,
925 nsIContent* aContent,
926 nsIFrame* aParentFrame,
927 nsIAtom* aTag,
928 nsStyleContext* aStyleContext,
929 const nsStyleDisplay* aStyleDisplay,
930 nsFrameItems& aFrameItems,
931 nsIFrame** aNewFrame);
932 #endif
934 nsresult ConstructFrameByDisplayType(nsFrameConstructorState& aState,
935 const nsStyleDisplay* aDisplay,
936 nsIContent* aContent,
937 PRInt32 aNameSpaceID,
938 nsIAtom* aTag,
939 nsIFrame* aParentFrame,
940 nsStyleContext* aStyleContext,
941 nsFrameItems& aFrameItems,
942 PRBool aHasPseudoParent);
945 * Construct the frames for the children of aContent. "children" is defined
946 * as "whatever ChildIterator returns for aContent". This means we're
947 * basically operating on children in the "flattened tree" per sXBL/XBL2.
948 * This method will also handle constructing ::before, ::after,
949 * ::first-letter, and ::first-line frames, as needed and if allowed.
951 * If the parent is a float containing block, this method will handle pushing
952 * it as the float containing block in aState (so there's no need for callers
953 * to push it themselves).
955 * @param aState the frame construction state
956 * @param aContent the content node whose children need frames
957 * @param aStyleContext the style context for aContent
958 * @param aFrame the frame to use as the parent frame for the new in-flow
959 * kids. Note that this must be its own content insertion frame, but
960 * need not be be the primary frame for aContent. This frame will be
961 * pushed as the float containing block, as needed. aFrame is also
962 * used to find the parent style context for the kids' style contexts
963 * (not necessary aFrame's style context).
964 * @param aCanHaveGeneratedContent Whether to allow :before and
965 * :after styles on the parent.
966 * @param aFrameItems the list in which we should place the in-flow children
967 * @param aAllowBlockStyles Whether to allow first-letter and first-line
968 * styles on the parent.
969 * @param aTableCreator if non-null, will just make this method call
970 * TableProcessChildren between constructing the ::before and ::after
971 * content instead of doing whatever it would normally do.
973 nsresult ProcessChildren(nsFrameConstructorState& aState,
974 nsIContent* aContent,
975 nsStyleContext* aStyleContext,
976 nsIFrame* aFrame,
977 PRBool aCanHaveGeneratedContent,
978 nsFrameItems& aFrameItems,
979 PRBool aAllowBlockStyles);
981 nsIFrame* GetFrameFor(nsIContent* aContent);
984 * These two functions are used when we start frame creation from a non-root
985 * element. They should recreate the same state that we would have
986 * arrived at if we had built frames from the root frame to aFrame.
987 * Therefore, any calls to PushFloatContainingBlock and
988 * PushAbsoluteContainingBlock during frame construction should get
989 * corresponding logic in these functions.
991 public:
992 nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame);
993 private:
994 nsIFrame* GetFloatContainingBlock(nsIFrame* aFrame);
996 nsIContent* PropagateScrollToViewport();
998 // Build a scroll frame:
999 // Calls BeginBuildingScrollFrame, InitAndRestoreFrame, and then FinishBuildingScrollFrame.
1000 // Sets the primary frame for the content to the output aNewFrame.
1001 // @param aNewFrame the created scrollframe --- output only
1002 // @param aParentFrame the geometric parent that the scrollframe will have.
1003 nsresult
1004 BuildScrollFrame(nsFrameConstructorState& aState,
1005 nsIContent* aContent,
1006 nsStyleContext* aContentStyle,
1007 nsIFrame* aScrolledFrame,
1008 nsIFrame* aParentFrame,
1009 nsIFrame*& aNewFrame);
1011 // Builds the initial ScrollFrame
1012 already_AddRefed<nsStyleContext>
1013 BeginBuildingScrollFrame(nsFrameConstructorState& aState,
1014 nsIContent* aContent,
1015 nsStyleContext* aContentStyle,
1016 nsIFrame* aParentFrame,
1017 nsIAtom* aScrolledPseudo,
1018 PRBool aIsRoot,
1019 nsIFrame*& aNewFrame);
1021 // Completes the building of the scrollframe:
1022 // Creates a view for the scrolledframe and makes it the child of the scrollframe.
1023 void
1024 FinishBuildingScrollFrame(nsIFrame* aScrollFrame,
1025 nsIFrame* aScrolledFrame);
1027 // InitializeSelectFrame puts scrollFrame in aFrameItems if aBuildCombobox is false
1028 nsresult
1029 InitializeSelectFrame(nsFrameConstructorState& aState,
1030 nsIFrame* scrollFrame,
1031 nsIFrame* scrolledFrame,
1032 nsIContent* aContent,
1033 nsIFrame* aParentFrame,
1034 nsStyleContext* aStyleContext,
1035 PRBool aBuildCombobox,
1036 nsFrameItems& aFrameItems);
1038 nsresult MaybeRecreateFramesForContent(nsIContent* aContent);
1040 nsresult RecreateFramesForContent(nsIContent* aContent);
1042 // If removal of aFrame from the frame tree requires reconstruction of some
1043 // containing block (either of aFrame or of its parent) due to {ib} splits,
1044 // recreate the relevant containing block. The return value indicates
1045 // whether this happened. If this method returns true, *aResult is the
1046 // return value of ReframeContainingBlock. If this method returns false, the
1047 // value of *aResult is no affected. aFrame and aResult must not be null.
1048 // aFrame must be the result of a GetPrimaryFrameFor() call (which means its
1049 // parent is also not null).
1050 PRBool MaybeRecreateContainerForIBSplitterFrame(nsIFrame* aFrame,
1051 nsresult* aResult);
1053 nsresult CreateContinuingOuterTableFrame(nsIPresShell* aPresShell,
1054 nsPresContext* aPresContext,
1055 nsIFrame* aFrame,
1056 nsIFrame* aParentFrame,
1057 nsIContent* aContent,
1058 nsStyleContext* aStyleContext,
1059 nsIFrame** aContinuingFrame);
1061 nsresult CreateContinuingTableFrame(nsIPresShell* aPresShell,
1062 nsPresContext* aPresContext,
1063 nsIFrame* aFrame,
1064 nsIFrame* aParentFrame,
1065 nsIContent* aContent,
1066 nsStyleContext* aStyleContext,
1067 nsIFrame** aContinuingFrame);
1069 //----------------------------------------
1071 // Methods support creating block frames and their children
1073 already_AddRefed<nsStyleContext>
1074 GetFirstLetterStyle(nsIContent* aContent,
1075 nsStyleContext* aStyleContext);
1077 already_AddRefed<nsStyleContext>
1078 GetFirstLineStyle(nsIContent* aContent,
1079 nsStyleContext* aStyleContext);
1081 PRBool ShouldHaveFirstLetterStyle(nsIContent* aContent,
1082 nsStyleContext* aStyleContext);
1084 // Check whether a given block has first-letter style. Make sure to
1085 // only pass in blocks! And don't pass in null either.
1086 PRBool HasFirstLetterStyle(nsIFrame* aBlockFrame);
1088 PRBool ShouldHaveFirstLineStyle(nsIContent* aContent,
1089 nsStyleContext* aStyleContext);
1091 void ShouldHaveSpecialBlockStyle(nsIContent* aContent,
1092 nsStyleContext* aStyleContext,
1093 PRBool* aHaveFirstLetterStyle,
1094 PRBool* aHaveFirstLineStyle);
1096 // |aContentParentFrame| should be null if it's really the same as
1097 // |aParentFrame|.
1098 // @param aFrameItems where we want to put the block in case it's in-flow.
1099 // @param aNewFrame an in/out parameter. On input it is the block to be
1100 // constructed. On output it is reset to the outermost
1101 // frame constructed (e.g. if we need to wrap the block in an
1102 // nsColumnSetFrame.
1103 // @param aParentFrame is the desired parent for the (possibly wrapped)
1104 // block
1105 // @param aContentParent is the parent the block would have if it
1106 // were in-flow
1107 nsresult ConstructBlock(nsFrameConstructorState& aState,
1108 const nsStyleDisplay* aDisplay,
1109 nsIContent* aContent,
1110 nsIFrame* aParentFrame,
1111 nsIFrame* aContentParentFrame,
1112 nsStyleContext* aStyleContext,
1113 nsIFrame** aNewFrame,
1114 nsFrameItems& aFrameItems,
1115 PRBool aAbsPosContainer);
1117 nsresult ConstructInline(nsFrameConstructorState& aState,
1118 const nsStyleDisplay* aDisplay,
1119 nsIContent* aContent,
1120 nsIFrame* aParentFrame,
1121 nsStyleContext* aStyleContext,
1122 PRBool aIsPositioned,
1123 nsIFrame* aNewFrame);
1126 * Move an already-constructed framelist into the inline frame at
1127 * the tail end of an {ib} split. Creates said inline if it doesn't
1128 * already exist.
1130 * @param aState the frame construction state we're using right now.
1131 * @param aExistingEndFrame if non-null, the already-existing end frame.
1132 * @param aIsPositioned Whether the end frame should be positioned.
1133 * @param aContent the content node for this {ib} split.
1134 * @param aStyleContext the style context to use for the new frame
1135 * @param aFramesToMove The frame list to move over
1136 * @param aBlockPart the block part of the {ib} split.
1137 * @param aTargetState if non-null, the target state to pass to
1138 * MoveChildrenTo for float reparenting.
1139 * XXXbz test float reparenting?
1141 * @note aIsPositioned, aContent, aStyleContext, are
1142 * only used if aExistingEndFrame is null.
1144 nsIFrame* MoveFramesToEndOfIBSplit(nsFrameConstructorState& aState,
1145 nsIFrame* aExistingEndFrame,
1146 PRBool aIsPositioned,
1147 nsIContent* aContent,
1148 nsStyleContext* aStyleContext,
1149 nsIFrame* aFramesToMove,
1150 nsIFrame* aBlockPart,
1151 nsFrameConstructorState* aTargetState);
1153 nsresult ProcessInlineChildren(nsFrameConstructorState& aState,
1154 nsIContent* aContent,
1155 nsIFrame* aFrame,
1156 PRBool aCanHaveGeneratedContent,
1157 nsFrameItems& aFrameItems,
1158 PRBool* aKidsAllInline);
1160 // Determine whether we need to wipe out what we just did and start over
1161 // because we're doing something like adding block kids to an inline frame
1162 // (and therefore need an {ib} split). If aIsAppend is true, aPrevSibling is
1163 // ignored. Otherwise it may be used to determine whether to reframe when
1164 // inserting into the block of an {ib} split.
1165 // @return PR_TRUE if we reconstructed the containing block, PR_FALSE
1166 // otherwise
1167 PRBool WipeContainingBlock(nsFrameConstructorState& aState,
1168 nsIFrame* aContainingBlock,
1169 nsIFrame* aFrame,
1170 const nsFrameItems& aFrameList,
1171 PRBool aIsAppend,
1172 nsIFrame* aPrevSibling);
1174 nsresult ReframeContainingBlock(nsIFrame* aFrame);
1176 nsresult StyleChangeReflow(nsIFrame* aFrame);
1178 /** Helper function that searches the immediate child frames
1179 * (and their children if the frames are "special")
1180 * for a frame that maps the specified content object
1182 * @param aParentFrame the primary frame for aParentContent
1183 * @param aContent the content node for which we seek a frame
1184 * @param aParentContent the parent for aContent
1185 * @param aHint an optional hint used to make the search for aFrame faster
1187 nsIFrame* FindFrameWithContent(nsFrameManager* aFrameManager,
1188 nsIFrame* aParentFrame,
1189 nsIContent* aParentContent,
1190 nsIContent* aContent,
1191 nsFindFrameHint* aHint);
1193 //----------------------------------------
1195 // Methods support :first-letter style
1197 void CreateFloatingLetterFrame(nsFrameConstructorState& aState,
1198 nsIFrame* aBlockFrame,
1199 nsIContent* aTextContent,
1200 nsIFrame* aTextFrame,
1201 nsIContent* aBlockContent,
1202 nsIFrame* aParentFrame,
1203 nsStyleContext* aStyleContext,
1204 nsFrameItems& aResult);
1206 nsresult CreateLetterFrame(nsIFrame* aBlockFrame,
1207 nsIContent* aTextContent,
1208 nsIFrame* aParentFrame,
1209 nsFrameItems& aResult);
1211 nsresult WrapFramesInFirstLetterFrame(nsIContent* aBlockContent,
1212 nsIFrame* aBlockFrame,
1213 nsFrameItems& aBlockFrames);
1215 nsresult WrapFramesInFirstLetterFrame(nsIFrame* aBlockFrame,
1216 nsIFrame* aParentFrame,
1217 nsIFrame* aParentFrameList,
1218 nsIFrame** aModifiedParent,
1219 nsIFrame** aTextFrame,
1220 nsIFrame** aPrevFrame,
1221 nsFrameItems& aLetterFrame,
1222 PRBool* aStopLooking);
1224 nsresult RecoverLetterFrames(nsIFrame* aBlockFrame);
1227 nsresult RemoveLetterFrames(nsPresContext* aPresContext,
1228 nsIPresShell* aPresShell,
1229 nsFrameManager* aFrameManager,
1230 nsIFrame* aBlockFrame);
1232 // Recursive helper for RemoveLetterFrames
1233 nsresult RemoveFirstLetterFrames(nsPresContext* aPresContext,
1234 nsIPresShell* aPresShell,
1235 nsFrameManager* aFrameManager,
1236 nsIFrame* aFrame,
1237 PRBool* aStopLooking);
1239 // Special remove method for those pesky floating first-letter frames
1240 nsresult RemoveFloatingFirstLetterFrames(nsPresContext* aPresContext,
1241 nsIPresShell* aPresShell,
1242 nsFrameManager* aFrameManager,
1243 nsIFrame* aBlockFrame,
1244 PRBool* aStopLooking);
1246 // Capture state for the frame tree rooted at the frame associated with the
1247 // content object, aContent
1248 nsresult CaptureStateForFramesOf(nsIContent* aContent,
1249 nsILayoutHistoryState* aHistoryState);
1251 // Capture state for the frame tree rooted at aFrame.
1252 nsresult CaptureStateFor(nsIFrame* aFrame,
1253 nsILayoutHistoryState* aHistoryState);
1255 //----------------------------------------
1257 // Methods support :first-line style
1259 nsresult WrapFramesInFirstLineFrame(nsFrameConstructorState& aState,
1260 nsIContent* aBlockContent,
1261 nsIFrame* aBlockFrame,
1262 nsFrameItems& aFrameItems);
1264 nsresult AppendFirstLineFrames(nsFrameConstructorState& aState,
1265 nsIContent* aContent,
1266 nsIFrame* aBlockFrame,
1267 nsFrameItems& aFrameItems);
1269 nsresult InsertFirstLineFrames(nsFrameConstructorState& aState,
1270 nsIContent* aContent,
1271 nsIFrame* aBlockFrame,
1272 nsIFrame** aParentFrame,
1273 nsIFrame* aPrevSibling,
1274 nsFrameItems& aFrameItems);
1276 nsresult RemoveFixedItems(const nsFrameConstructorState& aState,
1277 nsIFrame* aRootElementFrame);
1279 // Find the right frame to use for aContent when looking for sibling
1280 // frames for aTargetContent. If aPrevSibling is true, this
1281 // will look for last continuations, etc, as necessary. This calls
1282 // IsValidSibling as needed; if that returns false it returns null.
1284 // @param aTargetContentDisplay the CSS display enum for aTargetContent if
1285 // already known, UNSET_DISPLAY otherwise.
1286 nsIFrame* FindFrameForContentSibling(nsIContent* aContent,
1287 nsIContent* aTargetContent,
1288 PRUint8& aTargetContentDisplay,
1289 PRBool aPrevSibling);
1291 // Find the ``rightmost'' frame for the content immediately preceding the one
1292 // aIter points to, following continuations if necessary. aIter is passed by
1293 // value on purpose, so as not to modify the callee's iterator.
1294 nsIFrame* FindPreviousSibling(const ChildIterator& aFirst,
1295 ChildIterator aIter);
1297 // Find the frame for the content node immediately following the one aIter
1298 // points to, following continuations if necessary. aIter is passed by value
1299 // on purpose, so as not to modify the callee's iterator.
1300 nsIFrame* FindNextSibling(ChildIterator aIter,
1301 const ChildIterator& aLast);
1303 // see if aContent and aSibling are legitimate siblings due to restrictions
1304 // imposed by table columns
1305 // XXXbz this code is generally wrong, since the frame for aContent
1306 // may be constructed based on tag, not based on aDisplay!
1307 PRBool IsValidSibling(nsIFrame* aSibling,
1308 nsIContent* aContent,
1309 PRUint8& aDisplay);
1311 void QuotesDirty() {
1312 NS_PRECONDITION(mUpdateCount != 0, "Instant quote updates are bad news");
1313 mQuotesDirty = PR_TRUE;
1316 void CountersDirty() {
1317 NS_PRECONDITION(mUpdateCount != 0, "Instant counter updates are bad news");
1318 mCountersDirty = PR_TRUE;
1321 public:
1322 struct RestyleData;
1323 friend struct RestyleData;
1325 struct RestyleData {
1326 nsReStyleHint mRestyleHint; // What we want to restyle
1327 nsChangeHint mChangeHint; // The minimal change hint for "self"
1330 struct RestyleEnumerateData : public RestyleData {
1331 nsCOMPtr<nsIContent> mContent;
1334 class RestyleEvent;
1335 friend class RestyleEvent;
1337 class RestyleEvent : public nsRunnable {
1338 public:
1339 NS_DECL_NSIRUNNABLE
1340 RestyleEvent(nsCSSFrameConstructor *aConstructor)
1341 : mConstructor(aConstructor) {
1342 NS_PRECONDITION(aConstructor, "Must have a constructor!");
1344 void Revoke() { mConstructor = nsnull; }
1345 private:
1346 nsCSSFrameConstructor *mConstructor;
1349 friend class nsFrameConstructorState;
1351 private:
1353 class LazyGenerateChildrenEvent;
1354 friend class LazyGenerateChildrenEvent;
1356 // See comments of nsCSSFrameConstructor::AddLazyChildren()
1357 class LazyGenerateChildrenEvent : public nsRunnable {
1358 public:
1359 NS_DECL_NSIRUNNABLE
1360 LazyGenerateChildrenEvent(nsIContent *aContent,
1361 nsIPresShell *aPresShell,
1362 nsLazyFrameConstructionCallback* aCallback,
1363 void* aArg)
1364 : mContent(aContent), mPresShell(aPresShell), mCallback(aCallback), mArg(aArg)
1367 private:
1368 nsCOMPtr<nsIContent> mContent;
1369 nsCOMPtr<nsIPresShell> mPresShell;
1370 nsLazyFrameConstructionCallback* mCallback;
1371 void* mArg;
1374 nsIDocument* mDocument; // Weak ref
1375 nsIPresShell* mPresShell; // Weak ref
1377 // See the comment at the start of ConstructRootFrame for more details
1378 // about the following frames.
1380 // This is just the outermost frame for the root element.
1381 nsIFrame* mRootElementFrame;
1382 // This is the frame for the root element that has no pseudo-element style.
1383 nsIFrame* mRootElementStyleFrame;
1384 // This is the containing block for fixed-pos frames --- the viewport
1385 nsIFrame* mFixedContainingBlock;
1386 // This is the containing block that contains the root element ---
1387 // the real "initial containing block" according to CSS 2.1.
1388 nsIFrame* mDocElementContainingBlock;
1389 nsIFrame* mGfxScrollFrame;
1390 nsIFrame* mPageSequenceFrame;
1391 nsQuoteList mQuoteList;
1392 nsCounterManager mCounterManager;
1393 PRUint16 mUpdateCount;
1394 PRUint32 mFocusSuppressCount;
1395 PRPackedBool mQuotesDirty : 1;
1396 PRPackedBool mCountersDirty : 1;
1397 PRPackedBool mIsDestroyingFrameTree : 1;
1398 PRPackedBool mRebuildAllStyleData : 1;
1399 // This is true if mDocElementContainingBlock supports absolute positioning
1400 PRPackedBool mHasRootAbsPosContainingBlock : 1;
1401 PRUint32 mHoverGeneration;
1402 nsChangeHint mRebuildAllExtraHint;
1404 nsRevocableEventPtr<RestyleEvent> mRestyleEvent;
1406 nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState;
1408 nsDataHashtable<nsISupportsHashKey, RestyleData> mPendingRestyles;
1410 static nsIXBLService * gXBLService;
1413 #endif /* nsCSSFrameConstructor_h___ */