From efab9b17ef04545e09dae3abdecea79f5dfd7cd5 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Sat, 10 Mar 2012 14:49:10 -0800 Subject: [PATCH] Bug 640443: Allow positioned display:-moz-box elements to be containers for absolutely-positioned content. r=bz --- layout/base/nsCSSFrameConstructor.cpp | 14 ++++++-- .../box/flexbox-abspos-container-1-ref.html | 27 +++++++++++++++ .../box/flexbox-abspos-container-1a.html | 30 +++++++++++++++++ .../box/flexbox-abspos-container-1b.html | 29 ++++++++++++++++ .../box/flexbox-abspos-container-1c.html | 33 +++++++++++++++++++ .../box/flexbox-abspos-container-1d.html | 31 +++++++++++++++++ .../box/flexbox-abspos-container-2-ref.html | 27 +++++++++++++++ .../box/flexbox-abspos-container-2.html | 31 +++++++++++++++++ layout/reftests/box/reftest.list | 5 +++ layout/xul/base/src/nsBoxFrame.cpp | 33 +++++++++++++++++++ 10 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 layout/reftests/box/flexbox-abspos-container-1-ref.html create mode 100644 layout/reftests/box/flexbox-abspos-container-1a.html create mode 100644 layout/reftests/box/flexbox-abspos-container-1b.html create mode 100644 layout/reftests/box/flexbox-abspos-container-1c.html create mode 100644 layout/reftests/box/flexbox-abspos-container-1d.html create mode 100644 layout/reftests/box/flexbox-abspos-container-2-ref.html create mode 100644 layout/reftests/box/flexbox-abspos-container-2.html 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); }