diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index e089329e1b40..6eedc39707e8 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3914,6 +3914,12 @@ bool IsXULDisplayType(const nsStyleDisplay* aDisplay)
#define SCROLLABLE_XUL_FCDATA(_func) \
FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_SKIP_ABSPOS_PUSH | \
FCDATA_MAY_NEED_SCROLLFRAME, _func)
+// .. but we allow some XUL frames to be _containers_ for out-of-flow content
+// (This is the same as SCROLLABLE_XUL_FCDATA, but w/o FCDATA_SKIP_ABSPOS_PUSH)
+#define SCROLLABLE_ABSPOS_CONTAINER_XUL_FCDATA(_func) \
+ FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | \
+ FCDATA_MAY_NEED_SCROLLFRAME, _func)
+
#define SIMPLE_XUL_CREATE(_tag, _func) \
{ &nsGkAtoms::_tag, SIMPLE_XUL_FCDATA(_func) }
#define SCROLLABLE_XUL_CREATE(_tag, _func) \
@@ -3922,6 +3928,8 @@ bool IsXULDisplayType(const nsStyleDisplay* aDisplay)
{ _int, SIMPLE_XUL_FCDATA(_func) }
#define SCROLLABLE_XUL_INT_CREATE(_int, _func) \
{ _int, SCROLLABLE_XUL_FCDATA(_func) }
+#define SCROLLABLE_ABSPOS_CONTAINER_XUL_INT_CREATE(_int, _func) \
+ { _int, SCROLLABLE_ABSPOS_CONTAINER_XUL_FCDATA(_func) }
static
nsIFrame* NS_NewGridBoxFrame(nsIPresShell* aPresShell,
@@ -4117,8 +4125,10 @@ nsCSSFrameConstructor::FindXULDisplayData(const nsStyleDisplay* aDisplay,
nsStyleContext* aStyleContext)
{
static const FrameConstructionDataByInt sXULDisplayData[] = {
- SCROLLABLE_XUL_INT_CREATE(NS_STYLE_DISPLAY_INLINE_BOX, NS_NewBoxFrame),
- SCROLLABLE_XUL_INT_CREATE(NS_STYLE_DISPLAY_BOX, NS_NewBoxFrame),
+ SCROLLABLE_ABSPOS_CONTAINER_XUL_INT_CREATE(NS_STYLE_DISPLAY_INLINE_BOX,
+ NS_NewBoxFrame),
+ SCROLLABLE_ABSPOS_CONTAINER_XUL_INT_CREATE(NS_STYLE_DISPLAY_BOX,
+ NS_NewBoxFrame),
#ifdef MOZ_XUL
SCROLLABLE_XUL_INT_CREATE(NS_STYLE_DISPLAY_INLINE_GRID, NS_NewGridBoxFrame),
SCROLLABLE_XUL_INT_CREATE(NS_STYLE_DISPLAY_GRID, NS_NewGridBoxFrame),
diff --git a/layout/reftests/box/flexbox-abspos-container-1-ref.html b/layout/reftests/box/flexbox-abspos-container-1-ref.html
new file mode 100644
index 000000000000..fbeaabf32aa5
--- /dev/null
+++ b/layout/reftests/box/flexbox-abspos-container-1-ref.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/box/flexbox-abspos-container-1a.html b/layout/reftests/box/flexbox-abspos-container-1a.html
new file mode 100644
index 000000000000..1f6ee21a70d9
--- /dev/null
+++ b/layout/reftests/box/flexbox-abspos-container-1a.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/box/flexbox-abspos-container-1b.html b/layout/reftests/box/flexbox-abspos-container-1b.html
new file mode 100644
index 000000000000..b19072382add
--- /dev/null
+++ b/layout/reftests/box/flexbox-abspos-container-1b.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/box/flexbox-abspos-container-1c.html b/layout/reftests/box/flexbox-abspos-container-1c.html
new file mode 100644
index 000000000000..553c9fc1b78c
--- /dev/null
+++ b/layout/reftests/box/flexbox-abspos-container-1c.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/box/flexbox-abspos-container-1d.html b/layout/reftests/box/flexbox-abspos-container-1d.html
new file mode 100644
index 000000000000..78bb84fa75d7
--- /dev/null
+++ b/layout/reftests/box/flexbox-abspos-container-1d.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/box/flexbox-abspos-container-2-ref.html b/layout/reftests/box/flexbox-abspos-container-2-ref.html
new file mode 100644
index 000000000000..d3ef61188765
--- /dev/null
+++ b/layout/reftests/box/flexbox-abspos-container-2-ref.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/box/flexbox-abspos-container-2.html b/layout/reftests/box/flexbox-abspos-container-2.html
new file mode 100644
index 000000000000..aa3013f534e0
--- /dev/null
+++ b/layout/reftests/box/flexbox-abspos-container-2.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/box/reftest.list b/layout/reftests/box/reftest.list
index 7acadb49d0ea..e32a3e84d789 100644
--- a/layout/reftests/box/reftest.list
+++ b/layout/reftests/box/reftest.list
@@ -1,3 +1,8 @@
+== flexbox-abspos-container-1a.html flexbox-abspos-container-1-ref.html
+== flexbox-abspos-container-1b.html flexbox-abspos-container-1-ref.html
+== flexbox-abspos-container-1c.html flexbox-abspos-container-1-ref.html
+== flexbox-abspos-container-1d.html flexbox-abspos-container-1-ref.html
+== flexbox-abspos-container-2.html flexbox-abspos-container-2-ref.html
== flexbox-attributes-no-box-horizontal.xhtml flexbox-attributes-no-box-horizontal-ref.xhtml
== flexbox-attributes-no-box-vertical.xhtml flexbox-attributes-no-box-vertical-ref.xhtml
== flexbox-attributes-no-input-horizontal.xhtml flexbox-attributes-no-input-horizontal-ref.xhtml
diff --git a/layout/xul/base/src/nsBoxFrame.cpp b/layout/xul/base/src/nsBoxFrame.cpp
index 476a9cd08775..38db8793c26e 100644
--- a/layout/xul/base/src/nsBoxFrame.cpp
+++ b/layout/xul/base/src/nsBoxFrame.cpp
@@ -758,6 +758,8 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext,
}
#endif
+ ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
+
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;
}
@@ -934,6 +936,35 @@ nsBoxFrame::DoLayout(nsBoxLayoutState& aState)
aState.SetLayoutFlags(oldFlags);
+ if (HasAbsolutelyPositionedChildren()) {
+ // Set up a |reflowState| to pass into ReflowAbsoluteFrames
+ nsHTMLReflowState reflowState(aState.PresContext(), this,
+ aState.GetRenderingContext(),
+ nsSize(mRect.width, NS_UNCONSTRAINEDSIZE));
+
+ // Set up a |desiredSize| to pass into ReflowAbsoluteFrames
+ nsHTMLReflowMetrics desiredSize;
+ desiredSize.width = mRect.width;
+ desiredSize.height = mRect.height;
+
+ // get the ascent (cribbed from ::Reflow)
+ nscoord ascent = mRect.height;
+
+ // getting the ascent could be a lot of work. Don't get it if
+ // we are the root. The viewport doesn't care about it.
+ if (!(mState & NS_STATE_IS_ROOT)) {
+ ascent = GetBoxAscent(aState);
+ }
+ desiredSize.ascent = ascent;
+ desiredSize.mOverflowAreas = GetOverflowAreas();
+
+ // Set up a |reflowStatus| to pass into ReflowAbsoluteFrames
+ // (just a dummy value; hopefully that's OK)
+ nsReflowStatus reflowStatus = NS_FRAME_COMPLETE;
+ ReflowAbsoluteFrames(aState.PresContext(), desiredSize,
+ reflowState, reflowStatus);
+ }
+
return rv;
}
@@ -946,6 +977,8 @@ nsBoxFrame::DestroyFrom(nsIFrame* aDestructRoot)
// clean up the container box's layout manager and child boxes
SetLayoutManager(nsnull);
+ DestroyAbsoluteFrames(aDestructRoot);
+
nsContainerFrame::DestroyFrom(aDestructRoot);
}