Bug 391559 - "Incorrect ordered-list numbering within -moz-column-* (and/or numbering changes when clicked)" [p=craig.topper@gmail.com (Craig Topper) r+sr=roc a1.9=beltzner]

This commit is contained in:
reed%reedloden.com 2008-02-24 07:31:30 +00:00
Родитель 9150b58c2d
Коммит 26da7d911c
4 изменённых файлов: 81 добавлений и 50 удалений

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

@ -5153,6 +5153,14 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
}
}
nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
PRBool* aFoundValidLine)
: mFrame(aFrame), mInOverflowLines(nsnull)
{
mLine = aFrame->begin_lines();
*aFoundValidLine = FindValidLine();
}
PRBool
nsBlockInFlowLineIterator::IsLastLineInList()
{
@ -5164,29 +5172,7 @@ PRBool
nsBlockInFlowLineIterator::Next()
{
++mLine;
line_iterator end = mInOverflowLines ? mInOverflowLines->end() : mFrame->end_lines();
if (mLine != end)
return PR_TRUE;
PRBool currentlyInOverflowLines = mInOverflowLines != nsnull;
while (PR_TRUE) {
if (currentlyInOverflowLines) {
mFrame = static_cast<nsBlockFrame*>(mFrame->GetNextInFlow());
if (!mFrame)
return PR_FALSE;
mInOverflowLines = nsnull;
mLine = mFrame->begin_lines();
if (mLine != mFrame->end_lines())
return PR_TRUE;
} else {
mInOverflowLines = mFrame->GetOverflowLines();
if (mInOverflowLines) {
mLine = mInOverflowLines->begin();
NS_ASSERTION(mLine != mInOverflowLines->end(), "empty overflow line list?");
return PR_TRUE;
}
}
currentlyInOverflowLines = !currentlyInOverflowLines;
}
return FindValidLine();
}
PRBool
@ -5221,6 +5207,34 @@ nsBlockInFlowLineIterator::Prev()
}
}
PRBool
nsBlockInFlowLineIterator::FindValidLine()
{
line_iterator end = mInOverflowLines ? mInOverflowLines->end() : mFrame->end_lines();
if (mLine != end)
return PR_TRUE;
PRBool currentlyInOverflowLines = mInOverflowLines != nsnull;
while (PR_TRUE) {
if (currentlyInOverflowLines) {
mFrame = static_cast<nsBlockFrame*>(mFrame->GetNextInFlow());
if (!mFrame)
return PR_FALSE;
mInOverflowLines = nsnull;
mLine = mFrame->begin_lines();
if (mLine != mFrame->end_lines())
return PR_TRUE;
} else {
mInOverflowLines = mFrame->GetOverflowLines();
if (mInOverflowLines) {
mLine = mInOverflowLines->begin();
NS_ASSERTION(mLine != mInOverflowLines->end(), "empty overflow line list?");
return PR_TRUE;
}
}
currentlyInOverflowLines = !currentlyInOverflowLines;
}
}
static nsresult RemoveBlockChild(nsIFrame* aFrame, PRBool aDestroyFrames,
PRBool aRemoveOnlyFluidContinuations)
{
@ -6453,29 +6467,28 @@ nsBlockFrame::RenumberListsInBlock(nsPresContext* aPresContext,
PRInt32* aOrdinal,
PRInt32 aDepth)
{
// Examine each line in the block
PRBool foundValidLine;
nsBlockInFlowLineIterator bifLineIter(aBlockFrame, &foundValidLine);
if (!foundValidLine)
return PR_FALSE;
PRBool renumberedABullet = PR_FALSE;
while (nsnull != aBlockFrame) {
// Examine each line in the block
for (line_iterator line = aBlockFrame->begin_lines(),
line_end = aBlockFrame->end_lines();
line != line_end;
++line) {
nsIFrame* kid = line->mFirstChild;
PRInt32 n = line->GetChildCount();
while (--n >= 0) {
PRBool kidRenumberedABullet = RenumberListsFor(aPresContext, kid, aOrdinal, aDepth);
if (kidRenumberedABullet) {
line->MarkDirty();
renumberedABullet = PR_TRUE;
}
kid = kid->GetNextSibling();
do {
nsLineList::iterator line = bifLineIter.GetLine();
nsIFrame* kid = line->mFirstChild;
PRInt32 n = line->GetChildCount();
while (--n >= 0) {
PRBool kidRenumberedABullet = RenumberListsFor(aPresContext, kid, aOrdinal, aDepth);
if (kidRenumberedABullet) {
line->MarkDirty();
renumberedABullet = PR_TRUE;
}
kid = kid->GetNextSibling();
}
// Advance to the next continuation
aBlockFrame = static_cast<nsBlockFrame*>(aBlockFrame->GetNextInFlow());
}
} while (bifLineIter.Next());
return renumberedABullet;
}
@ -6492,14 +6505,18 @@ nsBlockFrame::RenumberListsFor(nsPresContext* aPresContext,
if (MAX_DEPTH_FOR_LIST_RENUMBERING < aDepth)
return PR_FALSE;
PRBool kidRenumberedABullet = PR_FALSE;
// if the frame is a placeholder, then get the out of flow frame
nsIFrame* kid = nsPlaceholderFrame::GetRealFrameFor(aKid);
// drill down through any wrappers to the real frame
kid = kid->GetContentInsertionFrame();
// possible there is no content insertion frame
if (!kid)
return PR_FALSE;
PRBool kidRenumberedABullet = PR_FALSE;
// If the frame is a list-item and the frame implements our
// block frame API then get its bullet and set the list item
// ordinal.

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

@ -570,12 +570,12 @@ protected:
// reflow.
PRBool RenumberLists(nsPresContext* aPresContext);
PRBool RenumberListsInBlock(nsPresContext* aPresContext,
nsBlockFrame* aContainerFrame,
PRInt32* aOrdinal,
PRInt32 aDepth);
static PRBool RenumberListsInBlock(nsPresContext* aPresContext,
nsBlockFrame* aBlockFrame,
PRInt32* aOrdinal,
PRInt32 aDepth);
PRBool RenumberListsFor(nsPresContext* aPresContext, nsIFrame* aKid, PRInt32* aOrdinal, PRInt32 aDepth);
static PRBool RenumberListsFor(nsPresContext* aPresContext, nsIFrame* aKid, PRInt32* aOrdinal, PRInt32 aDepth);
static PRBool FrameStartsCounterScope(nsIFrame* aFrame);
@ -692,6 +692,7 @@ class nsBlockInFlowLineIterator {
public:
typedef nsBlockFrame::line_iterator line_iterator;
nsBlockInFlowLineIterator(nsBlockFrame* aFrame, line_iterator aLine, PRBool aInOverflow);
nsBlockInFlowLineIterator(nsBlockFrame* aFrame, PRBool* aFoundValidLine);
line_iterator GetLine() { return mLine; }
PRBool IsLastLineInList();
@ -712,6 +713,12 @@ private:
nsBlockFrame* mFrame;
line_iterator mLine;
nsLineList* mInOverflowLines;
/**
* Moves iterator to next valid line reachable from the current block.
* Returns false if there are no valid lines.
*/
PRBool FindValidLine();
};
#endif /* nsBlockFrame_h___ */

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

@ -74,7 +74,13 @@ public:
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
virtual nsIFrame* GetContentInsertionFrame() {
return GetFirstChild(nsnull)->GetContentInsertionFrame();
nsIFrame* frame = GetFirstChild(nsnull);
// if no children return nsnull
if (!frame)
return nsnull;
return frame->GetContentInsertionFrame();
}
virtual nsresult StealFrame(nsPresContext* aPresContext,

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

@ -585,6 +585,7 @@ public:
/**
* Get the frame that should be the parent for the frames of child elements
* May return nsnull during reflow
*/
virtual nsIFrame* GetContentInsertionFrame() { return this; }