зеркало из https://github.com/mozilla/gecko-dev.git
Changed the body to be a subclass of nsBlockFrame rather than contain a
block frame
This commit is contained in:
Родитель
d14f0035d3
Коммит
f350be91c1
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
|
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
|
||||||
|
|
||||||
|
nsIAtom* nsBodyFrame::gAbsoluteAtom;
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewBodyFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame*& aResult,
|
NS_NewBodyFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame*& aResult,
|
||||||
PRUint32 aFlags)
|
PRUint32 aFlags)
|
||||||
|
@ -55,10 +57,14 @@ NS_NewBodyFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame*& aResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsBodyFrame::nsBodyFrame(nsIContent* aContent, nsIFrame* aParentFrame)
|
nsBodyFrame::nsBodyFrame(nsIContent* aContent, nsIFrame* aParentFrame)
|
||||||
: nsHTMLContainerFrame(aContent, aParentFrame)
|
: nsBlockFrame(aContent, aParentFrame)
|
||||||
{
|
{
|
||||||
mSpaceManager = new nsSpaceManager(this);
|
mSpaceManager = new nsSpaceManager(this);
|
||||||
NS_ADDREF(mSpaceManager);
|
NS_ADDREF(mSpaceManager);
|
||||||
|
// XXX for now this is a memory leak
|
||||||
|
if (nsnull == gAbsoluteAtom) {
|
||||||
|
gAbsoluteAtom = NS_NewAtom("Absolute-list");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsBodyFrame::~nsBodyFrame()
|
nsBodyFrame::~nsBodyFrame()
|
||||||
|
@ -88,42 +94,37 @@ nsBodyFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||||
// nsIFrame
|
// nsIFrame
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsBodyFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
nsBodyFrame::DeleteFrame(nsIPresContext& aPresContext)
|
||||||
nsIAtom* aListName,
|
|
||||||
nsIFrame* aChildList)
|
|
||||||
{
|
{
|
||||||
if (nsnull == mPrevInFlow) {
|
DeleteFrameList(aPresContext, &mAbsoluteFrames);
|
||||||
// Create a block frame and set its style context
|
return nsBlockFrame::DeleteFrame(aPresContext);
|
||||||
nsresult rv = NS_NewBlockFrame(mContent, this, mFirstChild, mFlags);
|
}
|
||||||
if (NS_OK != rv) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
mChildCount = 1;
|
|
||||||
nsIStyleContext* pseudoStyleContext =
|
|
||||||
aPresContext.ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::columnPseudo, mStyleContext);
|
|
||||||
mFirstChild->SetStyleContext(&aPresContext, pseudoStyleContext);
|
|
||||||
NS_RELEASE(pseudoStyleContext);
|
|
||||||
|
|
||||||
// Set the geometric and content parent for each of the child frames
|
NS_IMETHODIMP
|
||||||
for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) {
|
nsBodyFrame::GetAdditionalChildListName(PRInt32 aIndex,
|
||||||
frame->SetGeometricParent(mFirstChild);
|
nsIAtom*& aListName) const
|
||||||
frame->SetContentParent(mFirstChild);
|
{
|
||||||
}
|
if (aIndex < 0) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
// Queue up the frames for the block frame
|
|
||||||
return mFirstChild->SetInitialChildList(aPresContext, nsnull, aChildList);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// We have a prev-in-flow, so create a continuing block frame
|
|
||||||
nsBodyFrame* prevBodyFrame = (nsBodyFrame*)mPrevInFlow;
|
|
||||||
nsIStyleContext* blockStyleContext;
|
|
||||||
|
|
||||||
prevBodyFrame->mFirstChild->GetStyleContext(blockStyleContext);
|
|
||||||
prevBodyFrame->mFirstChild->CreateContinuingFrame(aPresContext, this,
|
|
||||||
blockStyleContext, mFirstChild);
|
|
||||||
NS_RELEASE(blockStyleContext);
|
|
||||||
return mFirstChild->SetInitialChildList(aPresContext, nsnull, nsnull);
|
|
||||||
}
|
}
|
||||||
|
nsIAtom* atom = nsnull;
|
||||||
|
if (0 == aIndex) {
|
||||||
|
atom = gAbsoluteAtom;
|
||||||
|
NS_ADDREF(atom);
|
||||||
|
}
|
||||||
|
aListName = atom;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsBodyFrame::FirstChild(nsIAtom* aListName, nsIFrame*& aFirstChild) const
|
||||||
|
{
|
||||||
|
if (aListName == gAbsoluteAtom) {
|
||||||
|
aFirstChild = mAbsoluteFrames;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsBlockFrame::FirstChild(aListName, aFirstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
|
@ -191,15 +192,17 @@ nsBodyFrame::BandData::ComputeAvailSpaceRect()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NS_DEBUG
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsBodyFrame::Paint(nsIPresContext& aPresContext,
|
nsBodyFrame::Paint(nsIPresContext& aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect)
|
const nsRect& aDirtyRect)
|
||||||
{
|
{
|
||||||
nsresult rv = nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext,
|
// Note: all absolutely positioned elements have views so we don't
|
||||||
aDirtyRect);
|
// need to worry about painting them
|
||||||
|
nsresult rv = nsBlockFrame::Paint(aPresContext, aRenderingContext,
|
||||||
|
aDirtyRect);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
|
||||||
if (nsIFrame::GetShowFrameBorders()) {
|
if (nsIFrame::GetShowFrameBorders()) {
|
||||||
// Render the bands in the spacemanager
|
// Render the bands in the spacemanager
|
||||||
BandData band;
|
BandData band;
|
||||||
|
@ -237,10 +240,10 @@ nsBodyFrame::Paint(nsIPresContext& aPresContext,
|
||||||
y = band.availSpace.YMost();
|
y = band.availSpace.YMost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsBodyFrame::Reflow(nsIPresContext& aPresContext,
|
nsBodyFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
|
@ -254,229 +257,94 @@ nsBodyFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
aReflowState.maxSize.height,
|
aReflowState.maxSize.height,
|
||||||
aReflowState.reason));
|
aReflowState.reason));
|
||||||
|
|
||||||
const nsHTMLReflowState* rsp = &aReflowState;
|
// Make a copy of the reflow state so we can set the space manager
|
||||||
nsHTMLReflowState resizeReflowState(aReflowState);
|
nsHTMLReflowState reflowState(aReflowState);
|
||||||
resizeReflowState.spaceManager = mSpaceManager;
|
reflowState.spaceManager = mSpaceManager;
|
||||||
|
|
||||||
aStatus = NS_FRAME_COMPLETE; // initialize out parameter
|
if (eReflowReason_Resize == reflowState.reason) {
|
||||||
|
// Clear any regions that are marked as unavailable
|
||||||
#if 0
|
// XXX Temporary hack until everything is incremental...
|
||||||
else {
|
mSpaceManager->ClearRegions();
|
||||||
NS_ASSERTION(eReflowReason_Initial != aReflowState.reason, "bad reason");
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
nsIFrame* reflowCmdTarget;
|
// XXX We need to peek at incremental reflow commands and see if the next
|
||||||
nsIReflowCommand::ReflowType reflowCmdType;
|
// frame is one of the absolutely positioned frames...
|
||||||
|
nsresult rv = nsBlockFrame::Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
|
||||||
|
|
||||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
// Reflow any absolutely positioned frames that need reflowing
|
||||||
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
|
// XXX We shouldn't really be doing this for all incremental reflow commands
|
||||||
|
ReflowAbsoluteItems(aPresContext, reflowState);
|
||||||
|
|
||||||
// Get the target and the type of reflow command
|
// Compute our desired size. Take into account any floaters when computing the
|
||||||
aReflowState.reflowCommand->GetTarget(reflowCmdTarget);
|
// height
|
||||||
aReflowState.reflowCommand->GetType(reflowCmdType);
|
if (mSpaceManager->YMost() > aDesiredSize.height) {
|
||||||
|
aDesiredSize.height = mSpaceManager->YMost();
|
||||||
|
}
|
||||||
|
|
||||||
if (this == reflowCmdTarget) {
|
// Also take into account absolutely positioned elements
|
||||||
NS_ASSERTION(nsIReflowCommand::FrameAppended == reflowCmdType,
|
const nsStyleDisplay* display= (const nsStyleDisplay*)
|
||||||
"unexpected reflow command");
|
mStyleContext->GetStyleData(eStyleStruct_Display);
|
||||||
|
|
||||||
// Append reflow commands will be targeted at us. Reset the target and
|
if (NS_STYLE_OVERFLOW_HIDDEN != display->mOverflow) {
|
||||||
// send the reflow command.
|
for (PRInt32 i = 0; i < mAbsoluteItems.Count(); i++) {
|
||||||
// XXX Would it be better to have the frame generate the reflow command
|
// Get the anchor frame
|
||||||
// that way it could correctly set the target?
|
nsAbsoluteFrame* anchorFrame = (nsAbsoluteFrame*)mAbsoluteItems[i];
|
||||||
reflowCmdTarget = mFirstChild;
|
nsIFrame* absoluteFrame = anchorFrame->GetAbsoluteFrame();
|
||||||
aReflowState.reflowCommand->SetTarget(mFirstChild);
|
nsRect rect;
|
||||||
|
|
||||||
// Reset the geometric and content parent for each of the child frames
|
absoluteFrame->GetRect(rect);
|
||||||
nsIFrame* childList;
|
nscoord xmost = rect.XMost();
|
||||||
aReflowState.reflowCommand->GetChildFrame(childList);
|
nscoord ymost = rect.YMost();
|
||||||
for (nsIFrame* frame = childList; nsnull != frame; frame->GetNextSibling(frame)) {
|
if (xmost > aDesiredSize.width) {
|
||||||
frame->SetGeometricParent(mFirstChild);
|
aDesiredSize.width = xmost;
|
||||||
frame->SetContentParent(mFirstChild);
|
|
||||||
}
|
}
|
||||||
}
|
if (ymost > aDesiredSize.height) {
|
||||||
|
aDesiredSize.height = ymost;
|
||||||
// The reflow command should never be target for us
|
|
||||||
#ifdef NS_DEBUG
|
|
||||||
NS_ASSERTION(this != reflowCmdTarget, "bad reflow command target");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Is the next frame in the reflow chain the pseudo block-frame or an
|
|
||||||
// absolutely positioned frame?
|
|
||||||
//
|
|
||||||
// If the next frame is the pseudo block-frame then fall thru to the main
|
|
||||||
// code below. The only thing that should be handled below is absolutely
|
|
||||||
// positioned elements...
|
|
||||||
nsIFrame* nextFrame;
|
|
||||||
aReflowState.reflowCommand->GetNext(nextFrame);
|
|
||||||
if ((nsnull != nextFrame) && (mFirstChild != nextFrame)) {
|
|
||||||
NS_ASSERTION(this != nextFrame, "huh?");
|
|
||||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
|
|
||||||
("nsBodyFrame::Reflow: reflowing frame=%p",
|
|
||||||
nextFrame));
|
|
||||||
// It's an absolutely positioned frame that's the target.
|
|
||||||
// XXX FIX ME. For an absolutely positioned item we need to properly
|
|
||||||
// compute the available space and compute the origin...
|
|
||||||
nsIHTMLReflow* reflow;
|
|
||||||
if (NS_OK == nextFrame->QueryInterface(kIHTMLReflowIID, (void**)&reflow)) {
|
|
||||||
nsHTMLReflowState reflowState(aPresContext, nextFrame, aReflowState,
|
|
||||||
aReflowState.maxSize);
|
|
||||||
reflowState.spaceManager = mSpaceManager;
|
|
||||||
reflow->WillReflow(aPresContext);
|
|
||||||
nsresult rv = reflow->Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
|
|
||||||
if (NS_OK != rv) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
nextFrame->SizeTo(aDesiredSize.width, aDesiredSize.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Commented this out because the absolute positioning code
|
|
||||||
// above doesn't check if it needs to position the absolute frame.
|
|
||||||
#if 0
|
|
||||||
// XXX Temporary code: if the frame we just reflowed is a
|
|
||||||
// floating frame then fall through into the main reflow pathway
|
|
||||||
// after clearing out our incremental reflow status. This forces
|
|
||||||
// our child to adjust to the new size of the floater.
|
|
||||||
//
|
|
||||||
// XXXX We shouldn't be here at all for floating frames, just for absolutely
|
|
||||||
// positioned frames. What's happening is that if a child of the body is
|
|
||||||
// floated then the reflow state path isn't getting set up correctly. The
|
|
||||||
// body's block pseudo-frame isn't getting included in the reflow path like
|
|
||||||
// it shoudld and that's why we end up here
|
|
||||||
const nsStyleDisplay* display;
|
|
||||||
nextFrame->GetStyleData(eStyleStruct_Display,
|
|
||||||
(const nsStyleStruct*&) display);
|
|
||||||
if (NS_STYLE_FLOAT_NONE == display->mFloats) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Switch over to a reflow-state that is called resize instead
|
|
||||||
// of an incremental reflow state like we were passed in.
|
|
||||||
resizeReflowState.reason = eReflowReason_Resize;
|
|
||||||
resizeReflowState.reflowCommand = nsnull;
|
|
||||||
rsp = &resizeReflowState;
|
|
||||||
|
|
||||||
// XXX End temporary code
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The area that needs to be repainted. Depends on the reflow type.
|
// XXX This code is really temporary; the lower level frame
|
||||||
|
// classes need to contribute to the area that needs damage
|
||||||
|
// repair. This class should only worry about damage repairing
|
||||||
|
// it's border+padding area.
|
||||||
nsRect damageArea(0, 0, 0, 0);
|
nsRect damageArea(0, 0, 0, 0);
|
||||||
|
|
||||||
// Reflow the child frame
|
// Decide how much to repaint based on the reflow type.
|
||||||
if (nsnull != mFirstChild) {
|
// Note: we don't have to handle the initial reflow case and the
|
||||||
// Get our border/padding info
|
// resize reflow case, because they're handled by the scroll frame
|
||||||
const nsStyleSpacing* mySpacing =
|
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||||
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
|
nsIReflowCommand::ReflowType reflowType;
|
||||||
nsMargin borderPadding;
|
aReflowState.reflowCommand->GetType(reflowType);
|
||||||
mySpacing->CalcBorderPaddingFor(this, borderPadding);
|
|
||||||
|
|
||||||
// Compute the child frame's max size
|
// For append reflow commands that target the flowed frames just
|
||||||
nsSize kidMaxSize = GetColumnAvailSpace(aPresContext, borderPadding,
|
// repaint the newly added part of the frame.
|
||||||
*rsp);
|
if (nsIReflowCommand::FrameAppended == reflowType) {
|
||||||
mSpaceManager->Translate(borderPadding.left, borderPadding.top);
|
// It's an append reflow command
|
||||||
|
damageArea.y = mRect.YMost();
|
||||||
if (eReflowReason_Resize == rsp->reason) {
|
damageArea.width = aDesiredSize.width;
|
||||||
// Clear any regions that are marked as unavailable
|
damageArea.height = aDesiredSize.height - mRect.height;
|
||||||
// XXX Temporary hack until everything is incremental...
|
if (aDesiredSize.height == mRect.height) {
|
||||||
mSpaceManager->ClearRegions();
|
// Since we don't know what changed, assume it all changed.
|
||||||
}
|
damageArea.y = 0;
|
||||||
|
|
||||||
// Get the child's current rect
|
|
||||||
nsRect kidOldRect;
|
|
||||||
mFirstChild->GetRect(kidOldRect);
|
|
||||||
|
|
||||||
// Get the column's desired size
|
|
||||||
nsHTMLReflowState reflowState(aPresContext, mFirstChild, *rsp, kidMaxSize);
|
|
||||||
reflowState.spaceManager = mSpaceManager;
|
|
||||||
nsIHTMLReflow* htmlReflow;
|
|
||||||
|
|
||||||
if (NS_OK == mFirstChild->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) {
|
|
||||||
htmlReflow->WillReflow(aPresContext);
|
|
||||||
htmlReflow->Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the frame is complete, then check whether there's a next-in-flow that
|
|
||||||
// needs to be deleted
|
|
||||||
if (NS_FRAME_IS_COMPLETE(aStatus)) {
|
|
||||||
nsIFrame* kidNextInFlow;
|
|
||||||
|
|
||||||
mFirstChild->GetNextInFlow(kidNextInFlow);
|
|
||||||
if (nsnull != kidNextInFlow) {
|
|
||||||
// Remove all of the childs next-in-flows
|
|
||||||
DeleteChildsNextInFlow(aPresContext, mFirstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mSpaceManager->Translate(-borderPadding.left, -borderPadding.top);
|
|
||||||
|
|
||||||
// Place and size the frame
|
|
||||||
nsRect desiredRect(borderPadding.left, borderPadding.top,
|
|
||||||
aDesiredSize.width, aDesiredSize.height);
|
|
||||||
mFirstChild->SetRect(desiredRect);
|
|
||||||
|
|
||||||
// Reflow any absolutely positioned frames that need reflowing
|
|
||||||
ReflowAbsoluteItems(aPresContext, *rsp);
|
|
||||||
|
|
||||||
// Return our desired size
|
|
||||||
ComputeDesiredSize(aPresContext, aReflowState, desiredRect,
|
|
||||||
rsp->maxSize, borderPadding, aDesiredSize);
|
|
||||||
|
|
||||||
// XXX This code is really temporary; the lower level frame
|
|
||||||
// classes need to contribute to the area that needs damage
|
|
||||||
// repair. This class should only worry about damage repairing
|
|
||||||
// it's border+padding area.
|
|
||||||
|
|
||||||
// Decide how much to repaint based on the reflow type.
|
|
||||||
// Note: we don't have to handle the initial reflow case and the
|
|
||||||
// resize reflow case, because they're handled by the root content
|
|
||||||
// frame
|
|
||||||
if (eReflowReason_Incremental == rsp->reason) {
|
|
||||||
// For append reflow commands that target the body just repaint the newly
|
|
||||||
// added part of the frame.
|
|
||||||
if ((nsIReflowCommand::FrameAppended == reflowCmdType) &&
|
|
||||||
(reflowCmdTarget == mFirstChild)) {
|
|
||||||
// It's an append reflow command targeted at us
|
|
||||||
damageArea.y = kidOldRect.YMost();
|
|
||||||
damageArea.width = aDesiredSize.width;
|
|
||||||
damageArea.height = aDesiredSize.height - kidOldRect.height;
|
|
||||||
if (desiredRect.height == kidOldRect.height) {
|
|
||||||
// Since we don't know what changed, assume it all changed.
|
|
||||||
damageArea.y = 0;
|
|
||||||
damageArea.height = aDesiredSize.height;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Ideally the frame that is the target of the reflow command
|
|
||||||
// (or its parent frame) would generate a damage rect, but
|
|
||||||
// since none of the frame classes know how to do this then
|
|
||||||
// for the time being just repaint the entire frame
|
|
||||||
damageArea.width = aDesiredSize.width;
|
|
||||||
damageArea.height = aDesiredSize.height;
|
damageArea.height = aDesiredSize.height;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
// Ideally the frame that is the target of the reflow command
|
||||||
}
|
// (or its parent frame) would generate a damage rect, but
|
||||||
else {
|
// since none of the frame classes know how to do this then
|
||||||
aDesiredSize.width = 0;
|
// for the time being just repaint the entire frame
|
||||||
aDesiredSize.height = 0;
|
damageArea.width = aDesiredSize.width;
|
||||||
aDesiredSize.ascent = 0;
|
damageArea.height = aDesiredSize.height;
|
||||||
aDesiredSize.descent = 0;
|
|
||||||
if (nsnull != aDesiredSize.maxElementSize) {
|
|
||||||
aDesiredSize.maxElementSize->width = 0;
|
|
||||||
aDesiredSize.maxElementSize->height = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is really The Body, we force a repaint of the damage area
|
// If this is really the body, force a repaint of the damage area
|
||||||
if ((NS_BODY_THE_BODY & mFlags) && !damageArea.IsEmpty()) {
|
if ((NS_BODY_THE_BODY & mFlags) && !damageArea.IsEmpty()) {
|
||||||
Invalidate(damageArea);
|
Invalidate(damageArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
|
return rv;
|
||||||
("exit nsBodyFrame::Reflow: status=%d width=%d height=%d",
|
|
||||||
aStatus, aDesiredSize.width, aDesiredSize.height));
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_METHOD
|
NS_METHOD
|
||||||
|
@ -490,7 +358,6 @@ nsBodyFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
PrepareContinuingFrame(aPresContext, aParent, aStyleContext, cf);
|
PrepareContinuingFrame(aPresContext, aParent, aStyleContext, cf);
|
||||||
cf->SetInitialChildList(aPresContext, nsnull, nsnull);
|
|
||||||
aContinuingFrame = cf;
|
aContinuingFrame = cf;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -609,115 +476,18 @@ nsBodyFrame::DidSetStyleContext(nsIPresContext* aPresContext)
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Helper functions
|
// Helper functions
|
||||||
|
|
||||||
nsSize
|
|
||||||
nsBodyFrame::GetColumnAvailSpace(nsIPresContext& aPresContext,
|
|
||||||
const nsMargin& aBorderPadding,
|
|
||||||
const nsHTMLReflowState& aReflowState)
|
|
||||||
{
|
|
||||||
nsSize result(aReflowState.maxSize);
|
|
||||||
|
|
||||||
// If we are being used as a top-level frame then make adjustments
|
|
||||||
// for border/padding and a vertical scrollbar
|
|
||||||
if (NS_BODY_THE_BODY & mFlags) {
|
|
||||||
// If our width is constrained then subtract for the border/padding
|
|
||||||
if (aReflowState.maxSize.width != NS_UNCONSTRAINEDSIZE) {
|
|
||||||
result.width -= aBorderPadding.left + aBorderPadding.right;
|
|
||||||
}
|
|
||||||
// If our height is constrained then subtract for the border/padding
|
|
||||||
if (aReflowState.maxSize.height != NS_UNCONSTRAINEDSIZE) {
|
|
||||||
result.height -= aBorderPadding.top + aBorderPadding.bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (aReflowState.HaveFixedContentWidth()) {
|
|
||||||
result.width = aReflowState.minWidth +
|
|
||||||
aBorderPadding.left + aBorderPadding.right;
|
|
||||||
}
|
|
||||||
if (aReflowState.HaveFixedContentHeight()) {
|
|
||||||
result.height -= aBorderPadding.top + aBorderPadding.bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
|
|
||||||
(": nsBodyFrame: columnAvailSpace=%d,%d [%s,%s]\n",
|
|
||||||
result.width, result.height,
|
|
||||||
eHTMLFrameConstraint_Unconstrained == aReflowState.widthConstraint
|
|
||||||
? "not-constrained" : "constrained",
|
|
||||||
eHTMLFrameConstraint_Unconstrained == aReflowState.heightConstraint
|
|
||||||
? "not-constrained" : "constrained"));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsBodyFrame::ComputeDesiredSize(nsIPresContext& aPresContext,
|
|
||||||
const nsHTMLReflowState& aReflowState,
|
|
||||||
const nsRect& aDesiredRect,
|
|
||||||
const nsSize& aMaxSize,
|
|
||||||
const nsMargin& aBorderPadding,
|
|
||||||
nsHTMLReflowMetrics& aMetrics)
|
|
||||||
{
|
|
||||||
// Note: Body used as a pseudo-frame shrink wraps (unless of course
|
|
||||||
// style says otherwise)
|
|
||||||
nscoord height = PR_MAX(aDesiredRect.YMost(), mSpaceManager->YMost());
|
|
||||||
nscoord width = aDesiredRect.XMost();
|
|
||||||
|
|
||||||
// Take into account absolutely positioned elements when computing the
|
|
||||||
// desired size
|
|
||||||
for (PRInt32 i = 0; i < mAbsoluteItems.Count(); i++) {
|
|
||||||
// Get the anchor frame
|
|
||||||
nsAbsoluteFrame* anchorFrame = (nsAbsoluteFrame*)mAbsoluteItems[i];
|
|
||||||
nsIFrame* absoluteFrame = anchorFrame->GetAbsoluteFrame();
|
|
||||||
nsRect rect;
|
|
||||||
|
|
||||||
absoluteFrame->GetRect(rect);
|
|
||||||
nscoord xmost = rect.XMost();
|
|
||||||
nscoord ymost = rect.YMost();
|
|
||||||
if (xmost > width) {
|
|
||||||
width = xmost;
|
|
||||||
}
|
|
||||||
if (ymost > height) {
|
|
||||||
height = ymost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply style size if present; XXX note the inner value (style-size -
|
|
||||||
// border+padding) should be given to the child as a max-size
|
|
||||||
if (aReflowState.HaveFixedContentWidth()) {
|
|
||||||
width = aReflowState.minWidth + aBorderPadding.left + aBorderPadding.right;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((0 == (NS_BODY_SHRINK_WRAP & mFlags)) &&
|
|
||||||
(NS_UNCONSTRAINEDSIZE != aMaxSize.width)) {
|
|
||||||
// Make sure we're at least as wide as our available width
|
|
||||||
if (aMaxSize.width > width) {
|
|
||||||
width = aMaxSize.width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (aReflowState.HaveFixedContentHeight()) {
|
|
||||||
height = aReflowState.minHeight +
|
|
||||||
aBorderPadding.top + aBorderPadding.bottom;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// aBorderPadding.top is already reflected in the
|
|
||||||
// aDesiredRect.YMost() value.
|
|
||||||
height += aBorderPadding.bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
aMetrics.width = width;
|
|
||||||
aMetrics.height = height;
|
|
||||||
aMetrics.ascent = height;
|
|
||||||
aMetrics.descent = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the frame to the end of the child list
|
// Add the frame to the end of the child list
|
||||||
void nsBodyFrame::AddAbsoluteFrame(nsIFrame* aFrame)
|
void nsBodyFrame::AddAbsoluteFrame(nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
nsIFrame* lastChild = LastFrame(mFirstChild);
|
if (nsnull == mAbsoluteFrames) {
|
||||||
|
mAbsoluteFrames = aFrame;
|
||||||
|
} else {
|
||||||
|
nsIFrame* lastChild = LastFrame(mAbsoluteFrames);
|
||||||
|
|
||||||
lastChild->SetNextSibling(aFrame);
|
lastChild->SetNextSibling(aFrame);
|
||||||
aFrame->SetNextSibling(nsnull);
|
aFrame->SetNextSibling(nsnull);
|
||||||
mChildCount++;
|
// XXX Eliminate mChildCount...
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -728,33 +498,7 @@ nsBodyFrame::HandleEvent(nsIPresContext& aPresContext,
|
||||||
nsGUIEvent* aEvent,
|
nsGUIEvent* aEvent,
|
||||||
nsEventStatus& aEventStatus)
|
nsEventStatus& aEventStatus)
|
||||||
{
|
{
|
||||||
aEventStatus = nsEventStatus_eIgnore;
|
nsBlockFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
|
|
||||||
// Pass event down to our children. Give it to the children after
|
|
||||||
// our first-child first (children after the first-child are either
|
|
||||||
// absolute positioned frames or are floating frames, both of which
|
|
||||||
// are on top (in the z order) of the first-child).
|
|
||||||
|
|
||||||
/*XXX Commenting event dispatch to BodyFrame's absolutely positioned
|
|
||||||
* children. They already get the event through the view hierarchy.
|
|
||||||
*/
|
|
||||||
/*PRInt32 n = mChildCount;*/
|
|
||||||
nsIFrame* kid = mFirstChild;
|
|
||||||
/*kid->GetNextSibling(kid);
|
|
||||||
while (--n >= 0) {
|
|
||||||
if (nsnull == kid) {
|
|
||||||
kid = mFirstChild;
|
|
||||||
}*/
|
|
||||||
nsRect kidRect;
|
|
||||||
kid->GetRect(kidRect);
|
|
||||||
if (kidRect.Contains(aEvent->point)) {
|
|
||||||
aEvent->point.MoveBy(-kidRect.x, -kidRect.y);
|
|
||||||
kid->HandleEvent(aPresContext, aEvent, aEventStatus);
|
|
||||||
aEvent->point.MoveBy(kidRect.x, kidRect.y);
|
|
||||||
/*break;*/
|
|
||||||
}
|
|
||||||
/*kid->GetNextSibling(kid);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// XXX Hack mouse enter/exit and cursor code. THIS DOESN'T BELONG HERE!
|
// XXX Hack mouse enter/exit and cursor code. THIS DOESN'T BELONG HERE!
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -857,36 +601,6 @@ nsBodyFrame::HandleEvent(nsIPresContext& aPresContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsBodyFrame::GetCursorAndContentAt(nsIPresContext& aPresContext,
|
|
||||||
const nsPoint& aPoint,
|
|
||||||
nsIFrame** aFrame,
|
|
||||||
nsIContent** aContent,
|
|
||||||
PRInt32& aCursor)
|
|
||||||
{
|
|
||||||
aCursor = NS_STYLE_CURSOR_INHERIT;
|
|
||||||
*aContent = mContent;
|
|
||||||
|
|
||||||
nsPoint tmp;
|
|
||||||
PRInt32 n = mChildCount;
|
|
||||||
nsIFrame* kid = mFirstChild;
|
|
||||||
kid->GetNextSibling(kid);
|
|
||||||
while (--n >= 0) {
|
|
||||||
if (nsnull == kid) {
|
|
||||||
kid = mFirstChild;
|
|
||||||
}
|
|
||||||
nsRect kidRect;
|
|
||||||
kid->GetRect(kidRect);
|
|
||||||
if (kidRect.Contains(aPoint)) {
|
|
||||||
tmp.MoveTo(aPoint.x - kidRect.x, aPoint.y - kidRect.y);
|
|
||||||
kid->GetCursorAndContentAt(aPresContext, tmp, aFrame, aContent, aCursor);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
kid->GetNextSibling(kid);
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// nsIAbsoluteItems
|
// nsIAbsoluteItems
|
||||||
|
|
||||||
|
@ -898,6 +612,19 @@ NS_METHOD nsBodyFrame::AddAbsoluteItem(nsAbsoluteFrame* aAnchorFrame)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsBodyFrame::IsAbsoluteFrame(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
// Check whether the frame is in our list of absolutely positioned frames
|
||||||
|
for (nsIFrame* f = mAbsoluteFrames; nsnull != f; f->GetNextSibling(f)) {
|
||||||
|
if (f == aFrame) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
NS_METHOD nsBodyFrame::RemoveAbsoluteItem(nsAbsoluteFrame* aAnchorFrame)
|
NS_METHOD nsBodyFrame::RemoveAbsoluteItem(nsAbsoluteFrame* aAnchorFrame)
|
||||||
{
|
{
|
||||||
NS_NOTYETIMPLEMENTED("removing an absolutely positioned frame");
|
NS_NOTYETIMPLEMENTED("removing an absolutely positioned frame");
|
||||||
|
@ -926,9 +653,7 @@ nsBodyFrame::ReflowAbsoluteItems(nsIPresContext& aPresContext,
|
||||||
absoluteFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)position);
|
absoluteFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)position);
|
||||||
|
|
||||||
// See whether the frame is a newly added frame
|
// See whether the frame is a newly added frame
|
||||||
nsIFrame* parent;
|
if (!IsAbsoluteFrame(absoluteFrame)) {
|
||||||
absoluteFrame->GetGeometricParent(parent);
|
|
||||||
if (parent != this) {
|
|
||||||
// The absolutely position item hasn't yet been added to our child list
|
// The absolutely position item hasn't yet been added to our child list
|
||||||
absoluteFrame->SetGeometricParent(this);
|
absoluteFrame->SetGeometricParent(this);
|
||||||
|
|
||||||
|
@ -1227,22 +952,6 @@ void nsBodyFrame::ComputeAbsoluteFrameBounds(nsIFrame* aAnchorFra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsHTMLContainerFrame
|
|
||||||
|
|
||||||
// XXX use same logic as block frame?
|
|
||||||
PRIntn nsBodyFrame::GetSkipSides() const
|
|
||||||
{
|
|
||||||
PRIntn skip = 0;
|
|
||||||
if (nsnull != mPrevInFlow) {
|
|
||||||
skip |= 1 << NS_SIDE_TOP;
|
|
||||||
}
|
|
||||||
if (nsnull != mNextInFlow) {
|
|
||||||
skip |= 1 << NS_SIDE_BOTTOM;
|
|
||||||
}
|
|
||||||
return skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Diagnostics
|
// Diagnostics
|
||||||
|
|
||||||
|
@ -1263,6 +972,27 @@ nsBodyFrame::ListTag(FILE* out) const
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsBodyFrame::List(FILE* out, PRInt32 aIndent, nsIListFilter* aFilter) const
|
||||||
|
{
|
||||||
|
nsresult rv = nsBlockFrame::List(out, aIndent, aFilter);
|
||||||
|
|
||||||
|
// Output absolutely positioned frames
|
||||||
|
if (nsnull != mAbsoluteFrames) {
|
||||||
|
for (PRInt32 i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
|
fprintf(out, "absolute-items <\n");
|
||||||
|
}
|
||||||
|
nsIFrame* f = mAbsoluteFrames;
|
||||||
|
while (nsnull != f) {
|
||||||
|
f->List(out, aIndent+1, aFilter);
|
||||||
|
f->GetNextSibling(f);
|
||||||
|
}
|
||||||
|
for (PRInt32 i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||||
|
fputs(">\n", out);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
NS_METHOD nsBodyFrame::VerifyTree() const
|
NS_METHOD nsBodyFrame::VerifyTree() const
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#ifndef nsBodyFrame_h___
|
#ifndef nsBodyFrame_h___
|
||||||
#define nsBodyFrame_h___
|
#define nsBodyFrame_h___
|
||||||
|
|
||||||
#include "nsHTMLContainerFrame.h"
|
#include "nsBlockFrame.h"
|
||||||
#include "nsIAbsoluteItems.h"
|
#include "nsIAbsoluteItems.h"
|
||||||
#include "nsISpaceManager.h"
|
#include "nsISpaceManager.h"
|
||||||
#include "nsVoidArray.h"
|
#include "nsVoidArray.h"
|
||||||
|
@ -28,7 +28,7 @@ class nsSpaceManager;
|
||||||
struct nsStyleDisplay;
|
struct nsStyleDisplay;
|
||||||
struct nsStylePosition;
|
struct nsStylePosition;
|
||||||
|
|
||||||
class nsBodyFrame : public nsHTMLContainerFrame,
|
class nsBodyFrame : public nsBlockFrame,
|
||||||
public nsIAbsoluteItems
|
public nsIAbsoluteItems
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -37,34 +37,35 @@ public:
|
||||||
|
|
||||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||||
|
|
||||||
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
|
NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
|
||||||
nsIAtom* aListName,
|
|
||||||
nsIFrame* aChildList);
|
NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex,
|
||||||
|
nsIAtom*& aListName) const;
|
||||||
|
|
||||||
|
NS_IMETHOD FirstChild(nsIAtom* aListName, nsIFrame*& aFirstChild) const;
|
||||||
|
|
||||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||||
nsHTMLReflowMetrics& aDesiredSize,
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
|
||||||
|
#ifdef NS_DEBUG
|
||||||
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
NS_IMETHOD Paint(nsIPresContext& aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect);
|
const nsRect& aDirtyRect);
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
|
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aPresContext,
|
||||||
nsIFrame* aParent,
|
nsIFrame* aParent,
|
||||||
nsIStyleContext* aStyleContext,
|
nsIStyleContext* aStyleContext,
|
||||||
nsIFrame*& aContinuingFrame);
|
nsIFrame*& aContinuingFrame);
|
||||||
|
|
||||||
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
|
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
|
||||||
nsGUIEvent* aEvent,
|
nsGUIEvent* aEvent,
|
||||||
nsEventStatus& aEventStatus);
|
nsEventStatus& aEventStatus);
|
||||||
|
|
||||||
NS_IMETHOD GetCursorAndContentAt(nsIPresContext& aPresContext,
|
|
||||||
const nsPoint& aPoint,
|
|
||||||
nsIFrame** aFrame,
|
|
||||||
nsIContent** aContent,
|
|
||||||
PRInt32& aCursor);
|
|
||||||
|
|
||||||
NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext);
|
NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext);
|
||||||
|
NS_METHOD List(FILE* out, PRInt32 aIndent, nsIListFilter* aFilter) const;
|
||||||
NS_IMETHOD ListTag(FILE* out) const;
|
NS_IMETHOD ListTag(FILE* out) const;
|
||||||
|
|
||||||
// nsIAbsoluteItems
|
// nsIAbsoluteItems
|
||||||
|
@ -75,6 +76,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PRUint32 mFlags;
|
PRUint32 mFlags;
|
||||||
|
static nsIAtom* gAbsoluteAtom;
|
||||||
|
|
||||||
void SetFlags(PRUint32 aFlags) {
|
void SetFlags(PRUint32 aFlags) {
|
||||||
mFlags = aFlags;
|
mFlags = aFlags;
|
||||||
|
@ -84,15 +86,6 @@ protected:
|
||||||
|
|
||||||
~nsBodyFrame();
|
~nsBodyFrame();
|
||||||
|
|
||||||
void ComputeDesiredSize(nsIPresContext& aPresContext,
|
|
||||||
const nsHTMLReflowState& aReflowState,
|
|
||||||
const nsRect& aDesiredRect,
|
|
||||||
const nsSize& aMaxSize,
|
|
||||||
const nsMargin& aBorderPadding,
|
|
||||||
nsHTMLReflowMetrics& aDesiredSize);
|
|
||||||
|
|
||||||
virtual PRIntn GetSkipSides() const;
|
|
||||||
|
|
||||||
void ReflowAbsoluteItems(nsIPresContext& aPresContext,
|
void ReflowAbsoluteItems(nsIPresContext& aPresContext,
|
||||||
const nsHTMLReflowState& aReflowState);
|
const nsHTMLReflowState& aReflowState);
|
||||||
|
|
||||||
|
@ -106,16 +99,14 @@ protected:
|
||||||
nsRect& aRect) const;
|
nsRect& aRect) const;
|
||||||
|
|
||||||
void AddAbsoluteFrame(nsIFrame* aFrame);
|
void AddAbsoluteFrame(nsIFrame* aFrame);
|
||||||
|
PRBool IsAbsoluteFrame(nsIFrame* aFrame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsSpaceManager* mSpaceManager;
|
nsSpaceManager* mSpaceManager;
|
||||||
nsVoidArray mAbsoluteItems;
|
nsVoidArray mAbsoluteItems;
|
||||||
|
nsIFrame* mAbsoluteFrames; // additional named child list
|
||||||
PRInt32 mChildCount;
|
PRInt32 mChildCount;
|
||||||
|
|
||||||
nsSize GetColumnAvailSpace(nsIPresContext& aPresContext,
|
|
||||||
const nsMargin& aBorderPadding,
|
|
||||||
const nsHTMLReflowState& aReflowState);
|
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
struct BandData : public nsBandData {
|
struct BandData : public nsBandData {
|
||||||
// Trapezoids used during band processing
|
// Trapezoids used during band processing
|
||||||
|
|
Загрузка…
Ссылка в новой задаче