Reduce the border-radius of elements with overflow != visible so that any present scrollbars are not clipped. (Bug 459144, patch 8) r=roc a2.0=blocking:beta6+

This commit is contained in:
L. David Baron 2010-09-07 15:20:35 -07:00
Родитель bc123def7f
Коммит 619904027c
7 изменённых файлов: 249 добавлений и 0 удалений

Просмотреть файл

@ -3141,6 +3141,69 @@ nsGfxScrollFrameInner::SetCoordAttribute(nsIContent* aContent, nsIAtom* aAtom,
aContent->SetAttr(kNameSpaceID_None, aAtom, newValue, PR_TRUE);
}
static void
ReduceRadii(nscoord aXBorder, nscoord aYBorder,
nscoord& aXRadius, nscoord& aYRadius)
{
// In order to ensure that the inside edge of the border has no
// curvature, we need at least one of its radii to be zero.
if (aXRadius <= aXBorder || aYRadius <= aYBorder)
return;
// For any corner where we reduce the radii, preserve the corner's shape.
double ratio = NS_MAX(double(aXBorder) / aXRadius,
double(aYBorder) / aYRadius);
aXRadius *= ratio;
aYRadius *= ratio;
}
/**
* Implement an override for nsIFrame::GetBorderRadii to ensure that
* the clipping region for the border radius does not clip the scrollbars.
*
* In other words, we require that the border radius be reduced until the
* inner border radius at the inner edge of the border is 0 wherever we
* have scrollbars.
*/
PRBool
nsGfxScrollFrameInner::GetBorderRadii(nscoord aRadii[8]) const
{
if (!mOuter->nsContainerFrame::GetBorderRadii(aRadii))
return PR_FALSE;
// Since we can use GetActualScrollbarSizes (rather than
// GetDesiredScrollbarSizes) since this doesn't affect reflow, we
// probably should.
nsMargin sb = GetActualScrollbarSizes();
nsMargin border = mOuter->GetUsedBorder();
if (sb.left > 0 || sb.top > 0) {
ReduceRadii(border.left, border.top,
aRadii[NS_CORNER_TOP_LEFT_X],
aRadii[NS_CORNER_TOP_LEFT_Y]);
}
if (sb.top > 0 || sb.right > 0) {
ReduceRadii(border.right, border.top,
aRadii[NS_CORNER_TOP_RIGHT_X],
aRadii[NS_CORNER_TOP_RIGHT_Y]);
}
if (sb.right > 0 || sb.bottom > 0) {
ReduceRadii(border.right, border.bottom,
aRadii[NS_CORNER_BOTTOM_RIGHT_X],
aRadii[NS_CORNER_BOTTOM_RIGHT_Y]);
}
if (sb.bottom > 0 || sb.left > 0) {
ReduceRadii(border.left, border.bottom,
aRadii[NS_CORNER_BOTTOM_LEFT_X],
aRadii[NS_CORNER_BOTTOM_LEFT_Y]);
}
return PR_TRUE;
}
nsRect
nsGfxScrollFrameInner::GetScrolledRect() const
{

Просмотреть файл

@ -91,6 +91,8 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
PRBool GetBorderRadii(nscoord aRadii[8]) const;
// nsIReflowCallback
virtual PRBool ReflowFinished();
virtual void ReflowCallbackCanceled();
@ -341,6 +343,10 @@ public:
const nsPoint& aScrollPosition);
nscoord GetIntrinsicVScrollbarWidth(nsIRenderingContext *aRenderingContext);
virtual PRBool GetBorderRadii(nscoord aRadii[8]) const {
return mInner.GetBorderRadii(aRadii);
}
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
NS_IMETHOD GetPadding(nsMargin& aPadding);
@ -596,6 +602,10 @@ public:
NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetPadding(nsMargin& aPadding);
virtual PRBool GetBorderRadii(nscoord aRadii[8]) const {
return mInner.GetBorderRadii(aRadii);
}
nsresult Layout(nsBoxLayoutState& aState);
void LayoutScrollArea(nsBoxLayoutState& aState, const nsPoint& aScrollPosition);

Просмотреть файл

@ -48,3 +48,7 @@ fails == clipping-1.html clipping-1-ref.html # background color should completel
== invalidate-1a.html invalidate-1-ref.html
== invalidate-1b.html invalidate-1-ref.html
# test that border-radius is reduced for scrollbars
== scrollbar-clamping-1.html scrollbar-clamping-1-ref.html
== scrollbar-clamping-2.html scrollbar-clamping-2-ref.html

Просмотреть файл

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html dir="ltr">
<title>Test of reduction of border-radius for scrollbars (border drawing)</title>
<style>
.contain { height: 130px; position: relative }
.test {
position: absolute;
top: 0;
left: 0;
/* border-width: 2px 4px 8px 10px; */
height: 100px;
width: 200px;
/* -moz-border-radius: 12px / 15px; */
border: medium solid blue;
border-width: 2px 4px 8px 10px;
}
.cover {
position: absolute;
width: 200px;
height: 100px;
top: 2px;
left: 10px;
background: blue;
}
</style>
<div class="contain">
<!-- scrollbar along bottom -->
<div class="test" id="x" style="-moz-border-radius: 12px 12px 6.4px 10px / 15px 15px 8px 12.5px"></div>
<div class="cover" style="-moz-border-radius-topright: 5px"></div>
</div>
<div class="contain">
<!-- scrollbar along right -->
<div class="test" id="y" style="-moz-border-radius: 12px 4px 6.4px 12px / 15px 5px 8px 15px"></div>
<div class="cover"></div>
</div>
<div class="contain">
<!-- scrollbar along bottom and right -->
<div class="test" id="xy" style="-moz-border-radius: 12px 4px 6.4px 10px / 15px 5px 8px 12.5px"></div>
<div class="cover"></div>
</div>

Просмотреть файл

@ -0,0 +1,45 @@
<!DOCTYPE HTML>
<title>Test of reduction of border-radius for scrollbars (border drawing)</title>
<style>
.contain { height: 130px; position: relative }
.test {
position: absolute;
top: 0;
left: 0;
border: medium solid blue;
border-width: 2px 4px 8px 10px;
height: 100px;
width: 200px;
-moz-border-radius: 12px / 15px;
}
.cover {
position: absolute;
width: 200px;
height: 100px;
top: 2px;
left: 10px;
background: blue;
}
#x, #xy { overflow-x: scroll }
#y, #xy { overflow-y: scroll }
</style>
<div class="contain">
<div class="test" id="x"></div>
<div class="cover" style="-moz-border-radius-topright: 5px"></div>
</div>
<div class="contain">
<div class="test" id="y"></div>
<div class="cover"></div>
</div>
<div class="contain">
<div class="test" id="xy"></div>
<div class="cover"></div>
</div>

Просмотреть файл

@ -0,0 +1,34 @@
<!DOCTYPE HTML>
<html dir="ltr">
<title>Test of reduction of border-radius for scrollbars (background drawing)</title>
<style>
.contain { height: 130px; position: relative }
.test {
position: absolute;
top: 0;
left: 0;
/* border-width: 2px 4px 8px 10px; */
height: 110px;
width: 214px;
/* -moz-border-radius: 12px / 15px; */
background: blue;
}
</style>
<div class="contain">
<!-- scrollbar along bottom -->
<div class="test" id="x" style="-moz-border-radius: 12px 12px 6.4px 10px / 15px 15px 8px 12.5px"></div>
</div>
<div class="contain">
<!-- scrollbar along right -->
<div class="test" id="y" style="-moz-border-radius: 12px 4px 6.4px 12px / 15px 5px 8px 15px"></div>
</div>
<div class="contain">
<!-- scrollbar along bottom and right -->
<div class="test" id="xy" style="-moz-border-radius: 12px 4px 6.4px 10px / 15px 5px 8px 12.5px"></div>
</div>

Просмотреть файл

@ -0,0 +1,46 @@
<!DOCTYPE HTML>
<title>Test of reduction of border-radius for scrollbars (background drawing)</title>
<style>
.contain { height: 130px; position: relative }
.test {
position: absolute;
top: 0;
left: 0;
border: medium solid transparent;
background: blue;
border-width: 2px 4px 8px 10px;
height: 100px;
width: 200px;
-moz-border-radius: 12px / 15px;
}
.cover {
position: absolute;
width: 200px;
height: 100px;
top: 2px;
left: 10px;
background: blue;
}
#x, #xy { overflow-x: scroll }
#y, #xy { overflow-y: scroll }
</style>
<div class="contain">
<div class="test" id="x"></div>
<div class="cover" style="margin-top: 50px; height: 50px"></div>
</div>
<div class="contain">
<div class="test" id="y"></div>
<div class="cover" style="margin-left: 100px; width: 100px"></div>
</div>
<div class="contain">
<div class="test" id="xy"></div>
<div class="cover"></div>
</div>