mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-06 06:22:33 +00:00
Work-in-progress for making relatively positioned inline-level elements a
container for absolutely positioned child elements
This commit is contained in:
parent
d724778c32
commit
bfd8240682
@ -2918,12 +2918,18 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
|
||||
floaterList.childList);
|
||||
}
|
||||
}
|
||||
// See if it's a relatively positioned block
|
||||
else if ((NS_STYLE_POSITION_RELATIVE == position->mPosition) &&
|
||||
((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay))) {
|
||||
// See if it's relatively positioned
|
||||
else if (NS_STYLE_POSITION_RELATIVE == position->mPosition) {
|
||||
// Is it block-level or inline-level?
|
||||
if (NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) {
|
||||
// Create an area frame. No space manager, though
|
||||
NS_NewAreaFrame(newFrame, NS_AREA_NO_SPACE_MGR);
|
||||
} else {
|
||||
// Create a positioned inline frame
|
||||
NS_NewPositionedInlineFrame(newFrame);
|
||||
}
|
||||
|
||||
// Create an area frame. No space manager, though
|
||||
NS_NewAreaFrame(newFrame, NS_AREA_NO_SPACE_MGR);
|
||||
// Initialize the frame
|
||||
newFrame->Init(*aPresContext, aContent, aParentFrame, aStyleContext, nsnull);
|
||||
|
||||
// Create a view
|
||||
@ -2935,8 +2941,15 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
|
||||
nsAbsoluteItems absoluteItems(newFrame);
|
||||
nsAbsoluteItems floaterList(newFrame);
|
||||
nsFrameItems childItems;
|
||||
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
|
||||
childItems, aFixedItems, floaterList, PR_TRUE);
|
||||
|
||||
if (NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) {
|
||||
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
|
||||
childItems, aFixedItems, floaterList, PR_TRUE);
|
||||
|
||||
} else {
|
||||
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
|
||||
childItems, aFixedItems, aFloatingItems, PR_TRUE);
|
||||
}
|
||||
|
||||
// Set the frame's initial child list
|
||||
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
|
||||
|
@ -258,6 +258,7 @@ extern nsresult NS_NewViewportFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewRootFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewImageFrame(nsIFrame*& aFrameResult);
|
||||
extern nsresult NS_NewInlineFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewPositionedInlineFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewObjectFrame(nsIFrame*& aFrameResult);
|
||||
extern nsresult NS_NewSpacerFrame(nsIFrame*& aResult);
|
||||
extern nsresult NS_NewTextFrame(nsIFrame*& aResult);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
// XXX TODO:
|
||||
// append/insert/remove floater testing
|
||||
@ -190,6 +192,135 @@ protected:
|
||||
nsReflowStatus& aStatus);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Derived class created for relatively positioned inline-level elements
|
||||
// that acts as a containing block for child absolutely positioned
|
||||
// elements
|
||||
|
||||
class nsPositionedInlineFrame : public nsInlineFrame
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
|
||||
|
||||
NS_IMETHOD SetInitialChildList(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,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
protected:
|
||||
nsAbsoluteContainingBlock mAbsoluteContainer;
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_NewPositionedInlineFrame(nsIFrame*& aNewFrame)
|
||||
{
|
||||
nsPositionedInlineFrame* it = new nsPositionedInlineFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::DeleteFrame(nsIPresContext& aPresContext)
|
||||
{
|
||||
mAbsoluteContainer.DeleteFrames(aPresContext);
|
||||
return nsInlineFrame::DeleteFrame(aPresContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (nsLayoutAtoms::absoluteList == aListName) {
|
||||
rv = mAbsoluteContainer.SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
} else {
|
||||
rv = nsInlineFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::GetAdditionalChildListName(PRInt32 aIndex,
|
||||
nsIAtom** aListName) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aListName, "null OUT parameter pointer");
|
||||
*aListName = nsnull;
|
||||
if (0 == aIndex) {
|
||||
*aListName = nsLayoutAtoms::absoluteList;
|
||||
NS_ADDREF(*aListName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer");
|
||||
if (aListName == nsLayoutAtoms::absoluteList) {
|
||||
return mAbsoluteContainer.FirstChild(aListName, aFirstChild);
|
||||
}
|
||||
|
||||
return nsInlineFrame::FirstChild(aListName, aFirstChild);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// See if it's an incremental reflow command
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
// Give the absolute positioning code a chance to handle it
|
||||
PRBool handled;
|
||||
|
||||
mAbsoluteContainer.IncrementalReflow(aPresContext, aReflowState, handled);
|
||||
|
||||
// If the incremental reflow command was handled by the absolute positioning
|
||||
// code, then we're all done
|
||||
if (handled) {
|
||||
// Just return our current size as our desired size
|
||||
aDesiredSize.width = mRect.width;
|
||||
aDesiredSize.height = mRect.height;
|
||||
// XXX This isn't correct...
|
||||
aDesiredSize.ascent = mRect.height;
|
||||
aDesiredSize.descent = 0;
|
||||
|
||||
// Whether or not we're complete hasn't changed
|
||||
aStatus = (nsnull != mNextInFlow) ? NS_FRAME_NOT_COMPLETE : NS_FRAME_COMPLETE;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Let the inline frame do its reflow first
|
||||
rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
|
||||
// Let the absolutely positioned container reflow any absolutely positioned
|
||||
// child frames that need to be reflowed
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// SectionData implementation
|
||||
|
||||
|
@ -258,6 +258,7 @@ extern nsresult NS_NewViewportFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewRootFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewImageFrame(nsIFrame*& aFrameResult);
|
||||
extern nsresult NS_NewInlineFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewPositionedInlineFrame(nsIFrame*& aNewFrame);
|
||||
extern nsresult NS_NewObjectFrame(nsIFrame*& aFrameResult);
|
||||
extern nsresult NS_NewSpacerFrame(nsIFrame*& aResult);
|
||||
extern nsresult NS_NewTextFrame(nsIFrame*& aResult);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
// XXX TODO:
|
||||
// append/insert/remove floater testing
|
||||
@ -190,6 +192,135 @@ protected:
|
||||
nsReflowStatus& aStatus);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Derived class created for relatively positioned inline-level elements
|
||||
// that acts as a containing block for child absolutely positioned
|
||||
// elements
|
||||
|
||||
class nsPositionedInlineFrame : public nsInlineFrame
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext);
|
||||
|
||||
NS_IMETHOD SetInitialChildList(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,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
protected:
|
||||
nsAbsoluteContainingBlock mAbsoluteContainer;
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_NewPositionedInlineFrame(nsIFrame*& aNewFrame)
|
||||
{
|
||||
nsPositionedInlineFrame* it = new nsPositionedInlineFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::DeleteFrame(nsIPresContext& aPresContext)
|
||||
{
|
||||
mAbsoluteContainer.DeleteFrames(aPresContext);
|
||||
return nsInlineFrame::DeleteFrame(aPresContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (nsLayoutAtoms::absoluteList == aListName) {
|
||||
rv = mAbsoluteContainer.SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
} else {
|
||||
rv = nsInlineFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::GetAdditionalChildListName(PRInt32 aIndex,
|
||||
nsIAtom** aListName) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aListName, "null OUT parameter pointer");
|
||||
*aListName = nsnull;
|
||||
if (0 == aIndex) {
|
||||
*aListName = nsLayoutAtoms::absoluteList;
|
||||
NS_ADDREF(*aListName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aFirstChild, "null OUT parameter pointer");
|
||||
if (aListName == nsLayoutAtoms::absoluteList) {
|
||||
return mAbsoluteContainer.FirstChild(aListName, aFirstChild);
|
||||
}
|
||||
|
||||
return nsInlineFrame::FirstChild(aListName, aFirstChild);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPositionedInlineFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// See if it's an incremental reflow command
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
// Give the absolute positioning code a chance to handle it
|
||||
PRBool handled;
|
||||
|
||||
mAbsoluteContainer.IncrementalReflow(aPresContext, aReflowState, handled);
|
||||
|
||||
// If the incremental reflow command was handled by the absolute positioning
|
||||
// code, then we're all done
|
||||
if (handled) {
|
||||
// Just return our current size as our desired size
|
||||
aDesiredSize.width = mRect.width;
|
||||
aDesiredSize.height = mRect.height;
|
||||
// XXX This isn't correct...
|
||||
aDesiredSize.ascent = mRect.height;
|
||||
aDesiredSize.descent = 0;
|
||||
|
||||
// Whether or not we're complete hasn't changed
|
||||
aStatus = (nsnull != mNextInFlow) ? NS_FRAME_NOT_COMPLETE : NS_FRAME_COMPLETE;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Let the inline frame do its reflow first
|
||||
rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
|
||||
// Let the absolutely positioned container reflow any absolutely positioned
|
||||
// child frames that need to be reflowed
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// SectionData implementation
|
||||
|
||||
|
@ -2918,12 +2918,18 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
|
||||
floaterList.childList);
|
||||
}
|
||||
}
|
||||
// See if it's a relatively positioned block
|
||||
else if ((NS_STYLE_POSITION_RELATIVE == position->mPosition) &&
|
||||
((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay))) {
|
||||
// See if it's relatively positioned
|
||||
else if (NS_STYLE_POSITION_RELATIVE == position->mPosition) {
|
||||
// Is it block-level or inline-level?
|
||||
if (NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) {
|
||||
// Create an area frame. No space manager, though
|
||||
NS_NewAreaFrame(newFrame, NS_AREA_NO_SPACE_MGR);
|
||||
} else {
|
||||
// Create a positioned inline frame
|
||||
NS_NewPositionedInlineFrame(newFrame);
|
||||
}
|
||||
|
||||
// Create an area frame. No space manager, though
|
||||
NS_NewAreaFrame(newFrame, NS_AREA_NO_SPACE_MGR);
|
||||
// Initialize the frame
|
||||
newFrame->Init(*aPresContext, aContent, aParentFrame, aStyleContext, nsnull);
|
||||
|
||||
// Create a view
|
||||
@ -2935,8 +2941,15 @@ nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresContext* aPresCo
|
||||
nsAbsoluteItems absoluteItems(newFrame);
|
||||
nsAbsoluteItems floaterList(newFrame);
|
||||
nsFrameItems childItems;
|
||||
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
|
||||
childItems, aFixedItems, floaterList, PR_TRUE);
|
||||
|
||||
if (NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) {
|
||||
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
|
||||
childItems, aFixedItems, floaterList, PR_TRUE);
|
||||
|
||||
} else {
|
||||
ProcessChildren(aPresContext, aContent, newFrame, absoluteItems,
|
||||
childItems, aFixedItems, aFloatingItems, PR_TRUE);
|
||||
}
|
||||
|
||||
// Set the frame's initial child list
|
||||
newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList);
|
||||
|
Loading…
x
Reference in New Issue
Block a user