Bug 261037. Support scrolled fieldsets. r=mats

The main change here is to have nsCSSFrameConstructor able to construct
a scrollframe for nsFieldSetFrame's inner frame.
To make this work properly (as much like normal scrolled elements, and
to be consistent with Chrome), we need another major change, which is to move
the padding from the nsFieldSetFrame to its inner frame. We do this by copying
the padding to the inner frame and ignoring the padding on the outer frame.
To get this right for percentage padding and intrinsic widths is a little
tricky. For that, we need nsLayoutUtils::IntrinsicForContainer to be able to
ignore the padding on a frame so we don't add it twice.
Overriding nsFieldSetFrame::GetScrollTargetFrame makes setting scrollTop/
scrollLeft on a <fieldset> work as expected.
* * *
Bug 261037 - A fieldset overflow:auto reftest.

--HG--
extra : rebase_source : d737eebdc25b3b748a84de676d5e8e066505e00b
This commit is contained in:
Robert O'Callahan 2013-10-23 00:46:40 +02:00
parent d2da7791d3
commit f82ba263d9
24 changed files with 490 additions and 78 deletions

View File

@ -502,8 +502,8 @@ Element::GetScrollFrame(nsIFrame **aStyledFrame, bool aFlushLayout)
// menu frames implement GetScrollTargetFrame but we don't want
// to use it here. Similar for comboboxes.
if (frame->GetType() != nsGkAtoms::menuFrame &&
frame->GetType() != nsGkAtoms::comboboxControlFrame) {
nsIAtom* type = frame->GetType();
if (type != nsGkAtoms::menuFrame && type != nsGkAtoms::comboboxControlFrame) {
nsIScrollableFrame *scrollFrame = frame->GetScrollTargetFrame();
if (scrollFrame)
return scrollFrame;

View File

@ -3050,39 +3050,51 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
nsIContent* const content = aItem.mContent;
nsStyleContext* const styleContext = aItem.mStyleContext;
nsIFrame* newFrame = NS_NewFieldSetFrame(mPresShell, styleContext);
nsIFrame* fieldsetFrame = NS_NewFieldSetFrame(mPresShell, styleContext);
// Initialize it
InitAndRestoreFrame(aState, content,
aState.GetGeometricParent(aStyleDisplay, aParentFrame),
newFrame);
fieldsetFrame);
// Resolve style and initialize the frame
nsRefPtr<nsStyleContext> fieldsetContentStyle;
fieldsetContentStyle = mPresShell->StyleSet()->
ResolveAnonymousBoxStyle(nsCSSAnonBoxes::fieldsetContent, styleContext);
const nsStyleDisplay* fieldsetContentDisplay = fieldsetContentStyle->StyleDisplay();
bool isScrollable = fieldsetContentDisplay->IsScrollableOverflow();
nsIFrame* scrollFrame = nullptr;
if (isScrollable) {
fieldsetContentStyle =
BeginBuildingScrollFrame(aState, content, fieldsetContentStyle,
aState.GetGeometricParent(fieldsetContentDisplay, fieldsetFrame),
nsCSSAnonBoxes::scrolledContent,
false, scrollFrame);
}
nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, fieldsetContentStyle,
NS_BLOCK_FLOAT_MGR |
NS_BLOCK_MARGIN_ROOT);
InitAndRestoreFrame(aState, content, newFrame, blockFrame);
InitAndRestoreFrame(aState, content,
scrollFrame ? scrollFrame : fieldsetFrame, blockFrame);
aState.AddChild(newFrame, aFrameItems, content, styleContext, aParentFrame);
aState.AddChild(fieldsetFrame, aFrameItems, content, styleContext, aParentFrame);
// Process children
nsFrameConstructorSaveState absoluteSaveState;
nsFrameItems childItems;
newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
if (newFrame->IsPositioned()) {
aState.PushAbsoluteContainingBlock(newFrame, newFrame, absoluteSaveState);
blockFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
if (fieldsetFrame->IsPositioned()) {
aState.PushAbsoluteContainingBlock(blockFrame, fieldsetFrame, absoluteSaveState);
}
ProcessChildren(aState, content, styleContext, blockFrame, true,
childItems, true, aItem.mPendingBinding);
nsFrameItems fieldsetKids;
fieldsetKids.AddChild(blockFrame);
fieldsetKids.AddChild(scrollFrame ? scrollFrame : blockFrame);
for (nsFrameList::Enumerator e(childItems); !e.AtEnd(); e.Next()) {
nsIFrame* child = e.get();
@ -3094,21 +3106,25 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
// GetAdjustedParentFrame() below depends on this frame order.
childItems.RemoveFrame(child);
// Make sure to reparent the legend so it has the fieldset as the parent.
fieldsetKids.InsertFrame(newFrame, nullptr, child);
fieldsetKids.InsertFrame(fieldsetFrame, nullptr, child);
break;
}
}
if (isScrollable) {
FinishBuildingScrollFrame(scrollFrame, blockFrame);
}
// Set the inner frame's initial child lists
blockFrame->SetInitialChildList(kPrincipalList, childItems);
// Set the outer frame's initial child list
newFrame->SetInitialChildList(kPrincipalList, fieldsetKids);
fieldsetFrame->SetInitialChildList(kPrincipalList, fieldsetKids);
newFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
fieldsetFrame->AddStateBits(NS_FRAME_MAY_HAVE_GENERATED_CONTENT);
// Our new frame returned is the outer frame, which is the fieldset frame.
return newFrame;
return fieldsetFrame;
}
static nsIFrame*
@ -3262,6 +3278,17 @@ nsCSSFrameConstructor::FindDataByTag(nsIAtom* aTag,
#define COMPLEX_TAG_CREATE(_tag, _func) \
{ &nsGkAtoms::_tag, FULL_CTOR_FCDATA(0, _func) }
static bool
IsFrameForFieldSet(nsIFrame* aFrame, nsIAtom* aFrameType)
{
nsIAtom* pseudo = aFrame->StyleContext()->GetPseudo();
if (pseudo == nsCSSAnonBoxes::fieldsetContent ||
pseudo == nsCSSAnonBoxes::scrolledContent) {
return IsFrameForFieldSet(aFrame->GetParent(), aFrame->GetParent()->GetType());
}
return aFrameType == nsGkAtoms::fieldSetFrame;
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindHTMLData(Element* aElement,
@ -3284,9 +3311,7 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement,
"Unexpected parent for fieldset content anon box");
if (aTag == nsGkAtoms::legend &&
(!aParentFrame ||
(aParentFrame->GetType() != nsGkAtoms::fieldSetFrame &&
aParentFrame->StyleContext()->GetPseudo() !=
nsCSSAnonBoxes::fieldsetContent) ||
!IsFrameForFieldSet(aParentFrame, aParentFrame->GetType()) ||
!aElement->GetParent() ||
!aElement->GetParent()->IsHTML(nsGkAtoms::fieldset) ||
aStyleContext->StyleDisplay()->IsFloatingStyle() ||
@ -5919,13 +5944,8 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
{
nsIFrame* parentFrame = aSibling->GetParent();
nsIAtom* parentType = nullptr;
nsIAtom* grandparentType = nullptr;
if (parentFrame) {
parentType = parentFrame->GetType();
nsIFrame* grandparentFrame = parentFrame->GetParent();
if (grandparentFrame) {
grandparentType = grandparentFrame->GetType();
}
}
uint8_t siblingDisplay = aSibling->GetDisplay();
@ -5984,9 +6004,7 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
return true;
}
else if (nsGkAtoms::fieldSetFrame == parentType ||
(nsGkAtoms::fieldSetFrame == grandparentType &&
nsGkAtoms::blockFrame == parentType)) {
else if (IsFrameForFieldSet(parentFrame, parentType)) {
// Legends can be sibling of legends but not of other content in the fieldset
nsIAtom* sibType = aSibling->GetContentInsertionFrame()->GetType();
bool legendContent = aContent->IsHTML(nsGkAtoms::legend);
@ -7083,7 +7101,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// fieldsets have multiple insertion points.
NS_ASSERTION(isSingleInsert || frameType != nsGkAtoms::fieldSetFrame,
"Unexpected parent");
if (frameType == nsGkAtoms::fieldSetFrame &&
if (IsFrameForFieldSet(parentFrame, frameType) &&
aStartChild->Tag() == nsGkAtoms::legend) {
// Just reframe the parent, since figuring out whether this
// should be the new legend and then handling it is too complex.

View File

@ -2807,7 +2807,8 @@ static int32_t gNoiseIndent = 0;
/* static */ nscoord
nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
nsIFrame *aFrame,
IntrinsicWidthType aType)
IntrinsicWidthType aType,
uint32_t aFlags)
{
NS_PRECONDITION(aFrame, "null frame");
NS_PRECONDITION(aType == MIN_WIDTH || aType == PREF_WIDTH, "bad type");
@ -2901,15 +2902,17 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
// fall through
}
case NS_STYLE_BOX_SIZING_PADDING: {
const nsStylePadding* stylePadding = aFrame->StylePadding();
nscoord pad;
if (GetAbsoluteCoord(stylePadding->mPadding.GetTop(), pad) ||
GetPercentHeight(stylePadding->mPadding.GetTop(), aFrame, pad)) {
heightTakenByBoxSizing += pad;
}
if (GetAbsoluteCoord(stylePadding->mPadding.GetBottom(), pad) ||
GetPercentHeight(stylePadding->mPadding.GetBottom(), aFrame, pad)) {
heightTakenByBoxSizing += pad;
if (!(aFlags & IGNORE_PADDING)) {
const nsStylePadding* stylePadding = aFrame->StylePadding();
nscoord pad;
if (GetAbsoluteCoord(stylePadding->mPadding.GetTop(), pad) ||
GetPercentHeight(stylePadding->mPadding.GetTop(), aFrame, pad)) {
heightTakenByBoxSizing += pad;
}
if (GetAbsoluteCoord(stylePadding->mPadding.GetBottom(), pad) ||
GetPercentHeight(stylePadding->mPadding.GetBottom(), aFrame, pad)) {
heightTakenByBoxSizing += pad;
}
}
// fall through
}
@ -2960,18 +2963,22 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
// percentages do not operate linearly.
// Doing this is ok because although percentages aren't handled
// linearly, they are handled monotonically.
nscoord coordOutsideWidth = offsets.hPadding;
float pctOutsideWidth = offsets.hPctPadding;
nscoord coordOutsideWidth = 0;
float pctOutsideWidth = 0;
float pctTotal = 0.0f;
if (boxSizing == NS_STYLE_BOX_SIZING_PADDING) {
min += coordOutsideWidth;
result = NSCoordSaturatingAdd(result, coordOutsideWidth);
pctTotal += pctOutsideWidth;
if (!(aFlags & IGNORE_PADDING)) {
coordOutsideWidth += offsets.hPadding;
pctOutsideWidth += offsets.hPctPadding;
coordOutsideWidth = 0;
pctOutsideWidth = 0.0f;
if (boxSizing == NS_STYLE_BOX_SIZING_PADDING) {
min += coordOutsideWidth;
result = NSCoordSaturatingAdd(result, coordOutsideWidth);
pctTotal += pctOutsideWidth;
coordOutsideWidth = 0;
pctOutsideWidth = 0.0f;
}
}
coordOutsideWidth += offsets.hBorder;

View File

@ -988,9 +988,13 @@ public:
* and margin.
*/
enum IntrinsicWidthType { MIN_WIDTH, PREF_WIDTH };
enum {
IGNORE_PADDING = 0x01
};
static nscoord IntrinsicForContainer(nsRenderingContext* aRenderingContext,
nsIFrame* aFrame,
IntrinsicWidthType aType);
IntrinsicWidthType aType,
uint32_t aFlags = 0);
/*
* Convert nsStyleCoord to nscoord when percentages depend on the

View File

@ -15,6 +15,7 @@
#include "nsStyleConsts.h"
#include "nsDisplayList.h"
#include "nsRenderingContext.h"
#include "nsIScrollableFrame.h"
#include "mozilla/Likely.h"
using namespace mozilla;
@ -78,6 +79,10 @@ public:
return nsContainerFrame::IsFrameOfType(aFlags &
~nsIFrame::eCanContainOverflowContainers);
}
virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE
{
return do_QueryFrame(GetInner());
}
#ifdef ACCESSIBILITY
virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
@ -356,10 +361,14 @@ nsFieldSetFrame::GetIntrinsicWidth(nsRenderingContext* aRenderingContext,
}
if (nsIFrame* inner = GetInner()) {
// Ignore padding on the inner, since the padding will be applied to the
// outer instead, and the padding computed for the inner is wrong
// for percentage padding.
contentWidth =
nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, aType);
nsLayoutUtils::IntrinsicForContainer(aRenderingContext, inner, aType,
nsLayoutUtils::IGNORE_PADDING);
}
return std::max(legendWidth, contentWidth);
}
@ -444,7 +453,10 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
// We don't allow fieldsets to break vertically. If we did, we'd
// need logic here to push and pull overflow frames.
nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
// Since we're not applying our padding in this frame, we need to add it here
// to compute the available width for our children.
nsSize availSize(aReflowState.ComputedWidth() + aReflowState.mComputedPadding.LeftRight(),
NS_UNCONSTRAINEDSIZE);
NS_ASSERTION(!inner ||
nsLayoutUtils::IntrinsicForContainer(aReflowState.rendContext,
inner,
@ -459,8 +471,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
"Bogus availSize.width; should be bigger");
// get our border and padding
const nsMargin &borderPadding = aReflowState.mComputedBorderPadding;
nsMargin border = borderPadding - aReflowState.mComputedPadding;
nsMargin border = aReflowState.mComputedBorderPadding - aReflowState.mComputedPadding;
// Figure out how big the legend is if there is one.
// get the legend's margin
@ -481,7 +492,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
legendMargin = legend->GetUsedMargin();
mLegendRect.width = legendDesiredSize.width + legendMargin.left + legendMargin.right;
mLegendRect.height = legendDesiredSize.height + legendMargin.top + legendMargin.bottom;
mLegendRect.x = borderPadding.left;
mLegendRect.x = 0;
mLegendRect.y = 0;
nscoord oldSpace = mLegendSpace;
@ -513,16 +524,22 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
// reflow the content frame only if needed
if (reflowInner) {
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, inner,
availSize);
availSize, -1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
// Override computed padding, in case it's percentage padding
kidReflowState.Init(aPresContext, -1, -1, nullptr,
&aReflowState.mComputedPadding);
// Our child is "height:100%" but we actually want its height to be reduced
// by the amount of content-height the legend is eating up, unless our
// height is unconstrained (in which case the child's will be too).
if (aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE) {
kidReflowState.SetComputedHeight(std::max(0, aReflowState.ComputedHeight() - mLegendSpace));
kidReflowState.SetComputedHeight(
std::max(0, aReflowState.ComputedHeight() - mLegendSpace));
}
kidReflowState.mComputedMinHeight =
std::max(0, aReflowState.mComputedMinHeight - mLegendSpace);
if (aReflowState.mComputedMinHeight > 0) {
kidReflowState.mComputedMinHeight =
std::max(0, aReflowState.mComputedMinHeight - mLegendSpace);
}
if (aReflowState.mComputedMaxHeight != NS_UNCONSTRAINEDSIZE) {
kidReflowState.mComputedMaxHeight =
@ -533,7 +550,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
// Reflow the frame
NS_ASSERTION(kidReflowState.mComputedMargin == nsMargin(0,0,0,0),
"Margins on anonymous fieldset child not supported!");
nsPoint pt(borderPadding.left, borderPadding.top + mLegendSpace);
nsPoint pt(border.left, border.top + mLegendSpace);
ReflowChild(inner, aPresContext, kidDesiredSize, kidReflowState,
pt.x, pt.y, 0, aStatus);
@ -542,37 +559,45 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
NS_FRAME_TRACE_REFLOW_OUT("FieldSet::Reflow", aStatus);
}
nsRect contentRect(0,0,0,0);
nsRect contentRect;
if (inner) {
// We don't support margins on inner, so our "content rect" is just
// its rect.
// We don't support margins on inner, so our content rect is just the
// inner's border-box.
contentRect = inner->GetRect();
}
// use the computed width if the inner content does not fill it
if (aReflowState.ComputedWidth() > contentRect.width) {
contentRect.width = aReflowState.ComputedWidth();
// Our content rect must fill up the available width
if (availSize.width > contentRect.width) {
contentRect.width = availSize.width;
}
if (legend) {
// if the content rect is larger then the legend we can align the legend
if (contentRect.width > mLegendRect.width) {
// the legend is postioned horizontally within the inner's content rect
// (so that padding on the fieldset affects the legend position).
nsRect innerContentRect = contentRect;
innerContentRect.Deflate(aReflowState.mComputedPadding);
// if the inner content rect is larger than the legend, we can align the legend
if (innerContentRect.width > mLegendRect.width) {
int32_t align = static_cast<nsLegendFrame*>
(legend->GetContentInsertionFrame())->GetAlign();
switch(align) {
switch (align) {
case NS_STYLE_TEXT_ALIGN_RIGHT:
mLegendRect.x = contentRect.width - mLegendRect.width + borderPadding.left;
mLegendRect.x = innerContentRect.XMost() - mLegendRect.width;
break;
case NS_STYLE_TEXT_ALIGN_CENTER:
// Note: rounding removed; there doesn't seem to be any need
mLegendRect.x = contentRect.width / 2 - mLegendRect.width / 2 + borderPadding.left;
mLegendRect.x = innerContentRect.width / 2 - mLegendRect.width / 2 + innerContentRect.x;
break;
default:
mLegendRect.x = innerContentRect.x;
break;
}
} else {
// otherwise make place for the legend
contentRect.width = mLegendRect.width;
mLegendRect.x = innerContentRect.x;
innerContentRect.width = mLegendRect.width;
contentRect.width = mLegendRect.width + aReflowState.mComputedPadding.LeftRight();
}
// place the legend
nsRect actualLegendRect(mLegendRect);
@ -594,16 +619,16 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext,
// Return our size and our result
if (aReflowState.ComputedHeight() == NS_INTRINSICSIZE) {
aDesiredSize.height = mLegendSpace +
borderPadding.TopBottom() +
contentRect.height;
border.TopBottom() +
(inner ? inner->GetRect().height : 0);
} else {
nscoord min = borderPadding.TopBottom() + mLegendRect.height;
nscoord min = border.TopBottom() + mLegendRect.height;
aDesiredSize.height =
aReflowState.ComputedHeight() + borderPadding.TopBottom();
aReflowState.ComputedHeight() + aReflowState.mComputedBorderPadding.TopBottom();
if (aDesiredSize.height < min)
aDesiredSize.height = min;
}
aDesiredSize.width = contentRect.width + borderPadding.LeftRight();
aDesiredSize.width = contentRect.width + border.LeftRight();
aDesiredSize.SetOverflowAreasToDesiredBounds();
if (legend)
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, legend);
@ -681,9 +706,6 @@ nsFieldSetFrame::ReparentFrameList(const nsFrameList& aFrameList)
nscoord
nsFieldSetFrame::GetBaseline() const
{
// We know inner is a block, so calling GetBaseline() on it will do
// the right thing (that being to return the baseline of the last line).
nsIFrame* inner = GetInner();
NS_ASSERTION(nsLayoutUtils::GetAsBlock(inner), "Unexpected inner");
return inner->GetPosition().y + inner->GetBaseline();
}

View File

@ -0,0 +1,24 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
fieldset {
background:pink;
overflow:hidden;
height:100px;
}
legend::after { content:"legend"; }
p {
background:lime;
height:20px;
}
</style>
</head>
<body>
<fieldset id="f1"><legend></legend><p></p></fieldset>
<br>
<fieldset id="f2"><legend></legend><p></p></fieldset>
<br>
<fieldset id="f3"><legend></legend></fieldset>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<style>
fieldset {
background:pink;
overflow:hidden;
height:100px;
}
legend::after { content:"legend"; }
p {
background:lime;
height:20px;
}
</style>
</head>
<body>
<fieldset id="f1"><p></p></fieldset>
<br>
<fieldset id="f2"><p></p></fieldset>
<br>
<fieldset id="f3"></fieldset>
<script>
function doTest() {
f1.appendChild(document.createElement('legend'));
f2.insertBefore(document.createElement('legend'), f2.firstChild);
f3.appendChild(document.createElement('legend'));
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest);
</script>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="width:200px; height:200px; padding:0">
<legend>Legend</legend>
<div style="overflow:hidden; height:100%;">
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
</div>
</fieldset>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="overflow:hidden; width:200px; height:200px; padding:0">
<legend>Legend</legend>
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
</fieldset>
</body>
</html>

View File

@ -0,0 +1,8 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="width:0; padding:0;">
<div style="width:400px; height:200px;"></div>
</fieldset>
</body>
</html>

View File

@ -0,0 +1,8 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="padding:50px; float:left;">
<div style="width:300px; height:100px;"></div>
</fieldset>
</body>
</html>

View File

@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8">
<title>Testcase for bug 261037</title>
<style type="text/css">
fieldset, div {
background:pink;
overflow:auto;
height:100px;
margin:0; padding:0; border:0;
}
p {
background:blue;
height:100px;
margin:0; padding:0;
}
.overflow {
height:110px;
}
.abs {
position:absolute;
width:100px;
top:250px;
}
p.abs {
top:0;left:0;
}
.b { border:10px solid black; }
.p { padding: 7px 0; }
.p p { height:114px; }
</style>
</head>
<body>
<div><p></p></div>
<br>
<div><p class="overflow"></p></div>
<br>
<div class="abs"><p class="abs"></p></div>
<br>
<div class="abs" style="left:120px"><p class="abs overflow"></p></div>
<br>
<div class="abs b" style="left:240px"><p class="abs"></p></div>
<br>
<div class="abs b" style="left:370px"><p class="abs overflow"></p></div>
<br>
<div class="abs b p" style="left:510px"><p class="abs"></p></div>
<br>
<div class="abs b p" style="left:640px"><p class="abs overflow"></p></div>
</body>
</html>

View File

@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8">
<title>Testcase for bug 261037</title>
<style type="text/css">
fieldset, div {
background:pink;
overflow:auto;
height:100px;
margin:0; padding:0; border:0;
}
p {
background:blue;
height:100px;
margin:0; padding:0;
}
.overflow {
height:110px;
}
.abs {
position:absolute;
width:100px;
top:250px;
}
p.abs {
top:0;left:0;
}
.b { border:10px solid black; }
.p { padding: 7px 0; }
.p p { height:114px; }
</style>
</head>
<body>
<fieldset><p></p></fieldset>
<br>
<fieldset><p class="overflow"></p></fieldset>
<br>
<fieldset class="abs"><p class="abs"></p></fieldset>
<br>
<fieldset class="abs" style="left:120px"><p class="abs overflow"></p></fieldset>
<br>
<fieldset class="abs b" style="left:240px"><p class="abs"></p></fieldset>
<br>
<fieldset class="abs b" style="left:370px"><p class="abs overflow"></p></fieldset>
<br>
<fieldset class="abs b p" style="left:510px"><p class="abs"></p></fieldset>
<br>
<fieldset class="abs b p" style="left:640px"><p class="abs overflow"></p></fieldset>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="width:700px; border:2px solid green; overflow:hidden">
<fieldset style="padding:140px; width:400px;">
<legend>Legend</legend>
TextTextTextTextTextText
</fieldset>
<fieldset style="padding:140px; display:inline;">
<legend>Legend</legend>
TextTextTextTextTextText
</fieldset>
<fieldset style="padding:140px; float:left;">
<legend>Legend</legend>
TextTextTextTextTextText
</fieldset>
</div>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="width:700px; border:2px solid green; overflow:hidden">
<fieldset style="padding:20%; width:400px;">
<legend>Legend</legend>
TextTextTextTextTextText
</fieldset>
<fieldset style="padding:20%; display:inline;">
<legend>Legend</legend>
TextTextTextTextTextText
</fieldset>
<fieldset style="padding:20%; float:left;">
<legend>Legend</legend>
TextTextTextTextTextText
</fieldset>
</div>
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="width:200px; height:200px; padding:0">
<legend>Legend</legend>
<div style="overflow:scroll; height:100%">
</fieldset>
</body>
</html>

View File

@ -0,0 +1,8 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="overflow:scroll; width:200px; height:200px; padding:0">
<legend>Legend</legend>
</fieldset>
</body>
</html>

View File

@ -0,0 +1,24 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="width:200px; height:200px; padding:0">
<legend style="overflow:hidden">Legend</legend>
<div id="d" style="overflow:hidden; height:100%;">
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
</div>
</fieldset>
<script>
d.scrollTop = 20;
</script>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body>
<fieldset id="f" style="overflow:hidden; width:200px; height:200px; padding:0">
<legend style="overflow:hidden">Legend</legend>
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
<p>Hello Kitty
</fieldset>
<script>
f.scrollTop = 0;
function doTest() {
f.scrollTop = 20;
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest);
</script>
</body>
</html>

View File

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset style="position:relative; overflow:hidden; width:500px; height:500px;">
<legend>Legend</legend>
<div style="height:1000px;">
<div style="position:absolute; left:20px; top:20px; background:yellow;">Abs-pos</div>
</div>
</fieldset>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<body>
<fieldset id="f" style="position:relative; overflow:hidden; width:500px; height:500px;">
<legend>Legend</legend>
<div style="height:1000px;">
<div style="position:absolute; left:20px; top:50px; background:yellow;">Abs-pos</div>
</div>
</fieldset>
<script>
f.scrollTop = 30;
</script>
</body>
</html>

View File

@ -0,0 +1,8 @@
== dynamic-legend-scroll-1.html dynamic-legend-scroll-1-ref.html
== fieldset-hidden-1.html fieldset-hidden-1-ref.html
== fieldset-intrinsic-width-1.html fieldset-intrinsic-width-1-ref.html
== fieldset-percentage-padding-1.html fieldset-percentage-padding-1-ref.html
== fieldset-scroll-1.html fieldset-scroll-1-ref.html
== fieldset-scrolled-1.html fieldset-scrolled-1-ref.html
== fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html
== positioned-container-1.html positioned-container-1-ref.html

View File

@ -6,6 +6,9 @@ include button/reftest.list
# legend element
include legend/reftest.list
# fieldset element
include fieldset/reftest.list
# placeholder
include placeholder/reftest.list

View File

@ -14,6 +14,8 @@
display: block;
unicode-bidi: inherit;
text-overflow: inherit;
overflow: inherit;
padding: inherit;
height: 100%; /* Need this so percentage heights of kids work right */
}