Bug 1465250 - Make contain:paint trigger clipping independent of the overflow property. r=mattwoodrow

MozReview-Commit-ID: 2QbfZD1jnWX

--HG--
extra : rebase_source : c3a61463a25d9160adde3f04abc4b6b59bf42b6a
This commit is contained in:
Yusuf Sermet 2018-05-30 14:28:53 -07:00
Родитель 30ff1c45fb
Коммит f215910786
10 изменённых файлов: 122 добавлений и 85 удалений

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

@ -1831,37 +1831,31 @@ nsIFrame::GetBorderRadii(nscoord aRadii[8]) const
bool
nsIFrame::GetMarginBoxBorderRadii(nscoord aRadii[8]) const
{
if (!GetBorderRadii(aRadii)) {
return false;
}
OutsetBorderRadii(aRadii, GetUsedMargin());
NS_FOR_CSS_HALF_CORNERS(corner) {
if (aRadii[corner]) {
return true;
}
}
return false;
return GetBoxBorderRadii(aRadii, GetUsedMargin(), true);
}
bool
nsIFrame::GetPaddingBoxBorderRadii(nscoord aRadii[8]) const
{
if (!GetBorderRadii(aRadii))
return false;
InsetBorderRadii(aRadii, GetUsedBorder());
NS_FOR_CSS_HALF_CORNERS(corner) {
if (aRadii[corner])
return true;
}
return false;
return GetBoxBorderRadii(aRadii, GetUsedBorder(), false);
}
bool
nsIFrame::GetContentBoxBorderRadii(nscoord aRadii[8]) const
{
return GetBoxBorderRadii(aRadii, GetUsedBorderAndPadding(), false);
}
bool
nsIFrame::GetBoxBorderRadii(nscoord aRadii[8], nsMargin aOffset, bool aIsOutset) const
{
if (!GetBorderRadii(aRadii))
return false;
InsetBorderRadii(aRadii, GetUsedBorderAndPadding());
if (aIsOutset) {
OutsetBorderRadii(aRadii, aOffset);
} else {
InsetBorderRadii(aRadii, aOffset);
}
NS_FOR_CSS_HALF_CORNERS(corner) {
if (aRadii[corner])
return true;
@ -2515,35 +2509,28 @@ ApplyOverflowClipping(nsDisplayListBuilder* aBuilder,
bool haveRadii = false;
nscoord radii[8];
auto* disp = aFrame->StyleDisplay();
if (disp->mOverflowClipBoxBlock == NS_STYLE_OVERFLOW_CLIP_BOX_PADDING_BOX &&
disp->mOverflowClipBoxInline == NS_STYLE_OVERFLOW_CLIP_BOX_PADDING_BOX) {
clipRect = aFrame->GetPaddingRectRelativeToSelf() +
aBuilder->ToReferenceFrame(aFrame);
haveRadii = aFrame->GetPaddingBoxBorderRadii(radii);
} else {
// Only deflate the padding if we clip to the content-box in that axis.
auto wm = aFrame->GetWritingMode();
bool cbH = (wm.IsVertical() ? disp->mOverflowClipBoxBlock
: disp->mOverflowClipBoxInline) ==
NS_STYLE_OVERFLOW_CLIP_BOX_CONTENT_BOX;
bool cbV = (wm.IsVertical() ? disp->mOverflowClipBoxInline
: disp->mOverflowClipBoxBlock) ==
NS_STYLE_OVERFLOW_CLIP_BOX_CONTENT_BOX;
nsMargin bp = aFrame->GetUsedPadding();
if (!cbH) {
bp.left = bp.right = nscoord(0);
}
if (!cbV) {
bp.top = bp.bottom = nscoord(0);
}
bp += aFrame->GetUsedBorder();
bp.ApplySkipSides(aFrame->GetSkipSides());
nsRect rect(nsPoint(0, 0), aFrame->GetSize());
rect.Deflate(bp);
clipRect = rect + aBuilder->ToReferenceFrame(aFrame);
// XXX border-radius
// Only deflate the padding if we clip to the content-box in that axis.
auto wm = aFrame->GetWritingMode();
bool cbH = (wm.IsVertical() ? disp->mOverflowClipBoxBlock
: disp->mOverflowClipBoxInline) ==
NS_STYLE_OVERFLOW_CLIP_BOX_CONTENT_BOX;
bool cbV = (wm.IsVertical() ? disp->mOverflowClipBoxInline
: disp->mOverflowClipBoxBlock) ==
NS_STYLE_OVERFLOW_CLIP_BOX_CONTENT_BOX;
nsMargin bp = aFrame->GetUsedPadding();
if (!cbH) {
bp.left = bp.right = nscoord(0);
}
if (!cbV) {
bp.top = bp.bottom = nscoord(0);
}
bp += aFrame->GetUsedBorder();
bp.ApplySkipSides(aFrame->GetSkipSides());
nsRect rect(nsPoint(0, 0), aFrame->GetSize());
rect.Deflate(bp);
clipRect = rect + aBuilder->ToReferenceFrame(aFrame);
haveRadii = aFrame->GetBoxBorderRadii(radii, bp, false);
aClipState.ClipContainingBlockDescendantsExtra(clipRect, haveRadii ? radii : nullptr);
return true;
}

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

@ -626,6 +626,12 @@ public:
return true;
}
// contain: paint, which we should interpret as -moz-hidden-unscrollable
// by default.
if (aDisp->IsContainPaint()) {
return true;
}
// and overflow:hidden that we should interpret as -moz-hidden-unscrollable
if (aDisp->mOverflowX == NS_STYLE_OVERFLOW_HIDDEN &&
aDisp->mOverflowY == NS_STYLE_OVERFLOW_HIDDEN) {

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

@ -1415,6 +1415,7 @@ public:
bool GetMarginBoxBorderRadii(nscoord aRadii[8]) const;
bool GetPaddingBoxBorderRadii(nscoord aRadii[8]) const;
bool GetContentBoxBorderRadii(nscoord aRadii[8]) const;
bool GetBoxBorderRadii(nscoord aRadii[8], nsMargin aOffset, bool aIsOutset) const;
bool GetShapeBoxBorderRadii(nscoord aRadii[8]) const;
/**

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

@ -14,7 +14,7 @@
contain: paint;
width: 100px;
height: 100px;
background: green;
background: blue;
margin: 25px;
padding: 25px;
}

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

@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<style>
body {
@ -14,7 +15,8 @@
height: 100px;
background: green;
margin: 25px;
padding: 25px;
padding: 10px;
border-radius: 4em;
}
</style>
</head>

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

@ -2,7 +2,8 @@
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: 'contain: paint' with overflowing text contents.</title>
<title>CSS Test: 'contain: paint' with overflowing text contents inside a rounded rectangle box.</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<link rel="help" href="http://www.w3.org/TR/css-containment-1/#containment-paint">
<link rel="match" href="contain-paint-clip-002-ref.html">
@ -16,7 +17,8 @@
height: 100px;
background: green;
margin: 25px;
padding: 25px;
padding: 10px;
border-radius: 4em;
}
</style>
</head>

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

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Reftest Reference</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<style>
body {
margin: 0;
}
.root {
width: 100px;
height: 100px;
background: green;
margin: 25px;
padding: 25px;
overflow: hidden;
overflow-clip-box: content-box;
}
</style>
</head>
<body>
<div class="root">
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA This text should
be clipped to the content box. Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed
nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum.
Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa.
Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora
torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales
ligula in libero.
</div>
</body>
</html>

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

@ -0,0 +1,37 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: 'contain: paint' with overflowing text contents while "overflow-clip-box: content-box" enabled.</title>
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
<link rel="help" href="http://www.w3.org/TR/css-containment-1/#containment-paint">
<link rel="match" href="contain-paint-clip-006-ref.html">
<style>
body {
margin: 0;
}
.root {
contain: paint;
width: 100px;
height: 100px;
background: green;
margin: 25px;
padding: 25px;
overflow-clip-box: content-box;
}
</style>
</head>
<body>
<div class="root">
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA This text should
be clipped to the content box. Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed
nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum.
Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa.
Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora
torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales
ligula in libero.
</div>
</body>
</html>

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

@ -5,6 +5,7 @@ default-preferences pref(layout.css.contain.enabled,true)
== contain-paint-clip-003.html contain-paint-clip-003-ref.html
== contain-paint-clip-004.html contain-paint-clip-004-ref.html
== contain-paint-clip-005.html contain-paint-clip-003-ref.html
pref(layout.css.overflow-clip-box.enabled,true) == contain-paint-clip-006.html contain-paint-clip-006-ref.html
== contain-paint-containing-block-absolute-001.html contain-paint-containing-block-absolute-001-ref.html
== contain-paint-containing-block-fixed-001.html contain-paint-containing-block-fixed-001-ref.html
== contain-paint-formatting-context-float-001.html contain-paint-formatting-context-float-001-ref.html

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

@ -315,39 +315,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
}
}
#[cfg(feature = "gecko")]
fn adjust_for_contain(&mut self) {
use properties::longhands::contain::SpecifiedValue;
// An element with contain: paint needs to be a formatting context, and
// also implies overflow: clip.
//
// TODO(emilio): This mimics Gecko, but spec links are missing!
let contain = self.style.get_box().clone_contain();
if !contain.contains(SpecifiedValue::PAINT) {
return;
}
if self.style.get_box().clone_display() == Display::Inline {
self.style
.mutate_box()
.set_adjusted_display(Display::InlineBlock, false);
}
// When 'contain: paint', update overflow from 'visible' to 'clip'.
if self.style
.get_box()
.clone_contain()
.contains(SpecifiedValue::PAINT)
{
if self.style.get_box().clone_overflow_x() == Overflow::Visible {
let box_style = self.style.mutate_box();
box_style.set_overflow_x(Overflow::MozHiddenUnscrollable);
box_style.set_overflow_y(Overflow::MozHiddenUnscrollable);
}
}
}
/// When mathvariant is not "none", font-weight and font-style are
/// both forced to "normal".
#[cfg(feature = "gecko")]
@ -752,7 +719,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
#[cfg(feature = "gecko")]
{
self.adjust_for_table_text_align();
self.adjust_for_contain();
self.adjust_for_mathvariant();
self.adjust_for_justify_items();
}