Commit 080186fb authored by George Steel's avatar George Steel Committed by Commit Bot

fix background-position-xy serialization for right/bottom offsets

Make the implementations of CSSValueFromComputedStyle for
background-position-x/y return correct values when three/four-value
syntax is used with background-position. Since these properties only
support single-value syntax, positions from the right or bottom will
use calc() values if they result in mixed lengths and percentages when
converted to be from the left/top. This is not the canonical form in
the css-backgrounds-4 spec proposal, but does not require changes to
the parser.

Add a reftest (passes without patch) for three/four-value
background-position syntax (there is currently only a manual test).
Add another version of the reftest (fails without patch) which takes
the above and attempts to write back the computed values of
background-position-x/y.

This is done in preparation to make transitions use normal keyframes
which require round-trip serialization of all transition properties.

Change-Id: I50e714746cc15fd0591bcd0a41cf9ecd56f55c44
Bug: 610627
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2121415Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Commit-Queue: George Steel <gtsteel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#755462}
parent 52788b20
......@@ -289,8 +289,15 @@ const CSSValue* ComputedStyleUtils::BackgroundPositionXOrWebkitMaskPositionX(
const FillLayer* curr_layer) {
CSSValueList* list = CSSValueList::CreateCommaSeparated();
for (; curr_layer; curr_layer = curr_layer->Next()) {
list->Append(
*ZoomAdjustedPixelValueForLength(curr_layer->PositionX(), style));
const Length& from_edge = curr_layer->PositionX();
if (curr_layer->BackgroundXOrigin() == BackgroundEdgeOrigin::kRight) {
// TODO(crbug.com/610627): This should use two-value syntax once the
// parser accepts it.
list->Append(*ZoomAdjustedPixelValueForLength(
from_edge.SubtractFromOneHundredPercent(), style));
} else {
list->Append(*ZoomAdjustedPixelValueForLength(from_edge, style));
}
}
return list;
}
......@@ -300,8 +307,15 @@ const CSSValue* ComputedStyleUtils::BackgroundPositionYOrWebkitMaskPositionY(
const FillLayer* curr_layer) {
CSSValueList* list = CSSValueList::CreateCommaSeparated();
for (; curr_layer; curr_layer = curr_layer->Next()) {
list->Append(
*ZoomAdjustedPixelValueForLength(curr_layer->PositionY(), style));
const Length& from_edge = curr_layer->PositionY();
if (curr_layer->BackgroundYOrigin() == BackgroundEdgeOrigin::kBottom) {
// TODO(crbug.com/610627): This should use two-value syntax once the
// parser accepts it.
list->Append(*ZoomAdjustedPixelValueForLength(
from_edge.SubtractFromOneHundredPercent(), style));
} else {
list->Append(*ZoomAdjustedPixelValueForLength(from_edge, style));
}
}
return list;
}
......
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: 'Background-position' with three and four values</title>
<link rel="help" href="http://www.w3.org/TR/css3-background/#background-position" />
<meta name="assert" content="If three or four values are given to 'background-position', then each percentage or length value represents an offset from the edge specified by the preceeding keyword." />
<link rel="match" href="reference/background-position-three-four-values-ref.html">
<style type="text/css">
div {
width: 200px;
height: 200px;
border: 2px solid black;
background-image: url("support/blue_color.png");
background-repeat: no-repeat;
display: inline-block;
}
.test1 {
background-position: left 50px center;
}
.test2 {
background-position: right 25px top 75%;
}
.test3 {
background-position: left 25px bottom 75%;
}
.test4 {
background-position: right 25px bottom 25%;
}
</style>
</head>
<body>
<div class="test1"></div>
<div class="test2"></div>
<div class="test3"></div>
<div class="test4"></div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: 'Background-position' with three and four values</title>
<link rel="help" href="http://www.w3.org/TR/css3-background/#background-position" />
<meta name="assert" content="background-position-x/y will round-trip serialized values even if the new three/four value syntax is used for background-position." />
<link rel="match" href="reference/background-position-three-four-values-ref.html">
<style type="text/css">
div {
width: 200px;
height: 200px;
border: 2px solid black;
background-image: url("support/blue_color.png");
background-repeat: no-repeat;
display: inline-block;
}
#test1 {
background-position: left 50px center;
}
#test2 {
background-position: right 25px top 75%;
}
#test3 {
background-position: left 25px bottom 75%;
}
#test4 {
background-position: right 25px bottom 25%;
}
</style>
</head>
<body>
<div id="test1"></div>
<div id="test2"></div>
<div id="test3"></div>
<div id="test4"></div>
<script>
for (let id of ['test1','test2','test3','test4']) {
let d = document.getElementById(id);
let x = getComputedStyle(d).backgroundPositionX;
let y = getComputedStyle(d).backgroundPositionY;
d.style.backgroundPositionX = x;
d.style.backgroundPositionY = y;
}
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CSS Test: 'Background-position' with three and four values</title>
<link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
<link rel="help" href="http://www.w3.org/TR/css3-background/#background-position" />
<meta name="flags" content="" />
<meta name="assert" content="If three or four values are given to 'background-position', then each percentage or length value represents an offset from the edge specified by the keyword." />
<style type="text/css">
div
{
width: 3in;
height: 2in;
border: thick solid black;
margin: 10px;
background-image: url("support/blue_color.png");
background-repeat: no-repeat;
}
.reference
{
background-position: right center;
}
.test1
{
background-position: left 2in center;
}
.test2
{
background-position: left 2in top 50%;
}
</style>
</head>
<body>
<p>Test passes if the content of the three black boxes is identical.</p>
<div class="reference"></div>
<div class="test1"></div>
<div class="test2"></div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
div {
width: 200px;
height: 200px;
border: 2px solid black;
background-image: url("../support/blue_color.png");
background-repeat: no-repeat;
display: inline-block;
}
.test1 {
background-position: 50px 50%;
}
.test2 {
background-position: 75% 75%;
}
.test3 {
background-position: 25px 25%;
}
.test4 {
background-position: 75% 75%;
}
</style>
</head>
<body>
<div class="test1"></div>
<div class="test2"></div>
<div class="test3"></div>
<div class="test4"></div>
</body>
</html>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment