servo: Merge #15065 - Use Box<CalcLengthOrPercentage> in specified values to avoid bloating inline sizes (from Manishearth:box-calclop); r=heycam

For #15061

CalcLOP is a large struct, and gets used quite often. While #15063 reduces its size a bit,
it will still be much larger than any of the other variants in the `specified::Length*` types,
so it will still bloat sizes, especially for specified values that contain many lengths.

This change boxes it in the length types, so that it just takes one word.

r? @heycam

Source-Repo: https://github.com/servo/servo
Source-Revision: f010fb58fdb4526a76581ba6536f807f2b2a4955
This commit is contained in:
Manish Goregaokar 2017-01-17 11:49:52 -08:00
Родитель 53573083db
Коммит 971a8aa41e
20 изменённых файлов: 280 добавлений и 249 удалений

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

@ -480,7 +480,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
hints.push(from_declaration( hints.push(from_declaration(
PropertyDeclaration::BorderSpacing(DeclaredValue::Value( PropertyDeclaration::BorderSpacing(DeclaredValue::Value(
border_spacing::SpecifiedValue { border_spacing::SpecifiedValue {
horizontal: width_value, horizontal: width_value.clone(),
vertical: width_value, vertical: width_value,
})))); }))));
} }
@ -625,11 +625,11 @@ impl LayoutElementHelpers for LayoutJS<Element> {
let width_value = specified::BorderWidth::from_length( let width_value = specified::BorderWidth::from_length(
specified::Length::Absolute(Au::from_px(border as i32))); specified::Length::Absolute(Au::from_px(border as i32)));
hints.push(from_declaration( hints.push(from_declaration(
PropertyDeclaration::BorderTopWidth(DeclaredValue::Value(width_value)))); PropertyDeclaration::BorderTopWidth(DeclaredValue::Value(width_value.clone()))));
hints.push(from_declaration( hints.push(from_declaration(
PropertyDeclaration::BorderLeftWidth(DeclaredValue::Value(width_value)))); PropertyDeclaration::BorderLeftWidth(DeclaredValue::Value(width_value.clone()))));
hints.push(from_declaration( hints.push(from_declaration(
PropertyDeclaration::BorderBottomWidth(DeclaredValue::Value(width_value)))); PropertyDeclaration::BorderBottomWidth(DeclaredValue::Value(width_value.clone()))));
hints.push(from_declaration( hints.push(from_declaration(
PropertyDeclaration::BorderRightWidth(DeclaredValue::Value(width_value)))); PropertyDeclaration::BorderRightWidth(DeclaredValue::Value(width_value))));
} }

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

@ -427,7 +427,7 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
impl ToCss for computed_value::SingleComputedValue { impl ToCss for computed_value::SingleComputedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
computed_value::SingleComputedValue::LengthOrPercentage(len) => len.to_css(dest), computed_value::SingleComputedValue::LengthOrPercentage(ref len) => len.to_css(dest),
computed_value::SingleComputedValue::Number(number) => number.to_css(dest), computed_value::SingleComputedValue::Number(number) => number.to_css(dest),
computed_value::SingleComputedValue::Auto => dest.write_str("auto"), computed_value::SingleComputedValue::Auto => dest.write_str("auto"),
} }
@ -436,7 +436,7 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
impl ToCss for SingleSpecifiedValue { impl ToCss for SingleSpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
SingleSpecifiedValue::LengthOrPercentage(len) => len.to_css(dest), SingleSpecifiedValue::LengthOrPercentage(ref len) => len.to_css(dest),
SingleSpecifiedValue::Number(number) => number.to_css(dest), SingleSpecifiedValue::Number(number) => number.to_css(dest),
SingleSpecifiedValue::Auto => dest.write_str("auto"), SingleSpecifiedValue::Auto => dest.write_str("auto"),
} }
@ -449,7 +449,7 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> computed_value::SingleComputedValue { fn to_computed_value(&self, context: &Context) -> computed_value::SingleComputedValue {
match *self { match *self {
SingleSpecifiedValue::LengthOrPercentage(len) => { SingleSpecifiedValue::LengthOrPercentage(ref len) => {
computed_value::SingleComputedValue::LengthOrPercentage( computed_value::SingleComputedValue::LengthOrPercentage(
len.to_computed_value(context)) len.to_computed_value(context))
}, },

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

@ -258,7 +258,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
SpecifiedValue::LengthOrPercentage(length) => length.has_viewport_percentage(), SpecifiedValue::LengthOrPercentage(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
@ -266,7 +266,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
/// The `vertical-align` value. /// The `vertical-align` value.
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq, Copy)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue { pub enum SpecifiedValue {
% for keyword in vertical_align_keywords: % for keyword in vertical_align_keywords:
@ -281,7 +281,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
% for keyword in vertical_align_keywords: % for keyword in vertical_align_keywords:
SpecifiedValue::${to_rust_ident(keyword)} => dest.write_str("${keyword}"), SpecifiedValue::${to_rust_ident(keyword)} => dest.write_str("${keyword}"),
% endfor % endfor
SpecifiedValue::LengthOrPercentage(value) => value.to_css(dest), SpecifiedValue::LengthOrPercentage(ref value) => value.to_css(dest),
} }
} }
} }
@ -324,7 +324,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
% for keyword in vertical_align_keywords: % for keyword in vertical_align_keywords:
T::${to_rust_ident(keyword)} => dest.write_str("${keyword}"), T::${to_rust_ident(keyword)} => dest.write_str("${keyword}"),
% endfor % endfor
T::LengthOrPercentage(value) => value.to_css(dest), T::LengthOrPercentage(ref value) => value.to_css(dest),
} }
} }
} }
@ -347,7 +347,7 @@ ${helpers.single_keyword("-moz-top-layer", "none top",
computed_value::T::${to_rust_ident(keyword)} computed_value::T::${to_rust_ident(keyword)}
} }
% endfor % endfor
SpecifiedValue::LengthOrPercentage(value) => SpecifiedValue::LengthOrPercentage(ref value) =>
computed_value::T::LengthOrPercentage(value.to_computed_value(context)), computed_value::T::LengthOrPercentage(value.to_computed_value(context)),
} }
} }
@ -954,7 +954,7 @@ ${helpers.single_keyword("animation-fill-mode",
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
SpecifiedValue::Repeat(length) => length.has_viewport_percentage(), SpecifiedValue::Repeat(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
@ -968,7 +968,7 @@ ${helpers.single_keyword("animation-fill-mode",
pub struct T(pub Option<LengthOrPercentage>); pub struct T(pub Option<LengthOrPercentage>);
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue { pub enum SpecifiedValue {
None, None,
@ -979,7 +979,7 @@ ${helpers.single_keyword("animation-fill-mode",
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match self.0 { match self.0 {
None => dest.write_str("none"), None => dest.write_str("none"),
Some(l) => { Some(ref l) => {
try!(dest.write_str("repeat(")); try!(dest.write_str("repeat("));
try!(l.to_css(dest)); try!(l.to_css(dest));
dest.write_str(")") dest.write_str(")")
@ -1012,7 +1012,7 @@ ${helpers.single_keyword("animation-fill-mode",
fn to_computed_value(&self, context: &Context) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::None => computed_value::T(None), SpecifiedValue::None => computed_value::T(None),
SpecifiedValue::Repeat(l) => SpecifiedValue::Repeat(ref l) =>
computed_value::T(Some(l.to_computed_value(context))), computed_value::T(Some(l.to_computed_value(context))),
} }
} }
@ -1167,12 +1167,12 @@ ${helpers.single_keyword("animation-fill-mode",
impl HasViewportPercentage for SpecifiedOperation { impl HasViewportPercentage for SpecifiedOperation {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
SpecifiedOperation::Translate(_, l1, l2, l3) => { SpecifiedOperation::Translate(_, ref l1, ref l2, ref l3) => {
l1.has_viewport_percentage() || l1.has_viewport_percentage() ||
l2.has_viewport_percentage() || l2.has_viewport_percentage() ||
l3.has_viewport_percentage() l3.has_viewport_percentage()
}, },
SpecifiedOperation::Perspective(length) => length.has_viewport_percentage(), SpecifiedOperation::Perspective(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
@ -1183,13 +1183,13 @@ ${helpers.single_keyword("animation-fill-mode",
match *self { match *self {
// todo(gw): implement serialization for transform // todo(gw): implement serialization for transform
// types other than translate. // types other than translate.
SpecifiedOperation::Matrix(_m) => { SpecifiedOperation::Matrix(..) => {
Ok(()) Ok(())
} }
SpecifiedOperation::Skew(_sx, _sy) => { SpecifiedOperation::Skew(..) => {
Ok(()) Ok(())
} }
SpecifiedOperation::Translate(kind, tx, ty, tz) => { SpecifiedOperation::Translate(kind, ref tx, ref ty, ref tz) => {
match kind { match kind {
TranslateKind::Translate => { TranslateKind::Translate => {
try!(dest.write_str("translate(")); try!(dest.write_str("translate("));
@ -1224,13 +1224,13 @@ ${helpers.single_keyword("animation-fill-mode",
} }
} }
} }
SpecifiedOperation::Scale(_sx, _sy, _sz) => { SpecifiedOperation::Scale(..) => {
Ok(()) Ok(())
} }
SpecifiedOperation::Rotate(_ax, _ay, _az, _angle) => { SpecifiedOperation::Rotate(..) => {
Ok(()) Ok(())
} }
SpecifiedOperation::Perspective(_p) => { SpecifiedOperation::Perspective(_) => {
Ok(()) Ok(())
} }
} }
@ -1525,7 +1525,7 @@ ${helpers.single_keyword("animation-fill-mode",
SpecifiedOperation::Skew(theta_x, theta_y) => { SpecifiedOperation::Skew(theta_x, theta_y) => {
result.push(computed_value::ComputedOperation::Skew(theta_x, theta_y)); result.push(computed_value::ComputedOperation::Skew(theta_x, theta_y));
} }
SpecifiedOperation::Perspective(d) => { SpecifiedOperation::Perspective(ref d) => {
result.push(computed_value::ComputedOperation::Perspective(d.to_computed_value(context))); result.push(computed_value::ComputedOperation::Perspective(d.to_computed_value(context)));
} }
}; };
@ -1674,7 +1674,7 @@ ${helpers.predefined_type("perspective",
} }
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue { pub struct SpecifiedValue {
horizontal: LengthOrPercentage, horizontal: LengthOrPercentage,
@ -1788,7 +1788,7 @@ ${helpers.single_keyword("transform-style",
} }
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue { pub struct SpecifiedValue {
horizontal: LengthOrPercentage, horizontal: LengthOrPercentage,

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

@ -150,13 +150,13 @@ ${helpers.predefined_type("opacity",
impl HasViewportPercentage for SpecifiedClipRect { impl HasViewportPercentage for SpecifiedClipRect {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
self.top.has_viewport_percentage() || self.top.has_viewport_percentage() ||
self.right.map_or(false, |x| x.has_viewport_percentage()) || self.right.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
self.bottom.map_or(false, |x| x.has_viewport_percentage()) || self.bottom.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
self.left.has_viewport_percentage() self.left.has_viewport_percentage()
} }
} }
#[derive(Clone, Debug, PartialEq, Copy)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedClipRect { pub struct SpecifiedClipRect {
pub top: specified::Length, pub top: specified::Length,
@ -167,12 +167,11 @@ ${helpers.predefined_type("opacity",
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
let &SpecifiedValue(clip) = self; self.0.as_ref().map_or(false, |x| x.has_viewport_percentage())
clip.map_or(false, |x| x.has_viewport_percentage())
} }
} }
#[derive(Clone, Debug, PartialEq, Copy)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue(Option<SpecifiedClipRect>); pub struct SpecifiedValue(Option<SpecifiedClipRect>);
@ -183,14 +182,14 @@ ${helpers.predefined_type("opacity",
try!(self.top.to_css(dest)); try!(self.top.to_css(dest));
try!(dest.write_str(", ")); try!(dest.write_str(", "));
if let Some(right) = self.right { if let Some(ref right) = self.right {
try!(right.to_css(dest)); try!(right.to_css(dest));
try!(dest.write_str(", ")); try!(dest.write_str(", "));
} else { } else {
try!(dest.write_str("auto, ")); try!(dest.write_str("auto, "));
} }
if let Some(bottom) = self.bottom { if let Some(ref bottom) = self.bottom {
try!(bottom.to_css(dest)); try!(bottom.to_css(dest));
try!(dest.write_str(", ")); try!(dest.write_str(", "));
} else { } else {
@ -224,10 +223,10 @@ ${helpers.predefined_type("opacity",
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.map(|value| computed_value::ClipRect { computed_value::T(self.0.as_ref().map(|value| computed_value::ClipRect {
top: value.top.to_computed_value(context), top: value.top.to_computed_value(context),
right: value.right.map(|right| right.to_computed_value(context)), right: value.right.as_ref().map(|right| right.to_computed_value(context)),
bottom: value.bottom.map(|bottom| bottom.to_computed_value(context)), bottom: value.bottom.as_ref().map(|bottom| bottom.to_computed_value(context)),
left: value.left.to_computed_value(context), left: value.left.to_computed_value(context),
})) }))
} }
@ -302,8 +301,7 @@ ${helpers.predefined_type("opacity",
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
let &SpecifiedValue(ref vec) = self; self.0.iter().any(|ref x| x.has_viewport_percentage())
vec.iter().any(|ref x| x.has_viewport_percentage())
} }
} }
@ -314,7 +312,7 @@ ${helpers.predefined_type("opacity",
impl HasViewportPercentage for SpecifiedFilter { impl HasViewportPercentage for SpecifiedFilter {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
SpecifiedFilter::Blur(length) => length.has_viewport_percentage(), SpecifiedFilter::Blur(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
@ -439,7 +437,7 @@ ${helpers.predefined_type("opacity",
impl ToCss for computed_value::Filter { impl ToCss for computed_value::Filter {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
computed_value::Filter::Blur(value) => { computed_value::Filter::Blur(ref value) => {
try!(dest.write_str("blur(")); try!(dest.write_str("blur("));
try!(value.to_css(dest)); try!(value.to_css(dest));
try!(dest.write_str(")")); try!(dest.write_str(")"));
@ -477,7 +475,7 @@ ${helpers.predefined_type("opacity",
impl ToCss for SpecifiedFilter { impl ToCss for SpecifiedFilter {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
SpecifiedFilter::Blur(value) => { SpecifiedFilter::Blur(ref value) => {
try!(dest.write_str("blur(")); try!(dest.write_str("blur("));
try!(value.to_css(dest)); try!(value.to_css(dest));
try!(dest.write_str(")")); try!(dest.write_str(")"));
@ -567,7 +565,7 @@ ${helpers.predefined_type("opacity",
fn to_computed_value(&self, context: &Context) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T{ filters: self.0.iter().map(|value| { computed_value::T{ filters: self.0.iter().map(|value| {
match *value { match *value {
SpecifiedFilter::Blur(factor) => SpecifiedFilter::Blur(ref factor) =>
computed_value::Filter::Blur(factor.to_computed_value(context)), computed_value::Filter::Blur(factor.to_computed_value(context)),
SpecifiedFilter::Brightness(factor) => computed_value::Filter::Brightness(factor), SpecifiedFilter::Brightness(factor) => computed_value::Filter::Brightness(factor),
SpecifiedFilter::Contrast(factor) => computed_value::Filter::Contrast(factor), SpecifiedFilter::Contrast(factor) => computed_value::Filter::Contrast(factor),

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

@ -309,8 +309,7 @@ ${helpers.single_keyword("font-variant-caps",
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
let &SpecifiedValue(length) = self; return self.0.has_viewport_percentage()
return length.has_viewport_percentage()
} }
} }
@ -340,13 +339,13 @@ ${helpers.single_keyword("font-variant-caps",
LengthOrPercentage::Length(Length::ServoCharacterWidth(value)) => { LengthOrPercentage::Length(Length::ServoCharacterWidth(value)) => {
value.to_computed_value(context.inherited_style().get_font().clone_font_size()) value.to_computed_value(context.inherited_style().get_font().clone_font_size())
} }
LengthOrPercentage::Length(l) => { LengthOrPercentage::Length(ref l) => {
l.to_computed_value(context) l.to_computed_value(context)
} }
LengthOrPercentage::Percentage(Percentage(value)) => { LengthOrPercentage::Percentage(Percentage(value)) => {
context.inherited_style().get_font().clone_font_size().scale_by(value) context.inherited_style().get_font().clone_font_size().scale_by(value)
} }
LengthOrPercentage::Calc(calc) => { LengthOrPercentage::Calc(ref calc) => {
let calc = calc.to_computed_value(context); let calc = calc.to_computed_value(context);
calc.length() + context.inherited_style().get_font().clone_font_size() calc.length() + context.inherited_style().get_font().clone_font_size()
.scale_by(calc.percentage()) .scale_by(calc.percentage())

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

@ -107,21 +107,26 @@ ${helpers.single_keyword("caption-side", "top bottom",
} }
pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
let mut lengths = [ None, None ]; let mut first = None;
for i in 0..2 { let mut second = None;
match specified::Length::parse_non_negative(input) { match specified::Length::parse_non_negative(input) {
Err(()) => break, Err(()) => (),
Ok(length) => lengths[i] = Some(length), Ok(length) => {
first = Some(length);
match specified::Length::parse_non_negative(input) {
Err(()) => (),
Ok(length) => second = Some(length),
}
} }
} }
if input.next().is_ok() { if input.next().is_ok() {
return Err(()) return Err(())
} }
match (lengths[0], lengths[1]) { match (first, second) {
(None, None) => Err(()), (None, None) => Err(()),
(Some(length), None) => { (Some(length), None) => {
Ok(SpecifiedValue { Ok(SpecifiedValue {
horizontal: length, horizontal: length.clone(),
vertical: length, vertical: length,
}) })
} }

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

@ -15,13 +15,13 @@
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
SpecifiedValue::LengthOrPercentage(length) => length.has_viewport_percentage(), SpecifiedValue::LengthOrPercentage(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
} }
#[derive(Debug, Clone, PartialEq, Copy)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue { pub enum SpecifiedValue {
Normal, Normal,
@ -39,7 +39,7 @@
% if product == "gecko": % if product == "gecko":
SpecifiedValue::MozBlockHeight => dest.write_str("-moz-block-height"), SpecifiedValue::MozBlockHeight => dest.write_str("-moz-block-height"),
% endif % endif
SpecifiedValue::LengthOrPercentage(value) => value.to_css(dest), SpecifiedValue::LengthOrPercentage(ref value) => value.to_css(dest),
SpecifiedValue::Number(number) => write!(dest, "{}", number), SpecifiedValue::Number(number) => write!(dest, "{}", number),
} }
} }
@ -108,15 +108,15 @@
SpecifiedValue::MozBlockHeight => computed_value::T::MozBlockHeight, SpecifiedValue::MozBlockHeight => computed_value::T::MozBlockHeight,
% endif % endif
SpecifiedValue::Number(value) => computed_value::T::Number(value), SpecifiedValue::Number(value) => computed_value::T::Number(value),
SpecifiedValue::LengthOrPercentage(value) => { SpecifiedValue::LengthOrPercentage(ref value) => {
match value { match *value {
specified::LengthOrPercentage::Length(value) => specified::LengthOrPercentage::Length(ref value) =>
computed_value::T::Length(value.to_computed_value(context)), computed_value::T::Length(value.to_computed_value(context)),
specified::LengthOrPercentage::Percentage(specified::Percentage(value)) => { specified::LengthOrPercentage::Percentage(specified::Percentage(value)) => {
let fr = specified::Length::FontRelative(specified::FontRelativeLength::Em(value)); let fr = specified::Length::FontRelative(specified::FontRelativeLength::Em(value));
computed_value::T::Length(fr.to_computed_value(context)) computed_value::T::Length(fr.to_computed_value(context))
}, },
specified::LengthOrPercentage::Calc(calc) => { specified::LengthOrPercentage::Calc(ref calc) => {
let calc = calc.to_computed_value(context); let calc = calc.to_computed_value(context);
let fr = specified::FontRelativeLength::Em(calc.percentage()); let fr = specified::FontRelativeLength::Em(calc.percentage());
let fr = specified::Length::FontRelative(fr); let fr = specified::Length::FontRelative(fr);
@ -267,13 +267,13 @@ ${helpers.single_keyword("text-align-last",
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
SpecifiedValue::Specified(length) => length.has_viewport_percentage(), SpecifiedValue::Specified(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue { pub enum SpecifiedValue {
Normal, Normal,
@ -284,7 +284,7 @@ ${helpers.single_keyword("text-align-last",
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
SpecifiedValue::Normal => dest.write_str("normal"), SpecifiedValue::Normal => dest.write_str("normal"),
SpecifiedValue::Specified(l) => l.to_css(dest), SpecifiedValue::Specified(ref l) => l.to_css(dest),
} }
} }
} }
@ -317,7 +317,7 @@ ${helpers.single_keyword("text-align-last",
fn to_computed_value(&self, context: &Context) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Normal => computed_value::T(None), SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) => SpecifiedValue::Specified(ref l) =>
computed_value::T(Some(l.to_computed_value(context))) computed_value::T(Some(l.to_computed_value(context)))
} }
} }
@ -348,13 +348,13 @@ ${helpers.single_keyword("text-align-last",
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
SpecifiedValue::Specified(length) => length.has_viewport_percentage(), SpecifiedValue::Specified(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue { pub enum SpecifiedValue {
Normal, Normal,
@ -365,7 +365,7 @@ ${helpers.single_keyword("text-align-last",
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
SpecifiedValue::Normal => dest.write_str("normal"), SpecifiedValue::Normal => dest.write_str("normal"),
SpecifiedValue::Specified(l) => l.to_css(dest), SpecifiedValue::Specified(ref l) => l.to_css(dest),
} }
} }
} }
@ -398,7 +398,7 @@ ${helpers.single_keyword("text-align-last",
fn to_computed_value(&self, context: &Context) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Normal => computed_value::T(None), SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) => SpecifiedValue::Specified(ref l) =>
computed_value::T(Some(l.to_computed_value(context))), computed_value::T(Some(l.to_computed_value(context))),
} }
} }
@ -681,7 +681,9 @@ ${helpers.single_keyword("text-align-last",
fn parse_one_text_shadow(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedTextShadow,()> { fn parse_one_text_shadow(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedTextShadow,()> {
use app_units::Au; use app_units::Au;
let mut lengths = [specified::Length::Absolute(Au(0)); 3]; let mut lengths = [specified::Length::Absolute(Au(0)),
specified::Length::Absolute(Au(0)),
specified::Length::Absolute(Au(0))];
let mut lengths_parsed = false; let mut lengths_parsed = false;
let mut color = None; let mut color = None;
@ -723,9 +725,9 @@ ${helpers.single_keyword("text-align-last",
} }
Ok(SpecifiedTextShadow { Ok(SpecifiedTextShadow {
offset_x: lengths[0], offset_x: lengths[0].take(),
offset_y: lengths[1], offset_y: lengths[1].take(),
blur_radius: lengths[2], blur_radius: lengths[2].take(),
color: color, color: color,
}) })
} }

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

@ -48,7 +48,7 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
impl HasViewportPercentage for SpecifiedValue { impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
let &SpecifiedValue(length) = self; let &SpecifiedValue(ref length) = self;
length.has_viewport_percentage() length.has_viewport_percentage()
} }
} }

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

@ -33,18 +33,7 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style",
impl<'a> LonghandsToSerialize<'a> { impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
let ${side} = match self.border_${side}_width { let ${side} = self.border_${side}_width.clone();
&DeclaredValue::Value(ref value) => DeclaredValue::Value(*value),
&DeclaredValue::WithVariables {
css: ref a, first_token_type: ref b, base_url: ref c, from_shorthand: ref d
} => DeclaredValue::WithVariables {
// WithVariables should not be reachable during serialization
css: a.clone(), first_token_type: b.clone(), base_url: c.clone(), from_shorthand: d.clone()
},
&DeclaredValue::Initial => DeclaredValue::Initial,
&DeclaredValue::Inherit => DeclaredValue::Inherit,
&DeclaredValue::Unset => DeclaredValue::Unset,
};
% endfor % endfor
super::serialize_four_sides(dest, &top, &right, &bottom, &left) super::serialize_four_sides(dest, &top, &right, &bottom, &left)
@ -136,7 +125,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser)
% for side in ["top", "right", "bottom", "left"]: % for side in ["top", "right", "bottom", "left"]:
border_${side}_color: color.clone(), border_${side}_color: color.clone(),
border_${side}_style: style, border_${side}_style: style,
border_${side}_width: width, border_${side}_width: width.clone(),
% endfor % endfor
}) })
} }

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

@ -100,7 +100,7 @@ impl Device {
/// A expression kind servo understands and parses. /// A expression kind servo understands and parses.
/// ///
/// Only `pub` for unit testing, please don't use it directly! /// Only `pub` for unit testing, please don't use it directly!
#[derive(PartialEq, Copy, Clone, Debug)] #[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum ExpressionKind { pub enum ExpressionKind {
/// http://dev.w3.org/csswg/mediaqueries-3/#width /// http://dev.w3.org/csswg/mediaqueries-3/#width

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

@ -190,7 +190,7 @@ impl ToComputedValue for specified::GradientKind {
specified::GradientKind::Linear(angle_or_corner) => { specified::GradientKind::Linear(angle_or_corner) => {
GradientKind::Linear(angle_or_corner.to_computed_value(context)) GradientKind::Linear(angle_or_corner.to_computed_value(context))
}, },
specified::GradientKind::Radial(ref shape, position) => { specified::GradientKind::Radial(ref shape, ref position) => {
GradientKind::Radial(shape.to_computed_value(context), GradientKind::Radial(shape.to_computed_value(context),
position.to_computed_value(context)) position.to_computed_value(context))
}, },
@ -253,7 +253,7 @@ impl ToComputedValue for specified::ColorStop {
color: self.color.parsed, color: self.color.parsed,
position: match self.position { position: match self.position {
None => None, None => None,
Some(value) => Some(value.to_computed_value(context)), Some(ref value) => Some(value.to_computed_value(context)),
}, },
} }
} }
@ -374,7 +374,7 @@ impl ToComputedValue for specified::LengthOrKeyword {
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrKeyword { fn to_computed_value(&self, context: &Context) -> LengthOrKeyword {
match *self { match *self {
specified::LengthOrKeyword::Length(length) => { specified::LengthOrKeyword::Length(ref length) => {
LengthOrKeyword::Length(length.to_computed_value(context)) LengthOrKeyword::Length(length.to_computed_value(context))
}, },
specified::LengthOrKeyword::Keyword(keyword) => { specified::LengthOrKeyword::Keyword(keyword) => {
@ -437,7 +437,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrKeyword {
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrKeyword { fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrKeyword {
match *self { match *self {
specified::LengthOrPercentageOrKeyword::LengthOrPercentage(first_len, second_len) => { specified::LengthOrPercentageOrKeyword::LengthOrPercentage(ref first_len, ref second_len) => {
LengthOrPercentageOrKeyword::LengthOrPercentage(first_len.to_computed_value(context), LengthOrPercentageOrKeyword::LengthOrPercentage(first_len.to_computed_value(context),
second_len.to_computed_value(context)) second_len.to_computed_value(context))
}, },

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

@ -194,13 +194,13 @@ impl ToComputedValue for specified::LengthOrPercentage {
fn to_computed_value(&self, context: &Context) -> LengthOrPercentage { fn to_computed_value(&self, context: &Context) -> LengthOrPercentage {
match *self { match *self {
specified::LengthOrPercentage::Length(value) => { specified::LengthOrPercentage::Length(ref value) => {
LengthOrPercentage::Length(value.to_computed_value(context)) LengthOrPercentage::Length(value.to_computed_value(context))
} }
specified::LengthOrPercentage::Percentage(value) => { specified::LengthOrPercentage::Percentage(value) => {
LengthOrPercentage::Percentage(value.0) LengthOrPercentage::Percentage(value.0)
} }
specified::LengthOrPercentage::Calc(calc) => { specified::LengthOrPercentage::Calc(ref calc) => {
LengthOrPercentage::Calc(calc.to_computed_value(context)) LengthOrPercentage::Calc(calc.to_computed_value(context))
} }
} }
@ -216,9 +216,9 @@ impl ToComputedValue for specified::LengthOrPercentage {
LengthOrPercentage::Percentage(value) => { LengthOrPercentage::Percentage(value) => {
specified::LengthOrPercentage::Percentage(specified::Percentage(value)) specified::LengthOrPercentage::Percentage(specified::Percentage(value))
} }
LengthOrPercentage::Calc(calc) => { LengthOrPercentage::Calc(ref calc) => {
specified::LengthOrPercentage::Calc( specified::LengthOrPercentage::Calc(
ToComputedValue::from_computed_value(&calc) Box::new(ToComputedValue::from_computed_value(calc))
) )
} }
} }
@ -277,7 +277,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto { fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto {
match *self { match *self {
specified::LengthOrPercentageOrAuto::Length(value) => { specified::LengthOrPercentageOrAuto::Length(ref value) => {
LengthOrPercentageOrAuto::Length(value.to_computed_value(context)) LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
} }
specified::LengthOrPercentageOrAuto::Percentage(value) => { specified::LengthOrPercentageOrAuto::Percentage(value) => {
@ -286,7 +286,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
specified::LengthOrPercentageOrAuto::Auto => { specified::LengthOrPercentageOrAuto::Auto => {
LengthOrPercentageOrAuto::Auto LengthOrPercentageOrAuto::Auto
} }
specified::LengthOrPercentageOrAuto::Calc(calc) => { specified::LengthOrPercentageOrAuto::Calc(ref calc) => {
LengthOrPercentageOrAuto::Calc(calc.to_computed_value(context)) LengthOrPercentageOrAuto::Calc(calc.to_computed_value(context))
} }
} }
@ -306,7 +306,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
} }
LengthOrPercentageOrAuto::Calc(calc) => { LengthOrPercentageOrAuto::Calc(calc) => {
specified::LengthOrPercentageOrAuto::Calc( specified::LengthOrPercentageOrAuto::Calc(
ToComputedValue::from_computed_value(&calc) Box::new(ToComputedValue::from_computed_value(&calc))
) )
} }
} }
@ -354,13 +354,13 @@ impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent {
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAutoOrContent { fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAutoOrContent {
match *self { match *self {
specified::LengthOrPercentageOrAutoOrContent::Length(value) => { specified::LengthOrPercentageOrAutoOrContent::Length(ref value) => {
LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context)) LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context))
}, },
specified::LengthOrPercentageOrAutoOrContent::Percentage(value) => { specified::LengthOrPercentageOrAutoOrContent::Percentage(value) => {
LengthOrPercentageOrAutoOrContent::Percentage(value.0) LengthOrPercentageOrAutoOrContent::Percentage(value.0)
}, },
specified::LengthOrPercentageOrAutoOrContent::Calc(calc) => { specified::LengthOrPercentageOrAutoOrContent::Calc(ref calc) => {
LengthOrPercentageOrAutoOrContent::Calc(calc.to_computed_value(context)) LengthOrPercentageOrAutoOrContent::Calc(calc.to_computed_value(context))
}, },
specified::LengthOrPercentageOrAutoOrContent::Auto => { specified::LengthOrPercentageOrAutoOrContent::Auto => {
@ -392,7 +392,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent {
} }
LengthOrPercentageOrAutoOrContent::Calc(calc) => { LengthOrPercentageOrAutoOrContent::Calc(calc) => {
specified::LengthOrPercentageOrAutoOrContent::Calc( specified::LengthOrPercentageOrAutoOrContent::Calc(
ToComputedValue::from_computed_value(&calc) Box::new(ToComputedValue::from_computed_value(&calc))
) )
} }
} }
@ -439,13 +439,13 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone {
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone { fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone {
match *self { match *self {
specified::LengthOrPercentageOrNone::Length(value) => { specified::LengthOrPercentageOrNone::Length(ref value) => {
LengthOrPercentageOrNone::Length(value.to_computed_value(context)) LengthOrPercentageOrNone::Length(value.to_computed_value(context))
} }
specified::LengthOrPercentageOrNone::Percentage(value) => { specified::LengthOrPercentageOrNone::Percentage(value) => {
LengthOrPercentageOrNone::Percentage(value.0) LengthOrPercentageOrNone::Percentage(value.0)
} }
specified::LengthOrPercentageOrNone::Calc(calc) => { specified::LengthOrPercentageOrNone::Calc(ref calc) => {
LengthOrPercentageOrNone::Calc(calc.to_computed_value(context)) LengthOrPercentageOrNone::Calc(calc.to_computed_value(context))
} }
specified::LengthOrPercentageOrNone::None => { specified::LengthOrPercentageOrNone::None => {
@ -468,7 +468,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone {
} }
LengthOrPercentageOrNone::Calc(calc) => { LengthOrPercentageOrNone::Calc(calc) => {
specified::LengthOrPercentageOrNone::Calc( specified::LengthOrPercentageOrNone::Calc(
ToComputedValue::from_computed_value(&calc) Box::new(ToComputedValue::from_computed_value(&calc))
) )
} }
} }

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

@ -128,7 +128,7 @@ impl ToComputedValue for specified::Length {
fn to_computed_value(&self, context: &Context) -> Au { fn to_computed_value(&self, context: &Context) -> Au {
match *self { match *self {
specified::Length::Absolute(length) => length, specified::Length::Absolute(length) => length,
specified::Length::Calc(calc, range) => range.clamp(calc.to_computed_value(context).length()), specified::Length::Calc(ref calc, range) => range.clamp(calc.to_computed_value(context).length()),
specified::Length::FontRelative(length) => specified::Length::FontRelative(length) =>
length.to_computed_value(context, /* use inherited */ false), length.to_computed_value(context, /* use inherited */ false),
specified::Length::ViewportPercentage(length) => specified::Length::ViewportPercentage(length) =>

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

@ -166,9 +166,9 @@ impl Parse for BasicShape {
impl ToCss for BasicShape { impl ToCss for BasicShape {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
BasicShape::Inset(rect) => rect.to_css(dest), BasicShape::Inset(ref rect) => rect.to_css(dest),
BasicShape::Circle(circle) => circle.to_css(dest), BasicShape::Circle(ref circle) => circle.to_css(dest),
BasicShape::Ellipse(e) => e.to_css(dest), BasicShape::Ellipse(ref e) => e.to_css(dest),
BasicShape::Polygon(ref poly) => poly.to_css(dest), BasicShape::Polygon(ref poly) => poly.to_css(dest),
} }
} }
@ -180,9 +180,9 @@ impl ToComputedValue for BasicShape {
#[inline] #[inline]
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue { fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
match *self { match *self {
BasicShape::Inset(rect) => computed_basic_shape::BasicShape::Inset(rect.to_computed_value(cx)), BasicShape::Inset(ref rect) => computed_basic_shape::BasicShape::Inset(rect.to_computed_value(cx)),
BasicShape::Circle(circle) => computed_basic_shape::BasicShape::Circle(circle.to_computed_value(cx)), BasicShape::Circle(ref circle) => computed_basic_shape::BasicShape::Circle(circle.to_computed_value(cx)),
BasicShape::Ellipse(e) => computed_basic_shape::BasicShape::Ellipse(e.to_computed_value(cx)), BasicShape::Ellipse(ref e) => computed_basic_shape::BasicShape::Ellipse(e.to_computed_value(cx)),
BasicShape::Polygon(ref poly) => computed_basic_shape::BasicShape::Polygon(poly.to_computed_value(cx)), BasicShape::Polygon(ref poly) => computed_basic_shape::BasicShape::Polygon(poly.to_computed_value(cx)),
} }
} }
@ -205,7 +205,7 @@ impl ToComputedValue for BasicShape {
} }
} }
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// https://drafts.csswg.org/css-shapes/#funcdef-inset /// https://drafts.csswg.org/css-shapes/#funcdef-inset
#[allow(missing_docs)] #[allow(missing_docs)]
@ -275,7 +275,7 @@ impl ToComputedValue for InsetRect {
right: self.right.to_computed_value(cx), right: self.right.to_computed_value(cx),
bottom: self.bottom.to_computed_value(cx), bottom: self.bottom.to_computed_value(cx),
left: self.left.to_computed_value(cx), left: self.left.to_computed_value(cx),
round: self.round.map(|r| r.to_computed_value(cx)), round: self.round.as_ref().map(|r| r.to_computed_value(cx)),
} }
} }
@ -305,6 +305,7 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W)
// keyword-percentage pairs can be folded into a single percentage // keyword-percentage pairs can be folded into a single percentage
fn fold_keyword(keyword: Option<Keyword>, length: Option<LengthOrPercentage>) fn fold_keyword(keyword: Option<Keyword>, length: Option<LengthOrPercentage>)
-> Option<LengthOrPercentage> { -> Option<LengthOrPercentage> {
let none = length.is_none();
let pc = match length.map(replace_with_percent) { let pc = match length.map(replace_with_percent) {
None => Percentage(0.0), // unspecified length = 0% None => Percentage(0.0), // unspecified length = 0%
Some(LengthOrPercentage::Percentage(pc)) => pc, Some(LengthOrPercentage::Percentage(pc)) => pc,
@ -313,7 +314,7 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W)
let percent = match keyword { let percent = match keyword {
Some(Keyword::Center) => { Some(Keyword::Center) => {
// center cannot pair with lengths // center cannot pair with lengths
assert!(length.is_none()); assert!(none);
Percentage(0.5) Percentage(0.5)
}, },
Some(Keyword::Left) | Some(Keyword::Top) | None => pc, Some(Keyword::Left) | Some(Keyword::Top) | None => pc,
@ -342,8 +343,8 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W)
replace_with_percent(y).to_css(dest) replace_with_percent(y).to_css(dest)
} }
match (position.horizontal.keyword, position.horizontal.position, match (position.horizontal.keyword, position.horizontal.position.clone(),
position.vertical.keyword, position.vertical.position) { position.vertical.keyword, position.vertical.position.clone()) {
(Some(hk), None, Some(vk), None) => { (Some(hk), None, Some(vk), None) => {
// two keywords: serialize as two lengths // two keywords: serialize as two lengths
serialize_position_pair(hk.to_length_or_percentage(), serialize_position_pair(hk.to_length_or_percentage(),
@ -357,7 +358,8 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W)
(hk, hp, vk, vp) => { (hk, hp, vk, vp) => {
// only fold if both fold; the three-value form isn't // only fold if both fold; the three-value form isn't
// allowed here. // allowed here.
if let (Some(x), Some(y)) = (fold_keyword(hk, hp), fold_keyword(vk, vp)) { if let (Some(x), Some(y)) = (fold_keyword(hk, hp.clone()),
fold_keyword(vk, vp.clone())) {
serialize_position_pair(x, y, dest) serialize_position_pair(x, y, dest)
} else { } else {
// We failed to reduce it to a two-value form, // We failed to reduce it to a two-value form,
@ -365,7 +367,7 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W)
let zero = LengthOrPercentage::Percentage(Percentage(0.0)); let zero = LengthOrPercentage::Percentage(Percentage(0.0));
try!(hk.unwrap_or(Keyword::Left).to_css(dest)); try!(hk.unwrap_or(Keyword::Left).to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
try!(replace_with_percent(hp.unwrap_or(zero)).to_css(dest)); try!(replace_with_percent(hp.unwrap_or(zero.clone())).to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
try!(vk.unwrap_or(Keyword::Top).to_css(dest)); try!(vk.unwrap_or(Keyword::Top).to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
@ -375,7 +377,7 @@ fn serialize_basicshape_position<W>(position: &Position, dest: &mut W)
} }
} }
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// https://drafts.csswg.org/css-shapes/#funcdef-circle /// https://drafts.csswg.org/css-shapes/#funcdef-circle
#[allow(missing_docs)] #[allow(missing_docs)]
@ -454,7 +456,7 @@ impl ToComputedValue for Circle {
} }
} }
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// https://drafts.csswg.org/css-shapes/#funcdef-ellipse /// https://drafts.csswg.org/css-shapes/#funcdef-ellipse
#[allow(missing_docs)] #[allow(missing_docs)]
@ -508,7 +510,7 @@ impl Parse for Ellipse {
impl ToCss for Ellipse { impl ToCss for Ellipse {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(dest.write_str("ellipse(")); try!(dest.write_str("ellipse("));
if (self.semiaxis_x, self.semiaxis_y) != Default::default() { if !self.semiaxis_x.is_default() || !self.semiaxis_y.is_default() {
try!(self.semiaxis_x.to_css(dest)); try!(self.semiaxis_x.to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
try!(self.semiaxis_y.to_css(dest)); try!(self.semiaxis_y.to_css(dest));
@ -635,7 +637,7 @@ impl ToComputedValue for Polygon {
} }
/// https://drafts.csswg.org/css-shapes/#typedef-shape-radius /// https://drafts.csswg.org/css-shapes/#typedef-shape-radius
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum ShapeRadius { pub enum ShapeRadius {
@ -644,6 +646,16 @@ pub enum ShapeRadius {
FarthestSide, FarthestSide,
} }
impl ShapeRadius {
fn is_default(&self) -> bool {
if let ShapeRadius::ClosestSide = *self {
true
} else {
false
}
}
}
impl Default for ShapeRadius { impl Default for ShapeRadius {
fn default() -> Self { fn default() -> Self {
ShapeRadius::ClosestSide ShapeRadius::ClosestSide
@ -665,7 +677,7 @@ impl Parse for ShapeRadius {
impl ToCss for ShapeRadius { impl ToCss for ShapeRadius {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
ShapeRadius::Length(lop) => lop.to_css(dest), ShapeRadius::Length(ref lop) => lop.to_css(dest),
ShapeRadius::ClosestSide => dest.write_str("closest-side"), ShapeRadius::ClosestSide => dest.write_str("closest-side"),
ShapeRadius::FarthestSide => dest.write_str("farthest-side"), ShapeRadius::FarthestSide => dest.write_str("farthest-side"),
} }
@ -679,7 +691,7 @@ impl ToComputedValue for ShapeRadius {
#[inline] #[inline]
fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue { fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue {
match *self { match *self {
ShapeRadius::Length(lop) => { ShapeRadius::Length(ref lop) => {
computed_basic_shape::ShapeRadius::Length(lop.to_computed_value(cx)) computed_basic_shape::ShapeRadius::Length(lop.to_computed_value(cx))
} }
ShapeRadius::ClosestSide => computed_basic_shape::ShapeRadius::ClosestSide, ShapeRadius::ClosestSide => computed_basic_shape::ShapeRadius::ClosestSide,
@ -700,7 +712,7 @@ impl ToComputedValue for ShapeRadius {
} }
/// https://drafts.csswg.org/css-backgrounds-3/#border-radius /// https://drafts.csswg.org/css-backgrounds-3/#border-radius
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct BorderRadius { pub struct BorderRadius {
@ -739,17 +751,20 @@ impl ToCss for BorderRadius {
impl Parse for BorderRadius { impl Parse for BorderRadius {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
let widths = try!(parse_one_set_of_border_values(context, input)); let mut widths = try!(parse_one_set_of_border_values(context, input));
let heights = if input.try(|input| input.expect_delim('/')).is_ok() { let mut heights = if input.try(|input| input.expect_delim('/')).is_ok() {
try!(parse_one_set_of_border_values(context, input)) try!(parse_one_set_of_border_values(context, input))
} else { } else {
widths.clone() [widths[0].clone(),
widths[1].clone(),
widths[2].clone(),
widths[3].clone()]
}; };
Ok(BorderRadius { Ok(BorderRadius {
top_left: BorderRadiusSize::new(widths[0], heights[0]), top_left: BorderRadiusSize::new(widths[0].take(), heights[0].take()),
top_right: BorderRadiusSize::new(widths[1], heights[1]), top_right: BorderRadiusSize::new(widths[1].take(), heights[1].take()),
bottom_right: BorderRadiusSize::new(widths[2], heights[2]), bottom_right: BorderRadiusSize::new(widths[2].take(), heights[2].take()),
bottom_left: BorderRadiusSize::new(widths[3], heights[3]), bottom_left: BorderRadiusSize::new(widths[3].take(), heights[3].take()),
}) })
} }
} }
@ -761,19 +776,19 @@ fn parse_one_set_of_border_values(context: &ParserContext, mut input: &mut Parse
let b = if let Ok(b) = input.try(|i| LengthOrPercentage::parse(context, i)) { let b = if let Ok(b) = input.try(|i| LengthOrPercentage::parse(context, i)) {
b b
} else { } else {
return Ok([a, a, a, a]) return Ok([a.clone(), a.clone(), a.clone(), a])
}; };
let c = if let Ok(c) = input.try(|i| LengthOrPercentage::parse(context, i)) { let c = if let Ok(c) = input.try(|i| LengthOrPercentage::parse(context, i)) {
c c
} else { } else {
return Ok([a, b, a, b]) return Ok([a.clone(), b.clone(), a, b])
}; };
if let Ok(d) = input.try(|i| LengthOrPercentage::parse(context, i)) { if let Ok(d) = input.try(|i| LengthOrPercentage::parse(context, i)) {
Ok([a, b, c, d]) Ok([a, b, c, d])
} else { } else {
Ok([a, b, c, b]) Ok([a, b.clone(), c, b])
} }
} }

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

@ -80,7 +80,7 @@ impl ToCss for Gradient {
skipcomma = true; skipcomma = true;
} }
}, },
GradientKind::Radial(ref shape, position) => { GradientKind::Radial(ref shape, ref position) => {
try!(dest.write_str("radial-gradient(")); try!(dest.write_str("radial-gradient("));
try!(shape.to_css(dest)); try!(shape.to_css(dest));
try!(dest.write_str(" at ")); try!(dest.write_str(" at "));
@ -312,7 +312,7 @@ pub struct ColorStop {
impl ToCss for ColorStop { impl ToCss for ColorStop {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.color.to_css(dest)); try!(self.color.to_css(dest));
if let Some(position) = self.position { if let Some(ref position) = self.position {
try!(dest.write_str(" ")); try!(dest.write_str(" "));
try!(position.to_css(dest)); try!(position.to_css(dest));
} }
@ -413,7 +413,7 @@ impl Parse for LengthOrPercentageOrKeyword {
impl ToCss for LengthOrPercentageOrKeyword { impl ToCss for LengthOrPercentageOrKeyword {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
LengthOrPercentageOrKeyword::LengthOrPercentage(ref first_len, second_len) => { LengthOrPercentageOrKeyword::LengthOrPercentage(ref first_len, ref second_len) => {
try!(first_len.to_css(dest)); try!(first_len.to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
second_len.to_css(dest) second_len.to_css(dest)

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

@ -11,9 +11,8 @@ use cssparser::{Parser, Token};
use euclid::size::Size2D; use euclid::size::Size2D;
use font_metrics::FontMetrics; use font_metrics::FontMetrics;
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
use std::{cmp, fmt, mem};
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::cmp;
use std::fmt;
use std::ops::Mul; use std::ops::Mul;
use style_traits::ToCss; use style_traits::ToCss;
use style_traits::values::specified::AllowedNumericType; use style_traits::values::specified::AllowedNumericType;
@ -209,7 +208,7 @@ impl CharacterWidth {
/// A length. /// A length.
/// ///
/// https://drafts.csswg.org/css-values/#lengths /// https://drafts.csswg.org/css-values/#lengths
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum Length { pub enum Length {
/// An absolute length: https://drafts.csswg.org/css-values/#absolute-length /// An absolute length: https://drafts.csswg.org/css-values/#absolute-length
@ -237,7 +236,7 @@ pub enum Length {
/// ///
/// TODO(emilio): We have more `Calc` variants around, we should only use /// TODO(emilio): We have more `Calc` variants around, we should only use
/// one. /// one.
Calc(CalcLengthOrPercentage, AllowedNumericType), Calc(Box<CalcLengthOrPercentage>, AllowedNumericType),
} }
impl HasViewportPercentage for Length { impl HasViewportPercentage for Length {
@ -382,6 +381,15 @@ impl Length {
pub fn from_px(px_value: CSSFloat) -> Length { pub fn from_px(px_value: CSSFloat) -> Length {
Length::Absolute(Au((px_value * AU_PER_PX) as i32)) Length::Absolute(Au((px_value * AU_PER_PX) as i32))
} }
/// Extract inner length without a clone, replacing it with a 0 Au
///
/// Use when you need to move out of a length array without cloning
#[inline]
pub fn take(&mut self) -> Self {
let new = Length::Absolute(Au(0));
mem::replace(self, new)
}
} }
impl Parse for Length { impl Parse for Length {
@ -584,7 +592,7 @@ impl CalcLengthOrPercentage {
node_with_unit = Some(match *node { node_with_unit = Some(match *node {
CalcValueNode::Sum(ref sum) => CalcValueNode::Sum(ref sum) =>
try!(CalcLengthOrPercentage::simplify_products_in_sum(sum)), try!(CalcLengthOrPercentage::simplify_products_in_sum(sum)),
CalcValueNode::Length(l) => SimplifiedValueNode::Length(l), CalcValueNode::Length(ref l) => SimplifiedValueNode::Length(l.clone()),
CalcValueNode::Angle(a) => SimplifiedValueNode::Angle(a), CalcValueNode::Angle(a) => SimplifiedValueNode::Angle(a),
CalcValueNode::Time(t) => SimplifiedValueNode::Time(t), CalcValueNode::Time(t) => SimplifiedValueNode::Time(t),
CalcValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p), CalcValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p),
@ -604,7 +612,7 @@ impl CalcLengthOrPercentage {
fn parse_length(input: &mut Parser, fn parse_length(input: &mut Parser,
context: AllowedNumericType) -> Result<Length, ()> { context: AllowedNumericType) -> Result<Length, ()> {
CalcLengthOrPercentage::parse(input, CalcUnit::Length).map(|calc| { CalcLengthOrPercentage::parse(input, CalcUnit::Length).map(|calc| {
Length::Calc(calc, context) Length::Calc(Box::new(calc), context)
}) })
} }
@ -844,13 +852,13 @@ impl Parse for Percentage {
/// A length or a percentage value. /// A length or a percentage value.
/// ///
/// TODO(emilio): Does this make any sense vs. CalcLengthOrPercentage? /// TODO(emilio): Does this make any sense vs. CalcLengthOrPercentage?
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum LengthOrPercentage { pub enum LengthOrPercentage {
Length(Length), Length(Length),
Percentage(Percentage), Percentage(Percentage),
Calc(CalcLengthOrPercentage), Calc(Box<CalcLengthOrPercentage>),
} }
impl HasViewportPercentage for LengthOrPercentage { impl HasViewportPercentage for LengthOrPercentage {
@ -866,9 +874,9 @@ impl HasViewportPercentage for LengthOrPercentage {
impl ToCss for LengthOrPercentage { impl ToCss for LengthOrPercentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
LengthOrPercentage::Length(length) => length.to_css(dest), LengthOrPercentage::Length(ref length) => length.to_css(dest),
LengthOrPercentage::Percentage(percentage) => percentage.to_css(dest), LengthOrPercentage::Percentage(percentage) => percentage.to_css(dest),
LengthOrPercentage::Calc(calc) => calc.to_css(dest), LengthOrPercentage::Calc(ref calc) => calc.to_css(dest),
} }
} }
} }
@ -890,7 +898,7 @@ impl LengthOrPercentage {
Ok(LengthOrPercentage::Length(Length::Absolute(Au(0)))), Ok(LengthOrPercentage::Length(Length::Absolute(Au(0)))),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
Ok(LengthOrPercentage::Calc(calc)) Ok(LengthOrPercentage::Calc(Box::new(calc)))
}, },
_ => Err(()) _ => Err(())
} }
@ -901,6 +909,15 @@ impl LengthOrPercentage {
pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> { pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrPercentage, ()> {
LengthOrPercentage::parse_internal(input, AllowedNumericType::NonNegative) LengthOrPercentage::parse_internal(input, AllowedNumericType::NonNegative)
} }
/// Extract value from ref without a clone, replacing it with a 0 Au
///
/// Use when you need to move out of a length array without cloning
#[inline]
pub fn take(&mut self) -> Self {
let new = LengthOrPercentage::Length(Length::Absolute(Au(0)));
mem::replace(self, new)
}
} }
impl Parse for LengthOrPercentage { impl Parse for LengthOrPercentage {
@ -912,14 +929,14 @@ impl Parse for LengthOrPercentage {
/// TODO(emilio): Do the Length and Percentage variants make any sense with /// TODO(emilio): Do the Length and Percentage variants make any sense with
/// CalcLengthOrPercentage? /// CalcLengthOrPercentage?
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum LengthOrPercentageOrAuto { pub enum LengthOrPercentageOrAuto {
Length(Length), Length(Length),
Percentage(Percentage), Percentage(Percentage),
Auto, Auto,
Calc(CalcLengthOrPercentage), Calc(Box<CalcLengthOrPercentage>),
} }
impl HasViewportPercentage for LengthOrPercentageOrAuto { impl HasViewportPercentage for LengthOrPercentageOrAuto {
@ -935,10 +952,10 @@ impl HasViewportPercentage for LengthOrPercentageOrAuto {
impl ToCss for LengthOrPercentageOrAuto { impl ToCss for LengthOrPercentageOrAuto {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
LengthOrPercentageOrAuto::Length(length) => length.to_css(dest), LengthOrPercentageOrAuto::Length(ref length) => length.to_css(dest),
LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest), LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest),
LengthOrPercentageOrAuto::Auto => dest.write_str("auto"), LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest), LengthOrPercentageOrAuto::Calc(ref calc) => calc.to_css(dest),
} }
} }
} }
@ -958,7 +975,7 @@ impl LengthOrPercentageOrAuto {
Ok(LengthOrPercentageOrAuto::Auto), Ok(LengthOrPercentageOrAuto::Auto),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
Ok(LengthOrPercentageOrAuto::Calc(calc)) Ok(LengthOrPercentageOrAuto::Calc(Box::new(calc)))
}, },
_ => Err(()) _ => Err(())
} }
@ -980,13 +997,13 @@ impl Parse for LengthOrPercentageOrAuto {
/// TODO(emilio): Do the Length and Percentage variants make any sense with /// TODO(emilio): Do the Length and Percentage variants make any sense with
/// CalcLengthOrPercentage? /// CalcLengthOrPercentage?
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum LengthOrPercentageOrNone { pub enum LengthOrPercentageOrNone {
Length(Length), Length(Length),
Percentage(Percentage), Percentage(Percentage),
Calc(CalcLengthOrPercentage), Calc(Box<CalcLengthOrPercentage>),
None, None,
} }
@ -1023,7 +1040,7 @@ impl LengthOrPercentageOrNone {
Ok(LengthOrPercentageOrNone::Length(Length::Absolute(Au(0)))), Ok(LengthOrPercentageOrNone::Length(Length::Absolute(Au(0)))),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
Ok(LengthOrPercentageOrNone::Calc(calc)) Ok(LengthOrPercentageOrNone::Calc(Box::new(calc)))
}, },
Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => Token::Ident(ref value) if value.eq_ignore_ascii_case("none") =>
Ok(LengthOrPercentageOrNone::None), Ok(LengthOrPercentageOrNone::None),
@ -1057,7 +1074,7 @@ pub type LengthOrAuto = Either<Length, Auto>;
/// `content` keyword. /// `content` keyword.
/// ///
/// TODO(emilio): Do the Length and Percentage variants make any sense with /// TODO(emilio): Do the Length and Percentage variants make any sense with
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum LengthOrPercentageOrAutoOrContent { pub enum LengthOrPercentageOrAutoOrContent {
/// A `<length>`. /// A `<length>`.
@ -1065,7 +1082,7 @@ pub enum LengthOrPercentageOrAutoOrContent {
/// A percentage. /// A percentage.
Percentage(Percentage), Percentage(Percentage),
/// A `calc` node. /// A `calc` node.
Calc(CalcLengthOrPercentage), Calc(Box<CalcLengthOrPercentage>),
/// The `auto` keyword. /// The `auto` keyword.
Auto, Auto,
/// The `content` keyword. /// The `content` keyword.
@ -1075,7 +1092,7 @@ pub enum LengthOrPercentageOrAutoOrContent {
impl HasViewportPercentage for LengthOrPercentageOrAutoOrContent { impl HasViewportPercentage for LengthOrPercentageOrAutoOrContent {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
LengthOrPercentageOrAutoOrContent::Length(length) => length.has_viewport_percentage(), LengthOrPercentageOrAutoOrContent::Length(ref length) => length.has_viewport_percentage(),
LengthOrPercentageOrAutoOrContent::Calc(ref calc) => calc.has_viewport_percentage(), LengthOrPercentageOrAutoOrContent::Calc(ref calc) => calc.has_viewport_percentage(),
_ => false _ => false
} }
@ -1085,11 +1102,11 @@ impl HasViewportPercentage for LengthOrPercentageOrAutoOrContent {
impl ToCss for LengthOrPercentageOrAutoOrContent { impl ToCss for LengthOrPercentageOrAutoOrContent {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
LengthOrPercentageOrAutoOrContent::Length(len) => len.to_css(dest), LengthOrPercentageOrAutoOrContent::Length(ref len) => len.to_css(dest),
LengthOrPercentageOrAutoOrContent::Percentage(perc) => perc.to_css(dest), LengthOrPercentageOrAutoOrContent::Percentage(perc) => perc.to_css(dest),
LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"), LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content"), LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content"),
LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest), LengthOrPercentageOrAutoOrContent::Calc(ref calc) => calc.to_css(dest),
} }
} }
} }
@ -1110,7 +1127,7 @@ impl Parse for LengthOrPercentageOrAutoOrContent {
Ok(LengthOrPercentageOrAutoOrContent::Content), Ok(LengthOrPercentageOrAutoOrContent::Content),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage));
Ok(LengthOrPercentageOrAutoOrContent::Calc(calc)) Ok(LengthOrPercentageOrAutoOrContent::Calc(Box::new(calc)))
}, },
_ => Err(()) _ => Err(())
} }

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

@ -122,7 +122,7 @@ impl<'a> Mul<CSSFloat> for &'a SimplifiedValueNode {
#[inline] #[inline]
fn mul(self, scalar: CSSFloat) -> SimplifiedValueNode { fn mul(self, scalar: CSSFloat) -> SimplifiedValueNode {
match *self { match *self {
SimplifiedValueNode::Length(l) => SimplifiedValueNode::Length(l * scalar), SimplifiedValueNode::Length(ref l) => SimplifiedValueNode::Length(l.clone() * scalar),
SimplifiedValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p * scalar), SimplifiedValueNode::Percentage(p) => SimplifiedValueNode::Percentage(p * scalar),
SimplifiedValueNode::Angle(Angle(a)) => SimplifiedValueNode::Angle(Angle(a * scalar)), SimplifiedValueNode::Angle(Angle(a)) => SimplifiedValueNode::Angle(Angle(a * scalar)),
SimplifiedValueNode::Time(Time(t)) => SimplifiedValueNode::Time(Time(t * scalar)), SimplifiedValueNode::Time(Time(t)) => SimplifiedValueNode::Time(Time(t * scalar)),
@ -187,7 +187,7 @@ pub fn parse_number(input: &mut Parser) -> Result<f32, ()> {
} }
} }
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>); pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>);
@ -198,7 +198,7 @@ impl BorderRadiusSize {
#[allow(missing_docs)] #[allow(missing_docs)]
pub fn zero() -> BorderRadiusSize { pub fn zero() -> BorderRadiusSize {
let zero = LengthOrPercentage::Length(Length::Absolute(Au(0))); let zero = LengthOrPercentage::Length(Length::Absolute(Au(0)));
BorderRadiusSize(Size2D::new(zero, zero)) BorderRadiusSize(Size2D::new(zero.clone(), zero))
} }
#[allow(missing_docs)] #[allow(missing_docs)]
@ -208,7 +208,7 @@ impl BorderRadiusSize {
#[allow(missing_docs)] #[allow(missing_docs)]
pub fn circle(radius: LengthOrPercentage) -> BorderRadiusSize { pub fn circle(radius: LengthOrPercentage) -> BorderRadiusSize {
BorderRadiusSize(Size2D::new(radius, radius)) BorderRadiusSize(Size2D::new(radius.clone(), radius))
} }
} }
@ -216,7 +216,8 @@ impl Parse for BorderRadiusSize {
#[inline] #[inline]
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
let first = try!(LengthOrPercentage::parse_non_negative(input)); let first = try!(LengthOrPercentage::parse_non_negative(input));
let second = input.try(LengthOrPercentage::parse_non_negative).unwrap_or(first); let second = input.try(LengthOrPercentage::parse_non_negative)
.unwrap_or_else(|()| first.clone());
Ok(BorderRadiusSize(Size2D::new(first, second))) Ok(BorderRadiusSize(Size2D::new(first, second)))
} }
} }
@ -312,7 +313,7 @@ pub fn parse_border_width(input: &mut Parser) -> Result<Length, ()> {
}) })
} }
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum BorderWidth { pub enum BorderWidth {
@ -349,7 +350,7 @@ impl ToCss for BorderWidth {
BorderWidth::Thin => dest.write_str("thin"), BorderWidth::Thin => dest.write_str("thin"),
BorderWidth::Medium => dest.write_str("medium"), BorderWidth::Medium => dest.write_str("medium"),
BorderWidth::Thick => dest.write_str("thick"), BorderWidth::Thick => dest.write_str("thick"),
BorderWidth::Width(length) => length.to_css(dest) BorderWidth::Width(ref length) => length.to_css(dest)
} }
} }
} }
@ -358,7 +359,7 @@ impl HasViewportPercentage for BorderWidth {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
BorderWidth::Thin | BorderWidth::Medium | BorderWidth::Thick => false, BorderWidth::Thin | BorderWidth::Medium | BorderWidth::Thick => false,
BorderWidth::Width(length) => length.has_viewport_percentage() BorderWidth::Width(ref length) => length.has_viewport_percentage()
} }
} }
} }
@ -375,7 +376,7 @@ impl ToComputedValue for BorderWidth {
BorderWidth::Thin => Length::from_px(1.).to_computed_value(context), BorderWidth::Thin => Length::from_px(1.).to_computed_value(context),
BorderWidth::Medium => Length::from_px(3.).to_computed_value(context), BorderWidth::Medium => Length::from_px(3.).to_computed_value(context),
BorderWidth::Thick => Length::from_px(5.).to_computed_value(context), BorderWidth::Thick => Length::from_px(5.).to_computed_value(context),
BorderWidth::Width(length) => length.to_computed_value(context) BorderWidth::Width(ref length) => length.to_computed_value(context)
} }
} }
@ -605,7 +606,10 @@ impl Shadow {
pub fn parse(context: &ParserContext, input: &mut Parser, disable_spread_and_inset: bool) -> Result<Shadow, ()> { pub fn parse(context: &ParserContext, input: &mut Parser, disable_spread_and_inset: bool) -> Result<Shadow, ()> {
use app_units::Au; use app_units::Au;
let length_count = if disable_spread_and_inset { 3 } else { 4 }; let length_count = if disable_spread_and_inset { 3 } else { 4 };
let mut lengths = [Length::Absolute(Au(0)); 4]; let mut lengths = [Length::Absolute(Au(0)),
Length::Absolute(Au(0)),
Length::Absolute(Au(0)),
Length::Absolute(Au(0))];
let mut lengths_parsed = false; let mut lengths_parsed = false;
let mut color = None; let mut color = None;
let mut inset = false; let mut inset = false;
@ -654,10 +658,10 @@ impl Shadow {
} }
Ok(Shadow { Ok(Shadow {
offset_x: lengths[0], offset_x: lengths[0].take(),
offset_y: lengths[1], offset_y: lengths[1].take(),
blur_radius: lengths[2], blur_radius: lengths[2].take(),
spread_radius: if disable_spread_and_inset { Length::Absolute(Au(0)) } else { lengths[3] }, spread_radius: if disable_spread_and_inset { Length::Absolute(Au(0)) } else { lengths[3].take() },
color: color, color: color,
inset: inset, inset: inset,
}) })

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

@ -13,12 +13,12 @@ use parser::{Parse, ParserContext};
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use values::HasViewportPercentage; use values::HasViewportPercentage;
use values::computed::{CalcLengthOrPercentage, Context}; use values::computed::{self, CalcLengthOrPercentage, Context};
use values::computed::{LengthOrPercentage as ComputedLengthOrPercentage, ToComputedValue}; use values::computed::{LengthOrPercentage as ComputedLengthOrPercentage, ToComputedValue};
use values::computed::position as computed_position; use values::computed::position as computed_position;
use values::specified::{LengthOrPercentage, Percentage}; use values::specified::{LengthOrPercentage, Percentage};
#[derive(Debug, Clone, PartialEq, Copy)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// A [position][pos]. /// A [position][pos].
/// ///
@ -38,7 +38,7 @@ impl ToCss for Position {
try!(dest.write_str(" ")); try!(dest.write_str(" "));
space_present = true; space_present = true;
}; };
if let Some(horiz_pos) = self.horizontal.position { if let Some(ref horiz_pos) = self.horizontal.position {
try!(horiz_pos.to_css(dest)); try!(horiz_pos.to_css(dest));
try!(dest.write_str(" ")); try!(dest.write_str(" "));
space_present = true; space_present = true;
@ -47,7 +47,7 @@ impl ToCss for Position {
try!(vert_key.to_css(dest)); try!(vert_key.to_css(dest));
space_present = false; space_present = false;
}; };
if let Some(vert_pos) = self.vertical.position { if let Some(ref vert_pos) = self.vertical.position {
if space_present == false { if space_present == false {
try!(dest.write_str(" ")); try!(dest.write_str(" "));
} }
@ -71,23 +71,23 @@ impl Position {
second_keyword: Option<PositionComponent>) second_keyword: Option<PositionComponent>)
-> Result<Position, ()> { -> Result<Position, ()> {
// Unwrap for checking if values are at right place. // Unwrap for checking if values are at right place.
let first_key = first_keyword.unwrap_or(PositionComponent::Keyword(Keyword::Left)); let first_key = first_keyword.clone().unwrap_or(PositionComponent::Keyword(Keyword::Left));
let second_key = second_keyword.unwrap_or(PositionComponent::Keyword(Keyword::Top)); let second_key = second_keyword.clone().unwrap_or(PositionComponent::Keyword(Keyword::Top));
// Check if position specified after center keyword. // Check if position specified after center keyword.
if let PositionCategory::OtherKeyword = category(first_key) { if let PositionCategory::OtherKeyword = category(&first_key) {
if let Some(_) = first_position { if let Some(_) = first_position {
return Err(()); return Err(());
}; };
}; };
if let PositionCategory::OtherKeyword = category(second_key) { if let PositionCategory::OtherKeyword = category(&second_key) {
if let Some(_) = second_position { if let Some(_) = second_position {
return Err(()); return Err(());
}; };
}; };
// Check first and second keywords for both 2 and 4 value positions. // Check first and second keywords for both 2 and 4 value positions.
let (horiz_keyword, vert_keyword) = match (category(first_key), category(second_key)) { let (horiz_keyword, vert_keyword) = match (category(&first_key), category(&second_key)) {
// Don't allow two vertical keywords or two horizontal keywords. // Don't allow two vertical keywords or two horizontal keywords.
// also don't allow length/percentage values in the wrong position // also don't allow length/percentage values in the wrong position
(PositionCategory::HorizontalKeyword, PositionCategory::HorizontalKeyword) | (PositionCategory::HorizontalKeyword, PositionCategory::HorizontalKeyword) |
@ -186,12 +186,12 @@ impl Parse for Position {
Position::new(Some(second), Some(fourth), Some(first), Some(third)) Position::new(Some(second), Some(fourth), Some(first), Some(third))
} else { } else {
// Handle 3 value background position there are several options: // Handle 3 value background position there are several options:
if let PositionCategory::LengthOrPercentage = category(first) { if let PositionCategory::LengthOrPercentage = category(&first) {
// "length keyword length" // "length keyword length"
Position::new(Some(first), Some(third), None, Some(second)) Position::new(Some(first), Some(third), None, Some(second))
} else { } else {
if let PositionCategory::LengthOrPercentage = category(second) { if let PositionCategory::LengthOrPercentage = category(&second) {
if let PositionCategory::LengthOrPercentage = category(third) { if let PositionCategory::LengthOrPercentage = category(&third) {
// "keyword length length" // "keyword length length"
Position::new(Some(second), Some(third), Some(first), None) Position::new(Some(second), Some(third), Some(first), None)
} else { } else {
@ -206,14 +206,14 @@ impl Parse for Position {
} }
} else { } else {
// Handle 2 value background position. // Handle 2 value background position.
if let PositionCategory::LengthOrPercentage = category(first) { if let PositionCategory::LengthOrPercentage = category(&first) {
if let PositionCategory::LengthOrPercentage = category(second) { if let PositionCategory::LengthOrPercentage = category(&second) {
Position::new(Some(first), Some(second), None, None) Position::new(Some(first), Some(second), None, None)
} else { } else {
Position::new(Some(first), None, None, Some(second)) Position::new(Some(first), None, None, Some(second))
} }
} else { } else {
if let PositionCategory::LengthOrPercentage = category(second) { if let PositionCategory::LengthOrPercentage = category(&second) {
Position::new(None, Some(second), Some(first), None) Position::new(None, Some(second), Some(first), None)
} else { } else {
Position::new(None, None, Some(first), Some(second)) Position::new(None, None, Some(first), Some(second))
@ -249,7 +249,7 @@ impl ToComputedValue for Position {
} }
} }
#[derive(Debug, Clone, PartialEq, Copy)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct HorizontalPosition { pub struct HorizontalPosition {
@ -259,7 +259,7 @@ pub struct HorizontalPosition {
impl HasViewportPercentage for HorizontalPosition { impl HasViewportPercentage for HorizontalPosition {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
self.position.map_or(false, |pos| pos.has_viewport_percentage()) self.position.as_ref().map_or(false, |pos| pos.has_viewport_percentage())
} }
} }
@ -271,7 +271,7 @@ impl ToCss for HorizontalPosition {
keyword_present = true; keyword_present = true;
}; };
if let Some(position) = self.position { if let Some(ref position) = self.position {
if keyword_present { if keyword_present {
try!(dest.write_str(" ")); try!(dest.write_str(" "));
} }
@ -287,7 +287,7 @@ impl Parse for HorizontalPosition {
let first = try!(PositionComponent::parse(context, input)); let first = try!(PositionComponent::parse(context, input));
let second = input.try(|i| PositionComponent::parse(context, i)).ok(); let second = input.try(|i| PositionComponent::parse(context, i)).ok();
let (keyword, position) = if let PositionCategory::LengthOrPercentage = category(first) { let (keyword, position) = if let PositionCategory::LengthOrPercentage = category(&first) {
// "length keyword?" // "length keyword?"
(second, Some(first)) (second, Some(first))
} else { } else {
@ -298,7 +298,7 @@ impl Parse for HorizontalPosition {
// Unwrapping and checking keyword. // Unwrapping and checking keyword.
let keyword = match keyword { let keyword = match keyword {
Some(PositionComponent::Keyword(key)) => { Some(PositionComponent::Keyword(key)) => {
match category(keyword.unwrap()) { match category(keyword.as_ref().unwrap()) {
PositionCategory::VerticalKeyword | PositionCategory::VerticalKeyword |
PositionCategory::VerticalLogicalKeyword => return Err(()), PositionCategory::VerticalLogicalKeyword => return Err(()),
_ => Some(key), _ => Some(key),
@ -339,10 +339,10 @@ impl ToComputedValue for HorizontalPosition {
let horizontal = match keyword { let horizontal = match keyword {
// FIXME(canaltinova): Support logical keywords. // FIXME(canaltinova): Support logical keywords.
Keyword::Right | Keyword::XEnd => { Keyword::Right | Keyword::XEnd => {
if let Some(x) = self.position { if let Some(ref x) = self.position {
let (length, percentage) = match x { let (length, percentage) = match *x {
LengthOrPercentage::Percentage(Percentage(y)) => (Au(0), Some(1.0 - y)), LengthOrPercentage::Percentage(Percentage(y)) => (Au(0), Some(1.0 - y)),
LengthOrPercentage::Length(y) => (-y.to_computed_value(context), Some(1.0)), LengthOrPercentage::Length(ref y) => (-y.to_computed_value(context), Some(1.0)),
_ => (Au(0), None), _ => (Au(0), None),
}; };
ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage { ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage {
@ -357,8 +357,8 @@ impl ToComputedValue for HorizontalPosition {
keyword.to_length_or_percentage().to_computed_value(context) keyword.to_length_or_percentage().to_computed_value(context)
}, },
_ => { _ => {
let horiz = self.position let zero = LengthOrPercentage::Percentage(Percentage(0.0));
.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.0))); let horiz = self.position.as_ref().unwrap_or(&zero);
horiz.to_computed_value(context) horiz.to_computed_value(context)
}, },
}; };
@ -375,7 +375,7 @@ impl ToComputedValue for HorizontalPosition {
} }
} }
#[derive(Debug, Clone, PartialEq, Copy)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct VerticalPosition { pub struct VerticalPosition {
@ -385,7 +385,7 @@ pub struct VerticalPosition {
impl HasViewportPercentage for VerticalPosition { impl HasViewportPercentage for VerticalPosition {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
self.position.map_or(false, |pos| pos.has_viewport_percentage()) self.position.as_ref().map_or(false, |pos| pos.has_viewport_percentage())
} }
} }
@ -397,7 +397,7 @@ impl ToCss for VerticalPosition {
keyword_present = true; keyword_present = true;
}; };
if let Some(position) = self.position { if let Some(ref position) = self.position {
if keyword_present { if keyword_present {
try!(dest.write_str(" ")); try!(dest.write_str(" "));
} }
@ -413,7 +413,7 @@ impl Parse for VerticalPosition {
let first = try!(PositionComponent::parse(context, input)); let first = try!(PositionComponent::parse(context, input));
let second = input.try(|i| PositionComponent::parse(context, i)).ok(); let second = input.try(|i| PositionComponent::parse(context, i)).ok();
let (keyword, position) = if let PositionCategory::LengthOrPercentage = category(first) { let (keyword, position) = if let PositionCategory::LengthOrPercentage = category(&first) {
// "length keyword?" // "length keyword?"
(second, Some(first)) (second, Some(first))
} else { } else {
@ -424,7 +424,7 @@ impl Parse for VerticalPosition {
// Unwrapping and checking keyword. // Unwrapping and checking keyword.
let keyword = match keyword { let keyword = match keyword {
Some(PositionComponent::Keyword(key)) => { Some(PositionComponent::Keyword(key)) => {
match category(keyword.unwrap()) { match category(keyword.as_ref().unwrap()) {
PositionCategory::HorizontalKeyword | PositionCategory::HorizontalKeyword |
PositionCategory::HorizontalLogicalKeyword => return Err(()), PositionCategory::HorizontalLogicalKeyword => return Err(()),
_ => Some(key), _ => Some(key),
@ -465,10 +465,10 @@ impl ToComputedValue for VerticalPosition {
let vertical = match keyword { let vertical = match keyword {
// FIXME(canaltinova): Support logical keywords. // FIXME(canaltinova): Support logical keywords.
Keyword::Bottom | Keyword::YEnd => { Keyword::Bottom | Keyword::YEnd => {
if let Some(x) = self.position { if let Some(ref x) = self.position {
let (length, percentage) = match x { let (length, percentage) = match *x {
LengthOrPercentage::Percentage(Percentage(y)) => (Au(0), Some(1.0 - y)), LengthOrPercentage::Percentage(Percentage(y)) => (Au(0), Some(1.0 - y)),
LengthOrPercentage::Length(y) => (-y.to_computed_value(context), Some(1.0)), LengthOrPercentage::Length(ref y) => (-y.to_computed_value(context), Some(1.0)),
_ => (Au(0), None), _ => (Au(0), None),
}; };
ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage { ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage {
@ -483,8 +483,8 @@ impl ToComputedValue for VerticalPosition {
keyword.to_length_or_percentage().to_computed_value(context) keyword.to_length_or_percentage().to_computed_value(context)
}, },
_ => { _ => {
let vert = self.position let zero = LengthOrPercentage::Percentage(Percentage(0.0));
.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.0))); let vert = self.position.as_ref().unwrap_or(&zero);
vert.to_computed_value(context) vert.to_computed_value(context)
}, },
}; };
@ -539,7 +539,7 @@ enum PositionCategory {
/// A position component. /// A position component.
/// ///
/// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position /// http://dev.w3.org/csswg/css2/colors.html#propdef-background-position
#[derive(Clone, PartialEq, Copy)] #[derive(Clone, PartialEq)]
pub enum PositionComponent { pub enum PositionComponent {
/// A `<length>` /// A `<length>`
Length(LengthOrPercentage), Length(LengthOrPercentage),
@ -547,8 +547,8 @@ pub enum PositionComponent {
Keyword(Keyword), Keyword(Keyword),
} }
fn category(p: PositionComponent) -> PositionCategory { fn category(p: &PositionComponent) -> PositionCategory {
if let PositionComponent::Keyword(keyword) = p { if let PositionComponent::Keyword(keyword) = *p {
match keyword { match keyword {
Keyword::Left | Keyword::Right => Keyword::Left | Keyword::Right =>
PositionCategory::HorizontalKeyword, PositionCategory::HorizontalKeyword,
@ -569,7 +569,7 @@ fn category(p: PositionComponent) -> PositionCategory {
impl HasViewportPercentage for PositionComponent { impl HasViewportPercentage for PositionComponent {
fn has_viewport_percentage(&self) -> bool { fn has_viewport_percentage(&self) -> bool {
match *self { match *self {
PositionComponent::Length(length) => length.has_viewport_percentage(), PositionComponent::Length(ref length) => length.has_viewport_percentage(),
_ => false _ => false
} }
} }
@ -578,10 +578,12 @@ impl HasViewportPercentage for PositionComponent {
impl PositionComponent { impl PositionComponent {
/// Convert the given position component to a length or a percentage. /// Convert the given position component to a length or a percentage.
#[inline] #[inline]
pub fn to_length_or_percentage(self) -> LengthOrPercentage { pub fn to_length_or_percentage_computed(&self, cx: &Context) -> computed::LengthOrPercentage {
match self { match *self {
PositionComponent::Length(value) => value, PositionComponent::Length(ref value) => value.to_computed_value(cx),
PositionComponent::Keyword(keyword) => keyword.to_length_or_percentage(), PositionComponent::Keyword(keyword) => {
keyword.to_length_or_percentage().to_computed_value(cx)
}
} }
} }
} }

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

@ -85,7 +85,7 @@ macro_rules! declare_viewport_descriptor_inner {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
$( $(
ViewportDescriptor::$assigned_variant(val) => { ViewportDescriptor::$assigned_variant(ref val) => {
try!(dest.write_str($assigned_variant_name)); try!(dest.write_str($assigned_variant_name));
try!(dest.write_str(": ")); try!(dest.write_str(": "));
try!(val.to_css(dest)); try!(val.to_css(dest));
@ -121,7 +121,7 @@ trait FromMeta: Sized {
/// See: /// See:
/// * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc /// * http://dev.w3.org/csswg/css-device-adapt/#min-max-width-desc
/// * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom /// * http://dev.w3.org/csswg/css-device-adapt/#extend-to-zoom
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum ViewportLength { pub enum ViewportLength {
@ -134,7 +134,7 @@ impl ToCss for ViewportLength {
where W: fmt::Write, where W: fmt::Write,
{ {
match *self { match *self {
ViewportLength::Specified(length) => length.to_css(dest), ViewportLength::Specified(ref length) => length.to_css(dest),
ViewportLength::ExtendToZoom => write!(dest, "extend-to-zoom"), ViewportLength::ExtendToZoom => write!(dest, "extend-to-zoom"),
} }
} }
@ -244,11 +244,11 @@ impl ToCss for ViewportDescriptorDeclaration {
} }
} }
fn parse_shorthand(input: &mut Parser) -> Result<[ViewportLength; 2], ()> { fn parse_shorthand(input: &mut Parser) -> Result<(ViewportLength, ViewportLength), ()> {
let min = try!(ViewportLength::parse(input)); let min = try!(ViewportLength::parse(input));
match input.try(|input| ViewportLength::parse(input)) { match input.try(|input| ViewportLength::parse(input)) {
Err(()) => Ok([min, min]), Err(()) => Ok((min.clone(), min)),
Ok(max) => Ok([min, max]) Ok(max) => Ok((min, max))
} }
} }
@ -282,8 +282,8 @@ impl<'a, 'b> DeclarationParser for ViewportRuleParser<'a, 'b> {
let shorthand = try!(parse_shorthand(input)); let shorthand = try!(parse_shorthand(input));
let important = input.try(parse_important).is_ok(); let important = input.try(parse_important).is_ok();
Ok(vec![declaration!($min(value: shorthand[0], important: important)), Ok(vec![declaration!($min(value: shorthand.0, important: important)),
declaration!($max(value: shorthand[1], important: important))]) declaration!($max(value: shorthand.1, important: important))])
}} }}
} }
@ -631,11 +631,11 @@ impl MaybeNew for ViewportConstraints {
// collapse the list of declarations into descriptor values // collapse the list of declarations into descriptor values
for declaration in &rule.declarations { for declaration in &rule.declarations {
match declaration.descriptor { match declaration.descriptor {
ViewportDescriptor::MinWidth(value) => min_width = Some(value), ViewportDescriptor::MinWidth(ref value) => min_width = Some(value),
ViewportDescriptor::MaxWidth(value) => max_width = Some(value), ViewportDescriptor::MaxWidth(ref value) => max_width = Some(value),
ViewportDescriptor::MinHeight(value) => min_height = Some(value), ViewportDescriptor::MinHeight(ref value) => min_height = Some(value),
ViewportDescriptor::MaxHeight(value) => max_height = Some(value), ViewportDescriptor::MaxHeight(ref value) => max_height = Some(value),
ViewportDescriptor::Zoom(value) => initial_zoom = value.to_f32(), ViewportDescriptor::Zoom(value) => initial_zoom = value.to_f32(),
ViewportDescriptor::MinZoom(value) => min_zoom = value.to_f32(), ViewportDescriptor::MinZoom(value) => min_zoom = value.to_f32(),
@ -654,7 +654,7 @@ impl MaybeNew for ViewportConstraints {
(None, None) => None, (None, None) => None,
(a, None) => a, (a, None) => a,
(None, b) => b, (None, b) => b,
(a, b) => Some(a.unwrap().$op(b.unwrap())), (Some(a), Some(b)) => Some(a.$op(b)),
} }
} }
} }
@ -709,14 +709,14 @@ impl MaybeNew for ViewportConstraints {
macro_rules! to_pixel_length { macro_rules! to_pixel_length {
($value:ident, $dimension:ident, $extend_to:ident => $auto_extend_to:expr) => { ($value:ident, $dimension:ident, $extend_to:ident => $auto_extend_to:expr) => {
if let Some($value) = $value { if let Some($value) = $value {
match $value { match *$value {
ViewportLength::Specified(length) => match length { ViewportLength::Specified(ref length) => match *length {
LengthOrPercentageOrAuto::Length(value) => LengthOrPercentageOrAuto::Length(ref value) =>
Some(value.to_computed_value(&context)), Some(value.to_computed_value(&context)),
LengthOrPercentageOrAuto::Percentage(value) => LengthOrPercentageOrAuto::Percentage(value) =>
Some(initial_viewport.$dimension.scale_by(value.0)), Some(initial_viewport.$dimension.scale_by(value.0)),
LengthOrPercentageOrAuto::Auto => None, LengthOrPercentageOrAuto::Auto => None,
LengthOrPercentageOrAuto::Calc(calc) => { LengthOrPercentageOrAuto::Calc(ref calc) => {
let calc = calc.to_computed_value(&context); let calc = calc.to_computed_value(&context);
Some(initial_viewport.$dimension.scale_by(calc.percentage()) + calc.length()) Some(initial_viewport.$dimension.scale_by(calc.percentage()) + calc.length())
} }

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

@ -207,7 +207,7 @@ fn test_mq_default_expressions() {
assert!(q.media_type == MediaQueryType::All, css.to_owned()); assert!(q.media_type == MediaQueryType::All, css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))), ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });
@ -219,7 +219,7 @@ fn test_mq_default_expressions() {
assert!(q.media_type == MediaQueryType::All, css.to_owned()); assert!(q.media_type == MediaQueryType::All, css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(43))), ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(43))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });
@ -234,7 +234,7 @@ fn test_mq_expressions() {
assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))), ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });
@ -246,7 +246,7 @@ fn test_mq_expressions() {
assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(43))), ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(43))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });
@ -258,7 +258,7 @@ fn test_mq_expressions() {
assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Eq(w)) => assert!(w == specified::Length::Absolute(Au::from_px(43))), ExpressionKind::Width(Range::Eq(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(43))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });
@ -270,7 +270,7 @@ fn test_mq_expressions() {
assert!(q.media_type == MediaQueryType::Unknown(Atom::from("fridge")), css.to_owned()); assert!(q.media_type == MediaQueryType::Unknown(Atom::from("fridge")), css.to_owned());
assert!(q.expressions.len() == 1, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(52))), ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(52))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });
@ -295,11 +295,11 @@ fn test_mq_multiple_expressions() {
assert!(q.media_type == MediaQueryType::All, css.to_owned()); assert!(q.media_type == MediaQueryType::All, css.to_owned());
assert!(q.expressions.len() == 2, css.to_owned()); assert!(q.expressions.len() == 2, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))), ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
match *q.expressions[1].kind_for_testing() { match *q.expressions[1].kind_for_testing() {
ExpressionKind::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(200))), ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(200))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });
@ -311,11 +311,11 @@ fn test_mq_multiple_expressions() {
assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned());
assert!(q.expressions.len() == 2, css.to_owned()); assert!(q.expressions.len() == 2, css.to_owned());
match *q.expressions[0].kind_for_testing() { match *q.expressions[0].kind_for_testing() {
ExpressionKind::Width(Range::Min(w)) => assert!(w == specified::Length::Absolute(Au::from_px(100))), ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
match *q.expressions[1].kind_for_testing() { match *q.expressions[1].kind_for_testing() {
ExpressionKind::Width(Range::Max(w)) => assert!(w == specified::Length::Absolute(Au::from_px(200))), ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(200))),
_ => panic!("wrong expression type"), _ => panic!("wrong expression type"),
} }
}); });