mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Extracted shorthands to separate files.
I've deliberately tried to keep things similarly structured as in the longhand files. I.e. if a given property is in e.g. longhand/box.mako.rs, the shorthand stuff that relates to the same property is in shorthand/box.mako.rs and so forth.
This commit is contained in:
parent
1fee7185a7
commit
38f90a3e2e
12 changed files with 727 additions and 664 deletions
|
@ -189,3 +189,82 @@
|
|||
}
|
||||
</%call>
|
||||
</%def>
|
||||
|
||||
<%def name="shorthand(name, sub_properties, experimental=False)">
|
||||
<%
|
||||
shorthand = data.declare_shorthand(name, sub_properties.split(), experimental=experimental)
|
||||
%>
|
||||
pub mod ${shorthand.ident} {
|
||||
use cssparser::Parser;
|
||||
use parser::ParserContext;
|
||||
use properties::{longhands, PropertyDeclaration, DeclaredValue, Shorthand};
|
||||
|
||||
pub struct Longhands {
|
||||
% for sub_property in shorthand.sub_properties:
|
||||
pub ${sub_property.ident}:
|
||||
Option<longhands::${sub_property.ident}::SpecifiedValue>,
|
||||
% endfor
|
||||
}
|
||||
|
||||
pub fn parse(context: &ParserContext, input: &mut Parser,
|
||||
declarations: &mut Vec<PropertyDeclaration>)
|
||||
-> Result<(), ()> {
|
||||
input.look_for_var_functions();
|
||||
let start = input.position();
|
||||
let value = input.parse_entirely(|input| parse_value(context, input));
|
||||
if value.is_err() {
|
||||
while let Ok(_) = input.next() {} // Look for var() after the error.
|
||||
}
|
||||
let var = input.seen_var_functions();
|
||||
if let Ok(value) = value {
|
||||
% for sub_property in shorthand.sub_properties:
|
||||
declarations.push(PropertyDeclaration::${sub_property.camel_case}(
|
||||
match value.${sub_property.ident} {
|
||||
Some(value) => DeclaredValue::Value(value),
|
||||
None => DeclaredValue::Initial,
|
||||
}
|
||||
));
|
||||
% endfor
|
||||
Ok(())
|
||||
} else if var {
|
||||
input.reset(start);
|
||||
let (first_token_type, css) = try!(
|
||||
::custom_properties::parse_non_custom_with_var(input));
|
||||
% for sub_property in shorthand.sub_properties:
|
||||
declarations.push(PropertyDeclaration::${sub_property.camel_case}(
|
||||
DeclaredValue::WithVariables {
|
||||
css: css.clone().into_owned(),
|
||||
first_token_type: first_token_type,
|
||||
base_url: context.base_url.clone(),
|
||||
from_shorthand: Some(Shorthand::${shorthand.camel_case}),
|
||||
}
|
||||
));
|
||||
% endfor
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||
${caller.body()}
|
||||
}
|
||||
}
|
||||
</%def>
|
||||
|
||||
<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function)">
|
||||
<%self:shorthand name="${name}" sub_properties="${
|
||||
' '.join(sub_property_pattern % side
|
||||
for side in ['top', 'right', 'bottom', 'left'])}">
|
||||
use super::parse_four_sides;
|
||||
use values::specified;
|
||||
let _unused = context;
|
||||
let (top, right, bottom, left) = try!(parse_four_sides(input, ${parser_function}));
|
||||
Ok(Longhands {
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
${to_rust_ident(sub_property_pattern % side)}: Some(${side}),
|
||||
% endfor
|
||||
})
|
||||
</%self:shorthand>
|
||||
</%def>
|
||||
|
|
|
@ -70,75 +70,11 @@ pub mod longhands {
|
|||
<%include file="/longhand/svg.mako.rs" />
|
||||
}
|
||||
|
||||
|
||||
pub mod shorthands {
|
||||
use cssparser::Parser;
|
||||
use parser::ParserContext;
|
||||
use values::specified;
|
||||
|
||||
<%def name="shorthand(name, sub_properties, experimental=False)">
|
||||
<%
|
||||
shorthand = data.declare_shorthand(name, sub_properties.split(), experimental=experimental)
|
||||
%>
|
||||
pub mod ${shorthand.ident} {
|
||||
use cssparser::Parser;
|
||||
use parser::ParserContext;
|
||||
use properties::{longhands, PropertyDeclaration, DeclaredValue, Shorthand};
|
||||
|
||||
pub struct Longhands {
|
||||
% for sub_property in shorthand.sub_properties:
|
||||
pub ${sub_property.ident}:
|
||||
Option<longhands::${sub_property.ident}::SpecifiedValue>,
|
||||
% endfor
|
||||
}
|
||||
|
||||
pub fn parse(context: &ParserContext, input: &mut Parser,
|
||||
declarations: &mut Vec<PropertyDeclaration>)
|
||||
-> Result<(), ()> {
|
||||
input.look_for_var_functions();
|
||||
let start = input.position();
|
||||
let value = input.parse_entirely(|input| parse_value(context, input));
|
||||
if value.is_err() {
|
||||
while let Ok(_) = input.next() {} // Look for var() after the error.
|
||||
}
|
||||
let var = input.seen_var_functions();
|
||||
if let Ok(value) = value {
|
||||
% for sub_property in shorthand.sub_properties:
|
||||
declarations.push(PropertyDeclaration::${sub_property.camel_case}(
|
||||
match value.${sub_property.ident} {
|
||||
Some(value) => DeclaredValue::Value(value),
|
||||
None => DeclaredValue::Initial,
|
||||
}
|
||||
));
|
||||
% endfor
|
||||
Ok(())
|
||||
} else if var {
|
||||
input.reset(start);
|
||||
let (first_token_type, css) = try!(
|
||||
::custom_properties::parse_non_custom_with_var(input));
|
||||
% for sub_property in shorthand.sub_properties:
|
||||
declarations.push(PropertyDeclaration::${sub_property.camel_case}(
|
||||
DeclaredValue::WithVariables {
|
||||
css: css.clone().into_owned(),
|
||||
first_token_type: first_token_type,
|
||||
base_url: context.base_url.clone(),
|
||||
from_shorthand: Some(Shorthand::${shorthand.camel_case}),
|
||||
}
|
||||
));
|
||||
% endfor
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
|
||||
${caller.body()}
|
||||
}
|
||||
}
|
||||
</%def>
|
||||
|
||||
fn parse_four_sides<F, T>(input: &mut Parser, parse_one: F) -> Result<(T, T, T, T), ()>
|
||||
where F: Fn(&mut Parser) -> Result<T, ()>, F: Copy, T: Clone {
|
||||
// zero or more than four values is invalid.
|
||||
|
@ -182,606 +118,16 @@ pub mod shorthands {
|
|||
Ok((top, right, bottom, left))
|
||||
}
|
||||
|
||||
<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function)">
|
||||
<%self:shorthand name="${name}" sub_properties="${
|
||||
' '.join(sub_property_pattern % side
|
||||
for side in ['top', 'right', 'bottom', 'left'])}">
|
||||
use super::parse_four_sides;
|
||||
use values::specified;
|
||||
let _unused = context;
|
||||
let (top, right, bottom, left) = try!(parse_four_sides(input, ${parser_function}));
|
||||
Ok(Longhands {
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
${to_rust_ident(sub_property_pattern % side)}: Some(${side}),
|
||||
% endfor
|
||||
})
|
||||
</%self:shorthand>
|
||||
</%def>
|
||||
|
||||
// TODO: other background-* properties
|
||||
<%self:shorthand name="background"
|
||||
sub_properties="background-color background-position background-repeat background-attachment
|
||||
background-image background-size background-origin background-clip">
|
||||
use properties::longhands::{background_color, background_position, background_repeat, background_attachment};
|
||||
use properties::longhands::{background_image, background_size, background_origin, background_clip};
|
||||
|
||||
let mut color = None;
|
||||
let mut image = None;
|
||||
let mut position = None;
|
||||
let mut repeat = None;
|
||||
let mut size = None;
|
||||
let mut attachment = None;
|
||||
let mut any = false;
|
||||
let mut origin = None;
|
||||
let mut clip = None;
|
||||
|
||||
loop {
|
||||
if position.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_position::parse(context, input)) {
|
||||
position = Some(value);
|
||||
any = true;
|
||||
|
||||
// Parse background size, if applicable.
|
||||
size = input.try(|input| {
|
||||
try!(input.expect_delim('/'));
|
||||
background_size::parse(context, input)
|
||||
}).ok();
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
if color.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_color::parse(context, input)) {
|
||||
color = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if image.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_image::parse(context, input)) {
|
||||
image = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if repeat.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_repeat::parse(context, input)) {
|
||||
repeat = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if attachment.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_attachment::parse(context, input)) {
|
||||
attachment = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if origin.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_origin::parse(context, input)) {
|
||||
origin = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if clip.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_clip::parse(context, input)) {
|
||||
clip = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if any {
|
||||
Ok(Longhands {
|
||||
background_color: color,
|
||||
background_image: image,
|
||||
background_position: position,
|
||||
background_repeat: repeat,
|
||||
background_attachment: attachment,
|
||||
background_size: size,
|
||||
background_origin: origin,
|
||||
background_clip: clip,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
</%self:shorthand>
|
||||
|
||||
${four_sides_shorthand("margin", "margin-%s", "specified::LengthOrPercentageOrAuto::parse")}
|
||||
${four_sides_shorthand("padding", "padding-%s", "specified::LengthOrPercentage::parse")}
|
||||
|
||||
${four_sides_shorthand("border-color", "border-%s-color", "specified::CSSColor::parse")}
|
||||
${four_sides_shorthand("border-style", "border-%s-style",
|
||||
"specified::BorderStyle::parse")}
|
||||
<%self:shorthand name="border-width" sub_properties="${
|
||||
' '.join('border-%s-width' % side
|
||||
for side in ['top', 'right', 'bottom', 'left'])}">
|
||||
use super::parse_four_sides;
|
||||
use values::specified;
|
||||
let _unused = context;
|
||||
let (top, right, bottom, left) = try!(parse_four_sides(input, specified::parse_border_width));
|
||||
Ok(Longhands {
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
${to_rust_ident('border-%s-width' % side)}:
|
||||
Some(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue(${side})),
|
||||
% endfor
|
||||
})
|
||||
</%self:shorthand>
|
||||
|
||||
|
||||
pub fn parse_border(context: &ParserContext, input: &mut Parser)
|
||||
-> Result<(Option<specified::CSSColor>,
|
||||
Option<specified::BorderStyle>,
|
||||
Option<specified::Length>), ()> {
|
||||
use values::specified;
|
||||
let _unused = context;
|
||||
let mut color = None;
|
||||
let mut style = None;
|
||||
let mut width = None;
|
||||
let mut any = false;
|
||||
loop {
|
||||
if color.is_none() {
|
||||
if let Ok(value) = input.try(specified::CSSColor::parse) {
|
||||
color = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if style.is_none() {
|
||||
if let Ok(value) = input.try(specified::BorderStyle::parse) {
|
||||
style = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if width.is_none() {
|
||||
if let Ok(value) = input.try(specified::parse_border_width) {
|
||||
width = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if any { Ok((color, style, width)) } else { Err(()) }
|
||||
}
|
||||
|
||||
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
<%self:shorthand name="border-${side}" sub_properties="${' '.join(
|
||||
'border-%s-%s' % (side, prop)
|
||||
for prop in ['color', 'style', 'width']
|
||||
)}">
|
||||
let (color, style, width) = try!(super::parse_border(context, input));
|
||||
Ok(Longhands {
|
||||
border_${side}_color: color,
|
||||
border_${side}_style: style,
|
||||
border_${side}_width:
|
||||
width.map(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue),
|
||||
})
|
||||
</%self:shorthand>
|
||||
% endfor
|
||||
|
||||
<%self:shorthand name="border" sub_properties="${' '.join(
|
||||
'border-%s-%s' % (side, prop)
|
||||
for side in ['top', 'right', 'bottom', 'left']
|
||||
for prop in ['color', 'style', 'width']
|
||||
)}">
|
||||
let (color, style, width) = try!(super::parse_border(context, input));
|
||||
Ok(Longhands {
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
border_${side}_color: color.clone(),
|
||||
border_${side}_style: style,
|
||||
border_${side}_width:
|
||||
width.map(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue),
|
||||
% endfor
|
||||
})
|
||||
</%self:shorthand>
|
||||
|
||||
<%self:shorthand name="border-radius" sub_properties="${' '.join(
|
||||
'border-%s-radius' % (corner)
|
||||
for corner in ['top-left', 'top-right', 'bottom-right', 'bottom-left']
|
||||
)}">
|
||||
use app_units::Au;
|
||||
use values::specified::{Length, LengthOrPercentage};
|
||||
use values::specified::BorderRadiusSize;
|
||||
|
||||
let _ignored = context;
|
||||
|
||||
fn parse_one_set_of_border_values(mut input: &mut Parser)
|
||||
-> Result<[LengthOrPercentage; 4], ()> {
|
||||
let mut count = 0;
|
||||
let mut values = [LengthOrPercentage::Length(Length::Absolute(Au(0))); 4];
|
||||
while count < 4 {
|
||||
if let Ok(value) = input.try(LengthOrPercentage::parse) {
|
||||
values[count] = value;
|
||||
count += 1;
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
match count {
|
||||
1 => Ok([values[0], values[0], values[0], values[0]]),
|
||||
2 => Ok([values[0], values[1], values[0], values[1]]),
|
||||
3 => Ok([values[0], values[1], values[2], values[1]]),
|
||||
4 => Ok([values[0], values[1], values[2], values[3]]),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_one_set_of_border_radii(mut input: &mut Parser)
|
||||
-> Result<[BorderRadiusSize; 4], ()> {
|
||||
let widths = try!(parse_one_set_of_border_values(input));
|
||||
let mut heights = widths.clone();
|
||||
let mut radii_values = [BorderRadiusSize::zero(); 4];
|
||||
if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||
heights = try!(parse_one_set_of_border_values(input));
|
||||
}
|
||||
for i in 0..radii_values.len() {
|
||||
radii_values[i] = BorderRadiusSize::new(widths[i], heights[i]);
|
||||
}
|
||||
Ok(radii_values)
|
||||
}
|
||||
|
||||
let radii = try!(parse_one_set_of_border_radii(input));
|
||||
Ok(Longhands {
|
||||
border_top_left_radius: Some(radii[0]),
|
||||
border_top_right_radius: Some(radii[1]),
|
||||
border_bottom_right_radius: Some(radii[2]),
|
||||
border_bottom_left_radius: Some(radii[3]),
|
||||
})
|
||||
</%self:shorthand>
|
||||
|
||||
<%self:shorthand name="outline" sub_properties="outline-color outline-style outline-width">
|
||||
use properties::longhands::outline_width;
|
||||
use values::specified;
|
||||
|
||||
let _unused = context;
|
||||
let mut color = None;
|
||||
let mut style = None;
|
||||
let mut width = None;
|
||||
let mut any = false;
|
||||
loop {
|
||||
if color.is_none() {
|
||||
if let Ok(value) = input.try(specified::CSSColor::parse) {
|
||||
color = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if style.is_none() {
|
||||
if let Ok(value) = input.try(specified::BorderStyle::parse) {
|
||||
style = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if width.is_none() {
|
||||
if let Ok(value) = input.try(|input| outline_width::parse(context, input)) {
|
||||
width = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if any {
|
||||
Ok(Longhands {
|
||||
outline_color: color,
|
||||
outline_style: style,
|
||||
outline_width: width,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
</%self:shorthand>
|
||||
|
||||
<%self:shorthand name="font" sub_properties="font-style font-variant font-weight
|
||||
font-size line-height font-family">
|
||||
use properties::longhands::{font_style, font_variant, font_weight, font_size,
|
||||
line_height, font_family};
|
||||
let mut nb_normals = 0;
|
||||
let mut style = None;
|
||||
let mut variant = None;
|
||||
let mut weight = None;
|
||||
let size;
|
||||
loop {
|
||||
// Special-case 'normal' because it is valid in each of
|
||||
// font-style, font-weight and font-variant.
|
||||
// Leaves the values to None, 'normal' is the initial value for each of them.
|
||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||
nb_normals += 1;
|
||||
continue;
|
||||
}
|
||||
if style.is_none() {
|
||||
if let Ok(value) = input.try(|input| font_style::parse(context, input)) {
|
||||
style = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
if weight.is_none() {
|
||||
if let Ok(value) = input.try(|input| font_weight::parse(context, input)) {
|
||||
weight = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
if variant.is_none() {
|
||||
if let Ok(value) = input.try(|input| font_variant::parse(context, input)) {
|
||||
variant = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
size = Some(try!(font_size::parse(context, input)));
|
||||
break
|
||||
}
|
||||
#[inline]
|
||||
fn count<T>(opt: &Option<T>) -> u8 {
|
||||
if opt.is_some() { 1 } else { 0 }
|
||||
}
|
||||
if size.is_none() || (count(&style) + count(&weight) + count(&variant) + nb_normals) > 3 {
|
||||
return Err(())
|
||||
}
|
||||
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||
Some(try!(line_height::parse(context, input)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let family = try!(input.parse_comma_separated(font_family::parse_one_family));
|
||||
Ok(Longhands {
|
||||
font_style: style,
|
||||
font_variant: variant,
|
||||
font_weight: weight,
|
||||
font_size: size,
|
||||
line_height: line_height,
|
||||
font_family: Some(font_family::SpecifiedValue(family))
|
||||
})
|
||||
</%self:shorthand>
|
||||
|
||||
// Per CSS-TEXT 6.2, "for legacy reasons, UAs must treat `word-wrap` as an alternate name for
|
||||
// the `overflow-wrap` property, as if it were a shorthand of `overflow-wrap`."
|
||||
<%self:shorthand name="word-wrap" sub_properties="overflow-wrap">
|
||||
use properties::longhands::overflow_wrap;
|
||||
Ok(Longhands {
|
||||
overflow_wrap: Some(try!(overflow_wrap::parse(context, input))),
|
||||
})
|
||||
</%self:shorthand>
|
||||
|
||||
<%self:shorthand name="list-style"
|
||||
sub_properties="list-style-image list-style-position list-style-type">
|
||||
use properties::longhands::{list_style_image, list_style_position, list_style_type};
|
||||
|
||||
// `none` is ambiguous until we've finished parsing the shorthands, so we count the number
|
||||
// of times we see it.
|
||||
let mut nones = 0u8;
|
||||
let (mut image, mut position, mut list_style_type, mut any) = (None, None, None, false);
|
||||
loop {
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
nones = nones + 1;
|
||||
if nones > 2 {
|
||||
return Err(())
|
||||
}
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
|
||||
if list_style_type.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_type::parse(context, input)) {
|
||||
list_style_type = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if image.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_image::parse(context, input)) {
|
||||
image = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if position.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_position::parse(context, input)) {
|
||||
position = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// If there are two `none`s, then we can't have a type or image; if there is one `none`,
|
||||
// then we can't have both a type *and* an image; if there is no `none` then we're fine as
|
||||
// long as we parsed something.
|
||||
match (any, nones, list_style_type, image) {
|
||||
(true, 2, None, None) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||
})
|
||||
}
|
||||
(true, 1, None, Some(image)) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(image),
|
||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||
})
|
||||
}
|
||||
(true, 1, Some(list_style_type), None) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||
list_style_type: Some(list_style_type),
|
||||
})
|
||||
}
|
||||
(true, 1, None, None) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||
})
|
||||
}
|
||||
(true, 0, list_style_type, image) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: image,
|
||||
list_style_type: list_style_type,
|
||||
})
|
||||
}
|
||||
_ => Err(()),
|
||||
}
|
||||
</%self:shorthand>
|
||||
|
||||
<%self:shorthand name="columns" sub_properties="column-count column-width" experimental="True">
|
||||
use properties::longhands::{column_count, column_width};
|
||||
let mut column_count = None;
|
||||
let mut column_width = None;
|
||||
let mut autos = 0;
|
||||
|
||||
loop {
|
||||
if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
|
||||
// Leave the options to None, 'auto' is the initial value.
|
||||
autos += 1;
|
||||
continue
|
||||
}
|
||||
|
||||
if column_count.is_none() {
|
||||
if let Ok(value) = input.try(|input| column_count::parse(context, input)) {
|
||||
column_count = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if column_width.is_none() {
|
||||
if let Ok(value) = input.try(|input| column_width::parse(context, input)) {
|
||||
column_width = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
let values = autos + column_count.iter().len() + column_width.iter().len();
|
||||
if values == 0 || values > 2 {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(Longhands {
|
||||
column_count: column_count,
|
||||
column_width: column_width,
|
||||
})
|
||||
}
|
||||
</%self:shorthand>
|
||||
|
||||
<%self:shorthand name="overflow" sub_properties="overflow-x overflow-y">
|
||||
use properties::longhands::{overflow_x, overflow_y};
|
||||
|
||||
let overflow = try!(overflow_x::parse(context, input));
|
||||
Ok(Longhands {
|
||||
overflow_x: Some(overflow),
|
||||
overflow_y: Some(overflow_y::SpecifiedValue(overflow)),
|
||||
})
|
||||
</%self:shorthand>
|
||||
|
||||
<%self:shorthand name="transition"
|
||||
sub_properties="transition-property transition-duration transition-timing-function
|
||||
transition-delay">
|
||||
use properties::longhands::{transition_delay, transition_duration, transition_property};
|
||||
use properties::longhands::{transition_timing_function};
|
||||
|
||||
struct SingleTransition {
|
||||
transition_property: transition_property::SingleSpecifiedValue,
|
||||
transition_duration: transition_duration::SingleSpecifiedValue,
|
||||
transition_timing_function: transition_timing_function::SingleSpecifiedValue,
|
||||
transition_delay: transition_delay::SingleSpecifiedValue,
|
||||
}
|
||||
|
||||
fn parse_one_transition(input: &mut Parser) -> Result<SingleTransition,()> {
|
||||
let (mut property, mut duration) = (None, None);
|
||||
let (mut timing_function, mut delay) = (None, None);
|
||||
loop {
|
||||
if property.is_none() {
|
||||
if let Ok(value) = input.try(|input| transition_property::parse_one(input)) {
|
||||
property = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if duration.is_none() {
|
||||
if let Ok(value) = input.try(|input| transition_duration::parse_one(input)) {
|
||||
duration = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if timing_function.is_none() {
|
||||
if let Ok(value) = input.try(|input| {
|
||||
transition_timing_function::parse_one(input)
|
||||
}) {
|
||||
timing_function = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if delay.is_none() {
|
||||
if let Ok(value) = input.try(|input| transition_delay::parse_one(input)) {
|
||||
delay = Some(value);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
if let Some(property) = property {
|
||||
Ok(SingleTransition {
|
||||
transition_property: property,
|
||||
transition_duration:
|
||||
duration.unwrap_or(transition_duration::get_initial_single_value()),
|
||||
transition_timing_function:
|
||||
timing_function.unwrap_or(
|
||||
transition_timing_function::get_initial_single_value()),
|
||||
transition_delay:
|
||||
delay.unwrap_or(transition_delay::get_initial_single_value()),
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(Longhands {
|
||||
transition_property: None,
|
||||
transition_duration: None,
|
||||
transition_timing_function: None,
|
||||
transition_delay: None,
|
||||
})
|
||||
}
|
||||
|
||||
let results = try!(input.parse_comma_separated(parse_one_transition));
|
||||
let (mut properties, mut durations) = (Vec::new(), Vec::new());
|
||||
let (mut timing_functions, mut delays) = (Vec::new(), Vec::new());
|
||||
for result in results {
|
||||
properties.push(result.transition_property);
|
||||
durations.push(result.transition_duration);
|
||||
timing_functions.push(result.transition_timing_function);
|
||||
delays.push(result.transition_delay);
|
||||
}
|
||||
|
||||
Ok(Longhands {
|
||||
transition_property: Some(transition_property::SpecifiedValue(properties)),
|
||||
transition_duration: Some(transition_duration::SpecifiedValue(durations)),
|
||||
transition_timing_function:
|
||||
Some(transition_timing_function::SpecifiedValue(timing_functions)),
|
||||
transition_delay: Some(transition_delay::SpecifiedValue(delays)),
|
||||
})
|
||||
</%self:shorthand>
|
||||
<%include file="/shorthand/background.mako.rs" />
|
||||
<%include file="/shorthand/border.mako.rs" />
|
||||
<%include file="/shorthand/box.mako.rs" />
|
||||
<%include file="/shorthand/column.mako.rs" />
|
||||
<%include file="/shorthand/font.mako.rs" />
|
||||
<%include file="/shorthand/inherited_text.mako.rs" />
|
||||
<%include file="/shorthand/list.mako.rs" />
|
||||
<%include file="/shorthand/margin.mako.rs" />
|
||||
<%include file="/shorthand/outline.mako.rs" />
|
||||
<%include file="/shorthand/padding.mako.rs" />
|
||||
}
|
||||
|
||||
|
||||
|
|
99
components/style/properties/shorthand/background.mako.rs
Normal file
99
components/style/properties/shorthand/background.mako.rs
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
// TODO: other background-* properties
|
||||
<%helpers:shorthand name="background"
|
||||
sub_properties="background-color background-position background-repeat background-attachment
|
||||
background-image background-size background-origin background-clip">
|
||||
use properties::longhands::{background_color, background_position, background_repeat, background_attachment};
|
||||
use properties::longhands::{background_image, background_size, background_origin, background_clip};
|
||||
|
||||
let mut color = None;
|
||||
let mut image = None;
|
||||
let mut position = None;
|
||||
let mut repeat = None;
|
||||
let mut size = None;
|
||||
let mut attachment = None;
|
||||
let mut any = false;
|
||||
let mut origin = None;
|
||||
let mut clip = None;
|
||||
|
||||
loop {
|
||||
if position.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_position::parse(context, input)) {
|
||||
position = Some(value);
|
||||
any = true;
|
||||
|
||||
// Parse background size, if applicable.
|
||||
size = input.try(|input| {
|
||||
try!(input.expect_delim('/'));
|
||||
background_size::parse(context, input)
|
||||
}).ok();
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
if color.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_color::parse(context, input)) {
|
||||
color = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if image.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_image::parse(context, input)) {
|
||||
image = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if repeat.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_repeat::parse(context, input)) {
|
||||
repeat = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if attachment.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_attachment::parse(context, input)) {
|
||||
attachment = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if origin.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_origin::parse(context, input)) {
|
||||
origin = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if clip.is_none() {
|
||||
if let Ok(value) = input.try(|input| background_clip::parse(context, input)) {
|
||||
clip = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if any {
|
||||
Ok(Longhands {
|
||||
background_color: color,
|
||||
background_image: image,
|
||||
background_position: position,
|
||||
background_repeat: repeat,
|
||||
background_attachment: attachment,
|
||||
background_size: size,
|
||||
background_origin: origin,
|
||||
background_clip: clip,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
|
149
components/style/properties/shorthand/border.mako.rs
Normal file
149
components/style/properties/shorthand/border.mako.rs
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
<% from data import to_rust_ident %>
|
||||
|
||||
${helpers.four_sides_shorthand("border-color", "border-%s-color", "specified::CSSColor::parse")}
|
||||
${helpers.four_sides_shorthand("border-style", "border-%s-style",
|
||||
"specified::BorderStyle::parse")}
|
||||
<%helpers:shorthand name="border-width" sub_properties="${
|
||||
' '.join('border-%s-width' % side
|
||||
for side in ['top', 'right', 'bottom', 'left'])}">
|
||||
use super::parse_four_sides;
|
||||
use values::specified;
|
||||
let _unused = context;
|
||||
let (top, right, bottom, left) = try!(parse_four_sides(input, specified::parse_border_width));
|
||||
Ok(Longhands {
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
${to_rust_ident('border-%s-width' % side)}:
|
||||
Some(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue(${side})),
|
||||
% endfor
|
||||
})
|
||||
</%helpers:shorthand>
|
||||
|
||||
|
||||
pub fn parse_border(context: &ParserContext, input: &mut Parser)
|
||||
-> Result<(Option<specified::CSSColor>,
|
||||
Option<specified::BorderStyle>,
|
||||
Option<specified::Length>), ()> {
|
||||
use values::specified;
|
||||
let _unused = context;
|
||||
let mut color = None;
|
||||
let mut style = None;
|
||||
let mut width = None;
|
||||
let mut any = false;
|
||||
loop {
|
||||
if color.is_none() {
|
||||
if let Ok(value) = input.try(specified::CSSColor::parse) {
|
||||
color = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if style.is_none() {
|
||||
if let Ok(value) = input.try(specified::BorderStyle::parse) {
|
||||
style = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if width.is_none() {
|
||||
if let Ok(value) = input.try(specified::parse_border_width) {
|
||||
width = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if any { Ok((color, style, width)) } else { Err(()) }
|
||||
}
|
||||
|
||||
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
<%helpers:shorthand name="border-${side}" sub_properties="${' '.join(
|
||||
'border-%s-%s' % (side, prop)
|
||||
for prop in ['color', 'style', 'width']
|
||||
)}">
|
||||
let (color, style, width) = try!(super::parse_border(context, input));
|
||||
Ok(Longhands {
|
||||
border_${side}_color: color,
|
||||
border_${side}_style: style,
|
||||
border_${side}_width:
|
||||
width.map(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue),
|
||||
})
|
||||
</%helpers:shorthand>
|
||||
% endfor
|
||||
|
||||
<%helpers:shorthand name="border" sub_properties="${' '.join(
|
||||
'border-%s-%s' % (side, prop)
|
||||
for side in ['top', 'right', 'bottom', 'left']
|
||||
for prop in ['color', 'style', 'width']
|
||||
)}">
|
||||
let (color, style, width) = try!(super::parse_border(context, input));
|
||||
Ok(Longhands {
|
||||
% for side in ["top", "right", "bottom", "left"]:
|
||||
border_${side}_color: color.clone(),
|
||||
border_${side}_style: style,
|
||||
border_${side}_width:
|
||||
width.map(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue),
|
||||
% endfor
|
||||
})
|
||||
</%helpers:shorthand>
|
||||
|
||||
<%helpers:shorthand name="border-radius" sub_properties="${' '.join(
|
||||
'border-%s-radius' % (corner)
|
||||
for corner in ['top-left', 'top-right', 'bottom-right', 'bottom-left']
|
||||
)}">
|
||||
use app_units::Au;
|
||||
use values::specified::{Length, LengthOrPercentage};
|
||||
use values::specified::BorderRadiusSize;
|
||||
|
||||
let _ignored = context;
|
||||
|
||||
fn parse_one_set_of_border_values(mut input: &mut Parser)
|
||||
-> Result<[LengthOrPercentage; 4], ()> {
|
||||
let mut count = 0;
|
||||
let mut values = [LengthOrPercentage::Length(Length::Absolute(Au(0))); 4];
|
||||
while count < 4 {
|
||||
if let Ok(value) = input.try(LengthOrPercentage::parse) {
|
||||
values[count] = value;
|
||||
count += 1;
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
match count {
|
||||
1 => Ok([values[0], values[0], values[0], values[0]]),
|
||||
2 => Ok([values[0], values[1], values[0], values[1]]),
|
||||
3 => Ok([values[0], values[1], values[2], values[1]]),
|
||||
4 => Ok([values[0], values[1], values[2], values[3]]),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_one_set_of_border_radii(mut input: &mut Parser)
|
||||
-> Result<[BorderRadiusSize; 4], ()> {
|
||||
let widths = try!(parse_one_set_of_border_values(input));
|
||||
let mut heights = widths.clone();
|
||||
let mut radii_values = [BorderRadiusSize::zero(); 4];
|
||||
if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||
heights = try!(parse_one_set_of_border_values(input));
|
||||
}
|
||||
for i in 0..radii_values.len() {
|
||||
radii_values[i] = BorderRadiusSize::new(widths[i], heights[i]);
|
||||
}
|
||||
Ok(radii_values)
|
||||
}
|
||||
|
||||
let radii = try!(parse_one_set_of_border_radii(input));
|
||||
Ok(Longhands {
|
||||
border_top_left_radius: Some(radii[0]),
|
||||
border_top_right_radius: Some(radii[1]),
|
||||
border_bottom_right_radius: Some(radii[2]),
|
||||
border_bottom_left_radius: Some(radii[3]),
|
||||
})
|
||||
</%helpers:shorthand>
|
109
components/style/properties/shorthand/box.mako.rs
Normal file
109
components/style/properties/shorthand/box.mako.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
<%helpers:shorthand name="overflow" sub_properties="overflow-x overflow-y">
|
||||
use properties::longhands::{overflow_x, overflow_y};
|
||||
|
||||
let overflow = try!(overflow_x::parse(context, input));
|
||||
Ok(Longhands {
|
||||
overflow_x: Some(overflow),
|
||||
overflow_y: Some(overflow_y::SpecifiedValue(overflow)),
|
||||
})
|
||||
</%helpers:shorthand>
|
||||
|
||||
<%helpers:shorthand name="transition"
|
||||
sub_properties="transition-property transition-duration transition-timing-function
|
||||
transition-delay">
|
||||
use properties::longhands::{transition_delay, transition_duration, transition_property};
|
||||
use properties::longhands::{transition_timing_function};
|
||||
|
||||
struct SingleTransition {
|
||||
transition_property: transition_property::SingleSpecifiedValue,
|
||||
transition_duration: transition_duration::SingleSpecifiedValue,
|
||||
transition_timing_function: transition_timing_function::SingleSpecifiedValue,
|
||||
transition_delay: transition_delay::SingleSpecifiedValue,
|
||||
}
|
||||
|
||||
fn parse_one_transition(input: &mut Parser) -> Result<SingleTransition,()> {
|
||||
let (mut property, mut duration) = (None, None);
|
||||
let (mut timing_function, mut delay) = (None, None);
|
||||
loop {
|
||||
if property.is_none() {
|
||||
if let Ok(value) = input.try(|input| transition_property::parse_one(input)) {
|
||||
property = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if duration.is_none() {
|
||||
if let Ok(value) = input.try(|input| transition_duration::parse_one(input)) {
|
||||
duration = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if timing_function.is_none() {
|
||||
if let Ok(value) = input.try(|input| {
|
||||
transition_timing_function::parse_one(input)
|
||||
}) {
|
||||
timing_function = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if delay.is_none() {
|
||||
if let Ok(value) = input.try(|input| transition_delay::parse_one(input)) {
|
||||
delay = Some(value);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
if let Some(property) = property {
|
||||
Ok(SingleTransition {
|
||||
transition_property: property,
|
||||
transition_duration:
|
||||
duration.unwrap_or(transition_duration::get_initial_single_value()),
|
||||
transition_timing_function:
|
||||
timing_function.unwrap_or(
|
||||
transition_timing_function::get_initial_single_value()),
|
||||
transition_delay:
|
||||
delay.unwrap_or(transition_delay::get_initial_single_value()),
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(Longhands {
|
||||
transition_property: None,
|
||||
transition_duration: None,
|
||||
transition_timing_function: None,
|
||||
transition_delay: None,
|
||||
})
|
||||
}
|
||||
|
||||
let results = try!(input.parse_comma_separated(parse_one_transition));
|
||||
let (mut properties, mut durations) = (Vec::new(), Vec::new());
|
||||
let (mut timing_functions, mut delays) = (Vec::new(), Vec::new());
|
||||
for result in results {
|
||||
properties.push(result.transition_property);
|
||||
durations.push(result.transition_duration);
|
||||
timing_functions.push(result.transition_timing_function);
|
||||
delays.push(result.transition_delay);
|
||||
}
|
||||
|
||||
Ok(Longhands {
|
||||
transition_property: Some(transition_property::SpecifiedValue(properties)),
|
||||
transition_duration: Some(transition_duration::SpecifiedValue(durations)),
|
||||
transition_timing_function:
|
||||
Some(transition_timing_function::SpecifiedValue(timing_functions)),
|
||||
transition_delay: Some(transition_delay::SpecifiedValue(delays)),
|
||||
})
|
||||
</%helpers:shorthand>
|
46
components/style/properties/shorthand/column.mako.rs
Normal file
46
components/style/properties/shorthand/column.mako.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
<%helpers:shorthand name="columns" sub_properties="column-count column-width" experimental="True">
|
||||
use properties::longhands::{column_count, column_width};
|
||||
let mut column_count = None;
|
||||
let mut column_width = None;
|
||||
let mut autos = 0;
|
||||
|
||||
loop {
|
||||
if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
|
||||
// Leave the options to None, 'auto' is the initial value.
|
||||
autos += 1;
|
||||
continue
|
||||
}
|
||||
|
||||
if column_count.is_none() {
|
||||
if let Ok(value) = input.try(|input| column_count::parse(context, input)) {
|
||||
column_count = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if column_width.is_none() {
|
||||
if let Ok(value) = input.try(|input| column_width::parse(context, input)) {
|
||||
column_width = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
let values = autos + column_count.iter().len() + column_width.iter().len();
|
||||
if values == 0 || values > 2 {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(Longhands {
|
||||
column_count: column_count,
|
||||
column_width: column_width,
|
||||
})
|
||||
}
|
||||
</%helpers:shorthand>
|
66
components/style/properties/shorthand/font.mako.rs
Normal file
66
components/style/properties/shorthand/font.mako.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
<%helpers:shorthand name="font" sub_properties="font-style font-variant font-weight
|
||||
font-size line-height font-family">
|
||||
use properties::longhands::{font_style, font_variant, font_weight, font_size,
|
||||
line_height, font_family};
|
||||
let mut nb_normals = 0;
|
||||
let mut style = None;
|
||||
let mut variant = None;
|
||||
let mut weight = None;
|
||||
let size;
|
||||
loop {
|
||||
// Special-case 'normal' because it is valid in each of
|
||||
// font-style, font-weight and font-variant.
|
||||
// Leaves the values to None, 'normal' is the initial value for each of them.
|
||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||
nb_normals += 1;
|
||||
continue;
|
||||
}
|
||||
if style.is_none() {
|
||||
if let Ok(value) = input.try(|input| font_style::parse(context, input)) {
|
||||
style = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
if weight.is_none() {
|
||||
if let Ok(value) = input.try(|input| font_weight::parse(context, input)) {
|
||||
weight = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
if variant.is_none() {
|
||||
if let Ok(value) = input.try(|input| font_variant::parse(context, input)) {
|
||||
variant = Some(value);
|
||||
continue
|
||||
}
|
||||
}
|
||||
size = Some(try!(font_size::parse(context, input)));
|
||||
break
|
||||
}
|
||||
#[inline]
|
||||
fn count<T>(opt: &Option<T>) -> u8 {
|
||||
if opt.is_some() { 1 } else { 0 }
|
||||
}
|
||||
if size.is_none() || (count(&style) + count(&weight) + count(&variant) + nb_normals) > 3 {
|
||||
return Err(())
|
||||
}
|
||||
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||
Some(try!(line_height::parse(context, input)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let family = try!(input.parse_comma_separated(font_family::parse_one_family));
|
||||
Ok(Longhands {
|
||||
font_style: style,
|
||||
font_variant: variant,
|
||||
font_weight: weight,
|
||||
font_size: size,
|
||||
line_height: line_height,
|
||||
font_family: Some(font_family::SpecifiedValue(family))
|
||||
})
|
||||
</%helpers:shorthand>
|
14
components/style/properties/shorthand/inherited_text.mako.rs
Normal file
14
components/style/properties/shorthand/inherited_text.mako.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
// Per CSS-TEXT 6.2, "for legacy reasons, UAs must treat `word-wrap` as an alternate name for
|
||||
// the `overflow-wrap` property, as if it were a shorthand of `overflow-wrap`."
|
||||
<%helpers:shorthand name="word-wrap" sub_properties="overflow-wrap">
|
||||
use properties::longhands::overflow_wrap;
|
||||
Ok(Longhands {
|
||||
overflow_wrap: Some(try!(overflow_wrap::parse(context, input))),
|
||||
})
|
||||
</%helpers:shorthand>
|
92
components/style/properties/shorthand/list.mako.rs
Normal file
92
components/style/properties/shorthand/list.mako.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
<%helpers:shorthand name="list-style"
|
||||
sub_properties="list-style-image list-style-position list-style-type">
|
||||
use properties::longhands::{list_style_image, list_style_position, list_style_type};
|
||||
|
||||
// `none` is ambiguous until we've finished parsing the shorthands, so we count the number
|
||||
// of times we see it.
|
||||
let mut nones = 0u8;
|
||||
let (mut image, mut position, mut list_style_type, mut any) = (None, None, None, false);
|
||||
loop {
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
nones = nones + 1;
|
||||
if nones > 2 {
|
||||
return Err(())
|
||||
}
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
|
||||
if list_style_type.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_type::parse(context, input)) {
|
||||
list_style_type = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if image.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_image::parse(context, input)) {
|
||||
image = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if position.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_position::parse(context, input)) {
|
||||
position = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// If there are two `none`s, then we can't have a type or image; if there is one `none`,
|
||||
// then we can't have both a type *and* an image; if there is no `none` then we're fine as
|
||||
// long as we parsed something.
|
||||
match (any, nones, list_style_type, image) {
|
||||
(true, 2, None, None) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||
})
|
||||
}
|
||||
(true, 1, None, Some(image)) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(image),
|
||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||
})
|
||||
}
|
||||
(true, 1, Some(list_style_type), None) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||
list_style_type: Some(list_style_type),
|
||||
})
|
||||
}
|
||||
(true, 1, None, None) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||
})
|
||||
}
|
||||
(true, 0, list_style_type, image) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: image,
|
||||
list_style_type: list_style_type,
|
||||
})
|
||||
}
|
||||
_ => Err(()),
|
||||
}
|
||||
</%helpers:shorthand>
|
7
components/style/properties/shorthand/margin.mako.rs
Normal file
7
components/style/properties/shorthand/margin.mako.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
${helpers.four_sides_shorthand("margin", "margin-%s", "specified::LengthOrPercentageOrAuto::parse")}
|
49
components/style/properties/shorthand/outline.mako.rs
Normal file
49
components/style/properties/shorthand/outline.mako.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
<%helpers:shorthand name="outline" sub_properties="outline-color outline-style outline-width">
|
||||
use properties::longhands::outline_width;
|
||||
use values::specified;
|
||||
|
||||
let _unused = context;
|
||||
let mut color = None;
|
||||
let mut style = None;
|
||||
let mut width = None;
|
||||
let mut any = false;
|
||||
loop {
|
||||
if color.is_none() {
|
||||
if let Ok(value) = input.try(specified::CSSColor::parse) {
|
||||
color = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if style.is_none() {
|
||||
if let Ok(value) = input.try(specified::BorderStyle::parse) {
|
||||
style = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if width.is_none() {
|
||||
if let Ok(value) = input.try(|input| outline_width::parse(context, input)) {
|
||||
width = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if any {
|
||||
Ok(Longhands {
|
||||
outline_color: color,
|
||||
outline_style: style,
|
||||
outline_width: width,
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
</%helpers:shorthand>
|
7
components/style/properties/shorthand/padding.mako.rs
Normal file
7
components/style/properties/shorthand/padding.mako.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
|
||||
${helpers.four_sides_shorthand("padding", "padding-%s", "specified::LengthOrPercentage::parse")}
|
Loading…
Add table
Add a link
Reference in a new issue