Bug 230417. When a placeholder frame lands in a block's overflowList, put its out of flow frame in a new child list, overflowOutOfFlowsList
This commit is contained in:
@@ -82,6 +82,7 @@ LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
|
|||||||
LAYOUT_ATOM(fixedList, "Fixed-list")
|
LAYOUT_ATOM(fixedList, "Fixed-list")
|
||||||
LAYOUT_ATOM(floatList, "Float-list")
|
LAYOUT_ATOM(floatList, "Float-list")
|
||||||
LAYOUT_ATOM(overflowList, "Overflow-list")
|
LAYOUT_ATOM(overflowList, "Overflow-list")
|
||||||
|
LAYOUT_ATOM(overflowOutOfFlowList, "OverflowOutOfFlow-list")
|
||||||
LAYOUT_ATOM(popupList, "Popup-list")
|
LAYOUT_ATOM(popupList, "Popup-list")
|
||||||
|
|
||||||
LAYOUT_ATOM(commentTagName, "__moz_comment")
|
LAYOUT_ATOM(commentTagName, "__moz_comment")
|
||||||
@@ -139,6 +140,7 @@ LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*
|
|||||||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||||
|
LAYOUT_ATOM(overflowOutOfFlowsProperty, "OverflowOutOfFlowsProperty") // nsFrameList*
|
||||||
LAYOUT_ATOM(overflowPlaceholdersProperty, "OverflowPlaceholdersProperty") // nsPlaceholder*
|
LAYOUT_ATOM(overflowPlaceholdersProperty, "OverflowPlaceholdersProperty") // nsPlaceholder*
|
||||||
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
||||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
|
|||||||
LAYOUT_ATOM(fixedList, "Fixed-list")
|
LAYOUT_ATOM(fixedList, "Fixed-list")
|
||||||
LAYOUT_ATOM(floatList, "Float-list")
|
LAYOUT_ATOM(floatList, "Float-list")
|
||||||
LAYOUT_ATOM(overflowList, "Overflow-list")
|
LAYOUT_ATOM(overflowList, "Overflow-list")
|
||||||
|
LAYOUT_ATOM(overflowOutOfFlowList, "OverflowOutOfFlow-list")
|
||||||
LAYOUT_ATOM(popupList, "Popup-list")
|
LAYOUT_ATOM(popupList, "Popup-list")
|
||||||
|
|
||||||
LAYOUT_ATOM(commentTagName, "__moz_comment")
|
LAYOUT_ATOM(commentTagName, "__moz_comment")
|
||||||
@@ -139,6 +140,7 @@ LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*
|
|||||||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||||
|
LAYOUT_ATOM(overflowOutOfFlowsProperty, "OverflowOutOfFlowsProperty") // nsFrameList*
|
||||||
LAYOUT_ATOM(overflowPlaceholdersProperty, "OverflowPlaceholdersProperty") // nsPlaceholder*
|
LAYOUT_ATOM(overflowPlaceholdersProperty, "OverflowPlaceholdersProperty") // nsPlaceholder*
|
||||||
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
||||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||||
|
|||||||
@@ -304,6 +304,11 @@ nsBlockFrame::Destroy(nsIPresContext* aPresContext)
|
|||||||
if (overflowLines) {
|
if (overflowLines) {
|
||||||
nsLineBox::DeleteLineList(aPresContext, *overflowLines);
|
nsLineBox::DeleteLineList(aPresContext, *overflowLines);
|
||||||
}
|
}
|
||||||
|
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||||
|
if (overflowOutOfFlows) {
|
||||||
|
overflowOutOfFlows->DestroyFrames(aPresContext);
|
||||||
|
delete overflowOutOfFlows;
|
||||||
|
}
|
||||||
|
|
||||||
return nsBlockFrameSuper::Destroy(aPresContext);
|
return nsBlockFrameSuper::Destroy(aPresContext);
|
||||||
}
|
}
|
||||||
@@ -477,6 +482,10 @@ nsBlockFrame::GetFirstChild(nsIAtom* aListName) const
|
|||||||
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||||
return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
|
return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
|
||||||
}
|
}
|
||||||
|
else if (aListName == nsLayoutAtoms::overflowOutOfFlowList) {
|
||||||
|
nsFrameList* oof = GetOverflowOutOfFlows(PR_FALSE);
|
||||||
|
return oof ? oof->FirstChild() : nsnull;
|
||||||
|
}
|
||||||
else if (aListName == nsLayoutAtoms::floatList) {
|
else if (aListName == nsLayoutAtoms::floatList) {
|
||||||
return mFloats.FirstChild();
|
return mFloats.FirstChild();
|
||||||
}
|
}
|
||||||
@@ -498,6 +507,8 @@ nsBlockFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
|||||||
return nsLayoutAtoms::bulletList;
|
return nsLayoutAtoms::bulletList;
|
||||||
case NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX:
|
case NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX:
|
||||||
return nsLayoutAtoms::overflowList;
|
return nsLayoutAtoms::overflowList;
|
||||||
|
case NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX:
|
||||||
|
return nsLayoutAtoms::overflowOutOfFlowList;
|
||||||
case NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX:
|
case NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX:
|
||||||
return mAbsoluteContainer.GetChildListName();
|
return mAbsoluteContainer.GetChildListName();
|
||||||
default:
|
default:
|
||||||
@@ -4205,7 +4216,6 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The overflowLines property is stored as a pointer to a line list,
|
// The overflowLines property is stored as a pointer to a line list,
|
||||||
// which must be deleted. However, the following functions all maintain
|
// which must be deleted. However, the following functions all maintain
|
||||||
// the invariant that the property is never set if the list is empty.
|
// the invariant that the property is never set if the list is empty.
|
||||||
@@ -4240,26 +4250,6 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||||||
// present in the lines, so their views can be reparented?
|
// present in the lines, so their views can be reparented?
|
||||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, prevBlock, this);
|
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, prevBlock, this);
|
||||||
|
|
||||||
// If the frame we are looking at is a placeholder for a float, we
|
|
||||||
// need to reparent both it's out-of-flow frame and any views it has.
|
|
||||||
//
|
|
||||||
// Note: A floating table (example: style="position: relative; float: right")
|
|
||||||
// is an example of an out-of-flow frame with a view
|
|
||||||
|
|
||||||
// XXXldb What about a placeholder within an inline or block descendant?
|
|
||||||
|
|
||||||
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
|
||||||
nsIFrame *outOfFlowFrame =
|
|
||||||
NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
|
||||||
if (!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
|
||||||
// It's not an absolute or fixed positioned frame, so it
|
|
||||||
// must be a float!
|
|
||||||
outOfFlowFrame->SetParent(this);
|
|
||||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext,
|
|
||||||
outOfFlowFrame, prevBlock, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the next frame
|
// Get the next frame
|
||||||
lastFrame = frame;
|
lastFrame = frame;
|
||||||
frame = frame->GetNextSibling();
|
frame = frame->GetNextSibling();
|
||||||
@@ -4275,6 +4265,20 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||||||
mLines.splice(mLines.begin(), *overflowLines);
|
mLines.splice(mLines.begin(), *overflowLines);
|
||||||
NS_ASSERTION(overflowLines->empty(), "splice should empty list");
|
NS_ASSERTION(overflowLines->empty(), "splice should empty list");
|
||||||
delete overflowLines;
|
delete overflowLines;
|
||||||
|
|
||||||
|
// Out-of-flow floats need to be reparented too.
|
||||||
|
nsFrameList* overflowOutOfFlows = prevBlock->GetOverflowOutOfFlows(PR_TRUE);
|
||||||
|
if (overflowOutOfFlows) {
|
||||||
|
for (nsIFrame* f = overflowOutOfFlows->FirstChild(); f;
|
||||||
|
f = f->GetNextSibling()) {
|
||||||
|
f->SetParent(this);
|
||||||
|
|
||||||
|
// When pushing and pulling frames we need to check for whether any
|
||||||
|
// views need to be reparented
|
||||||
|
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, prevBlock, this);
|
||||||
|
}
|
||||||
|
delete overflowOutOfFlows;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4295,6 +4299,14 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||||||
mLines.splice(mLines.end(), *overflowLines);
|
mLines.splice(mLines.end(), *overflowLines);
|
||||||
drained = PR_TRUE;
|
drained = PR_TRUE;
|
||||||
delete overflowLines;
|
delete overflowLines;
|
||||||
|
|
||||||
|
// Likewise, drain our own overflow out-of-flows. We don't need to
|
||||||
|
// reparent them since they're already our children. We don't need
|
||||||
|
// to put them on any child list since BuildFloatList will put
|
||||||
|
// them on some child list. All we need to do is remove the
|
||||||
|
// property.
|
||||||
|
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||||
|
delete overflowOutOfFlows;
|
||||||
}
|
}
|
||||||
return drained;
|
return drained;
|
||||||
}
|
}
|
||||||
@@ -4341,6 +4353,36 @@ nsBlockFrame::SetOverflowLines(nsIPresContext* aPresContext,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsFrameList*
|
||||||
|
nsBlockFrame::GetOverflowOutOfFlows(PRBool aRemoveProperty) const
|
||||||
|
{
|
||||||
|
return NS_STATIC_CAST(nsFrameList*,
|
||||||
|
GetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||||
|
aRemoveProperty));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor function for the overflowPlaceholders frame property
|
||||||
|
static void
|
||||||
|
DestroyOverflowOOFs(nsIPresContext* aPresContext,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
nsIAtom* aPropertyName,
|
||||||
|
void* aPropertyValue)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("This helper method should never be called!");
|
||||||
|
delete NS_STATIC_CAST(nsFrameList*, aPropertyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This takes ownership of aFloaters.
|
||||||
|
nsresult
|
||||||
|
nsBlockFrame::SetOverflowOutOfFlows(nsFrameList* aOOFs)
|
||||||
|
{
|
||||||
|
nsresult rv = SetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||||
|
aOOFs, DestroyOverflowOOFs);
|
||||||
|
// Verify that we didn't overwrite an existing overflow list
|
||||||
|
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow float list");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsFrameList*
|
nsFrameList*
|
||||||
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||||
PRBool aRemoveProperty) const
|
PRBool aRemoveProperty) const
|
||||||
@@ -6370,6 +6412,8 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
|
|||||||
void
|
void
|
||||||
nsBlockFrame::BuildFloatList()
|
nsBlockFrame::BuildFloatList()
|
||||||
{
|
{
|
||||||
|
// Accumulate float list into mFloats.
|
||||||
|
// Use the float cache to speed up searching the lines for floats.
|
||||||
nsIFrame* head = nsnull;
|
nsIFrame* head = nsnull;
|
||||||
nsIFrame* current = nsnull;
|
nsIFrame* current = nsnull;
|
||||||
for (line_iterator line = begin_lines(), line_end = end_lines();
|
for (line_iterator line = begin_lines(), line_end = end_lines();
|
||||||
@@ -6379,10 +6423,9 @@ nsBlockFrame::BuildFloatList()
|
|||||||
nsFloatCache* fc = line->GetFirstFloat();
|
nsFloatCache* fc = line->GetFirstFloat();
|
||||||
while (fc) {
|
while (fc) {
|
||||||
nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
|
nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
|
||||||
if (nsnull == head) {
|
if (!head) {
|
||||||
current = head = floatFrame;
|
current = head = floatFrame;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
current->SetNextSibling(floatFrame);
|
current->SetNextSibling(floatFrame);
|
||||||
current = floatFrame;
|
current = floatFrame;
|
||||||
}
|
}
|
||||||
@@ -6392,10 +6435,51 @@ nsBlockFrame::BuildFloatList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Terminate end of float list just in case a float was removed
|
// Terminate end of float list just in case a float was removed
|
||||||
if (nsnull != current) {
|
if (current) {
|
||||||
current->SetNextSibling(nsnull);
|
current->SetNextSibling(nsnull);
|
||||||
}
|
}
|
||||||
mFloats.SetFrames(head);
|
mFloats.SetFrames(head);
|
||||||
|
|
||||||
|
// ensure that the floats in the overflow lines are put on a child list
|
||||||
|
// and not dropped from the frame tree!
|
||||||
|
// Note that overflow lines do not have any float cache set up for them,
|
||||||
|
// because the float cache contains only laid-out floats
|
||||||
|
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||||
|
if (overflowLines) {
|
||||||
|
head = nsnull;
|
||||||
|
current = nsnull;
|
||||||
|
|
||||||
|
nsIFrame* frame = overflowLines->front()->mFirstChild;
|
||||||
|
while (frame) {
|
||||||
|
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
||||||
|
nsIFrame *outOfFlowFrame = NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
||||||
|
if (outOfFlowFrame &&
|
||||||
|
!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
||||||
|
// It's not an absolute or fixed positioned frame, so it
|
||||||
|
// must be a float!
|
||||||
|
// XXX This is a lame-o way of detecting a float, but it's the only way
|
||||||
|
// apparently
|
||||||
|
if (!head) {
|
||||||
|
head = current = outOfFlowFrame;
|
||||||
|
} else {
|
||||||
|
current->SetNextSibling(outOfFlowFrame);
|
||||||
|
current = outOfFlowFrame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXXldb What about a placeholder within an inline or block descendant?
|
||||||
|
frame = frame->GetNextSibling();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current) {
|
||||||
|
current->SetNextSibling(nsnull);
|
||||||
|
nsFrameList* frameList = new nsFrameList(head);
|
||||||
|
if (frameList) {
|
||||||
|
SetOverflowOutOfFlows(frameList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX keep the text-run data in the first-in-flow of the block
|
// XXX keep the text-run data in the first-in-flow of the block
|
||||||
|
|||||||
@@ -56,10 +56,11 @@ class nsIntervalSet;
|
|||||||
* Child list name indices
|
* Child list name indices
|
||||||
* @see #GetAdditionalChildListName()
|
* @see #GetAdditionalChildListName()
|
||||||
*/
|
*/
|
||||||
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
||||||
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
||||||
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
||||||
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 3
|
#define NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX 3
|
||||||
|
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 4
|
||||||
#define NS_BLOCK_FRAME_LAST_LIST_INDEX NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX
|
#define NS_BLOCK_FRAME_LAST_LIST_INDEX NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX
|
||||||
|
|
||||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||||
@@ -542,16 +543,17 @@ protected:
|
|||||||
|
|
||||||
nsLineList* GetOverflowLines(nsIPresContext* aPresContext,
|
nsLineList* GetOverflowLines(nsIPresContext* aPresContext,
|
||||||
PRBool aRemoveProperty) const;
|
PRBool aRemoveProperty) const;
|
||||||
|
|
||||||
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
||||||
nsLineList* aOverflowLines);
|
nsLineList* aOverflowLines);
|
||||||
|
|
||||||
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||||
PRBool aRemoveProperty) const;
|
PRBool aRemoveProperty) const;
|
||||||
|
|
||||||
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||||
nsFrameList* aOverflowPlaceholders);
|
nsFrameList* aOverflowPlaceholders);
|
||||||
|
|
||||||
|
nsFrameList* GetOverflowOutOfFlows(PRBool aRemoveProperty) const;
|
||||||
|
nsresult SetOverflowOutOfFlows(nsFrameList* aFloaters);
|
||||||
|
|
||||||
nsIFrame* LastChild();
|
nsIFrame* LastChild();
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
|
|||||||
@@ -304,6 +304,11 @@ nsBlockFrame::Destroy(nsIPresContext* aPresContext)
|
|||||||
if (overflowLines) {
|
if (overflowLines) {
|
||||||
nsLineBox::DeleteLineList(aPresContext, *overflowLines);
|
nsLineBox::DeleteLineList(aPresContext, *overflowLines);
|
||||||
}
|
}
|
||||||
|
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||||
|
if (overflowOutOfFlows) {
|
||||||
|
overflowOutOfFlows->DestroyFrames(aPresContext);
|
||||||
|
delete overflowOutOfFlows;
|
||||||
|
}
|
||||||
|
|
||||||
return nsBlockFrameSuper::Destroy(aPresContext);
|
return nsBlockFrameSuper::Destroy(aPresContext);
|
||||||
}
|
}
|
||||||
@@ -477,6 +482,10 @@ nsBlockFrame::GetFirstChild(nsIAtom* aListName) const
|
|||||||
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||||
return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
|
return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
|
||||||
}
|
}
|
||||||
|
else if (aListName == nsLayoutAtoms::overflowOutOfFlowList) {
|
||||||
|
nsFrameList* oof = GetOverflowOutOfFlows(PR_FALSE);
|
||||||
|
return oof ? oof->FirstChild() : nsnull;
|
||||||
|
}
|
||||||
else if (aListName == nsLayoutAtoms::floatList) {
|
else if (aListName == nsLayoutAtoms::floatList) {
|
||||||
return mFloats.FirstChild();
|
return mFloats.FirstChild();
|
||||||
}
|
}
|
||||||
@@ -498,6 +507,8 @@ nsBlockFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
|||||||
return nsLayoutAtoms::bulletList;
|
return nsLayoutAtoms::bulletList;
|
||||||
case NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX:
|
case NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX:
|
||||||
return nsLayoutAtoms::overflowList;
|
return nsLayoutAtoms::overflowList;
|
||||||
|
case NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX:
|
||||||
|
return nsLayoutAtoms::overflowOutOfFlowList;
|
||||||
case NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX:
|
case NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX:
|
||||||
return mAbsoluteContainer.GetChildListName();
|
return mAbsoluteContainer.GetChildListName();
|
||||||
default:
|
default:
|
||||||
@@ -4205,7 +4216,6 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The overflowLines property is stored as a pointer to a line list,
|
// The overflowLines property is stored as a pointer to a line list,
|
||||||
// which must be deleted. However, the following functions all maintain
|
// which must be deleted. However, the following functions all maintain
|
||||||
// the invariant that the property is never set if the list is empty.
|
// the invariant that the property is never set if the list is empty.
|
||||||
@@ -4240,26 +4250,6 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||||||
// present in the lines, so their views can be reparented?
|
// present in the lines, so their views can be reparented?
|
||||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, prevBlock, this);
|
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, prevBlock, this);
|
||||||
|
|
||||||
// If the frame we are looking at is a placeholder for a float, we
|
|
||||||
// need to reparent both it's out-of-flow frame and any views it has.
|
|
||||||
//
|
|
||||||
// Note: A floating table (example: style="position: relative; float: right")
|
|
||||||
// is an example of an out-of-flow frame with a view
|
|
||||||
|
|
||||||
// XXXldb What about a placeholder within an inline or block descendant?
|
|
||||||
|
|
||||||
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
|
||||||
nsIFrame *outOfFlowFrame =
|
|
||||||
NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
|
||||||
if (!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
|
||||||
// It's not an absolute or fixed positioned frame, so it
|
|
||||||
// must be a float!
|
|
||||||
outOfFlowFrame->SetParent(this);
|
|
||||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext,
|
|
||||||
outOfFlowFrame, prevBlock, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the next frame
|
// Get the next frame
|
||||||
lastFrame = frame;
|
lastFrame = frame;
|
||||||
frame = frame->GetNextSibling();
|
frame = frame->GetNextSibling();
|
||||||
@@ -4275,6 +4265,20 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||||||
mLines.splice(mLines.begin(), *overflowLines);
|
mLines.splice(mLines.begin(), *overflowLines);
|
||||||
NS_ASSERTION(overflowLines->empty(), "splice should empty list");
|
NS_ASSERTION(overflowLines->empty(), "splice should empty list");
|
||||||
delete overflowLines;
|
delete overflowLines;
|
||||||
|
|
||||||
|
// Out-of-flow floats need to be reparented too.
|
||||||
|
nsFrameList* overflowOutOfFlows = prevBlock->GetOverflowOutOfFlows(PR_TRUE);
|
||||||
|
if (overflowOutOfFlows) {
|
||||||
|
for (nsIFrame* f = overflowOutOfFlows->FirstChild(); f;
|
||||||
|
f = f->GetNextSibling()) {
|
||||||
|
f->SetParent(this);
|
||||||
|
|
||||||
|
// When pushing and pulling frames we need to check for whether any
|
||||||
|
// views need to be reparented
|
||||||
|
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, prevBlock, this);
|
||||||
|
}
|
||||||
|
delete overflowOutOfFlows;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4295,6 +4299,14 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||||||
mLines.splice(mLines.end(), *overflowLines);
|
mLines.splice(mLines.end(), *overflowLines);
|
||||||
drained = PR_TRUE;
|
drained = PR_TRUE;
|
||||||
delete overflowLines;
|
delete overflowLines;
|
||||||
|
|
||||||
|
// Likewise, drain our own overflow out-of-flows. We don't need to
|
||||||
|
// reparent them since they're already our children. We don't need
|
||||||
|
// to put them on any child list since BuildFloatList will put
|
||||||
|
// them on some child list. All we need to do is remove the
|
||||||
|
// property.
|
||||||
|
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||||
|
delete overflowOutOfFlows;
|
||||||
}
|
}
|
||||||
return drained;
|
return drained;
|
||||||
}
|
}
|
||||||
@@ -4341,6 +4353,36 @@ nsBlockFrame::SetOverflowLines(nsIPresContext* aPresContext,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsFrameList*
|
||||||
|
nsBlockFrame::GetOverflowOutOfFlows(PRBool aRemoveProperty) const
|
||||||
|
{
|
||||||
|
return NS_STATIC_CAST(nsFrameList*,
|
||||||
|
GetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||||
|
aRemoveProperty));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor function for the overflowPlaceholders frame property
|
||||||
|
static void
|
||||||
|
DestroyOverflowOOFs(nsIPresContext* aPresContext,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
nsIAtom* aPropertyName,
|
||||||
|
void* aPropertyValue)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("This helper method should never be called!");
|
||||||
|
delete NS_STATIC_CAST(nsFrameList*, aPropertyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This takes ownership of aFloaters.
|
||||||
|
nsresult
|
||||||
|
nsBlockFrame::SetOverflowOutOfFlows(nsFrameList* aOOFs)
|
||||||
|
{
|
||||||
|
nsresult rv = SetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||||
|
aOOFs, DestroyOverflowOOFs);
|
||||||
|
// Verify that we didn't overwrite an existing overflow list
|
||||||
|
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow float list");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsFrameList*
|
nsFrameList*
|
||||||
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||||
PRBool aRemoveProperty) const
|
PRBool aRemoveProperty) const
|
||||||
@@ -6370,6 +6412,8 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
|
|||||||
void
|
void
|
||||||
nsBlockFrame::BuildFloatList()
|
nsBlockFrame::BuildFloatList()
|
||||||
{
|
{
|
||||||
|
// Accumulate float list into mFloats.
|
||||||
|
// Use the float cache to speed up searching the lines for floats.
|
||||||
nsIFrame* head = nsnull;
|
nsIFrame* head = nsnull;
|
||||||
nsIFrame* current = nsnull;
|
nsIFrame* current = nsnull;
|
||||||
for (line_iterator line = begin_lines(), line_end = end_lines();
|
for (line_iterator line = begin_lines(), line_end = end_lines();
|
||||||
@@ -6379,10 +6423,9 @@ nsBlockFrame::BuildFloatList()
|
|||||||
nsFloatCache* fc = line->GetFirstFloat();
|
nsFloatCache* fc = line->GetFirstFloat();
|
||||||
while (fc) {
|
while (fc) {
|
||||||
nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
|
nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
|
||||||
if (nsnull == head) {
|
if (!head) {
|
||||||
current = head = floatFrame;
|
current = head = floatFrame;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
current->SetNextSibling(floatFrame);
|
current->SetNextSibling(floatFrame);
|
||||||
current = floatFrame;
|
current = floatFrame;
|
||||||
}
|
}
|
||||||
@@ -6392,10 +6435,51 @@ nsBlockFrame::BuildFloatList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Terminate end of float list just in case a float was removed
|
// Terminate end of float list just in case a float was removed
|
||||||
if (nsnull != current) {
|
if (current) {
|
||||||
current->SetNextSibling(nsnull);
|
current->SetNextSibling(nsnull);
|
||||||
}
|
}
|
||||||
mFloats.SetFrames(head);
|
mFloats.SetFrames(head);
|
||||||
|
|
||||||
|
// ensure that the floats in the overflow lines are put on a child list
|
||||||
|
// and not dropped from the frame tree!
|
||||||
|
// Note that overflow lines do not have any float cache set up for them,
|
||||||
|
// because the float cache contains only laid-out floats
|
||||||
|
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||||
|
if (overflowLines) {
|
||||||
|
head = nsnull;
|
||||||
|
current = nsnull;
|
||||||
|
|
||||||
|
nsIFrame* frame = overflowLines->front()->mFirstChild;
|
||||||
|
while (frame) {
|
||||||
|
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
||||||
|
nsIFrame *outOfFlowFrame = NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
||||||
|
if (outOfFlowFrame &&
|
||||||
|
!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
||||||
|
// It's not an absolute or fixed positioned frame, so it
|
||||||
|
// must be a float!
|
||||||
|
// XXX This is a lame-o way of detecting a float, but it's the only way
|
||||||
|
// apparently
|
||||||
|
if (!head) {
|
||||||
|
head = current = outOfFlowFrame;
|
||||||
|
} else {
|
||||||
|
current->SetNextSibling(outOfFlowFrame);
|
||||||
|
current = outOfFlowFrame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXXldb What about a placeholder within an inline or block descendant?
|
||||||
|
frame = frame->GetNextSibling();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current) {
|
||||||
|
current->SetNextSibling(nsnull);
|
||||||
|
nsFrameList* frameList = new nsFrameList(head);
|
||||||
|
if (frameList) {
|
||||||
|
SetOverflowOutOfFlows(frameList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX keep the text-run data in the first-in-flow of the block
|
// XXX keep the text-run data in the first-in-flow of the block
|
||||||
|
|||||||
@@ -56,10 +56,11 @@ class nsIntervalSet;
|
|||||||
* Child list name indices
|
* Child list name indices
|
||||||
* @see #GetAdditionalChildListName()
|
* @see #GetAdditionalChildListName()
|
||||||
*/
|
*/
|
||||||
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
||||||
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
||||||
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
||||||
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 3
|
#define NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX 3
|
||||||
|
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 4
|
||||||
#define NS_BLOCK_FRAME_LAST_LIST_INDEX NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX
|
#define NS_BLOCK_FRAME_LAST_LIST_INDEX NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX
|
||||||
|
|
||||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||||
@@ -542,16 +543,17 @@ protected:
|
|||||||
|
|
||||||
nsLineList* GetOverflowLines(nsIPresContext* aPresContext,
|
nsLineList* GetOverflowLines(nsIPresContext* aPresContext,
|
||||||
PRBool aRemoveProperty) const;
|
PRBool aRemoveProperty) const;
|
||||||
|
|
||||||
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
||||||
nsLineList* aOverflowLines);
|
nsLineList* aOverflowLines);
|
||||||
|
|
||||||
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||||
PRBool aRemoveProperty) const;
|
PRBool aRemoveProperty) const;
|
||||||
|
|
||||||
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||||
nsFrameList* aOverflowPlaceholders);
|
nsFrameList* aOverflowPlaceholders);
|
||||||
|
|
||||||
|
nsFrameList* GetOverflowOutOfFlows(PRBool aRemoveProperty) const;
|
||||||
|
nsresult SetOverflowOutOfFlows(nsFrameList* aFloaters);
|
||||||
|
|
||||||
nsIFrame* LastChild();
|
nsIFrame* LastChild();
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
|
|||||||
Reference in New Issue
Block a user