зеркало из https://github.com/mozilla/gecko-dev.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:
Родитель
1fe14ebeaa
Коммит
0a512d8393
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -148,7 +148,6 @@ protected:
|
||||||
nsFrameConstructorState& aState,
|
nsFrameConstructorState& aState,
|
||||||
nsIContent* aContent,
|
nsIContent* aContent,
|
||||||
nsIFrame* aParentFrame,
|
nsIFrame* aParentFrame,
|
||||||
PRBool aHaveFirstLetterStyle,
|
|
||||||
nsFrameItems& aFrameItems);
|
nsFrameItems& aFrameItems);
|
||||||
|
|
||||||
nsresult ConstructDocElementFrame(nsIPresContext* aPresContext,
|
nsresult ConstructDocElementFrame(nsIPresContext* aPresContext,
|
||||||
|
@ -506,7 +505,6 @@ protected:
|
||||||
nsIContent* aContent,
|
nsIContent* aContent,
|
||||||
nsIFrame* aParentFrame,
|
nsIFrame* aParentFrame,
|
||||||
nsIStyleContext* aStyleContext,
|
nsIStyleContext* aStyleContext,
|
||||||
PRBool aHaveFirstLetterStyle,
|
|
||||||
nsFrameItems& aFrameItems);
|
nsFrameItems& aFrameItems);
|
||||||
|
|
||||||
nsresult GetAdjustedParentFrame(nsIFrame* aCurrentParentFrame,
|
nsresult GetAdjustedParentFrame(nsIFrame* aCurrentParentFrame,
|
||||||
|
@ -662,13 +660,49 @@ InitializeSelectFrame(nsIPresContext* aPresContext,
|
||||||
nsIStyleContext* aStyleContext,
|
nsIStyleContext* aStyleContext,
|
||||||
nsIFrame* aNewFrame);
|
nsIFrame* aNewFrame);
|
||||||
|
|
||||||
|
nsresult ProcessBlockChildren(nsIPresContext* aPresContext,
|
||||||
|
nsFrameConstructorState& aState,
|
||||||
|
nsIContent* aContent,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
PRBool aCanHaveGeneratedContent,
|
||||||
|
nsFrameItems& aFrameItems,
|
||||||
|
PRBool aParentIsBlock);
|
||||||
|
|
||||||
nsresult ConstructInline(nsIPresContext* aPresContext,
|
nsresult ConstructInline(nsIPresContext* aPresContext,
|
||||||
nsFrameConstructorState& aState,
|
nsFrameConstructorState& aState,
|
||||||
const nsStyleDisplay* aDisplay,
|
const nsStyleDisplay* aDisplay,
|
||||||
nsIContent* aContent,
|
nsIContent* aContent,
|
||||||
nsIFrame* aParentFrame,
|
nsIFrame* aParentFrame,
|
||||||
nsIStyleContext* aStyleContext,
|
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,
|
nsIFrame* aPrevSibling,
|
||||||
nsFrameItems& aFrameItems);
|
nsFrameItems& aFrameItems);
|
||||||
|
|
||||||
nsresult MaybeCreateContainerFrame(nsIPresContext* aPresContext,
|
|
||||||
nsIContent* aContainer);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsIDocument* mDocument;
|
nsIDocument* mDocument;
|
||||||
|
|
||||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||||
// line and don't stop the line reflow...
|
// line and don't stop the line reflow...
|
||||||
PRBool splitLine = !reflowingFirstLetter;
|
PRBool splitLine = !reflowingFirstLetter;
|
||||||
if (reflowingFirstLetter) {
|
if (reflowingFirstLetter) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
if (aLine->IsFirstLine()) {
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||||
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||||
splitLine = PR_TRUE;
|
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) {
|
if (splitLine) {
|
||||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
||||||
return nsnull;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||||
if (lastLine) {
|
if (lastLine) {
|
||||||
lastKid = lastLine->LastChild();
|
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
|
// Add frames after the last child
|
||||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
nsLineBox* prevSibLine = nsnull;
|
nsLineBox* prevSibLine = nsnull;
|
||||||
PRInt32 prevSiblingIndex = -1;
|
PRInt32 prevSiblingIndex = -1;
|
||||||
if (aPrevSibling) {
|
if (aPrevSibling) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
// Find the line that contains the previous sibling
|
||||||
// Its possible we have an nsFirstLineFrame managing some of our
|
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||||
// child frames. If we do and the AddFrames is targetted at it,
|
&prevSiblingIndex);
|
||||||
// use AddFirstLineFrames to get the frames properly placed.
|
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||||
nsIFrame* prevSiblingParent;
|
if (nsnull == prevSibLine) {
|
||||||
aPrevSibling->GetParent(&prevSiblingParent);
|
// Note: defensive code! FindLineContaining must not return
|
||||||
if (prevSiblingParent != this) {
|
// null in this case, so if it does...
|
||||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
aPrevSibling = nsnull;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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
|
// Find the frame following aPrevSibling so that we can join up the
|
||||||
// two lists of frames.
|
// two lists of frames.
|
||||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||||
|
@ -4834,15 +4550,6 @@ nsresult
|
||||||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aDeletedFrame)
|
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
|
// Find the line and the previous sibling that contains
|
||||||
// deletedFrame; we also find the pointer to the line.
|
// deletedFrame; we also find the pointer to the line.
|
||||||
nsBlockFrame* flow = this;
|
nsBlockFrame* flow = this;
|
||||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
while (nsnull != aDeletedFrame) {
|
while (nsnull != aDeletedFrame) {
|
||||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
#ifndef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIFrame* parent;
|
nsIFrame* parent;
|
||||||
#endif
|
|
||||||
aDeletedFrame->GetParent(&parent);
|
aDeletedFrame->GetParent(&parent);
|
||||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||||
nsIFrame* aChild)
|
nsIFrame* aChild)
|
||||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
||||||
return fls;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
#endif
|
#endif
|
||||||
NS_RELEASE(firstLetterStyle);
|
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);
|
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->GetChildCount();
|
PRInt32 n = line->GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
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->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
return NS_OK;
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
seenBlock = PR_TRUE;
|
seenBlock = PR_TRUE;
|
||||||
}
|
}
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
if (line->IsFirstLine()) {
|
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
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();
|
count += line->GetChildCount();
|
||||||
line = line->mNext;
|
line = line->mNext;
|
||||||
|
|
|
@ -40,9 +40,6 @@ class nsFirstLineFrame;
|
||||||
*/
|
*/
|
||||||
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET 0x80000000
|
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET 0x80000000
|
||||||
#define NS_BLOCK_IS_HTML_PARAGRAPH 0x40000000
|
#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 NS_BLOCK_HAS_FIRST_LETTER_STYLE 0x10000000
|
||||||
|
|
||||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||||
|
@ -146,10 +143,6 @@ protected:
|
||||||
|
|
||||||
nsIStyleContext* GetFirstLetterStyle(nsIPresContext* aPresContext);
|
nsIStyleContext* GetFirstLetterStyle(nsIPresContext* aPresContext);
|
||||||
|
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIStyleContext* GetFirstLineStyle(nsIPresContext* aPresContext);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SetFlags(PRUint32 aFlags) {
|
void SetFlags(PRUint32 aFlags) {
|
||||||
mFlags = aFlags;
|
mFlags = aFlags;
|
||||||
}
|
}
|
||||||
|
@ -173,22 +166,6 @@ protected:
|
||||||
nsIFrame* aFrameList,
|
nsIFrame* aFrameList,
|
||||||
nsIFrame* aPrevSibling);
|
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);
|
void FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||||
|
|
||||||
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
|
@ -381,72 +358,5 @@ protected:
|
||||||
friend class nsBlockReflowState;
|
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___ */
|
#endif /* nsBlockFrame_h___ */
|
||||||
|
|
||||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||||
// line and don't stop the line reflow...
|
// line and don't stop the line reflow...
|
||||||
PRBool splitLine = !reflowingFirstLetter;
|
PRBool splitLine = !reflowingFirstLetter;
|
||||||
if (reflowingFirstLetter) {
|
if (reflowingFirstLetter) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
if (aLine->IsFirstLine()) {
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||||
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||||
splitLine = PR_TRUE;
|
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) {
|
if (splitLine) {
|
||||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
||||||
return nsnull;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||||
if (lastLine) {
|
if (lastLine) {
|
||||||
lastKid = lastLine->LastChild();
|
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
|
// Add frames after the last child
|
||||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
nsLineBox* prevSibLine = nsnull;
|
nsLineBox* prevSibLine = nsnull;
|
||||||
PRInt32 prevSiblingIndex = -1;
|
PRInt32 prevSiblingIndex = -1;
|
||||||
if (aPrevSibling) {
|
if (aPrevSibling) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
// Find the line that contains the previous sibling
|
||||||
// Its possible we have an nsFirstLineFrame managing some of our
|
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||||
// child frames. If we do and the AddFrames is targetted at it,
|
&prevSiblingIndex);
|
||||||
// use AddFirstLineFrames to get the frames properly placed.
|
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||||
nsIFrame* prevSiblingParent;
|
if (nsnull == prevSibLine) {
|
||||||
aPrevSibling->GetParent(&prevSiblingParent);
|
// Note: defensive code! FindLineContaining must not return
|
||||||
if (prevSiblingParent != this) {
|
// null in this case, so if it does...
|
||||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
aPrevSibling = nsnull;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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
|
// Find the frame following aPrevSibling so that we can join up the
|
||||||
// two lists of frames.
|
// two lists of frames.
|
||||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||||
|
@ -4834,15 +4550,6 @@ nsresult
|
||||||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aDeletedFrame)
|
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
|
// Find the line and the previous sibling that contains
|
||||||
// deletedFrame; we also find the pointer to the line.
|
// deletedFrame; we also find the pointer to the line.
|
||||||
nsBlockFrame* flow = this;
|
nsBlockFrame* flow = this;
|
||||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
while (nsnull != aDeletedFrame) {
|
while (nsnull != aDeletedFrame) {
|
||||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
#ifndef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIFrame* parent;
|
nsIFrame* parent;
|
||||||
#endif
|
|
||||||
aDeletedFrame->GetParent(&parent);
|
aDeletedFrame->GetParent(&parent);
|
||||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||||
nsIFrame* aChild)
|
nsIFrame* aChild)
|
||||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
||||||
return fls;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
#endif
|
#endif
|
||||||
NS_RELEASE(firstLetterStyle);
|
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);
|
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->GetChildCount();
|
PRInt32 n = line->GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
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->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
return NS_OK;
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
seenBlock = PR_TRUE;
|
seenBlock = PR_TRUE;
|
||||||
}
|
}
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
if (line->IsFirstLine()) {
|
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
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();
|
count += line->GetChildCount();
|
||||||
line = line->mNext;
|
line = line->mNext;
|
||||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||||
// line and don't stop the line reflow...
|
// line and don't stop the line reflow...
|
||||||
PRBool splitLine = !reflowingFirstLetter;
|
PRBool splitLine = !reflowingFirstLetter;
|
||||||
if (reflowingFirstLetter) {
|
if (reflowingFirstLetter) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
if (aLine->IsFirstLine()) {
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||||
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||||
splitLine = PR_TRUE;
|
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) {
|
if (splitLine) {
|
||||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
||||||
return nsnull;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||||
if (lastLine) {
|
if (lastLine) {
|
||||||
lastKid = lastLine->LastChild();
|
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
|
// Add frames after the last child
|
||||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
nsLineBox* prevSibLine = nsnull;
|
nsLineBox* prevSibLine = nsnull;
|
||||||
PRInt32 prevSiblingIndex = -1;
|
PRInt32 prevSiblingIndex = -1;
|
||||||
if (aPrevSibling) {
|
if (aPrevSibling) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
// Find the line that contains the previous sibling
|
||||||
// Its possible we have an nsFirstLineFrame managing some of our
|
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||||
// child frames. If we do and the AddFrames is targetted at it,
|
&prevSiblingIndex);
|
||||||
// use AddFirstLineFrames to get the frames properly placed.
|
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||||
nsIFrame* prevSiblingParent;
|
if (nsnull == prevSibLine) {
|
||||||
aPrevSibling->GetParent(&prevSiblingParent);
|
// Note: defensive code! FindLineContaining must not return
|
||||||
if (prevSiblingParent != this) {
|
// null in this case, so if it does...
|
||||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
aPrevSibling = nsnull;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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
|
// Find the frame following aPrevSibling so that we can join up the
|
||||||
// two lists of frames.
|
// two lists of frames.
|
||||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||||
|
@ -4834,15 +4550,6 @@ nsresult
|
||||||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aDeletedFrame)
|
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
|
// Find the line and the previous sibling that contains
|
||||||
// deletedFrame; we also find the pointer to the line.
|
// deletedFrame; we also find the pointer to the line.
|
||||||
nsBlockFrame* flow = this;
|
nsBlockFrame* flow = this;
|
||||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
while (nsnull != aDeletedFrame) {
|
while (nsnull != aDeletedFrame) {
|
||||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
#ifndef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIFrame* parent;
|
nsIFrame* parent;
|
||||||
#endif
|
|
||||||
aDeletedFrame->GetParent(&parent);
|
aDeletedFrame->GetParent(&parent);
|
||||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||||
nsIFrame* aChild)
|
nsIFrame* aChild)
|
||||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
||||||
return fls;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
#endif
|
#endif
|
||||||
NS_RELEASE(firstLetterStyle);
|
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);
|
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->GetChildCount();
|
PRInt32 n = line->GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
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->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
return NS_OK;
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
seenBlock = PR_TRUE;
|
seenBlock = PR_TRUE;
|
||||||
}
|
}
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
if (line->IsFirstLine()) {
|
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
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();
|
count += line->GetChildCount();
|
||||||
line = line->mNext;
|
line = line->mNext;
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,6 +30,12 @@ class nsAnonymousBlockFrame;
|
||||||
|
|
||||||
#define nsInlineFrameSuper nsHTMLContainerFrame
|
#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
|
class nsInlineFrame : public nsInlineFrameSuper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -39,9 +45,6 @@ public:
|
||||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||||
|
|
||||||
// nsIFrame overrides
|
// nsIFrame overrides
|
||||||
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
|
|
||||||
nsIAtom* aListName,
|
|
||||||
nsIFrame* aChildList);
|
|
||||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -55,7 +58,11 @@ public:
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
nsIFrame* aOldFrame);
|
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 GetFrameName(nsString& aResult) const;
|
||||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||||
|
|
||||||
|
@ -65,15 +72,15 @@ public:
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
NS_IMETHOD FindTextRuns(nsLineLayout& aLineLayout);
|
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;
|
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:
|
protected:
|
||||||
// Additional reflow state used during our reflow methods
|
// Additional reflow state used during our reflow methods
|
||||||
struct InlineReflowState {
|
struct InlineReflowState {
|
||||||
|
@ -82,75 +89,15 @@ protected:
|
||||||
nsInlineFrame* mNextInFlow;
|
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();
|
nsInlineFrame();
|
||||||
|
|
||||||
virtual PRIntn GetSkipSides() const;
|
virtual PRIntn GetSkipSides() const;
|
||||||
|
|
||||||
PRBool HaveAnonymousBlock() const {
|
nsresult ReflowFrames(nsIPresContext* aPresContext,
|
||||||
return mFrames.NotEmpty()
|
const nsHTMLReflowState& aReflowState,
|
||||||
? nsLineLayout::TreatFrameAsBlock(mFrames.FirstChild())
|
InlineReflowState& rs,
|
||||||
: PR_FALSE;
|
nsHTMLReflowMetrics& aMetrics,
|
||||||
}
|
nsReflowStatus& aStatus);
|
||||||
|
|
||||||
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 ReflowInlineFrame(nsIPresContext* aPresContext,
|
nsresult ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
|
@ -158,29 +105,23 @@ protected:
|
||||||
nsIFrame* aFrame,
|
nsIFrame* aFrame,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
|
||||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||||
InlineReflowState& rs,
|
InlineReflowState& rs,
|
||||||
PRBool* aIsComplete);
|
PRBool* aIsComplete);
|
||||||
|
|
||||||
virtual void PushFrames(nsIPresContext* aPresContext,
|
virtual void PushFrames(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aFromChild,
|
nsIFrame* aFromChild,
|
||||||
nsIFrame* aPrevSibling);
|
nsIFrame* aPrevSibling);
|
||||||
|
|
||||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
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 {
|
class nsFirstLineFrame : public nsInlineFrame {
|
||||||
public:
|
public:
|
||||||
friend nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
friend nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
||||||
|
@ -192,62 +133,20 @@ public:
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
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
|
// Take frames starting at aFrame until the end of the frame-list
|
||||||
// away from this frame. The caller is presumed to keep them alive.
|
// away from this frame. The caller is presumed to keep them alive.
|
||||||
void StealFramesFrom(nsIFrame* aFrame);
|
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:
|
protected:
|
||||||
nsFirstLineFrame();
|
nsFirstLineFrame();
|
||||||
|
|
||||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||||
InlineReflowState& rs,
|
InlineReflowState& rs,
|
||||||
PRBool* aIsComplete);
|
PRBool* aIsComplete);
|
||||||
|
|
||||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
// Derived class created for relatively positioned inline-level elements
|
// 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...
|
// line and don't stop the line reflow...
|
||||||
PRBool splitLine = !reflowingFirstLetter;
|
PRBool splitLine = !reflowingFirstLetter;
|
||||||
if (reflowingFirstLetter) {
|
if (reflowingFirstLetter) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
if (aLine->IsFirstLine()) {
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||||
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||||
splitLine = PR_TRUE;
|
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) {
|
if (splitLine) {
|
||||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
||||||
return nsnull;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||||
if (lastLine) {
|
if (lastLine) {
|
||||||
lastKid = lastLine->LastChild();
|
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
|
// Add frames after the last child
|
||||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
nsLineBox* prevSibLine = nsnull;
|
nsLineBox* prevSibLine = nsnull;
|
||||||
PRInt32 prevSiblingIndex = -1;
|
PRInt32 prevSiblingIndex = -1;
|
||||||
if (aPrevSibling) {
|
if (aPrevSibling) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
// Find the line that contains the previous sibling
|
||||||
// Its possible we have an nsFirstLineFrame managing some of our
|
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||||
// child frames. If we do and the AddFrames is targetted at it,
|
&prevSiblingIndex);
|
||||||
// use AddFirstLineFrames to get the frames properly placed.
|
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||||
nsIFrame* prevSiblingParent;
|
if (nsnull == prevSibLine) {
|
||||||
aPrevSibling->GetParent(&prevSiblingParent);
|
// Note: defensive code! FindLineContaining must not return
|
||||||
if (prevSiblingParent != this) {
|
// null in this case, so if it does...
|
||||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
aPrevSibling = nsnull;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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
|
// Find the frame following aPrevSibling so that we can join up the
|
||||||
// two lists of frames.
|
// two lists of frames.
|
||||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||||
|
@ -4834,15 +4550,6 @@ nsresult
|
||||||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aDeletedFrame)
|
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
|
// Find the line and the previous sibling that contains
|
||||||
// deletedFrame; we also find the pointer to the line.
|
// deletedFrame; we also find the pointer to the line.
|
||||||
nsBlockFrame* flow = this;
|
nsBlockFrame* flow = this;
|
||||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
while (nsnull != aDeletedFrame) {
|
while (nsnull != aDeletedFrame) {
|
||||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
#ifndef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIFrame* parent;
|
nsIFrame* parent;
|
||||||
#endif
|
|
||||||
aDeletedFrame->GetParent(&parent);
|
aDeletedFrame->GetParent(&parent);
|
||||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||||
nsIFrame* aChild)
|
nsIFrame* aChild)
|
||||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
||||||
return fls;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
#endif
|
#endif
|
||||||
NS_RELEASE(firstLetterStyle);
|
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);
|
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->GetChildCount();
|
PRInt32 n = line->GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
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->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
return NS_OK;
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
seenBlock = PR_TRUE;
|
seenBlock = PR_TRUE;
|
||||||
}
|
}
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
if (line->IsFirstLine()) {
|
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
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();
|
count += line->GetChildCount();
|
||||||
line = line->mNext;
|
line = line->mNext;
|
||||||
|
|
|
@ -40,9 +40,6 @@ class nsFirstLineFrame;
|
||||||
*/
|
*/
|
||||||
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET 0x80000000
|
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET 0x80000000
|
||||||
#define NS_BLOCK_IS_HTML_PARAGRAPH 0x40000000
|
#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 NS_BLOCK_HAS_FIRST_LETTER_STYLE 0x10000000
|
||||||
|
|
||||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||||
|
@ -146,10 +143,6 @@ protected:
|
||||||
|
|
||||||
nsIStyleContext* GetFirstLetterStyle(nsIPresContext* aPresContext);
|
nsIStyleContext* GetFirstLetterStyle(nsIPresContext* aPresContext);
|
||||||
|
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIStyleContext* GetFirstLineStyle(nsIPresContext* aPresContext);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SetFlags(PRUint32 aFlags) {
|
void SetFlags(PRUint32 aFlags) {
|
||||||
mFlags = aFlags;
|
mFlags = aFlags;
|
||||||
}
|
}
|
||||||
|
@ -173,22 +166,6 @@ protected:
|
||||||
nsIFrame* aFrameList,
|
nsIFrame* aFrameList,
|
||||||
nsIFrame* aPrevSibling);
|
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);
|
void FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||||
|
|
||||||
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
|
@ -381,72 +358,5 @@ protected:
|
||||||
friend class nsBlockReflowState;
|
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___ */
|
#endif /* nsBlockFrame_h___ */
|
||||||
|
|
||||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||||
// line and don't stop the line reflow...
|
// line and don't stop the line reflow...
|
||||||
PRBool splitLine = !reflowingFirstLetter;
|
PRBool splitLine = !reflowingFirstLetter;
|
||||||
if (reflowingFirstLetter) {
|
if (reflowingFirstLetter) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
if (aLine->IsFirstLine()) {
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||||
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||||
splitLine = PR_TRUE;
|
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) {
|
if (splitLine) {
|
||||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
||||||
return nsnull;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||||
if (lastLine) {
|
if (lastLine) {
|
||||||
lastKid = lastLine->LastChild();
|
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
|
// Add frames after the last child
|
||||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
nsLineBox* prevSibLine = nsnull;
|
nsLineBox* prevSibLine = nsnull;
|
||||||
PRInt32 prevSiblingIndex = -1;
|
PRInt32 prevSiblingIndex = -1;
|
||||||
if (aPrevSibling) {
|
if (aPrevSibling) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
// Find the line that contains the previous sibling
|
||||||
// Its possible we have an nsFirstLineFrame managing some of our
|
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||||
// child frames. If we do and the AddFrames is targetted at it,
|
&prevSiblingIndex);
|
||||||
// use AddFirstLineFrames to get the frames properly placed.
|
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||||
nsIFrame* prevSiblingParent;
|
if (nsnull == prevSibLine) {
|
||||||
aPrevSibling->GetParent(&prevSiblingParent);
|
// Note: defensive code! FindLineContaining must not return
|
||||||
if (prevSiblingParent != this) {
|
// null in this case, so if it does...
|
||||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
aPrevSibling = nsnull;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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
|
// Find the frame following aPrevSibling so that we can join up the
|
||||||
// two lists of frames.
|
// two lists of frames.
|
||||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||||
|
@ -4834,15 +4550,6 @@ nsresult
|
||||||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aDeletedFrame)
|
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
|
// Find the line and the previous sibling that contains
|
||||||
// deletedFrame; we also find the pointer to the line.
|
// deletedFrame; we also find the pointer to the line.
|
||||||
nsBlockFrame* flow = this;
|
nsBlockFrame* flow = this;
|
||||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
while (nsnull != aDeletedFrame) {
|
while (nsnull != aDeletedFrame) {
|
||||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
#ifndef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIFrame* parent;
|
nsIFrame* parent;
|
||||||
#endif
|
|
||||||
aDeletedFrame->GetParent(&parent);
|
aDeletedFrame->GetParent(&parent);
|
||||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||||
nsIFrame* aChild)
|
nsIFrame* aChild)
|
||||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
||||||
return fls;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
#endif
|
#endif
|
||||||
NS_RELEASE(firstLetterStyle);
|
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);
|
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->GetChildCount();
|
PRInt32 n = line->GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
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->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
return NS_OK;
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
seenBlock = PR_TRUE;
|
seenBlock = PR_TRUE;
|
||||||
}
|
}
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
if (line->IsFirstLine()) {
|
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
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();
|
count += line->GetChildCount();
|
||||||
line = line->mNext;
|
line = line->mNext;
|
||||||
|
|
|
@ -3746,21 +3746,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState,
|
||||||
// line and don't stop the line reflow...
|
// line and don't stop the line reflow...
|
||||||
PRBool splitLine = !reflowingFirstLetter;
|
PRBool splitLine = !reflowingFirstLetter;
|
||||||
if (reflowingFirstLetter) {
|
if (reflowingFirstLetter) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
if (aLine->IsFirstLine()) {
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
||||||
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
||||||
splitLine = PR_TRUE;
|
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) {
|
if (splitLine) {
|
||||||
|
@ -4281,100 +4272,6 @@ nsBlockFrame::LastChild()
|
||||||
return nsnull;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
|
@ -4399,14 +4296,6 @@ nsBlockFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||||
if (lastLine) {
|
if (lastLine) {
|
||||||
lastKid = lastLine->LastChild();
|
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
|
// Add frames after the last child
|
||||||
|
@ -4496,50 +4385,16 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
nsLineBox* prevSibLine = nsnull;
|
nsLineBox* prevSibLine = nsnull;
|
||||||
PRInt32 prevSiblingIndex = -1;
|
PRInt32 prevSiblingIndex = -1;
|
||||||
if (aPrevSibling) {
|
if (aPrevSibling) {
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
// Find the line that contains the previous sibling
|
||||||
// Its possible we have an nsFirstLineFrame managing some of our
|
prevSibLine = nsLineBox::FindLineContaining(mLines, aPrevSibling,
|
||||||
// child frames. If we do and the AddFrames is targetted at it,
|
&prevSiblingIndex);
|
||||||
// use AddFirstLineFrames to get the frames properly placed.
|
NS_ASSERTION(nsnull != prevSibLine, "prev sibling not in line list");
|
||||||
nsIFrame* prevSiblingParent;
|
if (nsnull == prevSibLine) {
|
||||||
aPrevSibling->GetParent(&prevSiblingParent);
|
// Note: defensive code! FindLineContaining must not return
|
||||||
if (prevSiblingParent != this) {
|
// null in this case, so if it does...
|
||||||
// We are attempting an insert into a nsFirstLineFrame. Mark the
|
aPrevSibling = nsnull;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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
|
// Find the frame following aPrevSibling so that we can join up the
|
||||||
// two lists of frames.
|
// two lists of frames.
|
||||||
|
@ -4609,151 +4464,12 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext,
|
||||||
aPrevSibling->SetNextSibling(prevSiblingNextFrame);
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
nsBlockFrame::FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
||||||
|
@ -4834,15 +4550,6 @@ nsresult
|
||||||
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aDeletedFrame)
|
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
|
// Find the line and the previous sibling that contains
|
||||||
// deletedFrame; we also find the pointer to the line.
|
// deletedFrame; we also find the pointer to the line.
|
||||||
nsBlockFrame* flow = this;
|
nsBlockFrame* flow = this;
|
||||||
|
@ -4878,9 +4585,7 @@ nsBlockFrame::DoRemoveFrame(nsIPresContext* aPresContext,
|
||||||
while (nsnull != aDeletedFrame) {
|
while (nsnull != aDeletedFrame) {
|
||||||
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
while ((nsnull != line) && (nsnull != aDeletedFrame)) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
#ifndef BLOCK_DOES_FIRST_LINE
|
|
||||||
nsIFrame* parent;
|
nsIFrame* parent;
|
||||||
#endif
|
|
||||||
aDeletedFrame->GetParent(&parent);
|
aDeletedFrame->GetParent(&parent);
|
||||||
NS_ASSERTION(flow == parent, "messed up delete code");
|
NS_ASSERTION(flow == parent, "messed up delete code");
|
||||||
NS_ASSERTION(line->Contains(aDeletedFrame), "frame not in line");
|
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
|
#ifdef DEBUG
|
||||||
VerifyLines(PR_TRUE);
|
VerifyLines(PR_TRUE);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
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
|
void
|
||||||
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext& aPresContext,
|
||||||
nsIFrame* aChild)
|
nsIFrame* aChild)
|
||||||
|
@ -6108,18 +5765,6 @@ nsBlockFrame::GetFirstLetterStyle(nsIPresContext* aPresContext)
|
||||||
return fls;
|
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
|
NS_IMETHODIMP
|
||||||
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -6143,18 +5788,6 @@ nsBlockFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||||
#endif
|
#endif
|
||||||
NS_RELEASE(firstLetterStyle);
|
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);
|
rv = AddFrames(&aPresContext, aChildList, nsnull);
|
||||||
|
@ -6448,15 +6081,7 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
nsIFrame* frame = line->mFirstChild;
|
nsIFrame* frame = line->mFirstChild;
|
||||||
PRInt32 n = line->GetChildCount();
|
PRInt32 n = line->GetChildCount();
|
||||||
while (--n >= 0) {
|
while (--n >= 0) {
|
||||||
nsresult rv = frame->FindTextRuns(textRunThingy);
|
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->GetNextSibling(&frame);
|
frame->GetNextSibling(&frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6474,210 +6099,6 @@ nsBlockFrame::ComputeTextRuns(nsIPresContext* aPresContext)
|
||||||
return NS_OK;
|
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
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
|
@ -6700,24 +6121,9 @@ nsBlockFrame::VerifyLines(PRBool aFinalCheckOK)
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
seenBlock = PR_TRUE;
|
seenBlock = PR_TRUE;
|
||||||
}
|
}
|
||||||
#ifdef BLOCK_DOES_FIRST_LINE
|
|
||||||
if (line->IsFirstLine()) {
|
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (line->IsBlock()) {
|
if (line->IsBlock()) {
|
||||||
NS_ASSERTION(1 == line->GetChildCount(), "bad first line");
|
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();
|
count += line->GetChildCount();
|
||||||
line = line->mNext;
|
line = line->mNext;
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -30,6 +30,12 @@ class nsAnonymousBlockFrame;
|
||||||
|
|
||||||
#define nsInlineFrameSuper nsHTMLContainerFrame
|
#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
|
class nsInlineFrame : public nsInlineFrameSuper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -39,9 +45,6 @@ public:
|
||||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||||
|
|
||||||
// nsIFrame overrides
|
// nsIFrame overrides
|
||||||
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
|
|
||||||
nsIAtom* aListName,
|
|
||||||
nsIFrame* aChildList);
|
|
||||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
|
@ -55,7 +58,11 @@ public:
|
||||||
nsIPresShell& aPresShell,
|
nsIPresShell& aPresShell,
|
||||||
nsIAtom* aListName,
|
nsIAtom* aListName,
|
||||||
nsIFrame* aOldFrame);
|
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 GetFrameName(nsString& aResult) const;
|
||||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||||
|
|
||||||
|
@ -65,15 +72,15 @@ public:
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
NS_IMETHOD FindTextRuns(nsLineLayout& aLineLayout);
|
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;
|
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:
|
protected:
|
||||||
// Additional reflow state used during our reflow methods
|
// Additional reflow state used during our reflow methods
|
||||||
struct InlineReflowState {
|
struct InlineReflowState {
|
||||||
|
@ -82,75 +89,15 @@ protected:
|
||||||
nsInlineFrame* mNextInFlow;
|
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();
|
nsInlineFrame();
|
||||||
|
|
||||||
virtual PRIntn GetSkipSides() const;
|
virtual PRIntn GetSkipSides() const;
|
||||||
|
|
||||||
PRBool HaveAnonymousBlock() const {
|
nsresult ReflowFrames(nsIPresContext* aPresContext,
|
||||||
return mFrames.NotEmpty()
|
const nsHTMLReflowState& aReflowState,
|
||||||
? nsLineLayout::TreatFrameAsBlock(mFrames.FirstChild())
|
InlineReflowState& rs,
|
||||||
: PR_FALSE;
|
nsHTMLReflowMetrics& aMetrics,
|
||||||
}
|
nsReflowStatus& aStatus);
|
||||||
|
|
||||||
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 ReflowInlineFrame(nsIPresContext* aPresContext,
|
nsresult ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
|
@ -158,29 +105,23 @@ protected:
|
||||||
nsIFrame* aFrame,
|
nsIFrame* aFrame,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
|
||||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||||
InlineReflowState& rs,
|
InlineReflowState& rs,
|
||||||
PRBool* aIsComplete);
|
PRBool* aIsComplete);
|
||||||
|
|
||||||
virtual void PushFrames(nsIPresContext* aPresContext,
|
virtual void PushFrames(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aFromChild,
|
nsIFrame* aFromChild,
|
||||||
nsIFrame* aPrevSibling);
|
nsIFrame* aPrevSibling);
|
||||||
|
|
||||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
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 {
|
class nsFirstLineFrame : public nsInlineFrame {
|
||||||
public:
|
public:
|
||||||
friend nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
friend nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
||||||
|
@ -192,62 +133,20 @@ public:
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
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
|
// Take frames starting at aFrame until the end of the frame-list
|
||||||
// away from this frame. The caller is presumed to keep them alive.
|
// away from this frame. The caller is presumed to keep them alive.
|
||||||
void StealFramesFrom(nsIFrame* aFrame);
|
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:
|
protected:
|
||||||
nsFirstLineFrame();
|
nsFirstLineFrame();
|
||||||
|
|
||||||
virtual nsIFrame* PullInlineFrame(nsIPresContext* aPresContext,
|
virtual nsIFrame* PullOneFrame(nsIPresContext* aPresContext,
|
||||||
InlineReflowState& rs,
|
InlineReflowState& rs,
|
||||||
PRBool* aIsComplete);
|
PRBool* aIsComplete);
|
||||||
|
|
||||||
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
virtual void DrainOverflow(nsIPresContext* aPresContext);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsresult NS_NewFirstLineFrame(nsIFrame** aNewFrame);
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
// Derived class created for relatively positioned inline-level elements
|
// Derived class created for relatively positioned inline-level elements
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -148,7 +148,6 @@ protected:
|
||||||
nsFrameConstructorState& aState,
|
nsFrameConstructorState& aState,
|
||||||
nsIContent* aContent,
|
nsIContent* aContent,
|
||||||
nsIFrame* aParentFrame,
|
nsIFrame* aParentFrame,
|
||||||
PRBool aHaveFirstLetterStyle,
|
|
||||||
nsFrameItems& aFrameItems);
|
nsFrameItems& aFrameItems);
|
||||||
|
|
||||||
nsresult ConstructDocElementFrame(nsIPresContext* aPresContext,
|
nsresult ConstructDocElementFrame(nsIPresContext* aPresContext,
|
||||||
|
@ -506,7 +505,6 @@ protected:
|
||||||
nsIContent* aContent,
|
nsIContent* aContent,
|
||||||
nsIFrame* aParentFrame,
|
nsIFrame* aParentFrame,
|
||||||
nsIStyleContext* aStyleContext,
|
nsIStyleContext* aStyleContext,
|
||||||
PRBool aHaveFirstLetterStyle,
|
|
||||||
nsFrameItems& aFrameItems);
|
nsFrameItems& aFrameItems);
|
||||||
|
|
||||||
nsresult GetAdjustedParentFrame(nsIFrame* aCurrentParentFrame,
|
nsresult GetAdjustedParentFrame(nsIFrame* aCurrentParentFrame,
|
||||||
|
@ -662,13 +660,49 @@ InitializeSelectFrame(nsIPresContext* aPresContext,
|
||||||
nsIStyleContext* aStyleContext,
|
nsIStyleContext* aStyleContext,
|
||||||
nsIFrame* aNewFrame);
|
nsIFrame* aNewFrame);
|
||||||
|
|
||||||
|
nsresult ProcessBlockChildren(nsIPresContext* aPresContext,
|
||||||
|
nsFrameConstructorState& aState,
|
||||||
|
nsIContent* aContent,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
PRBool aCanHaveGeneratedContent,
|
||||||
|
nsFrameItems& aFrameItems,
|
||||||
|
PRBool aParentIsBlock);
|
||||||
|
|
||||||
nsresult ConstructInline(nsIPresContext* aPresContext,
|
nsresult ConstructInline(nsIPresContext* aPresContext,
|
||||||
nsFrameConstructorState& aState,
|
nsFrameConstructorState& aState,
|
||||||
const nsStyleDisplay* aDisplay,
|
const nsStyleDisplay* aDisplay,
|
||||||
nsIContent* aContent,
|
nsIContent* aContent,
|
||||||
nsIFrame* aParentFrame,
|
nsIFrame* aParentFrame,
|
||||||
nsIStyleContext* aStyleContext,
|
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,
|
nsIFrame* aPrevSibling,
|
||||||
nsFrameItems& aFrameItems);
|
nsFrameItems& aFrameItems);
|
||||||
|
|
||||||
nsresult MaybeCreateContainerFrame(nsIPresContext* aPresContext,
|
|
||||||
nsIContent* aContainer);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsIDocument* mDocument;
|
nsIDocument* mDocument;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче