mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
Part of frame construction changes
This commit is contained in:
parent
2083b19aff
commit
4ad7bda623
@ -1074,6 +1074,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext,
|
||||
|
||||
case NS_STYLE_DISPLAY_INLINE:
|
||||
rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame);
|
||||
ProcessChildren(aPresContext, frame, aContent);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -276,7 +276,7 @@ protected:
|
||||
|
||||
nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFloatedFrame);
|
||||
nsresult AddNewFrames(nsIPresContext* aPresContext, nsIFrame*);
|
||||
nsresult AppendNewFrames(nsIPresContext* aPresContext, nsIFrame*);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
PRBool IsChild(nsIFrame* aFrame);
|
||||
@ -1010,7 +1010,7 @@ NS_IMETHODIMP
|
||||
nsCSSBlockFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
mHasBeenInitialized = PR_TRUE;
|
||||
return AddNewFrames(&aPresContext, aChildList);
|
||||
return AppendNewFrames(&aPresContext, aChildList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1680,7 +1680,7 @@ nsCSSBlockFrame::CreatePlaceholderFrame(nsIPresContext* aPresContext,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSBlockFrame::AddNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame)
|
||||
nsCSSBlockFrame::AppendNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame)
|
||||
{
|
||||
// Get our last line and then get its last child
|
||||
nsIFrame* lastFrame;
|
||||
@ -1729,6 +1729,7 @@ nsCSSBlockFrame::AddNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame)
|
||||
if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) {
|
||||
// Create a placeholder frame that will serve as the anchor point.
|
||||
nsPlaceholderFrame* placeholder = CreatePlaceholderFrame(aPresContext, frame);
|
||||
|
||||
// Remove the floated element from the flow, and replace it with the
|
||||
// placeholder frame
|
||||
if (nsnull != prevFrame) {
|
||||
@ -1860,7 +1861,7 @@ nsCSSBlockFrame::FrameAppendedReflow(nsCSSBlockReflowState& aState)
|
||||
|
||||
// Add the new frames to the child list, and create new lines. Each
|
||||
// impacted line will be marked dirty
|
||||
AddNewFrames(aState.mPresContext, firstAppendedFrame);
|
||||
AppendNewFrames(aState.mPresContext, firstAppendedFrame);
|
||||
#endif
|
||||
|
||||
// Generate text-run information
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "nsIReflowCommand.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
|
||||
#include "nsHTMLIIDs.h"// XXX
|
||||
#include "nsHTMLBase.h"// XXX rename to nsCSSBase?
|
||||
@ -142,6 +143,82 @@ nsCSSInlineFrame::GetSkipSides() const
|
||||
return skip;
|
||||
}
|
||||
|
||||
nsPlaceholderFrame*
|
||||
nsCSSInlineFrame::CreatePlaceholderFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFloatedFrame)
|
||||
{
|
||||
nsIContent* content;
|
||||
aFloatedFrame->GetContent(content);
|
||||
|
||||
// XXX We should wrap the floated element in a BODY frame...
|
||||
nsPlaceholderFrame* placeholder;
|
||||
nsPlaceholderFrame::NewFrame((nsIFrame**)&placeholder, content, this, aFloatedFrame);
|
||||
NS_IF_RELEASE(content);
|
||||
|
||||
// Let the placeholder share the same style context as the floated element
|
||||
nsIStyleContext* kidSC;
|
||||
aFloatedFrame->GetStyleContext(aPresContext, kidSC);
|
||||
placeholder->SetStyleContext(aPresContext, kidSC);
|
||||
NS_RELEASE(kidSC);
|
||||
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSInlineFrame::AppendNewFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aNewFrame)
|
||||
{
|
||||
nsIFrame* lastFrame;
|
||||
if (nsnull == mFirstChild) {
|
||||
lastFrame = nsnull;
|
||||
mFirstChild = aNewFrame;
|
||||
} else {
|
||||
LastChild(lastFrame);
|
||||
lastFrame->SetNextSibling(aNewFrame);
|
||||
}
|
||||
mChildCount += LengthOf(aNewFrame);
|
||||
|
||||
// Now walk the new frames and check if there are any elements that want
|
||||
// to be floated
|
||||
nsIFrame* prevFrame = lastFrame;
|
||||
for (nsIFrame* frame = aNewFrame; nsnull != frame; frame->GetNextSibling(frame)) {
|
||||
const nsStyleDisplay* display;
|
||||
frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
|
||||
|
||||
// See if the element wants to be floated
|
||||
if (NS_STYLE_FLOAT_NONE != display->mFloats) {
|
||||
// Create a placeholder frame that will serve as the anchor point.
|
||||
nsPlaceholderFrame* placeholder = CreatePlaceholderFrame(aPresContext, frame);
|
||||
|
||||
// Remove the floated element from the flow, and replace it with the
|
||||
// placeholder frame
|
||||
if (nsnull == prevFrame) {
|
||||
mFirstChild = placeholder;
|
||||
} else {
|
||||
prevFrame->SetNextSibling(placeholder);
|
||||
}
|
||||
nsIFrame* nextSibling;
|
||||
frame->GetNextSibling(nextSibling);
|
||||
placeholder->SetNextSibling(nextSibling);
|
||||
frame->SetNextSibling(nsnull);
|
||||
|
||||
frame = placeholder;
|
||||
}
|
||||
|
||||
// Remember the previous frame
|
||||
prevFrame = frame;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSInlineFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
|
||||
{
|
||||
NS_PRECONDITION(nsnull == mFirstChild, "already initialized");
|
||||
return AppendNewFrames(&aPresContext, aChildList);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSInlineFrame::CreateContinuingFrame(nsIPresContext& aCX,
|
||||
nsIFrame* aParent,
|
||||
@ -180,31 +257,6 @@ nsCSSInlineFrame::FindTextRuns(nsCSSLineLayout& aLineLayout,
|
||||
// Gather up children from the overflow lists
|
||||
DrainOverflowLists();
|
||||
|
||||
// Create new frames if necessary
|
||||
if (NS_FRAME_FIRST_REFLOW & mState) {
|
||||
if ((nsnull == mPrevInFlow) && (nsnull == mNextInFlow) &&
|
||||
(0 == mChildCount)) {
|
||||
rv = CreateNewFrames(aLineLayout.mPresContext);
|
||||
if (NS_OK != rv) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nsnull != aReflowCommand) {
|
||||
nsIFrame* target;
|
||||
aReflowCommand->GetTarget(target);
|
||||
if (this == target) {
|
||||
nsIReflowCommand::ReflowType type;
|
||||
aReflowCommand->GetType(type);
|
||||
if (nsIReflowCommand::FrameAppended == type) {
|
||||
rv = CreateNewFrames(aLineLayout.mPresContext);
|
||||
if (NS_OK != rv) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ask each child frame for its text runs
|
||||
frame = mFirstChild;
|
||||
n = mChildCount;
|
||||
@ -225,7 +277,6 @@ nsCSSInlineFrame::FindTextRuns(nsCSSLineLayout& aLineLayout,
|
||||
frame->GetNextSibling(frame);
|
||||
}
|
||||
|
||||
done:;
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||
("exit nsCSSInlineFrame::FindTextRuns rv=%x [%d,%d,%c]",
|
||||
rv, mFirstContentOffset, mLastContentOffset,
|
||||
@ -402,19 +453,6 @@ nsCSSInlineFrame::InitialReflow(nsCSSInlineReflowState& aState)
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if XXX
|
||||
// Create any frames that need creating; note that they should have
|
||||
// been created during FindTextRuns which should have been called
|
||||
// before this, but we check anyway.
|
||||
if ((nsnull == mPrevInFlow) && (nsnull == mNextInFlow) &&
|
||||
(0 == mChildCount)) {
|
||||
nsresult rv = CreateNewFrames(aState.mPresContext);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsInlineReflowStatus rs = NS_FRAME_COMPLETE;
|
||||
if (0 != mChildCount) {
|
||||
if (!ReflowMapped(aState, rs)) {
|
||||
@ -430,13 +468,12 @@ nsCSSInlineFrame::FrameAppendedReflow(nsCSSInlineReflowState& aState)
|
||||
NS_PRECONDITION(nsnull == mNextInFlow, "bad frame-appended-reflow");
|
||||
NS_PRECONDITION(mLastContentIsComplete == PR_TRUE, "bad state");
|
||||
|
||||
#if XXX
|
||||
// Create any frames that need creating
|
||||
nsresult rv = CreateNewFrames(aState.mPresContext);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
// Get the first of the newly appended frames
|
||||
nsIFrame* firstAppendedFrame;
|
||||
aState.reflowCommand->GetChildFrame(firstAppendedFrame);
|
||||
|
||||
// Add the new frames
|
||||
AppendNewFrames(aState.mPresContext, firstAppendedFrame);
|
||||
|
||||
nsInlineReflowStatus rs = NS_FRAME_COMPLETE;
|
||||
if (0 != mChildCount) {
|
||||
@ -447,86 +484,6 @@ nsCSSInlineFrame::FrameAppendedReflow(nsCSSInlineReflowState& aState)
|
||||
return rs;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSInlineFrame::CreateNewFrames(nsIPresContext* aPresContext)
|
||||
{
|
||||
// reason: initial: (a) null nif, pif: create frames
|
||||
// (b) pullup: don't create frames
|
||||
// reason: incremental: (a) append targetted at us => create frames
|
||||
|
||||
// Get the childPrevInFlow for our eventual first child if we are a
|
||||
// continuation and we have no children and the last child in our
|
||||
// prev-in-flow is incomplete. While we are at it, we also compute
|
||||
// our kidContentIndex.
|
||||
PRInt32 kidContentIndex;
|
||||
nsIFrame* childPrevInFlow = nsnull;
|
||||
nsIFrame* prevChild = nsnull;
|
||||
if ((nsnull == mFirstChild) && (nsnull != mPrevInFlow)) {
|
||||
nsCSSInlineFrame* prev = (nsCSSInlineFrame*)mPrevInFlow;
|
||||
NS_ASSERTION(prev->mLastContentOffset >= prev->mFirstContentOffset,
|
||||
"bad prevInFlow");
|
||||
kidContentIndex = prev->NextChildOffset();
|
||||
if (!prev->mLastContentIsComplete) {
|
||||
// Our prev-in-flow's last child is not complete
|
||||
prev->LastChild(childPrevInFlow);
|
||||
}
|
||||
}
|
||||
else {
|
||||
kidContentIndex = NextChildOffset();
|
||||
LastChild(prevChild);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
PRInt32 lastContentIndex;
|
||||
mContent->ChildCount(lastContentIndex);
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||
("enter nsCSSInlineFrame::CreateNewFrames: kidContentIndex=%d lastContentIndex=%d childPrevInFlow=%p",
|
||||
kidContentIndex, lastContentIndex, childPrevInFlow));
|
||||
while (kidContentIndex < lastContentIndex) {
|
||||
nsIContent* kid;
|
||||
mContent->ChildAt(kidContentIndex, kid);
|
||||
if (nsnull == kid) {
|
||||
// Our content container is bad
|
||||
break;
|
||||
}
|
||||
|
||||
// Create child
|
||||
nsIFrame* child;
|
||||
rv = nsHTMLBase::CreateFrame(aPresContext, this, kid, childPrevInFlow,
|
||||
child);
|
||||
NS_RELEASE(kid);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
if (nsnull == prevChild) {
|
||||
mFirstChild = child;
|
||||
mFirstContentOffset = kidContentIndex;
|
||||
}
|
||||
else {
|
||||
prevChild->SetNextSibling(child);
|
||||
}
|
||||
mChildCount++;
|
||||
kidContentIndex++;
|
||||
childPrevInFlow = nsnull;
|
||||
prevChild = child;
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_NEW_FRAMES,
|
||||
("nsCSSInlineFrame::CreateNewFrames: new-frame=%p prev-in-flow=%p",
|
||||
child, childPrevInFlow));
|
||||
}
|
||||
if (kidContentIndex == 0) {
|
||||
NS_ASSERTION(lastContentIndex == 0, "bad kid content index");
|
||||
mLastContentOffset = 0;
|
||||
} else {
|
||||
mLastContentOffset = kidContentIndex - 1;
|
||||
}
|
||||
NS_ASSERTION(mFirstContentOffset <= mLastContentOffset, "bad fco/lco");
|
||||
mLastContentIsComplete = PR_TRUE;
|
||||
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
||||
("exit nsCSSInlineFrame::CreateNewFrames"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsInlineReflowStatus
|
||||
nsCSSInlineFrame::ChildIncrementalReflow(nsCSSInlineReflowState& aState)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nsCSSLineLayout.h"
|
||||
|
||||
class nsCSSInlineFrame;
|
||||
class nsPlaceholderFrame;
|
||||
|
||||
/**
|
||||
* Reflow state object for managing css inline layout. Most of the state
|
||||
@ -62,6 +63,7 @@ public:
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
|
||||
// nsIFrame
|
||||
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aCX,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
@ -110,8 +112,6 @@ protected:
|
||||
nsIFrame* PullOneChild(nsCSSInlineFrame* aNextInFlow,
|
||||
nsIFrame* aLastChild);
|
||||
|
||||
nsresult CreateNewFrames(nsIPresContext* aPresContext);
|
||||
|
||||
nsresult MaybeCreateNextInFlow(nsCSSInlineReflowState& aState,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
@ -120,6 +120,11 @@ protected:
|
||||
|
||||
void DrainOverflowLists();
|
||||
|
||||
nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFloatedFrame);
|
||||
|
||||
nsresult AppendNewFrames(nsIPresContext* aPresContext, nsIFrame*);
|
||||
|
||||
friend nsresult NS_NewCSSInlineFrame(nsIFrame** aInstancePtrResult,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent);
|
||||
|
@ -1074,6 +1074,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext,
|
||||
|
||||
case NS_STYLE_DISPLAY_INLINE:
|
||||
rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame);
|
||||
ProcessChildren(aPresContext, frame, aContent);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1074,6 +1074,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext,
|
||||
|
||||
case NS_STYLE_DISPLAY_INLINE:
|
||||
rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame);
|
||||
ProcessChildren(aPresContext, frame, aContent);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user