diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index d515946fd4ae..4461f72ef199 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3178,16 +3178,16 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState, fieldsetKids.AddChild(blockFrame); for (nsFrameList::Enumerator e(childItems); !e.AtEnd(); e.Next()) { - nsLegendFrame* legendFrame = do_QueryFrame(e.get()); - if (legendFrame) { + nsIFrame* child = e.get(); + if (child->GetContentInsertionFrame()->GetType() == nsGkAtoms::legendFrame) { // We want the legend to be the first frame in the fieldset child list. // That way the EventStateManager will do the right thing when tabbing // from a selection point within the legend (bug 236071), which is // used for implementing legend access keys (bug 81481). // GetAdjustedParentFrame() below depends on this frame order. - childItems.RemoveFrame(legendFrame); + childItems.RemoveFrame(child); // Make sure to reparent the legend so it has the fieldset as the parent. - fieldsetKids.InsertFrame(newFrame, nsnull, legendFrame); + fieldsetKids.InsertFrame(newFrame, nsnull, child); break; } } @@ -3414,7 +3414,8 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement, COMPLEX_TAG_CREATE(fieldset, &nsCSSFrameConstructor::ConstructFieldSetFrame), { &nsGkAtoms::legend, - FCDATA_DECL(FCDATA_ALLOW_BLOCK_STYLES, NS_NewLegendFrame) }, + FCDATA_DECL(FCDATA_ALLOW_BLOCK_STYLES | FCDATA_MAY_NEED_SCROLLFRAME, + NS_NewLegendFrame) }, SIMPLE_TAG_CREATE(frameset, NS_NewHTMLFramesetFrame), SIMPLE_TAG_CREATE(iframe, NS_NewSubDocumentFrame), { &nsGkAtoms::button, @@ -5813,7 +5814,7 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling, (nsGkAtoms::fieldSetFrame == grandparentType && nsGkAtoms::blockFrame == parentType)) { // Legends can be sibling of legends but not of other content in the fieldset - nsIAtom* sibType = aSibling->GetType(); + nsIAtom* sibType = aSibling->GetContentInsertionFrame()->GetType(); nsCOMPtr legendContent(do_QueryInterface(aContent)); if ((legendContent && (nsGkAtoms::legendFrame != sibType)) || @@ -8900,7 +8901,7 @@ nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame, return true; } - if (aFrame->GetType() == nsGkAtoms::legendFrame && + if (aFrame->GetContentInsertionFrame()->GetType() == nsGkAtoms::legendFrame && aFrame->GetParent()->GetType() == nsGkAtoms::fieldSetFrame) { // When we remove the legend for a fieldset, we should reframe // the fieldset to ensure another legend is used, if there is one diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index b182ae35406b..885cb995b0fe 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -126,6 +126,8 @@ protected: virtual PRIntn GetSkipSides() const; void ReparentFrameList(const nsFrameList& aFrameList); + // mLegendFrame is a nsLegendFrame or a nsHTMLScrollFrame with the + // nsLegendFrame as the scrolled frame (aka content insertion frame). nsIFrame* mLegendFrame; nsIFrame* mContentFrame; nsRect mLegendRect; @@ -560,7 +562,8 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext, if (mLegendFrame) { // if the content rect is larger then the legend we can align the legend if (contentRect.width > mLegendRect.width) { - PRInt32 align = static_cast(mLegendFrame)->GetAlign(); + PRInt32 align = static_cast + (mLegendFrame->GetContentInsertionFrame())->GetAlign(); switch(align) { case NS_STYLE_TEXT_ALIGN_RIGHT: diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index d0a8cd831ab2..54c623fab90f 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -1873,13 +1873,16 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext, } else { AutoMaybeNullInflationContainer an(frame); - bool isBlock = - NS_CSS_FRAME_TYPE_BLOCK == NS_FRAME_GET_TYPE(mFrameType); - // make sure legend frames with display:block and width:auto still - // shrink-wrap + bool isBlock = NS_CSS_FRAME_TYPE_BLOCK == NS_FRAME_GET_TYPE(mFrameType); + PRUint32 computeSizeFlags = isBlock ? 0 : nsIFrame::eShrinkWrap; - PRUint32 computeSizeFlags = 0; - if (!isBlock || aFrameType == nsGkAtoms::legendFrame) { + // Make sure legend frames with display:block and width:auto still + // shrink-wrap. + if (isBlock && + ((aFrameType == nsGkAtoms::legendFrame && + frame->GetStyleContext()->GetPseudo() != nsCSSAnonBoxes::scrolledContent) || + (aFrameType == nsGkAtoms::scrollFrame && + frame->GetContentInsertionFrame()->GetType() == nsGkAtoms::legendFrame))) { computeSizeFlags |= nsIFrame::eShrinkWrap; } diff --git a/layout/reftests/forms/legend-ref.html b/layout/reftests/forms/legend-ref.html new file mode 100644 index 000000000000..8238e239f163 --- /dev/null +++ b/layout/reftests/forms/legend-ref.html @@ -0,0 +1,94 @@ + + + Testcase for bug 740743 + + + + +
+
Legend Test
+
Legend Test
+
+
Legend Test
+
Legend Test
+
+
Legend Test
+
Legend Test
+
Legend Test
+ +
+
+
+
Legend Test
+
+
+ +
+ +Legend Test +Legend Test + +Legend Test +Legend Test + +Legend Test + + + + +Legend Test + + +
+ +
+ +Legend Test +Legend Test + +Legend Test +Legend Test + +Legend Test +Legend Test + + + + +Legend Test + + +
+ +Legend Test +Legend Test +Legend Test + + + diff --git a/layout/reftests/forms/legend.html b/layout/reftests/forms/legend.html new file mode 100644 index 000000000000..9d05fbe6af75 --- /dev/null +++ b/layout/reftests/forms/legend.html @@ -0,0 +1,87 @@ + + + Testcase for bug 740743 + + + + +
+
Legend Test
+
Legend Test
+
+
Legend Test
+
Legend Test
+
+
Legend Test
+
Legend Test
+
Legend Test
+ +
+
+
+
Legend Test
+
+
+ +
+ +Legend Test +Legend Test + +Legend Test +Legend Test + +Legend Test + + + + +Legend Test + + +
+ +
+ +Legend Test +Legend Test + +Legend Test +Legend Test + +Legend Test +Legend Test + + + + +Legend Test + + +
+ +Legend Test +Legend Test +Legend Test + + + diff --git a/layout/reftests/forms/reftest.list b/layout/reftests/forms/reftest.list index 58efaa7679f9..3700b70ce3ee 100644 --- a/layout/reftests/forms/reftest.list +++ b/layout/reftests/forms/reftest.list @@ -64,6 +64,8 @@ fails-if(Android) != textarea-rtl.html textarea-no-resize.html asserts(2) == button-first-letter-1.html button-first-letter-1-ref.html asserts(1) != button-first-letter-1.html button-first-letter-1-noref.html +== legend.html legend-ref.html + # placeholder include placeholder/reftest.list