Bug 504221 part 8. Make CreateAnonymousColFrames saner. r=bernd, sr=roc

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

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

@ -676,66 +676,6 @@ CleanupFrameReferences(nsFrameManager* aFrameManager,
// ----------------------------------------------------------- // -----------------------------------------------------------
// Structure used when constructing formatting object trees.
struct nsFrameItems : public nsFrameList {
nsIFrame* lastChild;
nsFrameItems(nsIFrame* aFrame = nsnull);
// Appends the frame to the end of the list
void AddChild(nsIFrame* aChild);
void InsertFrame(nsIFrame* aParent, nsIFrame* aPrevSibling,
nsIFrame* aNewFrame) {
nsFrameList::InsertFrame(aParent, aPrevSibling, aNewFrame);
if (aPrevSibling == lastChild) {
lastChild = aNewFrame;
}
}
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) nsFrameItems::nsFrameItems(nsIFrame* aFrame)
: nsFrameList(aFrame), lastChild(aFrame) : nsFrameList(aFrame), lastChild(aFrame)
{ {

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

@ -81,6 +81,66 @@ typedef void (nsLazyFrameConstructionCallback)
class nsFrameConstructorState; class nsFrameConstructorState;
class nsFrameConstructorSaveState; class nsFrameConstructorSaveState;
// Structure used when constructing formatting object trees.
struct nsFrameItems : public nsFrameList {
nsIFrame* lastChild;
nsFrameItems(nsIFrame* aFrame = nsnull);
// Appends the frame to the end of the list
void AddChild(nsIFrame* aChild);
void InsertFrame(nsIFrame* aParent, nsIFrame* aPrevSibling,
nsIFrame* aNewFrame) {
nsFrameList::InsertFrame(aParent, aPrevSibling, aNewFrame);
if (aPrevSibling == lastChild) {
lastChild = aNewFrame;
}
}
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(); }
};
class nsCSSFrameConstructor class nsCSSFrameConstructor
{ {
public: public:

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

@ -192,12 +192,8 @@ nsTableColGroupFrame::SetInitialChildList(nsIAtom* aListName,
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
if (!aChildList) { if (!aChildList) {
nsIFrame* firstChild; tableFrame->AppendAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup,
tableFrame->CreateAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup, PR_FALSE);
PR_FALSE, nsnull, &firstChild);
if (firstChild) {
SetInitialChildList(aListName, firstChild);
}
return NS_OK; return NS_OK;
} }

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

@ -207,7 +207,7 @@ public:
/** provide access to the mFrames list /** provide access to the mFrames list
*/ */
nsFrameList& GetChildList(); nsFrameList& GetWritableChildList();
/** set the column index for all frames starting at aStartColFrame, it /** set the column index for all frames starting at aStartColFrame, it
* will also reset the column indices in all subsequent colgroups * will also reset the column indices in all subsequent colgroups
@ -275,7 +275,7 @@ inline PRInt32 nsTableColGroupFrame::GetColCount() const
return mColCount; return mColCount;
} }
inline nsFrameList& nsTableColGroupFrame::GetChildList() inline nsFrameList& nsTableColGroupFrame::GetWritableChildList()
{ {
return mFrames; return mFrames;
} }

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

@ -713,23 +713,12 @@ nsTableFrame::CreateAnonymousColGroupFrame(nsTableColGroupType aColGroupType)
void void
nsTableFrame::AppendAnonymousColFrames(PRInt32 aNumColsToAdd) nsTableFrame::AppendAnonymousColFrames(PRInt32 aNumColsToAdd)
{ {
nsTableColFrame* prevCol = nsnull;
// get the last col group frame // get the last col group frame
nsTableColGroupFrame* colGroupFrame = nsnull; nsTableColGroupFrame* colGroupFrame =
nsIFrame* childFrame = mColGroups.FirstChild(); static_cast<nsTableColGroupFrame*>(mColGroups.LastChild());
while (childFrame) {
if (nsGkAtoms::tableColGroupFrame == childFrame->GetType()) {
colGroupFrame = (nsTableColGroupFrame *)childFrame;
}
childFrame = childFrame->GetNextSibling();
}
if (colGroupFrame && if (!colGroupFrame ||
(colGroupFrame->GetColType() == eColGroupAnonymousCell)) { (colGroupFrame->GetColType() != eColGroupAnonymousCell)) {
prevCol =
static_cast<nsTableColFrame*> (colGroupFrame->GetChildList().LastChild());
}
else {
PRInt32 colIndex = (colGroupFrame) ? PRInt32 colIndex = (colGroupFrame) ?
colGroupFrame->GetStartColumnIndex() + colGroupFrame->GetStartColumnIndex() +
colGroupFrame->GetColCount() : 0; colGroupFrame->GetColCount() : 0;
@ -741,38 +730,26 @@ nsTableFrame::AppendAnonymousColFrames(PRInt32 aNumColsToAdd)
mColGroups.AppendFrame(this, colGroupFrame); mColGroups.AppendFrame(this, colGroupFrame);
colGroupFrame->SetStartColumnIndex(colIndex); colGroupFrame->SetStartColumnIndex(colIndex);
} }
nsIFrame* firstNewFrame; AppendAnonymousColFrames(colGroupFrame, aNumColsToAdd, eColAnonymousCell,
CreateAnonymousColFrames(colGroupFrame, aNumColsToAdd, eColAnonymousCell, PR_TRUE);
PR_TRUE, prevCol, &firstNewFrame);
} }
// XXX this needs to be moved to nsCSSFrameConstructor // XXX this needs to be moved to nsCSSFrameConstructor
// Right now it only creates the col frames at the end // Right now it only creates the col frames at the end
void void
nsTableFrame::CreateAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame, nsTableFrame::AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
PRInt32 aNumColsToAdd, PRInt32 aNumColsToAdd,
nsTableColType aColType, nsTableColType aColType,
PRBool aAddToColGroupAndTable, PRBool aAddToTable)
nsIFrame* aPrevFrameIn,
nsIFrame** aFirstNewFrame)
{ {
NS_PRECONDITION(aColGroupFrame, "null frame"); NS_PRECONDITION(aColGroupFrame, "null frame");
NS_PRECONDITION(aColType != eColAnonymousCol, "Shouldn't happen"); NS_PRECONDITION(aColType != eColAnonymousCol, "Shouldn't happen");
*aFirstNewFrame = nsnull; nsIPresShell *shell = PresContext()->PresShell();
nsIFrame* lastColFrame = nsnull;
nsPresContext* presContext = PresContext();
nsIPresShell *shell = presContext->PresShell();
// Get the last col frame // Get the last col frame
nsIFrame* childFrame = aColGroupFrame->GetFirstChild(nsnull); nsFrameItems newColFrames;
while (childFrame) {
if (nsGkAtoms::tableColFrame == childFrame->GetType()) {
lastColFrame = (nsTableColGroupFrame *)childFrame;
}
childFrame = childFrame->GetNextSibling();
}
PRInt32 startIndex = mColFrames.Length(); PRInt32 startIndex = mColFrames.Length();
PRInt32 lastIndex = startIndex + aNumColsToAdd - 1; PRInt32 lastIndex = startIndex + aNumColsToAdd - 1;
@ -796,35 +773,26 @@ nsTableFrame::CreateAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
nsIFrame* colFrame = NS_NewTableColFrame(shell, styleContext); nsIFrame* colFrame = NS_NewTableColFrame(shell, styleContext);
((nsTableColFrame *) colFrame)->SetColType(aColType); ((nsTableColFrame *) colFrame)->SetColType(aColType);
colFrame->Init(iContent, aColGroupFrame, nsnull); colFrame->Init(iContent, aColGroupFrame, nsnull);
colFrame->SetInitialChildList(nsnull, nsnull);
// Add the col to the sibling chain newColFrames.AddChild(colFrame);
if (lastColFrame) {
lastColFrame->SetNextSibling(colFrame);
}
lastColFrame = colFrame;
if (childX == startIndex) {
*aFirstNewFrame = colFrame;
}
} }
if (aAddToColGroupAndTable) { nsFrameList& cols = aColGroupFrame->GetWritableChildList();
nsFrameList& cols = aColGroupFrame->GetChildList(); nsIFrame* oldLastCol = cols.LastChild();
// the chain already exists, now add it to the col group child list nsIFrame* firstNewCol = newColFrames.FirstChild();
if (!aPrevFrameIn) { nsIFrame* lastNewCol = newColFrames.lastChild;
cols.AppendFrames(aColGroupFrame, *aFirstNewFrame); cols.InsertFrames(nsnull, oldLastCol, newColFrames);
} if (aAddToTable) {
// get the starting col index in the cache // get the starting col index in the cache
PRInt32 startColIndex = aColGroupFrame->GetStartColumnIndex(); PRInt32 startColIndex;
if (aPrevFrameIn) { if (oldLastCol) {
nsTableColFrame* colFrame = startColIndex =
(nsTableColFrame*)nsTableFrame::GetFrameAtOrBefore((nsIFrame*) aColGroupFrame, aPrevFrameIn, static_cast<nsTableColFrame*>(oldLastCol)->GetColIndex() + 1;
nsGkAtoms::tableColFrame); } else {
if (colFrame) { startColIndex = aColGroupFrame->GetStartColumnIndex();
startColIndex = colFrame->GetColIndex() + 1;
}
} }
aColGroupFrame->AddColsToTable(startColIndex, PR_TRUE, aColGroupFrame->AddColsToTable(startColIndex, PR_TRUE,
*aFirstNewFrame, lastColFrame); firstNewCol, lastNewCol);
} }
} }

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

@ -451,14 +451,18 @@ public:
PRInt32 DestroyAnonymousColFrames(PRInt32 aNumFrames); PRInt32 DestroyAnonymousColFrames(PRInt32 aNumFrames);
// Append aNumColsToAdd anonymous col frames of type eColAnonymousCell to our
// last eColGroupAnonymousCell colgroup. If we have no such colgroup, then
// create one.
void AppendAnonymousColFrames(PRInt32 aNumColsToAdd); void AppendAnonymousColFrames(PRInt32 aNumColsToAdd);
void CreateAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame, // Append aNumColsToAdd anonymous col frames of type aColType to
// aColGroupFrame. If aAddToTable is true, also call AddColsToTable on the
// new cols.
void AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
PRInt32 aNumColsToAdd, PRInt32 aNumColsToAdd,
nsTableColType aColType, nsTableColType aColType,
PRBool aAddToColGroupAndTable, PRBool aAddToTable);
nsIFrame* aPrevCol,
nsIFrame** aFirstNewFrame);
void MatchCellMapToColCache(nsTableCellMap* aCellMap); void MatchCellMapToColCache(nsTableCellMap* aCellMap);
/** empty the column frame cache */ /** empty the column frame cache */