зеркало из https://github.com/mozilla/pjs.git
r=troy; reworked the way that blocks inside of inline elements are handled. It's all in the frame construction code now (bugs 15999, 16737)
This commit is contained in:
Родитель
7c3c6240fe
Коммит
0699f8cc22
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -148,7 +148,6 @@ protected:
|
|||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
PRBool aHaveFirstLetterStyle,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult ConstructDocElementFrame(nsIPresContext* aPresContext,
|
||||
|
@ -506,7 +505,6 @@ protected:
|
|||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIStyleContext* aStyleContext,
|
||||
PRBool aHaveFirstLetterStyle,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult GetAdjustedParentFrame(nsIFrame* aCurrentParentFrame,
|
||||
|
@ -662,13 +660,49 @@ InitializeSelectFrame(nsIPresContext* aPresContext,
|
|||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame* aNewFrame);
|
||||
|
||||
nsresult ProcessBlockChildren(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aFrame,
|
||||
PRBool aCanHaveGeneratedContent,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aParentIsBlock);
|
||||
|
||||
nsresult ConstructInline(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
const nsStyleDisplay* aDisplay,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame* aNewFrame);
|
||||
nsIFrame* aNewFrame,
|
||||
nsIFrame** aNewBlockFrame,
|
||||
nsIFrame** aNextInlineFrame);
|
||||
|
||||
nsresult ProcessInlineChildren(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aFrame,
|
||||
PRBool aCanHaveGeneratedContent,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool* aKidsAllInline);
|
||||
|
||||
PRBool AreAllKidsInline(nsIFrame* aFrameList);
|
||||
|
||||
PRBool IsFrameSpecial(nsIFrameManager* aFrameManager, nsIFrame* aFrame);
|
||||
|
||||
PRBool IsFrameSpecial(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
void SetFrameIsSpecial(nsIFrameManager* aFrameManager, nsIFrame* aFrame);
|
||||
|
||||
PRBool WipeContainingBlock(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* blockContent,
|
||||
nsIFrame* aFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult ReframeContainingBlock(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
nsresult RecreateEntireFrameTree(nsIPresContext* aPresContext);
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
|
@ -757,9 +791,6 @@ InitializeSelectFrame(nsIPresContext* aPresContext,
|
|||
nsIFrame* aPrevSibling,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult MaybeCreateContainerFrame(nsIPresContext* aPresContext,
|
||||
nsIContent* aContainer);
|
||||
|
||||
protected:
|
||||
nsIDocument* mDocument;
|
||||
|
||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
|||
// line and don't stop the line reflow...
|
||||
PRBool splitLine = !reflowingFirstLetter;
|
||||
if (reflowingFirstLetter) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (aLine->IsFirstLine()) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
if (NS_SUCCEEDED(aFrame->GetFrameType(&frameType)) && frameType) {
|
||||
if (frameType == nsLayoutAtoms::inlineFrame) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(frameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splitLine) {
|
||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::WrapFramesInFirstLineFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (!line) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the first and last inline line that has frames that aren't
|
||||
// yet in the first-line-frame.
|
||||
nsLineBox* prevLine = nsnull;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
nsFirstLineFrame* lineFrame = nsnull;
|
||||
nsIFrame* nextSib = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
while (line) {
|
||||
if (line->IsBlock()) {
|
||||
nextSib = line->mFirstChild;
|
||||
break;
|
||||
}
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->mChildCount, "bad first line");
|
||||
lineFrame = (nsFirstLineFrame*) line->mFirstChild;
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
else {
|
||||
if (!firstInlineFrame) {
|
||||
firstInlineFrame = line->mFirstChild;
|
||||
}
|
||||
if (prevLine) {
|
||||
prevLine->mNext = line->mNext;
|
||||
delete line;
|
||||
line = prevLine->mNext;
|
||||
}
|
||||
else {
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!firstInlineFrame) {
|
||||
// All of the inline frames are already where they should be
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make the last inline frame thats going into the first-line-frame
|
||||
// have no next sibling.
|
||||
if (line) {
|
||||
nsFrameList frames(firstInlineFrame);
|
||||
nsIFrame* lastInlineFrame = frames.GetPrevSiblingFor(line->mFirstChild);
|
||||
lastInlineFrame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// If there is no first-line-frame currently, we create it
|
||||
if (!lineFrame) {
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(aPresContext);
|
||||
|
||||
// Create line frame
|
||||
rv = NS_NewFirstLineFrame((nsIFrame**) &lineFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = lineFrame->Init(*aPresContext, mContent, this,
|
||||
firstLineStyle, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
line = mLines;
|
||||
line->mFirstChild = lineFrame;
|
||||
line->mChildCount = 1;
|
||||
line->SetIsFirstLine(PR_TRUE);
|
||||
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
|
||||
// Connect last first-line-frame to the remaining frames
|
||||
lineFrame->SetNextSibling(nextSib);
|
||||
|
||||
// Put the new children into the line-frame
|
||||
lineFrame->AppendFrames2(aPresContext, firstInlineFrame);
|
||||
|
||||
// Mark the first-line frames dirty
|
||||
line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
|||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (lastLine) {
|
||||
lastKid = lastLine->LastChild();
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (lastLine->IsFirstLine()) {
|
||||
// Get last frame in the nsFirstLineFrame
|
||||
lastKid->FirstChild(nsnull, &lastKid);
|
||||
nsFrameList frames(lastKid);
|
||||
lastKid = frames.LastChild();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add frames after the last child
|
||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
nsLineBox* prevSibLine = nsnull;
|
||||
PRInt32 prevSiblingIndex = -1;
|
||||
if (aPrevSibling) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Its possible we have an nsFirstLineFrame managing some of our
|
||||
// child frames. If we do and the AddFrames is targetted at it,
|
||||
// use AddFirstLineFrames to get the frames properly placed.
|
||||
nsIFrame* prevSiblingParent;
|
||||
aPrevSibling->GetParent(&prevSiblingParent);
|
||||
if (prevSiblingParent != this) {
|
||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
||||
// first-line's dirty. Not exactly optimial, but it will
|
||||
// guarantee a correct reflow.
|
||||
nsLineBox* line = mLines;
|
||||
while (line) {
|
||||
if (!line->IsFirstLine()) {
|
||||
break;
|
||||
}
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)prevSiblingParent,
|
||||
aFrameList, aPrevSibling);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
else if (mLines && mLines->IsFirstLine()) {
|
||||
mLines->MarkDirty();
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)mLines->mFirstChild,
|
||||
aFrameList, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the frame following aPrevSibling so that we can join up the
|
||||
// two lists of frames.
|
||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling)
|
||||
{
|
||||
// The first run of inline frames being added always go into the
|
||||
// line frame. If we hit a block frame then we need to chop the line
|
||||
// frame into two pieces.
|
||||
nsIFrame* frame = aFrameList;
|
||||
nsIFrame* lastAddedFrame = frame;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
PRInt32 pendingInlines = 0;
|
||||
while (frame) {
|
||||
if (nsLineLayout::TreatFrameAsBlock(frame)) {
|
||||
// There are 3 cases. The block is going to the front of the
|
||||
// line-frames children, in the middle or at the end.
|
||||
if (aPrevSibling) {
|
||||
nsIFrame* next;
|
||||
aPrevSibling->GetNextSibling(&next);
|
||||
|
||||
// Take kids from the line frame starting at next.
|
||||
nsIFrame* kids;
|
||||
if (nsnull == next) {
|
||||
// The block goes in front of aLineFrame's continuation, if
|
||||
// it has one.
|
||||
nsFirstLineFrame* nextLineFrame;
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &nextLineFrame);
|
||||
if (!nextLineFrame) {
|
||||
// No continuation, therefore the block goes after aLineFrame
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, aLineFrame);
|
||||
}
|
||||
// Use nextLineFrame and take away all its kids
|
||||
aLineFrame = nextLineFrame;
|
||||
}
|
||||
kids = TakeKidsFromLineFrame(aLineFrame, next);
|
||||
|
||||
// We will leave the line-frame and its continuations in
|
||||
// place but mark the lines dirty so that they are reflowed
|
||||
// and the empty line-frames (if any) are cleaned up.
|
||||
nsLineBox* line = mLines;
|
||||
nsIFrame* lastLineFrame = aLineFrame;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
lastLineFrame = line->mFirstChild;
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
// Join the taken kids onto the *end* of the frames being
|
||||
// added.
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, lastLineFrame);
|
||||
}
|
||||
else {
|
||||
// Block is trying to go to the front of the line frame (and
|
||||
// therefore in front of all the line-frames children and its
|
||||
// continuations children). Therefore, we don't need a line
|
||||
// frame anymore.
|
||||
nsIFrame* kids = TakeKidsFromLineFrame(aLineFrame, nsnull);
|
||||
|
||||
// Join the kids onto the end of the frames being added
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, newFrames.FirstChild());
|
||||
|
||||
// Remove the line frame (and its continuations). This also
|
||||
// removes the nsLineBox's that pointed to the line-frame. Do
|
||||
// this after FixParentAndView because FixParentAndView needs
|
||||
// a valid old-parent to work.
|
||||
DoRemoveFrame(aPresContext, aLineFrame);
|
||||
|
||||
// Re-enter AddFrames, this time there won't be any first-line
|
||||
// frames so we will use the normal path.
|
||||
return AddFrames(aPresContext, newFrames.FirstChild(), nsnull);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (0 == pendingInlines) {
|
||||
firstInlineFrame = frame;
|
||||
}
|
||||
pendingInlines++;
|
||||
}
|
||||
lastAddedFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
// All of the frames being added are inline frames
|
||||
if (pendingInlines) {
|
||||
return aLineFrame->InsertFrames2(aPresContext, aPrevSibling, aFrameList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsBlockFrame::TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid)
|
||||
{
|
||||
nsFrameList kids;
|
||||
nsIFrame* lastKid;
|
||||
if (aFromKid) {
|
||||
kids.SetFrames(aFromKid);
|
||||
aLineFrame->RemoveFramesFrom(aFromKid);
|
||||
}
|
||||
else {
|
||||
aLineFrame->FirstChild(nsnull, &lastKid);
|
||||
kids.SetFrames(lastKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
}
|
||||
lastKid = kids.LastChild();
|
||||
|
||||
// Capture the next-in-flows kids as well.
|
||||
for (;;) {
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &aLineFrame);
|
||||
if (!aLineFrame) {
|
||||
break;
|
||||
}
|
||||
aLineFrame->FirstChild(nsnull, &aFromKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
lastKid->SetNextSibling(aFromKid);
|
||||
nsFrameList tmp(aFromKid);
|
||||
lastKid = tmp.LastChild();
|
||||
}
|
||||
|
||||
return kids.FirstChild();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
|
@ -4834,15 +4550,6 @@ nsresult
|
|||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
if (parent != this) {
|
||||
return RemoveFirstLineFrame(aPresContext, (nsFirstLineFrame*)parent,
|
||||
aDeletedFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the line and the previous sibling that contains
|
||||
// deletedFrame; we also find the pointer to the line.
|
||||
nsBlockFrame* flow = this;
|
||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
while (nsnull != aDeletedFrame) {
|
||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||
#ifdef NS_DEBUG
|
||||
#ifndef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
#endif
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
||||
|
@ -4990,60 +4695,12 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line, or we
|
||||
// removed a block that preceeded the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
// Strip deleted frame out of the nsFirstLineFrame
|
||||
aLineFrame->RemoveFrame2(aPresContext, aDeletedFrame);
|
||||
aDeletedFrame->Destroy(*aPresContext);
|
||||
|
||||
// See if the line-frame and its continuations are now empty
|
||||
nsFirstLineFrame* lf = (nsFirstLineFrame*) aLineFrame->GetFirstInFlow();
|
||||
nsFirstLineFrame* lf0 = lf;
|
||||
PRBool empty = PR_TRUE;
|
||||
while (lf) {
|
||||
nsIFrame* kids;
|
||||
lf->FirstChild(nsnull, &kids);
|
||||
if (kids) {
|
||||
empty = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
lf->GetNextInFlow((nsIFrame**) &lf);
|
||||
}
|
||||
if (empty) {
|
||||
return DoRemoveFrame(aPresContext, lf0);
|
||||
}
|
||||
|
||||
// Mark first-line lines dirty
|
||||
nsLineBox* line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||
nsIFrame* aChild)
|
||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
|||
return fls;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext*
|
||||
nsBlockFrame::GetFirstLineStyle(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIStyleContext* fls;
|
||||
aPresContext->ProbePseudoStyleContextFor(mContent,
|
||||
nsHTMLAtoms::firstLinePseudo,
|
||||
mStyleContext, PR_FALSE, &fls);
|
||||
return fls;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
|||
#endif
|
||||
NS_RELEASE(firstLetterStyle);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(&aPresContext);
|
||||
if (nsnull != firstLineStyle) {
|
||||
mState |= NS_BLOCK_HAS_FIRST_LINE_STYLE;
|
||||
#ifdef NOISY_FIRST_LINE
|
||||
ListTag(stdout);
|
||||
printf(": first-line style found\n");
|
||||
#endif
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
while (--n >= 0) {
|
||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
// A frame that doesn't implement nsIHTMLReflow isn't text
|
||||
// therefore it will end an open text run.
|
||||
textRunThingy.EndTextRun();
|
||||
}
|
||||
frame->FindTextRuns(textRunThingy);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
}
|
||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsAnonymousBlockFrame* it = new nsAnonymousBlockFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::~nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->AppendFrames(aPresContext, aPresShell, aListName,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->InsertFrames(aPresContext, aPresShell, aListName,
|
||||
aPrevFrame, aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return mParent->RemoveFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::AppendFrames(*aPresContext, *aPresShell,
|
||||
aListName, aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::InsertFrames(*aPresContext, *aPresShell,
|
||||
aListName, aPrevFrame,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::RemoveFrame(*aPresContext, *aPresShell,
|
||||
aListName, aOldFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFirstFrame()
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
nsIFrame* firstChild = line->mFirstChild;
|
||||
|
||||
#if XXX
|
||||
// If the line has floaters on it, see if the frame being removed
|
||||
// is a placeholder frame. If it is, then remove it from the lines
|
||||
// floater array and from the block frames floater child list.
|
||||
if (line->mFloaters.NotEmpty()) {
|
||||
// XXX UNTESTED!
|
||||
nsPlaceholderFrame* placeholderFrame;
|
||||
nsVoidArray& floaters = *line->mFloaters;
|
||||
PRInt32 i, n = floaters.Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
placeholderFrame = (nsPlaceholderFrame*) floaters[i];
|
||||
if (firstChild == placeholderFrame) {
|
||||
// Remove placeholder from the line's floater array
|
||||
floaters.RemoveElementAt(i);
|
||||
if (0 == floaters.Count()) {
|
||||
delete line->mFloaters;
|
||||
line->mFloaters = nsnull;
|
||||
}
|
||||
|
||||
// Remove the floater from the block frames mFloaters list too
|
||||
mFloaters.RemoveFrame(placeholderFrame->GetOutOfFlowFrame());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 lineChildCount = line->GetChildCount();
|
||||
if (1 == lineChildCount) {
|
||||
// Remove line when last frame goes away
|
||||
mLines = line->mNext;
|
||||
delete line;
|
||||
}
|
||||
else {
|
||||
// Remove frame from line and mark the line dirty
|
||||
line->SetChildCount(lineChildCount - 1);
|
||||
line->MarkDirty();
|
||||
firstChild->GetNextSibling(&line->mFirstChild);
|
||||
}
|
||||
|
||||
// Break linkage to next child after stolen frame
|
||||
firstChild->SetNextSibling(nsnull);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFramesFrom(nsIFrame* aFrame)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
// Chop the child sibling list into two pieces
|
||||
nsFrameList tmp(line->mFirstChild);
|
||||
nsIFrame* prevSibling = tmp.GetPrevSiblingFor(aFrame);
|
||||
if (nsnull != prevSibling) {
|
||||
// Chop the sibling list into two pieces
|
||||
prevSibling->SetNextSibling(nsnull);
|
||||
|
||||
nsLineBox* prevLine = nsnull;
|
||||
while (nsnull != line) {
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 i, n = line->GetChildCount();
|
||||
PRBool done = PR_FALSE;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
// We just found the target frame (and the line its in and
|
||||
// the previous line)
|
||||
if (frame == line->mFirstChild) {
|
||||
// No more children on this line, so let it get removed
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
// The only frames that remain on this line are the
|
||||
// frames preceeding aFrame. Adjust the count to
|
||||
// indicate that fact.
|
||||
line->SetChildCount(i);
|
||||
|
||||
// Remove the lines that follow this line
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all of the remaining lines
|
||||
while (nsnull != line) {
|
||||
nsLineBox* next = line->mNext;
|
||||
delete line;
|
||||
line = next;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
|||
if (line->IsBlock()) {
|
||||
seenBlock = PR_TRUE;
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) {
|
||||
if (seenBlock) {
|
||||
NS_ASSERTION(!line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
count += line->GetChildCount();
|
||||
line = line->mNext;
|
||||
|
|
|
@ -40,9 +40,6 @@ class nsFirstLineFrame;
|
|||
*/
|
||||
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET 0x80000000
|
||||
#define NS_BLOCK_IS_HTML_PARAGRAPH 0x40000000
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
#define NS_BLOCK_HAS_FIRST_LINE_STYLE 0x20000000
|
||||
#endif
|
||||
#define NS_BLOCK_HAS_FIRST_LETTER_STYLE 0x10000000
|
||||
|
||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||
|
@ -146,10 +143,6 @@ protected:
|
|||
|
||||
nsIStyleContext* GetFirstLetterStyle(nsIPresContext* aPresContext);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* GetFirstLineStyle(nsIPresContext* aPresContext);
|
||||
#endif
|
||||
|
||||
void SetFlags(PRUint32 aFlags) {
|
||||
mFlags = aFlags;
|
||||
}
|
||||
|
@ -173,22 +166,6 @@ protected:
|
|||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
nsIFrame* TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid);
|
||||
|
||||
nsresult RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame);
|
||||
|
||||
nsresult WrapFramesInFirstLineFrame(nsIPresContext* aPresContext);
|
||||
#endif
|
||||
|
||||
void FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
|
@ -381,72 +358,5 @@ protected:
|
|||
friend class nsBlockReflowState;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define nsAnonymousBlockFrameSuper nsBlockFrame
|
||||
|
||||
// Anonymous block frame. An anonymous block is used by some other
|
||||
// container (the parent frame) to provide block reflow for a set of
|
||||
// child frames. The parent is responsible for the maintainance of the
|
||||
// anonymous blocks child list. To accomplish this, the normal methods
|
||||
// for managing the child list (AppendFrames, InsertFrames, and
|
||||
// RemoveFrame) forward the operation to the parent frame (the
|
||||
// container of the anonymous block).
|
||||
class nsAnonymousBlockFrame : public nsAnonymousBlockFrameSuper {
|
||||
public:
|
||||
friend nsresult NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame);
|
||||
|
||||
// nsIFrame overrides
|
||||
|
||||
// AppendFrames/InsertFrames/RemoveFrame are implemented to forward
|
||||
// the method call to the parent frame.
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
// These methods are used by the parent frame to actually modify the
|
||||
// child frames of the anonymous block frame.
|
||||
nsresult AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
// Take the first frame away from the anonymous block frame. The
|
||||
// caller is responsible for the first frames final disposition
|
||||
// (e.g. deleting it if it wants to).
|
||||
void RemoveFirstFrame();
|
||||
|
||||
// Remove from the blocks list of children the frames starting at
|
||||
// aFrame until the end of the child list. The caller is responsible
|
||||
// for the first frames final disposition (e.g. deleting it if it
|
||||
// wants to).
|
||||
void RemoveFramesFrom(nsIFrame* aFrame);
|
||||
|
||||
protected:
|
||||
nsAnonymousBlockFrame();
|
||||
~nsAnonymousBlockFrame();
|
||||
};
|
||||
|
||||
#endif /* nsBlockFrame_h___ */
|
||||
|
||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
|||
// line and don't stop the line reflow...
|
||||
PRBool splitLine = !reflowingFirstLetter;
|
||||
if (reflowingFirstLetter) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (aLine->IsFirstLine()) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
if (NS_SUCCEEDED(aFrame->GetFrameType(&frameType)) && frameType) {
|
||||
if (frameType == nsLayoutAtoms::inlineFrame) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(frameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splitLine) {
|
||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::WrapFramesInFirstLineFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (!line) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the first and last inline line that has frames that aren't
|
||||
// yet in the first-line-frame.
|
||||
nsLineBox* prevLine = nsnull;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
nsFirstLineFrame* lineFrame = nsnull;
|
||||
nsIFrame* nextSib = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
while (line) {
|
||||
if (line->IsBlock()) {
|
||||
nextSib = line->mFirstChild;
|
||||
break;
|
||||
}
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->mChildCount, "bad first line");
|
||||
lineFrame = (nsFirstLineFrame*) line->mFirstChild;
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
else {
|
||||
if (!firstInlineFrame) {
|
||||
firstInlineFrame = line->mFirstChild;
|
||||
}
|
||||
if (prevLine) {
|
||||
prevLine->mNext = line->mNext;
|
||||
delete line;
|
||||
line = prevLine->mNext;
|
||||
}
|
||||
else {
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!firstInlineFrame) {
|
||||
// All of the inline frames are already where they should be
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make the last inline frame thats going into the first-line-frame
|
||||
// have no next sibling.
|
||||
if (line) {
|
||||
nsFrameList frames(firstInlineFrame);
|
||||
nsIFrame* lastInlineFrame = frames.GetPrevSiblingFor(line->mFirstChild);
|
||||
lastInlineFrame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// If there is no first-line-frame currently, we create it
|
||||
if (!lineFrame) {
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(aPresContext);
|
||||
|
||||
// Create line frame
|
||||
rv = NS_NewFirstLineFrame((nsIFrame**) &lineFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = lineFrame->Init(*aPresContext, mContent, this,
|
||||
firstLineStyle, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
line = mLines;
|
||||
line->mFirstChild = lineFrame;
|
||||
line->mChildCount = 1;
|
||||
line->SetIsFirstLine(PR_TRUE);
|
||||
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
|
||||
// Connect last first-line-frame to the remaining frames
|
||||
lineFrame->SetNextSibling(nextSib);
|
||||
|
||||
// Put the new children into the line-frame
|
||||
lineFrame->AppendFrames2(aPresContext, firstInlineFrame);
|
||||
|
||||
// Mark the first-line frames dirty
|
||||
line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
|||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (lastLine) {
|
||||
lastKid = lastLine->LastChild();
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (lastLine->IsFirstLine()) {
|
||||
// Get last frame in the nsFirstLineFrame
|
||||
lastKid->FirstChild(nsnull, &lastKid);
|
||||
nsFrameList frames(lastKid);
|
||||
lastKid = frames.LastChild();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add frames after the last child
|
||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
nsLineBox* prevSibLine = nsnull;
|
||||
PRInt32 prevSiblingIndex = -1;
|
||||
if (aPrevSibling) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Its possible we have an nsFirstLineFrame managing some of our
|
||||
// child frames. If we do and the AddFrames is targetted at it,
|
||||
// use AddFirstLineFrames to get the frames properly placed.
|
||||
nsIFrame* prevSiblingParent;
|
||||
aPrevSibling->GetParent(&prevSiblingParent);
|
||||
if (prevSiblingParent != this) {
|
||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
||||
// first-line's dirty. Not exactly optimial, but it will
|
||||
// guarantee a correct reflow.
|
||||
nsLineBox* line = mLines;
|
||||
while (line) {
|
||||
if (!line->IsFirstLine()) {
|
||||
break;
|
||||
}
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)prevSiblingParent,
|
||||
aFrameList, aPrevSibling);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
else if (mLines && mLines->IsFirstLine()) {
|
||||
mLines->MarkDirty();
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)mLines->mFirstChild,
|
||||
aFrameList, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the frame following aPrevSibling so that we can join up the
|
||||
// two lists of frames.
|
||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling)
|
||||
{
|
||||
// The first run of inline frames being added always go into the
|
||||
// line frame. If we hit a block frame then we need to chop the line
|
||||
// frame into two pieces.
|
||||
nsIFrame* frame = aFrameList;
|
||||
nsIFrame* lastAddedFrame = frame;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
PRInt32 pendingInlines = 0;
|
||||
while (frame) {
|
||||
if (nsLineLayout::TreatFrameAsBlock(frame)) {
|
||||
// There are 3 cases. The block is going to the front of the
|
||||
// line-frames children, in the middle or at the end.
|
||||
if (aPrevSibling) {
|
||||
nsIFrame* next;
|
||||
aPrevSibling->GetNextSibling(&next);
|
||||
|
||||
// Take kids from the line frame starting at next.
|
||||
nsIFrame* kids;
|
||||
if (nsnull == next) {
|
||||
// The block goes in front of aLineFrame's continuation, if
|
||||
// it has one.
|
||||
nsFirstLineFrame* nextLineFrame;
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &nextLineFrame);
|
||||
if (!nextLineFrame) {
|
||||
// No continuation, therefore the block goes after aLineFrame
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, aLineFrame);
|
||||
}
|
||||
// Use nextLineFrame and take away all its kids
|
||||
aLineFrame = nextLineFrame;
|
||||
}
|
||||
kids = TakeKidsFromLineFrame(aLineFrame, next);
|
||||
|
||||
// We will leave the line-frame and its continuations in
|
||||
// place but mark the lines dirty so that they are reflowed
|
||||
// and the empty line-frames (if any) are cleaned up.
|
||||
nsLineBox* line = mLines;
|
||||
nsIFrame* lastLineFrame = aLineFrame;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
lastLineFrame = line->mFirstChild;
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
// Join the taken kids onto the *end* of the frames being
|
||||
// added.
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, lastLineFrame);
|
||||
}
|
||||
else {
|
||||
// Block is trying to go to the front of the line frame (and
|
||||
// therefore in front of all the line-frames children and its
|
||||
// continuations children). Therefore, we don't need a line
|
||||
// frame anymore.
|
||||
nsIFrame* kids = TakeKidsFromLineFrame(aLineFrame, nsnull);
|
||||
|
||||
// Join the kids onto the end of the frames being added
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, newFrames.FirstChild());
|
||||
|
||||
// Remove the line frame (and its continuations). This also
|
||||
// removes the nsLineBox's that pointed to the line-frame. Do
|
||||
// this after FixParentAndView because FixParentAndView needs
|
||||
// a valid old-parent to work.
|
||||
DoRemoveFrame(aPresContext, aLineFrame);
|
||||
|
||||
// Re-enter AddFrames, this time there won't be any first-line
|
||||
// frames so we will use the normal path.
|
||||
return AddFrames(aPresContext, newFrames.FirstChild(), nsnull);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (0 == pendingInlines) {
|
||||
firstInlineFrame = frame;
|
||||
}
|
||||
pendingInlines++;
|
||||
}
|
||||
lastAddedFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
// All of the frames being added are inline frames
|
||||
if (pendingInlines) {
|
||||
return aLineFrame->InsertFrames2(aPresContext, aPrevSibling, aFrameList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsBlockFrame::TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid)
|
||||
{
|
||||
nsFrameList kids;
|
||||
nsIFrame* lastKid;
|
||||
if (aFromKid) {
|
||||
kids.SetFrames(aFromKid);
|
||||
aLineFrame->RemoveFramesFrom(aFromKid);
|
||||
}
|
||||
else {
|
||||
aLineFrame->FirstChild(nsnull, &lastKid);
|
||||
kids.SetFrames(lastKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
}
|
||||
lastKid = kids.LastChild();
|
||||
|
||||
// Capture the next-in-flows kids as well.
|
||||
for (;;) {
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &aLineFrame);
|
||||
if (!aLineFrame) {
|
||||
break;
|
||||
}
|
||||
aLineFrame->FirstChild(nsnull, &aFromKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
lastKid->SetNextSibling(aFromKid);
|
||||
nsFrameList tmp(aFromKid);
|
||||
lastKid = tmp.LastChild();
|
||||
}
|
||||
|
||||
return kids.FirstChild();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
|
@ -4834,15 +4550,6 @@ nsresult
|
|||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
if (parent != this) {
|
||||
return RemoveFirstLineFrame(aPresContext, (nsFirstLineFrame*)parent,
|
||||
aDeletedFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the line and the previous sibling that contains
|
||||
// deletedFrame; we also find the pointer to the line.
|
||||
nsBlockFrame* flow = this;
|
||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
while (nsnull != aDeletedFrame) {
|
||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||
#ifdef NS_DEBUG
|
||||
#ifndef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
#endif
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
||||
|
@ -4990,60 +4695,12 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line, or we
|
||||
// removed a block that preceeded the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
// Strip deleted frame out of the nsFirstLineFrame
|
||||
aLineFrame->RemoveFrame2(aPresContext, aDeletedFrame);
|
||||
aDeletedFrame->Destroy(*aPresContext);
|
||||
|
||||
// See if the line-frame and its continuations are now empty
|
||||
nsFirstLineFrame* lf = (nsFirstLineFrame*) aLineFrame->GetFirstInFlow();
|
||||
nsFirstLineFrame* lf0 = lf;
|
||||
PRBool empty = PR_TRUE;
|
||||
while (lf) {
|
||||
nsIFrame* kids;
|
||||
lf->FirstChild(nsnull, &kids);
|
||||
if (kids) {
|
||||
empty = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
lf->GetNextInFlow((nsIFrame**) &lf);
|
||||
}
|
||||
if (empty) {
|
||||
return DoRemoveFrame(aPresContext, lf0);
|
||||
}
|
||||
|
||||
// Mark first-line lines dirty
|
||||
nsLineBox* line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||
nsIFrame* aChild)
|
||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
|||
return fls;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext*
|
||||
nsBlockFrame::GetFirstLineStyle(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIStyleContext* fls;
|
||||
aPresContext->ProbePseudoStyleContextFor(mContent,
|
||||
nsHTMLAtoms::firstLinePseudo,
|
||||
mStyleContext, PR_FALSE, &fls);
|
||||
return fls;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
|||
#endif
|
||||
NS_RELEASE(firstLetterStyle);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(&aPresContext);
|
||||
if (nsnull != firstLineStyle) {
|
||||
mState |= NS_BLOCK_HAS_FIRST_LINE_STYLE;
|
||||
#ifdef NOISY_FIRST_LINE
|
||||
ListTag(stdout);
|
||||
printf(": first-line style found\n");
|
||||
#endif
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
while (--n >= 0) {
|
||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
// A frame that doesn't implement nsIHTMLReflow isn't text
|
||||
// therefore it will end an open text run.
|
||||
textRunThingy.EndTextRun();
|
||||
}
|
||||
frame->FindTextRuns(textRunThingy);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
}
|
||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsAnonymousBlockFrame* it = new nsAnonymousBlockFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::~nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->AppendFrames(aPresContext, aPresShell, aListName,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->InsertFrames(aPresContext, aPresShell, aListName,
|
||||
aPrevFrame, aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return mParent->RemoveFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::AppendFrames(*aPresContext, *aPresShell,
|
||||
aListName, aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::InsertFrames(*aPresContext, *aPresShell,
|
||||
aListName, aPrevFrame,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::RemoveFrame(*aPresContext, *aPresShell,
|
||||
aListName, aOldFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFirstFrame()
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
nsIFrame* firstChild = line->mFirstChild;
|
||||
|
||||
#if XXX
|
||||
// If the line has floaters on it, see if the frame being removed
|
||||
// is a placeholder frame. If it is, then remove it from the lines
|
||||
// floater array and from the block frames floater child list.
|
||||
if (line->mFloaters.NotEmpty()) {
|
||||
// XXX UNTESTED!
|
||||
nsPlaceholderFrame* placeholderFrame;
|
||||
nsVoidArray& floaters = *line->mFloaters;
|
||||
PRInt32 i, n = floaters.Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
placeholderFrame = (nsPlaceholderFrame*) floaters[i];
|
||||
if (firstChild == placeholderFrame) {
|
||||
// Remove placeholder from the line's floater array
|
||||
floaters.RemoveElementAt(i);
|
||||
if (0 == floaters.Count()) {
|
||||
delete line->mFloaters;
|
||||
line->mFloaters = nsnull;
|
||||
}
|
||||
|
||||
// Remove the floater from the block frames mFloaters list too
|
||||
mFloaters.RemoveFrame(placeholderFrame->GetOutOfFlowFrame());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 lineChildCount = line->GetChildCount();
|
||||
if (1 == lineChildCount) {
|
||||
// Remove line when last frame goes away
|
||||
mLines = line->mNext;
|
||||
delete line;
|
||||
}
|
||||
else {
|
||||
// Remove frame from line and mark the line dirty
|
||||
line->SetChildCount(lineChildCount - 1);
|
||||
line->MarkDirty();
|
||||
firstChild->GetNextSibling(&line->mFirstChild);
|
||||
}
|
||||
|
||||
// Break linkage to next child after stolen frame
|
||||
firstChild->SetNextSibling(nsnull);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFramesFrom(nsIFrame* aFrame)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
// Chop the child sibling list into two pieces
|
||||
nsFrameList tmp(line->mFirstChild);
|
||||
nsIFrame* prevSibling = tmp.GetPrevSiblingFor(aFrame);
|
||||
if (nsnull != prevSibling) {
|
||||
// Chop the sibling list into two pieces
|
||||
prevSibling->SetNextSibling(nsnull);
|
||||
|
||||
nsLineBox* prevLine = nsnull;
|
||||
while (nsnull != line) {
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 i, n = line->GetChildCount();
|
||||
PRBool done = PR_FALSE;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
// We just found the target frame (and the line its in and
|
||||
// the previous line)
|
||||
if (frame == line->mFirstChild) {
|
||||
// No more children on this line, so let it get removed
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
// The only frames that remain on this line are the
|
||||
// frames preceeding aFrame. Adjust the count to
|
||||
// indicate that fact.
|
||||
line->SetChildCount(i);
|
||||
|
||||
// Remove the lines that follow this line
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all of the remaining lines
|
||||
while (nsnull != line) {
|
||||
nsLineBox* next = line->mNext;
|
||||
delete line;
|
||||
line = next;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
|||
if (line->IsBlock()) {
|
||||
seenBlock = PR_TRUE;
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) {
|
||||
if (seenBlock) {
|
||||
NS_ASSERTION(!line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
count += line->GetChildCount();
|
||||
line = line->mNext;
|
||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
|||
// line and don't stop the line reflow...
|
||||
PRBool splitLine = !reflowingFirstLetter;
|
||||
if (reflowingFirstLetter) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (aLine->IsFirstLine()) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
if (NS_SUCCEEDED(aFrame->GetFrameType(&frameType)) && frameType) {
|
||||
if (frameType == nsLayoutAtoms::inlineFrame) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(frameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splitLine) {
|
||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::WrapFramesInFirstLineFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (!line) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the first and last inline line that has frames that aren't
|
||||
// yet in the first-line-frame.
|
||||
nsLineBox* prevLine = nsnull;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
nsFirstLineFrame* lineFrame = nsnull;
|
||||
nsIFrame* nextSib = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
while (line) {
|
||||
if (line->IsBlock()) {
|
||||
nextSib = line->mFirstChild;
|
||||
break;
|
||||
}
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->mChildCount, "bad first line");
|
||||
lineFrame = (nsFirstLineFrame*) line->mFirstChild;
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
else {
|
||||
if (!firstInlineFrame) {
|
||||
firstInlineFrame = line->mFirstChild;
|
||||
}
|
||||
if (prevLine) {
|
||||
prevLine->mNext = line->mNext;
|
||||
delete line;
|
||||
line = prevLine->mNext;
|
||||
}
|
||||
else {
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!firstInlineFrame) {
|
||||
// All of the inline frames are already where they should be
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make the last inline frame thats going into the first-line-frame
|
||||
// have no next sibling.
|
||||
if (line) {
|
||||
nsFrameList frames(firstInlineFrame);
|
||||
nsIFrame* lastInlineFrame = frames.GetPrevSiblingFor(line->mFirstChild);
|
||||
lastInlineFrame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// If there is no first-line-frame currently, we create it
|
||||
if (!lineFrame) {
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(aPresContext);
|
||||
|
||||
// Create line frame
|
||||
rv = NS_NewFirstLineFrame((nsIFrame**) &lineFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = lineFrame->Init(*aPresContext, mContent, this,
|
||||
firstLineStyle, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
line = mLines;
|
||||
line->mFirstChild = lineFrame;
|
||||
line->mChildCount = 1;
|
||||
line->SetIsFirstLine(PR_TRUE);
|
||||
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
|
||||
// Connect last first-line-frame to the remaining frames
|
||||
lineFrame->SetNextSibling(nextSib);
|
||||
|
||||
// Put the new children into the line-frame
|
||||
lineFrame->AppendFrames2(aPresContext, firstInlineFrame);
|
||||
|
||||
// Mark the first-line frames dirty
|
||||
line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
|||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (lastLine) {
|
||||
lastKid = lastLine->LastChild();
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (lastLine->IsFirstLine()) {
|
||||
// Get last frame in the nsFirstLineFrame
|
||||
lastKid->FirstChild(nsnull, &lastKid);
|
||||
nsFrameList frames(lastKid);
|
||||
lastKid = frames.LastChild();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add frames after the last child
|
||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
nsLineBox* prevSibLine = nsnull;
|
||||
PRInt32 prevSiblingIndex = -1;
|
||||
if (aPrevSibling) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Its possible we have an nsFirstLineFrame managing some of our
|
||||
// child frames. If we do and the AddFrames is targetted at it,
|
||||
// use AddFirstLineFrames to get the frames properly placed.
|
||||
nsIFrame* prevSiblingParent;
|
||||
aPrevSibling->GetParent(&prevSiblingParent);
|
||||
if (prevSiblingParent != this) {
|
||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
||||
// first-line's dirty. Not exactly optimial, but it will
|
||||
// guarantee a correct reflow.
|
||||
nsLineBox* line = mLines;
|
||||
while (line) {
|
||||
if (!line->IsFirstLine()) {
|
||||
break;
|
||||
}
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)prevSiblingParent,
|
||||
aFrameList, aPrevSibling);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
else if (mLines && mLines->IsFirstLine()) {
|
||||
mLines->MarkDirty();
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)mLines->mFirstChild,
|
||||
aFrameList, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the frame following aPrevSibling so that we can join up the
|
||||
// two lists of frames.
|
||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling)
|
||||
{
|
||||
// The first run of inline frames being added always go into the
|
||||
// line frame. If we hit a block frame then we need to chop the line
|
||||
// frame into two pieces.
|
||||
nsIFrame* frame = aFrameList;
|
||||
nsIFrame* lastAddedFrame = frame;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
PRInt32 pendingInlines = 0;
|
||||
while (frame) {
|
||||
if (nsLineLayout::TreatFrameAsBlock(frame)) {
|
||||
// There are 3 cases. The block is going to the front of the
|
||||
// line-frames children, in the middle or at the end.
|
||||
if (aPrevSibling) {
|
||||
nsIFrame* next;
|
||||
aPrevSibling->GetNextSibling(&next);
|
||||
|
||||
// Take kids from the line frame starting at next.
|
||||
nsIFrame* kids;
|
||||
if (nsnull == next) {
|
||||
// The block goes in front of aLineFrame's continuation, if
|
||||
// it has one.
|
||||
nsFirstLineFrame* nextLineFrame;
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &nextLineFrame);
|
||||
if (!nextLineFrame) {
|
||||
// No continuation, therefore the block goes after aLineFrame
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, aLineFrame);
|
||||
}
|
||||
// Use nextLineFrame and take away all its kids
|
||||
aLineFrame = nextLineFrame;
|
||||
}
|
||||
kids = TakeKidsFromLineFrame(aLineFrame, next);
|
||||
|
||||
// We will leave the line-frame and its continuations in
|
||||
// place but mark the lines dirty so that they are reflowed
|
||||
// and the empty line-frames (if any) are cleaned up.
|
||||
nsLineBox* line = mLines;
|
||||
nsIFrame* lastLineFrame = aLineFrame;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
lastLineFrame = line->mFirstChild;
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
// Join the taken kids onto the *end* of the frames being
|
||||
// added.
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, lastLineFrame);
|
||||
}
|
||||
else {
|
||||
// Block is trying to go to the front of the line frame (and
|
||||
// therefore in front of all the line-frames children and its
|
||||
// continuations children). Therefore, we don't need a line
|
||||
// frame anymore.
|
||||
nsIFrame* kids = TakeKidsFromLineFrame(aLineFrame, nsnull);
|
||||
|
||||
// Join the kids onto the end of the frames being added
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, newFrames.FirstChild());
|
||||
|
||||
// Remove the line frame (and its continuations). This also
|
||||
// removes the nsLineBox's that pointed to the line-frame. Do
|
||||
// this after FixParentAndView because FixParentAndView needs
|
||||
// a valid old-parent to work.
|
||||
DoRemoveFrame(aPresContext, aLineFrame);
|
||||
|
||||
// Re-enter AddFrames, this time there won't be any first-line
|
||||
// frames so we will use the normal path.
|
||||
return AddFrames(aPresContext, newFrames.FirstChild(), nsnull);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (0 == pendingInlines) {
|
||||
firstInlineFrame = frame;
|
||||
}
|
||||
pendingInlines++;
|
||||
}
|
||||
lastAddedFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
// All of the frames being added are inline frames
|
||||
if (pendingInlines) {
|
||||
return aLineFrame->InsertFrames2(aPresContext, aPrevSibling, aFrameList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsBlockFrame::TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid)
|
||||
{
|
||||
nsFrameList kids;
|
||||
nsIFrame* lastKid;
|
||||
if (aFromKid) {
|
||||
kids.SetFrames(aFromKid);
|
||||
aLineFrame->RemoveFramesFrom(aFromKid);
|
||||
}
|
||||
else {
|
||||
aLineFrame->FirstChild(nsnull, &lastKid);
|
||||
kids.SetFrames(lastKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
}
|
||||
lastKid = kids.LastChild();
|
||||
|
||||
// Capture the next-in-flows kids as well.
|
||||
for (;;) {
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &aLineFrame);
|
||||
if (!aLineFrame) {
|
||||
break;
|
||||
}
|
||||
aLineFrame->FirstChild(nsnull, &aFromKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
lastKid->SetNextSibling(aFromKid);
|
||||
nsFrameList tmp(aFromKid);
|
||||
lastKid = tmp.LastChild();
|
||||
}
|
||||
|
||||
return kids.FirstChild();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
|
@ -4834,15 +4550,6 @@ nsresult
|
|||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
if (parent != this) {
|
||||
return RemoveFirstLineFrame(aPresContext, (nsFirstLineFrame*)parent,
|
||||
aDeletedFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the line and the previous sibling that contains
|
||||
// deletedFrame; we also find the pointer to the line.
|
||||
nsBlockFrame* flow = this;
|
||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
while (nsnull != aDeletedFrame) {
|
||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||
#ifdef NS_DEBUG
|
||||
#ifndef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
#endif
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
||||
|
@ -4990,60 +4695,12 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line, or we
|
||||
// removed a block that preceeded the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
// Strip deleted frame out of the nsFirstLineFrame
|
||||
aLineFrame->RemoveFrame2(aPresContext, aDeletedFrame);
|
||||
aDeletedFrame->Destroy(*aPresContext);
|
||||
|
||||
// See if the line-frame and its continuations are now empty
|
||||
nsFirstLineFrame* lf = (nsFirstLineFrame*) aLineFrame->GetFirstInFlow();
|
||||
nsFirstLineFrame* lf0 = lf;
|
||||
PRBool empty = PR_TRUE;
|
||||
while (lf) {
|
||||
nsIFrame* kids;
|
||||
lf->FirstChild(nsnull, &kids);
|
||||
if (kids) {
|
||||
empty = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
lf->GetNextInFlow((nsIFrame**) &lf);
|
||||
}
|
||||
if (empty) {
|
||||
return DoRemoveFrame(aPresContext, lf0);
|
||||
}
|
||||
|
||||
// Mark first-line lines dirty
|
||||
nsLineBox* line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||
nsIFrame* aChild)
|
||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
|||
return fls;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext*
|
||||
nsBlockFrame::GetFirstLineStyle(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIStyleContext* fls;
|
||||
aPresContext->ProbePseudoStyleContextFor(mContent,
|
||||
nsHTMLAtoms::firstLinePseudo,
|
||||
mStyleContext, PR_FALSE, &fls);
|
||||
return fls;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
|||
#endif
|
||||
NS_RELEASE(firstLetterStyle);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(&aPresContext);
|
||||
if (nsnull != firstLineStyle) {
|
||||
mState |= NS_BLOCK_HAS_FIRST_LINE_STYLE;
|
||||
#ifdef NOISY_FIRST_LINE
|
||||
ListTag(stdout);
|
||||
printf(": first-line style found\n");
|
||||
#endif
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
while (--n >= 0) {
|
||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
// A frame that doesn't implement nsIHTMLReflow isn't text
|
||||
// therefore it will end an open text run.
|
||||
textRunThingy.EndTextRun();
|
||||
}
|
||||
frame->FindTextRuns(textRunThingy);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
}
|
||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsAnonymousBlockFrame* it = new nsAnonymousBlockFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::~nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->AppendFrames(aPresContext, aPresShell, aListName,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->InsertFrames(aPresContext, aPresShell, aListName,
|
||||
aPrevFrame, aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return mParent->RemoveFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::AppendFrames(*aPresContext, *aPresShell,
|
||||
aListName, aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::InsertFrames(*aPresContext, *aPresShell,
|
||||
aListName, aPrevFrame,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::RemoveFrame(*aPresContext, *aPresShell,
|
||||
aListName, aOldFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFirstFrame()
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
nsIFrame* firstChild = line->mFirstChild;
|
||||
|
||||
#if XXX
|
||||
// If the line has floaters on it, see if the frame being removed
|
||||
// is a placeholder frame. If it is, then remove it from the lines
|
||||
// floater array and from the block frames floater child list.
|
||||
if (line->mFloaters.NotEmpty()) {
|
||||
// XXX UNTESTED!
|
||||
nsPlaceholderFrame* placeholderFrame;
|
||||
nsVoidArray& floaters = *line->mFloaters;
|
||||
PRInt32 i, n = floaters.Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
placeholderFrame = (nsPlaceholderFrame*) floaters[i];
|
||||
if (firstChild == placeholderFrame) {
|
||||
// Remove placeholder from the line's floater array
|
||||
floaters.RemoveElementAt(i);
|
||||
if (0 == floaters.Count()) {
|
||||
delete line->mFloaters;
|
||||
line->mFloaters = nsnull;
|
||||
}
|
||||
|
||||
// Remove the floater from the block frames mFloaters list too
|
||||
mFloaters.RemoveFrame(placeholderFrame->GetOutOfFlowFrame());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 lineChildCount = line->GetChildCount();
|
||||
if (1 == lineChildCount) {
|
||||
// Remove line when last frame goes away
|
||||
mLines = line->mNext;
|
||||
delete line;
|
||||
}
|
||||
else {
|
||||
// Remove frame from line and mark the line dirty
|
||||
line->SetChildCount(lineChildCount - 1);
|
||||
line->MarkDirty();
|
||||
firstChild->GetNextSibling(&line->mFirstChild);
|
||||
}
|
||||
|
||||
// Break linkage to next child after stolen frame
|
||||
firstChild->SetNextSibling(nsnull);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFramesFrom(nsIFrame* aFrame)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
// Chop the child sibling list into two pieces
|
||||
nsFrameList tmp(line->mFirstChild);
|
||||
nsIFrame* prevSibling = tmp.GetPrevSiblingFor(aFrame);
|
||||
if (nsnull != prevSibling) {
|
||||
// Chop the sibling list into two pieces
|
||||
prevSibling->SetNextSibling(nsnull);
|
||||
|
||||
nsLineBox* prevLine = nsnull;
|
||||
while (nsnull != line) {
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 i, n = line->GetChildCount();
|
||||
PRBool done = PR_FALSE;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
// We just found the target frame (and the line its in and
|
||||
// the previous line)
|
||||
if (frame == line->mFirstChild) {
|
||||
// No more children on this line, so let it get removed
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
// The only frames that remain on this line are the
|
||||
// frames preceeding aFrame. Adjust the count to
|
||||
// indicate that fact.
|
||||
line->SetChildCount(i);
|
||||
|
||||
// Remove the lines that follow this line
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all of the remaining lines
|
||||
while (nsnull != line) {
|
||||
nsLineBox* next = line->mNext;
|
||||
delete line;
|
||||
line = next;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
|||
if (line->IsBlock()) {
|
||||
seenBlock = PR_TRUE;
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) {
|
||||
if (seenBlock) {
|
||||
NS_ASSERTION(!line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
count += line->GetChildCount();
|
||||
line = line->mNext;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,6 +30,12 @@ class nsAnonymousBlockFrame;
|
|||
|
||||
#define nsInlineFrameSuper nsHTMLContainerFrame
|
||||
|
||||
/**
|
||||
* Inline frame class.
|
||||
*
|
||||
* This class manages a list of child frames that are inline frames. Working with
|
||||
* nsLineLayout, the class will reflow and place inline frames on a line.
|
||||
*/
|
||||
class nsInlineFrame : public nsInlineFrameSuper
|
||||
{
|
||||
public:
|
||||
|
@ -39,9 +45,6 @@ public:
|
|||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
||||
// nsIFrame overrides
|
||||
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList);
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
|
@ -55,7 +58,11 @@ public:
|
|||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
NS_IMETHOD Destroy(nsIPresContext& aPresContext);
|
||||
NS_IMETHOD ReplaceFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame,
|
||||
nsIFrame* aNewFrame);
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
|
||||
|
@ -65,15 +72,15 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
NS_IMETHOD FindTextRuns(nsLineLayout& aLineLayout);
|
||||
#if XXX_fix_me
|
||||
NS_IMETHOD AdjustFrameSize(nscoord aExtraSpace, nscoord& aUsedSpace);
|
||||
NS_IMETHOD TrimTrailingWhiteSpace(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRC,
|
||||
nscoord& aDeltaWidth);
|
||||
#endif
|
||||
|
||||
static nsIID kInlineFrameCID;
|
||||
|
||||
// Take all of the frames away from this frame. The caller is
|
||||
// presumed to keep them alive.
|
||||
void StealAllFrames() {
|
||||
mFrames.SetFrames(nsnull);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Additional reflow state used during our reflow methods
|
||||
struct InlineReflowState {
|
||||
|
@ -82,75 +89,15 @@ protected:
|
|||
nsInlineFrame* mNextInFlow;
|
||||
};
|
||||
|
||||
// A helper class that knows how to take a list of frames and chop
|
||||
// it up into 3 sections.
|
||||
struct SectionData {
|
||||
SectionData(nsIFrame* aFrameList);
|
||||
|
||||
PRBool SplitFrameList(nsFrameList& aSection1,
|
||||
nsFrameList& aSection2,
|
||||
nsFrameList& aSection3);
|
||||
|
||||
PRBool HasABlock() const {
|
||||
return nsnull != firstBlock;
|
||||
}
|
||||
|
||||
nsIFrame* firstBlock;
|
||||
nsIFrame* prevFirstBlock;
|
||||
nsIFrame* lastBlock;
|
||||
nsIFrame* firstFrame;
|
||||
nsIFrame* lastFrame;
|
||||
};
|
||||
|
||||
nsInlineFrame();
|
||||
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
PRBool HaveAnonymousBlock() const {
|
||||
return mFrames.NotEmpty()
|
||||
? nsLineLayout::TreatFrameAsBlock(mFrames.FirstChild())
|
||||
: PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool ParentIsInlineFrame(nsIFrame* aFrame, nsIFrame** aParent) {
|
||||
void* tmp;
|
||||
nsIFrame* parent;
|
||||
aFrame->GetParent(&parent);
|
||||
*aParent = parent;
|
||||
if (NS_SUCCEEDED(parent->QueryInterface(kInlineFrameCID, &tmp))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame* FindPrevAnonymousBlock(nsInlineFrame** aBlockParent);
|
||||
|
||||
nsAnonymousBlockFrame* FindAnonymousBlock(nsInlineFrame** aBlockParent);
|
||||
|
||||
nsresult CreateAnonymousBlock(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame** aResult);
|
||||
|
||||
nsresult AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aFrameList,
|
||||
PRBool aGenerateReflowCommands);
|
||||
|
||||
nsresult InsertBlockFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult InsertInlineFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult ReflowInlineFrames(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
InlineReflowState& rs,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
nsReflowStatus& aStatus);
|
||||
nsresult ReflowFrames(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
InlineReflowState& rs,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
nsresult ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
@ -158,29 +105,23 @@ protected:
|
|||
nsIFrame* aFrame,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
|
||||
virtual void PushFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFromChild,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
||||
|
||||
nsIFrame* PullAnyFrame(nsIPresContext* aPresContext, InlineReflowState& rs);
|
||||
|
||||
nsresult ReflowBlockFrame(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
InlineReflowState& rs,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
nsReflowStatus& aStatus);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Variation on inline-frame used to manage lines for line layout in
|
||||
// special situations.
|
||||
/**
|
||||
* Variation on inline-frame used to manage lines for line layout in
|
||||
* special situations (:first-line style in particular).
|
||||
*/
|
||||
class nsFirstLineFrame : public nsInlineFrame {
|
||||
public:
|
||||
friend nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
||||
|
@ -192,62 +133,20 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// AppendFrames/InsertFrames/RemoveFrame are implemented to forward
|
||||
// the method call to the parent frame.
|
||||
#endif
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// These methods are used by the parent frame to actually modify the
|
||||
// child frames of the line frame. These methods do not generate
|
||||
// reflow commands.
|
||||
nsresult AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
#endif
|
||||
// Take frames starting at aFrame until the end of the frame-list
|
||||
// away from this frame. The caller is presumed to keep them alive.
|
||||
void StealFramesFrom(nsIFrame* aFrame);
|
||||
|
||||
// Take all of the frames away from this frame. The caller is
|
||||
// presumed to keep them alive.
|
||||
void StealAllFrames() {
|
||||
mFrames.SetFrames(nsnull);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsFirstLineFrame();
|
||||
|
||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
|
||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
||||
};
|
||||
|
||||
extern nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Derived class created for relatively positioned inline-level elements
|
||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
|||
// line and don't stop the line reflow...
|
||||
PRBool splitLine = !reflowingFirstLetter;
|
||||
if (reflowingFirstLetter) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (aLine->IsFirstLine()) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
if (NS_SUCCEEDED(aFrame->GetFrameType(&frameType)) && frameType) {
|
||||
if (frameType == nsLayoutAtoms::inlineFrame) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(frameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splitLine) {
|
||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::WrapFramesInFirstLineFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (!line) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the first and last inline line that has frames that aren't
|
||||
// yet in the first-line-frame.
|
||||
nsLineBox* prevLine = nsnull;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
nsFirstLineFrame* lineFrame = nsnull;
|
||||
nsIFrame* nextSib = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
while (line) {
|
||||
if (line->IsBlock()) {
|
||||
nextSib = line->mFirstChild;
|
||||
break;
|
||||
}
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->mChildCount, "bad first line");
|
||||
lineFrame = (nsFirstLineFrame*) line->mFirstChild;
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
else {
|
||||
if (!firstInlineFrame) {
|
||||
firstInlineFrame = line->mFirstChild;
|
||||
}
|
||||
if (prevLine) {
|
||||
prevLine->mNext = line->mNext;
|
||||
delete line;
|
||||
line = prevLine->mNext;
|
||||
}
|
||||
else {
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!firstInlineFrame) {
|
||||
// All of the inline frames are already where they should be
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make the last inline frame thats going into the first-line-frame
|
||||
// have no next sibling.
|
||||
if (line) {
|
||||
nsFrameList frames(firstInlineFrame);
|
||||
nsIFrame* lastInlineFrame = frames.GetPrevSiblingFor(line->mFirstChild);
|
||||
lastInlineFrame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// If there is no first-line-frame currently, we create it
|
||||
if (!lineFrame) {
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(aPresContext);
|
||||
|
||||
// Create line frame
|
||||
rv = NS_NewFirstLineFrame((nsIFrame**) &lineFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = lineFrame->Init(*aPresContext, mContent, this,
|
||||
firstLineStyle, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
line = mLines;
|
||||
line->mFirstChild = lineFrame;
|
||||
line->mChildCount = 1;
|
||||
line->SetIsFirstLine(PR_TRUE);
|
||||
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
|
||||
// Connect last first-line-frame to the remaining frames
|
||||
lineFrame->SetNextSibling(nextSib);
|
||||
|
||||
// Put the new children into the line-frame
|
||||
lineFrame->AppendFrames2(aPresContext, firstInlineFrame);
|
||||
|
||||
// Mark the first-line frames dirty
|
||||
line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
|||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (lastLine) {
|
||||
lastKid = lastLine->LastChild();
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (lastLine->IsFirstLine()) {
|
||||
// Get last frame in the nsFirstLineFrame
|
||||
lastKid->FirstChild(nsnull, &lastKid);
|
||||
nsFrameList frames(lastKid);
|
||||
lastKid = frames.LastChild();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add frames after the last child
|
||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
nsLineBox* prevSibLine = nsnull;
|
||||
PRInt32 prevSiblingIndex = -1;
|
||||
if (aPrevSibling) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Its possible we have an nsFirstLineFrame managing some of our
|
||||
// child frames. If we do and the AddFrames is targetted at it,
|
||||
// use AddFirstLineFrames to get the frames properly placed.
|
||||
nsIFrame* prevSiblingParent;
|
||||
aPrevSibling->GetParent(&prevSiblingParent);
|
||||
if (prevSiblingParent != this) {
|
||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
||||
// first-line's dirty. Not exactly optimial, but it will
|
||||
// guarantee a correct reflow.
|
||||
nsLineBox* line = mLines;
|
||||
while (line) {
|
||||
if (!line->IsFirstLine()) {
|
||||
break;
|
||||
}
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)prevSiblingParent,
|
||||
aFrameList, aPrevSibling);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
else if (mLines && mLines->IsFirstLine()) {
|
||||
mLines->MarkDirty();
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)mLines->mFirstChild,
|
||||
aFrameList, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the frame following aPrevSibling so that we can join up the
|
||||
// two lists of frames.
|
||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling)
|
||||
{
|
||||
// The first run of inline frames being added always go into the
|
||||
// line frame. If we hit a block frame then we need to chop the line
|
||||
// frame into two pieces.
|
||||
nsIFrame* frame = aFrameList;
|
||||
nsIFrame* lastAddedFrame = frame;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
PRInt32 pendingInlines = 0;
|
||||
while (frame) {
|
||||
if (nsLineLayout::TreatFrameAsBlock(frame)) {
|
||||
// There are 3 cases. The block is going to the front of the
|
||||
// line-frames children, in the middle or at the end.
|
||||
if (aPrevSibling) {
|
||||
nsIFrame* next;
|
||||
aPrevSibling->GetNextSibling(&next);
|
||||
|
||||
// Take kids from the line frame starting at next.
|
||||
nsIFrame* kids;
|
||||
if (nsnull == next) {
|
||||
// The block goes in front of aLineFrame's continuation, if
|
||||
// it has one.
|
||||
nsFirstLineFrame* nextLineFrame;
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &nextLineFrame);
|
||||
if (!nextLineFrame) {
|
||||
// No continuation, therefore the block goes after aLineFrame
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, aLineFrame);
|
||||
}
|
||||
// Use nextLineFrame and take away all its kids
|
||||
aLineFrame = nextLineFrame;
|
||||
}
|
||||
kids = TakeKidsFromLineFrame(aLineFrame, next);
|
||||
|
||||
// We will leave the line-frame and its continuations in
|
||||
// place but mark the lines dirty so that they are reflowed
|
||||
// and the empty line-frames (if any) are cleaned up.
|
||||
nsLineBox* line = mLines;
|
||||
nsIFrame* lastLineFrame = aLineFrame;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
lastLineFrame = line->mFirstChild;
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
// Join the taken kids onto the *end* of the frames being
|
||||
// added.
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, lastLineFrame);
|
||||
}
|
||||
else {
|
||||
// Block is trying to go to the front of the line frame (and
|
||||
// therefore in front of all the line-frames children and its
|
||||
// continuations children). Therefore, we don't need a line
|
||||
// frame anymore.
|
||||
nsIFrame* kids = TakeKidsFromLineFrame(aLineFrame, nsnull);
|
||||
|
||||
// Join the kids onto the end of the frames being added
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, newFrames.FirstChild());
|
||||
|
||||
// Remove the line frame (and its continuations). This also
|
||||
// removes the nsLineBox's that pointed to the line-frame. Do
|
||||
// this after FixParentAndView because FixParentAndView needs
|
||||
// a valid old-parent to work.
|
||||
DoRemoveFrame(aPresContext, aLineFrame);
|
||||
|
||||
// Re-enter AddFrames, this time there won't be any first-line
|
||||
// frames so we will use the normal path.
|
||||
return AddFrames(aPresContext, newFrames.FirstChild(), nsnull);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (0 == pendingInlines) {
|
||||
firstInlineFrame = frame;
|
||||
}
|
||||
pendingInlines++;
|
||||
}
|
||||
lastAddedFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
// All of the frames being added are inline frames
|
||||
if (pendingInlines) {
|
||||
return aLineFrame->InsertFrames2(aPresContext, aPrevSibling, aFrameList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsBlockFrame::TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid)
|
||||
{
|
||||
nsFrameList kids;
|
||||
nsIFrame* lastKid;
|
||||
if (aFromKid) {
|
||||
kids.SetFrames(aFromKid);
|
||||
aLineFrame->RemoveFramesFrom(aFromKid);
|
||||
}
|
||||
else {
|
||||
aLineFrame->FirstChild(nsnull, &lastKid);
|
||||
kids.SetFrames(lastKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
}
|
||||
lastKid = kids.LastChild();
|
||||
|
||||
// Capture the next-in-flows kids as well.
|
||||
for (;;) {
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &aLineFrame);
|
||||
if (!aLineFrame) {
|
||||
break;
|
||||
}
|
||||
aLineFrame->FirstChild(nsnull, &aFromKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
lastKid->SetNextSibling(aFromKid);
|
||||
nsFrameList tmp(aFromKid);
|
||||
lastKid = tmp.LastChild();
|
||||
}
|
||||
|
||||
return kids.FirstChild();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
|
@ -4834,15 +4550,6 @@ nsresult
|
|||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
if (parent != this) {
|
||||
return RemoveFirstLineFrame(aPresContext, (nsFirstLineFrame*)parent,
|
||||
aDeletedFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the line and the previous sibling that contains
|
||||
// deletedFrame; we also find the pointer to the line.
|
||||
nsBlockFrame* flow = this;
|
||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
while (nsnull != aDeletedFrame) {
|
||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||
#ifdef NS_DEBUG
|
||||
#ifndef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
#endif
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
||||
|
@ -4990,60 +4695,12 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line, or we
|
||||
// removed a block that preceeded the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
// Strip deleted frame out of the nsFirstLineFrame
|
||||
aLineFrame->RemoveFrame2(aPresContext, aDeletedFrame);
|
||||
aDeletedFrame->Destroy(*aPresContext);
|
||||
|
||||
// See if the line-frame and its continuations are now empty
|
||||
nsFirstLineFrame* lf = (nsFirstLineFrame*) aLineFrame->GetFirstInFlow();
|
||||
nsFirstLineFrame* lf0 = lf;
|
||||
PRBool empty = PR_TRUE;
|
||||
while (lf) {
|
||||
nsIFrame* kids;
|
||||
lf->FirstChild(nsnull, &kids);
|
||||
if (kids) {
|
||||
empty = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
lf->GetNextInFlow((nsIFrame**) &lf);
|
||||
}
|
||||
if (empty) {
|
||||
return DoRemoveFrame(aPresContext, lf0);
|
||||
}
|
||||
|
||||
// Mark first-line lines dirty
|
||||
nsLineBox* line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||
nsIFrame* aChild)
|
||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
|||
return fls;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext*
|
||||
nsBlockFrame::GetFirstLineStyle(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIStyleContext* fls;
|
||||
aPresContext->ProbePseudoStyleContextFor(mContent,
|
||||
nsHTMLAtoms::firstLinePseudo,
|
||||
mStyleContext, PR_FALSE, &fls);
|
||||
return fls;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
|||
#endif
|
||||
NS_RELEASE(firstLetterStyle);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(&aPresContext);
|
||||
if (nsnull != firstLineStyle) {
|
||||
mState |= NS_BLOCK_HAS_FIRST_LINE_STYLE;
|
||||
#ifdef NOISY_FIRST_LINE
|
||||
ListTag(stdout);
|
||||
printf(": first-line style found\n");
|
||||
#endif
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
while (--n >= 0) {
|
||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
// A frame that doesn't implement nsIHTMLReflow isn't text
|
||||
// therefore it will end an open text run.
|
||||
textRunThingy.EndTextRun();
|
||||
}
|
||||
frame->FindTextRuns(textRunThingy);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
}
|
||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsAnonymousBlockFrame* it = new nsAnonymousBlockFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::~nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->AppendFrames(aPresContext, aPresShell, aListName,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->InsertFrames(aPresContext, aPresShell, aListName,
|
||||
aPrevFrame, aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return mParent->RemoveFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::AppendFrames(*aPresContext, *aPresShell,
|
||||
aListName, aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::InsertFrames(*aPresContext, *aPresShell,
|
||||
aListName, aPrevFrame,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::RemoveFrame(*aPresContext, *aPresShell,
|
||||
aListName, aOldFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFirstFrame()
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
nsIFrame* firstChild = line->mFirstChild;
|
||||
|
||||
#if XXX
|
||||
// If the line has floaters on it, see if the frame being removed
|
||||
// is a placeholder frame. If it is, then remove it from the lines
|
||||
// floater array and from the block frames floater child list.
|
||||
if (line->mFloaters.NotEmpty()) {
|
||||
// XXX UNTESTED!
|
||||
nsPlaceholderFrame* placeholderFrame;
|
||||
nsVoidArray& floaters = *line->mFloaters;
|
||||
PRInt32 i, n = floaters.Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
placeholderFrame = (nsPlaceholderFrame*) floaters[i];
|
||||
if (firstChild == placeholderFrame) {
|
||||
// Remove placeholder from the line's floater array
|
||||
floaters.RemoveElementAt(i);
|
||||
if (0 == floaters.Count()) {
|
||||
delete line->mFloaters;
|
||||
line->mFloaters = nsnull;
|
||||
}
|
||||
|
||||
// Remove the floater from the block frames mFloaters list too
|
||||
mFloaters.RemoveFrame(placeholderFrame->GetOutOfFlowFrame());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 lineChildCount = line->GetChildCount();
|
||||
if (1 == lineChildCount) {
|
||||
// Remove line when last frame goes away
|
||||
mLines = line->mNext;
|
||||
delete line;
|
||||
}
|
||||
else {
|
||||
// Remove frame from line and mark the line dirty
|
||||
line->SetChildCount(lineChildCount - 1);
|
||||
line->MarkDirty();
|
||||
firstChild->GetNextSibling(&line->mFirstChild);
|
||||
}
|
||||
|
||||
// Break linkage to next child after stolen frame
|
||||
firstChild->SetNextSibling(nsnull);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFramesFrom(nsIFrame* aFrame)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
// Chop the child sibling list into two pieces
|
||||
nsFrameList tmp(line->mFirstChild);
|
||||
nsIFrame* prevSibling = tmp.GetPrevSiblingFor(aFrame);
|
||||
if (nsnull != prevSibling) {
|
||||
// Chop the sibling list into two pieces
|
||||
prevSibling->SetNextSibling(nsnull);
|
||||
|
||||
nsLineBox* prevLine = nsnull;
|
||||
while (nsnull != line) {
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 i, n = line->GetChildCount();
|
||||
PRBool done = PR_FALSE;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
// We just found the target frame (and the line its in and
|
||||
// the previous line)
|
||||
if (frame == line->mFirstChild) {
|
||||
// No more children on this line, so let it get removed
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
// The only frames that remain on this line are the
|
||||
// frames preceeding aFrame. Adjust the count to
|
||||
// indicate that fact.
|
||||
line->SetChildCount(i);
|
||||
|
||||
// Remove the lines that follow this line
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all of the remaining lines
|
||||
while (nsnull != line) {
|
||||
nsLineBox* next = line->mNext;
|
||||
delete line;
|
||||
line = next;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
|||
if (line->IsBlock()) {
|
||||
seenBlock = PR_TRUE;
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) {
|
||||
if (seenBlock) {
|
||||
NS_ASSERTION(!line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
count += line->GetChildCount();
|
||||
line = line->mNext;
|
||||
|
|
|
@ -40,9 +40,6 @@ class nsFirstLineFrame;
|
|||
*/
|
||||
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET 0x80000000
|
||||
#define NS_BLOCK_IS_HTML_PARAGRAPH 0x40000000
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
#define NS_BLOCK_HAS_FIRST_LINE_STYLE 0x20000000
|
||||
#endif
|
||||
#define NS_BLOCK_HAS_FIRST_LETTER_STYLE 0x10000000
|
||||
|
||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||
|
@ -146,10 +143,6 @@ protected:
|
|||
|
||||
nsIStyleContext* GetFirstLetterStyle(nsIPresContext* aPresContext);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* GetFirstLineStyle(nsIPresContext* aPresContext);
|
||||
#endif
|
||||
|
||||
void SetFlags(PRUint32 aFlags) {
|
||||
mFlags = aFlags;
|
||||
}
|
||||
|
@ -173,22 +166,6 @@ protected:
|
|||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
nsIFrame* TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid);
|
||||
|
||||
nsresult RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame);
|
||||
|
||||
nsresult WrapFramesInFirstLineFrame(nsIPresContext* aPresContext);
|
||||
#endif
|
||||
|
||||
void FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
|
@ -381,72 +358,5 @@ protected:
|
|||
friend class nsBlockReflowState;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define nsAnonymousBlockFrameSuper nsBlockFrame
|
||||
|
||||
// Anonymous block frame. An anonymous block is used by some other
|
||||
// container (the parent frame) to provide block reflow for a set of
|
||||
// child frames. The parent is responsible for the maintainance of the
|
||||
// anonymous blocks child list. To accomplish this, the normal methods
|
||||
// for managing the child list (AppendFrames, InsertFrames, and
|
||||
// RemoveFrame) forward the operation to the parent frame (the
|
||||
// container of the anonymous block).
|
||||
class nsAnonymousBlockFrame : public nsAnonymousBlockFrameSuper {
|
||||
public:
|
||||
friend nsresult NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame);
|
||||
|
||||
// nsIFrame overrides
|
||||
|
||||
// AppendFrames/InsertFrames/RemoveFrame are implemented to forward
|
||||
// the method call to the parent frame.
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
// These methods are used by the parent frame to actually modify the
|
||||
// child frames of the anonymous block frame.
|
||||
nsresult AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
// Take the first frame away from the anonymous block frame. The
|
||||
// caller is responsible for the first frames final disposition
|
||||
// (e.g. deleting it if it wants to).
|
||||
void RemoveFirstFrame();
|
||||
|
||||
// Remove from the blocks list of children the frames starting at
|
||||
// aFrame until the end of the child list. The caller is responsible
|
||||
// for the first frames final disposition (e.g. deleting it if it
|
||||
// wants to).
|
||||
void RemoveFramesFrom(nsIFrame* aFrame);
|
||||
|
||||
protected:
|
||||
nsAnonymousBlockFrame();
|
||||
~nsAnonymousBlockFrame();
|
||||
};
|
||||
|
||||
#endif /* nsBlockFrame_h___ */
|
||||
|
||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
|||
// line and don't stop the line reflow...
|
||||
PRBool splitLine = !reflowingFirstLetter;
|
||||
if (reflowingFirstLetter) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (aLine->IsFirstLine()) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
if (NS_SUCCEEDED(aFrame->GetFrameType(&frameType)) && frameType) {
|
||||
if (frameType == nsLayoutAtoms::inlineFrame) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(frameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splitLine) {
|
||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::WrapFramesInFirstLineFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (!line) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the first and last inline line that has frames that aren't
|
||||
// yet in the first-line-frame.
|
||||
nsLineBox* prevLine = nsnull;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
nsFirstLineFrame* lineFrame = nsnull;
|
||||
nsIFrame* nextSib = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
while (line) {
|
||||
if (line->IsBlock()) {
|
||||
nextSib = line->mFirstChild;
|
||||
break;
|
||||
}
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->mChildCount, "bad first line");
|
||||
lineFrame = (nsFirstLineFrame*) line->mFirstChild;
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
else {
|
||||
if (!firstInlineFrame) {
|
||||
firstInlineFrame = line->mFirstChild;
|
||||
}
|
||||
if (prevLine) {
|
||||
prevLine->mNext = line->mNext;
|
||||
delete line;
|
||||
line = prevLine->mNext;
|
||||
}
|
||||
else {
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!firstInlineFrame) {
|
||||
// All of the inline frames are already where they should be
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make the last inline frame thats going into the first-line-frame
|
||||
// have no next sibling.
|
||||
if (line) {
|
||||
nsFrameList frames(firstInlineFrame);
|
||||
nsIFrame* lastInlineFrame = frames.GetPrevSiblingFor(line->mFirstChild);
|
||||
lastInlineFrame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// If there is no first-line-frame currently, we create it
|
||||
if (!lineFrame) {
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(aPresContext);
|
||||
|
||||
// Create line frame
|
||||
rv = NS_NewFirstLineFrame((nsIFrame**) &lineFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = lineFrame->Init(*aPresContext, mContent, this,
|
||||
firstLineStyle, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
line = mLines;
|
||||
line->mFirstChild = lineFrame;
|
||||
line->mChildCount = 1;
|
||||
line->SetIsFirstLine(PR_TRUE);
|
||||
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
|
||||
// Connect last first-line-frame to the remaining frames
|
||||
lineFrame->SetNextSibling(nextSib);
|
||||
|
||||
// Put the new children into the line-frame
|
||||
lineFrame->AppendFrames2(aPresContext, firstInlineFrame);
|
||||
|
||||
// Mark the first-line frames dirty
|
||||
line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
|||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (lastLine) {
|
||||
lastKid = lastLine->LastChild();
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (lastLine->IsFirstLine()) {
|
||||
// Get last frame in the nsFirstLineFrame
|
||||
lastKid->FirstChild(nsnull, &lastKid);
|
||||
nsFrameList frames(lastKid);
|
||||
lastKid = frames.LastChild();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add frames after the last child
|
||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
nsLineBox* prevSibLine = nsnull;
|
||||
PRInt32 prevSiblingIndex = -1;
|
||||
if (aPrevSibling) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Its possible we have an nsFirstLineFrame managing some of our
|
||||
// child frames. If we do and the AddFrames is targetted at it,
|
||||
// use AddFirstLineFrames to get the frames properly placed.
|
||||
nsIFrame* prevSiblingParent;
|
||||
aPrevSibling->GetParent(&prevSiblingParent);
|
||||
if (prevSiblingParent != this) {
|
||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
||||
// first-line's dirty. Not exactly optimial, but it will
|
||||
// guarantee a correct reflow.
|
||||
nsLineBox* line = mLines;
|
||||
while (line) {
|
||||
if (!line->IsFirstLine()) {
|
||||
break;
|
||||
}
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)prevSiblingParent,
|
||||
aFrameList, aPrevSibling);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
else if (mLines && mLines->IsFirstLine()) {
|
||||
mLines->MarkDirty();
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)mLines->mFirstChild,
|
||||
aFrameList, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the frame following aPrevSibling so that we can join up the
|
||||
// two lists of frames.
|
||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling)
|
||||
{
|
||||
// The first run of inline frames being added always go into the
|
||||
// line frame. If we hit a block frame then we need to chop the line
|
||||
// frame into two pieces.
|
||||
nsIFrame* frame = aFrameList;
|
||||
nsIFrame* lastAddedFrame = frame;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
PRInt32 pendingInlines = 0;
|
||||
while (frame) {
|
||||
if (nsLineLayout::TreatFrameAsBlock(frame)) {
|
||||
// There are 3 cases. The block is going to the front of the
|
||||
// line-frames children, in the middle or at the end.
|
||||
if (aPrevSibling) {
|
||||
nsIFrame* next;
|
||||
aPrevSibling->GetNextSibling(&next);
|
||||
|
||||
// Take kids from the line frame starting at next.
|
||||
nsIFrame* kids;
|
||||
if (nsnull == next) {
|
||||
// The block goes in front of aLineFrame's continuation, if
|
||||
// it has one.
|
||||
nsFirstLineFrame* nextLineFrame;
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &nextLineFrame);
|
||||
if (!nextLineFrame) {
|
||||
// No continuation, therefore the block goes after aLineFrame
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, aLineFrame);
|
||||
}
|
||||
// Use nextLineFrame and take away all its kids
|
||||
aLineFrame = nextLineFrame;
|
||||
}
|
||||
kids = TakeKidsFromLineFrame(aLineFrame, next);
|
||||
|
||||
// We will leave the line-frame and its continuations in
|
||||
// place but mark the lines dirty so that they are reflowed
|
||||
// and the empty line-frames (if any) are cleaned up.
|
||||
nsLineBox* line = mLines;
|
||||
nsIFrame* lastLineFrame = aLineFrame;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
lastLineFrame = line->mFirstChild;
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
// Join the taken kids onto the *end* of the frames being
|
||||
// added.
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, lastLineFrame);
|
||||
}
|
||||
else {
|
||||
// Block is trying to go to the front of the line frame (and
|
||||
// therefore in front of all the line-frames children and its
|
||||
// continuations children). Therefore, we don't need a line
|
||||
// frame anymore.
|
||||
nsIFrame* kids = TakeKidsFromLineFrame(aLineFrame, nsnull);
|
||||
|
||||
// Join the kids onto the end of the frames being added
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, newFrames.FirstChild());
|
||||
|
||||
// Remove the line frame (and its continuations). This also
|
||||
// removes the nsLineBox's that pointed to the line-frame. Do
|
||||
// this after FixParentAndView because FixParentAndView needs
|
||||
// a valid old-parent to work.
|
||||
DoRemoveFrame(aPresContext, aLineFrame);
|
||||
|
||||
// Re-enter AddFrames, this time there won't be any first-line
|
||||
// frames so we will use the normal path.
|
||||
return AddFrames(aPresContext, newFrames.FirstChild(), nsnull);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (0 == pendingInlines) {
|
||||
firstInlineFrame = frame;
|
||||
}
|
||||
pendingInlines++;
|
||||
}
|
||||
lastAddedFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
// All of the frames being added are inline frames
|
||||
if (pendingInlines) {
|
||||
return aLineFrame->InsertFrames2(aPresContext, aPrevSibling, aFrameList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsBlockFrame::TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid)
|
||||
{
|
||||
nsFrameList kids;
|
||||
nsIFrame* lastKid;
|
||||
if (aFromKid) {
|
||||
kids.SetFrames(aFromKid);
|
||||
aLineFrame->RemoveFramesFrom(aFromKid);
|
||||
}
|
||||
else {
|
||||
aLineFrame->FirstChild(nsnull, &lastKid);
|
||||
kids.SetFrames(lastKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
}
|
||||
lastKid = kids.LastChild();
|
||||
|
||||
// Capture the next-in-flows kids as well.
|
||||
for (;;) {
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &aLineFrame);
|
||||
if (!aLineFrame) {
|
||||
break;
|
||||
}
|
||||
aLineFrame->FirstChild(nsnull, &aFromKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
lastKid->SetNextSibling(aFromKid);
|
||||
nsFrameList tmp(aFromKid);
|
||||
lastKid = tmp.LastChild();
|
||||
}
|
||||
|
||||
return kids.FirstChild();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
|
@ -4834,15 +4550,6 @@ nsresult
|
|||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
if (parent != this) {
|
||||
return RemoveFirstLineFrame(aPresContext, (nsFirstLineFrame*)parent,
|
||||
aDeletedFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the line and the previous sibling that contains
|
||||
// deletedFrame; we also find the pointer to the line.
|
||||
nsBlockFrame* flow = this;
|
||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
while (nsnull != aDeletedFrame) {
|
||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||
#ifdef NS_DEBUG
|
||||
#ifndef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
#endif
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
||||
|
@ -4990,60 +4695,12 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line, or we
|
||||
// removed a block that preceeded the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
// Strip deleted frame out of the nsFirstLineFrame
|
||||
aLineFrame->RemoveFrame2(aPresContext, aDeletedFrame);
|
||||
aDeletedFrame->Destroy(*aPresContext);
|
||||
|
||||
// See if the line-frame and its continuations are now empty
|
||||
nsFirstLineFrame* lf = (nsFirstLineFrame*) aLineFrame->GetFirstInFlow();
|
||||
nsFirstLineFrame* lf0 = lf;
|
||||
PRBool empty = PR_TRUE;
|
||||
while (lf) {
|
||||
nsIFrame* kids;
|
||||
lf->FirstChild(nsnull, &kids);
|
||||
if (kids) {
|
||||
empty = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
lf->GetNextInFlow((nsIFrame**) &lf);
|
||||
}
|
||||
if (empty) {
|
||||
return DoRemoveFrame(aPresContext, lf0);
|
||||
}
|
||||
|
||||
// Mark first-line lines dirty
|
||||
nsLineBox* line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||
nsIFrame* aChild)
|
||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
|||
return fls;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext*
|
||||
nsBlockFrame::GetFirstLineStyle(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIStyleContext* fls;
|
||||
aPresContext->ProbePseudoStyleContextFor(mContent,
|
||||
nsHTMLAtoms::firstLinePseudo,
|
||||
mStyleContext, PR_FALSE, &fls);
|
||||
return fls;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
|||
#endif
|
||||
NS_RELEASE(firstLetterStyle);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(&aPresContext);
|
||||
if (nsnull != firstLineStyle) {
|
||||
mState |= NS_BLOCK_HAS_FIRST_LINE_STYLE;
|
||||
#ifdef NOISY_FIRST_LINE
|
||||
ListTag(stdout);
|
||||
printf(": first-line style found\n");
|
||||
#endif
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
while (--n >= 0) {
|
||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
// A frame that doesn't implement nsIHTMLReflow isn't text
|
||||
// therefore it will end an open text run.
|
||||
textRunThingy.EndTextRun();
|
||||
}
|
||||
frame->FindTextRuns(textRunThingy);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
}
|
||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsAnonymousBlockFrame* it = new nsAnonymousBlockFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::~nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->AppendFrames(aPresContext, aPresShell, aListName,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->InsertFrames(aPresContext, aPresShell, aListName,
|
||||
aPrevFrame, aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return mParent->RemoveFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::AppendFrames(*aPresContext, *aPresShell,
|
||||
aListName, aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::InsertFrames(*aPresContext, *aPresShell,
|
||||
aListName, aPrevFrame,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::RemoveFrame(*aPresContext, *aPresShell,
|
||||
aListName, aOldFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFirstFrame()
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
nsIFrame* firstChild = line->mFirstChild;
|
||||
|
||||
#if XXX
|
||||
// If the line has floaters on it, see if the frame being removed
|
||||
// is a placeholder frame. If it is, then remove it from the lines
|
||||
// floater array and from the block frames floater child list.
|
||||
if (line->mFloaters.NotEmpty()) {
|
||||
// XXX UNTESTED!
|
||||
nsPlaceholderFrame* placeholderFrame;
|
||||
nsVoidArray& floaters = *line->mFloaters;
|
||||
PRInt32 i, n = floaters.Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
placeholderFrame = (nsPlaceholderFrame*) floaters[i];
|
||||
if (firstChild == placeholderFrame) {
|
||||
// Remove placeholder from the line's floater array
|
||||
floaters.RemoveElementAt(i);
|
||||
if (0 == floaters.Count()) {
|
||||
delete line->mFloaters;
|
||||
line->mFloaters = nsnull;
|
||||
}
|
||||
|
||||
// Remove the floater from the block frames mFloaters list too
|
||||
mFloaters.RemoveFrame(placeholderFrame->GetOutOfFlowFrame());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 lineChildCount = line->GetChildCount();
|
||||
if (1 == lineChildCount) {
|
||||
// Remove line when last frame goes away
|
||||
mLines = line->mNext;
|
||||
delete line;
|
||||
}
|
||||
else {
|
||||
// Remove frame from line and mark the line dirty
|
||||
line->SetChildCount(lineChildCount - 1);
|
||||
line->MarkDirty();
|
||||
firstChild->GetNextSibling(&line->mFirstChild);
|
||||
}
|
||||
|
||||
// Break linkage to next child after stolen frame
|
||||
firstChild->SetNextSibling(nsnull);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFramesFrom(nsIFrame* aFrame)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
// Chop the child sibling list into two pieces
|
||||
nsFrameList tmp(line->mFirstChild);
|
||||
nsIFrame* prevSibling = tmp.GetPrevSiblingFor(aFrame);
|
||||
if (nsnull != prevSibling) {
|
||||
// Chop the sibling list into two pieces
|
||||
prevSibling->SetNextSibling(nsnull);
|
||||
|
||||
nsLineBox* prevLine = nsnull;
|
||||
while (nsnull != line) {
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 i, n = line->GetChildCount();
|
||||
PRBool done = PR_FALSE;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
// We just found the target frame (and the line its in and
|
||||
// the previous line)
|
||||
if (frame == line->mFirstChild) {
|
||||
// No more children on this line, so let it get removed
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
// The only frames that remain on this line are the
|
||||
// frames preceeding aFrame. Adjust the count to
|
||||
// indicate that fact.
|
||||
line->SetChildCount(i);
|
||||
|
||||
// Remove the lines that follow this line
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all of the remaining lines
|
||||
while (nsnull != line) {
|
||||
nsLineBox* next = line->mNext;
|
||||
delete line;
|
||||
line = next;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
|||
if (line->IsBlock()) {
|
||||
seenBlock = PR_TRUE;
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) {
|
||||
if (seenBlock) {
|
||||
NS_ASSERTION(!line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
count += line->GetChildCount();
|
||||
line = line->mNext;
|
||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
|||
// line and don't stop the line reflow...
|
||||
PRBool splitLine = !reflowingFirstLetter;
|
||||
if (reflowingFirstLetter) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (aLine->IsFirstLine()) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nsIAtom* frameType;
|
||||
if (NS_SUCCEEDED(aFrame->GetFrameType(&frameType)) && frameType) {
|
||||
if (frameType == nsLayoutAtoms::inlineFrame) {
|
||||
splitLine = PR_TRUE;
|
||||
}
|
||||
NS_RELEASE(frameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splitLine) {
|
||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::WrapFramesInFirstLineFrame(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (!line) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the first and last inline line that has frames that aren't
|
||||
// yet in the first-line-frame.
|
||||
nsLineBox* prevLine = nsnull;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
nsFirstLineFrame* lineFrame = nsnull;
|
||||
nsIFrame* nextSib = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
while (line) {
|
||||
if (line->IsBlock()) {
|
||||
nextSib = line->mFirstChild;
|
||||
break;
|
||||
}
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->mChildCount, "bad first line");
|
||||
lineFrame = (nsFirstLineFrame*) line->mFirstChild;
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
else {
|
||||
if (!firstInlineFrame) {
|
||||
firstInlineFrame = line->mFirstChild;
|
||||
}
|
||||
if (prevLine) {
|
||||
prevLine->mNext = line->mNext;
|
||||
delete line;
|
||||
line = prevLine->mNext;
|
||||
}
|
||||
else {
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!firstInlineFrame) {
|
||||
// All of the inline frames are already where they should be
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make the last inline frame thats going into the first-line-frame
|
||||
// have no next sibling.
|
||||
if (line) {
|
||||
nsFrameList frames(firstInlineFrame);
|
||||
nsIFrame* lastInlineFrame = frames.GetPrevSiblingFor(line->mFirstChild);
|
||||
lastInlineFrame->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
// If there is no first-line-frame currently, we create it
|
||||
if (!lineFrame) {
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(aPresContext);
|
||||
|
||||
// Create line frame
|
||||
rv = NS_NewFirstLineFrame((nsIFrame**) &lineFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = lineFrame->Init(*aPresContext, mContent, this,
|
||||
firstLineStyle, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
line = mLines;
|
||||
line->mFirstChild = lineFrame;
|
||||
line->mChildCount = 1;
|
||||
line->SetIsFirstLine(PR_TRUE);
|
||||
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
|
||||
// Connect last first-line-frame to the remaining frames
|
||||
lineFrame->SetNextSibling(nextSib);
|
||||
|
||||
// Put the new children into the line-frame
|
||||
lineFrame->AppendFrames2(aPresContext, firstInlineFrame);
|
||||
|
||||
// Mark the first-line frames dirty
|
||||
line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
|||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (lastLine) {
|
||||
lastKid = lastLine->LastChild();
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (lastLine->IsFirstLine()) {
|
||||
// Get last frame in the nsFirstLineFrame
|
||||
lastKid->FirstChild(nsnull, &lastKid);
|
||||
nsFrameList frames(lastKid);
|
||||
lastKid = frames.LastChild();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Add frames after the last child
|
||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
nsLineBox* prevSibLine = nsnull;
|
||||
PRInt32 prevSiblingIndex = -1;
|
||||
if (aPrevSibling) {
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Its possible we have an nsFirstLineFrame managing some of our
|
||||
// child frames. If we do and the AddFrames is targetted at it,
|
||||
// use AddFirstLineFrames to get the frames properly placed.
|
||||
nsIFrame* prevSiblingParent;
|
||||
aPrevSibling->GetParent(&prevSiblingParent);
|
||||
if (prevSiblingParent != this) {
|
||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
||||
// first-line's dirty. Not exactly optimial, but it will
|
||||
// guarantee a correct reflow.
|
||||
nsLineBox* line = mLines;
|
||||
while (line) {
|
||||
if (!line->IsFirstLine()) {
|
||||
break;
|
||||
}
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)prevSiblingParent,
|
||||
aFrameList, aPrevSibling);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
// Find the line that contains the previous sibling
|
||||
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||
&prevSiblingIndex);
|
||||
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||
if (nsnull == prevSibLine) {
|
||||
// Note: defensive code! FindLineContaining must not return
|
||||
// null in this case, so if it does...
|
||||
aPrevSibling = nsnull;
|
||||
}
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
else if (mLines && mLines->IsFirstLine()) {
|
||||
mLines->MarkDirty();
|
||||
return AddFirstLineFrames(aPresContext,
|
||||
(nsFirstLineFrame*)mLines->mFirstChild,
|
||||
aFrameList, nsnull);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the frame following aPrevSibling so that we can join up the
|
||||
// two lists of frames.
|
||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
|||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::AddFirstLineFrames(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling)
|
||||
{
|
||||
// The first run of inline frames being added always go into the
|
||||
// line frame. If we hit a block frame then we need to chop the line
|
||||
// frame into two pieces.
|
||||
nsIFrame* frame = aFrameList;
|
||||
nsIFrame* lastAddedFrame = frame;
|
||||
nsIFrame* firstInlineFrame = nsnull;
|
||||
PRInt32 pendingInlines = 0;
|
||||
while (frame) {
|
||||
if (nsLineLayout::TreatFrameAsBlock(frame)) {
|
||||
// There are 3 cases. The block is going to the front of the
|
||||
// line-frames children, in the middle or at the end.
|
||||
if (aPrevSibling) {
|
||||
nsIFrame* next;
|
||||
aPrevSibling->GetNextSibling(&next);
|
||||
|
||||
// Take kids from the line frame starting at next.
|
||||
nsIFrame* kids;
|
||||
if (nsnull == next) {
|
||||
// The block goes in front of aLineFrame's continuation, if
|
||||
// it has one.
|
||||
nsFirstLineFrame* nextLineFrame;
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &nextLineFrame);
|
||||
if (!nextLineFrame) {
|
||||
// No continuation, therefore the block goes after aLineFrame
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, aLineFrame);
|
||||
}
|
||||
// Use nextLineFrame and take away all its kids
|
||||
aLineFrame = nextLineFrame;
|
||||
}
|
||||
kids = TakeKidsFromLineFrame(aLineFrame, next);
|
||||
|
||||
// We will leave the line-frame and its continuations in
|
||||
// place but mark the lines dirty so that they are reflowed
|
||||
// and the empty line-frames (if any) are cleaned up.
|
||||
nsLineBox* line = mLines;
|
||||
nsIFrame* lastLineFrame = aLineFrame;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
lastLineFrame = line->mFirstChild;
|
||||
line = line->mNext;
|
||||
}
|
||||
|
||||
// Join the taken kids onto the *end* of the frames being
|
||||
// added.
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, frame);
|
||||
return AddFrames(aPresContext, frame, lastLineFrame);
|
||||
}
|
||||
else {
|
||||
// Block is trying to go to the front of the line frame (and
|
||||
// therefore in front of all the line-frames children and its
|
||||
// continuations children). Therefore, we don't need a line
|
||||
// frame anymore.
|
||||
nsIFrame* kids = TakeKidsFromLineFrame(aLineFrame, nsnull);
|
||||
|
||||
// Join the kids onto the end of the frames being added
|
||||
nsFrameList newFrames(frame);
|
||||
newFrames.AppendFrames(this, kids);
|
||||
FixParentAndView(aPresContext, newFrames.FirstChild());
|
||||
|
||||
// Remove the line frame (and its continuations). This also
|
||||
// removes the nsLineBox's that pointed to the line-frame. Do
|
||||
// this after FixParentAndView because FixParentAndView needs
|
||||
// a valid old-parent to work.
|
||||
DoRemoveFrame(aPresContext, aLineFrame);
|
||||
|
||||
// Re-enter AddFrames, this time there won't be any first-line
|
||||
// frames so we will use the normal path.
|
||||
return AddFrames(aPresContext, newFrames.FirstChild(), nsnull);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (0 == pendingInlines) {
|
||||
firstInlineFrame = frame;
|
||||
}
|
||||
pendingInlines++;
|
||||
}
|
||||
lastAddedFrame = frame;
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
|
||||
// All of the frames being added are inline frames
|
||||
if (pendingInlines) {
|
||||
return aLineFrame->InsertFrames2(aPresContext, aPrevSibling, aFrameList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsBlockFrame::TakeKidsFromLineFrame(nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aFromKid)
|
||||
{
|
||||
nsFrameList kids;
|
||||
nsIFrame* lastKid;
|
||||
if (aFromKid) {
|
||||
kids.SetFrames(aFromKid);
|
||||
aLineFrame->RemoveFramesFrom(aFromKid);
|
||||
}
|
||||
else {
|
||||
aLineFrame->FirstChild(nsnull, &lastKid);
|
||||
kids.SetFrames(lastKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
}
|
||||
lastKid = kids.LastChild();
|
||||
|
||||
// Capture the next-in-flows kids as well.
|
||||
for (;;) {
|
||||
aLineFrame->GetNextInFlow((nsIFrame**) &aLineFrame);
|
||||
if (!aLineFrame) {
|
||||
break;
|
||||
}
|
||||
aLineFrame->FirstChild(nsnull, &aFromKid);
|
||||
aLineFrame->RemoveAllFrames();
|
||||
lastKid->SetNextSibling(aFromKid);
|
||||
nsFrameList tmp(aFromKid);
|
||||
lastKid = tmp.LastChild();
|
||||
}
|
||||
|
||||
return kids.FirstChild();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||
|
@ -4834,15 +4550,6 @@ nsresult
|
|||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
if (parent != this) {
|
||||
return RemoveFirstLineFrame(aPresContext, (nsFirstLineFrame*)parent,
|
||||
aDeletedFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Find the line and the previous sibling that contains
|
||||
// deletedFrame; we also find the pointer to the line.
|
||||
nsBlockFrame* flow = this;
|
||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
while (nsnull != aDeletedFrame) {
|
||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||
#ifdef NS_DEBUG
|
||||
#ifndef BLOCK_DOES_FIRST_LINE
|
||||
nsIFrame* parent;
|
||||
#endif
|
||||
aDeletedFrame->GetParent(&parent);
|
||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
||||
|
@ -4990,60 +4695,12 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// Fixup any frames that should be in a first-line frame but aren't
|
||||
if ((NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) &&
|
||||
(nsnull != mLines) && !mLines->IsBlock()) {
|
||||
// We just added one or more frame(s) to the first line, or we
|
||||
// removed a block that preceeded the first line.
|
||||
WrapFramesInFirstLineFrame(aPresContext);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsresult
|
||||
nsBlockFrame::RemoveFirstLineFrame(nsIPresContext* aPresContext,
|
||||
nsFirstLineFrame* aLineFrame,
|
||||
nsIFrame* aDeletedFrame)
|
||||
{
|
||||
// Strip deleted frame out of the nsFirstLineFrame
|
||||
aLineFrame->RemoveFrame2(aPresContext, aDeletedFrame);
|
||||
aDeletedFrame->Destroy(*aPresContext);
|
||||
|
||||
// See if the line-frame and its continuations are now empty
|
||||
nsFirstLineFrame* lf = (nsFirstLineFrame*) aLineFrame->GetFirstInFlow();
|
||||
nsFirstLineFrame* lf0 = lf;
|
||||
PRBool empty = PR_TRUE;
|
||||
while (lf) {
|
||||
nsIFrame* kids;
|
||||
lf->FirstChild(nsnull, &kids);
|
||||
if (kids) {
|
||||
empty = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
lf->GetNextInFlow((nsIFrame**) &lf);
|
||||
}
|
||||
if (empty) {
|
||||
return DoRemoveFrame(aPresContext, lf0);
|
||||
}
|
||||
|
||||
// Mark first-line lines dirty
|
||||
nsLineBox* line = mLines;
|
||||
while (line && line->IsFirstLine()) {
|
||||
line->MarkDirty();
|
||||
line = line->mNext;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||
nsIFrame* aChild)
|
||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
|||
return fls;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext*
|
||||
nsBlockFrame::GetFirstLineStyle(nsIPresContext* aPresContext)
|
||||
{
|
||||
nsIStyleContext* fls;
|
||||
aPresContext->ProbePseudoStyleContextFor(mContent,
|
||||
nsHTMLAtoms::firstLinePseudo,
|
||||
mStyleContext, PR_FALSE, &fls);
|
||||
return fls;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
|||
#endif
|
||||
NS_RELEASE(firstLetterStyle);
|
||||
}
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
nsIStyleContext* firstLineStyle = GetFirstLineStyle(&aPresContext);
|
||||
if (nsnull != firstLineStyle) {
|
||||
mState |= NS_BLOCK_HAS_FIRST_LINE_STYLE;
|
||||
#ifdef NOISY_FIRST_LINE
|
||||
ListTag(stdout);
|
||||
printf(": first-line style found\n");
|
||||
#endif
|
||||
NS_RELEASE(firstLineStyle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 n = line->GetChildCount();
|
||||
while (--n >= 0) {
|
||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
// A frame that doesn't implement nsIHTMLReflow isn't text
|
||||
// therefore it will end an open text run.
|
||||
textRunThingy.EndTextRun();
|
||||
}
|
||||
frame->FindTextRuns(textRunThingy);
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
}
|
||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
NS_NewAnonymousBlockFrame(nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsAnonymousBlockFrame* it = new nsAnonymousBlockFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame::~nsAnonymousBlockFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->AppendFrames(aPresContext, aPresShell, aListName,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return mParent->InsertFrames(aPresContext, aPresShell, aListName,
|
||||
aPrevFrame, aFrameList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAnonymousBlockFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return mParent->RemoveFrame(aPresContext, aPresShell, aListName,
|
||||
aOldFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::AppendFrames(*aPresContext, *aPresShell,
|
||||
aListName, aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::InsertFrames(*aPresContext, *aPresShell,
|
||||
aListName, aPrevFrame,
|
||||
aFrameList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAnonymousBlockFrame::RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
return nsAnonymousBlockFrameSuper::RemoveFrame(*aPresContext, *aPresShell,
|
||||
aListName, aOldFrame);
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFirstFrame()
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
nsIFrame* firstChild = line->mFirstChild;
|
||||
|
||||
#if XXX
|
||||
// If the line has floaters on it, see if the frame being removed
|
||||
// is a placeholder frame. If it is, then remove it from the lines
|
||||
// floater array and from the block frames floater child list.
|
||||
if (line->mFloaters.NotEmpty()) {
|
||||
// XXX UNTESTED!
|
||||
nsPlaceholderFrame* placeholderFrame;
|
||||
nsVoidArray& floaters = *line->mFloaters;
|
||||
PRInt32 i, n = floaters.Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
placeholderFrame = (nsPlaceholderFrame*) floaters[i];
|
||||
if (firstChild == placeholderFrame) {
|
||||
// Remove placeholder from the line's floater array
|
||||
floaters.RemoveElementAt(i);
|
||||
if (0 == floaters.Count()) {
|
||||
delete line->mFloaters;
|
||||
line->mFloaters = nsnull;
|
||||
}
|
||||
|
||||
// Remove the floater from the block frames mFloaters list too
|
||||
mFloaters.RemoveFrame(placeholderFrame->GetOutOfFlowFrame());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRInt32 lineChildCount = line->GetChildCount();
|
||||
if (1 == lineChildCount) {
|
||||
// Remove line when last frame goes away
|
||||
mLines = line->mNext;
|
||||
delete line;
|
||||
}
|
||||
else {
|
||||
// Remove frame from line and mark the line dirty
|
||||
line->SetChildCount(lineChildCount - 1);
|
||||
line->MarkDirty();
|
||||
firstChild->GetNextSibling(&line->mFirstChild);
|
||||
}
|
||||
|
||||
// Break linkage to next child after stolen frame
|
||||
firstChild->SetNextSibling(nsnull);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsAnonymousBlockFrame::RemoveFramesFrom(nsIFrame* aFrame)
|
||||
{
|
||||
nsLineBox* line = mLines;
|
||||
if (nsnull != line) {
|
||||
// Chop the child sibling list into two pieces
|
||||
nsFrameList tmp(line->mFirstChild);
|
||||
nsIFrame* prevSibling = tmp.GetPrevSiblingFor(aFrame);
|
||||
if (nsnull != prevSibling) {
|
||||
// Chop the sibling list into two pieces
|
||||
prevSibling->SetNextSibling(nsnull);
|
||||
|
||||
nsLineBox* prevLine = nsnull;
|
||||
while (nsnull != line) {
|
||||
nsIFrame* frame = line->mFirstChild;
|
||||
PRInt32 i, n = line->GetChildCount();
|
||||
PRBool done = PR_FALSE;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (frame == aFrame) {
|
||||
// We just found the target frame (and the line its in and
|
||||
// the previous line)
|
||||
if (frame == line->mFirstChild) {
|
||||
// No more children on this line, so let it get removed
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
// The only frames that remain on this line are the
|
||||
// frames preceeding aFrame. Adjust the count to
|
||||
// indicate that fact.
|
||||
line->SetChildCount(i);
|
||||
|
||||
// Remove the lines that follow this line
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
prevLine->mNext = nsnull;
|
||||
}
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
frame->GetNextSibling(&frame);
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
prevLine = line;
|
||||
line = line->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all of the remaining lines
|
||||
while (nsnull != line) {
|
||||
nsLineBox* next = line->mNext;
|
||||
delete line;
|
||||
line = next;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyLines(PR_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
|||
if (line->IsBlock()) {
|
||||
seenBlock = PR_TRUE;
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (line->IsFirstLine()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#endif
|
||||
if (line->IsBlock()) {
|
||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
||||
}
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
if (NS_BLOCK_HAS_FIRST_LINE_STYLE & mState) {
|
||||
if (seenBlock) {
|
||||
NS_ASSERTION(!line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(line->IsFirstLine(), "bad first line");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
count += line->GetChildCount();
|
||||
line = line->mNext;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,6 +30,12 @@ class nsAnonymousBlockFrame;
|
|||
|
||||
#define nsInlineFrameSuper nsHTMLContainerFrame
|
||||
|
||||
/**
|
||||
* Inline frame class.
|
||||
*
|
||||
* This class manages a list of child frames that are inline frames. Working with
|
||||
* nsLineLayout, the class will reflow and place inline frames on a line.
|
||||
*/
|
||||
class nsInlineFrame : public nsInlineFrameSuper
|
||||
{
|
||||
public:
|
||||
|
@ -39,9 +45,6 @@ public:
|
|||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
||||
// nsIFrame overrides
|
||||
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList);
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
|
@ -55,7 +58,11 @@ public:
|
|||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
NS_IMETHOD Destroy(nsIPresContext& aPresContext);
|
||||
NS_IMETHOD ReplaceFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame,
|
||||
nsIFrame* aNewFrame);
|
||||
NS_IMETHOD GetFrameName(nsString& aResult) const;
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
|
||||
|
@ -65,15 +72,15 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
NS_IMETHOD FindTextRuns(nsLineLayout& aLineLayout);
|
||||
#if XXX_fix_me
|
||||
NS_IMETHOD AdjustFrameSize(nscoord aExtraSpace, nscoord& aUsedSpace);
|
||||
NS_IMETHOD TrimTrailingWhiteSpace(nsIPresContext& aPresContext,
|
||||
nsIRenderingContext& aRC,
|
||||
nscoord& aDeltaWidth);
|
||||
#endif
|
||||
|
||||
static nsIID kInlineFrameCID;
|
||||
|
||||
// Take all of the frames away from this frame. The caller is
|
||||
// presumed to keep them alive.
|
||||
void StealAllFrames() {
|
||||
mFrames.SetFrames(nsnull);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Additional reflow state used during our reflow methods
|
||||
struct InlineReflowState {
|
||||
|
@ -82,75 +89,15 @@ protected:
|
|||
nsInlineFrame* mNextInFlow;
|
||||
};
|
||||
|
||||
// A helper class that knows how to take a list of frames and chop
|
||||
// it up into 3 sections.
|
||||
struct SectionData {
|
||||
SectionData(nsIFrame* aFrameList);
|
||||
|
||||
PRBool SplitFrameList(nsFrameList& aSection1,
|
||||
nsFrameList& aSection2,
|
||||
nsFrameList& aSection3);
|
||||
|
||||
PRBool HasABlock() const {
|
||||
return nsnull != firstBlock;
|
||||
}
|
||||
|
||||
nsIFrame* firstBlock;
|
||||
nsIFrame* prevFirstBlock;
|
||||
nsIFrame* lastBlock;
|
||||
nsIFrame* firstFrame;
|
||||
nsIFrame* lastFrame;
|
||||
};
|
||||
|
||||
nsInlineFrame();
|
||||
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
PRBool HaveAnonymousBlock() const {
|
||||
return mFrames.NotEmpty()
|
||||
? nsLineLayout::TreatFrameAsBlock(mFrames.FirstChild())
|
||||
: PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool ParentIsInlineFrame(nsIFrame* aFrame, nsIFrame** aParent) {
|
||||
void* tmp;
|
||||
nsIFrame* parent;
|
||||
aFrame->GetParent(&parent);
|
||||
*aParent = parent;
|
||||
if (NS_SUCCEEDED(parent->QueryInterface(kInlineFrameCID, &tmp))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsAnonymousBlockFrame* FindPrevAnonymousBlock(nsInlineFrame** aBlockParent);
|
||||
|
||||
nsAnonymousBlockFrame* FindAnonymousBlock(nsInlineFrame** aBlockParent);
|
||||
|
||||
nsresult CreateAnonymousBlock(nsIPresContext& aPresContext,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame** aResult);
|
||||
|
||||
nsresult AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aFrameList,
|
||||
PRBool aGenerateReflowCommands);
|
||||
|
||||
nsresult InsertBlockFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult InsertInlineFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult ReflowInlineFrames(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
InlineReflowState& rs,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
nsReflowStatus& aStatus);
|
||||
nsresult ReflowFrames(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
InlineReflowState& rs,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
nsresult ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
@ -158,29 +105,23 @@ protected:
|
|||
nsIFrame* aFrame,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
|
||||
virtual void PushFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFromChild,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
||||
|
||||
nsIFrame* PullAnyFrame(nsIPresContext* aPresContext, InlineReflowState& rs);
|
||||
|
||||
nsresult ReflowBlockFrame(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
InlineReflowState& rs,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
nsReflowStatus& aStatus);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Variation on inline-frame used to manage lines for line layout in
|
||||
// special situations.
|
||||
/**
|
||||
* Variation on inline-frame used to manage lines for line layout in
|
||||
* special situations (:first-line style in particular).
|
||||
*/
|
||||
class nsFirstLineFrame : public nsInlineFrame {
|
||||
public:
|
||||
friend nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
||||
|
@ -192,62 +133,20 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// AppendFrames/InsertFrames/RemoveFrame are implemented to forward
|
||||
// the method call to the parent frame.
|
||||
#endif
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
#ifdef BLOCK_DOES_FIRST_LINE
|
||||
// These methods are used by the parent frame to actually modify the
|
||||
// child frames of the line frame. These methods do not generate
|
||||
// reflow commands.
|
||||
nsresult AppendFrames2(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult InsertFrames2(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult RemoveFrame2(nsIPresContext* aPresContext,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
#endif
|
||||
// Take frames starting at aFrame until the end of the frame-list
|
||||
// away from this frame. The caller is presumed to keep them alive.
|
||||
void StealFramesFrom(nsIFrame* aFrame);
|
||||
|
||||
// Take all of the frames away from this frame. The caller is
|
||||
// presumed to keep them alive.
|
||||
void StealAllFrames() {
|
||||
mFrames.SetFrames(nsnull);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsFirstLineFrame();
|
||||
|
||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||
InlineReflowState& rs,
|
||||
PRBool* aIsComplete);
|
||||
|
||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
||||
};
|
||||
|
||||
extern nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Derived class created for relatively positioned inline-level elements
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -148,7 +148,6 @@ protected:
|
|||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
PRBool aHaveFirstLetterStyle,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult ConstructDocElementFrame(nsIPresContext* aPresContext,
|
||||
|
@ -506,7 +505,6 @@ protected:
|
|||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIStyleContext* aStyleContext,
|
||||
PRBool aHaveFirstLetterStyle,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult GetAdjustedParentFrame(nsIFrame* aCurrentParentFrame,
|
||||
|
@ -662,13 +660,49 @@ InitializeSelectFrame(nsIPresContext* aPresContext,
|
|||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame* aNewFrame);
|
||||
|
||||
nsresult ProcessBlockChildren(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aFrame,
|
||||
PRBool aCanHaveGeneratedContent,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool aParentIsBlock);
|
||||
|
||||
nsresult ConstructInline(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
const nsStyleDisplay* aDisplay,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame* aNewFrame);
|
||||
nsIFrame* aNewFrame,
|
||||
nsIFrame** aNewBlockFrame,
|
||||
nsIFrame** aNextInlineFrame);
|
||||
|
||||
nsresult ProcessInlineChildren(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aFrame,
|
||||
PRBool aCanHaveGeneratedContent,
|
||||
nsFrameItems& aFrameItems,
|
||||
PRBool* aKidsAllInline);
|
||||
|
||||
PRBool AreAllKidsInline(nsIFrame* aFrameList);
|
||||
|
||||
PRBool IsFrameSpecial(nsIFrameManager* aFrameManager, nsIFrame* aFrame);
|
||||
|
||||
PRBool IsFrameSpecial(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
void SetFrameIsSpecial(nsIFrameManager* aFrameManager, nsIFrame* aFrame);
|
||||
|
||||
PRBool WipeContainingBlock(nsIPresContext* aPresContext,
|
||||
nsFrameConstructorState& aState,
|
||||
nsIContent* blockContent,
|
||||
nsIFrame* aFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
||||
nsresult ReframeContainingBlock(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
nsresult RecreateEntireFrameTree(nsIPresContext* aPresContext);
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
|
@ -757,9 +791,6 @@ InitializeSelectFrame(nsIPresContext* aPresContext,
|
|||
nsIFrame* aPrevSibling,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
nsresult MaybeCreateContainerFrame(nsIPresContext* aPresContext,
|
||||
nsIContent* aContainer);
|
||||
|
||||
protected:
|
||||
nsIDocument* mDocument;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче