зеркало из https://github.com/mozilla/gecko-dev.git
Bug 504221 part 8. Make CreateAnonymousColFrames saner. r=bernd, sr=roc
This commit is contained in:
Родитель
1d9375f5db
Коммит
05d3ed5b06
|
@ -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)
|
||||
: nsFrameList(aFrame), lastChild(aFrame)
|
||||
{
|
||||
|
|
|
@ -81,6 +81,66 @@ typedef void (nsLazyFrameConstructionCallback)
|
|||
class nsFrameConstructorState;
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -192,12 +192,8 @@ nsTableColGroupFrame::SetInitialChildList(nsIAtom* aListName,
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (!aChildList) {
|
||||
nsIFrame* firstChild;
|
||||
tableFrame->CreateAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup,
|
||||
PR_FALSE, nsnull, &firstChild);
|
||||
if (firstChild) {
|
||||
SetInitialChildList(aListName, firstChild);
|
||||
}
|
||||
tableFrame->AppendAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup,
|
||||
PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ public:
|
|||
|
||||
/** provide access to the mFrames list
|
||||
*/
|
||||
nsFrameList& GetChildList();
|
||||
nsFrameList& GetWritableChildList();
|
||||
|
||||
/** set the column index for all frames starting at aStartColFrame, it
|
||||
* will also reset the column indices in all subsequent colgroups
|
||||
|
@ -275,7 +275,7 @@ inline PRInt32 nsTableColGroupFrame::GetColCount() const
|
|||
return mColCount;
|
||||
}
|
||||
|
||||
inline nsFrameList& nsTableColGroupFrame::GetChildList()
|
||||
inline nsFrameList& nsTableColGroupFrame::GetWritableChildList()
|
||||
{
|
||||
return mFrames;
|
||||
}
|
||||
|
|
|
@ -713,23 +713,12 @@ nsTableFrame::CreateAnonymousColGroupFrame(nsTableColGroupType aColGroupType)
|
|||
void
|
||||
nsTableFrame::AppendAnonymousColFrames(PRInt32 aNumColsToAdd)
|
||||
{
|
||||
nsTableColFrame* prevCol = nsnull;
|
||||
// get the last col group frame
|
||||
nsTableColGroupFrame* colGroupFrame = nsnull;
|
||||
nsIFrame* childFrame = mColGroups.FirstChild();
|
||||
while (childFrame) {
|
||||
if (nsGkAtoms::tableColGroupFrame == childFrame->GetType()) {
|
||||
colGroupFrame = (nsTableColGroupFrame *)childFrame;
|
||||
}
|
||||
childFrame = childFrame->GetNextSibling();
|
||||
}
|
||||
nsTableColGroupFrame* colGroupFrame =
|
||||
static_cast<nsTableColGroupFrame*>(mColGroups.LastChild());
|
||||
|
||||
if (colGroupFrame &&
|
||||
(colGroupFrame->GetColType() == eColGroupAnonymousCell)) {
|
||||
prevCol =
|
||||
static_cast<nsTableColFrame*> (colGroupFrame->GetChildList().LastChild());
|
||||
}
|
||||
else {
|
||||
if (!colGroupFrame ||
|
||||
(colGroupFrame->GetColType() != eColGroupAnonymousCell)) {
|
||||
PRInt32 colIndex = (colGroupFrame) ?
|
||||
colGroupFrame->GetStartColumnIndex() +
|
||||
colGroupFrame->GetColCount() : 0;
|
||||
|
@ -741,38 +730,26 @@ nsTableFrame::AppendAnonymousColFrames(PRInt32 aNumColsToAdd)
|
|||
mColGroups.AppendFrame(this, colGroupFrame);
|
||||
colGroupFrame->SetStartColumnIndex(colIndex);
|
||||
}
|
||||
nsIFrame* firstNewFrame;
|
||||
CreateAnonymousColFrames(colGroupFrame, aNumColsToAdd, eColAnonymousCell,
|
||||
PR_TRUE, prevCol, &firstNewFrame);
|
||||
AppendAnonymousColFrames(colGroupFrame, aNumColsToAdd, eColAnonymousCell,
|
||||
PR_TRUE);
|
||||
|
||||
}
|
||||
|
||||
// XXX this needs to be moved to nsCSSFrameConstructor
|
||||
// Right now it only creates the col frames at the end
|
||||
void
|
||||
nsTableFrame::CreateAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
|
||||
nsTableFrame::AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
|
||||
PRInt32 aNumColsToAdd,
|
||||
nsTableColType aColType,
|
||||
PRBool aAddToColGroupAndTable,
|
||||
nsIFrame* aPrevFrameIn,
|
||||
nsIFrame** aFirstNewFrame)
|
||||
PRBool aAddToTable)
|
||||
{
|
||||
NS_PRECONDITION(aColGroupFrame, "null frame");
|
||||
NS_PRECONDITION(aColType != eColAnonymousCol, "Shouldn't happen");
|
||||
|
||||
*aFirstNewFrame = nsnull;
|
||||
nsIFrame* lastColFrame = nsnull;
|
||||
nsPresContext* presContext = PresContext();
|
||||
nsIPresShell *shell = presContext->PresShell();
|
||||
nsIPresShell *shell = PresContext()->PresShell();
|
||||
|
||||
// Get the last col frame
|
||||
nsIFrame* childFrame = aColGroupFrame->GetFirstChild(nsnull);
|
||||
while (childFrame) {
|
||||
if (nsGkAtoms::tableColFrame == childFrame->GetType()) {
|
||||
lastColFrame = (nsTableColGroupFrame *)childFrame;
|
||||
}
|
||||
childFrame = childFrame->GetNextSibling();
|
||||
}
|
||||
nsFrameItems newColFrames;
|
||||
|
||||
PRInt32 startIndex = mColFrames.Length();
|
||||
PRInt32 lastIndex = startIndex + aNumColsToAdd - 1;
|
||||
|
@ -796,35 +773,26 @@ nsTableFrame::CreateAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
|
|||
nsIFrame* colFrame = NS_NewTableColFrame(shell, styleContext);
|
||||
((nsTableColFrame *) colFrame)->SetColType(aColType);
|
||||
colFrame->Init(iContent, aColGroupFrame, nsnull);
|
||||
colFrame->SetInitialChildList(nsnull, nsnull);
|
||||
|
||||
// Add the col to the sibling chain
|
||||
if (lastColFrame) {
|
||||
lastColFrame->SetNextSibling(colFrame);
|
||||
}
|
||||
lastColFrame = colFrame;
|
||||
if (childX == startIndex) {
|
||||
*aFirstNewFrame = colFrame;
|
||||
}
|
||||
}
|
||||
if (aAddToColGroupAndTable) {
|
||||
nsFrameList& cols = aColGroupFrame->GetChildList();
|
||||
// the chain already exists, now add it to the col group child list
|
||||
if (!aPrevFrameIn) {
|
||||
cols.AppendFrames(aColGroupFrame, *aFirstNewFrame);
|
||||
newColFrames.AddChild(colFrame);
|
||||
}
|
||||
nsFrameList& cols = aColGroupFrame->GetWritableChildList();
|
||||
nsIFrame* oldLastCol = cols.LastChild();
|
||||
nsIFrame* firstNewCol = newColFrames.FirstChild();
|
||||
nsIFrame* lastNewCol = newColFrames.lastChild;
|
||||
cols.InsertFrames(nsnull, oldLastCol, newColFrames);
|
||||
if (aAddToTable) {
|
||||
// get the starting col index in the cache
|
||||
PRInt32 startColIndex = aColGroupFrame->GetStartColumnIndex();
|
||||
if (aPrevFrameIn) {
|
||||
nsTableColFrame* colFrame =
|
||||
(nsTableColFrame*)nsTableFrame::GetFrameAtOrBefore((nsIFrame*) aColGroupFrame, aPrevFrameIn,
|
||||
nsGkAtoms::tableColFrame);
|
||||
if (colFrame) {
|
||||
startColIndex = colFrame->GetColIndex() + 1;
|
||||
}
|
||||
PRInt32 startColIndex;
|
||||
if (oldLastCol) {
|
||||
startColIndex =
|
||||
static_cast<nsTableColFrame*>(oldLastCol)->GetColIndex() + 1;
|
||||
} else {
|
||||
startColIndex = aColGroupFrame->GetStartColumnIndex();
|
||||
}
|
||||
|
||||
aColGroupFrame->AddColsToTable(startColIndex, PR_TRUE,
|
||||
*aFirstNewFrame, lastColFrame);
|
||||
firstNewCol, lastNewCol);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -451,14 +451,18 @@ public:
|
|||
|
||||
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 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,
|
||||
nsTableColType aColType,
|
||||
PRBool aAddToColGroupAndTable,
|
||||
nsIFrame* aPrevCol,
|
||||
nsIFrame** aFirstNewFrame);
|
||||
PRBool aAddToTable);
|
||||
|
||||
void MatchCellMapToColCache(nsTableCellMap* aCellMap);
|
||||
/** empty the column frame cache */
|
||||
|
|
Загрузка…
Ссылка в новой задаче