Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Member Functions | Static Public Member Functions | Static Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | Static Private Attributes | Friends
nsCSSFrameConstructor Class Reference

#include <nsCSSFrameConstructor.h>

Collaboration diagram for nsCSSFrameConstructor:
Collaboration graph
[legend]

List of all members.

Classes

struct  RestyleData
struct  RestyleEnumerateData
struct  RestyleEvent

Public Member Functions

 nsCSSFrameConstructor (nsIDocument *aDocument, nsIPresShell *aPresShell)
 ~nsCSSFrameConstructor (void)
nsresult ConstructRootFrame (nsIContent *aDocElement, nsIFrame **aNewFrame)
nsresult ReconstructDocElementHierarchy ()
nsresult ContentAppended (nsIContent *aContainer, PRInt32 aNewIndexInContainer)
nsresult ContentInserted (nsIContent *aContainer, nsIFrame *aContainerFrame, nsIContent *aChild, PRInt32 aIndexInContainer, nsILayoutHistoryState *aFrameState, PRBool aInReinsertContent)
nsresult ContentRemoved (nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer, PRBool aInReinsertContent)
nsresult CharacterDataChanged (nsIContent *aContent, PRBool aAppend)
nsresult ContentStatesChanged (nsIContent *aContent1, nsIContent *aContent2, PRInt32 aStateMask)
void NotifyDestroyingFrame (nsIFrame *aFrame)
nsresult AttributeChanged (nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRInt32 aModType)
void BeginUpdate ()
void EndUpdate ()
void RecalcQuotesAndCounters ()
void WillDestroyFrameTree ()
nsresult ProcessRestyledFrames (nsStyleChangeList &aRestyleArray)
void ProcessPendingRestyles ()
void PostRestyleEvent (nsIContent *aContent, nsReStyleHint aRestyleHint, nsChangeHint aMinChangeHint)
nsresult CantRenderReplacedElement (nsIFrame *aFrame)
nsresult CreateContinuingFrame (nsPresContext *aPresContext, nsIFrame *aFrame, nsIFrame *aParentFrame, nsIFrame **aContinuingFrame)
nsresult FindPrimaryFrameFor (nsFrameManager *aFrameManager, nsIContent *aContent, nsIFrame **aFrame, nsFindFrameHint *aHint)
nsresult GetInsertionPoint (nsIFrame *aParentFrame, nsIContent *aChildContent, nsIFrame **aInsertionPoint, PRBool *aMultiple=nsnull)
nsresult CreateListBoxContent (nsPresContext *aPresContext, nsIFrame *aParentFrame, nsIFrame *aPrevFrame, nsIContent *aChild, nsIFrame **aResult, PRBool aIsAppend, PRBool aIsScrollbar, nsILayoutHistoryState *aFrameState)
nsresult RemoveMappingsForFrameSubtree (nsIFrame *aRemovedFrame, nsILayoutHistoryState *aFrameState)
nsIFrameGetInitialContainingBlock ()
nsIFrameGetPageSequenceFrame ()

Static Public Member Functions

static nsIXBLServiceGetXBLService ()
static void ReleaseGlobals ()
static void GetAlternateTextFor (nsIContent *aContent, nsIAtom *aTag, nsXPIDLString &aAltText)

Static Protected Member Functions

static nsresult CreatePlaceholderFrameFor (nsIPresShell *aPresShell, nsPresContext *aPresContext, nsFrameManager *aFrameManager, nsIContent *aContent, nsIFrame *aFrame, nsStyleContext *aStyleContext, nsIFrame *aParentFrame, nsIFrame **aPlaceholderFrame)

Protected Attributes

nsCOMPtr< nsIEventQueuemRestyleEventQueue

Private Member Functions

 nsCSSFrameConstructor (const nsCSSFrameConstructor &aCopy)
nsCSSFrameConstructoroperator= (const nsCSSFrameConstructor &aCopy)
void ProcessOneRestyle (nsIContent *aContent, nsReStyleHint aRestyleHint, nsChangeHint aChangeHint)
nsresult ReinsertContent (nsIContent *aContainer, nsIContent *aChild)
nsresult ConstructPageFrame (nsIPresShell *aPresShell, nsPresContext *aPresContext, nsIFrame *aParentFrame, nsIFrame *aPrevPageFrame, nsIFrame *&aPageFrame, nsIFrame *&aPageContentFrame)
void DoContentStateChanged (nsIContent *aContent, PRInt32 aStateMask)
void RestyleElement (nsIContent *aContent, nsIFrame *aPrimaryFrame, nsChangeHint aMinHint)
void RestyleLaterSiblings (nsIContent *aContent)
nsresult InitAndRestoreFrame (const nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, nsIFrame *aPrevInFlow, nsIFrame *aNewFrame, PRBool aAllowCounters=PR_TRUE)
already_AddRefed< nsStyleContextResolveStyleContext (nsIFrame *aParentFrame, nsIContent *aContent)
nsresult ConstructFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsFrameItems &aFrameItems)
nsresult ConstructDocElementFrame (nsFrameConstructorState &aState, nsIContent *aDocElement, nsIFrame *aParentFrame, nsIFrame **aNewFrame)
 New one.
nsresult ConstructDocElementTableFrame (nsIContent *aDocElement, nsIFrame *aParentFrame, nsIFrame **aNewTableFrame, nsFrameConstructorState &aState)
nsresult CreateGeneratedFrameFor (nsIFrame *aParentFrame, nsIContent *aContent, nsStyleContext *aStyleContext, const nsStyleContent *aStyleContent, PRUint32 aContentIndex, nsIFrame **aFrame)
PRBool CreateGeneratedContentFrame (nsFrameConstructorState &aState, nsIFrame *aFrame, nsIContent *aContent, nsStyleContext *aStyleContext, nsIAtom *aPseudoElement, nsIFrame **aResult)
nsresult AppendFrames (const nsFrameConstructorState &aState, nsIContent *aContainer, nsIFrame *aParentFrame, nsIFrame *aFrameList, nsIFrame *aAfterFrame)
 This function is called by ContentAppended() and ContentInserted() when appending flowed frames to a parent's principal child list.
nsresult ConstructTableFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aContentParent, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, PRBool aIsPseudo, nsFrameItems &aChildItems, PRBool aAllowOutOfFlow, nsIFrame *&aNewOuterFrame, nsIFrame *&aNewInnerFrame)
 ConstructTableFrame will construct the outer and inner table frames and return them.
nsresult ConstructTableCaptionFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParent, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, nsFrameItems &aChildItems, nsIFrame *&aNewFrame, PRBool &aIsPseudoParent)
nsresult ConstructTableRowGroupFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParent, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, PRBool aIsPseudo, nsFrameItems &aChildItems, nsIFrame *&aNewFrame, PRBool &aIsPseudoParent)
nsresult ConstructTableColGroupFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParent, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, PRBool aIsPseudo, nsFrameItems &aChildItems, nsIFrame *&aNewFrame, PRBool &aIsPseudoParent)
nsresult ConstructTableRowFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParent, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, PRBool aIsPseudo, nsFrameItems &aChildItems, nsIFrame *&aNewFrame, PRBool &aIsPseudoParent)
nsresult ConstructTableColFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParent, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, PRBool aIsPseudo, nsFrameItems &aChildItems, nsIFrame *&aNewFrame, PRBool &aIsPseudoParent)
nsresult ConstructTableCellFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, PRBool aIsPseudo, nsFrameItems &aChildItems, nsIFrame *&aNewCellOuterFrame, nsIFrame *&aNewCellInnerFrame, PRBool &aIsPseudoParent)
nsresult ConstructTableForeignFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrameIn, nsStyleContext *aStyleContext, nsTableCreator &aTableCreator, nsFrameItems &aChildItems)
 ConstructTableForeignFrame constructs the frame for a non-table-element child of a table-element frame (where "table-element" can mean rows, cells, etc).
nsresult CreatePseudoTableFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame *aParentFrameIn=nsnull)
nsresult CreatePseudoRowGroupFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame *aParentFrameIn=nsnull)
nsresult CreatePseudoColGroupFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame *aParentFrameIn=nsnull)
nsresult CreatePseudoRowFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame *aParentFrameIn=nsnull)
nsresult CreatePseudoCellFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame *aParentFrameIn=nsnull)
nsresult GetPseudoTableFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame &aParentFrameIn)
nsresult GetPseudoColGroupFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame &aParentFrameIn)
nsresult GetPseudoRowGroupFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame &aParentFrameIn)
nsresult GetPseudoRowFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame &aParentFrameIn)
nsresult GetPseudoCellFrame (nsTableCreator &aTableCreator, nsFrameConstructorState &aState, nsIFrame &aParentFrameIn)
nsresult GetParentFrame (nsTableCreator &aTableCreator, nsIFrame &aParentFrameIn, nsIAtom *aChildFrameType, nsFrameConstructorState &aState, nsIFrame *&aParentFrame, PRBool &aIsPseudoParent)
nsresult AdjustParentFrame (nsIContent *aChildContent, const nsStyleDisplay *aChildDisplay, nsIAtom *aTag, PRInt32 aNameSpaceID, nsStyleContext *aChildStyle, nsIFrame *&aParentFrame, nsFrameItems *&aFrameItems, nsFrameConstructorState &aState, nsFrameConstructorSaveState &aSaveState, PRBool &aCreatedPseudo)
 Function to adjust aParentFrame and aFrameItems to deal with table pseudo-frames that may have to be inserted.
nsresult TableProcessChildren (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsTableCreator &aTableCreator, nsFrameItems &aChildItems, nsIFrame *&aCaption)
nsresult TableProcessChild (nsFrameConstructorState &aState, nsIContent *aChildContent, nsIContent *aParentContent, nsIFrame *aParentFrame, nsIAtom *aParentFrameType, nsStyleContext *aParentStyleContext, nsTableCreator &aTableCreator, nsFrameItems &aChildItems, nsIFrame *&aCaption)
const nsStyleDisplayGetDisplay (nsIFrame *aFrame)
nsresult ConstructAlternateFrame (nsIContent *aContent, nsStyleContext *aStyleContext, nsIFrame *aGeometricParent, nsIFrame *aContentParent, nsIFrame *&aFrame)
nsresult ConstructRadioControlFrame (nsIFrame **aNewFrame, nsIContent *aContent, nsStyleContext *aStyleContext)
nsresult ConstructCheckboxControlFrame (nsIFrame **aNewFrame, nsIContent *aContent, nsStyleContext *aStyleContext)
nsresult ConstructSelectFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsIAtom *aTag, nsStyleContext *aStyleContext, nsIFrame *&aNewFrame, const nsStyleDisplay *aStyleDisplay, PRBool &aFrameHasBeenInitialized, nsFrameItems &aFrameItems)
nsresult ConstructFieldSetFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsIAtom *aTag, nsStyleContext *aStyleContext, nsIFrame *&aNewFrame, nsFrameItems &aFrameItems, const nsStyleDisplay *aStyleDisplay, PRBool &aFrameHasBeenInitialized)
nsresult ConstructTextFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, nsFrameItems &aFrameItems, PRBool aPseudoParent)
nsresult ConstructPageBreakFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, nsFrameItems &aFrameItems)
PRBool PageBreakBefore (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, nsFrameItems &aFrameItems)
nsresult ConstructHTMLFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsIAtom *aTag, PRInt32 aNameSpaceID, nsStyleContext *aStyleContext, nsFrameItems &aFrameItems, PRBool aHasPseudoParent)
nsresult ConstructFrameInternal (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsIAtom *aTag, PRInt32 aNameSpaceID, nsStyleContext *aStyleContext, nsFrameItems &aFrameItems, PRBool aXBLBaseTag)
nsresult CreateAnonymousFrames (nsIAtom *aTag, nsFrameConstructorState &aState, nsIContent *aParent, nsIFrame *aNewFrame, PRBool aAppendToExisting, nsFrameItems &aChildItems, PRBool aIsRoot=PR_FALSE)
nsresult CreateAnonymousFrames (nsFrameConstructorState &aState, nsIContent *aParent, nsIDocument *aDocument, nsIFrame *aNewFrame, PRBool aForceBindingParent, PRBool aAppendToExisting, nsFrameItems &aChildItems, nsIFrame *aAnonymousCreator, nsIContent *aInsertionNode, PRBool aAnonymousParentIsBlock)
nsresult ConstructXULFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aParentFrame, nsIAtom *aTag, PRInt32 aNameSpaceID, nsStyleContext *aStyleContext, nsFrameItems &aFrameItems, PRBool aXBLBaseTag, PRBool aHasPseudoParent, PRBool *aHaltProcessing)
nsresult ConstructFrameByDisplayType (nsFrameConstructorState &aState, const nsStyleDisplay *aDisplay, nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aTag, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, nsFrameItems &aFrameItems, PRBool aHasPseudoParent)
nsresult ProcessChildren (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aFrame, PRBool aCanHaveGeneratedContent, nsFrameItems &aFrameItems, PRBool aParentIsBlock, nsTableCreator *aTableCreator=nsnull)
 Request to process the child content elements and create frames.
nsresult CreateInputFrame (nsIContent *aContent, nsIFrame **aFrame, nsStyleContext *aStyleContext)
nsresult AddDummyFrameToSelect (nsFrameConstructorState &aState, nsIFrame *aListFrame, nsIFrame *aParentFrame, nsFrameItems *aChildItems, nsIContent *aContainer, nsIDOMHTMLSelectElement *aSelectElement)
nsresult RemoveDummyFrameFromSelect (nsIContent *aContainer, nsIContent *aChild, nsIDOMHTMLSelectElement *aSelectElement)
nsIFrameGetFrameFor (nsIContent *aContent)
nsIFrameGetAbsoluteContainingBlock (nsIFrame *aFrame)
nsIFrameGetFloatContainingBlock (nsIFrame *aFrame)
nsIContentPropagateScrollToViewport ()
 This checks the root element and the HTML BODY, if any, for an "overflow" property that should be applied to the viewport.
nsresult BuildScrollFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsStyleContext *aContentStyle, nsIFrame *aScrolledFrame, nsIFrame *aParentFrame, nsIFrame *aContentParentFrame, nsIFrame *&aNewFrame, nsStyleContext *&aScrolledChildStyle)
 Called to wrap a gfx scrollframe around a frame.
already_AddRefed< nsStyleContextBeginBuildingScrollFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsStyleContext *aContentStyle, nsIFrame *aParentFrame, nsIFrame *aContentParentFrame, nsIAtom *aScrolledPseudo, PRBool aIsRoot, nsIFrame *&aNewFrame)
void FinishBuildingScrollFrame (nsIFrame *aScrollFrame, nsIFrame *aScrolledFrame)
nsresult InitializeSelectFrame (nsFrameConstructorState &aState, nsIFrame *scrollFrame, nsIFrame *scrolledFrame, nsIContent *aContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, PRBool aBuildCombobox, nsFrameItems &aFrameItems)
 Used to be InitializeScrollFrame but now its only used for the select tag But the select tag should really be fixed to use GFX scrollbars that can be create with BuildScrollFrame.
nsresult MaybeRecreateFramesForContent (nsIContent *aContent)
nsresult RecreateFramesForContent (nsIContent *aContent)
PRBool MaybeRecreateContainerForIBSplitterFrame (nsIFrame *aFrame, nsresult *aResult)
nsresult CreateContinuingOuterTableFrame (nsIPresShell *aPresShell, nsPresContext *aPresContext, nsIFrame *aFrame, nsIFrame *aParentFrame, nsIContent *aContent, nsStyleContext *aStyleContext, nsIFrame **aContinuingFrame)
nsresult CreateContinuingTableFrame (nsIPresShell *aPresShell, nsPresContext *aPresContext, nsIFrame *aFrame, nsIFrame *aParentFrame, nsIContent *aContent, nsStyleContext *aStyleContext, nsIFrame **aContinuingFrame)
already_AddRefed< nsStyleContextGetFirstLetterStyle (nsIContent *aContent, nsStyleContext *aStyleContext)
already_AddRefed< nsStyleContextGetFirstLineStyle (nsIContent *aContent, nsStyleContext *aStyleContext)
PRBool HaveFirstLetterStyle (nsIContent *aContent, nsStyleContext *aStyleContext)
PRBool HaveFirstLetterStyle (nsIFrame *aBlockFrame)
PRBool HaveFirstLineStyle (nsIContent *aContent, nsStyleContext *aStyleContext)
void HaveSpecialBlockStyle (nsIContent *aContent, nsStyleContext *aStyleContext, PRBool *aHaveFirstLetterStyle, PRBool *aHaveFirstLineStyle)
nsresult ConstructBlock (nsFrameConstructorState &aState, const nsStyleDisplay *aDisplay, nsIContent *aContent, nsIFrame *aParentFrame, nsIFrame *aContentParentFrame, nsStyleContext *aStyleContext, nsIFrame **aNewFrame, nsFrameItems &aFrameItems, PRBool aAbsPosContainer)
nsresult ConstructInline (nsFrameConstructorState &aState, const nsStyleDisplay *aDisplay, nsIContent *aContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, PRBool aIsPositioned, nsIFrame *aNewFrame)
nsresult ProcessInlineChildren (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aFrame, PRBool aCanHaveGeneratedContent, nsFrameItems &aFrameItems, PRBool *aKidsAllInline)
PRBool AreAllKidsInline (nsIFrame *aFrameList)
PRBool WipeContainingBlock (nsFrameConstructorState &aState, nsIFrame *blockContent, nsIFrame *aFrame, nsIFrame *aFrameList)
PRBool NeedSpecialFrameReframe (nsIContent *aParent1, nsIContent *aParent2, nsIFrame *&aParentFrame, nsIContent *aChild, PRInt32 aIndexInContainer, nsIFrame *&aPrevSibling, nsIFrame *aNextSibling)
nsresult SplitToContainingBlock (nsFrameConstructorState &aState, nsIFrame *aFrame, nsIFrame *aLeftInlineChildFrame, nsIFrame *aBlockChildFrame, nsIFrame *aRightInlineChildFrame, PRBool aTransfer)
nsresult ReframeContainingBlock (nsIFrame *aFrame)
nsresult StyleChangeReflow (nsIFrame *aFrame, nsIAtom *aAttribute)
nsIFrameFindFrameWithContent (nsFrameManager *aFrameManager, nsIFrame *aParentFrame, nsIContent *aParentContent, nsIContent *aContent, nsFindFrameHint *aHint)
 Helper function that searches the immediate child frames (and their children if the frames are "special") for a frame that maps the specified content object.
void CreateFloatingLetterFrame (nsFrameConstructorState &aState, nsIContent *aTextContent, nsIFrame *aTextFrame, nsIContent *aBlockContent, nsIFrame *aParentFrame, nsStyleContext *aStyleContext, nsFrameItems &aResult)
 Create a letter frame, only make it a floating frame.
nsresult CreateLetterFrame (nsFrameConstructorState &aState, nsIContent *aTextContent, nsIFrame *aParentFrame, nsFrameItems &aResult)
 Create a new letter frame for aTextFrame.
nsresult WrapFramesInFirstLetterFrame (nsFrameConstructorState &aState, nsIContent *aBlockContent, nsIFrame *aBlockFrame, nsFrameItems &aBlockFrames)
nsresult WrapFramesInFirstLetterFrame (nsFrameConstructorState &aState, nsIFrame *aParentFrame, nsIFrame *aParentFrameList, nsIFrame **aModifiedParent, nsIFrame **aTextFrame, nsIFrame **aPrevFrame, nsFrameItems &aLetterFrame, PRBool *aStopLooking)
nsresult RecoverLetterFrames (nsFrameConstructorState &aState, nsIFrame *aBlockFrame)
nsresult RemoveLetterFrames (nsPresContext *aPresContext, nsIPresShell *aPresShell, nsFrameManager *aFrameManager, nsIFrame *aBlockFrame)
nsresult RemoveFirstLetterFrames (nsPresContext *aPresContext, nsIPresShell *aPresShell, nsFrameManager *aFrameManager, nsIFrame *aFrame, PRBool *aStopLooking)
nsresult RemoveFloatingFirstLetterFrames (nsPresContext *aPresContext, nsIPresShell *aPresShell, nsFrameManager *aFrameManager, nsIFrame *aBlockFrame, PRBool *aStopLooking)
nsresult CaptureStateForFramesOf (nsIContent *aContent, nsILayoutHistoryState *aHistoryState)
nsresult CaptureStateFor (nsIFrame *aFrame, nsILayoutHistoryState *aHistoryState)
nsresult WrapFramesInFirstLineFrame (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aFrame, nsFrameItems &aFrameItems)
nsresult AppendFirstLineFrames (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aBlockFrame, nsFrameItems &aFrameItems)
nsresult InsertFirstLineFrames (nsFrameConstructorState &aState, nsIContent *aContent, nsIFrame *aBlockFrame, nsIFrame **aParentFrame, nsIFrame *aPrevSibling, nsFrameItems &aFrameItems)
nsresult RemoveFixedItems (const nsFrameConstructorState &aState)
nsIFrameFindPreviousSibling (nsIContent *aContainer, nsIFrame *aContainerFrame, PRInt32 aIndexInContainer, const nsIContent *aChild=nsnull)
 Find the ``rightmost'' frame for the content immediately preceding aIndexInContainer, following continuations if necessary.
nsIFrameFindNextSibling (nsIContent *aContainer, nsIFrame *aContainerFrame, PRInt32 aIndexInContainer, const nsIContent *aChild=nsnull)
 Find the frame for the content node immediately following aIndexInContainer.
PRBool IsValidSibling (nsIFrame *aParentFrame, const nsIFrame &aSibling, PRUint8 aSiblingDisplay, nsIContent &aContent, PRUint8 &aDisplay)
void QuotesDirty ()
void CountersDirty ()
 NS_HIDDEN_ (nsresult) CreateInsertionPointChildren(nsFrameConstructorState &aState
 CreateInsertionPointChildren (nsFrameConstructorState &aState, nsIFrame *aNewFrame, PRBool aUseInsertionFrame)

Private Attributes

nsIFrameaNewFrame
nsIFrame nsIContentaContent
nsIFrame nsIContent PRBool aUseInsertionFrame = PR_TRUE)
nsIDocumentmDocument
nsIPresShellmPresShell
nsIFramemInitialContainingBlock
nsIFramemFixedContainingBlock
nsIFramemDocElementContainingBlock
nsIFramemGfxScrollFrame
nsIFramemPageSequenceFrame
nsQuoteList mQuoteList
nsCounterManager mCounterManager
PRUint16 mUpdateCount
PRPackedBool mQuotesDirty: 1
PRPackedBool mCountersDirty: 1
PRPackedBool mInitialContainingBlockIsAbsPosContainer: 1
PRPackedBool mIsDestroyingFrameTree: 1
nsCOMPtr< nsILayoutHistoryStatemTempFrameTreeState
nsCOMPtr< nsIEventQueueServicemEventQueueService
nsDataHashtable
< nsISupportsHashKey,
RestyleData
mPendingRestyles

Static Private Attributes

static nsIXBLServicegXBLService = nsnull

Friends

struct RestyleData
struct RestyleEvent
class nsFrameConstructorState

Detailed Description

Definition at line 76 of file nsCSSFrameConstructor.h.


Constructor & Destructor Documentation

Definition at line 1910 of file nsCSSFrameConstructor.cpp.

  : mDocument(aDocument)
  , mPresShell(aPresShell)
  , mInitialContainingBlock(nsnull)
  , mFixedContainingBlock(nsnull)
  , mDocElementContainingBlock(nsnull)
  , mGfxScrollFrame(nsnull)
  , mPageSequenceFrame(nsnull)
  , mUpdateCount(0)
  , mQuotesDirty(PR_FALSE)
  , mCountersDirty(PR_FALSE)
  , mInitialContainingBlockIsAbsPosContainer(PR_FALSE)
  , mIsDestroyingFrameTree(PR_FALSE)
{
  if (!gGotXBLFormPrefs) {
    gGotXBLFormPrefs = PR_TRUE;

    gUseXBLForms =
      nsContentUtils::GetBoolPref("nglayout.debug.enable_xbl_forms");
  }

  // XXXbz this should be in Init() or something!
  if (!mPendingRestyles.Init()) {
    // now what?
  }

  // XXXbz this should be in Init() or something!
  mEventQueueService = do_GetService(kEventQueueServiceCID);
  
#ifdef DEBUG
  static PRBool gFirstTime = PR_TRUE;
  if (gFirstTime) {
    gFirstTime = PR_FALSE;
    char* flags = PR_GetEnv("GECKO_FRAMECTOR_DEBUG_FLAGS");
    if (flags) {
      PRBool error = PR_FALSE;
      for (;;) {
        char* comma = PL_strchr(flags, ',');
        if (comma)
          *comma = '\0';

        PRBool found = PR_FALSE;
        FrameCtorDebugFlags* flag = gFlags;
        FrameCtorDebugFlags* limit = gFlags + NUM_DEBUG_FLAGS;
        while (flag < limit) {
          if (PL_strcasecmp(flag->name, flags) == 0) {
            *(flag->on) = PR_TRUE;
            printf("nsCSSFrameConstructor: setting %s debug flag on\n", flag->name);
            found = PR_TRUE;
            break;
          }
          ++flag;
        }

        if (! found)
          error = PR_TRUE;

        if (! comma)
          break;

        *comma = ',';
        flags = comma + 1;
      }

      if (error) {
        printf("Here are the available GECKO_FRAMECTOR_DEBUG_FLAGS:\n");
        FrameCtorDebugFlags* flag = gFlags;
        FrameCtorDebugFlags* limit = gFlags + NUM_DEBUG_FLAGS;
        while (flag < limit) {
          printf("  %s\n", flag->name);
          ++flag;
        }
        printf("Note: GECKO_FRAMECTOR_DEBUG_FLAGS is a comma separated list of flag\n");
        printf("names (no whitespace)\n");
      }
    }
  }
#endif
}

Here is the call graph for this function:

Definition at line 80 of file nsCSSFrameConstructor.h.

{}

Member Function Documentation

nsresult nsCSSFrameConstructor::AddDummyFrameToSelect ( nsFrameConstructorState aState,
nsIFrame aListFrame,
nsIFrame aParentFrame,
nsFrameItems aChildItems,
nsIContent aContainer,
nsIDOMHTMLSelectElement aSelectElement 
) [private]

Definition at line 8984 of file nsCSSFrameConstructor.cpp.

{
  PRUint32 numOptions = 0;
  nsresult rv = aSelectElement->GetLength(&numOptions);
  if (NS_SUCCEEDED(rv) && 0 == numOptions) {
    nsISelectControlFrame* listFrame = nsnull;
    CallQueryInterface(aListFrame, &listFrame);
    if (listFrame) {
      nsIFrame* dummyFrame;
      listFrame->GetDummyFrame(&dummyFrame);

      if (!dummyFrame) {
        nsStyleContext* styleContext = aParentFrame->GetStyleContext();
        nsIFrame*         generatedFrame = nsnull;
        if (CreateGeneratedContentFrame(aState, aParentFrame, aContainer,
                                        styleContext,
                                        nsCSSAnonBoxes::dummyOption,
                                        &generatedFrame)) {
          // Add the generated frame to the child list
          if (aChildItems) {
            aChildItems->AddChild(generatedFrame);
          } else {
            aState.mFrameManager->AppendFrames(aParentFrame, nsnull,
                                               generatedFrame);
          }

          listFrame->SetDummyFrame(generatedFrame);
          return NS_OK;
        }
      }
    }
  }

  return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::AdjustParentFrame ( nsIContent aChildContent,
const nsStyleDisplay aChildDisplay,
nsIAtom aTag,
PRInt32  aNameSpaceID,
nsStyleContext aChildStyle,
nsIFrame *&  aParentFrame,
nsFrameItems *&  aFrameItems,
nsFrameConstructorState aState,
nsFrameConstructorSaveState aSaveState,
PRBool aCreatedPseudo 
) [private]

Function to adjust aParentFrame and aFrameItems to deal with table pseudo-frames that may have to be inserted.

Parameters:
aChildContentthe content node we want to construct a frame for
aChildDisplaythe display struct for aChildContent
aParentFramethe frame we think should be the parent. This will be adjusted to point to a pseudo-frame if needed.
aTagtag that would be used for frame construction
aNameSpaceIDnamespace that will be used for frame construction
aFrameItemsthe framelist we think we need to put the child frame into. If we have to construct pseudo-frames, we'll modify the pointer to point to the list the child frame should go into.
aStatethe nsFrameConstructorState we're using.
aSaveStatethe nsFrameConstructorSaveState we can use for pushing a float containing block if we have to do it.
aCreatedPseudowhether we had to create a pseudo-parent
Returns:
NS_OK on success, NS_ERROR_OUT_OF_MEMORY and such as needed.

Definition at line 3459 of file nsCSSFrameConstructor.cpp.

{
  NS_PRECONDITION(aChildDisplay, "Must have child's display struct");
  NS_PRECONDITION(aFrameItems, "Must have frame items to work with");

  aCreatedPseudo = PR_FALSE;
  if (!aParentFrame) {
    // Nothing to do here
    return NS_OK;
  }

  PRBool childIsSpecialContent = PR_FALSE; // lazy lookup
  // Only use the outer table frame as parent if the child is going to use a
  // tableCaptionFrame, otherwise the inner table frame is the parent
  // (bug 341858).
  if (aParentFrame->GetType() == nsLayoutAtoms::tableOuterFrame) {
    childIsSpecialContent = IsSpecialContent(aChildContent, aTag, aNameSpaceID,
                                             aChildStyle);
    if (childIsSpecialContent ||
       (aChildStyle->GetStyleDisplay()->mDisplay !=
       NS_STYLE_DISPLAY_TABLE_CAPTION)) {
      aParentFrame = aParentFrame->GetContentInsertionFrame();
    }
  }

  // If our parent is a table, table-row-group, or table-row, and
  // we're not table-related in any way, we have to create table
  // pseudo-frames so that we have a table cell to live in.
  if (IsTableRelated(aParentFrame->GetType(), PR_FALSE) &&
      (!IsTableRelated(aChildDisplay->mDisplay, PR_TRUE) ||
       // Also need to create a pseudo-parent if the child is going to end up
       // with a frame based on something other than display.
       childIsSpecialContent || // looked it up before
       IsSpecialContent(aChildContent, aTag, aNameSpaceID, aChildStyle))) {
    nsTableCreator tableCreator(aState.mPresShell);
    nsresult rv = GetPseudoCellFrame(tableCreator, aState, *aParentFrame);
    if (NS_FAILED(rv)) {
      return rv;
    }

    NS_ASSERTION(aState.mPseudoFrames.mCellInner.mFrame,
                 "Must have inner cell frame now!");

    aParentFrame = aState.mPseudoFrames.mCellInner.mFrame;
    aFrameItems = &aState.mPseudoFrames.mCellInner.mChildList;
    // We pushed an anonymous table cell.  The inner block of this
    // needs to become the float containing block.
    aState.PushFloatContainingBlock(aParentFrame, aSaveState, PR_FALSE,
                                    PR_FALSE);
    aCreatedPseudo = PR_TRUE;
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::AppendFirstLineFrames ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aBlockFrame,
nsFrameItems aFrameItems 
) [private]

Definition at line 12349 of file nsCSSFrameConstructor.cpp.

{
  // It's possible that aBlockFrame needs to have a first-line frame
  // created because it doesn't currently have any children.
  nsIFrame* blockKid = aBlockFrame->GetFirstChild(nsnull);
  if (!blockKid) {
    return WrapFramesInFirstLineFrame(aState, aContent,
                                      aBlockFrame, aFrameItems);
  }

  // Examine the last block child - if it's a first-line frame then
  // appended frames need special treatment.
  nsresult rv = NS_OK;
  nsFrameList blockFrames(blockKid);
  nsIFrame* lastBlockKid = blockFrames.LastChild();
  if (lastBlockKid->GetType() != nsLayoutAtoms::lineFrame) {
    // No first-line frame at the end of the list, therefore there is
    // an interveening block between any first-line frame the frames
    // we are appending. Therefore, we don't need any special
    // treatment of the appended frames.
    return rv;
  }
  nsIFrame* lineFrame = lastBlockKid;

  // Find the first and last inline frame in aFrameItems
  nsIFrame* kid = aFrameItems.childList;
  nsIFrame* firstInlineFrame = nsnull;
  nsIFrame* lastInlineFrame = nsnull;
  while (kid) {
    if (IsInlineFrame(kid)) {
      if (!firstInlineFrame) firstInlineFrame = kid;
      lastInlineFrame = kid;
    }
    else {
      break;
    }
    kid = kid->GetNextSibling();
  }

  // If we don't find any inline frames, then there is nothing to do
  if (!firstInlineFrame) {
    return rv;
  }

  // The inline frames get appended to the lineFrame. Make sure they
  // are reparented properly.
  nsIFrame* remainingFrames = lastInlineFrame->GetNextSibling();
  lastInlineFrame->SetNextSibling(nsnull);
  kid = firstInlineFrame;
  while (kid) {
    ReparentFrame(aState.mFrameManager, lineFrame, kid);
    kid = kid->GetNextSibling();
  }
  aState.mFrameManager->AppendFrames(lineFrame, nsnull, firstInlineFrame);

  // The remaining frames get appended to the block frame
  if (remainingFrames) {
    aFrameItems.childList = remainingFrames;
  }
  else {
    aFrameItems.childList = nsnull;
    aFrameItems.lastChild = nsnull;
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::AppendFrames ( const nsFrameConstructorState aState,
nsIContent aContainer,
nsIFrame aParentFrame,
nsIFrame aFrameList,
nsIFrame aAfterFrame 
) [private]

This function is called by ContentAppended() and ContentInserted() when appending flowed frames to a parent's principal child list.

It handles the case where the parent frame has :after pseudo-element generated content.

Definition at line 8188 of file nsCSSFrameConstructor.cpp.

{
#ifdef DEBUG
  nsIFrame* debugAfterFrame;
  nsIFrame* debugNewParent =
    ::AdjustAppendParentForAfterContent(aState.mPresContext, aContainer,
                                        aParentFrame, &debugAfterFrame);
  NS_ASSERTION(debugNewParent == aParentFrame, "Incorrect parent");
  NS_ASSERTION(debugAfterFrame == aAfterFrame, "Incorrect after frame");
#endif

  nsFrameManager* frameManager = aState.mFrameManager;
  if (aAfterFrame) {
    nsFrameList frames(aParentFrame->GetFirstChild(nsnull));

    // Insert the frames before the :after pseudo-element.
    return frameManager->InsertFrames(aParentFrame, nsnull,
                                      frames.GetPrevSiblingFor(aAfterFrame),
                                      aFrameList);
  }

  return frameManager->AppendFrames(aParentFrame, nsnull, aFrameList);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 13312 of file nsCSSFrameConstructor.cpp.

{
  nsIFrame* kid = aFrameList;
  while (kid) {
    if (!IsInlineFrame(kid)) {
      return PR_FALSE;
    }
    kid = kid->GetNextSibling();
  }
  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::AttributeChanged ( nsIContent aContent,
PRInt32  aNameSpaceID,
nsIAtom aAttribute,
PRInt32  aModType 
)

Definition at line 10678 of file nsCSSFrameConstructor.cpp.

{
  nsresult  result = NS_OK;

  // Hold onto the PresShell to prevent ourselves from being destroyed.
  // XXXbz how, exactly, would this attribute change cause us to be
  // destroyed from inside this function?
  nsCOMPtr<nsIPresShell> shell = mPresShell;

  // Get the frame associated with the content which is the highest in the frame tree
  nsIFrame* primaryFrame;
  shell->GetPrimaryFrameFor(aContent, &primaryFrame); 

#if 0
  NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
     ("HTMLStyleSheet::AttributeChanged: content=%p[%s] frame=%p",
      aContent, ContentTag(aContent, 0), frame));
#endif

  // the style tag has its own interpretation based on aHint 
  nsChangeHint hint = NS_STYLE_HINT_NONE;
  nsCOMPtr<nsIStyledContent> styledContent = do_QueryInterface(aContent);
  if (styledContent) { 
    // Get style hint from HTML content object. 
    hint = styledContent->GetAttributeChangeHint(aAttribute, aModType);
  } 

  PRBool reframe = (hint & nsChangeHint_ReconstructFrame) != 0;

#ifdef MOZ_XUL
  // The following listbox widget trap prevents offscreen listbox widget
  // content from being removed and re-inserted (which is what would
  // happen otherwise).
  if (!primaryFrame && !reframe) {
    PRInt32 namespaceID;
    nsCOMPtr<nsIAtom> tag;
    mDocument->BindingManager()->ResolveTag(aContent, &namespaceID,
                                            getter_AddRefs(tag));

    if (namespaceID == kNameSpaceID_XUL &&
        (tag == nsXULAtoms::listitem ||
         tag == nsXULAtoms::listcell))
      return NS_OK;
  }

  if (aAttribute == nsXULAtoms::tooltiptext ||
      aAttribute == nsXULAtoms::tooltip) 
  {
    nsIFrame* rootFrame = shell->FrameManager()->GetRootFrame();
    if (rootFrame)
      rootFrame = rootFrame->GetFirstChild(nsnull);
    nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
    if (rootBox) {
      if (aModType == nsIDOMMutationEvent::REMOVAL)
        rootBox->RemoveTooltipSupport(aContent);
      if (aModType == nsIDOMMutationEvent::ADDITION)
        rootBox->AddTooltipSupport(aContent);
    }
  }

#endif // MOZ_XUL

  // See if we have appearance information for a theme.
  if (primaryFrame) {
    const nsStyleDisplay* disp = primaryFrame->GetStyleDisplay();
    if (disp->mAppearance) {
      nsPresContext* presContext = mPresShell->GetPresContext();
      nsITheme *theme = presContext->GetTheme();
      if (theme && theme->ThemeSupportsWidget(presContext, primaryFrame, disp->mAppearance)) {
        PRBool repaint = PR_FALSE;
        theme->WidgetStateChanged(primaryFrame, disp->mAppearance, aAttribute, &repaint);
        if (repaint)
          NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
      }
    }
  }

  nsFrameManager *frameManager = shell->FrameManager();
  nsReStyleHint rshint = frameManager->HasAttributeDependentStyle(aContent,
                                                                  aAttribute,
                                                                  aModType);

  
  // let the frame deal with it now, so we don't have to deal later
  if (primaryFrame) {
    result = primaryFrame->AttributeChanged(aContent, aNameSpaceID,
                                            aAttribute, aModType);
    // XXXwaterson should probably check for special IB siblings
    // here, and propagate the AttributeChanged notification to
    // them, as well. Currently, inline frames don't do anything on
    // this notification, so it's not that big a deal.
  }

  // Menus and such can't deal with asynchronous changes of display
  // when the menugenerated or menuactive attribute changes, so make
  // sure to process that immediately
  if (aNameSpaceID == kNameSpaceID_None &&
      ((aAttribute == nsXULAtoms::menugenerated &&
        aModType != nsIDOMMutationEvent::REMOVAL) ||
       aAttribute == nsXULAtoms::menuactive)) {
    PRInt32 namespaceID;
    nsCOMPtr<nsIAtom> tag;
    mDocument->BindingManager()->ResolveTag(aContent, &namespaceID,
                                            getter_AddRefs(tag));

    if (namespaceID == kNameSpaceID_XUL &&
        (tag == nsXULAtoms::menupopup || tag == nsXULAtoms::popup ||
         tag == nsXULAtoms::tooltip || tag == nsXULAtoms::menu)) {
      nsIViewManager* viewManager = mPresShell->GetViewManager();
      viewManager->BeginUpdateViewBatch();
      ProcessOneRestyle(aContent, rshint, hint);
      viewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);

      return result;
    }
  }

  PostRestyleEvent(aContent, rshint, hint);

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

already_AddRefed< nsStyleContext > nsCSSFrameConstructor::BeginBuildingScrollFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsStyleContext aContentStyle,
nsIFrame aParentFrame,
nsIFrame aContentParentFrame,
nsIAtom aScrolledPseudo,
PRBool  aIsRoot,
nsIFrame *&  aNewFrame 
) [private]

Definition at line 6478 of file nsCSSFrameConstructor.cpp.

{
  // Check to see the type of parent frame so we know whether we need to 
  // turn off/on scaling for the scrollbars
  //
  // If the parent is a viewportFrame then we are the scrollbars for the UI
  // if not then we are scrollbars inside the document.
  PRBool noScalingOfTwips = PR_FALSE;
  PRBool isPrintPreview =
    aState.mPresContext->Type() == nsPresContext::eContext_PrintPreview;

  if (isPrintPreview) {
    noScalingOfTwips = aParentFrame->GetType() == nsLayoutAtoms::viewportFrame;
    if (noScalingOfTwips) {
      aState.mPresContext->SetScalingOfTwips(PR_FALSE);
    }
  }

  nsIFrame* parentFrame = nsnull;
  nsIFrame* gfxScrollFrame = aNewFrame;

  nsFrameItems anonymousItems;

  nsRefPtr<nsStyleContext> contentStyle = aContentStyle;

  if (!gfxScrollFrame) {
    // Build a XULScrollFrame when the child is a box, otherwise an
    // HTMLScrollFrame
    if (IsXULDisplayType(aContentStyle->GetStyleDisplay())) {
      NS_NewXULScrollFrame(mPresShell, &gfxScrollFrame, aIsRoot);
    } else {
      NS_NewHTMLScrollFrame(mPresShell, &gfxScrollFrame, aIsRoot);
    }

    InitAndRestoreFrame(aState, aContent, aParentFrame, contentStyle, nsnull,
                        gfxScrollFrame);

    // Create a view
    nsHTMLContainerFrame::CreateViewForFrame(gfxScrollFrame,
                                             aContentParentFrame, PR_FALSE);
  }

  // if there are any anonymous children for the scroll frame, create
  // frames for them.
  CreateAnonymousFrames(aState, aContent, mDocument, gfxScrollFrame, PR_FALSE,
                        PR_FALSE, anonymousItems, nsnull, nsnull, PR_FALSE);

  parentFrame = gfxScrollFrame;
  aNewFrame = gfxScrollFrame;

  // we used the style that was passed in. So resolve another one.
  nsStyleSet *styleSet = mPresShell->StyleSet();
  nsStyleContext* aScrolledChildStyle = styleSet->ResolvePseudoStyleFor(aContent,
                                                                        aScrolledPseudo,
                                                                        contentStyle).get();

  if (gfxScrollFrame) {
     gfxScrollFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                         anonymousItems.childList);
  }

  if (isPrintPreview && noScalingOfTwips) {
    aState.mPresContext->SetScalingOfTwips(PR_TRUE);
  }

  return aScrolledChildStyle;;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 133 of file nsCSSFrameConstructor.h.

{ ++mUpdateCount; }

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::BuildScrollFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsStyleContext aContentStyle,
nsIFrame aScrolledFrame,
nsIFrame aParentFrame,
nsIFrame aContentParentFrame,
nsIFrame *&  aNewFrame,
nsStyleContext *&  aScrolledContentStyle 
) [private]

Called to wrap a gfx scrollframe around a frame.

The hierarchy will look like this

------- for gfx scrollbars ------

       ScrollFrame
            ^
            |
          Frame (scrolled frame you passed in)

LEGEND:

ScrollFrame: This is a frame that manages gfx cross platform frame based scrollbars.

Parameters:
aContentthe content node of the child to wrap.
aScrolledFrameThe frame of the content to wrap. This should not be Initialized. This method will initialize it with a scrolled pseudo and no nsIContent. The content will be attached to the scrollframe returned.
aContentStylethe style context that has already been resolved for the content being passed in.
aParentFrameThe parent to attach the scroll frame to
aNewFrameThe new scrollframe or gfx scrollframe that we create. It will contain the scrolled frame you passed in. (returned) If this is not null, we'll just use it
aScrolledContentStylethe style that was resolved for the scrolled frame. (returned)

Definition at line 6601 of file nsCSSFrameConstructor.cpp.

{
    nsRefPtr<nsStyleContext> scrolledContentStyle =
      BeginBuildingScrollFrame(aState, aContent, aContentStyle, aParentFrame,
                               aContentParentFrame, nsCSSAnonBoxes::scrolledContent,
                               PR_FALSE, aNewFrame);
    
    InitAndRestoreFrame(aState, aContent, aNewFrame, scrolledContentStyle,
                        nsnull, aScrolledFrame);

    FinishBuildingScrollFrame(aNewFrame, aScrolledFrame);

    aScrolledContentStyle = scrolledContentStyle;

    // now set the primary frame to the ScrollFrame
    aState.mFrameManager->SetPrimaryFrameFor( aContent, aNewFrame );
    return NS_OK;

}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 11006 of file nsCSSFrameConstructor.cpp.

{
  nsresult                  rv = NS_OK;

  // Get parent frame and style context
  nsIFrame*                 parentFrame = aFrame->GetParent();
  nsStyleContext* styleContext = aFrame->GetStyleContext();

  // Get aFrame's content object and the tag name
  nsIAtom*                  tag;

  nsIContent* content = aFrame->GetContent();
  NS_ASSERTION(content, "null content object");
  tag = content->Tag();

  // Get the child list name that the frame is contained in
  nsCOMPtr<nsIAtom>  listName;
  GetChildListNameFor(parentFrame, aFrame, getter_AddRefs(listName));

  // If the frame is out of the flow, then it has a placeholder frame.
  nsPlaceholderFrame* placeholderFrame = nsnull;
  if (listName) {
    mPresShell->GetPlaceholderFrameFor(aFrame, (nsIFrame**) &placeholderFrame);
  }

  // Get the previous sibling frame
  nsFrameList frameList(parentFrame->GetFirstChild(listName));
  
  // See whether it's an IMG or an INPUT element (for image buttons)
  // or if it is an applet with no displayable children
  // XXX need to check nameSpaceID in these spots
  if (nsHTMLAtoms::img == tag || nsHTMLAtoms::input == tag ||
      (nsHTMLAtoms::applet == tag && !HasDisplayableChildren(aFrame))) {
    // Try and construct an alternate frame to use when the
    // image can't be rendered
    nsIFrame* newFrame;
    rv = ConstructAlternateFrame(content, styleContext,
                                 parentFrame, nsnull, newFrame);

    if (NS_SUCCEEDED(rv)) {
      nsFrameManager *frameManager = mPresShell->FrameManager();

      // Replace the old frame with the new frame

      ::DeletingFrameSubtree(mPresShell->GetPresContext(), frameManager,
                             aFrame);

      // Reset the primary frame mapping
      frameManager->SetPrimaryFrameFor(content, newFrame);

      // Replace the old frame with the new frame
      // XXXbz If this fails, we leak the content node newFrame points to!
      frameManager->ReplaceFrame(parentFrame, listName, aFrame, newFrame);

      // Now that we've replaced the primary frame, if there's a placeholder
      // frame then complete the transition from image frame to new frame
      if (placeholderFrame) {
        // Remove the association between the old frame and its placeholder
        frameManager->UnregisterPlaceholderFrame(placeholderFrame);
        
        // Placeholder frames have a pointer back to the out-of-flow frame.
        // Make sure that's correct, too.
        placeholderFrame->SetOutOfFlowFrame(newFrame);

        // Reuse the existing placeholder frame, and add an association to the
        // new frame
        frameManager->RegisterPlaceholderFrame(placeholderFrame);

        // XXX Work around a bug in the block code where the float won't get
        // reflowed unless the line containing the placeholder frame is reflowed...
        placeholderFrame->GetParent()->
          ReflowDirtyChild(mPresShell, placeholderFrame);
      }
    }

  } else if ((nsHTMLAtoms::object == tag) ||
             (nsHTMLAtoms::embed == tag) ||
             (nsHTMLAtoms::applet == tag)) {
    // It's an OBJECT, EMBED, or APPLET, so we should display the contents
    // instead
    nsIFrame* absoluteContainingBlock;
    nsIFrame* floatContainingBlock;
    nsIFrame* inFlowParent = parentFrame;

    // If the OBJECT frame is out-of-flow, then get the placeholder frame's
    // parent and use that when determining the absolute containing block and
    // float containing block
    if (placeholderFrame) {
      inFlowParent = placeholderFrame->GetParent();
    }

    absoluteContainingBlock = GetAbsoluteContainingBlock(inFlowParent);
    floatContainingBlock = GetFloatContainingBlock(inFlowParent);

#ifdef NS_DEBUG
    // Verify that we calculated the same containing block
    if (listName == nsLayoutAtoms::absoluteList) {
      NS_ASSERTION(absoluteContainingBlock == parentFrame,
                   "wrong absolute containing block");
    } else if (listName == nsLayoutAtoms::floatList) {
      NS_ASSERTION(floatContainingBlock == parentFrame,
                   "wrong float containing block");
    }
#endif

    // Now initialize the frame construction state
    nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                  absoluteContainingBlock,
                                  floatContainingBlock);
    nsFrameItems            frameItems;
    const nsStyleDisplay* display = styleContext->GetStyleDisplay();

    // Create a new frame based on the display type.
    // Note: if the old frame was out-of-flow, then so will the new frame
    // and we'll get a new placeholder frame
    // XXXbz handle pseudos?  Just trying to do it here doesn't quite work
    // because of the list-munging we end up doing later in this function....
    rv = ConstructFrameByDisplayType(state, display,
                                     content, content->GetNameSpaceID(), tag,
                                     inFlowParent, styleContext, frameItems,
                                     PR_FALSE);

    if (NS_FAILED(rv)) return rv;

    nsIFrame* newFrame = frameItems.childList;


    if (NS_SUCCEEDED(rv)) {
      if (placeholderFrame) {
        // Remove the association between the old frame and its placeholder
        // Note: ConstructFrameByDisplayType() will already have added an
        // association for the new placeholder frame
        state.mFrameManager->UnregisterPlaceholderFrame(placeholderFrame);

        // Verify that the new frame is also a placeholder frame
        NS_ASSERTION(IsPlaceholderFrame(newFrame), "unexpected frame type");

        // Replace the old placeholder frame with the new placeholder frame
        state.mFrameManager->ReplaceFrame(inFlowParent, nsnull,
                                          placeholderFrame, newFrame);
      }

      // Replace the primary frame
      if (listName == nsnull) {
        if (IsInlineFrame(parentFrame) && !AreAllKidsInline(newFrame)) {
          // We're in the uncomfortable position of being an inline
          // that now contains a block. As in ConstructInline(), break
          // the newly constructed frames into three lists: the inline
          // frames before the first block frame (list1), the inline
          // frames after the last block frame (list3), and all the
          // frames between the first and last block frames (list2).
          nsIFrame* list1 = newFrame;

          nsIFrame* prevToFirstBlock;
          nsIFrame* list2 = FindFirstBlock(list1, &prevToFirstBlock);
          NS_ASSERTION(list2, "Why did we get into this code?");
          
          if (prevToFirstBlock)
            prevToFirstBlock->SetNextSibling(nsnull);
          else list1 = nsnull;

          nsIFrame* afterFirstBlock = list2->GetNextSibling();

          nsIFrame* lastBlock = FindLastBlock(afterFirstBlock);
          if (! lastBlock)
            lastBlock = list2;

          nsIFrame* list3 = lastBlock->GetNextSibling();
          lastBlock->SetNextSibling(nsnull);

          // Create "special" inline-block linkage between the frames
          // XXXldb Do we really need to do this?  It doesn't seem
          // consistent with the use in ConstructInline.
          if (list1) {
            SetFrameIsSpecial(list1, list2);
            SetFrameIsSpecial(list2, list3);
            if (list3) {
              SetFrameIsSpecial(list3, nsnull);
            }
          }

          // Recursively split inlines back up to the first containing
          // block frame.
          SplitToContainingBlock(state, parentFrame, list1, list2, list3,
                                 PR_FALSE);
        }
      } else if (listName == nsLayoutAtoms::absoluteList) {
        newFrame = state.mAbsoluteItems.childList;
        state.mAbsoluteItems.childList = nsnull;
      } else if (listName == nsLayoutAtoms::fixedList) {
        newFrame = state.mFixedItems.childList;
        state.mFixedItems.childList = nsnull;
      } else if (listName == nsLayoutAtoms::floatList) {
        newFrame = state.mFloatedItems.childList;
        state.mFloatedItems.childList = nsnull;
      }
      ::DeletingFrameSubtree(state.mPresContext, state.mFrameManager, aFrame);
      state.mFrameManager->ReplaceFrame(parentFrame, listName, aFrame,
                                        newFrame);

      // Reset the primary frame mapping. Don't assume that
      // ConstructFrameByDisplayType() has done this
      state.mFrameManager->SetPrimaryFrameFor(content, newFrame);
    }
  } else if (nsHTMLAtoms::input == tag) {
    // XXX image INPUT elements are also image frames, but don't throw away the
    // image frame, because the frame class has extra logic that is specific to
    // INPUT elements

  } else {
    NS_ASSERTION(PR_FALSE, "unexpected tag");
  }

  return rv;
}

Here is the call graph for this function:

nsresult nsCSSFrameConstructor::CaptureStateFor ( nsIFrame aFrame,
nsILayoutHistoryState aHistoryState 
) [private]

Definition at line 11957 of file nsCSSFrameConstructor.cpp.

{
  if (aFrame && aHistoryState) {
    mPresShell->FrameManager()->CaptureFrameState(aFrame, aHistoryState);
  }
  return NS_OK;
}

Here is the caller graph for this function:

Definition at line 11942 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;

  nsIFrame* frame;
  rv = mPresShell->GetPrimaryFrameFor(aContent, &frame);
  if (NS_SUCCEEDED(rv) && frame) {
    CaptureStateFor(frame, aHistoryState);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 10369 of file nsCSSFrameConstructor.cpp.

{
  nsresult      rv = NS_OK;

  // Find the child frame
  nsIFrame* frame;
  mPresShell->GetPrimaryFrameFor(aContent, &frame);

  // Notify the first frame that maps the content. It will generate a reflow
  // command

  // It's possible the frame whose content changed isn't inserted into the
  // frame hierarchy yet, or that there is no frame that maps the content
  if (nsnull != frame) {
#if 0
    NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
       ("nsCSSFrameConstructor::CharacterDataChanged: content=%p[%s] subcontent=%p frame=%p",
        aContent, ContentTag(aContent, 0),
        aSubContent, frame));
#endif

    // Special check for text content that is a child of a letter frame.  If
    // this happens, we should remove the letter frame, do whatever we're
    // planning to do with this notification, then put the letter frame back.
    // Note that this is basically what ReinsertContent ends up doing; the
    // reason we dont' want to call that here is that our text content could be
    // native anonymous, in which case ReinsertContent would completely barf on
    // it.  And reinserting the non-anonymous ancestor would just lead us to
    // come back into this notification (e.g. if quotes or counters are
    // involved), leading to a loop.
    PRBool haveFirstLetterStyle = PR_FALSE;
    nsIFrame* block = nsnull;
    nsCOMPtr<nsITextContent> textContent(do_QueryInterface(aContent));
    if (textContent) {
      // Ok, it's text content. Now do some real work...
      block = GetFloatContainingBlock(frame);
      if (block) {
        // See if the block has first-letter style applied to it.
        haveFirstLetterStyle = HaveFirstLetterStyle(block);
        if (haveFirstLetterStyle) {
          RemoveLetterFrames(mPresShell->GetPresContext(), mPresShell,
                             mPresShell->FrameManager(), block);
          // Reget |frame|, since we might have killed it.  Do we
          // really need to call CharacterDataChanged in this case,
          // though?
          mPresShell->GetPrimaryFrameFor(aContent, &frame);
          NS_ASSERTION(frame, "Should have frame here!");
        }
      }
    }

    frame->CharacterDataChanged(mPresShell->GetPresContext(), aContent,
                                aAppend);

    if (haveFirstLetterStyle) {
      // Note that if we got here |block| is not null
      nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                    GetAbsoluteContainingBlock(frame),
                                    block, nsnull);
      RecoverLetterFrames(state, block);
    }
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructAlternateFrame ( nsIContent aContent,
nsStyleContext aStyleContext,
nsIFrame aGeometricParent,
nsIFrame aContentParent,
nsIFrame *&  aFrame 
) [private]

Definition at line 10883 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv;
  nsXPIDLString  altText;

  // Initialize OUT parameter
  aFrame = nsnull;

  // Get the alternate text to use
  GetAlternateTextFor(aContent, aContent->Tag(), altText);

  // Create a text content element for the alternate text
  nsCOMPtr<nsITextContent> altTextContent;
  rv = NS_NewTextNode(getter_AddRefs(altTextContent),
                      mDocument->NodeInfoManager());
  if (NS_FAILED(rv))
    return rv;

  // Set the content's text
  altTextContent->SetText(altText, PR_TRUE);
  
  // Set aContent as the parent content.
  // XXXbz should this set the binding parent to |altTextContent|?
  rv = altTextContent->BindToTree(mDocument, aContent, nsnull, PR_TRUE);
  if (NS_FAILED(rv)) {
    altTextContent->UnbindFromTree();
    return rv;
  }

  // XXXbz shouldn't it be set native anonymous too?

  // Create either an inline frame, block frame, or area frame
  nsIFrame* containerFrame;
  PRBool    isOutOfFlow = PR_FALSE;
  const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();
  
  if (display->IsAbsolutelyPositioned()) {
    NS_NewAbsoluteItemWrapperFrame(mPresShell, &containerFrame);
    isOutOfFlow = PR_TRUE;
  } else if (display->IsFloating()) {
    NS_NewFloatingItemWrapperFrame(mPresShell, &containerFrame);
    isOutOfFlow = PR_TRUE;
  } else if (NS_STYLE_DISPLAY_BLOCK == display->mDisplay) {
    NS_NewBlockFrame(mPresShell, &containerFrame);
  } else {
    NS_NewInlineFrame(mPresShell, &containerFrame);
  }
  nsPresContext* presContext = mPresShell->GetPresContext();
  containerFrame->Init(presContext, aContent, aGeometricParent, aStyleContext,
                       nsnull);
  nsHTMLContainerFrame::CreateViewForFrame(containerFrame, aContentParent,
                                           PR_FALSE);

  // If the frame is out-of-flow, then mark it as such
  if (isOutOfFlow) {
    containerFrame->AddStateBits(NS_FRAME_OUT_OF_FLOW);
  }

  // Create a text frame to display the alt-text. It gets a pseudo-element
  // style context
  nsIFrame*        textFrame;
  NS_NewTextFrame(mPresShell, &textFrame);

  nsRefPtr<nsStyleContext> textStyleContext;
  textStyleContext = mPresShell->StyleSet()->
    ResolveStyleForNonElement(aStyleContext);

  textFrame->Init(presContext, altTextContent, containerFrame,
                  textStyleContext, nsnull);
  containerFrame->SetInitialChildList(presContext, nsnull, textFrame);

  // Return the container frame
  aFrame = containerFrame;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructBlock ( nsFrameConstructorState aState,
const nsStyleDisplay aDisplay,
nsIContent aContent,
nsIFrame aParentFrame,
nsIFrame aContentParentFrame,
nsStyleContext aStyleContext,
nsIFrame **  aNewFrame,
nsFrameItems aFrameItems,
PRBool  aAbsPosContainer 
) [private]

Definition at line 13210 of file nsCSSFrameConstructor.cpp.

{
  // Create column wrapper if necessary
  nsIFrame* blockFrame = *aNewFrame;
  nsIFrame* parent = aParentFrame;
  nsIFrame* contentParent = aContentParentFrame;
  nsRefPtr<nsStyleContext> blockStyle = aStyleContext;
  const nsStyleColumn* columns = aStyleContext->GetStyleColumn();

  if (columns->mColumnCount != NS_STYLE_COLUMN_COUNT_AUTO
      || columns->mColumnWidth.GetUnit() != eStyleUnit_Auto) {
    nsIFrame* columnSetFrame = nsnull;
    NS_NewColumnSetFrame(mPresShell, &columnSetFrame, 0);
    if (!columnSetFrame) {
      return NS_ERROR_OUT_OF_MEMORY;
    }

    InitAndRestoreFrame(aState, aContent, aParentFrame, aStyleContext, nsnull,
                        columnSetFrame);
    // See if we need to create a view, e.g. the frame is absolutely positioned
    nsHTMLContainerFrame::CreateViewForFrame(columnSetFrame, aContentParentFrame,
                                             PR_FALSE);
    blockStyle = mPresShell->StyleSet()->
      ResolvePseudoStyleFor(aContent, nsCSSAnonBoxes::columnContent,
                            aStyleContext);
    contentParent = columnSetFrame;
    parent = columnSetFrame;
    *aNewFrame = columnSetFrame;

    columnSetFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                        blockFrame);

    blockFrame->AddStateBits(NS_BLOCK_SPACE_MGR);
  }

  InitAndRestoreFrame(aState, aContent, parent, blockStyle, nsnull,
                      blockFrame);

  nsresult rv = aState.AddChild(*aNewFrame, aFrameItems, aDisplay,
                                aContent, aStyleContext,
                                aContentParentFrame ? aContentParentFrame :
                                                      aParentFrame);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // See if we need to create a view, e.g. the frame is absolutely positioned
  nsHTMLContainerFrame::CreateViewForFrame(blockFrame, contentParent, PR_FALSE);

  // If we're the first block to be created (e.g., because we're
  // contained inside a XUL document), then make sure that we've got a
  // space manager so we can handle floats...
  if (! aState.mFloatedItems.containingBlock) {
    blockFrame->AddStateBits(NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT);
  }

  // We should make the outer frame be the absolute containing block,
  // if one is required. We have to do this because absolute
  // positioning must be computed with respect to the CSS dimensions
  // of the element, which are the dimensions of the outer block. But
  // we can't really do that because only blocks can have absolute
  // children. So use the block and try to compensate with hacks
  // in nsBlockFrame::CalculateContainingBlockSizeForAbsolutes.
  nsFrameConstructorSaveState absoluteSaveState;
  if (aAbsPosContainer) {
    //    NS_ASSERTION(aRelPos, "should have made area frame for this");
    aState.PushAbsoluteContainingBlock(blockFrame, absoluteSaveState);
  }

  // See if the block has first-letter style applied to it...
  PRBool haveFirstLetterStyle, haveFirstLineStyle;
  HaveSpecialBlockStyle(aContent, aStyleContext,
                        &haveFirstLetterStyle, &haveFirstLineStyle);

  // Process the child content
  nsFrameItems childItems;
  nsFrameConstructorSaveState floatSaveState;
  aState.PushFloatContainingBlock(blockFrame, floatSaveState,
                                  haveFirstLetterStyle,
                                  haveFirstLineStyle);
  rv = ProcessChildren(aState, aContent, blockFrame, PR_TRUE, childItems,
                       PR_TRUE);

  CreateAnonymousFrames(aContent->Tag(), aState, aContent, blockFrame,
                        PR_FALSE, childItems);

  // Set the frame's initial child list
  blockFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                  childItems.childList);

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructCheckboxControlFrame ( nsIFrame **  aNewFrame,
nsIContent aContent,
nsStyleContext aStyleContext 
) [private]

Definition at line 4997 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_NewGfxCheckboxControlFrame(mPresShell, aNewFrame);
  if (NS_FAILED(rv)) {
    *aNewFrame = nsnull;
    return rv;
  }

  nsRefPtr<nsStyleContext> checkboxStyle;
  checkboxStyle = mPresShell->StyleSet()->ResolvePseudoStyleFor(aContent,
                                                                nsCSSAnonBoxes::check, 
                                                                aStyleContext);
  nsICheckboxControlFrame* checkbox = nsnull;
  if (*aNewFrame && NS_SUCCEEDED(CallQueryInterface(*aNewFrame, &checkbox))) {
    checkbox->SetCheckboxFaceStyleContext(checkboxStyle);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructDocElementFrame ( nsFrameConstructorState aState,
nsIContent aDocElement,
nsIFrame aParentFrame,
nsIFrame **  aNewFrame 
) [private]

New one.

Definition at line 4411 of file nsCSSFrameConstructor.cpp.

{
    // how the root frame hierarchy should look

    /*

---------------No Scrollbars------


     AreaFrame or BoxFrame (InitialContainingBlock)
  


---------------Gfx Scrollbars ------


     ScrollFrame

         ^
         |
         |
     AreaFrame or BoxFrame (InitialContainingBlock)
          
*/    

  *aNewFrame = nsnull;

  if (!mTempFrameTreeState)
    aState.mPresShell->CaptureHistoryState(getter_AddRefs(mTempFrameTreeState));

  // ----- reattach gfx scrollbars ------
  // Gfx scrollframes were created in the root frame but the primary frame map may have been destroyed if a 
  // new style sheet was loaded so lets reattach the frames to their content.
  // XXX this seems truly bogus, we wipe out mGfxScrollFrame below
  if (mGfxScrollFrame) {
    nsIFrame* gfxScrollbarFrame1 = mGfxScrollFrame->GetFirstChild(nsnull);
    if (gfxScrollbarFrame1) {
      // XXX This works, but why?
      aState.mFrameManager->
        SetPrimaryFrameFor(gfxScrollbarFrame1->GetContent(), gfxScrollbarFrame1);

      nsIFrame* gfxScrollbarFrame2 = gfxScrollbarFrame1->GetNextSibling();
      if (gfxScrollbarFrame2) {
        // XXX This works, but why?
        aState.mFrameManager->
          SetPrimaryFrameFor(gfxScrollbarFrame2->GetContent(), gfxScrollbarFrame2);
      }
    }
  }

  // --------- CREATE AREA OR BOX FRAME -------
  nsRefPtr<nsStyleContext> styleContext;
  styleContext = mPresShell->StyleSet()->ResolveStyleFor(aDocElement,
                                                         nsnull);

  const nsStyleDisplay* display = styleContext->GetStyleDisplay();

  // Ensure that our XBL bindings are installed.
  if (display->mBinding) {
    // Get the XBL loader.
    nsresult rv;
    PRBool resolveStyle;
    
    nsIXBLService * xblService = GetXBLService();
    if (!xblService)
      return NS_ERROR_FAILURE;

    nsRefPtr<nsXBLBinding> binding;
    rv = xblService->LoadBindings(aDocElement, display->mBinding, PR_FALSE,
                                  getter_AddRefs(binding), &resolveStyle);
    if (NS_FAILED(rv))
      return NS_OK; // Binding will load asynchronously.

    if (binding) {
      mDocument->BindingManager()->AddToAttachedQueue(binding);
    }

    if (resolveStyle) {
      styleContext = mPresShell->StyleSet()->ResolveStyleFor(aDocElement,
                                                             nsnull);
      display = styleContext->GetStyleDisplay();
    }
  }

  // --------- IF SCROLLABLE WRAP IN SCROLLFRAME --------

  PRBool propagatedScrollToViewport =
    PropagateScrollToViewport() == aDocElement;

  // The document root should not be scrollable in any paginated context,
  // even in print preview.
  PRBool isScrollable = display->IsScrollableOverflow()
    && !aState.mPresContext->IsPaginated()
    && !propagatedScrollToViewport;

  nsIFrame* scrollFrame = nsnull;

  // build a scrollframe
  if (isScrollable) {
    nsRefPtr<nsStyleContext> newContext;

    newContext = BeginBuildingScrollFrame( aState,
                                           aDocElement,
                                           styleContext,
                                           aParentFrame,
                                           nsnull,
                                           nsCSSAnonBoxes::scrolledContent,
                                           PR_FALSE,
                                           scrollFrame);

    styleContext = newContext;
    aParentFrame = scrollFrame;
  }

  nsIFrame* contentFrame = nsnull;
  PRBool isBlockFrame = PR_FALSE;
  nsresult rv;

  // The rules from CSS 2.1, section 9.2.4, have already been applied
  // by the style system, so we can assume that display->mDisplay is
  // either NONE, BLOCK, or TABLE.

  PRBool docElemIsTable = display->mDisplay == NS_STYLE_DISPLAY_TABLE;

  if (docElemIsTable) {
    // if the document is a table then just populate it.
    rv = ConstructDocElementTableFrame(aDocElement, aParentFrame, &contentFrame,
                                       aState);
    if (NS_FAILED(rv)) {
      return rv;
    }
    styleContext = contentFrame->GetStyleContext();
  } else {
    // otherwise build a box or a block
#ifdef MOZ_XUL
    if (aDocElement->IsContentOfType(nsIContent::eXUL)) {
      rv = NS_NewDocElementBoxFrame(mPresShell, &contentFrame);
      if (NS_FAILED(rv)) {
        return rv;
      }
    }
    else
#endif 
#ifdef MOZ_SVG
    if (aDocElement->GetNameSpaceID() == kNameSpaceID_SVG &&
        nsSVGUtils::SVGEnabled()) {
      rv = NS_NewSVGOuterSVGFrame(mPresShell, aDocElement, &contentFrame);
      if (NS_FAILED(rv)) {
        return rv;
      }
    }
    else 
#endif
    {
      rv = NS_NewDocumentElementFrame(mPresShell, &contentFrame);
      if (NS_FAILED(rv)) {
        return rv;
      }
      isBlockFrame = PR_TRUE;
    }

    // initialize the child
    InitAndRestoreFrame(aState, aDocElement, aParentFrame, styleContext,
                        nsnull, contentFrame);
  }

  // set the primary frame
  aState.mFrameManager->SetPrimaryFrameFor(aDocElement, contentFrame);

  // Finish building the scrollframe
  if (isScrollable) {
    FinishBuildingScrollFrame(aParentFrame, contentFrame);
    // primary is set above (to the contentFrame)
    
    *aNewFrame = scrollFrame;
  } else {
    // if not scrollable the new frame is the content frame.
    *aNewFrame = contentFrame;
  }

  mInitialContainingBlock = contentFrame;
  mInitialContainingBlockIsAbsPosContainer = PR_FALSE;

  // if it was a table then we don't need to process our children.
  if (!docElemIsTable) {
    // Process the child content
    nsFrameConstructorSaveState absoluteSaveState;
    nsFrameConstructorSaveState floatSaveState;
    nsFrameItems                childItems;

    if (isBlockFrame) {
      PRBool haveFirstLetterStyle, haveFirstLineStyle;
      HaveSpecialBlockStyle(aDocElement, styleContext,
                            &haveFirstLetterStyle, &haveFirstLineStyle);
      mInitialContainingBlockIsAbsPosContainer = PR_TRUE;
      aState.PushAbsoluteContainingBlock(contentFrame, absoluteSaveState);
      aState.PushFloatContainingBlock(contentFrame, floatSaveState,
                                      haveFirstLetterStyle,
                                      haveFirstLineStyle);
    }

    // Create any anonymous frames the doc element frame requires
    // This must happen before ProcessChildren to ensure that popups are
    // never constructed before the popupset.
    CreateAnonymousFrames(nsnull, aState, aDocElement, contentFrame,
                          PR_FALSE, childItems, PR_TRUE);
    ProcessChildren(aState, aDocElement, contentFrame, PR_TRUE, childItems,
                    isBlockFrame);

    // Set the initial child lists
    contentFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                      childItems.childList);
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructDocElementTableFrame ( nsIContent aDocElement,
nsIFrame aParentFrame,
nsIFrame **  aNewTableFrame,
nsFrameConstructorState aState 
) [private]

Definition at line 4296 of file nsCSSFrameConstructor.cpp.

{
  nsFrameItems    frameItems;

  // XXXbz this is wrong.  We should at least be setting the fixed container in
  // the framestate here.  Better yet, we should pass through aState
  // unmodified.  Can't do that, though, because then a fixed or absolute
  // positioned root table with auto offsets would look for a block to compute
  // its hypothetical box and crash.  So we just disable fixed positioning
  // altogether in documents where the root is a table.  Oh, well.
  nsFrameConstructorState state(mPresShell, nsnull, nsnull, nsnull,
                                aState.mFrameState);
  ConstructFrame(state, aDocElement, aParentFrame, frameItems);
  *aNewTableFrame = frameItems.childList;
  if (!*aNewTableFrame) {
    NS_WARNING("cannot get table contentFrame");
    // XXXbz maybe better to return the error from ConstructFrame?
    return NS_ERROR_FAILURE;
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructFieldSetFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsIAtom aTag,
nsStyleContext aStyleContext,
nsIFrame *&  aNewFrame,
nsFrameItems aFrameItems,
const nsStyleDisplay aStyleDisplay,
PRBool aFrameHasBeenInitialized 
) [private]

Definition at line 5282 of file nsCSSFrameConstructor.cpp.

{
  nsIFrame * newFrame;
  nsresult rv = NS_NewFieldSetFrame(mPresShell, &newFrame, NS_BLOCK_SPACE_MGR);
  if (NS_FAILED(rv)) {
    return rv;
  }

  // Initialize it
  InitAndRestoreFrame(aState, aContent, 
                      aState.GetGeometricParent(aStyleDisplay, aParentFrame),
                      aStyleContext, nsnull, newFrame);

  // See if we need to create a view, e.g. the frame is absolutely
  // positioned
  nsHTMLContainerFrame::CreateViewForFrame(newFrame, aParentFrame, PR_FALSE);

  nsIFrame* areaFrame;
  NS_NewAreaFrame(mPresShell, &areaFrame,
                  NS_BLOCK_SPACE_MGR | NS_BLOCK_SHRINK_WRAP | NS_BLOCK_MARGIN_ROOT);

  // Resolve style and initialize the frame
  nsRefPtr<nsStyleContext> styleContext;
  styleContext = mPresShell->StyleSet()->ResolvePseudoStyleFor(aContent,
                                                               nsCSSAnonBoxes::fieldsetContent,
                                                               aStyleContext);
  InitAndRestoreFrame(aState, aContent, newFrame, styleContext, nsnull,
                      areaFrame);

  rv = aState.AddChild(newFrame, aFrameItems, aStyleDisplay, aContent,
                       aStyleContext, aParentFrame);
  if (NS_FAILED(rv)) {
    return rv;
  }
  

  // The area frame is a float container
  PRBool haveFirstLetterStyle, haveFirstLineStyle;
  HaveSpecialBlockStyle(aContent, aStyleContext,
                        &haveFirstLetterStyle, &haveFirstLineStyle);
  nsFrameConstructorSaveState floatSaveState;
  aState.PushFloatContainingBlock(areaFrame, floatSaveState,
                                  haveFirstLetterStyle,
                                  haveFirstLineStyle);

  // Process children
  nsFrameConstructorSaveState absoluteSaveState;
  nsFrameItems                childItems;

  if (aStyleDisplay->IsPositioned()) {
    // The area frame becomes a container for child frames that are
    // absolutely positioned
    aState.PushAbsoluteContainingBlock(areaFrame, absoluteSaveState);
  }

  ProcessChildren(aState, aContent, areaFrame, PR_FALSE,
                  childItems, PR_TRUE);

  static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID);
  nsIFrame * child      = childItems.childList;
  nsIFrame * previous   = nsnull;
  nsIFrame* legendFrame = nsnull;
  while (nsnull != child) {
    nsresult result = child->QueryInterface(kLegendFrameCID, (void**)&legendFrame);
    if (NS_SUCCEEDED(result) && legendFrame) {
      // We want the legend to be the first frame in the fieldset child list.
      // That way the EventStateManager will do the right thing when tabbing
      // from a selection point within the legend (bug 236071), which is
      // used for implementing legend access keys (bug 81481).
      // GetAdjustedParentFrame() below depends on this frame order.
      if (nsnull != previous) {
        previous->SetNextSibling(legendFrame->GetNextSibling());
      } else {
        childItems.childList = legendFrame->GetNextSibling();
      }
      legendFrame->SetNextSibling(areaFrame);
      legendFrame->SetParent(newFrame);
      break;
    }
    previous = child;
    child = child->GetNextSibling();
  }

  // Set the scrolled frame's initial child lists
  areaFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                 childItems.childList);

  // Set the scroll frame's initial child list
  newFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                legendFrame ? legendFrame : areaFrame);

  // our new frame retured is the top frame which is the list frame. 
  aNewFrame = newFrame; 

  // yes we have already initialized our frame 
  aFrameHasBeenInitialized = PR_TRUE; 

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsFrameItems aFrameItems 
) [private]

Definition at line 7752 of file nsCSSFrameConstructor.cpp.

{
  NS_PRECONDITION(nsnull != aParentFrame, "no parent frame");

  nsresult rv = NS_OK;

  // don't create a whitespace frame if aParent doesn't want it
  if (!NeedFrameFor(aParentFrame, aContent)) {
    return rv;
  }

  // never create frames for comments or PIs
  if (aContent->IsContentOfType(nsIContent::eCOMMENT) ||
      aContent->IsContentOfType(nsIContent::ePROCESSING_INSTRUCTION))
    return rv;

  nsRefPtr<nsStyleContext> styleContext;
  styleContext = ResolveStyleContext(aParentFrame, aContent);

  PRBool pageBreakAfter = PR_FALSE;

  if (aState.mPresContext->IsPaginated()) {
    // See if there is a page break before, if so construct one. Also see if there is one after
    pageBreakAfter = PageBreakBefore(aState, aContent, aParentFrame,
                                     styleContext, aFrameItems);
  }
  // construct the frame
  rv = ConstructFrameInternal(aState, aContent, aParentFrame,
                              aContent->Tag(), aContent->GetNameSpaceID(),
                              styleContext, aFrameItems, PR_FALSE);
  if (NS_SUCCEEDED(rv) && pageBreakAfter) {
    // Construct the page break after
    ConstructPageBreakFrame(aState, aContent, aParentFrame, styleContext,
                            aFrameItems);
  }
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructFrameByDisplayType ( nsFrameConstructorState aState,
const nsStyleDisplay aDisplay,
nsIContent aContent,
PRInt32  aNameSpaceID,
nsIAtom aTag,
nsIFrame aParentFrame,
nsStyleContext aStyleContext,
nsFrameItems aFrameItems,
PRBool  aHasPseudoParent 
) [private]

Definition at line 6629 of file nsCSSFrameConstructor.cpp.

{
  PRBool    primaryFrameSet = PR_FALSE;
  nsIFrame* newFrame = nsnull;  // the frame we construct
  nsTableCreator tableCreator(mPresShell); // Used to make table frames.
  PRBool    addToHashTable = PR_TRUE;
  PRBool    addedToFrameList = PR_FALSE;
  nsresult  rv = NS_OK;

  // The style system ensures that floated and positioned frames are
  // block-level.
  NS_ASSERTION(!(aDisplay->IsFloating() ||
                 aDisplay->IsAbsolutelyPositioned()) ||
               aDisplay->IsBlockLevel(),
               "Style system did not apply CSS2.1 section 9.7 fixups");

  // If this is "body", try propagating its scroll style to the viewport
  // Note that we need to do this even if the body is NOT scrollable;
  // it might have dynamically changed from scrollable to not scrollable,
  // and that might need to be propagated.
  PRBool propagatedScrollToViewport = PR_FALSE;
  if (aContent->GetNodeInfo()->Equals(nsHTMLAtoms::body) &&
      aContent->IsContentOfType(nsIContent::eHTML)) {
    propagatedScrollToViewport =
      PropagateScrollToViewport() == aContent;
  }

  // If the frame is a block-level frame and is scrollable, then wrap it
  // in a scroll frame.
  // XXX Ignore tables for the time being
  if (aDisplay->IsBlockLevel() &&
      aDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE &&
      aDisplay->IsScrollableOverflow() &&
      !propagatedScrollToViewport) {

    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }

    nsRefPtr<nsStyleContext> scrolledContentStyle
      = BeginBuildingScrollFrame(aState, aContent, aStyleContext,
                                 aState.GetGeometricParent(aDisplay, aParentFrame),
                                 aParentFrame,
                                 nsCSSAnonBoxes::scrolledContent,
                                 PR_FALSE, newFrame);
    
    // Initialize it
    nsIFrame* scrolledFrame = nsnull;
    NS_NewAreaFrame(mPresShell, &scrolledFrame, NS_BLOCK_SPACE_MGR |
                    NS_BLOCK_SHRINK_WRAP | NS_BLOCK_MARGIN_ROOT);
    nsFrameItems blockItem;
    rv = ConstructBlock(aState,
                        scrolledContentStyle->GetStyleDisplay(), aContent,
                        newFrame, newFrame, scrolledContentStyle,
                        &scrolledFrame, blockItem, aDisplay->IsPositioned());
    NS_ASSERTION(blockItem.childList == scrolledFrame,
                 "Scrollframe's frameItems should be exactly the scrolled frame");
    FinishBuildingScrollFrame(newFrame, scrolledFrame);

    rv = aState.AddChild(newFrame, aFrameItems, aDisplay, aContent,
                         aStyleContext, aParentFrame);
    if (NS_FAILED(rv)) {
      return rv;
    }

    addedToFrameList = PR_TRUE;
  }
  // See if the frame is absolute or fixed positioned
  else if (aDisplay->IsAbsolutelyPositioned() &&
           (NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay ||
            NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay)) {

    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }

    // Create a frame to wrap up the absolute positioned item
    NS_NewAbsoluteItemWrapperFrame(mPresShell, &newFrame);

    rv = ConstructBlock(aState, aDisplay, aContent,
                        aState.GetGeometricParent(aDisplay, aParentFrame), aParentFrame,
                        aStyleContext, &newFrame, aFrameItems, PR_TRUE);
    if (NS_FAILED(rv)) {
      return rv;
    }

    addedToFrameList = PR_TRUE;
  }
  // See if the frame is floated and it's a block frame
  else if (aDisplay->IsFloating() &&
           (NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay ||
            NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay)) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    // Create an area frame
    NS_NewFloatingItemWrapperFrame(mPresShell, &newFrame);

    rv = ConstructBlock(aState, aDisplay, aContent, 
                        aState.GetGeometricParent(aDisplay, aParentFrame),
                        aParentFrame, aStyleContext, &newFrame, aFrameItems,
                        aDisplay->mPosition == NS_STYLE_POSITION_RELATIVE);
    if (NS_FAILED(rv)) {
      return rv;
    }

    addedToFrameList = PR_TRUE;
  }
  // See if it's relatively positioned
  else if ((NS_STYLE_POSITION_RELATIVE == aDisplay->mPosition) &&
           ((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
            (NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay) ||
            (NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay))) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    // Is it block-level or inline-level?
    if ((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
        (NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay)) {
      // Create a wrapper frame. No space manager, though
      NS_NewRelativeItemWrapperFrame(mPresShell, &newFrame);
      // XXXbz should we be passing in a non-null aContentParentFrame?
      ConstructBlock(aState, aDisplay, aContent,
                     aParentFrame, nsnull, aStyleContext, &newFrame,
                     aFrameItems, PR_TRUE);
      addedToFrameList = PR_TRUE;
    } else {
      // Create a positioned inline frame
      NS_NewPositionedInlineFrame(mPresShell, &newFrame);
      // Note that we want to insert the inline after processing kids, since
      // processing of kids may split the inline.
      ConstructInline(aState, aDisplay, aContent,
                      aParentFrame, aStyleContext, PR_TRUE, newFrame);
    }
  }
  // See if it's a block frame of some sort
  else if ((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
           (NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay) ||
           (NS_STYLE_DISPLAY_RUN_IN == aDisplay->mDisplay) ||
           (NS_STYLE_DISPLAY_COMPACT == aDisplay->mDisplay) ||
           (NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay)) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    PRUint32 flags = 0;
    if (NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay) {
      flags = NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT;
    }
    // Create the block frame
    rv = NS_NewBlockFrame(mPresShell, &newFrame, flags);
    if (NS_SUCCEEDED(rv)) { // That worked so construct the block and its children
      // XXXbz should we be passing in a non-null aContentParentFrame?
      rv = ConstructBlock(aState, aDisplay, aContent,
                          aParentFrame, nsnull, aStyleContext, &newFrame,
                          aFrameItems, PR_FALSE);
      addedToFrameList = PR_TRUE;
    }
  }
  // See if it's an inline frame of some sort
  else if ((NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay) ||
           (NS_STYLE_DISPLAY_MARKER == aDisplay->mDisplay)) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    // Create the inline frame
    rv = NS_NewInlineFrame(mPresShell, &newFrame);
    if (NS_SUCCEEDED(rv)) { // That worked so construct the inline and its children
      // Note that we want to insert the inline after processing kids, since
      // processing of kids may split the inline.
      rv = ConstructInline(aState, aDisplay, aContent,
                           aParentFrame, aStyleContext, PR_FALSE, newFrame);
    }

    // To keep the hash table small don't add inline frames (they're
    // typically things like FONT and B), because we can quickly
    // find them if we need to
    addToHashTable = PR_FALSE;
  }
  // otherwise let the display property influence the frame type to create
  else {
    // XXX This section now only handles table frames; should be
    // factored out probably

    // Use the 'display' property to choose a frame type
    switch (aDisplay->mDisplay) {
    case NS_STYLE_DISPLAY_TABLE:
    {
      // XXXbz this isn't quite right, but checking for aHasPseudoParent here
      // would just lead us to ProcessPseudoFrames inside ConstructTableFrame.
      if (!aState.mPseudoFrames.IsEmpty()) {
        ProcessPseudoFrames(aState, aFrameItems); 
      }
      nsIFrame* innerTable;
      rv = ConstructTableFrame(aState, aContent, 
                               aParentFrame, aStyleContext,
                               tableCreator, PR_FALSE, aFrameItems, PR_TRUE,
                               newFrame, innerTable);
      addedToFrameList = PR_TRUE;
      // Note: table construction function takes care of initializing
      // the frame, processing children, and setting the initial child
      // list
      break;
    }
  
    // the next 5 cases are only relevant if the parent is not a table, ConstructTableFrame handles children
    case NS_STYLE_DISPLAY_TABLE_CAPTION:
    {
      // aParentFrame may be an inner table frame rather than an outer frame 
      // In this case we need to get the outer frame.
      nsIFrame* parentFrame = aParentFrame;
      nsIFrame* outerFrame = aParentFrame->GetParent();
      if (outerFrame) {
        if ((nsLayoutAtoms::tableOuterFrame == outerFrame->GetType()) &&
            (nsLayoutAtoms::tableFrame == parentFrame->GetType())) {
          parentFrame = outerFrame;
        }
      }
      rv = ConstructTableCaptionFrame(aState, aContent, parentFrame,
                                      aStyleContext, tableCreator, aFrameItems,
                                      newFrame, aHasPseudoParent);
      if (NS_SUCCEEDED(rv) && !aHasPseudoParent) {
        aFrameItems.AddChild(newFrame);
      }
      return rv;
    }

    case NS_STYLE_DISPLAY_TABLE_ROW_GROUP:
    case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
    case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
      rv = ConstructTableRowGroupFrame(aState, aContent, 
                                       aParentFrame, aStyleContext, tableCreator, 
                                       PR_FALSE, aFrameItems, newFrame, aHasPseudoParent);
      if (NS_SUCCEEDED(rv) && !aHasPseudoParent) {
        aFrameItems.AddChild(newFrame);
      }
      return rv;

    case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP:
      rv = ConstructTableColGroupFrame(aState, aContent, aParentFrame,
                                       aStyleContext, tableCreator, 
                                       PR_FALSE, aFrameItems, newFrame,
                                       aHasPseudoParent);
      if (NS_SUCCEEDED(rv) && !aHasPseudoParent) {
        aFrameItems.AddChild(newFrame);
      }
      return rv;
   
    case NS_STYLE_DISPLAY_TABLE_COLUMN:
      rv = ConstructTableColFrame(aState, aContent, aParentFrame,
                                  aStyleContext, tableCreator, PR_FALSE,
                                  aFrameItems, newFrame, aHasPseudoParent);
      if (NS_SUCCEEDED(rv) && !aHasPseudoParent) {
        aFrameItems.AddChild(newFrame);
      }
      return rv;
  
    case NS_STYLE_DISPLAY_TABLE_ROW:
      rv = ConstructTableRowFrame(aState, aContent, aParentFrame,
                                  aStyleContext, tableCreator, PR_FALSE,
                                  aFrameItems, newFrame, aHasPseudoParent);
      if (NS_SUCCEEDED(rv) && !aHasPseudoParent) {
        aFrameItems.AddChild(newFrame);
      }
      return rv;
  
    case NS_STYLE_DISPLAY_TABLE_CELL:
      {
        nsIFrame* innerTable;
        rv = ConstructTableCellFrame(aState, aContent, aParentFrame,
                                     aStyleContext, tableCreator, 
                                     PR_FALSE, aFrameItems, newFrame,
                                     innerTable, aHasPseudoParent);
        if (NS_SUCCEEDED(rv) && !aHasPseudoParent) {
          aFrameItems.AddChild(newFrame);
        }
        return rv;
      }
  
    default:
      NS_NOTREACHED("How did we get here? (ok if from CantRenderReplacedElement)");
      return NS_ERROR_FAILURE;
    }
  }

  if (!addedToFrameList) {
    // Gotta do it here
    NS_ASSERTION(!aDisplay->IsAbsolutelyPositioned() &&
                 !aDisplay->IsFloating(),
                 "Things that could be out-of-flow need to handle adding "
                 "to the frame list themselves");
    
    rv = aState.AddChild(newFrame, aFrameItems, aDisplay, aContent,
                         aStyleContext, aParentFrame);
    NS_ASSERTION(NS_SUCCEEDED(rv),
                 "Cases where AddChild() can fail must handle it themselves");
  }

  if (newFrame) {
    rv = CreateInsertionPointChildren(aState, newFrame, aContent);
    NS_ENSURE_SUCCESS(rv, rv);

    if (addToHashTable) {
      // Add a mapping from content object to primary frame. Note that for
      // floated and positioned frames this is the out-of-flow frame and not
      // the placeholder frame
      if (!primaryFrameSet)
        aState.mFrameManager->SetPrimaryFrameFor(aContent, newFrame);
    }
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructFrameInternal ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsIAtom aTag,
PRInt32  aNameSpaceID,
nsStyleContext aStyleContext,
nsFrameItems aFrameItems,
PRBool  aXBLBaseTag 
) [private]

Definition at line 7797 of file nsCSSFrameConstructor.cpp.

{
  // The following code allows the user to specify the base tag
  // of an element using XBL.  XUL and HTML objects (like boxes, menus, etc.)
  // can then be extended arbitrarily.
  const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();
  nsRefPtr<nsStyleContext> styleContext(aStyleContext);
  nsAutoEnqueueBinding binding(mDocument);
  if (!aXBLBaseTag)
  {
    
    // Ensure that our XBL bindings are installed.
    if (display->mBinding) {
      // Get the XBL loader.
      nsresult rv;
      // Load the bindings.
      PRBool resolveStyle;
      
      nsIXBLService * xblService = GetXBLService();
      if (!xblService)
        return NS_ERROR_FAILURE;

      rv = xblService->LoadBindings(aContent, display->mBinding, PR_FALSE,
                                    getter_AddRefs(binding.mBinding),
                                    &resolveStyle);
      if (NS_FAILED(rv))
        return NS_OK;

      if (resolveStyle) {
        styleContext = ResolveStyleContext(aParentFrame, aContent);
        display = styleContext->GetStyleDisplay();
      }

      nsCOMPtr<nsIAtom> baseTag;
      PRInt32 nameSpaceID;
      xblService->ResolveTag(aContent, &nameSpaceID, getter_AddRefs(baseTag));
 
      if (baseTag != aTag || aNameSpaceID != nameSpaceID) {
        // Construct the frame using the XBL base tag.
        rv = ConstructFrameInternal(aState,
                                    aContent,
                                    aParentFrame,
                                    baseTag,
                                    nameSpaceID,
                                    styleContext,
                                    aFrameItems,
                                    PR_TRUE);
        return rv;
      }
    }
  }

  // Pre-check for display "none" - if we find that, don't create
  // any frame at all
  if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
    aState.mFrameManager->SetUndisplayedContent(aContent, styleContext);
    return NS_OK;
  }
  
  nsIFrame* adjParentFrame = aParentFrame;
  nsFrameItems* frameItems = &aFrameItems;
  PRBool pseudoParent = PR_FALSE;
  nsFrameConstructorSaveState pseudoSaveState;
  nsresult rv = AdjustParentFrame(aContent, display, aTag, aNameSpaceID,
                                  styleContext, adjParentFrame, frameItems,
                                  aState, pseudoSaveState, pseudoParent);
  
  if (NS_FAILED(rv)) {
    return rv;
  }

  if (aContent->IsContentOfType(nsIContent::eTEXT)) 
    return ConstructTextFrame(aState, aContent, adjParentFrame, styleContext,
                              *frameItems, pseudoParent);

#ifdef MOZ_SVG
  // Don't create frames for non-SVG children of SVG elements
  if (aNameSpaceID != kNameSpaceID_SVG &&
      aParentFrame &&
      aParentFrame->IsFrameOfType(nsIFrame::eSVG)
#ifdef MOZ_SVG_FOREIGNOBJECT
      && !aParentFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)
#endif
      ) {
    return NS_OK;
  }
#endif
 
  // Style resolution can normally happen lazily.  However, getting the
  // Visibility struct can cause |SetBidiEnabled| to be called on the
  // pres context, and this needs to happen before we start reflow, so
  // do it now, when constructing frames.  See bug 115921.
  {
    styleContext->GetStyleVisibility();
  }

  nsIFrame* lastChild = frameItems->lastChild;

  // Handle specific frame types
  rv = ConstructHTMLFrame(aState, aContent, adjParentFrame, aTag, aNameSpaceID,
                          styleContext, *frameItems, pseudoParent);

  // Failing to find a matching HTML frame, try creating a specialized
  // XUL frame. This is temporary, pending planned factoring of this
  // whole process into separate, pluggable steps.
  if (NS_SUCCEEDED(rv) &&
      (!frameItems->childList || lastChild == frameItems->lastChild)) {
    PRBool haltProcessing;
    rv = ConstructXULFrame(aState, aContent, adjParentFrame, aTag,
                           aNameSpaceID, styleContext,
                           *frameItems, aXBLBaseTag, pseudoParent,
                           &haltProcessing);
    if (haltProcessing) {
      return rv;
    }
  } 

// MathML Mod - RBS
#ifdef MOZ_MATHML
  if (NS_SUCCEEDED(rv) &&
      (!frameItems->childList || lastChild == frameItems->lastChild)) {
    rv = ConstructMathMLFrame(aState, aContent, adjParentFrame, aTag,
                              aNameSpaceID, styleContext, *frameItems,
                              pseudoParent);
  }
#endif

// SVG
#ifdef MOZ_SVG
  if (NS_SUCCEEDED(rv) &&
      (!frameItems->childList || lastChild == frameItems->lastChild) &&
      aNameSpaceID == kNameSpaceID_SVG &&
      nsSVGUtils::SVGEnabled()) {
    PRBool haltProcessing;
    rv = ConstructSVGFrame(aState, aContent, adjParentFrame, aTag,
                           aNameSpaceID, styleContext,
                           *frameItems, pseudoParent, &haltProcessing);
    if (haltProcessing) {
      return rv;
    }
  }
#endif

// XTF
#ifdef MOZ_XTF
  if (aNameSpaceID > kNameSpaceID_LastBuiltin &&
      NS_SUCCEEDED(rv) &&
      (!frameItems->childList || lastChild == frameItems->lastChild)) {
    nsCOMPtr<nsIXTFElementWrapperPrivate> xtfElem = do_QueryInterface(aContent);
    if (xtfElem) {
      if (xtfElem->GetElementType() == nsIXTFElement::ELEMENT_TYPE_GENERIC_ELEMENT) {
        // we don't build frames for generic elements, only for visuals
        // XXXbz this is bogus, really.  These kids should just have
        // display:none, so they don't mess with pseudo-state!
        aState.mFrameManager->SetUndisplayedContent(aContent, styleContext);
        return NS_OK;
      } else if (xtfElem->GetElementType() != nsIXTFElement::ELEMENT_TYPE_BINDABLE)
        rv = ConstructXTFFrame(aState, aContent, adjParentFrame, aTag,
                               aNameSpaceID, styleContext, *frameItems,
                               pseudoParent);
    }
  }
#endif
  
  if (NS_SUCCEEDED(rv) &&
      (!frameItems->childList || lastChild == frameItems->lastChild)) {
    // When there is no explicit frame to create, assume it's a
    // container and let display style dictate the rest
    rv = ConstructFrameByDisplayType(aState, display, aContent, aNameSpaceID,
                                     aTag, adjParentFrame, styleContext,
                                     *frameItems, pseudoParent);
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructHTMLFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsIAtom aTag,
PRInt32  aNameSpaceID,
nsStyleContext aStyleContext,
nsFrameItems aFrameItems,
PRBool  aHasPseudoParent 
) [private]

Definition at line 5450 of file nsCSSFrameConstructor.cpp.

{
  // Ignore the tag if it's not HTML content and if it doesn't extend (via XBL)
  // a valid HTML namespace.
  if (!aContent->IsContentOfType(nsIContent::eHTML) &&
      aNameSpaceID != kNameSpaceID_XHTML) {
    return NS_OK;
  }

  PRBool    frameHasBeenInitialized = PR_FALSE;
  nsIFrame* newFrame = nsnull;  // the frame we construct
  PRBool    isReplaced = PR_FALSE;
  PRBool    addToHashTable = PR_TRUE;
  PRBool    isFloatContainer = PR_FALSE;
  PRBool    addedToFrameList = PR_FALSE;
  nsresult  rv = NS_OK;

  // See if the element is absolute or fixed positioned
  const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();

  // Create a frame based on the tag
  if (nsHTMLAtoms::img == aTag) {
    isReplaced = PR_TRUE;
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    // XXX If image display is turned off, then use ConstructAlternateFrame()
    // instead...
    rv = NS_NewImageFrame(mPresShell, &newFrame);
  }
  else if (nsHTMLAtoms::br == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    rv = NS_NewBRFrame(mPresShell, &newFrame);
    isReplaced = PR_TRUE;
    // BR frames don't go in the content->frame hash table: typically
    // there are many BR content objects and this would increase the size
    // of the hash table, and it's doubtful we need the mapping anyway
    addToHashTable = PR_FALSE;
  }
  else if (nsHTMLAtoms::wbr == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    rv = NS_NewWBRFrame(mPresShell, &newFrame);
  }
  else if (nsHTMLAtoms::input == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    isReplaced = PR_TRUE;
    rv = CreateInputFrame(aContent, &newFrame, aStyleContext);
  }
  else if (nsHTMLAtoms::textarea == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    isReplaced = PR_TRUE;
    rv = NS_NewTextControlFrame(mPresShell, &newFrame);
  }
  else if (nsHTMLAtoms::select == aTag) {
    if (!gUseXBLForms) {
      if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
        ProcessPseudoFrames(aState, aFrameItems); 
      }
      isReplaced = PR_TRUE;
      rv = ConstructSelectFrame(aState, aContent, aParentFrame,
                                aTag, aStyleContext, newFrame,
                                display, frameHasBeenInitialized,
                                aFrameItems);
      NS_ASSERTION(nsPlaceholderFrame::GetRealFrameFor(aFrameItems.lastChild) ==
                   newFrame,
                   "Frame didn't get added to aFrameItems?");
      addedToFrameList = PR_TRUE;
    }
  }
  else if (nsHTMLAtoms::object == aTag ||
           nsHTMLAtoms::applet == aTag ||
           nsHTMLAtoms::embed == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    isReplaced = PR_TRUE;
    rv = NS_NewObjectFrame(mPresShell, &newFrame);
  }
  else if (nsHTMLAtoms::fieldset == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    rv = ConstructFieldSetFrame(aState, aContent, aParentFrame,
                                aTag, aStyleContext, newFrame,
                                aFrameItems, display, frameHasBeenInitialized);
    NS_ASSERTION(nsPlaceholderFrame::GetRealFrameFor(aFrameItems.lastChild) ==
                 newFrame,
                 "Frame didn't get added to aFrameItems?");
    addedToFrameList = PR_TRUE;
  }
  else if (nsHTMLAtoms::legend == aTag) {
    NS_ASSERTION(!display->IsAbsolutelyPositioned() && !display->IsFloating(),
                 "Legends should not be positioned and should not float");
    
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    rv = NS_NewLegendFrame(mPresShell, &newFrame);
    isFloatContainer = PR_TRUE;
  }
  else if (nsHTMLAtoms::frameset == aTag) {
    NS_ASSERTION(!display->IsAbsolutelyPositioned() && !display->IsFloating(),
                 "Framesets should not be positioned and should not float");
    
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
   
    rv = NS_NewHTMLFramesetFrame(mPresShell, &newFrame);
  }
  else if (nsHTMLAtoms::iframe == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    
    isReplaced = PR_TRUE;
    rv = NS_NewSubDocumentFrame(mPresShell, &newFrame);
    if (newFrame) {
      // the nsSubDocumentFrame needs to know about its content parent during ::Init.
      // there is no reasonable way to get the value there.
      // so we store it as a frame property.
      nsCOMPtr<nsIAtom> contentParentAtom = do_GetAtom("contentParent");
      aState.mPresContext->PropertyTable()->
        SetProperty(newFrame, contentParentAtom,
                    aParentFrame, nsnull, nsnull);
    }
  }
  else if (nsHTMLAtoms::spacer == aTag) {
    NS_ASSERTION(!display->IsAbsolutelyPositioned() && !display->IsFloating(),
                 "Spacers should not be positioned and should not float");
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    rv = NS_NewSpacerFrame(mPresShell, &newFrame);
  }
  else if (nsHTMLAtoms::button == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    rv = NS_NewHTMLButtonControlFrame(mPresShell, &newFrame);
    // the html4 button needs to act just like a 
    // regular button except contain html content
    // so it must be replaced or html outside it will
    // draw into its borders. -EDV
    isReplaced = PR_TRUE;
    isFloatContainer = PR_TRUE;
  }
  else if (nsHTMLAtoms::isindex == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems);
    }
    isReplaced = PR_TRUE;
    rv = NS_NewIsIndexFrame(mPresShell, &newFrame);
  }
  else if (nsHTMLAtoms::canvas == aTag) {
    if (!aHasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aFrameItems); 
    }
    isReplaced = PR_TRUE;
    rv = NS_NewHTMLCanvasFrame(mPresShell, &newFrame);
  }

  if (NS_FAILED(rv) || !newFrame)
    return rv;

  // If we succeeded in creating a frame then initialize it, process its
  // children (if requested), and set the initial child list

  // If the frame is a replaced element, then set the frame state bit
  if (isReplaced) {
    newFrame->AddStateBits(NS_FRAME_REPLACED_ELEMENT);
  }

  // Note: at this point we should construct kids for newFrame only if
  // it's not a leaf and hasn't been initialized yet.
  
  if (!frameHasBeenInitialized) {
    NS_ASSERTION(!addedToFrameList,
                 "Frames that were already added to the frame list should be "
                 "initialized by now!");
    nsIFrame* geometricParent = aState.GetGeometricParent(display,
                                                          aParentFrame);
     
    rv = InitAndRestoreFrame(aState, aContent, geometricParent, aStyleContext,
                             nsnull, newFrame);
    if (rv == NS_ERROR_FRAME_REPLACED) {
      // The frame called CantRenderReplacedElement from inside Init().  That
      // failed to do anything useful, since the frame was not in the frame
      // tree yet... Create an alternate frame ourselves
      newFrame->Destroy(aState.mPresContext);

      if (aTag != nsHTMLAtoms::img && aTag != nsHTMLAtoms::input) {
        // XXXbz This should really be made to work for <object> too...
        return NS_OK;
      }

      // Try to construct the alternate frame
      newFrame = nsnull;
      rv = ConstructAlternateFrame(aContent, aStyleContext, geometricParent,
                                   aParentFrame, newFrame);
      NS_ENSURE_SUCCESS(rv, rv);
      NS_ASSERTION(newFrame, "ConstructAlternateFrame needs better error-checking");
    } else {
      NS_ASSERTION(NS_SUCCEEDED(rv), "InitAndRestoreFrame failed");
      // See if we need to create a view, e.g. the frame is absolutely
      // positioned
      nsHTMLContainerFrame::CreateViewForFrame(newFrame, aParentFrame, PR_FALSE);

      rv = aState.AddChild(newFrame, aFrameItems, display, aContent,
                           aStyleContext, aParentFrame);
      if (NS_FAILED(rv)) {
        return rv;
      }
      addedToFrameList = PR_TRUE;
      
      // Process the child content if requested
      nsFrameItems childItems;
      nsFrameConstructorSaveState absoluteSaveState;
      nsFrameConstructorSaveState floatSaveState;
      if (!newFrame->IsLeaf()) {
        if (display->IsPositioned()) {
          aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
        }
        if (isFloatContainer) {
          PRBool haveFirstLetterStyle, haveFirstLineStyle;
          HaveSpecialBlockStyle(aContent, aStyleContext,
                                &haveFirstLetterStyle, &haveFirstLineStyle);
          aState.PushFloatContainingBlock(newFrame, floatSaveState,
                                          PR_FALSE, PR_FALSE);
        }

        // Process the child frames
        rv = ProcessChildren(aState, aContent, newFrame,
                             PR_TRUE, childItems, PR_FALSE);
      }

      // if there are any anonymous children create frames for them
      CreateAnonymousFrames(aTag, aState, aContent, newFrame,
                            PR_FALSE, childItems);

      // Set the frame's initial child list
      if (childItems.childList) {
        newFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                      childItems.childList);
      }
    }
  }

  if (!addedToFrameList) {
    // Gotta do it here.  Note that things like absolutely positioned replaced
    // elements and the like will end up in this code.   So use the AddChild
    // on the state.
    rv = aState.AddChild(newFrame, aFrameItems, display, aContent,
                         aStyleContext, aParentFrame);
    if (NS_FAILED(rv)) {
      return rv;
    }
  }

  if (newFrame && !newFrame->IsLeaf()) {
    rv = CreateInsertionPointChildren(aState, newFrame, aContent);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (addToHashTable) {
    // Add a mapping from content object to primary frame. Note that for
    // floated and positioned frames this is the out-of-flow frame and not
    // the placeholder frame
    aState.mFrameManager->SetPrimaryFrameFor(aContent, newFrame);
  }

  return rv;
}

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructInline ( nsFrameConstructorState aState,
const nsStyleDisplay aDisplay,
nsIContent aContent,
nsIFrame aParentFrame,
nsStyleContext aStyleContext,
PRBool  aIsPositioned,
nsIFrame aNewFrame 
) [private]

Definition at line 13325 of file nsCSSFrameConstructor.cpp.

{
  // Initialize the frame
  InitAndRestoreFrame(aState, aContent, aParentFrame, aStyleContext, nsnull,
                      aNewFrame);

  nsFrameConstructorSaveState absoluteSaveState;  // definition cannot be inside next block
                                                  // because the object's destructor is significant
                                                  // this is part of the fix for bug 42372

  // Any inline frame might need a view (because of opacity, or fixed background)
  // XXXbz should we be passing in a non-null aContentParentFrame?
  nsHTMLContainerFrame::CreateViewForFrame(aNewFrame, nsnull, PR_FALSE);

  if (aIsPositioned) {                            
    // Relatively positioned frames becomes a container for child
    // frames that are positioned
    aState.PushAbsoluteContainingBlock(aNewFrame, absoluteSaveState);
  }

  // Process the child content
  nsFrameItems childItems;
  PRBool kidsAllInline;
  nsresult rv = ProcessInlineChildren(aState, aContent, aNewFrame, PR_TRUE,
                                      childItems, &kidsAllInline);
  if (kidsAllInline) {
    // Set the inline frame's initial child list
    CreateAnonymousFrames(aContent->Tag(), aState, aContent, aNewFrame,
                          PR_FALSE, childItems);

    aNewFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                   childItems.childList);
    return rv;
  }

  // This inline frame contains several types of children. Therefore
  // this frame has to be chopped into several pieces. We will produce
  // as a result of this 3 lists of children. The first list contains
  // all of the inline children that preceed the first block child
  // (and may be empty). The second list contains all of the block
  // children and any inlines that are between them (and must not be
  // empty, otherwise - why are we here?). The final list contains all
  // of the inline children that follow the final block child.

  // Find the first block child which defines list1 and list2
  nsIFrame* list1 = childItems.childList;
  nsIFrame* prevToFirstBlock;
  nsIFrame* list2 = FindFirstBlock(list1, &prevToFirstBlock);
  if (prevToFirstBlock) {
    prevToFirstBlock->SetNextSibling(nsnull);
  }
  else {
    list1 = nsnull;
  }

  // Find the last block child which defines the end of list2 and the
  // start of list3
  nsIFrame* afterFirstBlock = list2->GetNextSibling();
  nsIFrame* list3 = nsnull;
  nsIFrame* lastBlock = FindLastBlock(afterFirstBlock);
  if (!lastBlock) {
    lastBlock = list2;
  }
  list3 = lastBlock->GetNextSibling();
  lastBlock->SetNextSibling(nsnull);

  // list1's frames belong to this inline frame so go ahead and take them
  aNewFrame->SetInitialChildList(aState.mPresContext, nsnull, list1);

  // list2's frames belong to an anonymous block that we create right
  // now. The anonymous block will be the parent of the block children
  // of the inline.
  nsIFrame* blockFrame;
  nsIAtom* blockStyle;
  if (aIsPositioned) {
    NS_NewRelativeItemWrapperFrame(mPresShell, &blockFrame);
    blockStyle = nsCSSAnonBoxes::mozAnonymousPositionedBlock;
  }
  else {
    NS_NewBlockFrame(mPresShell, &blockFrame);
    blockStyle = nsCSSAnonBoxes::mozAnonymousBlock;
  }

  nsRefPtr<nsStyleContext> blockSC;
  blockSC = mPresShell->StyleSet()->ResolvePseudoStyleFor(aContent, blockStyle,
                                                          aStyleContext);

  if (! aState.mFloatedItems.containingBlock) {
    blockFrame->AddStateBits(NS_BLOCK_SPACE_MGR | NS_BLOCK_MARGIN_ROOT);
  }

  InitAndRestoreFrame(aState, aContent, aParentFrame, blockSC, nsnull,
                      blockFrame, PR_FALSE);  

  // Any inline frame could have a view (e.g., opacity)
  // XXXbz should we be passing in a non-null aContentParentFrame?
  nsHTMLContainerFrame::CreateViewForFrame(blockFrame, nsnull, PR_FALSE);

  if (blockFrame->HasView() || aNewFrame->HasView()) {
    // Move list2's frames into the new view
    nsHTMLContainerFrame::ReparentFrameViewList(aState.mPresContext, list2,
                                                list2->GetParent(), blockFrame);
  }

  blockFrame->SetInitialChildList(aState.mPresContext, nsnull, list2);

  nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                GetAbsoluteContainingBlock(blockFrame),
                                GetFloatContainingBlock(blockFrame));

  // If we have an inline between two blocks all inside an inline and the inner
  // inline contains a float, the float will end up in the float list of the
  // parent block of the inline, but its parent pointer will be the anonymous
  // block we create...  AdjustFloatParentPtrs() deals with this by moving the
  // float from the outer state |aState| to the inner |state|.
  MoveChildrenTo(state.mFrameManager, blockSC, blockFrame, list2, &state, &aState);

  // list3's frames belong to another inline frame
  nsIFrame* inlineFrame = nsnull;

  if (list3) {
    if (aIsPositioned) {
      NS_NewPositionedInlineFrame(mPresShell, &inlineFrame);
    }
    else {
      NS_NewInlineFrame(mPresShell, &inlineFrame);
    }

    InitAndRestoreFrame(aState, aContent, aParentFrame, aStyleContext, nsnull,
                        inlineFrame, PR_FALSE);

    // Any frame might need a view
    // XXXbz should we be passing in a non-null aContentParentFrame?
    nsHTMLContainerFrame::CreateViewForFrame(inlineFrame, nsnull, PR_FALSE);

    if (inlineFrame->HasView() || aNewFrame->HasView()) {
      // Move list3's frames into the new view
      nsHTMLContainerFrame::ReparentFrameViewList(aState.mPresContext, list3,
                                                  list3->GetParent(), inlineFrame);
    }

    // Reparent (cheaply) the frames in list3 - we don't have to futz
    // with their style context because they already have the right one.
    inlineFrame->SetInitialChildList(aState.mPresContext, nsnull, list3);
    MoveChildrenTo(aState.mFrameManager, nsnull, inlineFrame, list3, nsnull, nsnull);
  }

  // Mark the 3 frames as special. That way if any of the
  // append/insert/remove methods try to fiddle with the children, the
  // containing block will be reframed instead.
  SetFrameIsSpecial(aNewFrame, blockFrame);
  SetFrameIsSpecial(blockFrame, inlineFrame);
  MarkIBSpecialPrevSibling(aState.mPresContext, blockFrame, aNewFrame);

  if (inlineFrame)
    SetFrameIsSpecial(inlineFrame, nsnull);

#ifdef DEBUG
  if (gNoisyInlineConstruction) {
    nsIFrameDebug*  frameDebug;

    printf("nsCSSFrameConstructor::ConstructInline:\n");
    if (NS_SUCCEEDED(CallQueryInterface(aNewFrame, &frameDebug))) {
      printf("  ==> leading inline frame:\n");
      frameDebug->List(aState.mPresContext, stdout, 2);
    }
    if (NS_SUCCEEDED(CallQueryInterface(blockFrame, &frameDebug))) {
      printf("  ==> block frame:\n");
      frameDebug->List(aState.mPresContext, stdout, 2);
    }
    if (inlineFrame &&
        NS_SUCCEEDED(CallQueryInterface(inlineFrame, &frameDebug))) {
      printf("  ==> trailing inline frame:\n");
      frameDebug->List(aState.mPresContext, stdout, 2);
    }
  }
#endif

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructPageBreakFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsStyleContext aStyleContext,
nsFrameItems aFrameItems 
) [private]

Definition at line 7731 of file nsCSSFrameConstructor.cpp.

{
  nsRefPtr<nsStyleContext> pseudoStyle;
  pseudoStyle = mPresShell->StyleSet()->ResolvePseudoStyleFor(nsnull,
                                                              nsCSSAnonBoxes::pageBreak,
                                                              aStyleContext);
  nsIFrame* pageBreakFrame;
  nsresult rv = NS_NewPageBreakFrame(mPresShell, &pageBreakFrame); 
  if (NS_SUCCEEDED(rv)) {
    InitAndRestoreFrame(aState, aContent, aParentFrame, pseudoStyle, nsnull,
                        pageBreakFrame);
    aFrameItems.AddChild(pageBreakFrame);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructPageFrame ( nsIPresShell aPresShell,
nsPresContext aPresContext,
nsIFrame aParentFrame,
nsIFrame aPrevPageFrame,
nsIFrame *&  aPageFrame,
nsIFrame *&  aPageContentFrame 
) [private]

Definition at line 4886 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  rv = NS_NewPageFrame(aPresShell, &aPageFrame);
  if (NS_FAILED(rv))
    return rv;

  nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext();
  nsStyleSet *styleSet = aPresShell->StyleSet();

  nsRefPtr<nsStyleContext> pagePseudoStyle;
  pagePseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
                                                    nsCSSAnonBoxes::page,
                                                    parentStyleContext);

  // Initialize the page frame and force it to have a view. This makes printing of
  // the pages easier and faster.
  aPageFrame->Init(aPresContext, nsnull, aParentFrame, pagePseudoStyle, aPrevPageFrame);
  // XXXbz should we be passing in a non-null aContentParentFrame?
  rv = nsHTMLContainerFrame::CreateViewForFrame(aPageFrame, nsnull, PR_TRUE);
  if (NS_FAILED(rv))
    return NS_ERROR_NULL_POINTER;

  NS_NewPageContentFrame(aPresShell, &aPageContentFrame);

  nsRefPtr<nsStyleContext> pageContentPseudoStyle;
  pageContentPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
                                                           nsCSSAnonBoxes::pageContent,
                                                           pagePseudoStyle);

  // Initialize the page content frame and force it to have a view. Also make it the
  // containing block for fixed elements which are repeated on every page.
  aPageContentFrame->Init(aPresContext, nsnull, aPageFrame, pageContentPseudoStyle, nsnull);
  // XXXbz should we be passing in a non-null aContentParentFrame?
  nsHTMLContainerFrame::CreateViewForFrame(aPageContentFrame, nsnull, PR_TRUE);
  if (NS_FAILED(rv))
    return NS_ERROR_NULL_POINTER;
  mFixedContainingBlock = aPageContentFrame;

  aPageFrame->SetInitialChildList(aPresContext, nsnull, aPageContentFrame);

  // Fixed pos kids are taken care of directly in CreateContinuingFrame()
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructRadioControlFrame ( nsIFrame **  aNewFrame,
nsIContent aContent,
nsStyleContext aStyleContext 
) [private]

Definition at line 4975 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_NewGfxRadioControlFrame(mPresShell, aNewFrame);
  if (NS_FAILED(rv)) {
    *aNewFrame = nsnull;
    return rv;
  }

  nsRefPtr<nsStyleContext> radioStyle;
  radioStyle = mPresShell->StyleSet()->ResolvePseudoStyleFor(aContent,
                                                             nsCSSAnonBoxes::radio,
                                                             aStyleContext);
  nsIRadioControlFrame* radio = nsnull;
  if (*aNewFrame && NS_SUCCEEDED(CallQueryInterface(*aNewFrame, &radio))) {
    radio->SetRadioButtonFaceStyleContext(radioStyle);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4633 of file nsCSSFrameConstructor.cpp.

{
  NS_PRECONDITION(aNewFrame, "null out param");
  
  // how the root frame hierarchy should look

    /*

---------------No Scrollbars------



     ViewPortFrame (FixedContainingBlock) <---- RootView

         ^
         |
     RootFrame(DocElementContainingBlock)
  


---------------Gfx Scrollbars ------


     ViewPortFrame (FixedContainingBlock) <---- RootView

         ^
         |
     ScrollFrame

         ^
         |
     RootFrame(DocElementContainingBlock)
          
*/    

  // Set up our style rule observer.
  {
    nsCOMPtr<nsIStyleRuleSupplier> ruleSupplier =
      do_QueryInterface(mDocument->BindingManager());
    mPresShell->StyleSet()->SetStyleRuleSupplier(ruleSupplier);
  }

  // --------- BUILD VIEWPORT -----------
  nsIFrame*                 viewportFrame = nsnull;
  nsRefPtr<nsStyleContext> viewportPseudoStyle;
  nsStyleSet *styleSet = mPresShell->StyleSet();

  viewportPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
                                                        nsCSSAnonBoxes::viewport,
                                                        nsnull);

  NS_NewViewportFrame(mPresShell, &viewportFrame);

  nsPresContext* presContext = mPresShell->GetPresContext();

  // XXXbz do we _have_ to pass a null content pointer to that frame?
  // Would it really kill us to pass in the root element or something?
  // What would that break?
  viewportFrame->Init(presContext, nsnull, nsnull,
                      viewportPseudoStyle, nsnull);

  // Bind the viewport frame to the root view
  nsIViewManager* viewManager = mPresShell->GetViewManager();
  nsIView*        rootView;

  viewManager->GetRootView(rootView);
  viewportFrame->SetView(rootView);

  nsContainerFrame::SyncFrameViewProperties(presContext, viewportFrame,
                                            viewportPseudoStyle, rootView);

  // The viewport is the containing block for 'fixed' elements
  mFixedContainingBlock = viewportFrame;

  // --------- CREATE ROOT FRAME -------


    // Create the root frame. The document element's frame is a child of the
    // root frame.
    //
    // The root frame serves two purposes:
    // - reserves space for any margins needed for the document element's frame
    // - renders the document element's background. This ensures the background covers
    //   the entire canvas as specified by the CSS2 spec

    PRBool isPaginated = presContext->IsPaginated();
    PRBool isPrintPreview =
      presContext->Type() == nsPresContext::eContext_PrintPreview;

    nsIFrame* rootFrame = nsnull;
    nsIAtom* rootPseudo;
        
    if (!isPaginated) {
#ifdef MOZ_XUL
        if (aDocElement->IsContentOfType(nsIContent::eXUL)) 
        {
          NS_NewRootBoxFrame(mPresShell, &rootFrame);
        } else 
#endif
        {
          NS_NewCanvasFrame(mPresShell, &rootFrame);
        }

        rootPseudo = nsCSSAnonBoxes::canvas;
        mDocElementContainingBlock = rootFrame;
    } else {
        // Create a page sequence frame
        NS_NewSimplePageSequenceFrame(mPresShell, &rootFrame);
        mPageSequenceFrame = rootFrame;
        rootPseudo = nsCSSAnonBoxes::pageSequence;
    }


  // --------- IF SCROLLABLE WRAP IN SCROLLFRAME --------

  // If the device supports scrolling (e.g., in galley mode on the screen and
  // for print-preview, but not when printing), then create a scroll frame that
  // will act as the scrolling mechanism for the viewport. 
  // XXX Do we even need a viewport when printing to a printer?

  // As long as the webshell doesn't prohibit it, and the device supports
  // it, create a scroll frame that will act as the scolling mechanism for
  // the viewport.
  //
  // Threre are three possible values stored in the docshell:
  //  1) nsIScrollable::Scrollbar_Never = no scrollbars
  //  2) nsIScrollable::Scrollbar_Auto = scrollbars appear if needed
  //  3) nsIScrollable::Scrollbar_Always = scrollbars always
  // Only need to create a scroll frame/view for cases 2 and 3.

  PRBool isHTML = aDocElement->IsContentOfType(nsIContent::eHTML);
  PRBool isXUL = PR_FALSE;

  if (!isHTML) {
    isXUL = aDocElement->IsContentOfType(nsIContent::eXUL);
  }

  // Never create scrollbars for XUL documents
  PRBool isScrollable = !isXUL;

  // Never create scrollbars for frameset documents.
  if (isHTML) {
    nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
    if (htmlDoc && htmlDoc->GetIsFrameset())
      isScrollable = PR_FALSE;
  }

  if (isPaginated) {
    if (isPrintPreview) {
      isScrollable = presContext->HasPaginatedScrolling();
    } else {
      isScrollable = PR_FALSE; // we are printing
    }
  }

  // We no longer need to do overflow propagation here. It's taken care of
  // when we construct frames for the element whose overflow might be
  // propagated
  NS_ASSERTION(!isScrollable || !isXUL,
               "XUL documents should never be scrollable - see above");

  nsIFrame* newFrame = rootFrame;
  nsRefPtr<nsStyleContext> rootPseudoStyle;
  // we must create a state because if the scrollbars are GFX it needs the 
  // state to build the scrollbar frames.
  nsFrameConstructorState state(mPresShell, nsnull, nsnull, nsnull);

  nsIFrame* parentFrame = viewportFrame;

  // If paginated, make sure we don't put scrollbars in
  if (!isScrollable) {
    rootPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull,
                                                      rootPseudo,
                                                      viewportPseudoStyle);
  } else {
      if (rootPseudo == nsCSSAnonBoxes::canvas) {
        rootPseudo = nsCSSAnonBoxes::scrolledCanvas;
      } else {
        NS_ASSERTION(rootPseudo == nsCSSAnonBoxes::pageSequence,
                     "Unknown root pseudo");
        rootPseudo = nsCSSAnonBoxes::scrolledPageSequence;
      }

      // Build the frame. We give it the content we are wrapping which is the document,
      // the root frame, the parent view port frame, and we should get back the new
      // frame and the scrollable view if one was created.

      // resolve a context for the scrollframe
      nsRefPtr<nsStyleContext>  styleContext;
      styleContext = styleSet->ResolvePseudoStyleFor(nsnull,
                                                     nsCSSAnonBoxes::viewportScroll,
                                                     viewportPseudoStyle);

      // Note that the viewport scrollframe is always built with
      // overflow:auto style. This forces the scroll frame to create
      // anonymous content for both scrollbars. This is necessary even
      // if the HTML or BODY elements are overriding the viewport
      // scroll style to 'hidden' --- dynamic style changes might put
      // scrollbars back on the viewport and we don't want to have to
      // reframe the viewport to create the scrollbar content.
      newFrame = nsnull;
      rootPseudoStyle = BeginBuildingScrollFrame( state,
                                                  aDocElement,
                                                  styleContext,
                                                  viewportFrame,
                                                  nsnull,
                                                  rootPseudo,
                                                  PR_TRUE,
                                                  newFrame);

      nsIScrollableFrame* scrollable;
      CallQueryInterface(newFrame, &scrollable);
      NS_ENSURE_TRUE(scrollable, NS_ERROR_FAILURE);

      nsIScrollableView* scrollableView = scrollable->GetScrollableView();
      NS_ENSURE_TRUE(scrollableView, NS_ERROR_FAILURE);

      viewManager->SetRootScrollableView(scrollableView);
      parentFrame = newFrame;

      mGfxScrollFrame = newFrame;
  }
  

  rootFrame->Init(presContext, aDocElement, parentFrame,
                  rootPseudoStyle, nsnull);
  
  if (isScrollable) {
    FinishBuildingScrollFrame(parentFrame, rootFrame);
  }
  
  if (isPaginated) { // paginated
    // Create the first page
    // Set the initial child lists
    nsIFrame *pageFrame, *pageContentFrame;
    ConstructPageFrame(mPresShell, presContext, rootFrame, nsnull,
                       pageFrame, pageContentFrame);
    rootFrame->SetInitialChildList(presContext, nsnull, pageFrame);

    // The eventual parent of the document element frame.
    // XXX should this be set for every new page (in ConstructPageFrame)?
    mDocElementContainingBlock = pageContentFrame;
  }

  viewportFrame->SetInitialChildList(presContext, nsnull, newFrame);
  
  *aNewFrame = viewportFrame;

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsCSSFrameConstructor::ConstructSelectFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsIAtom aTag,
nsStyleContext aStyleContext,
nsIFrame *&  aNewFrame,
const nsStyleDisplay aStyleDisplay,
PRBool aFrameHasBeenInitialized,
nsFrameItems aFrameItems 
) [private]

Definition at line 5019 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  const PRInt32 kNoSizeSpecified = -1;

  // Construct a frame-based listbox or combobox
  nsCOMPtr<nsIDOMHTMLSelectElement> sel(do_QueryInterface(aContent));
  PRInt32 size = 1;
  if (sel) {
    sel->GetSize(&size); 
    PRBool multipleSelect = PR_FALSE;
    sel->GetMultiple(&multipleSelect);
     // Construct a combobox if size=1 or no size is specified and its multiple select
    if (((1 == size || 0 == size) || (kNoSizeSpecified  == size)) && (PR_FALSE == multipleSelect)) {
        // Construct a frame-based combo box.
        // The frame-based combo box is built out of three parts. A display area, a button and
        // a dropdown list. The display area and button are created through anonymous content.
        // The drop-down list's frame is created explicitly. The combobox frame shares it's content
        // with the drop-down list.
      PRUint32 flags = NS_BLOCK_SHRINK_WRAP | NS_BLOCK_SPACE_MGR;
      nsIFrame * comboboxFrame;
      rv = NS_NewComboboxControlFrame(mPresShell, &comboboxFrame, flags);

      // Save the history state so we don't restore during construction
      // since the complete tree is required before we restore.
      nsILayoutHistoryState *historyState = aState.mFrameState;
      aState.mFrameState = nsnull;
      // Initialize the combobox frame
      InitAndRestoreFrame(aState, aContent,
                          aState.GetGeometricParent(aStyleDisplay, aParentFrame),
                          aStyleContext, nsnull, comboboxFrame);

      nsHTMLContainerFrame::CreateViewForFrame(comboboxFrame, aParentFrame, PR_FALSE);

      rv = aState.AddChild(comboboxFrame, aFrameItems, aStyleDisplay,
                           aContent, aStyleContext, aParentFrame);
      if (NS_FAILED(rv)) {
        return rv;
      }
      
      // Combobox - Old Native Implementation
      nsIComboboxControlFrame* comboBox = nsnull;
      CallQueryInterface(comboboxFrame, &comboBox);
      NS_ASSERTION(comboBox, "NS_NewComboboxControlFrame returned frame that "
                             "doesn't implement nsIComboboxControlFrame");

        // Create a listbox
      nsIFrame * listFrame;
      rv = NS_NewListControlFrame(mPresShell, &listFrame);

        // Notify the listbox that it is being used as a dropdown list.
      nsIListControlFrame * listControlFrame;
      rv = CallQueryInterface(listFrame, &listControlFrame);
      if (NS_SUCCEEDED(rv)) {
        listControlFrame->SetComboboxFrame(comboboxFrame);
      }
         // Notify combobox that it should use the listbox as it's popup
      comboBox->SetDropDown(listFrame);

        // Resolve pseudo element style for the dropdown list 
      nsRefPtr<nsStyleContext> listStyle;
      listStyle = mPresShell->StyleSet()->ResolvePseudoStyleFor(aContent, 
                                                                nsCSSAnonBoxes::dropDownList, 
                                                                aStyleContext);

      NS_ASSERTION(!listStyle->GetStyleDisplay()->IsPositioned(),
                   "Ended up with positioned dropdown list somehow.");
      NS_ASSERTION(!listStyle->GetStyleDisplay()->IsFloating(),
                   "Ended up with floating dropdown list somehow.");
      
      // Initialize the scroll frame positioned. Note that it is NOT
      // initialized as absolutely positioned.
      nsIFrame* newFrame = nsnull;
      nsIFrame* scrolledFrame = nsnull;
      NS_NewSelectsAreaFrame(mPresShell, &scrolledFrame, flags);

      // make sure any existing anonymous content is cleared out. Gfx scroll frame construction
      // should reset it to just be the anonymous scrollbars, but we don't want to depend
      // on that.
      mPresShell->SetAnonymousContentFor(aContent, nsnull);

      InitializeSelectFrame(aState, listFrame,
                            scrolledFrame, aContent, comboboxFrame,
                            listStyle, PR_TRUE, aFrameItems);
      newFrame = listFrame;

        // Set flag so the events go to the listFrame not child frames.
        // XXX: We should replace this with a real widget manager similar
        // to how the nsFormControlFrame works. Re-directing events is a temporary Kludge.
      NS_ASSERTION(listFrame->GetView(), "ListFrame's view is nsnull");
      //listFrame->GetView()->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);

      // Create display and button frames from the combobox's anonymous content.
      // The anonymous content is appended to existing anonymous content for this
      // element (the scrollbars).

      nsFrameItems childItems;
      CreateAnonymousFrames(nsHTMLAtoms::combobox, aState, aContent,
                            comboboxFrame, PR_TRUE, childItems);
  
      comboboxFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                         childItems.childList);

      // Initialize the additional popup child list which contains the
      // dropdown list frame.
      nsFrameItems popupItems;
      popupItems.AddChild(listFrame);
      comboboxFrame->SetInitialChildList(aState.mPresContext,
                                         nsLayoutAtoms::popupList,
                                         popupItems.childList);

      aNewFrame = comboboxFrame;
      aFrameHasBeenInitialized = PR_TRUE;
      aState.mFrameState = historyState;
      if (aState.mFrameState && aState.mFrameManager) {
        // Restore frame state for the entire subtree of |comboboxFrame|.
        aState.mFrameManager->RestoreFrameState(comboboxFrame,
                                                aState.mFrameState);
      }
    } else {
      // ListBox - Old Native Implementation
      nsIFrame * listFrame;
      rv = NS_NewListControlFrame(mPresShell, &listFrame);

      PRUint32 flags = NS_BLOCK_SHRINK_WRAP | NS_BLOCK_SPACE_MGR;
      nsIFrame* scrolledFrame = nsnull;
      NS_NewSelectsAreaFrame(mPresShell, &scrolledFrame, flags);

      // ******* this code stolen from Initialze ScrollFrame ********
      // please adjust this code to use BuildScrollFrame.

      InitializeSelectFrame(aState, listFrame,
                            scrolledFrame, aContent, aParentFrame,
                            aStyleContext, PR_FALSE, aFrameItems);

      aNewFrame = listFrame;

      aFrameHasBeenInitialized = PR_TRUE;
    }
  }
  return rv;

}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableCaptionFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParent,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
nsFrameItems aChildItems,
nsIFrame *&  aNewFrame,
PRBool aIsPseudoParent 
) [private]

Definition at line 3628 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  if (!aParentFrameIn) return rv;

  nsIFrame* parentFrame = aParentFrameIn;
  aIsPseudoParent = PR_FALSE;
  // this frame may have a pseudo parent
  GetParentFrame(aTableCreator, *aParentFrameIn, 
                 nsLayoutAtoms::tableCaptionFrame, aState, parentFrame,
                 aIsPseudoParent);
  if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
    ProcessPseudoFrames(aState, aChildItems);
  }

  rv = aTableCreator.CreateTableCaptionFrame(&aNewFrame);
  if (NS_FAILED(rv)) return rv;
  InitAndRestoreFrame(aState, aContent, parentFrame, aStyleContext, nsnull,
                      aNewFrame);
  // XXXbz should we be passing in a non-null aContentParentFrame?
  nsHTMLContainerFrame::CreateViewForFrame(aNewFrame, nsnull, PR_FALSE);

  PRBool haveFirstLetterStyle, haveFirstLineStyle;
  HaveSpecialBlockStyle(aContent, aStyleContext,
                        &haveFirstLetterStyle, &haveFirstLineStyle);

  // The caption frame is a float container
  nsFrameConstructorSaveState floatSaveState;
  aState.PushFloatContainingBlock(aNewFrame, floatSaveState,
                                  haveFirstLetterStyle, haveFirstLineStyle);
  nsFrameItems childItems;
  // pass in aTableCreator so ProcessChildren will call TableProcessChildren
  rv = ProcessChildren(aState, aContent, aNewFrame,
                       PR_TRUE, childItems, PR_TRUE, &aTableCreator);
  if (NS_FAILED(rv)) return rv;
  aNewFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                 childItems.childList);
  if (aIsPseudoParent) {
    aState.mPseudoFrames.mTableOuter.mChildList2.AddChild(aNewFrame);
  }
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableCellFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
PRBool  aIsPseudo,
nsFrameItems aChildItems,
nsIFrame *&  aNewCellOuterFrame,
nsIFrame *&  aNewCellInnerFrame,
PRBool aIsPseudoParent 
) [private]

Definition at line 3925 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  if (!aParentFrameIn) return rv;

  nsIFrame* parentFrame = aParentFrameIn;
  aIsPseudoParent = PR_FALSE;
  if (!aIsPseudo) {
    // this frame may have a pseudo parent
    // use nsLayoutAtoms::tableCellFrame which will match if it is really nsLayoutAtoms::bcTableCellFrame
    GetParentFrame(aTableCreator, *aParentFrameIn, 
                   nsLayoutAtoms::tableCellFrame, aState, parentFrame,
                   aIsPseudoParent);
    if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aChildItems);
    }
    if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mCellOuter.mFrame) {
      ProcessPseudoFrames(aState, nsLayoutAtoms::tableCellFrame);
    }
  }

  rv = aTableCreator.CreateTableCellFrame(parentFrame, &aNewCellOuterFrame);
  if (NS_FAILED(rv)) return rv;
 
  // Initialize the table cell frame
  InitAndRestoreFrame(aState, aContent, parentFrame, aStyleContext, nsnull,
                      aNewCellOuterFrame);
  // XXXbz should we be passing in a non-null aContentParentFrame?
  nsHTMLContainerFrame::CreateViewForFrame(aNewCellOuterFrame, nsnull, PR_FALSE);

  // Create a block frame that will format the cell's content
  rv = aTableCreator.CreateTableCellInnerFrame(&aNewCellInnerFrame);

  if (NS_FAILED(rv)) {
    aNewCellOuterFrame->Destroy(aState.mPresContext);
    aNewCellOuterFrame = nsnull;
    return rv;
  }
  
  // Resolve pseudo style and initialize the body cell frame
  nsRefPtr<nsStyleContext> innerPseudoStyle;
  innerPseudoStyle = mPresShell->StyleSet()->
    ResolvePseudoStyleFor(aContent,
                          nsCSSAnonBoxes::cellContent, aStyleContext);

  InitAndRestoreFrame(aState, aContent, aNewCellOuterFrame, innerPseudoStyle,
                      nsnull, aNewCellInnerFrame);

  if (!aIsPseudo) {
    PRBool haveFirstLetterStyle, haveFirstLineStyle;
    HaveSpecialBlockStyle(aContent, aStyleContext,
                          &haveFirstLetterStyle, &haveFirstLineStyle);

    // The block frame is a float container
    nsFrameConstructorSaveState floatSaveState;
    aState.PushFloatContainingBlock(aNewCellInnerFrame, floatSaveState,
                                    haveFirstLetterStyle, haveFirstLineStyle);

    // Process the child content
    nsFrameItems childItems;
    // pass in null tableCreator so ProcessChildren will not call TableProcessChildren
    rv = ProcessChildren(aState, aContent, aNewCellInnerFrame, 
                         PR_TRUE, childItems, PR_TRUE, nsnull);
    if (NS_FAILED(rv)) {
      // Clean up
      // XXXbz kids of this stuff need to be cleaned up too!
      aNewCellInnerFrame->Destroy(aState.mPresContext);
      aNewCellInnerFrame = nsnull;
      aNewCellOuterFrame->Destroy(aState.mPresContext);
      aNewCellOuterFrame = nsnull;
      return rv;
    }

    aNewCellInnerFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                            childItems.childList);

    aNewCellOuterFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                            aNewCellInnerFrame);
    if (aIsPseudoParent) {
      aState.mPseudoFrames.mRow.mChildList.AddChild(aNewCellOuterFrame);
    }
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableColFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParent,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
PRBool  aIsPseudo,
nsFrameItems aChildItems,
nsIFrame *&  aNewFrame,
PRBool aIsPseudoParent 
) [private]

Definition at line 3861 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  if (!aParentFrameIn || !aStyleContext) return rv;

  nsIFrame* parentFrame = aParentFrameIn;
  aIsPseudoParent = PR_FALSE;
  if (!aIsPseudo) {
    // this frame may have a pseudo parent
    GetParentFrame(aTableCreator, *aParentFrameIn, 
                   nsLayoutAtoms::tableColFrame, aState, parentFrame,
                   aIsPseudoParent);
    if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aChildItems);
    }
  }

  rv = aTableCreator.CreateTableColFrame(&aNewFrame);
  if (NS_FAILED(rv)) return rv;
  InitAndRestoreFrame(aState, aContent, parentFrame, aStyleContext, nsnull,
                      aNewFrame);
  // if the parent frame was anonymous then reparent the style context
  if (aIsPseudoParent) {
    aState.mFrameManager->ReParentStyleContext(aNewFrame);
  }

  // construct additional col frames if the col frame has a span > 1
  PRInt32 span = 1;
  nsCOMPtr<nsIDOMHTMLTableColElement> cgContent(do_QueryInterface(aContent));
  if (cgContent) { 
    cgContent->GetSpan(&span);
    nsIFrame* lastCol = aNewFrame;
    nsStyleContext* styleContext = nsnull;
    for (PRInt32 spanX = 1; spanX < span; spanX++) {
      // The same content node should always resolve to the same style context.
      if (1 == spanX)
        styleContext = aNewFrame->GetStyleContext();
      nsIFrame* newCol;
      rv = aTableCreator.CreateTableColFrame(&newCol);
      if (NS_FAILED(rv)) return rv;
      InitAndRestoreFrame(aState, aContent, parentFrame, styleContext, nsnull,
                          newCol, PR_FALSE);
      ((nsTableColFrame*)newCol)->SetColType(eColAnonymousCol);
      lastCol->SetNextSibling(newCol);
      lastCol = newCol;
    }
  }

  if (!aIsPseudo && aIsPseudoParent) {
      aState.mPseudoFrames.mColGroup.mChildList.AddChild(aNewFrame);
  }
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableColGroupFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParent,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
PRBool  aIsPseudo,
nsFrameItems aChildItems,
nsIFrame *&  aNewFrame,
PRBool aIsPseudoParent 
) [private]

Definition at line 3756 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  if (!aParentFrameIn) return rv;

  nsIFrame* parentFrame = aParentFrameIn;
  aIsPseudoParent = PR_FALSE;
  if (!aIsPseudo) {
    // this frame may have a pseudo parent
    GetParentFrame(aTableCreator, *aParentFrameIn, 
                   nsLayoutAtoms::tableColGroupFrame, aState, parentFrame,
                   aIsPseudoParent);
    if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aChildItems);
    }
    if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mColGroup.mFrame) {
      ProcessPseudoFrames(aState, nsLayoutAtoms::tableColGroupFrame);
    }
  }

  rv = aTableCreator.CreateTableColGroupFrame(&aNewFrame);
  if (NS_FAILED(rv)) return rv;
  InitAndRestoreFrame(aState, aContent, parentFrame, aStyleContext, nsnull,
                      aNewFrame);

  if (!aIsPseudo) {
    nsFrameItems childItems;
    nsIFrame* captionFrame;
    rv = TableProcessChildren(aState, aContent, aNewFrame, aTableCreator,
                              childItems, captionFrame);
    if (NS_FAILED(rv)) return rv;
    aNewFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                   childItems.childList);
    if (aIsPseudoParent) {
      aState.mPseudoFrames.mTableInner.mChildList.AddChild(aNewFrame);
    }
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableForeignFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrameIn,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
nsFrameItems aChildItems 
) [private]

ConstructTableForeignFrame constructs the frame for a non-table-element child of a table-element frame (where "table-element" can mean rows, cells, etc).

This function will insert the new frame in the right child list automatically, create placeholders for it in the right places as needed, etc (hence does not return the new frame).

Definition at line 4038 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  if (!aParentFrameIn) return rv;

  nsIFrame* parentFrame = nsnull;
  PRBool hasPseudoParent = PR_FALSE;

  if (MustGeneratePseudoParent(aContent, aStyleContext)) {
    // this frame may have a pseudo parent, use block frame type to
    // trigger foreign
    rv = GetParentFrame(aTableCreator,
                        *aParentFrameIn, nsLayoutAtoms::blockFrame,
                        aState, parentFrame, hasPseudoParent);
    NS_ASSERTION(NS_SUCCEEDED(rv), "GetParentFrame failed!");
    if (!hasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aChildItems);
    }
  }

  if (!parentFrame) return rv; // if pseudo frame wasn't created
 
  // there are two situations where table related frames will wrap around
  // foreign frames
  // a) inner table cell, which is a pseudo frame
  // b) caption frame which will be always a real frame.
  NS_ASSERTION(nsLayoutAtoms::tableCaptionFrame == parentFrame->GetType() ||
               parentFrame == aState.mPseudoFrames.mCellInner.mFrame,
               "Weird parent in ConstructTableForeignFrame");

  // Push the parent as the floater containing block
  nsFrameConstructorSaveState saveState;
  aState.PushFloatContainingBlock(parentFrame, saveState, PR_FALSE, PR_FALSE);
  
  // save the pseudo frame state now, as descendants of the child frame may require
  // other pseudo frame creations
  nsPseudoFrames prevPseudoFrames; 
  aState.mPseudoFrames.Reset(&prevPseudoFrames);

  // Put the frames as kids of either the anonymous block (if we
  // created one), or just of our parent.
  nsFrameItems& childItems =
    hasPseudoParent ? prevPseudoFrames.mCellInner.mChildList : aChildItems;

  ConstructFrame(aState, aContent, parentFrame, childItems);
  // dont care about return value as ConstructFrame will not append a child if it fails.

  if (!aState.mPseudoFrames.IsEmpty()) {
    ProcessPseudoFrames(aState, childItems);
  }
  // restore the pseudo frame state
  aState.mPseudoFrames = prevPseudoFrames;

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aContentParent,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
PRBool  aIsPseudo,
nsFrameItems aChildItems,
PRBool  aAllowOutOfFlow,
nsIFrame *&  aNewOuterFrame,
nsIFrame *&  aNewInnerFrame 
) [private]

ConstructTableFrame will construct the outer and inner table frames and return them.

Unless aIsPseudo is PR_TRUE, it will put the inner frame in the child list of the outer frame, and will put any pseudo frames it had to create into aChildItems. The newly-created outer frame will either be in aChildItems or a descendant of a pseudo in aChildItems (unless it's positioned or floated, in which case its placeholder will be in aChildItems). If aAllowOutOfFlow is false, the table frame will be forced to be in-flow no matter what its float or position values are.

Definition at line 3527 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;

  // Create the outer table frame which holds the caption and inner table frame
  aTableCreator.CreateTableOuterFrame(&aNewOuterFrame);

  nsIFrame* parentFrame = aContentParent;
  nsFrameItems* frameItems = &aChildItems;
  // We may need to push a float containing block
  nsFrameConstructorSaveState floatSaveState;
  if (!aIsPseudo) {
    // this frame may have a pseudo parent
    PRBool hasPseudoParent = PR_FALSE;
    GetParentFrame(aTableCreator, *parentFrame, nsLayoutAtoms::tableOuterFrame,
                   aState, parentFrame, hasPseudoParent);
    if (!hasPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aChildItems);
    }
    if (hasPseudoParent) {
      aState.PushFloatContainingBlock(parentFrame, floatSaveState,
                                      PR_FALSE, PR_FALSE);
      frameItems = &aState.mPseudoFrames.mCellInner.mChildList;
      if (aState.mPseudoFrames.mTableOuter.mFrame) {
        ProcessPseudoFrames(aState, nsLayoutAtoms::tableOuterFrame);
      }
    }
  }

  // create the pseudo SC for the outer table as a child of the inner SC
  nsRefPtr<nsStyleContext> outerStyleContext;
  outerStyleContext = mPresShell->StyleSet()->
    ResolvePseudoStyleFor(aContent, nsCSSAnonBoxes::tableOuter, aStyleContext);

  const nsStyleDisplay* disp = outerStyleContext->GetStyleDisplay();
  nsIFrame* geometricParent =
    aAllowOutOfFlow ? aState.GetGeometricParent(disp, parentFrame) :
                      parentFrame;

  // Init the table outer frame and see if we need to create a view, e.g.
  // the frame is absolutely positioned  
  InitAndRestoreFrame(aState, aContent, geometricParent, outerStyleContext,
                      nsnull, aNewOuterFrame);  
  nsHTMLContainerFrame::CreateViewForFrame(aNewOuterFrame, aContentParent,
                                           PR_FALSE);

  // Create the inner table frame
  aTableCreator.CreateTableFrame(&aNewInnerFrame);

  InitAndRestoreFrame(aState, aContent, aNewOuterFrame, aStyleContext, nsnull,
                      aNewInnerFrame);

  if (!aIsPseudo) {
    // Put the newly created frames into the right child list
    aNewOuterFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                        aNewInnerFrame);

    rv = aState.AddChild(aNewOuterFrame, *frameItems, disp, aContent,
                         outerStyleContext, parentFrame, aAllowOutOfFlow,
                         aAllowOutOfFlow);
    if (NS_FAILED(rv)) {
      return rv;
    }

    nsFrameItems childItems;
    nsIFrame* captionFrame;

    rv = TableProcessChildren(aState, aContent, aNewInnerFrame,
                              aTableCreator, childItems, captionFrame);
    // XXXbz what about cleaning up?
    if (NS_FAILED(rv)) return rv;

    // if there are any anonymous children for the table, create frames for them
    CreateAnonymousFrames(nsnull, aState, aContent, aNewInnerFrame,
                          PR_FALSE, childItems);

    // Set the inner table frame's initial primary list 
    aNewInnerFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                        childItems.childList);

    // Set the outer table frame's primary and option lists
    if (captionFrame) {
      aNewOuterFrame->SetInitialChildList(aState.mPresContext,
                                          nsLayoutAtoms::captionList,
                                          captionFrame);
    }
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableRowFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParent,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
PRBool  aIsPseudo,
nsFrameItems aChildItems,
nsIFrame *&  aNewFrame,
PRBool aIsPseudoParent 
) [private]

Definition at line 3806 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  if (!aParentFrameIn) return rv;

  nsIFrame* parentFrame = aParentFrameIn;
  aIsPseudoParent = PR_FALSE;
  if (!aIsPseudo) {
    // this frame may have a pseudo parent
    GetParentFrame(aTableCreator, *aParentFrameIn,
                   nsLayoutAtoms::tableRowFrame, aState, parentFrame,
                   aIsPseudoParent);
    if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aChildItems);
    }
    if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mRow.mFrame) {
      ProcessPseudoFrames(aState, nsLayoutAtoms::tableRowFrame);
    }
  }

  rv = aTableCreator.CreateTableRowFrame(&aNewFrame);
  if (NS_FAILED(rv)) return rv;
  InitAndRestoreFrame(aState, aContent, parentFrame, aStyleContext, nsnull,
                      aNewFrame);
  // XXXbz should we be passing in a non-null aContentParentFrame?
  nsHTMLContainerFrame::CreateViewForFrame(aNewFrame, nsnull, PR_FALSE);
  if (!aIsPseudo) {
    nsFrameItems childItems;
    nsIFrame* captionFrame;
    rv = TableProcessChildren(aState, aContent, aNewFrame, aTableCreator,
                              childItems, captionFrame);
    if (NS_FAILED(rv)) return rv;
    // if there are any anonymous children for the table, create frames for them
    CreateAnonymousFrames(nsnull, aState, aContent, aNewFrame,
                          PR_FALSE, childItems);

    aNewFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                   childItems.childList);
    if (aIsPseudoParent) {
      aState.mPseudoFrames.mRowGroup.mChildList.AddChild(aNewFrame);
    }
  }

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTableRowGroupFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParent,
nsStyleContext aStyleContext,
nsTableCreator aTableCreator,
PRBool  aIsPseudo,
nsFrameItems aChildItems,
nsIFrame *&  aNewFrame,
PRBool aIsPseudoParent 
) [private]

Definition at line 3682 of file nsCSSFrameConstructor.cpp.

{
  nsresult rv = NS_OK;
  if (!aParentFrameIn) return rv;

  nsIFrame* parentFrame = aParentFrameIn;
  aIsPseudoParent = PR_FALSE;
  if (!aIsPseudo) {
    // this frame may have a pseudo parent
    GetParentFrame(aTableCreator, *aParentFrameIn, 
                   nsLayoutAtoms::tableRowGroupFrame, aState, parentFrame,
                   aIsPseudoParent);
    if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
      ProcessPseudoFrames(aState, aChildItems);
    }
    if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mRowGroup.mFrame) {
      ProcessPseudoFrames(aState, nsLayoutAtoms::tableRowGroupFrame);
    }
  }

  const nsStyleDisplay* styleDisplay = aStyleContext->GetStyleDisplay();

  rv = aTableCreator.CreateTableRowGroupFrame(&aNewFrame);

  nsIFrame* scrollFrame = nsnull;
  if (styleDisplay->IsScrollableOverflow()) {
    // Create an area container for the frame
    BuildScrollFrame(aState, aContent, aStyleContext, aNewFrame, parentFrame,
                     nsnull, scrollFrame, aStyleContext);

  } 
  else {
    if (NS_FAILED(rv)) return rv;
    InitAndRestoreFrame(aState, aContent, parentFrame, aStyleContext, nsnull,
                        aNewFrame);
    // XXXbz should we be passing in a non-null aContentParentFrame?
    nsHTMLContainerFrame::CreateViewForFrame(aNewFrame, nsnull, PR_FALSE);
  }

  if (!aIsPseudo) {
    nsFrameItems childItems;
    nsIFrame* captionFrame;
    rv = TableProcessChildren(aState, aContent, aNewFrame, aTableCreator,
                              childItems, captionFrame);
    if (NS_FAILED(rv)) return rv;
    // if there are any anonymous children for the table, create frames for them
    CreateAnonymousFrames(nsnull, aState, aContent, aNewFrame,
                          PR_FALSE, childItems);

    aNewFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                   childItems.childList);
    if (aIsPseudoParent) {
      nsIFrame* child = (scrollFrame) ? scrollFrame : aNewFrame;
      aState.mPseudoFrames.mTableInner.mChildList.AddChild(child);
    }
  } 

  // if there is a scroll frame, use it as the one constructed
  if (scrollFrame) {
    aNewFrame = scrollFrame;
  }
  
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructTextFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsStyleContext aStyleContext,
nsFrameItems aFrameItems,
PRBool  aPseudoParent 
) [private]

Definition at line 5391 of file nsCSSFrameConstructor.cpp.

{
  // process pending pseudo frames. whitespace doesn't have an effect.
  if (!aPseudoParent && !aState.mPseudoFrames.IsEmpty() &&
      !IsOnlyWhitespace(aContent))
    ProcessPseudoFrames(aState, aFrameItems);

  nsIFrame* newFrame = nsnull;

#ifdef MOZ_SVG
  nsresult rv;

  if (aParentFrame->IsFrameOfType(nsIFrame::eSVG)) {
    nsCOMPtr<nsISVGTextContainerFrame> svg_parent = do_QueryInterface(aParentFrame);
    if (!svg_parent) {
      return NS_OK;
    }
    rv = NS_NewSVGGlyphFrame(mPresShell, aContent, aParentFrame, &newFrame);
  }
  else
    rv = NS_NewTextFrame(mPresShell, &newFrame);
#else
  nsresult rv = NS_NewTextFrame(mPresShell, &newFrame);
#endif
  if (NS_FAILED(rv) || !newFrame)
    return rv;

  // Set the frame state bit for text frames to mark them as replaced.
  // XXX kipp: temporary
  newFrame->AddStateBits(NS_FRAME_REPLACED_ELEMENT);

  rv = InitAndRestoreFrame(aState, aContent, aParentFrame, aStyleContext,
                           nsnull, newFrame);

  if (NS_FAILED(rv)) {
    newFrame->Destroy(aState.mPresContext);
    return rv;
  }

  // We never need to create a view for a text frame.

  // Set the frame's initial child list to null.
  newFrame->SetInitialChildList(aState.mPresContext, nsnull, nsnull);

  // Add the newly constructed frame to the flow
  aFrameItems.AddChild(newFrame);

  // Text frames don't go in the content->frame hash table, because
  // they're anonymous. This keeps the hash table smaller

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ConstructXULFrame ( nsFrameConstructorState aState,
nsIContent aContent,
nsIFrame aParentFrame,
nsIAtom aTag,
PRInt32  aNameSpaceID,
nsStyleContext aStyleContext,
nsFrameItems aFrameItems,
PRBool  aXBLBaseTag,
PRBool  aHasPseudoParent,
PRBool aHaltProcessing 
) [private]

Definition at line 5931 of file nsCSSFrameConstructor.cpp.

{
  *aHaltProcessing = PR_FALSE;

  PRBool    primaryFrameSet = PR_FALSE;
  nsresult  rv = NS_OK;
  PRBool    isPopup = PR_FALSE;
  PRBool    isReplaced = PR_FALSE;
  PRBool    frameHasBeenInitialized = PR_FALSE;

  // XXXbz somewhere here we should process pseudo frames if !aHasPseudoParent
  
  // this is the new frame that will be created
  nsIFrame* newFrame = nsnull;
  
  // this is the also the new frame that is created. But if a scroll frame is needed
  // the content will be mapped to the scrollframe and topFrame will point to it.
  // newFrame will still point to the child that we created like a "div" for example.
  nsIFrame* topFrame = nsnull;

  // Store aParentFrame away, since we plan to stomp on it later
  nsIFrame* origParentFrame = aParentFrame;

  NS_ASSERTION(aTag != nsnull, "null XUL tag");
  if (aTag == nsnull)
    return NS_OK;

  const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();
  
  PRBool isXULNS = (aNameSpaceID == kNameSpaceID_XUL);
  PRBool isXULDisplay = IsXULDisplayType(display);

  // don't apply xul display types to tag based frames
  if (isXULDisplay && !isXULNS) {
    isXULDisplay = !IsSpecialContent(aContent, aTag, aNameSpaceID,
                                     aStyleContext);
  }

  if (isXULNS || isXULDisplay) {
    PRBool mayBeScrollable = PR_FALSE;

    if (isXULNS) {
      // First try creating a frame based on the tag
      // Make sure to keep IsSpecialContent in synch with this code
#ifdef MOZ_XUL
      // BUTTON CONSTRUCTION
      if (aTag == nsXULAtoms::button || aTag == nsXULAtoms::checkbox || aTag == nsXULAtoms::radio) {
        isReplaced = PR_TRUE;
        rv = NS_NewButtonBoxFrame(mPresShell, &newFrame);

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } // End of BUTTON CONSTRUCTION logic
      // AUTOREPEATBUTTON CONSTRUCTION
      else if (aTag == nsXULAtoms::autorepeatbutton) {
        isReplaced = PR_TRUE;
        rv = NS_NewAutoRepeatBoxFrame(mPresShell, &newFrame);

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } // End of AUTOREPEATBUTTON CONSTRUCTION logic


      // TITLEBAR CONSTRUCTION
      else if (aTag == nsXULAtoms::titlebar) {
        isReplaced = PR_TRUE;
        rv = NS_NewTitleBarFrame(mPresShell, &newFrame);

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } // End of TITLEBAR CONSTRUCTION logic

      // RESIZER CONSTRUCTION
      else if (aTag == nsXULAtoms::resizer) {
        isReplaced = PR_TRUE;
        rv = NS_NewResizerFrame(mPresShell, &newFrame);

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } // End of RESIZER CONSTRUCTION logic

      else if (aTag == nsXULAtoms::image) {
        isReplaced = PR_TRUE;
        rv = NS_NewImageBoxFrame(mPresShell, &newFrame);
      }
      else if (aTag == nsXULAtoms::spring ||
               aTag == nsHTMLAtoms::spacer) {
        isReplaced = PR_TRUE;
        rv = NS_NewLeafBoxFrame(mPresShell, &newFrame);
      }
       else if (aTag == nsXULAtoms::treechildren) {
        isReplaced = PR_TRUE;
        rv = NS_NewTreeBodyFrame(mPresShell, &newFrame);
      }
      else if (aTag == nsXULAtoms::treecol) {
        isReplaced = PR_TRUE;
        rv = NS_NewTreeColFrame(mPresShell, &newFrame);
      }
      // TEXT CONSTRUCTION
      else if (aTag == nsXULAtoms::text || aTag == nsHTMLAtoms::label ||
               aTag == nsXULAtoms::description) {
        if ((aTag == nsHTMLAtoms::label || aTag == nsXULAtoms::description) && 
            (! aContent->HasAttr(kNameSpaceID_None, nsHTMLAtoms::value))) {
          // XXX we should probably be calling ConstructBlock here to handle
          // things like columns etc
          rv = NS_NewAreaFrame(mPresShell, &newFrame,
                               NS_BLOCK_SPACE_MGR | NS_BLOCK_SHRINK_WRAP | NS_BLOCK_MARGIN_ROOT);
        }
        else {
          isReplaced = PR_TRUE;
          rv = NS_NewTextBoxFrame(mPresShell, &newFrame);
        }
      }
      // End of TEXT CONSTRUCTION logic

       // Menu Construction    
      else if (aTag == nsXULAtoms::menu ||
               aTag == nsXULAtoms::menuitem || 
               aTag == nsXULAtoms::menubutton) {
        // A derived class box frame
        // that has custom reflow to prevent menu children
        // from becoming part of the flow.
        isReplaced = PR_TRUE;
        rv = NS_NewMenuFrame(mPresShell, &newFrame, (aTag != nsXULAtoms::menuitem));
      }
      else if (aTag == nsXULAtoms::menubar) {
  #ifdef XP_MACOSX
        // On Mac OS X, we use the system menubar for any root chrome shell
        // XUL menubars.
        PRBool isRootChromeShell = PR_FALSE;
        nsCOMPtr<nsISupports> container = aState.mPresContext->GetContainer();
        if (container) {
          nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
          if (treeItem) {
            PRInt32 type;
            treeItem->GetItemType(&type);
            if (nsIDocShellTreeItem::typeChrome == type) {
              nsCOMPtr<nsIDocShellTreeItem> parent;
              treeItem->GetParent(getter_AddRefs(parent));
              isRootChromeShell = !parent;
            }
          }
        }

        if (isRootChromeShell) {
          *aHaltProcessing = PR_TRUE;
          return NS_OK;
        }
  #endif

        rv = NS_NewMenuBarFrame(mPresShell, &newFrame);
      }
      else if (aTag == nsXULAtoms::popupgroup) {
        // This frame contains child popups
        isReplaced = PR_TRUE;
        rv = NS_NewPopupSetFrame(mPresShell, &newFrame);
      }
      else if (aTag == nsXULAtoms::iframe || aTag == nsXULAtoms::editor ||
               aTag == nsXULAtoms::browser) {
        isReplaced = PR_TRUE;
        
        rv = NS_NewSubDocumentFrame(mPresShell, &newFrame);
      }
      // PROGRESS METER CONSTRUCTION
      else if (aTag == nsXULAtoms::progressmeter) {
        isReplaced = PR_TRUE;
        rv = NS_NewProgressMeterFrame(mPresShell, &newFrame);
      }
      // End of PROGRESS METER CONSTRUCTION logic
      else
#endif
      // SLIDER CONSTRUCTION
      if (aTag == nsXULAtoms::slider) {
        isReplaced = PR_TRUE;
        rv = NS_NewSliderFrame(mPresShell, &newFrame);
      }
      // End of SLIDER CONSTRUCTION logic

      // SCROLLBAR CONSTRUCTION
      else if (aTag == nsXULAtoms::scrollbar) {
        isReplaced = PR_TRUE;
        rv = NS_NewScrollbarFrame(mPresShell, &newFrame);
      }
      else if (aTag == nsXULAtoms::nativescrollbar) {
        isReplaced = PR_TRUE;
        rv = NS_NewNativeScrollbarFrame(mPresShell, &newFrame);
      }
      // End of SCROLLBAR CONSTRUCTION logic

      // SCROLLBUTTON CONSTRUCTION
      else if (aTag == nsXULAtoms::scrollbarbutton) {
        isReplaced = PR_TRUE;
        rv = NS_NewScrollbarButtonFrame(mPresShell, &newFrame);
      }
      // End of SCROLLBUTTON CONSTRUCTION logic

#ifdef MOZ_XUL
      // SPLITTER CONSTRUCTION
      else if (aTag == nsXULAtoms::splitter) {
        isReplaced = PR_TRUE;
        rv = NS_NewSplitterFrame(mPresShell, &newFrame);
      }
      // End of SPLITTER CONSTRUCTION logic

      // GRIPPY CONSTRUCTION
      else if (aTag == nsXULAtoms::grippy) {
        isReplaced = PR_TRUE;
        rv = NS_NewGrippyFrame(mPresShell, &newFrame);
      }
      // End of GRIPPY CONSTRUCTION logic
#endif
    }

    // Display types for XUL start here
    // First is BOX
    if (!newFrame && isXULDisplay) {
      if (display->mDisplay == NS_STYLE_DISPLAY_INLINE_BOX ||
               display->mDisplay == NS_STYLE_DISPLAY_BOX) {
        isReplaced = PR_TRUE;

        rv = NS_NewBoxFrame(mPresShell, &newFrame, PR_FALSE, nsnull);

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } // End of BOX CONSTRUCTION logic
#ifdef MOZ_XUL
      // ------- Begin Grid ---------
      else if (display->mDisplay == NS_STYLE_DISPLAY_INLINE_GRID ||
               display->mDisplay == NS_STYLE_DISPLAY_GRID) {
        isReplaced = PR_TRUE;
        nsCOMPtr<nsIBoxLayout> layout;
        NS_NewGridLayout2(mPresShell, getter_AddRefs(layout));
        rv = NS_NewBoxFrame(mPresShell, &newFrame, PR_FALSE, layout);

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } //------- End Grid ------

      // ------- Begin Rows/Columns ---------
      else if (display->mDisplay == NS_STYLE_DISPLAY_GRID_GROUP) {
        isReplaced = PR_TRUE;

        nsCOMPtr<nsIBoxLayout> layout;
      
        if (aTag == nsXULAtoms::listboxbody) {
          NS_NewListBoxLayout(mPresShell, layout);

          rv = NS_NewListBoxBodyFrame(mPresShell, &newFrame, PR_FALSE, layout);
          ((nsListBoxBodyFrame*)newFrame)->InitGroup(this,
                                                     aState.mPresContext);
        }
        else
        {
          NS_NewGridRowGroupLayout(mPresShell, getter_AddRefs(layout));
          rv = NS_NewGridRowGroupFrame(mPresShell, &newFrame, PR_FALSE, layout);
        }

        // Boxes can scroll.
        if (display->IsScrollableOverflow()) {
          // set the top to be the newly created scrollframe
          BuildScrollFrame(aState, aContent, aStyleContext, newFrame,
                           aParentFrame, nsnull, topFrame, aStyleContext);

          // we have a scrollframe so the parent becomes the scroll frame.
          aParentFrame = newFrame->GetParent();

          primaryFrameSet = PR_TRUE;

          frameHasBeenInitialized = PR_TRUE;
        }
      } //------- End Grid ------

      // ------- Begin Row/Column ---------
      else if (display->mDisplay == NS_STYLE_DISPLAY_GRID_LINE) {
        isReplaced = PR_TRUE;
      
        nsCOMPtr<nsIBoxLayout> layout;


        NS_NewGridRowLeafLayout(mPresShell, getter_AddRefs(layout));

        if (aTag == nsXULAtoms::listitem)
          rv = NS_NewListItemFrame(mPresShell, &newFrame, PR_FALSE, layout);
        else
          rv = NS_NewGridRowLeafFrame(mPresShell, &newFrame, PR_FALSE, layout);

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } //------- End Grid ------
      // End of STACK CONSTRUCTION logic
       // DECK CONSTRUCTION
      else if (display->mDisplay == NS_STYLE_DISPLAY_DECK) {
        isReplaced = PR_TRUE;
        rv = NS_NewDeckFrame(mPresShell, &newFrame);
      }
      // End of DECK CONSTRUCTION logic
      else if (display->mDisplay == NS_STYLE_DISPLAY_GROUPBOX) {
        rv = NS_NewGroupBoxFrame(mPresShell, &newFrame);
        isReplaced = PR_TRUE;

        // Boxes can scroll.
        mayBeScrollable = PR_TRUE;
      } 
      // STACK CONSTRUCTION
      else if (display->mDisplay == NS_STYLE_DISPLAY_STACK ||
               display->mDisplay == NS_STYLE_DISPLAY_INLINE_STACK) {
        isReplaced = PR_TRUE;

        rv = NS_NewStackFrame(mPresShell, &newFrame);

        mayBeScrollable = PR_TRUE;
      }
      else if (display->mDisplay == NS_STYLE_DISPLAY_POPUP) {
        // This is its own frame that derives from
        // box.
        isReplaced = PR_TRUE;
        rv = NS_NewMenuPopupFrame(mPresShell, &newFrame);

        if (aTag == nsXULAtoms::tooltip) {
          nsAutoString defaultTooltip;
          aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::defaultz, defaultTooltip);
          if (defaultTooltip.LowerCaseEqualsLiteral("true")) {
            // Locate the root frame and tell it about the tooltip.
            nsIFrame* rootFrame = aState.mFrameManager->GetRootFrame();
            if (rootFrame)
              rootFrame = rootFrame->GetFirstChild(nsnull);
            nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
            if (rootBox)
              rootBox->SetDefaultTooltip(aContent);
          }
        }

        // If a popup is inside a menu, then the menu understands the complex
        // rules/behavior governing the cascade of multiple menu popups and can handle
        // having the real popup frame placed under it as a child.  
        // If, however, the parent is *not* a menu frame, then we need to create
        // a placeholder frame for the popup, and then we add the popup frame to the
        // root popup set (that manages all such "detached" popups).
        nsCOMPtr<nsIMenuFrame> menuFrame(do_QueryInterface(aParentFrame));
        if (!menuFrame)
          isPopup = PR_TRUE;
      } 
#endif
    }

    if (mayBeScrollable && display->IsScrollableOverflow()) {
      // set the top to be the newly created scrollframe
      BuildScrollFrame(aState, aContent, aStyleContext, newFrame,
                       aParentFrame, nsnull, topFrame, aStyleContext);

      // we have a scrollframe so the parent becomes the scroll frame.
      // XXXldb Do we really want to do this?  The one case where it
      // matters when |frameHasBeenInitialized| is true is one where
      // I think we'd be better off the other way around.
      aParentFrame = newFrame->GetParent();
      primaryFrameSet = PR_TRUE;
      frameHasBeenInitialized = PR_TRUE;
    }
  }

  // If we succeeded in creating a frame then initialize it, process its
  // children (if requested), and set the initial child list
  if (NS_SUCCEEDED(rv) && newFrame != nsnull) {

    // if no top frame was created then the top is the new frame
    if (topFrame == nsnull)
        topFrame = newFrame;

    // If the frame is a replaced element, then set the frame state bit
    if (isReplaced) {
      newFrame->AddStateBits(NS_FRAME_REPLACED_ELEMENT);
    }

    // xul does not support absolute positioning
    nsIFrame* geometricParent = aParentFrame;

    /*
      nsIFrame* geometricParent = aState.GetGeometricParent(display, aParentFrame);
    */
    // if the new frame was already initialized to initialize it again.
    if (!frameHasBeenInitialized) {

      rv = InitAndRestoreFrame(aState, aContent, geometricParent,
                               aStyleContext, nsnull, newFrame);

      if (NS_FAILED(rv)) {
        newFrame->Destroy(aState.mPresContext);
        return rv;
      }
      
      /*
      // if our parent is a block frame then do things the way html likes it
      // if not then we are in a box so do what boxes like. On example is boxes
      // do not support the absolute positioning of their children. While html blocks
      // thats why we call different things here.
      nsIAtom* frameType = geometricParent->GetType();
      if ((frameType == nsLayoutAtoms::blockFrame) ||
          (frameType == nsLayoutAtoms::areaFrame)) {
      */
        // See if we need to create a view, e.g. the frame is absolutely positioned
        nsHTMLContainerFrame::CreateViewForFrame(newFrame, aParentFrame, PR_FALSE);

      /*
      } else {
          // we are in a box so do the box thing.
        nsBoxFrame::CreateViewForFrame(aState.mPresContext, newFrame,
                                                 aStyleContext, PR_FALSE);
      }
      */
      
    }

    // If the frame is a popup, then create a placeholder frame
#ifdef MOZ_XUL
    if (isPopup) {
      nsIFrame* placeholderFrame;

      CreatePlaceholderFrameFor(mPresShell, aState.mPresContext,
                                aState.mFrameManager, aContent,
                                newFrame, aStyleContext, aParentFrame,
                                &placeholderFrame);

      // Locate the root popup set and add ourselves to the popup set's list
      // of popup frames.
      nsIFrame* rootFrame = aState.mFrameManager->GetRootFrame();
      if (rootFrame)
        rootFrame = rootFrame->GetFirstChild(nsnull);
      nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
      PRBool added = PR_FALSE;
      if (rootBox) {
        nsIFrame* popupSetFrame;
        rootBox->GetPopupSetFrame(&popupSetFrame);
        NS_ASSERTION(popupSetFrame, "unexpected null pointer");
        if (popupSetFrame) {
          nsCOMPtr<nsIPopupSetFrame> popupSet(do_QueryInterface(popupSetFrame));
          NS_ASSERTION(popupSet, "unexpected null pointer");
          if (popupSet) {
            added = PR_TRUE;
            popupSet->AddPopupFrame(newFrame);
          }
        }
      }

      if (added) {
        // Add the placeholder frame to the flow
        aFrameItems.AddChild(placeholderFrame);
      } else {
        // Didn't add the popup set frame...  Need to clean up and
        // just not construct a frame here.
        aState.mFrameManager->UnregisterPlaceholderFrame(NS_STATIC_CAST(nsPlaceholderFrame*, placeholderFrame));
        newFrame->Destroy(aState.mPresContext);
        placeholderFrame->Destroy(aState.mPresContext);
        *aHaltProcessing = PR_TRUE;
        return NS_OK;
      }
    } else {
#endif
      // Add the new frame to our list of frame items.  Note that we
      // don't support floating or positioning of XUL frames.
      rv = aState.AddChild(topFrame, aFrameItems, display, aContent,
                           aStyleContext, origParentFrame, PR_FALSE, PR_FALSE);
      if (NS_FAILED(rv)) {
        return rv;
      }
#ifdef MOZ_XUL
    }
#endif

    // If the new frame isn't a float containing block, then push a null
    // float containing block to disable floats. This is needed to disable
    // floats within XUL frames.
    nsFrameConstructorSaveState floatSaveState;
    PRBool isFloatContainingBlock =
      newFrame->GetContentInsertionFrame()->IsFloatContainingBlock();
    aState.PushFloatContainingBlock(isFloatContainingBlock ? newFrame : nsnull,
                                    floatSaveState, PR_FALSE, PR_FALSE);

    // Process the child content if requested
    nsFrameItems childItems;
    if (!newFrame->IsLeaf()) {
      // XXXbz don't we need calls to ShouldBuildChildFrames
      // elsewhere too?  Why only for XUL?
      PRBool processChildren = PR_TRUE;
      mDocument->BindingManager()->ShouldBuildChildFrames(aContent,
                                                          &processChildren);
      if (processChildren)
        rv = ProcessChildren(aState, aContent, newFrame, PR_FALSE,
                             childItems, PR_FALSE);
    }
      
    CreateAnonymousFrames(aTag, aState, aContent, newFrame, PR_FALSE,
                          childItems);

    // Set the frame's initial child list
    newFrame->SetInitialChildList(aState.mPresContext, nsnull,
                                  childItems.childList);
  }

#ifdef MOZ_XUL
  // register tooltip support if needed
  nsAutoString value;
  if (aTag == nsXULAtoms::treechildren || // trees always need titletips
      aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::tooltiptext, value) !=
        NS_CONTENT_ATTR_NOT_THERE ||
      aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::tooltip, value) !=
        NS_CONTENT_ATTR_NOT_THERE)
  {
    nsIFrame* rootFrame = aState.mFrameManager->GetRootFrame();
    if (rootFrame)
      rootFrame = rootFrame->GetFirstChild(nsnull);
    nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
    if (rootBox)
      rootBox->AddTooltipSupport(aContent);
  }
#endif

// addToHashTable:

  if (newFrame && !newFrame->IsLeaf()) {
    rv = CreateInsertionPointChildren(aState, newFrame, aContent);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (topFrame) {
    // the top frame is always what we map the content to. This is the frame that contains a pointer
    // to the content node.

    // Add a mapping from content object to primary frame. Note that for
    // floated and positioned frames this is the out-of-flow frame and not
    // the placeholder frame
    if (!primaryFrameSet)
        aState.mFrameManager->SetPrimaryFrameFor(aContent, topFrame);
  }

  return rv;
}

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ContentAppended ( nsIContent aContainer,
PRInt32  aNewIndexInContainer 
)

Definition at line 8628 of file nsCSSFrameConstructor.cpp.

{
#ifdef DEBUG
  if (gNoisyContentUpdates) {
    printf("nsCSSFrameConstructor::ContentAppended container=%p index=%d\n",
           NS_STATIC_CAST(void*, aContainer), aNewIndexInContainer);
    if (gReallyNoisyContentUpdates && aContainer) {
      aContainer->List(stdout, 0);
    }
  }
#endif

#ifdef MOZ_XUL
  if (aContainer) {
    nsCOMPtr<nsIAtom> tag;
    PRInt32 namespaceID;
    mDocument->BindingManager()->ResolveTag(aContainer, &namespaceID,
                                            getter_AddRefs(tag));

    // Just ignore tree tags, anyway we don't create any frames for them.
    if (tag == nsXULAtoms::treechildren ||
        tag == nsXULAtoms::treeitem ||
        tag == nsXULAtoms::treerow ||
        (namespaceID == kNameSpaceID_XUL && gUseXBLForms &&
         ShouldIgnoreSelectChild(aContainer)))
      return NS_OK;

  }
#endif // MOZ_XUL

  // Get the frame associated with the content
  nsIFrame* parentFrame = GetFrameFor(aContainer);
  if (! parentFrame)
    return NS_OK;

  // See if we have an XBL insertion point. If so, then that's our
  // real parent frame; if not, then the frame hasn't been built yet
  // and we just bail.
  //
  nsIFrame* insertionPoint;
  PRBool multiple = PR_FALSE;
  GetInsertionPoint(parentFrame, nsnull, &insertionPoint, &multiple);
  if (! insertionPoint)
    return NS_OK; // Don't build the frames.

  PRBool hasInsertion = PR_FALSE;
  if (!multiple) {
    nsIBindingManager *bindingManager = nsnull;
    nsIDocument* document = nsnull; 
    nsIContent *firstAppendedChild =
      aContainer->GetChildAt(aNewIndexInContainer);
    if (firstAppendedChild) {
      document = firstAppendedChild->GetDocument();
    }
    if (document)
      bindingManager = document->BindingManager();
    if (bindingManager) {
      nsCOMPtr<nsIContent> insParent;
      bindingManager->GetInsertionParent(firstAppendedChild, getter_AddRefs(insParent));
      if (insParent)
        hasInsertion = PR_TRUE;
    }
  }
  
  if (multiple || hasInsertion) {
    // We have an insertion point.  There are some additional tests we need to do
    // in order to ensure that an append is a safe operation.
    PRUint32 childCount = 0;
      
    if (!multiple) {
      // We may need to make multiple ContentInserted calls instead.  A
      // reasonable heuristic to employ (in order to maintain good performance)
      // is to find out if the insertion point's content node contains any
      // explicit children.  If it does not, then it is highly likely that 
      // an append is occurring.  (Note it is not definite, and there are insane
      // cases we will not deal with by employing this heuristic, but it beats
      // always falling back to multiple ContentInserted calls).
      //
      // In the multiple insertion point case, we know we're going to need to do
      // multiple ContentInserted calls anyway.
      childCount = insertionPoint->GetContent()->GetChildCount();
    }

    if (multiple || childCount > 0) {
      // Now comes the fun part.  For each appended child, we must obtain its
      // insertion point and find its exact position within that insertion point.
      // We then make a ContentInserted call with the correct computed index.
      nsIContent* insertionContent = insertionPoint->GetContent();
      
      PRUint32 containerCount = aContainer->GetChildCount();
      for (PRUint32 i = aNewIndexInContainer; i < containerCount; i++) {
        nsIContent *child = aContainer->GetChildAt(i);
        if (multiple) {
          // Filters are in effect, so the insertion point needs to be refetched for
          // each child.
          GetInsertionPoint(parentFrame, child, &insertionPoint);
          if (!insertionPoint) {
            // This content node doesn't have an insertion point, so we just
            // skip over it
            continue;
          }
          insertionContent = insertionPoint->GetContent();
        }

        // Construct an iterator to locate this child at its correct index.
        ChildIterator iter, last;
        for (ChildIterator::Init(insertionContent, &iter, &last);
         iter != last;
         ++iter) {
          nsIContent* item = nsCOMPtr<nsIContent>(*iter);
          if (item == child)
            // Call ContentInserted with this index.
            ContentInserted(aContainer, nsnull, child,
                            iter.index(), mTempFrameTreeState, PR_FALSE);
        }
      }

      return NS_OK;
    }
  }

  parentFrame = insertionPoint;

  if (parentFrame->GetType() == nsLayoutAtoms::frameSetFrame) {
    // Just reframe the parent, since framesets are weird like that.
    return RecreateFramesForContent(parentFrame->GetContent());
  }
  
  if (parentFrame->IsLeaf()) {
    // Nothing to do here; we shouldn't be constructing kids of leaves
    return NS_OK;
  }
  
  // If the frame we are manipulating is a ``special'' frame (that
  // is, one that's been created as a result of a block-in-inline
  // situation) then do something different instead of just
  // appending newly created frames. Note that only the
  // first-in-flow is marked so we check before getting to the
  // last-in-flow.
  //
  // We run into this situation occasionally while loading web
  // pages, typically when some content generation tool has
  // sprinkled invalid markup into the document. More often than
  // not, we'll be able to just use the normal fast-path frame
  // construction code, because the frames will be appended to the
  // ``anonymous'' block that got created to parent the block
  // children of the inline.
  if (IsFrameSpecial(parentFrame)) {
#ifdef DEBUG
    if (gNoisyContentUpdates) {
      printf("nsCSSFrameConstructor::ContentAppended: parentFrame=");
      nsFrame::ListTag(stdout, parentFrame);
      printf(" is special\n");
    }
#endif

    // Since we're appending, we'll walk to the last anonymous frame
    // that was created for the broken inline frame.
    nsFrameManager *frameManager = mPresShell->FrameManager();

    while (1) {
      nsIFrame* sibling;
      GetSpecialSibling(frameManager, parentFrame, &sibling);
      if (! sibling)
        break;

      parentFrame = sibling;
    }

    // If this frame is the anonymous block frame, then all's well:
    // just append frames as usual.
    const nsStyleDisplay* display = parentFrame->GetStyleDisplay();

    if (NS_STYLE_DISPLAY_BLOCK != display->mDisplay) {
      // Nope, it's an inline, so just reframe the entire stinkin' mess if the
      // content is a block. We _could_ do better here with a little more work...
      // find out if the child is a block or inline, an inline means we don't have to reframe
      nsIContent *child = aContainer->GetChildAt(aNewIndexInContainer);
      PRBool needReframe = !child;
      if (child && child->IsContentOfType(nsIContent::eELEMENT)) {
        nsRefPtr<nsStyleContext> styleContext;
        styleContext = ResolveStyleContext(parentFrame, child);
        // XXX since the block child goes in the last inline of the sacred triad, frames would 
        // need to be moved into the 2nd triad (block) but that is more work, for now bail.
        needReframe = styleContext->GetStyleDisplay()->IsBlockLevel();
      }
      if (needReframe)
        return ReframeContainingBlock(parentFrame);
    }
  }

  // Get the parent frame's last-in-flow
  parentFrame = parentFrame->GetLastInFlow();

  nsIAtom* frameType = parentFrame->GetType();
  // Deal with inner/outer tables, fieldsets
  parentFrame = ::GetAdjustedParentFrame(parentFrame, frameType,
                                         aContainer, aNewIndexInContainer);

  // Deal with possible :after generated content on the parent
  nsIFrame* parentAfterFrame;
  parentFrame =
    ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
                                        aContainer, parentFrame,
                                        &parentAfterFrame);
  
  // Create some new frames
  PRUint32                count;
  nsIFrame*               firstAppendedFrame = nsnull;
  nsFrameItems            frameItems;
  nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                GetAbsoluteContainingBlock(parentFrame),
                                GetFloatContainingBlock(parentFrame));

  // See if the containing block has :first-letter style applied.
  PRBool haveFirstLetterStyle = PR_FALSE, haveFirstLineStyle = PR_FALSE;
  nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
  if (containingBlock) {
    haveFirstLetterStyle = HaveFirstLetterStyle(containingBlock);
    haveFirstLineStyle =
      HaveFirstLineStyle(containingBlock->GetContent(),
                         containingBlock->GetStyleContext());
  }

  if (haveFirstLetterStyle) {
    // Before we get going, remove the current letter frames
    RemoveLetterFrames(state.mPresContext, state.mPresShell,
                       state.mFrameManager, containingBlock);
  }

  // if the container is a table and a caption was appended, it needs to be put in
  // the outer table frame's additional child list. 
  nsFrameItems captionItems;
  
  PRUint32 i;
  count = aContainer->GetChildCount();
  for (i = aNewIndexInContainer; i < count; i++) {
    nsIContent *childContent = aContainer->GetChildAt(i);
    // lookup the table child frame type as it is much more difficult to remove a frame
    // and all it descendants (abs. pos. for instance) than to prevent the frame creation.
    if (nsLayoutAtoms::tableFrame == frameType) {
      nsFrameItems tempItems;
      ConstructFrame(state, childContent, parentFrame, tempItems);
      if (tempItems.childList) {
        if (nsLayoutAtoms::tableCaptionFrame == tempItems.childList->GetType()) {
          captionItems.AddChild(tempItems.childList);
        }
        else {
          frameItems.AddChild(tempItems.childList);
        }
      }
    }
    else if (nsLayoutAtoms::tableColGroupFrame == frameType) {
      nsRefPtr<nsStyleContext> childStyleContext;
      childStyleContext = ResolveStyleContext(parentFrame, childContent);
      if (childStyleContext->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_TABLE_COLUMN)
        continue; //don't create anything else than columns below a colgroup
      ConstructFrame(state, childContent, parentFrame, frameItems);
    }
    // Don't create child frames for iframes/frames, they should not
    // display any content that they contain.
    else if (nsLayoutAtoms::subDocumentFrame != frameType) {
      // Construct a child frame (that does not have a table as parent)
      ConstructFrame(state, childContent, parentFrame, frameItems);
    }
  }

  // process the current pseudo frame state
  if (!state.mPseudoFrames.IsEmpty()) {
    ProcessPseudoFrames(state, frameItems);
  }

  if (haveFirstLineStyle) {
    // It's possible that some of the new frames go into a
    // first-line frame. Look at them and see...
    AppendFirstLineFrames(state, aContainer, parentFrame, frameItems); 
  }

  nsresult result = NS_OK;
  firstAppendedFrame = frameItems.childList;
  if (!firstAppendedFrame) {
    firstAppendedFrame = captionItems.childList;
  }

  // Notify the parent frame passing it the list of new frames
  if (NS_SUCCEEDED(result) && firstAppendedFrame) {
    // Perform special check for diddling around with the frames in
    // a special inline frame.

    // XXX Bug 18366
    // Although select frame are inline we do not want to call
    // WipeContainingBlock because it will throw away the entire selct frame and 
    // start over which is something we do not want to do
    //
    nsCOMPtr<nsIDOMHTMLSelectElement> selectContent(do_QueryInterface(aContainer));
    if (!selectContent) {
      if (WipeContainingBlock(state, containingBlock, parentFrame,
                              frameItems.childList)) {
        return NS_OK;
      }
    }

    // Append the flowed frames to the principal child list, tables need special treatment
    if (nsLayoutAtoms::tableFrame == frameType) {
      if (captionItems.childList) { // append the caption to the outer table
        nsIFrame* outerTable = parentFrame->GetParent();
        if (outerTable) { 
          state.mFrameManager->AppendFrames(outerTable,
                                            nsLayoutAtoms::captionList,
                                            captionItems.childList);
        }
      }
      if (frameItems.childList) { // append children of the inner table
        AppendFrames(state, aContainer, parentFrame, frameItems.childList,
                     parentAfterFrame);
      }
    }
    else {
      AppendFrames(state, aContainer, parentFrame, firstAppendedFrame,
                   parentAfterFrame);
    }

    // Recover first-letter frames
    if (haveFirstLetterStyle) {
      RecoverLetterFrames(state, containingBlock);
    }
  }

  // Here we have been notified that content has been appended so if
  // the select now has a single item we need to go in and removed
  // the dummy frame.
  nsCOMPtr<nsIDOMHTMLSelectElement> sel(do_QueryInterface(aContainer));
  if (sel) {
    nsIContent *childContent = aContainer->GetChildAt(aNewIndexInContainer);
    if (childContent) {
      RemoveDummyFrameFromSelect(aContainer, childContent, sel);
    }
  } 

#ifdef DEBUG
  if (gReallyNoisyContentUpdates) {
    nsIFrameDebug* fdbg = nsnull;
    CallQueryInterface(parentFrame, &fdbg);
    if (fdbg) {
      printf("nsCSSFrameConstructor::ContentAppended: resulting frame model:\n");
      fdbg->List(state.mPresContext, stdout, 0);
    }
  }
#endif

  return NS_OK;
}

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ContentInserted ( nsIContent aContainer,
nsIFrame aContainerFrame,
nsIContent aChild,
PRInt32  aIndexInContainer,
nsILayoutHistoryState aFrameState,
PRBool  aInReinsertContent 
)

Definition at line 9247 of file nsCSSFrameConstructor.cpp.

{
  // XXXldb Do we need to re-resolve style to handle the CSS2 + combinator and
  // the :empty pseudo-class?
#ifdef DEBUG
  if (gNoisyContentUpdates) {
    printf("nsCSSFrameConstructor::ContentInserted container=%p child=%p index=%d\n",
           NS_STATIC_CAST(void*, aContainer),
           NS_STATIC_CAST(void*, aChild),
           aIndexInContainer);
    if (gReallyNoisyContentUpdates) {
      (aContainer ? aContainer : aChild)->List(stdout, 0);
    }
  }
#endif

  nsresult rv = NS_OK;

#ifdef MOZ_XUL
  if (NotifyListBoxBody(mPresShell->GetPresContext(), aContainer, aChild,
                        aIndexInContainer, 
                        mDocument, nsnull, gUseXBLForms, CONTENT_INSERTED))
    return NS_OK;
#endif // MOZ_XUL
  
  // If we have a null parent, then this must be the document element
  // being inserted
  if (! aContainer) {
    nsIContent *docElement = mDocument->GetRootContent();

    if (aChild == docElement) {
      NS_PRECONDITION(nsnull == mInitialContainingBlock, "initial containing block already created");
      
      if (!mDocElementContainingBlock)
        return NS_OK; // We get into this situation when an XBL binding is asynchronously
                      // applied to the root tag (e.g., <window> in XUL).  It's ok.  We can
                      // just bail here because the root will really be built later during
                      // InitialReflow.

      // Create frames for the document element and its child elements
      nsIFrame*               docElementFrame;
      nsFrameConstructorState state(mPresShell, mFixedContainingBlock, nsnull,
                                    nsnull, aFrameState);
      ConstructDocElementFrame(state,
                               docElement, 
                               mDocElementContainingBlock,
                               &docElementFrame);
    
      if (mDocElementContainingBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
        // Set the initial child list for the parent and wait on the initial
        // reflow.
        mDocElementContainingBlock->SetInitialChildList(state.mPresContext, 
                                                        nsnull, 
                                                        docElementFrame);
      } else {
        // Whoops, we've already received our initial reflow! Insert the doc.
        // element as a child so it reflows (note that containing block is
        // empty, so we can simply append).
        NS_ASSERTION(mDocElementContainingBlock->GetFirstChild(nsnull) == nsnull,
                     "Unexpected child of document element containing block");
        mDocElementContainingBlock->AppendFrames(nsnull, docElementFrame);
      }

#ifdef DEBUG
      if (gReallyNoisyContentUpdates && docElementFrame) {
        nsIFrameDebug* fdbg = nsnull;
        CallQueryInterface(docElementFrame, &fdbg);
        if (fdbg) {
          printf("nsCSSFrameConstructor::ContentInserted: resulting frame model:\n");
          fdbg->List(state.mPresContext, stdout, 0);
        }
      }
#endif
    }

    // otherwise this is not a child of the root element, and we
    // won't let it have a frame.
    return NS_OK;
  }

  // Otherwise, we've got parent content. Find its frame.
  nsIFrame* parentFrame = aContainerFrame;
  if (!parentFrame) {
    parentFrame = GetFrameFor(aContainer);
    if (! parentFrame)
      return NS_OK; // XXXwaterson will this break selects? (See ``Here
    // we have been notified...'' below.)
  }

  // See if we have an XBL insertion point. If so, then that's our
  // real parent frame; if not, then the frame hasn't been built yet
  // and we just bail.
  nsIFrame* insertionPoint;
  GetInsertionPoint(parentFrame, aChild, &insertionPoint);
  if (! insertionPoint)
    return NS_OK; // Don't build the frames.

  parentFrame = insertionPoint;

  // Find the frame that precedes the insertion point. Walk backwards
  // from the parent frame to get the parent content, because if an
  // XBL insertion point is involved, we'll need to use _that_ to find
  // the preceding frame.
  nsIContent* container = parentFrame->GetContent();

  // XXX if the insertionPoint was different from the original
  // parentFrame, then aIndexInContainer is most likely completely
  // wrong. What we need to do here is remember the original index,
  // then as we insert, search the child list where we're about to put
  // the new frame to make sure that it appears after any siblings
  // with a lower index, and before any siblings with a higher
  // index. Same with FindNextSibling(), below.
  nsIFrame* prevSibling = (aIndexInContainer >= 0)
    ? FindPreviousSibling(container, parentFrame, aIndexInContainer, aChild)
    : FindPreviousAnonymousSibling(mPresShell, mDocument, aContainer, aChild);

  PRBool    isAppend = PR_FALSE;
  nsIFrame* appendAfterFrame;  // This is only looked at when isAppend is true
  nsIFrame* nextSibling = nsnull;
    
  // If there is no previous sibling, then find the frame that follows
  if (! prevSibling) {
    nextSibling = (aIndexInContainer >= 0)
      ? FindNextSibling(container, parentFrame, aIndexInContainer, aChild)
      : FindNextAnonymousSibling(mPresShell, mDocument, aContainer, aChild);
  }

  PRBool handleSpecialFrame = IsFrameSpecial(parentFrame) && !aInReinsertContent;

  // Now, find the geometric parent so that we can handle
  // continuations properly. Use the prev sibling if we have it;
  // otherwise use the next sibling.
  if (prevSibling) {
    if (!handleSpecialFrame)
      parentFrame = prevSibling->GetParent();
  }
  else if (nextSibling) {
    if (!handleSpecialFrame)
      parentFrame = nextSibling->GetParent();
  }
  else {
    // No previous or next sibling, so treat this like an appended frame.
    isAppend = PR_TRUE;
    // Deal with inner/outer tables, fieldsets
    parentFrame = ::GetAdjustedParentFrame(parentFrame, parentFrame->GetType(),
                                           aContainer, aIndexInContainer);
    parentFrame =
      ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
                                          aContainer, parentFrame,
                                          &appendAfterFrame);
  }

  if (parentFrame->GetType() == nsLayoutAtoms::frameSetFrame) {
    // Just reframe the parent, since framesets are weird like that.
    return RecreateFramesForContent(parentFrame->GetContent());
  }
  
  // Don't construct kids of leaves
  if (parentFrame->IsLeaf()) {
    return NS_OK;
  }
  
  // If the frame we are manipulating is a special frame then see if we need to reframe 
  // NOTE: if we are in ReinsertContent, then don't reframe as we are already doing just that!
  if (handleSpecialFrame) {
    // a special inline frame has propagated some of its children upward to be children 
    // of the block and those frames may need to move around. Sometimes we may need to reframe
#ifdef DEBUG
    if (gNoisyContentUpdates) {
      printf("nsCSSFrameConstructor::ContentInserted: parentFrame=");
      nsFrame::ListTag(stdout, parentFrame);
      printf(" is special\n");
    }
#endif
    // if we don't need to reframe then set parentFrame and prevSibling to the correct values
    if (NeedSpecialFrameReframe(aContainer, container, parentFrame, 
                                aChild, aIndexInContainer, prevSibling,
                                nextSibling)) {
      return ReframeContainingBlock(parentFrame);
    }
  }

  nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
                                GetAbsoluteContainingBlock(parentFrame),
                                GetFloatContainingBlock(parentFrame),
                                aFrameState);


  // Recover state for the containing block - we need to know if
  // it has :first-letter or :first-line style applied to it. The
  // reason we care is that the internal structure in these cases
  // is not the normal structure and requires custom updating
  // logic.
  nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
  nsStyleContext* blockSC;
  nsIContent* blockContent = nsnull;
  PRBool haveFirstLetterStyle = PR_FALSE;
  PRBool haveFirstLineStyle = PR_FALSE;

  // In order to shave off some cycles, we only dig up the
  // containing block haveFirst* flags if the parent frame where
  // the insertion/append is occuring is an inline or block
  // container. For other types of containers this isn't relevant.
  const nsStyleDisplay* parentDisplay = parentFrame->GetStyleDisplay();

  // Examine the parentFrame where the insertion is taking
  // place. If its a certain kind of container then some special
  // processing is done.
  if ((NS_STYLE_DISPLAY_BLOCK == parentDisplay->mDisplay) ||
      (NS_STYLE_DISPLAY_LIST_ITEM == parentDisplay->mDisplay) ||
      (NS_STYLE_DISPLAY_INLINE == parentDisplay->mDisplay) ||
      (NS_STYLE_DISPLAY_INLINE_BLOCK == parentDisplay->mDisplay)) {
    // Recover the special style flags for the containing block
    if (containingBlock) {
      haveFirstLetterStyle = HaveFirstLetterStyle(containingBlock);
      haveFirstLineStyle =
        HaveFirstLineStyle(containingBlock->GetContent(),
                           containingBlock->GetStyleContext());
    }

    if (haveFirstLetterStyle) {
      // Get the correct parentFrame and prevSibling - if a
      // letter-frame is present, use its parent.
      if (parentFrame->GetType() == nsLayoutAtoms::letterFrame) {
        parentFrame = parentFrame->GetParent();
        container = parentFrame->GetContent();
      }

      // Remove the old letter frames before doing the insertion
      RemoveLetterFrames(state.mPresContext, mPresShell,
                         state.mFrameManager,
                         state.mFloatedItems.containingBlock);

      // Removing the letterframes messes around with the frame tree, removing
      // and creating frames.  We need to reget our prevsibling.
      // See XXX comment the first time we do this in this method....
      prevSibling = (aIndexInContainer >= 0)
        ? FindPreviousSibling(container, parentFrame, aIndexInContainer,
                              aChild)
        : FindPreviousAnonymousSibling(mPresShell, mDocument, aContainer,
                                       aChild);

      // If there is no previous sibling, then find the frame that follows
      if (! prevSibling) {
        nextSibling = (aIndexInContainer >= 0)
          ? FindNextSibling(container, parentFrame, aIndexInContainer, aChild)
          : FindNextAnonymousSibling(mPresShell, mDocument, aContainer, aChild);
      }

      handleSpecialFrame = IsFrameSpecial(parentFrame) && !aInReinsertContent;
      if (handleSpecialFrame &&
          NeedSpecialFrameReframe(aContainer, container, parentFrame,
                                  aChild, aIndexInContainer, prevSibling,
                                  nextSibling)) {
#ifdef DEBUG
        nsIContent* parentContainer = blockContent->GetParent();
        if (gNoisyContentUpdates) {
          printf("nsCSSFrameConstructor::ContentInserted: parentFrame=");
          nsFrame::ListTag(stdout, parentFrame);
          printf(" is special inline\n");
          printf("  ==> blockContent=%p, parentContainer=%p\n",
                 NS_STATIC_CAST(void*, blockContent),
                 NS_STATIC_CAST(void*, parentContainer));
        }
#endif

        NS_ASSERTION(GetFloatContainingBlock(parentFrame) == containingBlock,
                     "Unexpected block ancestor for parentFrame");

        // Note that in this case we're guaranteed that the closest block
        // containing parentFrame is |containingBlock|.  So
        // ReframeContainingBlock(parentFrame) will make sure to rebuild the
        // first-letter stuff we just blew away.
        return ReframeContainingBlock(parentFrame);
      }
    }
  }
  else if (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == parentDisplay->mDisplay) {
      nsRefPtr<nsStyleContext> childStyleContext;
      childStyleContext = ResolveStyleContext(parentFrame, aChild);
      if (childStyleContext->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_TABLE_COLUMN)
        return NS_OK; //don't create anything else than columns below a colgroup  
  }

  // if the container is a table and a caption will be appended, it needs to be
  // put in the outer table frame's additional child list.
  
  nsFrameItems frameItems, captionItems;

  ConstructFrame(state, aChild, parentFrame, frameItems);
  if (frameItems.childList) {
    if (nsLayoutAtoms::tableCaptionFrame == frameItems.childList->GetType()) {
      NS_ASSERTION(frameItems.childList == frameItems.lastChild ,
                   "adding a non caption frame to the caption childlist?");
      captionItems.AddChild(frameItems.childList);
      frameItems = nsFrameItems();
    }
  }

  // process the current pseudo frame state
  if (!state.mPseudoFrames.IsEmpty())
    ProcessPseudoFrames(state, frameItems);

  // If the final parent frame (decided by AdjustParentFrame()) is different
  // from the parent of the insertion point we calculated above then
  // parentFrame/prevSibling/appendAfterFrame are now invalid and  as it is
  // unknown where to insert correctly we append instead (bug 341858).
  if (frameItems.childList &&
      frameItems.childList->GetParent() != parentFrame) {
    prevSibling = nsnull;
    isAppend = PR_TRUE;
    parentFrame =
      ::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
                                          aContainer,
                                          frameItems.childList->GetParent(),
                                         &appendAfterFrame);
   }

  // XXX Bug 19949
  // Although select frame are inline we do not want to call
  // WipeContainingBlock because it will throw away the entire select frame and 
  // start over which is something we do not want to do
  //
  nsCOMPtr<nsIDOMHTMLSelectElement> selectContent = do_QueryInterface(aContainer);
  if (!selectContent) {
    // Perform special check for diddling around with the frames in
    // a special inline frame.
    if (WipeContainingBlock(state, containingBlock, parentFrame,
                            frameItems.childList))
      return NS_OK;
  }

  if (haveFirstLineStyle) {
    // It's possible that the new frame goes into a first-line
    // frame. Look at it and see...
    if (isAppend) {
      // Use append logic when appending
      AppendFirstLineFrames(state, aContainer, parentFrame, frameItems); 
    }
    else {
      // Use more complicated insert logic when inserting
      InsertFirstLineFrames(state, aContainer, containingBlock, &parentFrame,
                            prevSibling, frameItems);
    }
  }
      
  nsIFrame* newFrame = frameItems.childList;
  if (NS_SUCCEEDED(rv) && newFrame) {
    NS_ASSERTION(!captionItems.childList, "leaking caption frames");
    // Notify the parent frame
    if (isAppend) {
      AppendFrames(state, aContainer, parentFrame, newFrame, appendAfterFrame);
    }
    else {
      if (!prevSibling) {
        // We're inserting the new frame as the first child. See if the
        // parent has a :before pseudo-element
        nsIFrame* firstChild = parentFrame->GetFirstChild(nsnull);

        if (firstChild &&
            nsLayoutUtils::IsGeneratedContentFor(aContainer, firstChild,
                                                 nsCSSPseudoElements::before)) {
          // Insert the new frames after the :before pseudo-element
          prevSibling = firstChild;
        }
      }
      state.mFrameManager->InsertFrames(parentFrame,
                                        nsnull, prevSibling, newFrame);
    }

    if (haveFirstLetterStyle) {
      // Recover the letter frames for the containing block when
      // it has first-letter style.
      RecoverLetterFrames(state, state.mFloatedItems.containingBlock);
    }
  }
  else {
    // we might have a caption treat it here
    nsIFrame* newCaptionFrame = captionItems.childList;
    if (NS_SUCCEEDED(rv) && newCaptionFrame) {
      nsIFrame* outerTableFrame;
      if (GetCaptionAdjustedParent(parentFrame, newCaptionFrame, &outerTableFrame)) {
        // If the parent is not a outer table frame we will try to add frames
        // to a named child list that the parent does not honour and the frames
        // will get lost
        NS_ASSERTION(nsLayoutAtoms::tableOuterFrame == outerTableFrame->GetType(),
                     "Pseudo frame construction failure, a caption can be only a child of a outer table frame");
        if (isAppend) {
          state.mFrameManager->AppendFrames(outerTableFrame,
                                            nsLayoutAtoms::captionList,
                                            newCaptionFrame);
        }
        else {
          state.mFrameManager->InsertFrames(outerTableFrame,
                                            nsLayoutAtoms::captionList,
                                            prevSibling, newCaptionFrame);
        }
      }
    }
  }
  // Here we have been notified that content has been insert
  // so if the select now has a single item 
  // we need to go in and removed the dummy frame
  nsCOMPtr<nsIDOMHTMLSelectElement> selectElement = do_QueryInterface(aContainer);
  if (selectElement)
    RemoveDummyFrameFromSelect(aContainer, aChild, selectElement);

#ifdef DEBUG
  if (gReallyNoisyContentUpdates && parentFrame) {
    nsIFrameDebug* fdbg = nsnull;
    CallQueryInterface(parentFrame, &fdbg);
    if (fdbg) {
      printf("nsCSSFrameConstructor::ContentInserted: resulting frame model:\n");
      fdbg->List(state.mPresContext, stdout, 0);
    }
  }
#endif

  return NS_OK;
}

Here is the caller graph for this function:

nsresult nsCSSFrameConstructor::ContentRemoved ( nsIContent aContainer,
nsIContent aChild,
PRInt32  aIndexInContainer,
PRBool  aInReinsertContent 
)

Definition at line 9882 of file nsCSSFrameConstructor.cpp.

{
  // XXXldb Do we need to re-resolve style to handle the CSS2 + combinator and
  // the :empty pseudo-class?

#ifdef DEBUG
  if (gNoisyContentUpdates) {
    printf("nsCSSFrameConstructor::ContentRemoved container=%p child=%p index=%d\n",
           NS_STATIC_CAST(void*, aContainer),
           NS_STATIC_CAST(void*, aChild),
           aIndexInContainer);
    if (gReallyNoisyContentUpdates) {
      aContainer->List(stdout, 0);
    }
  }
#endif

  nsFrameManager *frameManager = mPresShell->FrameManager();
  nsPresContext *presContext = mPresShell->GetPresContext();
  nsresult                  rv = NS_OK;

  // Find the child frame that maps the content
  nsIFrame* childFrame;
  mPresShell->GetPrimaryFrameFor(aChild, &childFrame);

  if (! childFrame) {
    frameManager->ClearUndisplayedContentIn(aChild, aContainer);
  }

  // When the last item is removed from a select, 
  // we need to add a pseudo frame so select gets sized as the best it can
  // so here we see if it is a select and then we get the number of options
  if (aContainer && childFrame) {
    nsCOMPtr<nsIDOMHTMLSelectElement> selectElement = do_QueryInterface(aContainer);
    if (selectElement) {
      // XXX temp needed only native controls
      nsIFrame* selectFrame;
      // XXX temp needed only native controls
      mPresShell->GetPrimaryFrameFor(aContainer, &selectFrame);

      // For "select" add the pseudo frame after the last item is deleted
      nsIFrame* parentFrame = childFrame->GetParent();
      if (parentFrame && parentFrame != selectFrame) {
        nsFrameConstructorState state(mPresShell,
                                      nsnull, nsnull, nsnull);
        AddDummyFrameToSelect(state, selectFrame, parentFrame, nsnull,
                              aContainer, selectElement);
      }
    } 
  }

#ifdef MOZ_XUL
  if (NotifyListBoxBody(presContext, aContainer, aChild, aIndexInContainer, 
                        mDocument, childFrame, gUseXBLForms, CONTENT_REMOVED))
    return NS_OK;

#endif // MOZ_XUL

  if (childFrame) {
    // If the frame we are manipulating is a special frame then do
    // something different instead of just inserting newly created
    // frames.
    // NOTE: if we are in ReinsertContent, 
    //       then do not reframe as we are already doing just that!
    if (IsFrameSpecial(childFrame) && !aInReinsertContent) {
      // We are pretty harsh here (and definitely not optimal) -- we
      // wipe out the entire containing block and recreate it from
      // scratch. The reason is that because we know that a special
      // inline frame has propagated some of its children upward to be
      // children of the block and that those frames may need to move
      // around. This logic guarantees a correct answer.
#ifdef DEBUG
      if (gNoisyContentUpdates) {
        printf("nsCSSFrameConstructor::ContentRemoved: childFrame=");
        nsFrame::ListTag(stdout, childFrame);
        printf(" is special\n");
      }
#endif
      return ReframeContainingBlock(childFrame);
    }

    // Get the childFrame's parent frame
    nsIFrame* parentFrame = childFrame->GetParent();

    if (parentFrame->GetType() == nsLayoutAtoms::frameSetFrame) {
      // Just reframe the parent, since framesets are weird like that.
      return RecreateFramesForContent(parentFrame->GetContent());
    }

    // Examine the containing-block for the removed content and see if
    // :first-letter style applies.
    nsIFrame* containingBlock = GetFloatContainingBlock(parentFrame);
    PRBool haveFLS = containingBlock && HaveFirstLetterStyle(containingBlock);
    if (haveFLS) {
      // Trap out to special routine that handles adjusting a blocks
      // frame tree when first-letter style is present.
#ifdef NOISY_FIRST_LETTER
      printf("ContentRemoved: containingBlock=");
      nsFrame::ListTag(stdout, containingBlock);
      printf(" parentFrame=");
      nsFrame::ListTag(stdout, parentFrame);
      printf(" childFrame=");
      nsFrame::ListTag(stdout, childFrame);
      printf("\n");
#endif

      // First update the containing blocks structure by removing the
      // existing letter frames. This makes the subsequent logic
      // simpler.
      RemoveLetterFrames(presContext, mPresShell, frameManager,
                         containingBlock);

      // Recover childFrame and parentFrame
      mPresShell->GetPrimaryFrameFor(aChild, &childFrame);
      if (!childFrame) {
        frameManager->ClearUndisplayedContentIn(aChild, aContainer);
        return NS_OK;
      }
      parentFrame = childFrame->GetParent();

#ifdef NOISY_FIRST_LETTER
      printf("  ==> revised parentFrame=");
      nsFrame::ListTag(stdout, parentFrame);
      printf(" childFrame=");
      nsFrame::ListTag(stdout, childFrame);
      printf("\n");
#endif
    }

#ifdef DEBUG
    if (gReallyNoisyContentUpdates) {
      printf("nsCSSFrameConstructor::ContentRemoved: childFrame=");
      nsFrame::ListTag(stdout, childFrame);
      printf("\n");

      if (parentFrame) {
        nsIFrameDebug* fdbg = nsnull;
        CallQueryInterface(parentFrame, &fdbg);
        if (fdbg)
          fdbg->List(presContext, stdout, 0);
      }
      else
        printf("  ==> no parent frame\n");
    }
#endif

    // Walk the frame subtree deleting any out-of-flow frames, and
    // remove the mapping from content objects to frames
    ::DeletingFrameSubtree(presContext, frameManager, childFrame);

    // See if the child frame is a floating frame
    //   (positioned frames are handled below in the "else" clause)
    const nsStyleDisplay* display = childFrame->GetStyleDisplay();
    nsPlaceholderFrame* placeholderFrame = nsnull;
    if (display->mDisplay == NS_STYLE_DISPLAY_POPUP)
      // Get the placeholder frame
      placeholderFrame = frameManager->GetPlaceholderFrameFor(childFrame);
    if (placeholderFrame) {
      // Remove the mapping from the frame to its placeholder
      frameManager->UnregisterPlaceholderFrame(placeholderFrame);
    
      // Locate the root popup set and remove ourselves from the popup set's list
      // of popup frames.
      nsIFrame* rootFrame = frameManager->GetRootFrame();
      if (rootFrame)
        rootFrame = rootFrame->GetFirstChild(nsnull);
#ifdef MOZ_XUL
      nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
      if (rootBox) {
        nsIFrame* popupSetFrame;
        rootBox->GetPopupSetFrame(&popupSetFrame);
        if (popupSetFrame) {
          nsCOMPtr<nsIPopupSetFrame> popupSet(do_QueryInterface(popupSetFrame));
          if (popupSet)
            popupSet->RemovePopupFrame(childFrame);
        }
      }
#endif

      // Remove the placeholder frame first (XXX second for now) (so
      // that it doesn't retain a dangling pointer to memory)
      if (placeholderFrame) {
        parentFrame = placeholderFrame->GetParent();
        ::DeletingFrameSubtree(presContext, frameManager, placeholderFrame);
        frameManager->RemoveFrame(parentFrame, nsnull, placeholderFrame);
        return NS_OK;
      }
    }
    else if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
      if (display->IsFloating()) {
#ifdef NOISY_FIRST_LETTER
        printf("  ==> child display is still floating!\n");
#endif
        // Get the placeholder frame
        nsPlaceholderFrame* placeholderFrame =
          frameManager->GetPlaceholderFrameFor(childFrame);

        // Remove the mapping from the frame to its placeholder
        if (placeholderFrame)
          frameManager->UnregisterPlaceholderFrame(placeholderFrame);

        // Now we remove the floating frame

        // XXX has to be done first for now: the blocks line list
        // contains an array of pointers to the placeholder - we have to
        // remove the float first (which gets rid of the lines
        // reference to the placeholder and float) and then remove the
        // placeholder
        rv = frameManager->RemoveFrame(parentFrame,
                                       nsLayoutAtoms::floatList, childFrame);
        if (NS_FAILED(rv)) {
          // We might have made it normal content instead. Try removing it from
          // the normal child list.
          rv = frameManager->RemoveFrame(parentFrame, nsnull, childFrame);
        }

        // Remove the placeholder frame first (XXX second for now) (so
        // that it doesn't retain a dangling pointer to memory)
        if (placeholderFrame) {
          parentFrame = placeholderFrame->GetP