Bug 483446 - CSS3 'background-attachment: local' support. r=roc

This commit is contained in:
Simon Sapin 2013-07-23 09:22:58 -04:00
parent 355e4e73f5
commit d6f3091b8f
41 changed files with 986 additions and 7 deletions

View File

@ -1677,12 +1677,14 @@ SetupDirtyRects(const nsRect& aBGClipArea, const nsRect& aCallerDirtyRect,
}
struct BackgroundClipState {
nsRect mBGClipArea;
nsRect mBGClipArea; // Affected by mClippedRadii
nsRect mAdditionalBGClipArea; // Not affected by mClippedRadii
nsRect mDirtyRect;
gfxRect mDirtyRectGfx;
gfxCornerSizes mClippedRadii;
bool mRadiiAreOuter;
bool mHasAdditionalBGClipArea;
// Whether we are being asked to draw with a caller provided background
// clipping area. If this is true we also disable rounded corners.
@ -1691,15 +1693,49 @@ struct BackgroundClipState {
static void
GetBackgroundClip(gfxContext *aCtx, uint8_t aBackgroundClip,
uint8_t aBackgroundAttachment,
nsIFrame* aForFrame, const nsRect& aBorderArea,
const nsRect& aCallerDirtyRect, bool aHaveRoundedCorners,
const gfxCornerSizes& aBGRadii, nscoord aAppUnitsPerPixel,
/* out */ BackgroundClipState* aClipState)
{
aClipState->mBGClipArea = aBorderArea;
aClipState->mHasAdditionalBGClipArea = false;
aClipState->mCustomClip = false;
aClipState->mRadiiAreOuter = true;
aClipState->mClippedRadii = aBGRadii;
if (aForFrame->GetType() == nsGkAtoms::scrollFrame &&
NS_STYLE_BG_ATTACHMENT_LOCAL == aBackgroundAttachment) {
// As of this writing, this is still in discussion in the CSS Working Group
// http://lists.w3.org/Archives/Public/www-style/2013Jul/0250.html
// The rectangle for 'background-clip' scrolls with the content,
// but the background is also clipped at a non-scrolling 'padding-box'
// like the content. (See below.)
// Therefore, only 'content-box' makes a difference here.
if (aBackgroundClip == NS_STYLE_BG_CLIP_CONTENT) {
nsIScrollableFrame* scrollableFrame = do_QueryFrame(aForFrame);
// Clip at a rectangle attached to the scrolled content.
aClipState->mHasAdditionalBGClipArea = true;
aClipState->mAdditionalBGClipArea = nsRect(
aClipState->mBGClipArea.TopLeft()
+ scrollableFrame->GetScrolledFrame()->GetPosition()
// For the dir=rtl case:
+ scrollableFrame->GetScrollRange().TopLeft(),
scrollableFrame->GetScrolledRect().Size());
nsMargin padding = aForFrame->GetUsedPadding();
// padding-bottom is ignored on scrollable frames:
// https://bugzilla.mozilla.org/show_bug.cgi?id=748518
padding.bottom = 0;
aForFrame->ApplySkipSides(padding);
aClipState->mAdditionalBGClipArea.Deflate(padding);
}
// Also clip at a non-scrolling, rounded-corner 'padding-box',
// same as the scrolled content because of the 'overflow' property.
aBackgroundClip = NS_STYLE_BG_CLIP_PADDING;
}
if (aBackgroundClip != NS_STYLE_BG_CLIP_BORDER) {
nsMargin border = aForFrame->GetUsedBorder();
if (aBackgroundClip == NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING) {
@ -1731,6 +1767,13 @@ GetBackgroundClip(gfxContext *aCtx, uint8_t aBackgroundClip,
}
}
if (!aHaveRoundedCorners && aClipState->mHasAdditionalBGClipArea) {
// Do the intersection here to account for the fast path(?) below.
aClipState->mBGClipArea =
aClipState->mBGClipArea.Intersect(aClipState->mAdditionalBGClipArea);
aClipState->mHasAdditionalBGClipArea = false;
}
SetupDirtyRects(aClipState->mBGClipArea, aCallerDirtyRect, aAppUnitsPerPixel,
&aClipState->mDirtyRect, &aClipState->mDirtyRectGfx);
}
@ -1759,6 +1802,20 @@ SetupBackgroundClip(BackgroundClipState& aClipState, gfxContext *aCtx,
// as above with bgArea, arguably a bug, but table painting seems
// to depend on it.
if (aHaveRoundedCorners || aClipState.mHasAdditionalBGClipArea) {
aAutoSR->Reset(aCtx);
}
if (aClipState.mHasAdditionalBGClipArea) {
gfxRect bgAreaGfx = nsLayoutUtils::RectToGfxRect(
aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
bgAreaGfx.Round();
bgAreaGfx.Condition();
aCtx->NewPath();
aCtx->Rectangle(bgAreaGfx, true);
aCtx->Clip();
}
if (aHaveRoundedCorners) {
gfxRect bgAreaGfx =
nsLayoutUtils::RectToGfxRect(aClipState.mBGClipArea, aAppUnitsPerPixel);
@ -1774,7 +1831,6 @@ SetupBackgroundClip(BackgroundClipState& aClipState, gfxContext *aCtx,
return;
}
aAutoSR->Reset(aCtx);
aCtx->NewPath();
aCtx->RoundedRectangle(bgAreaGfx, aClipState.mClippedRadii, aClipState.mRadiiAreOuter);
aCtx->Clip();
@ -1821,9 +1877,20 @@ DrawBackgroundColor(BackgroundClipState& aClipState, gfxContext *aCtx,
aCtx->Rectangle(dirty, true);
aCtx->Clip();
if (aClipState.mHasAdditionalBGClipArea) {
gfxRect bgAdditionalAreaGfx = nsLayoutUtils::RectToGfxRect(
aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
bgAdditionalAreaGfx.Round();
bgAdditionalAreaGfx.Condition();
aCtx->NewPath();
aCtx->Rectangle(bgAdditionalAreaGfx, true);
aCtx->Clip();
}
aCtx->NewPath();
aCtx->RoundedRectangle(bgAreaGfx, aClipState.mClippedRadii,
aClipState.mRadiiAreOuter);
aCtx->Fill();
aCtx->Restore();
}
@ -2594,7 +2661,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_BG_CLIP_PADDING;
}
GetBackgroundClip(ctx, currentBackgroundClip, aForFrame, aBorderArea,
GetBackgroundClip(ctx, currentBackgroundClip, bg->BottomLayer().mAttachment,
aForFrame, aBorderArea,
aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
&clipState);
}
@ -2662,7 +2730,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
// already called GetBackgroundClip above and it stored its results
// in clipState.
if (clipSet) {
GetBackgroundClip(ctx, currentBackgroundClip, aForFrame,
GetBackgroundClip(ctx, currentBackgroundClip, layer.mAttachment, aForFrame,
aBorderArea, aDirtyRect, haveRoundedCorners,
bgRadii, appUnitsPerPixel, &clipState);
}
@ -2769,7 +2837,8 @@ nsCSSRendering::PaintBackgroundColorWithSC(nsPresContext* aPresContext,
}
BackgroundClipState clipState;
GetBackgroundClip(ctx, currentBackgroundClip, aForFrame, aBorderArea,
GetBackgroundClip(ctx, currentBackgroundClip, bg->BottomLayer().mAttachment,
aForFrame, aBorderArea,
aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
&clipState);
@ -2833,6 +2902,31 @@ nsCSSRendering::ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
if (geometryFrame) {
bgPositioningArea = geometryFrame->GetRect();
}
} else if (frameType == nsGkAtoms::scrollFrame &&
NS_STYLE_BG_ATTACHMENT_LOCAL == aLayer.mAttachment) {
nsIScrollableFrame* scrollableFrame = do_QueryFrame(aForFrame);
bgPositioningArea = nsRect(
scrollableFrame->GetScrolledFrame()->GetPosition()
// For the dir=rtl case:
+ scrollableFrame->GetScrollRange().TopLeft(),
scrollableFrame->GetScrolledRect().Size());
// The ScrolledRects size does not include the borders or scrollbars,
// reverse the handling of background-origin
// compared to the common case below.
if (aLayer.mOrigin == NS_STYLE_BG_ORIGIN_BORDER) {
nsMargin border = geometryFrame->GetUsedBorder();
geometryFrame->ApplySkipSides(border);
bgPositioningArea.Inflate(border);
bgPositioningArea.Inflate(scrollableFrame->GetActualScrollbarSizes());
} else if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
nsMargin padding = geometryFrame->GetUsedPadding();
geometryFrame->ApplySkipSides(padding);
bgPositioningArea.Deflate(padding);
NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
"unknown background-origin value");
}
*aAttachedToFrame = aForFrame;
return bgPositioningArea;
} else {
bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
}

View File

@ -233,6 +233,7 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
// See nsStyleBackground
#define NS_STYLE_BG_ATTACHMENT_SCROLL 0
#define NS_STYLE_BG_ATTACHMENT_FIXED 1
#define NS_STYLE_BG_ATTACHMENT_LOCAL 2
// See nsStyleBackground
// Code depends on these constants having the same values as BG_ORIGIN_*

View File

@ -498,6 +498,9 @@ public:
nsBoxLayoutState bls(aPresContext, aRC, 0);
return mInner.GetNondisappearingScrollbarWidth(&bls);
}
virtual nsRect GetScrolledRect() const MOZ_OVERRIDE {
return mInner.GetScrolledRect();
}
virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE {
return mInner.GetScrollPortRect();
}
@ -764,6 +767,9 @@ public:
nsBoxLayoutState bls(aPresContext, aRC, 0);
return mInner.GetNondisappearingScrollbarWidth(&bls);
}
virtual nsRect GetScrolledRect() const MOZ_OVERRIDE {
return mInner.GetScrolledRect();
}
virtual nsRect GetScrollPortRect() const MOZ_OVERRIDE {
return mInner.GetScrollPortRect();
}

View File

@ -87,6 +87,21 @@ public:
*/
virtual nscoord GetNondisappearingScrollbarWidth(nsPresContext* aPresContext,
nsRenderingContext* aRC) = 0;
/**
* GetScrolledRect is designed to encapsulate deciding which
* directions of overflow should be reachable by scrolling and which
* should not. Callers should NOT depend on it having any particular
* behavior (although nsXULScrollFrame currently does).
*
* This should only be called when the scrolled frame has been
* reflowed with the scroll port size given in mScrollPort.
*
* Currently it allows scrolling down and to the right for
* nsHTMLScrollFrames with LTR directionality and for all
* nsXULScrollFrames, and allows scrolling down and to the left for
* nsHTMLScrollFrames with RTL directionality.
*/
virtual nsRect GetScrolledRect() const = 0;
/**
* Get the area of the scrollport relative to the origin of this frame's
* border-box.

View File

@ -89,7 +89,7 @@ function do_test() {
"seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey",
"snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise",
"violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", "no-repeat", "repeat",
"repeat-x", "repeat-y", "fixed", "scroll", "center", "top", "bottom", "left", "right",
"repeat-x", "repeat-y", "fixed", "scroll", "local", "center", "top", "bottom", "left", "right",
"border-box", "padding-box", "content-box", "border-box", "padding-box", "content-box", "contain",
"cover", "rgb", "hsl", "-moz-rgba", "-moz-hsla", "rgba", "hsla", "none", "-moz-element", "-moz-image-rect" ];
ok(testValues(values, expected), "Shorthand property values.");

View File

@ -0,0 +1,18 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
background: green padding-box;
}
p {
margin-top: 5px;
}
</style>
<div id=outer>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,30 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: border-box; color}</title>
<link rel="match" href="attachment-local-clipping-color-1-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
overflow: hidden;
background: green local border-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,30 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: padding-box; color}</title>
<link rel="match" href="attachment-local-clipping-color-1-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
overflow: hidden;
background: green local padding-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,18 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 255px;
padding: 25px 40px 0;
border: 10px dashed;
background: green content-box;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,30 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: content-box; color}</title>
<link rel="match" href="attachment-local-clipping-color-3-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
overflow: hidden;
background: green local content-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,19 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
border-radius: 50%;
background: green padding-box;
}
p {
margin-top: 5px;
}
</style>
<div id=outer>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,31 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: border-box; color}; border-radius</title>
<link rel="match" href="attachment-local-clipping-color-4-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
background: green local border-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,31 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: padding-box; color}; border-radius</title>
<link rel="match" href="attachment-local-clipping-color-4-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
background: green local padding-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,27 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
}
#outer div {
background: green;
height: 500px;
margin-top: -15px;
}
p {
margin-top: 0;
padding-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>

View File

@ -0,0 +1,31 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: content-box; color}; border-radius</title>
<link rel="match" href="attachment-local-clipping-color-6-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
background: green local content-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,18 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
background: url(aqua-yellow-32x32.png) padding-box top -15px left 0;
}
p {
margin-top: 5px;
}
</style>
<div id=outer>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,32 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: border-box; image}</title>
<link rel="match" href="attachment-local-clipping-image-1-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
overflow: hidden;
background: url(aqua-yellow-32x32.png) local;
background-clip: border-box;
background-origin: padding-box; /* Match the reference. */
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,30 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: padding-box; image}</title>
<link rel="match" href="attachment-local-clipping-image-1-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
overflow: hidden;
background: url(aqua-yellow-32x32.png) local padding-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,18 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 255px;
padding: 25px 40px 0;
border: 10px dashed;
background: url(aqua-yellow-32x32.png) content-box;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,30 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: content-box; image}</title>
<link rel="match" href="attachment-local-clipping-image-3-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px dashed;
overflow: hidden;
background: url(aqua-yellow-32x32.png) local content-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,19 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
border-radius: 50%;
background: url(aqua-yellow-32x32.png) padding-box top -15px left 0;
}
p {
margin-top: 5px;
}
</style>
<div id=outer>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,33 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: border-box; image}; border-radius</title>
<link rel="match" href="attachment-local-clipping-image-4-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
background: url(aqua-yellow-32x32.png) local;
background-clip: border-box;
background-origin: padding-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,31 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: padding-box; image}; border-radius</title>
<link rel="match" href="attachment-local-clipping-image-4-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
background: url(aqua-yellow-32x32.png) local padding-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,27 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
}
#outer div {
background: url(aqua-yellow-32x32.png);
height: 500px;
margin-top: -15px;
}
p {
margin-top: 0;
padding-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>

View File

@ -0,0 +1,31 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; clip: content-box; image}; border-radius</title>
<link rel="match" href="attachment-local-clipping-image-6-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
width: 200px;
height: 200px;
padding: 40px;
border: 10px double;
overflow: hidden;
border-radius: 50%;
background: url(aqua-yellow-32x32.png) local content-box;
}
#outer div {
height: 500px;
}
p {
margin-top: 20px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png></p>
</div>
</div>
<script>
document.getElementById('outer').scrollTop = 15;
</script>

View File

@ -0,0 +1,16 @@
<!doctype html>
<title>background-attachment: scroll</title>
<style>
div {
background: url(aqua-yellow-32x32.png) no-repeat 100px 100px;
overflow: hidden;
height: 200px;
}
p {
padding-top: 40px;
height: 500px;
}
</style>
<div>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,19 @@
<!doctype html>
<title>background-attachment: scroll</title>
<style>
div {
background: url(aqua-yellow-32x32.png) no-repeat 100px 100px;
overflow: hidden;
height: 200px;
}
p {
padding-top: 100px;
height: 500px;
}
</style>
<div>
<p><img src=blue-32x32.png></p>
</div>
<script>
document.getElementsByTagName('div')[0].scrollTop = 60;
</script>

View File

@ -0,0 +1,25 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
border: solid;
background: url(aqua-yellow-32x32.png) local no-repeat 178px 278px;
overflow: hidden;
width: 200px;
height: 300px;
}
div div {
width: 250px;
height: 370px;
}
p {
margin: 0 0 0 -40px;
padding-top: 40px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png style="width: 160px"></p>
</div>
</div>

View File

@ -0,0 +1,35 @@
<!doctype html>
<title>CSS Test: background-attachment: local; positioning area</title>
<link rel="match" href="attachment-local-positioning-2-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
border: solid;
/* 100% 100% == (250px - 32px) (370px - 32px) == 218px 338px */
/* With scrolling, effective position is 178px 278px */
background: url(aqua-yellow-32x32.png) local no-repeat 100% 100%;
overflow: hidden;
width: 200px;
height: 300px;
}
div div {
width: 250px;
height: 370px;
}
p {
margin: 0;
padding-top: 100px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png style="width: 160px"></p>
</div>
</div>
<script>
var outer = document.getElementById('outer');
outer.scrollLeft = 40;
outer.scrollTop = 60;
</script>

View File

@ -0,0 +1,29 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
border: solid;
background: url(aqua-yellow-32x32.png) local no-repeat 178px 278px;
overflow: hidden;
width: 200px;
height: 300px;
}
div div {
width: 250px;
height: 370px;
}
p {
margin: 0;
padding-top: 100px;
text-align: right;
position: relative;
top: -60px;
left: -40px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png style="width: 160px"></p>
</div>
</div>

View File

@ -0,0 +1,36 @@
<!doctype html>
<title>CSS Test: background-attachment: local; positioning area with dir=rtl</title>
<link rel="match" href="attachment-local-positioning-3-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
border: solid;
/* 100% 100% == (250px - 32px) (370px - 32px) == 218px 338px */
/* With scrolling, effective position is 178px 278px */
background: url(aqua-yellow-32x32.png) local no-repeat 100% 100%;
overflow: hidden;
width: 200px;
height: 300px;
}
div div {
width: 250px;
height: 370px;
}
p {
margin: 0;
padding-top: 100px;
}
</style>
<div id=outer dir=rtl>
<div>
<p><img src=blue-32x32.png style="width: 160px"></p>
</div>
</div>
<script>
var outer = document.getElementById('outer');
// See https://bugzilla.mozilla.org/show_bug.cgi?id=383026 for negative values.
outer.scrollLeft = -10;
outer.scrollTop = 60;
</script>

View File

@ -0,0 +1,29 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
#outer {
border: solid;
background: url(aqua-yellow-32x32.png) local no-repeat -10px -10px;
overflow: hidden;
width: 200px;
height: 300px;
}
div div {
width: 250px;
height: 370px;
}
p {
margin: 0;
padding-top: 100px;
text-align: right;
position: relative;
top: -10px;
left: -10px;
}
</style>
<div id=outer>
<div>
<p><img src=blue-32x32.png style="width: 160px"></p>
</div>
</div>

View File

@ -0,0 +1,35 @@
<!doctype html>
<title>CSS Test: background-attachment: local; positioning area with dir=rtl, top left</title>
<link rel="match" href="attachment-local-positioning-4-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
#outer {
border: solid;
/* With scrolling, effective position is -10px -10px */
background: url(aqua-yellow-32x32.png) local no-repeat 0 0;
overflow: hidden;
width: 200px;
height: 300px;
}
div div {
width: 250px;
height: 370px;
}
p {
margin: 0;
padding-top: 100px;
}
</style>
<div id=outer dir=rtl>
<div>
<p><img src=blue-32x32.png style="width: 160px"></p>
</div>
</div>
<script>
var outer = document.getElementById('outer');
// See https://bugzilla.mozilla.org/show_bug.cgi?id=383026 for negative values.
outer.scrollLeft = -40;
outer.scrollTop = 10;
</script>

View File

@ -0,0 +1,18 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: local</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
div {
background: url(aqua-yellow-32x32.png) no-repeat 30px 25px;
overflow: hidden;
height: 200px;
}
p {
padding-left: 30px;
padding-top: 125px;
height: 500px;
}
</style>
<div>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,24 @@
<!doctype html>
<title>CSS Test: background-{attachment: local; origin: content-box}; positioning area</title>
<link rel="match" href="attachment-local-positioning-5-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
div {
background: url(aqua-yellow-32x32.png) local no-repeat content-box;
overflow: hidden;
height: 200px;
padding: 40px 30px;
}
p {
padding-top: 100px;
height: 500px;
}
</style>
<div>
<p><img src=blue-32x32.png></p>
</div>
<script>
document.getElementsByTagName('div')[0].scrollTop = 15;
</script>

View File

@ -0,0 +1,17 @@
<!doctype html>
<title>CSS Reftest Reference: background-attachment: scroll</title>
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<style>
div {
background: url(aqua-yellow-32x32.png) no-repeat 100px 100px;
overflow: hidden;
height: 200px;
}
p {
padding-top: 40px;
height: 500px;
}
</style>
<div>
<p><img src=blue-32x32.png></p>
</div>

View File

@ -0,0 +1,23 @@
<!doctype html>
<title>CSS Test: background-attachment: scroll; positioning area</title>
<link rel="match" href="attachment-scroll-positioning-1-ref.html" />
<meta name="flags" content="dom" />
<link rel="author" title="Simon Sapin" href="http://exyr.org/about/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-attachment" />
<style>
div {
background: url(aqua-yellow-32x32.png) no-repeat 100px 100px;
overflow: hidden;
height: 200px;
}
p {
padding-top: 100px;
height: 500px;
}
</style>
<div>
<p><img src=blue-32x32.png></p>
</div>
<script>
document.getElementsByTagName('div')[0].scrollTop = 60;
</script>

View File

@ -141,3 +141,24 @@ random-if(B2G) == really-big-background.html really-big-background-ref.html
== multi-background-clip-content-border.html multi-background-clip-content-border-ref.html
HTTP == background-referrer.html background-referrer-ref.html
== attachment-scroll-positioning-1.html attachment-scroll-positioning-1-ref.html
== attachment-local-positioning-1.html attachment-local-positioning-1-ref.html
== attachment-local-positioning-2.html attachment-local-positioning-2-ref.html
== attachment-local-positioning-3.html attachment-local-positioning-3-ref.html
== attachment-local-positioning-4.html attachment-local-positioning-4-ref.html
== attachment-local-positioning-5.html attachment-local-positioning-5-ref.html
== attachment-local-clipping-color-1.html attachment-local-clipping-color-1-ref.html
== attachment-local-clipping-color-2.html attachment-local-clipping-color-1-ref.html # Same ref as the previous test.
== attachment-local-clipping-color-3.html attachment-local-clipping-color-3-ref.html
== attachment-local-clipping-color-4.html attachment-local-clipping-color-4-ref.html
== attachment-local-clipping-color-5.html attachment-local-clipping-color-4-ref.html # Same ref as the previous test.
fuzzy(50,500) == attachment-local-clipping-color-6.html attachment-local-clipping-color-6-ref.html
== attachment-local-clipping-image-1.html attachment-local-clipping-image-1-ref.html
== attachment-local-clipping-image-2.html attachment-local-clipping-image-1-ref.html # Same ref as the previous test.
== attachment-local-clipping-image-3.html attachment-local-clipping-image-3-ref.html
== attachment-local-clipping-image-4.html attachment-local-clipping-image-4-ref.html
== attachment-local-clipping-image-5.html attachment-local-clipping-image-4-ref.html # Same ref as the previous test.
fuzzy(80,500) == attachment-local-clipping-image-6.html attachment-local-clipping-image-6-ref.html

View File

@ -325,6 +325,7 @@ CSS_KEY(line-through, line_through)
CSS_KEY(linear, linear)
CSS_KEY(lining-nums, lining_nums)
CSS_KEY(list-item, list_item)
CSS_KEY(local, local)
CSS_KEY(logical, logical)
CSS_KEY(lower-alpha, lower_alpha)
CSS_KEY(lower-greek, lower_greek)

View File

@ -636,6 +636,7 @@ const int32_t nsCSSProps::kTransformStyleKTable[] = {
const int32_t nsCSSProps::kBackgroundAttachmentKTable[] = {
eCSSKeyword_fixed, NS_STYLE_BG_ATTACHMENT_FIXED,
eCSSKeyword_scroll, NS_STYLE_BG_ATTACHMENT_SCROLL,
eCSSKeyword_local, NS_STYLE_BG_ATTACHMENT_LOCAL,
eCSSKeyword_UNKNOWN,-1
};

View File

@ -1363,7 +1363,7 @@ var gCSSProperties = {
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "scroll" ],
other_values: [ "fixed", "scroll,scroll", "fixed, scroll", "scroll, fixed, scroll", "fixed, fixed" ],
other_values: [ "fixed", "local", "scroll,scroll", "fixed, scroll", "scroll, fixed, local, scroll", "fixed, fixed" ],
invalid_values: []
},
"background-clip": {