Bug 504221 part 7. Make nsFrameItems inherit from nsFrameList. rfantasai, r+sr=roc

This commit is contained in:
Boris Zbarsky 2009-07-28 08:53:18 -04:00
Родитель ba5826b152
Коммит 1d9375f5db
3 изменённых файлов: 192 добавлений и 225 удалений

Просмотреть файл

@ -378,6 +378,9 @@ GetFieldSetBlockFrame(nsIFrame* aFieldsetFrame)
return firstChild && firstChild->GetNextSibling() ? firstChild->GetNextSibling() : firstChild;
}
#define FCDATA_DECL(_flags, _func) \
{ _flags, { (FrameCreationFunc)_func } }
//----------------------------------------------------------------------
static PRBool
@ -437,6 +440,16 @@ ReparentFrame(nsFrameManager* aFrameManager,
}
}
static void
ReparentFrames(nsFrameManager* aFrameManager,
nsIFrame* aNewParentFrame,
const nsFrameList& aFrameList)
{
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
ReparentFrame(aFrameManager, aNewParentFrame, e.get());
}
}
//----------------------------------------------------------------------
//
// When inline frames get weird and have block frames in them, we
@ -654,21 +667,17 @@ DoCleanupFrameReferences(nsFrameManager* aFrameManager,
// Helper function that walks a frame list and calls DoCleanupFrameReference()
static void
CleanupFrameReferences(nsFrameManager* aFrameManager,
nsIFrame* aFrameList)
const nsFrameList& aFrameList)
{
while (aFrameList) {
DoCleanupFrameReferences(aFrameManager, aFrameList);
// Get the sibling frame
aFrameList = aFrameList->GetNextSibling();
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
DoCleanupFrameReferences(aFrameManager, e.get());
}
}
// -----------------------------------------------------------
// Structure used when constructing formatting object trees.
struct nsFrameItems {
nsIFrame* childList;
struct nsFrameItems : public nsFrameList {
nsIFrame* lastChild;
nsFrameItems(nsIFrame* aFrame = nsnull);
@ -676,95 +685,80 @@ struct nsFrameItems {
// Appends the frame to the end of the list
void AddChild(nsIFrame* aChild);
// Inserts the frame somewhere in the list
void InsertChildAfter(nsIFrame* aChild, nsIFrame* aAfter);
void InsertFrame(nsIFrame* aParent, nsIFrame* aPrevSibling,
nsIFrame* aNewFrame) {
nsFrameList::InsertFrame(aParent, aPrevSibling, aNewFrame);
if (aPrevSibling == lastChild) {
lastChild = aNewFrame;
}
}
// Remove the frame from the list, return PR_FALSE if not found. If
// aPrevSibling is given, it must have aChild as its GetNextSibling().
// aPrevSibling may be null to indicate that the list should be searched.
PRBool RemoveChild(nsIFrame* aChild, nsIFrame* aPrevSibling);
void InsertFrames(nsIFrame* aParent, nsIFrame* aPrevSibling,
nsFrameItems& aFrames) {
nsFrameList::InsertFrames(aParent, aPrevSibling, aFrames);
if (aPrevSibling == lastChild) {
lastChild = aFrames.lastChild;
}
}
void DestroyFrame(nsIFrame* aFrameToDestroy, nsIFrame* aPrevSibling) {
NS_PRECONDITION((!aPrevSibling && aFrameToDestroy == FirstChild()) ||
aPrevSibling->GetNextSibling() == aFrameToDestroy,
"Unexpected prevsibling");
nsFrameList::DestroyFrame(aFrameToDestroy, aPrevSibling);
if (aFrameToDestroy == lastChild) {
lastChild = aPrevSibling;
}
}
PRBool RemoveFrame(nsIFrame* aFrameToRemove, nsIFrame* aPrevSibling) {
NS_PRECONDITION(!aPrevSibling ||
aPrevSibling->GetNextSibling() == aFrameToRemove,
"Unexpected aPrevSibling");
if (!aPrevSibling) {
aPrevSibling = GetPrevSiblingFor(aFrameToRemove);
}
PRBool removed = nsFrameList::RemoveFrame(aFrameToRemove, aPrevSibling);
if (aFrameToRemove == lastChild) {
lastChild = aPrevSibling;
}
return removed;
}
void Clear() {
mFirstChild = lastChild = nsnull;
}
// For now, until we change some SetInitialChildList signatures
operator nsIFrame* () { return FirstChild(); }
};
nsFrameItems::nsFrameItems(nsIFrame* aFrame)
: childList(aFrame), lastChild(aFrame)
: nsFrameList(aFrame), lastChild(aFrame)
{
}
void
nsFrameItems::AddChild(nsIFrame* aChild)
{
#ifdef DEBUG
nsIFrame* oldLastChild = lastChild;
#endif
if (childList == nsnull) {
childList = lastChild = aChild;
// It'd be really nice if we could just InsertFrame(nsnull, lastChild,
// aChild) here, but some of our callers put frames that have different
// parents (caption, I'm looking at you) on the same framelist, and
// nsFrameList asserts if you try to do that.
if (IsEmpty()) {
AppendFrames(nsnull, aChild);
}
else
{
NS_ASSERTION(aChild != lastChild,
"Same frame being added to frame list twice?");
lastChild->SetNextSibling(aChild);
lastChild = aChild;
}
// if aChild has siblings, lastChild needs to be the last one
for (nsIFrame* sib = lastChild->GetNextSibling(); sib;
sib = sib->GetNextSibling()) {
NS_ASSERTION(oldLastChild != sib, "Loop in frame list");
lastChild = sib;
}
}
void
nsFrameItems::InsertChildAfter(nsIFrame* aChild, nsIFrame* aAfter)
{
if (!childList || (aAfter && !aAfter->GetNextSibling())) {
// Appending to the end of the list
AddChild(aChild);
return;
}
if (!aAfter) {
// Inserting at beginning of list
aChild->SetNextSibling(childList);
childList = aChild;
return;
}
aChild->SetNextSibling(aAfter->GetNextSibling());
aAfter->SetNextSibling(aChild);
}
PRBool
nsFrameItems::RemoveChild(nsIFrame* aFrame, nsIFrame* aPrevSibling)
{
NS_PRECONDITION(aFrame, "null ptr");
nsIFrame* prev;
if (aPrevSibling) {
prev = aPrevSibling;
} else {
prev = nsnull;
nsIFrame* sib;
for (sib = childList; sib && sib != aFrame; sib = sib->GetNextSibling()) {
prev = sib;
}
if (!sib) {
return PR_FALSE;
}
}
NS_ASSERTION(!prev || prev->GetNextSibling() == aFrame,
"Unexpected prevsibling");
if (aFrame == childList) {
childList = aFrame->GetNextSibling();
} else {
prev->SetNextSibling(aFrame->GetNextSibling());
}
if (aFrame == lastChild) {
lastChild = prev;
}
aFrame->SetNextSibling(nsnull);
return PR_TRUE;
lastChild = nsLayoutUtils::GetLastSibling(aChild);
}
// -----------------------------------------------------------
@ -781,7 +775,7 @@ struct nsAbsoluteItems : nsFrameItems {
// childList in the nsAbsoluteItems we're copying? Introducing a difference
// between debug and non-debug behavior seems bad, so I guess not...
~nsAbsoluteItems() {
NS_ASSERTION(!childList,
NS_ASSERTION(!FirstChild(),
"Dangling child list. Someone forgot to insert it?");
}
#endif
@ -1143,6 +1137,8 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame,
PRBool aInsertAfter,
nsIFrame* aInsertAfterFrame)
{
NS_PRECONDITION(!aNewFrame->GetNextSibling(), "Shouldn't happen");
const nsStyleDisplay* disp = aNewFrame->GetStyleDisplay();
// The comments in GetGeometricParent regarding root table frames
@ -1201,7 +1197,7 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame,
// hence already set as the primary frame. So we have to clean up here.
// But it shouldn't have any out-of-flow kids.
// XXXbz Maybe add a utility function to assert that?
CleanupFrameReferences(mFrameManager, aNewFrame);
DoCleanupFrameReferences(mFrameManager, aNewFrame);
aNewFrame->Destroy();
return rv;
}
@ -1218,7 +1214,7 @@ nsFrameConstructorState::AddChild(nsIFrame* aNewFrame,
#endif
if (aInsertAfter) {
frameItems->InsertChildAfter(aNewFrame, aInsertAfterFrame);
frameItems->InsertFrame(nsnull, aInsertAfterFrame, aNewFrame);
} else {
frameItems->AddChild(aNewFrame);
}
@ -1257,9 +1253,7 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
"Unexpected aFrameItems/aChildListName combination");
#endif
nsIFrame* firstNewFrame = aFrameItems.childList;
if (!firstNewFrame) {
if (aFrameItems.IsEmpty()) {
return;
}
@ -1271,10 +1265,11 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
// Insert the frames hanging out in aItems. We can use SetInitialChildList()
// if the containing block hasn't been reflowed yet (so NS_FRAME_FIRST_REFLOW
// is set) and doesn't have any frames in the aChildListName child list yet.
nsIFrame* firstChild = containingBlock->GetFirstChild(aChildListName);
const nsFrameList& childList = containingBlock->GetChildList(aChildListName);
nsresult rv = NS_OK;
if (!firstChild && (containingBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
rv = containingBlock->SetInitialChildList(aChildListName, firstNewFrame);
if (childList.IsEmpty() &&
(containingBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
rv = containingBlock->SetInitialChildList(aChildListName, aFrameItems);
} else {
// Note that whether the frame construction context is doing an append or
// not is not helpful here, since it could be appending to some frame in
@ -1283,12 +1278,13 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
//
// We need to make sure the 'append to the end of document' case is fast.
// So first test the last child of the containing block
nsIFrame* lastChild = nsLayoutUtils::GetLastSibling(firstChild);
nsIFrame* lastChild = childList.LastChild();
// CompareTreePosition uses placeholder hierarchy for out of flow frames,
// so this will make out-of-flows respect the ordering of placeholders,
// which is great because it takes care of anonymous content.
nsIFrame* insertionPoint = nsnull;
nsIFrame* firstNewFrame = aFrameItems.FirstChild();
if (!lastChild ||
nsLayoutUtils::CompareTreePosition(lastChild, firstNewFrame, containingBlock) < 0) {
// no lastChild, or lastChild comes before the new children, so
@ -1296,7 +1292,8 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
insertionPoint = lastChild;
} else {
// try the other children
for (nsIFrame* f = firstChild; f != lastChild; f = f->GetNextSibling()) {
for (nsIFrame* f = childList.FirstChild(); f != lastChild;
f = f->GetNextSibling()) {
PRInt32 compare =
nsLayoutUtils::CompareTreePosition(f, firstNewFrame, containingBlock);
if (compare > 0) {
@ -1311,7 +1308,7 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
rv = containingBlock->InsertFrames(aChildListName, insertionPoint,
firstNewFrame);
}
aFrameItems.childList = nsnull;
aFrameItems.Clear();
// XXXbz And if NS_FAILED(rv), what? I guess we need to clean up the list
// and deal with all the placeholders... but what if the placeholders aren't
// in the document yet? Could that happen?
@ -1339,7 +1336,7 @@ nsFrameConstructorSaveState::~nsFrameConstructorSaveState()
#ifdef DEBUG
// We've transferred the child list, so drop the pointer we held to it.
// Note that this only matters for the assert in ~nsAbsoluteItems.
mSavedItems.childList = nsnull;
mSavedItems.Clear();
#endif
}
if (mFixedPosIsAbsPos) {
@ -1385,7 +1382,7 @@ AdjustFloatParentPtrs(nsIFrame* aFrame,
NS_ASSERTION(outOfFlowFrame->GetParent() == aOuterState.mFloatedItems.containingBlock,
"expected the float to be a child of the outer CB");
if (aOuterState.mFloatedItems.RemoveChild(outOfFlowFrame, nsnull)) {
if (aOuterState.mFloatedItems.RemoveFrame(outOfFlowFrame, nsnull)) {
aState.mFloatedItems.AddChild(outOfFlowFrame);
} else {
NS_NOTREACHED("float wasn't in the outer state float list");
@ -2042,12 +2039,12 @@ nsCSSFrameConstructor::AdjustParentFrame(nsIFrame* & aParentFra
static void
PullOutCaptionFrames(nsFrameItems& aItems, nsFrameItems& aCaptions)
{
nsIFrame *child = aItems.childList;
nsIFrame *child = aItems.FirstChild();
nsIFrame* prev = nsnull;
while (child) {
nsIFrame *nextSibling = child->GetNextSibling();
if (nsGkAtoms::tableCaptionFrame == child->GetType()) {
aItems.RemoveChild(child, prev);
aItems.RemoveFrame(child, prev);
aCaptions.AddChild(child);
} else {
prev = child;
@ -2143,12 +2140,11 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState,
PullOutCaptionFrames(childItems, captionItems);
// Set the inner table frame's initial primary list
innerFrame->SetInitialChildList(nsnull, childItems.childList);
innerFrame->SetInitialChildList(nsnull, childItems);
// Set the outer table frame's secondary childlist lists
if (captionItems.childList) {
newFrame->SetInitialChildList(nsGkAtoms::captionList,
captionItems.childList);
if (captionItems.NotEmpty()) {
newFrame->SetInitialChildList(nsGkAtoms::captionList, captionItems);
}
*aNewFrame = newFrame;
@ -2194,7 +2190,7 @@ nsCSSFrameConstructor::ConstructTableRow(nsFrameConstructorState& aState,
}
if (NS_FAILED(rv)) return rv;
newFrame->SetInitialChildList(nsnull, childItems.childList);
newFrame->SetInitialChildList(nsnull, childItems);
aFrameItems.AddChild(newFrame);
*aNewFrame = newFrame;
@ -2343,7 +2339,7 @@ nsCSSFrameConstructor::ConstructTableCell(nsFrameConstructorState& aState,
return rv;
}
cellInnerFrame->SetInitialChildList(nsnull, childItems.childList);
cellInnerFrame->SetInitialChildList(nsnull, childItems);
newFrame->SetInitialChildList(nsnull, cellInnerFrame);
aFrameItems.AddChild(newFrame);
*aNewFrame = newFrame;
@ -2601,10 +2597,10 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIContent* aDocEle
nsFrameItems frameItems;
rv = state.AddChild(contentFrame, frameItems, aDocElement,
styleContext, mDocElementContainingBlock);
if (NS_FAILED(rv) || !frameItems.childList) {
if (NS_FAILED(rv) || frameItems.IsEmpty()) {
return rv;
}
*aNewFrame = frameItems.childList;
*aNewFrame = frameItems.FirstChild();
processChildren = PR_TRUE;
// See if we need to create a view
@ -2625,7 +2621,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIContent* aDocEle
// FrameConstructionData/Item, then we'd need the right function
// here... but would probably be able to get away with less code in this
// function in general.
static const FrameConstructionData rootTableData = { 0, nsnull };
static const FrameConstructionData rootTableData = FCDATA_DECL(0, nsnull);
nsRefPtr<nsStyleContext> extraRef(styleContext);
FrameConstructionItem item(&rootTableData, aDocElement,
aDocElement->Tag(), kNameSpaceID_None,
@ -2638,11 +2634,10 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIContent* aDocEle
frameItems, &contentFrame);
if (NS_FAILED(rv))
return rv;
if (!contentFrame || !frameItems.childList)
if (!contentFrame || frameItems.IsEmpty())
return NS_ERROR_FAILURE;
*aNewFrame = frameItems.childList;
NS_ASSERTION(!frameItems.childList->GetNextSibling(),
"multiple root element frames");
*aNewFrame = frameItems.FirstChild();
NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
} else {
contentFrame = NS_NewBlockFrame(mPresShell, styleContext,
NS_BLOCK_FLOAT_MGR|NS_BLOCK_MARGIN_ROOT);
@ -2654,11 +2649,10 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIContent* aDocEle
mDocElementContainingBlock),
mDocElementContainingBlock, styleContext,
&contentFrame, frameItems, display->IsPositioned());
if (NS_FAILED(rv) || !frameItems.childList)
if (NS_FAILED(rv) || frameItems.IsEmpty())
return rv;
*aNewFrame = frameItems.childList;
NS_ASSERTION(!frameItems.childList->GetNextSibling(),
"multiple root element frames");
*aNewFrame = frameItems.FirstChild();
NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
}
}
@ -2690,7 +2684,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(nsIContent* aDocEle
childItems, PR_FALSE);
// Set the initial child lists
contentFrame->SetInitialChildList(nsnull, childItems.childList);
contentFrame->SetInitialChildList(nsnull, childItems);
}
mDocElementContainingBlock->AppendFrames(nsnull, *aNewFrame);
@ -3183,7 +3177,7 @@ nsCSSFrameConstructor::ConstructButtonFrame(nsFrameConstructorState& aState,
if (NS_FAILED(rv)) return rv;
// Set the areas frame's initial child lists
blockFrame->SetInitialChildList(nsnull, childItems.childList);
blockFrame->SetInitialChildList(nsnull, childItems);
}
buttonFrame->SetInitialChildList(nsnull, blockFrame);
@ -3194,10 +3188,10 @@ nsCSSFrameConstructor::ConstructButtonFrame(nsFrameConstructorState& aState,
// we're doing this using a different parent frame from the one we pass to
// ProcessChildren!
CreateAnonymousFrames(aState, content, buttonFrame, anonymousChildItems);
if (anonymousChildItems.childList) {
if (anonymousChildItems.NotEmpty()) {
// the anonymous content is already parented to the area frame
aState.mFrameManager->AppendFrames(blockFrame, nsnull,
anonymousChildItems.childList);
anonymousChildItems.FirstChild());
}
}
@ -3304,14 +3298,14 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState,
nsFrameItems childItems;
CreateAnonymousFrames(aState, content, comboboxFrame, childItems);
comboboxFrame->SetInitialChildList(nsnull, childItems.childList);
comboboxFrame->SetInitialChildList(nsnull, childItems);
// Initialize the additional popup child list which contains the
// dropdown list frame.
nsFrameItems popupItems;
popupItems.AddChild(listFrame);
comboboxFrame->SetInitialChildList(nsGkAtoms::selectPopupList,
popupItems.childList);
popupItems);
*aNewFrame = comboboxFrame;
aState.mFrameState = historyState;
@ -3427,7 +3421,7 @@ nsCSSFrameConstructor::InitializeSelectFrame(nsFrameConstructorState& aState,
childItems, PR_TRUE);
// Set the scrolled frame's initial child lists
scrolledFrame->SetInitialChildList(nsnull, childItems.childList);
scrolledFrame->SetInitialChildList(nsnull, childItems);
return NS_OK;
}
@ -3489,7 +3483,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
ProcessChildren(aState, content, styleContext, blockFrame, PR_TRUE,
childItems, PR_TRUE);
nsIFrame * child = childItems.childList;
nsIFrame * child = childItems.FirstChild();
nsIFrame * previous = nsnull;
nsLegendFrame* legendFrame = nsnull;
while (nsnull != child) {
@ -3500,11 +3494,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
// 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();
}
childItems.RemoveFrame(child, previous);
legendFrame->SetNextSibling(blockFrame);
legendFrame->SetParent(newFrame);
break;
@ -3514,7 +3504,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
}
// Set the scrolled frame's initial child lists
blockFrame->SetInitialChildList(nsnull, childItems.childList);
blockFrame->SetInitialChildList(nsnull, childItems);
// Set the scroll frame's initial child list
newFrame->SetInitialChildList(nsnull, legendFrame ? legendFrame : blockFrame);
@ -3539,8 +3529,6 @@ FindAncestorWithGeneratedContentPseudo(nsIFrame* aFrame)
return nsnull;
}
#define FCDATA_DECL(_flags, _func) \
{ _flags, { (FrameCreationFunc)_func } }
#define SIMPLE_FCDATA(_func) FCDATA_DECL(0, _func)
#define FULL_CTOR_FCDATA(_flags, _func) \
{ _flags | FCDATA_FUNC_IS_FULL_CTOR, { nsnull }, _func }
@ -3989,7 +3977,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
nsFrameItems newItems;
nsFrameItems currentBlock;
nsIFrame* f;
while ((f = childItems.childList) != nsnull) {
while ((f = childItems.FirstChild()) != nsnull) {
PRBool wrapFrame = IsInlineFrame(f) || IsFrameSpecial(f);
if (!wrapFrame) {
rv = FlushAccumulatedBlock(aState, content, newFrame, &currentBlock, &newItems);
@ -3997,7 +3985,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
break;
}
childItems.RemoveChild(f, nsnull);
childItems.RemoveFrame(f, nsnull);
if (wrapFrame) {
currentBlock.AddChild(f);
} else {
@ -4006,10 +3994,10 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
}
rv = FlushAccumulatedBlock(aState, content, newFrame, &currentBlock, &newItems);
if (childItems.childList) {
if (childItems.NotEmpty()) {
// an error must have occurred, delete unprocessed frames
CleanupFrameReferences(aState.mFrameManager, childItems.childList);
nsFrameList(childItems.childList).DestroyFrames();
CleanupFrameReferences(aState.mFrameManager, childItems);
childItems.DestroyFrames();
}
childItems = newItems;
@ -4018,8 +4006,8 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
// Set the frame's initial child list
// Note that MathML depends on this being called even if
// childItems.childList is null!
newFrame->SetInitialChildList(nsnull, childItems.childList);
// childItems is empty!
newFrame->SetInitialChildList(nsnull, childItems);
}
NS_ASSERTION(newFrame->IsFrameOfType(nsIFrame::eLineParticipant) ==
@ -4423,7 +4411,7 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState,
contentStyle).get();
if (gfxScrollFrame) {
gfxScrollFrame->SetInitialChildList(nsnull, anonymousItems.childList);
gfxScrollFrame->SetInitialChildList(nsnull, anonymousItems);
}
return aScrolledChildStyle;
@ -4648,7 +4636,7 @@ nsCSSFrameConstructor::ConstructScrollableBlock(nsFrameConstructorState& aState,
return rv;
}
NS_ASSERTION(blockItem.childList == scrolledFrame,
NS_ASSERTION(blockItem.FirstChild() == scrolledFrame,
"Scrollframe's frameItems should be exactly the scrolled frame");
FinishBuildingScrollFrame(*aNewFrame, scrolledFrame);
@ -4766,7 +4754,7 @@ nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState,
nsFrameItems* aBlockItems,
nsFrameItems* aNewItems)
{
if (!aBlockItems->childList) {
if (aBlockItems->IsEmpty()) {
// Nothing to do
return NS_OK;
}
@ -4789,12 +4777,10 @@ nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState,
return NS_ERROR_OUT_OF_MEMORY;
InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, blockFrame);
for (nsIFrame* f = aBlockItems->childList; f; f = f->GetNextSibling()) {
ReparentFrame(aState.mFrameManager, blockFrame, f);
}
ReparentFrames(aState.mFrameManager, blockFrame, *aBlockItems);
// abs-pos and floats are disabled in MathML children so we don't have to
// worry about messing up those.
blockFrame->SetInitialChildList(nsnull, aBlockItems->childList);
blockFrame->SetInitialChildList(nsnull, *aBlockItems);
*aBlockItems = nsFrameItems();
aNewItems->AddChild(blockFrame);
return NS_OK;
@ -5113,7 +5099,7 @@ nsCSSFrameConstructor::ConstructSVGForeignObjectFrame(nsFrameConstructorState& a
// of blockFrame with views...
nsHTMLContainerFrame::CreateViewForFrame(blockFrame, PR_TRUE);
newFrame->SetInitialChildList(nsnull, childItems.childList);
newFrame->SetInitialChildList(nsnull, childItems);
*aNewFrame = newFrame;
@ -5781,14 +5767,14 @@ nsCSSFrameConstructor::AppendFrames(nsFrameConstructorState& aState,
!IsInlineFrame(aParentFrame) &&
IsInlineOutside(aFrameList.lastChild)) {
// We want to put some of the frames into the following inline frame.
nsIFrame* lastBlock = FindLastBlock(aFrameList.childList);
nsIFrame* lastBlock = FindLastBlock(aFrameList.FirstChild());
nsIFrame* firstTrailingInline;
if (lastBlock) {
firstTrailingInline = lastBlock->GetNextSibling();
lastBlock->SetNextSibling(nsnull);
aFrameList.lastChild = lastBlock;
} else {
firstTrailingInline = aFrameList.childList;
firstTrailingInline = aFrameList.FirstChild();
aFrameList = nsFrameItems();
}
@ -5807,14 +5793,14 @@ nsCSSFrameConstructor::AppendFrames(nsFrameConstructorState& aState,
aParentFrame, &targetState);
}
if (!aFrameList.childList) {
if (aFrameList.IsEmpty()) {
// It all got eaten by the special inline
return NS_OK;
}
// Insert the frames after out aPrevSibling
return aState.mFrameManager->InsertFrames(aParentFrame, nsnull, aPrevSibling,
aFrameList.childList);
aFrameList.FirstChild());
}
#define UNSET_DISPLAY 255
@ -6472,17 +6458,17 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
if (NS_SUCCEEDED(result)) {
// Append the flowed frames to the principal child list; captions
// need special treatment
if (captionItems.childList) { // append the caption to the outer table
if (captionItems.NotEmpty()) { // append the caption to the outer table
NS_ASSERTION(nsGkAtoms::tableFrame == frameType, "how did that happen?");
nsIFrame* outerTable = parentFrame->GetParent();
if (outerTable) {
state.mFrameManager->AppendFrames(outerTable,
nsGkAtoms::captionList,
captionItems.childList);
captionItems.FirstChild());
}
}
if (frameItems.childList) { // append the in-flow kids
if (frameItems.NotEmpty()) { // append the in-flow kids
AppendFrames(state, parentFrame, frameItems, prevSibling);
}
}
@ -6797,14 +6783,14 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
nsFrameItems frameItems, captionItems;
ConstructFramesFromItemList(state, items, parentFrame, frameItems);
if (frameItems.childList) {
if (frameItems.NotEmpty()) {
InvalidateCanvasIfNeeded(mPresShell, aChild);
if (nsGkAtoms::tableCaptionFrame == frameItems.childList->GetType()) {
NS_ASSERTION(frameItems.childList == frameItems.lastChild ,
if (nsGkAtoms::tableCaptionFrame == frameItems.FirstChild()->GetType()) {
NS_ASSERTION(frameItems.OnlyChild(),
"adding a non caption frame to the caption childlist?");
captionItems.AddChild(frameItems.childList);
frameItems = nsFrameItems();
captionItems.AddChild(frameItems.FirstChild());
frameItems.Clear();
}
}
@ -6825,10 +6811,10 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
// XXXbz we should push our frame construction item code up higher, so we
// know what our items are by the time we start figuring out previous
// siblings
if (prevSibling && frameItems.childList &&
frameItems.childList->GetParent() != prevSibling->GetParent()) {
if (prevSibling && frameItems.NotEmpty() &&
frameItems.FirstChild()->GetParent() != prevSibling->GetParent()) {
#ifdef DEBUG
nsIFrame* frame1 = frameItems.childList->GetParent();
nsIFrame* frame1 = frameItems.FirstChild()->GetParent();
nsIFrame* frame2 = prevSibling->GetParent();
NS_ASSERTION(!IsFrameSpecial(frame1) && !IsFrameSpecial(frame2),
"Neither should be special");
@ -6846,7 +6832,7 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
parentFrame =
::AdjustAppendParentForAfterContent(mPresShell->GetPresContext(),
container,
frameItems.childList->GetParent(),
frameItems.FirstChild()->GetParent(),
&appendAfterFrame);
prevSibling = ::FindAppendPrevSibling(parentFrame, appendAfterFrame);
}
@ -6869,21 +6855,20 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
}
}
nsIFrame* const newFrame = frameItems.childList;
if (NS_SUCCEEDED(rv) && newFrame) {
NS_ASSERTION(!captionItems.childList, "leaking caption frames");
if (NS_SUCCEEDED(rv) && frameItems.NotEmpty()) {
NS_ASSERTION(captionItems.IsEmpty(), "leaking caption frames");
// Notify the parent frame
if (isAppend) {
AppendFrames(state, parentFrame, frameItems, prevSibling);
} else {
state.mFrameManager->InsertFrames(parentFrame,
nsnull, prevSibling, newFrame);
state.mFrameManager->InsertFrames(parentFrame, nsnull, prevSibling,
frameItems.FirstChild());
}
}
else {
// we might have a caption treat it here
nsIFrame* newCaptionFrame = captionItems.childList;
if (NS_SUCCEEDED(rv) && newCaptionFrame) {
if (NS_SUCCEEDED(rv) && captionItems.NotEmpty()) {
nsIFrame* newCaptionFrame = captionItems.FirstChild();
nsIFrame* outerTableFrame;
if (GetCaptionAdjustedParent(parentFrame, newCaptionFrame, &outerTableFrame)) {
// If the parent of our current prevSibling is different from the frame
@ -8173,7 +8158,7 @@ nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell* aPresShe
}
// Set the outer table's initial child list
newFrame->SetInitialChildList(nsnull, newChildFrames.childList);
newFrame->SetInitialChildList(nsnull, newChildFrames);
*aContinuingFrame = newFrame;
return NS_OK;
@ -8226,8 +8211,8 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
headerFooterFrame->Init(headerFooter, newFrame, nsnull);
ProcessChildren(state, headerFooter, rowGroupFrame->GetStyleContext(),
headerFooterFrame, PR_TRUE, childItems, PR_FALSE);
NS_ASSERTION(!state.mFloatedItems.childList, "unexpected floated element");
headerFooterFrame->SetInitialChildList(nsnull, childItems.childList);
NS_ASSERTION(state.mFloatedItems.IsEmpty(), "unexpected floated element");
headerFooterFrame->SetInitialChildList(nsnull, childItems);
headerFooterFrame->SetRepeatable(PR_TRUE);
// Table specific initialization
@ -8240,7 +8225,7 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
}
// Set the table frame's initial child list
newFrame->SetInitialChildList(nsnull, childFrames.childList);
newFrame->SetInitialChildList(nsnull, childFrames);
*aContinuingFrame = newFrame;
return NS_OK;
@ -8358,8 +8343,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
rv = CreateContinuingFrame(aPresContext, cellFrame, newFrame,
&continuingCellFrame);
if (NS_FAILED(rv)) {
nsFrameList tmp(newChildList.childList);
tmp.DestroyFrames();
newChildList.DestroyFrames();
newFrame->Destroy();
*aContinuingFrame = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
@ -8370,7 +8354,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
}
// Set the table cell's initial child list
newFrame->SetInitialChildList(nsnull, newChildList.childList);
newFrame->SetInitialChildList(nsnull, newChildList);
}
} else if (IS_TABLE_CELL(frameType)) {
@ -8563,7 +8547,7 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
// broken auto-positioning. Oh, well.
NS_ASSERTION(!canvasFrame->GetFirstChild(nsnull),
"leaking frames; doc root continuation must be empty");
canvasFrame->SetInitialChildList(nsnull, fixedPlaceholders.childList);
canvasFrame->SetInitialChildList(nsnull, fixedPlaceholders);
return NS_OK;
}
@ -9644,14 +9628,14 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
"Shouldn't have first-line style if we're a box");
NS_ASSERTION(!aFrame->IsBoxFrame() ||
itemsToConstruct.AnyItemsNeedBlockParent() ==
(AnyKidsNeedBlockParent(aFrameItems.childList) != nsnull),
(AnyKidsNeedBlockParent(aFrameItems.FirstChild()) != nsnull),
"Something went awry in our block parent calculations");
if (aFrame->IsBoxFrame() && itemsToConstruct.AnyItemsNeedBlockParent()) {
// XXXbz we could do this on the FrameConstructionItemList level,
// no? And if we cared we could look through the item list
// instead of groveling through the framelist here..
nsIContent *badKid = AnyKidsNeedBlockParent(aFrameItems.childList);
nsIContent *badKid = AnyKidsNeedBlockParent(aFrameItems.FirstChild());
nsAutoString parentTag, kidTag;
aContent->Tag()->ToString(parentTag);
badKid->Tag()->ToString(kidTag);
@ -9682,11 +9666,9 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
blockFrame, PR_FALSE);
NS_ASSERTION(!blockFrame->HasView(), "need to do view reparenting");
for (nsIFrame *f = aFrameItems.childList; f; f = f->GetNextSibling()) {
ReparentFrame(aState.mFrameManager, blockFrame, f);
}
ReparentFrames(aState.mFrameManager, blockFrame, aFrameItems);
blockFrame->AppendFrames(nsnull, aFrameItems.childList);
blockFrame->AppendFrames(nsnull, aFrameItems.FirstChild());
aFrameItems = nsFrameItems();
aFrameItems.AddChild(blockFrame);
@ -9720,7 +9702,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLineFrame(
nsresult rv = NS_OK;
// Find the first and last inline frame in aFrameItems
nsIFrame* kid = aFrameItems.childList;
nsIFrame* kid = aFrameItems.FirstChild();
nsIFrame* firstInlineFrame = nsnull;
nsIFrame* lastInlineFrame = nsnull;
while (kid) {
@ -9766,11 +9748,11 @@ nsCSSFrameConstructor::WrapFramesInFirstLineFrame(
if (secondBlockFrame) {
lineFrame->SetNextSibling(secondBlockFrame);
}
if (aFrameItems.childList == lastInlineFrame) {
if (aFrameItems.FirstChild() == lastInlineFrame) {
// Just in case the block had exactly one inline child
aFrameItems.lastChild = lineFrame;
}
aFrameItems.childList = lineFrame;
aFrameItems.SetFrames(lineFrame);
// Give the inline frames to the lineFrame <b>after</b> reparenting them
kid = firstInlineFrame;
@ -9822,7 +9804,7 @@ nsCSSFrameConstructor::AppendFirstLineFrames(
nsIFrame* lineFrame = lastBlockKid;
// Find the first and last inline frame in aFrameItems
nsIFrame* kid = aFrameItems.childList;
nsIFrame* kid = aFrameItems.FirstChild();
nsIFrame* firstInlineFrame = nsnull;
nsIFrame* lastInlineFrame = nsnull;
while (kid) {
@ -9854,11 +9836,10 @@ nsCSSFrameConstructor::AppendFirstLineFrames(
// The remaining frames get appended to the block frame
if (remainingFrames) {
aFrameItems.childList = remainingFrames;
aFrameItems.SetFrames(remainingFrames);
}
else {
aFrameItems.childList = nsnull;
aFrameItems.lastChild = nsnull;
aFrameItems.Clear();
}
return rv;
@ -10145,16 +10126,14 @@ nsCSSFrameConstructor::CreateFloatingLetterFrame(
}
}
NS_ASSERTION(aResult.childList == nsnull,
"aResult should be an empty nsFrameItems!");
NS_ASSERTION(aResult.IsEmpty(), "aResult should be an empty nsFrameItems!");
nsIFrame* insertAfter = nsnull;
nsIFrame* f;
// Put the new float before any of the floats in the block we're
// doing first-letter for, that is, before any floats whose parent is aBlockFrame
for (f = aState.mFloatedItems.childList; f; f = f->GetNextSibling()) {
if (f->GetParent() == aBlockFrame)
for (nsFrameList::Enumerator e(aState.mFloatedItems); !e.AtEnd(); e.Next()) {
if (e.get()->GetParent() == aBlockFrame)
break;
insertAfter = f;
insertAfter = e.get();
}
rv = aState.AddChild(letterFrame, aResult, letterContent, aStyleContext,
@ -10235,7 +10214,8 @@ nsCSSFrameConstructor::CreateLetterFrame(nsIFrame* aBlockFrame,
textFrame);
letterFrame->SetInitialChildList(nsnull, textFrame);
aResult.childList = aResult.lastChild = letterFrame;
aResult.Clear();
aResult.AddChild(letterFrame);
aBlockFrame->AddStateBits(NS_BLOCK_HAS_FIRST_LETTER_CHILD);
}
}
@ -10260,7 +10240,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
nsFrameItems letterFrames;
PRBool stopLooking = PR_FALSE;
rv = WrapFramesInFirstLetterFrame(aBlockFrame, aBlockFrame,
aBlockFrames.childList,
aBlockFrames.FirstChild(),
&parentFrame, &textFrame, &prevFrame,
letterFrames, &stopLooking);
if (NS_FAILED(rv)) {
@ -10268,26 +10248,10 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
}
if (parentFrame) {
if (parentFrame == aBlockFrame) {
// Text textFrame out of the blocks frame list and substitute the
// Take textFrame out of the block's frame list and substitute the
// letter frame(s) instead.
nsIFrame* nextSibling = textFrame->GetNextSibling();
textFrame->SetNextSibling(nsnull);
if (prevFrame) {
prevFrame->SetNextSibling(letterFrames.childList);
}
else {
aBlockFrames.childList = letterFrames.childList;
}
letterFrames.lastChild->SetNextSibling(nextSibling);
// Destroy the old textFrame
textFrame->Destroy();
// Repair lastChild; the only time this needs to happen is when
// the block had one child (the text frame).
if (!nextSibling) {
aBlockFrames.lastChild = letterFrames.lastChild;
}
aBlockFrames.DestroyFrame(textFrame, prevFrame);
aBlockFrames.InsertFrames(nsnull, prevFrame, letterFrames);
}
else {
// Take the old textFrame out of the inline parents child list
@ -10295,7 +10259,7 @@ nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
parentFrame->RemoveFrame(nsnull, textFrame);
// Insert in the letter frame(s)
parentFrame->InsertFrames(nsnull, prevFrame, letterFrames.childList);
parentFrame->InsertFrames(nsnull, prevFrame, letterFrames.FirstChild());
}
}
@ -10603,7 +10567,7 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsIFrame* aBlockFrame)
parentFrame->RemoveFrame(nsnull, textFrame);
// Insert in the letter frame(s)
parentFrame->InsertFrames(nsnull, prevFrame, letterFrames.childList);
parentFrame->InsertFrames(nsnull, prevFrame, letterFrames.FirstChild());
}
return rv;
}
@ -10654,7 +10618,7 @@ nsCSSFrameConstructor::CreateListBoxContent(nsPresContext* aPresContext,
items);
ConstructFramesFromItemList(state, items, aParentFrame, frameItems);
nsIFrame* newFrame = frameItems.childList;
nsIFrame* newFrame = frameItems.FirstChild();
*aNewFrame = newFrame;
if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) {
@ -10752,7 +10716,7 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
childItems, PR_TRUE);
// Set the frame's initial child list
blockFrame->SetInitialChildList(nsnull, childItems.childList);
blockFrame->SetInitialChildList(nsnull, childItems);
return rv;
}
@ -10805,7 +10769,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
return rv;
}
nsIFrame* list1 = childItems.childList;
nsIFrame* list1 = childItems.FirstChild();
nsIFrame* prevToFirstBlock;
nsIFrame* list2;
@ -10819,7 +10783,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
// acquired one when ancestor inline frames and {ib} splits got
// constructed). Just put all the kids into the single inline frame and
// bail.
newFrame->SetInitialChildList(nsnull, childItems.childList);
newFrame->SetInitialChildList(nsnull, childItems);
if (NS_SUCCEEDED(rv)) {
aState.AddChild(newFrame, aFrameItems, content, styleContext, aParentFrame);
*aNewFrame = newFrame;
@ -11874,7 +11838,7 @@ nsCSSFrameConstructor::LazyGenerateChildrenEvent::Run()
return rv;
}
frame->SetInitialChildList(nsnull, childItems.childList);
frame->SetInitialChildList(nsnull, childItems);
fc->EndUpdate();
}

Просмотреть файл

@ -170,10 +170,10 @@ nsFrameList::RemoveFirstChild()
}
PRBool
nsFrameList::DestroyFrame(nsIFrame* aFrame)
nsFrameList::DestroyFrame(nsIFrame* aFrame, nsIFrame* aPrevSiblingHint)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (RemoveFrame(aFrame)) {
if (RemoveFrame(aFrame, aPrevSiblingHint)) {
aFrame->Destroy();
return PR_TRUE;
}

Просмотреть файл

@ -135,9 +135,12 @@ public:
/**
* Take aFrame out of the frame list and then destroy it. This also
* disconnects aFrame from the sibling list. This will return
* PR_FALSE if aFrame is nsnull or if aFrame is not in the list.
* PR_FALSE if aFrame is nsnull or if aFrame is not in the list. The
* second frame is a hint for the prev-sibling of aFrame; if the
* hint is correct, then the time this method takes doesn't depend
* on the number of previous siblings of aFrame.
*/
PRBool DestroyFrame(nsIFrame* aFrame);
PRBool DestroyFrame(nsIFrame* aFrame, nsIFrame* aPrevSiblingHint = nsnull);
/**
* Inserts aNewFrame right after aPrevSibling, or prepends to