Auto merge of #13075 - emilio:calc-media, r=SimonSapin

style: Allow calc in media queries.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors

<!-- Either: -->
- [x] There are tests for these changes OR

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1290228

No tests have been added yet, I expect wpt to catch something, otherwise I'll write/import others.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13075)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-08-30 15:53:09 -05:00 committed by GitHub
commit 1fcc447941
5 changed files with 72 additions and 30 deletions

View file

@ -30,18 +30,23 @@ pub enum Range<T> {
impl Range<specified::Length> {
fn to_computed_range(&self, viewport_size: Size2D<Au>) -> Range<Au> {
let compute_width = |&width| {
match width {
specified::Length::Absolute(value) => value,
specified::Length::FontRelative(value) => {
// http://dev.w3.org/csswg/mediaqueries3/#units
// em units are relative to the initial font-size.
let initial_font_size = longhands::font_size::get_initial_value();
value.to_computed_value(initial_font_size, initial_font_size)
}
specified::Length::ViewportPercentage(value) =>
value.to_computed_value(viewport_size),
_ => unreachable!()
let compute_width = |&width| {
match width {
specified::Length::Absolute(value) => value,
specified::Length::FontRelative(value)
=> value.to_computed_value(initial_font_size, initial_font_size),
specified::Length::ViewportPercentage(value)
=> value.to_computed_value(viewport_size),
specified::Length::Calc(val)
=> val.compute_from_viewport_and_font_size(viewport_size,
initial_font_size,
initial_font_size)
.length(),
specified::Length::ServoCharacterWidth(..)
=> unreachable!(),
}
};

View file

@ -164,26 +164,9 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
type ComputedValue = CalcLengthOrPercentage;
fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
let mut length = None;
if let Some(absolute) = self.absolute {
length = Some(length.unwrap_or(Au(0)) + absolute);
}
for val in &[self.vw, self.vh, self.vmin, self.vmax] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) +
val.to_computed_value(context.viewport_size()));
}
}
for val in &[self.ch, self.em, self.ex, self.rem] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) + val.to_computed_value(
context.style().get_font().clone_font_size(), context.style().root_font_size()));
}
}
CalcLengthOrPercentage { length: length, percentage: self.percentage.map(|p| p.0) }
self.compute_from_viewport_and_font_size(context.viewport_size(),
context.style().get_font().clone_font_size(),
context.style().root_font_size())
}
}

View file

@ -16,7 +16,7 @@ use std::f32::consts::PI;
use std::fmt;
use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType;
use super::computed::{Context, ToComputedValue};
use super::computed::{self, Context, ToComputedValue};
use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage};
use url::Url;
@ -751,6 +751,37 @@ impl CalcLengthOrPercentage {
_ => Err(())
}
}
pub fn compute_from_viewport_and_font_size(&self,
viewport_size: Size2D<Au>,
font_size: Au,
root_font_size: Au)
-> computed::CalcLengthOrPercentage
{
let mut length = None;
if let Some(absolute) = self.absolute {
length = Some(length.unwrap_or(Au(0)) + absolute);
}
for val in &[self.vw, self.vh, self.vmin, self.vmax] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) +
val.to_computed_value(viewport_size));
}
}
for val in &[self.ch, self.em, self.ex, self.rem] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) + val.to_computed_value(
font_size, root_font_size));
}
}
computed::CalcLengthOrPercentage {
length: length,
percentage: self.percentage.map(|p| p.0)
}
}
}
impl HasViewportPercentage for CalcLengthOrPercentage {

View file

@ -6354,6 +6354,12 @@
"url": "/_mozilla/css/float_relative_to_position.html"
}
],
"css/media_calc_crash.html": [
{
"path": "css/media_calc_crash.html",
"url": "/_mozilla/css/media_calc_crash.html"
}
],
"css/meta_viewport_resize.html": [
{
"path": "css/meta_viewport_resize.html",

View file

@ -0,0 +1,17 @@
<!doctype html>
<meta charset="utf-8">
<title>Don't crash when a media query with calc() is found.</title>
<style>
@media (min-width: calc(60px)) {
pease-do {
not: crash;
}
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(function() {
assert_true(true, "Reached here without crashing");
})
</script>