Auto merge of #7496 - servo:calc_, r=SimonSapin

Implement CSS3 Calc

This is #7185 with one commit added to make it build merged with master, which got support for the `ch` unit in the meantime.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7496)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-09-02 02:33:18 -06:00
commit a547ae6826
21 changed files with 873 additions and 63 deletions

View file

@ -82,6 +82,7 @@ flaky_cpu == append_style_a.html append_style_b.html
== box_sizing_border_box_a.html box_sizing_border_box_ref.html
== box_sizing_sanity_check_a.html box_sizing_sanity_check_ref.html
== br.html br-ref.html
== calc-basic.html calc-basic-ref.html
== canvas_as_block_element_a.html canvas_as_block_element_ref.html
== canvas_linear_gradient_a.html canvas_linear_gradient_ref.html
== canvas_radial_gradient_a.html canvas_radial_gradient_ref.html

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<div id="outer">
<div id="inner">
</div>
</div>
<style>
#outer {
height: 100px;
width: 200px;
}
#inner {
height: 100%;
width: 110px;
background-color: green;
}
</style>

19
tests/ref/calc-basic.html Normal file
View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<div id="outer">
<div id="inner">
</div>
</div>
<style>
#outer {
height: 100px;
width: 200px;
}
#inner {
height: 100%;
width: calc(50px + 30%);
background-color: green;
}
</style>

View file

@ -1,5 +1,6 @@
<!DOCTYPE html>
<title>font-size (issues #1435, #3417)</title>
<style>p { margin: .5em }</style>
<body style="font-size: 20px">
<p style="font-size: 24pt">24pt is 32px.
<p style="font-size: 2em">2em is 40px.

View file

@ -1,5 +1,6 @@
<!DOCTYPE html>
<title>font-size (issues #1435, #3417)</title>
<style>p { margin: .5em }</style>
<body>
<p style="font-size: 32px">24pt is 32px.
<p style="font-size: 40px">2em is 40px.

View file

@ -299,6 +299,12 @@
"url": "/_mozilla/mozilla/body_listener.html"
}
],
"mozilla/calc.html": [
{
"path": "mozilla/calc.html",
"url": "/_mozilla/mozilla/calc.html"
}
],
"mozilla/caption.html": [
{
"path": "mozilla/caption.html",

View file

@ -0,0 +1,128 @@
[calc.html]
type: testharness
[calc(1px + 1pt + 1pc + 1in + 1cm + 1mm)]
expected: FAIL
[calc(0px + 0pt + 0pc + 0in + 0cm + 0mm + 0rem + 0em + 0ex + 0% + 0vw + 0vh + 0vmin + 0vmax)]
expected: FAIL
[calc for border-width]
expected: FAIL
[calc for border-top-width]
expected: FAIL
[calc for border-left-width]
expected: FAIL
[calc for border-right-width]
expected: FAIL
[calc for border-bottom-width]
expected: FAIL
[calc for outline-width]
expected: FAIL
[calc for outline-offset]
expected: FAIL
[calc for letter-spacing]
expected: FAIL
[calc for word-spacing]
expected: FAIL
[calc for border-spacing]
expected: FAIL
[calc for column-width]
expected: FAIL
[calc for column-gap]
expected: FAIL
[calc for perspective]
expected: FAIL
[calc for border-top-left-radius]
expected: FAIL
[calc for border-bottom-left-radius]
expected: FAIL
[calc for border-top-right-radius]
expected: FAIL
[calc for border-bottom-right-radius]
expected: FAIL
[calc for top]
expected: FAIL
[calc for left]
expected: FAIL
[calc for bottom]
expected: FAIL
[calc for right]
expected: FAIL
[calc for width]
expected: FAIL
[calc for height]
expected: FAIL
[calc for min-width]
expected: FAIL
[calc for min-height]
expected: FAIL
[calc for max-width]
expected: FAIL
[calc for max-height]
expected: FAIL
[calc for line-height]
expected: FAIL
[calc for vertical-align]
expected: FAIL
[calc for background-position]
expected: FAIL
[calc for background-size]
expected: FAIL
[calc for font-size]
expected: FAIL
[calc for text-indent]
expected: FAIL
[calc for transform-origin]
expected: FAIL
[calc for perspective-origin]
expected: FAIL
[calc for transition-delay]
expected: FAIL
[calc for z-index]
expected: FAIL
[calc for column-count]
expected: FAIL
[calc for opacity]
expected: FAIL
[calc for transition-duration]
expected: FAIL

View file

@ -0,0 +1,153 @@
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#outer {
width: 1000px;
}
</style>
</head>
<body>
<div id="outer">FOO<div id="inner"></div></div>
<script>
var div = document.getElementById('inner');
var widthTests = [
['calc(10px)', '10px', '10px'],
// Basic Arithmetic
['calc(10px + 10px)', '20px', '20px'],
['calc(10px - 5px)', '5px', '5px'],
['calc(2 * 10px)', '20px', '20px'],
['calc(10px / 2)', '5px', '5px'],
// Parse ok
['calc(20px/2)', '10px', '10px'],
['calc(10px*2)', '20px', '20px'],
// Parse errors - value left over from previous test
['calc(10px-10px)', '20px', '20px'],
['calc(5px+5px)', '20px', '20px'],
// Combining units
['calc(10px + 10em)', 'calc(10em + 10px)', '170px'],
['calc(10px + 10em - 10px)', 'calc(10em + 0px)', '160px'],
// Fold absolute units
['calc(1px + 1pt + 1pc + 1in + 1cm + 1mm)', '155.88333333333333px', '155.88333333333333px'],
// Alphabetical order
['calc(0px + 0pt + 0pc + 0in + 0cm + 0mm + 0rem + 0em + 0ex + 0% + 0vw + 0vh + 0vmin + 0vmax)',
'calc(0em + 0ex + 0px + 0rem + 0vh + 0vmax + 0vmin + 0vw + 0%)',
'0px'],
// Simplification
['calc((2 - 1) * 10px)', '10px', '10px'],
['calc(((3 - 1) * (8 + 4)) * 10px)', '240px', '240px'],
['calc(5 * (20px / 2 + 7 * (3em + 12px/4 + (8 - 2) * 2rem)))', 'calc(105em + 155px + 420rem)', '8555px'],
];
widthTests.forEach(function(item) {
test(function() {
div.style.setProperty('width', item[0]);
assert_equals(div.style.getPropertyValue('width'), item[1]);
assert_equals(window.getComputedStyle(div).getPropertyValue('width'), item[2]);
}, item[0]);
});
var lengthProperties = [
'border-width',
'border-top-width',
'border-left-width',
'border-right-width',
'border-bottom-width',
'outline-width',
'outline-offset',
'letter-spacing',
'word-spacing',
'border-spacing',
'column-width',
'column-gap',
'perspective',
];
lengthProperties.forEach(function(prop) {
test(function() {
div.style.setProperty(prop, 'calc(1px)');
assert_equals(div.style.getPropertyValue(prop), '1px');
assert_equals(window.getComputedStyle(div).getPropertyValue(prop), '1px');
}, 'calc for ' + prop);
});
var lengthOrPercentageProperties = [
'border-top-left-radius',
'border-bottom-left-radius',
'border-top-right-radius',
'border-bottom-right-radius',
'top',
'left',
'bottom',
'right',
'width',
'height',
'min-width',
'min-height',
'max-width',
'max-height',
'line-height',
'vertical-align',
'background-position',
'background-size',
'font-size',
'text-indent',
'transform-origin',
'perspective-origin',
];
lengthOrPercentageProperties.forEach(function(prop) {
test(function() {
div.style.setProperty(prop, 'calc(1px + 0%)');
assert_equals(div.style.getPropertyValue(prop), 'calc(1px + 0%)');
assert_equals(window.getComputedStyle(div).getPropertyValue(prop), '1px');
}, 'calc for ' + prop);
});
var timeProperties = [
'transition-delay',
];
timeProperties.forEach(function(prop) {
test(function() {
div.style.setProperty(prop, 'calc(1s)');
assert_equals(div.style.getPropertyValue(prop), '1s');
assert_equals(window.getComputedStyle(div).getPropertyValue(prop), '1s');
}, 'calc for ' + prop);
});
var numberProperties = [
'z-index',
'column-count',
'opacity',
'transition-duration',
];
numberProperties.forEach(function(prop) {
test(function() {
div.style.setProperty(prop, 'calc(1)');
assert_equals(div.style.getPropertyValue(prop), '1');
assert_equals(window.getComputedStyle(div).getPropertyValue(prop), '1');
}, 'calc for ' + prop);
});
/* TODO: test these:
counter-increment, counter-reset,
color, box-shadow, clip, text-shadow, transform
transition-timing-function
*/
</script>
</head>
</html>