mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
auto merge of #4856 : servo/servo/tocss, r=jdm
r? @jdm The in-progress Rust upgrade will go on top of this.
This commit is contained in:
commit
f5cb1690bf
4 changed files with 324 additions and 98 deletions
2
components/servo/Cargo.lock
generated
2
components/servo/Cargo.lock
generated
|
@ -133,7 +133,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/servo/rust-cssparser#42714934cbe83dab349190695503a09ae23f9528"
|
source = "git+https://github.com/servo/rust-cssparser#d7d50ae2a7da4aca1b2c4d248139510c8e9a25c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -16,7 +16,7 @@ use util::logical_geometry::{WritingMode, LogicalMargin};
|
||||||
use util::geometry::Au;
|
use util::geometry::Au;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser,
|
use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser,
|
||||||
DeclarationListParser, parse_important};
|
DeclarationListParser, parse_important, ToCss};
|
||||||
use geom::SideOffsets2D;
|
use geom::SideOffsets2D;
|
||||||
|
|
||||||
use values::specified::BorderStyle;
|
use values::specified::BorderStyle;
|
||||||
|
@ -361,18 +361,20 @@ pub mod longhands {
|
||||||
pub use super::computed_as_specified as to_computed_value;
|
pub use super::computed_as_specified as to_computed_value;
|
||||||
pub type SpecifiedValue = computed_value::T;
|
pub type SpecifiedValue = computed_value::T;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use std::fmt;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Eq, Copy)]
|
#[derive(PartialEq, Clone, Eq, Copy)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
Auto,
|
Auto,
|
||||||
Number(i32),
|
Number(i32),
|
||||||
}
|
}
|
||||||
impl fmt::Show for T {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for T {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&T::Auto => write!(f, "auto"),
|
&T::Auto => dest.write_str("auto"),
|
||||||
&T::Number(number) => write!(f, "{}", number),
|
&T::Number(number) => write!(dest, "{}", number),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,8 +453,10 @@ pub mod longhands {
|
||||||
${switch_to_style_struct("InheritedBox")}
|
${switch_to_style_struct("InheritedBox")}
|
||||||
|
|
||||||
<%self:longhand name="line-height">
|
<%self:longhand name="line-height">
|
||||||
use std::fmt;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Copy)]
|
#[derive(Clone, PartialEq, Copy)]
|
||||||
pub enum SpecifiedValue {
|
pub enum SpecifiedValue {
|
||||||
Normal,
|
Normal,
|
||||||
|
@ -460,13 +464,14 @@ pub mod longhands {
|
||||||
Number(CSSFloat),
|
Number(CSSFloat),
|
||||||
Percentage(CSSFloat),
|
Percentage(CSSFloat),
|
||||||
}
|
}
|
||||||
impl fmt::Show for SpecifiedValue {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&SpecifiedValue::Normal => write!(f, "normal"),
|
&SpecifiedValue::Normal => dest.write_str("normal"),
|
||||||
&SpecifiedValue::Length(length) => write!(f, "{:?}", length),
|
&SpecifiedValue::Length(length) => length.to_css(dest),
|
||||||
&SpecifiedValue::Number(number) => write!(f, "{}", number),
|
&SpecifiedValue::Number(number) => write!(dest, "{}", number),
|
||||||
&SpecifiedValue::Percentage(number) => write!(f, "{}%", number * 100.),
|
&SpecifiedValue::Percentage(number) => write!(dest, "{}%", number * 100.),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,7 +538,9 @@ pub mod longhands {
|
||||||
${switch_to_style_struct("Box")}
|
${switch_to_style_struct("Box")}
|
||||||
|
|
||||||
<%self:longhand name="vertical-align">
|
<%self:longhand name="vertical-align">
|
||||||
use std::fmt;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
<% vertical_align_keywords = (
|
<% vertical_align_keywords = (
|
||||||
"baseline sub super top text-top middle bottom text-bottom".split()) %>
|
"baseline sub super top text-top middle bottom text-bottom".split()) %>
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -544,13 +551,14 @@ pub mod longhands {
|
||||||
% endfor
|
% endfor
|
||||||
LengthOrPercentage(specified::LengthOrPercentage),
|
LengthOrPercentage(specified::LengthOrPercentage),
|
||||||
}
|
}
|
||||||
impl fmt::Show for SpecifiedValue {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
% for keyword in vertical_align_keywords:
|
% for keyword in vertical_align_keywords:
|
||||||
&SpecifiedValue::${to_rust_ident(keyword)} => write!(f, "${keyword}"),
|
&SpecifiedValue::${to_rust_ident(keyword)} => dest.write_str("${keyword}"),
|
||||||
% endfor
|
% endfor
|
||||||
&SpecifiedValue::LengthOrPercentage(lop) => write!(f, "{:?}", lop),
|
&SpecifiedValue::LengthOrPercentage(value) => value.to_css(dest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,19 +650,27 @@ pub mod longhands {
|
||||||
pub use self::computed_value::T as SpecifiedValue;
|
pub use self::computed_value::T as SpecifiedValue;
|
||||||
pub use self::computed_value::ContentItem;
|
pub use self::computed_value::ContentItem;
|
||||||
use cssparser::Token;
|
use cssparser::Token;
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use std::fmt;
|
use std::borrow::IntoCow;
|
||||||
|
use cssparser::{ToCss, Token};
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub enum ContentItem {
|
pub enum ContentItem {
|
||||||
StringContent(String),
|
StringContent(String),
|
||||||
}
|
}
|
||||||
impl fmt::Show for ContentItem {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for ContentItem {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&ContentItem::StringContent(ref s) => write!(f, "\"{}\"", s),
|
&ContentItem::StringContent(ref s) => {
|
||||||
|
Token::QuotedString((&**s).into_cow()).to_css(dest)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
|
@ -662,14 +678,17 @@ pub mod longhands {
|
||||||
none,
|
none,
|
||||||
Content(Vec<ContentItem>),
|
Content(Vec<ContentItem>),
|
||||||
}
|
}
|
||||||
impl fmt::Show for T {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for T {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&T::normal => write!(f, "normal"),
|
&T::normal => dest.write_str("normal"),
|
||||||
&T::none => write!(f, "none"),
|
&T::none => dest.write_str("none"),
|
||||||
&T::Content(ref content) => {
|
&T::Content(ref content) => {
|
||||||
for c in content.iter() {
|
let mut iter = content.iter();
|
||||||
let _ = write!(f, "{:?}", c);
|
try!(iter.next().unwrap().to_css(dest));
|
||||||
|
for c in iter {
|
||||||
|
try!(c.to_css(dest));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -698,8 +717,10 @@ pub mod longhands {
|
||||||
Ok(Token::QuotedString(value)) => {
|
Ok(Token::QuotedString(value)) => {
|
||||||
content.push(ContentItem::StringContent(value.into_owned()))
|
content.push(ContentItem::StringContent(value.into_owned()))
|
||||||
}
|
}
|
||||||
Ok(_) => return Err(()),
|
Err(()) if !content.is_empty() => {
|
||||||
Err(()) => return Ok(SpecifiedValue::Content(content))
|
return Ok(SpecifiedValue::Content(content))
|
||||||
|
}
|
||||||
|
_ => return Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,18 +742,46 @@ pub mod longhands {
|
||||||
"disc none circle square disclosure-open disclosure-closed")}
|
"disc none circle square disclosure-open disclosure-closed")}
|
||||||
|
|
||||||
<%self:longhand name="list-style-image">
|
<%self:longhand name="list-style-image">
|
||||||
|
use std::borrow::IntoCow;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
pub use super::computed_as_specified as to_computed_value;
|
use cssparser::{ToCss, Token};
|
||||||
pub type SpecifiedValue = Option<Url>;
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
|
pub enum SpecifiedValue {
|
||||||
|
None,
|
||||||
|
Url(Url),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
match *self {
|
||||||
|
SpecifiedValue::None => dest.write_str("none"),
|
||||||
|
SpecifiedValue::Url(ref url) => {
|
||||||
|
Token::Url(url.to_string().into_cow()).to_css(dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use url::Url;
|
use url::Url;
|
||||||
pub type T = Option<Url>;
|
pub type T = Option<Url>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_computed_value(value: SpecifiedValue, _context: &computed::Context)
|
||||||
|
-> computed_value::T {
|
||||||
|
match value {
|
||||||
|
SpecifiedValue::None => None,
|
||||||
|
SpecifiedValue::Url(url) => Some(url),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
Ok(None)
|
Ok(SpecifiedValue::None)
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(context.parse_url(try!(input.expect_url()).as_slice())))
|
Ok(SpecifiedValue::Url(context.parse_url(try!(input.expect_url()).as_slice())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -777,22 +826,17 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
|
||||||
<%self:longhand name="background-position">
|
<%self:longhand name="background-position">
|
||||||
use std::fmt;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use values::computed::LengthOrPercentage;
|
use values::computed::LengthOrPercentage;
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
pub struct T {
|
pub struct T {
|
||||||
pub horizontal: LengthOrPercentage,
|
pub horizontal: LengthOrPercentage,
|
||||||
pub vertical: LengthOrPercentage,
|
pub vertical: LengthOrPercentage,
|
||||||
}
|
}
|
||||||
impl fmt::Show for T {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{:?} {:?}", self.horizontal, self.vertical)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Copy)]
|
#[derive(Clone, PartialEq, Copy)]
|
||||||
|
@ -800,9 +844,13 @@ pub mod longhands {
|
||||||
pub horizontal: specified::LengthOrPercentage,
|
pub horizontal: specified::LengthOrPercentage,
|
||||||
pub vertical: specified::LengthOrPercentage,
|
pub vertical: specified::LengthOrPercentage,
|
||||||
}
|
}
|
||||||
impl fmt::Show for SpecifiedValue {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for SpecifiedValue {
|
||||||
write!(f, "{:?} {:?}", self.horizontal, self.vertical)
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
try!(self.horizontal.to_css(dest));
|
||||||
|
try!(dest.write_str(" "));
|
||||||
|
try!(self.vertical.to_css(dest));
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,7 +972,9 @@ pub mod longhands {
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use self::computed_value::FontFamily;
|
use self::computed_value::FontFamily;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use std::fmt;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub enum FontFamily {
|
pub enum FontFamily {
|
||||||
FamilyName(String),
|
FamilyName(String),
|
||||||
|
@ -942,22 +992,25 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl fmt::Show for FontFamily {
|
impl ToCss for FontFamily {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&FontFamily::FamilyName(ref name) => write!(f, "{}", name),
|
&FontFamily::FamilyName(ref name) => dest.write_str(&**name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub type T = Vec<FontFamily>;
|
impl ToCss for Vec<FontFamily> {
|
||||||
/*impl fmt::Show for T {
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
let mut iter = self.iter();
|
||||||
for font in self.iter() {
|
try!(iter.next().unwrap().to_css(dest));
|
||||||
write!(f, "{}", font);
|
for family in iter {
|
||||||
|
try!(dest.write_str(", "));
|
||||||
|
try!(family.to_css(dest));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
pub type T = Vec<FontFamily>;
|
||||||
}
|
}
|
||||||
pub type SpecifiedValue = computed_value::T;
|
pub type SpecifiedValue = computed_value::T;
|
||||||
|
|
||||||
|
@ -998,7 +1051,9 @@ pub mod longhands {
|
||||||
${single_keyword("font-variant", "normal small-caps")}
|
${single_keyword("font-variant", "normal small-caps")}
|
||||||
|
|
||||||
<%self:longhand name="font-weight">
|
<%self:longhand name="font-weight">
|
||||||
use std::fmt;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Copy)]
|
#[derive(Clone, PartialEq, Eq, Copy)]
|
||||||
pub enum SpecifiedValue {
|
pub enum SpecifiedValue {
|
||||||
Bolder,
|
Bolder,
|
||||||
|
@ -1007,13 +1062,14 @@ pub mod longhands {
|
||||||
Weight${weight},
|
Weight${weight},
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
impl fmt::Show for SpecifiedValue {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
match self {
|
match self {
|
||||||
&SpecifiedValue::Bolder => write!(f, "bolder"),
|
&SpecifiedValue::Bolder => dest.write_str("bolder"),
|
||||||
&SpecifiedValue::Lighter => write!(f, "lighter"),
|
&SpecifiedValue::Lighter => dest.write_str("lighter"),
|
||||||
% for weight in range(100, 901, 100):
|
% for weight in range(100, 901, 100):
|
||||||
&SpecifiedValue::Weight${weight} => write!(f, "{}", ${weight}i),
|
&SpecifiedValue::Weight${weight} => dest.write_str("${weight}"),
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,49 +1218,95 @@ pub mod longhands {
|
||||||
${single_keyword("text-align", "left right center justify")}
|
${single_keyword("text-align", "left right center justify")}
|
||||||
|
|
||||||
<%self:longhand name="letter-spacing">
|
<%self:longhand name="letter-spacing">
|
||||||
pub type SpecifiedValue = Option<specified::Length>;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub enum SpecifiedValue {
|
||||||
|
Normal,
|
||||||
|
Specified(specified::Length),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
match *self {
|
||||||
|
SpecifiedValue::Normal => dest.write_str("normal"),
|
||||||
|
SpecifiedValue::Specified(l) => l.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use util::geometry::Au;
|
use util::geometry::Au;
|
||||||
pub type T = Option<Au>;
|
pub type T = Option<Au>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
pub fn get_initial_value() -> computed_value::T {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
|
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
|
||||||
-> computed_value::T {
|
-> computed_value::T {
|
||||||
value.map(|length| computed::compute_Au(length, context))
|
match value {
|
||||||
|
SpecifiedValue::Normal => None,
|
||||||
|
SpecifiedValue::Specified(l) => Some(computed::compute_Au(l, context))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||||
Ok(None)
|
Ok(SpecifiedValue::Normal)
|
||||||
} else {
|
} else {
|
||||||
specified::Length::parse_non_negative(input).map(Some)
|
specified::Length::parse_non_negative(input).map(SpecifiedValue::Specified)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
|
||||||
<%self:longhand name="word-spacing">
|
<%self:longhand name="word-spacing">
|
||||||
pub type SpecifiedValue = Option<specified::Length>;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub enum SpecifiedValue {
|
||||||
|
Normal,
|
||||||
|
Specified(specified::Length), // FIXME(SimonSapin) support percentages
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
match *self {
|
||||||
|
SpecifiedValue::Normal => dest.write_str("normal"),
|
||||||
|
SpecifiedValue::Specified(l) => l.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use util::geometry::Au;
|
use util::geometry::Au;
|
||||||
pub type T = Option<Au>;
|
pub type T = Option<Au>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
pub fn get_initial_value() -> computed_value::T {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
|
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
|
||||||
-> computed_value::T {
|
-> computed_value::T {
|
||||||
value.map(|length| computed::compute_Au(length, context))
|
match value {
|
||||||
|
SpecifiedValue::Normal => None,
|
||||||
|
SpecifiedValue::Specified(l) => Some(computed::compute_Au(l, context))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||||
Ok(None)
|
Ok(SpecifiedValue::Normal)
|
||||||
} else {
|
} else {
|
||||||
specified::Length::parse_non_negative(input).map(Some)
|
specified::Length::parse_non_negative(input).map(SpecifiedValue::Specified)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
@ -1227,7 +1329,9 @@ pub mod longhands {
|
||||||
|
|
||||||
<%self:longhand name="text-decoration">
|
<%self:longhand name="text-decoration">
|
||||||
pub use super::computed_as_specified as to_computed_value;
|
pub use super::computed_as_specified as to_computed_value;
|
||||||
use std::fmt;
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||||
pub struct SpecifiedValue {
|
pub struct SpecifiedValue {
|
||||||
pub underline: bool,
|
pub underline: bool,
|
||||||
|
@ -1236,25 +1340,26 @@ pub mod longhands {
|
||||||
// 'blink' is accepted in the parser but ignored.
|
// 'blink' is accepted in the parser but ignored.
|
||||||
// Just not blinking the text is a conforming implementation per CSS 2.1.
|
// Just not blinking the text is a conforming implementation per CSS 2.1.
|
||||||
}
|
}
|
||||||
impl fmt::Show for SpecifiedValue {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
let mut space = false;
|
let mut space = false;
|
||||||
if self.underline {
|
if self.underline {
|
||||||
let _ = write!(f, "underline");
|
try!(dest.write_str("underline"));
|
||||||
space = true;
|
space = true;
|
||||||
}
|
}
|
||||||
if self.overline {
|
if self.overline {
|
||||||
if space {
|
if space {
|
||||||
let _ = write!(f, " ");
|
try!(dest.write_str(" "));
|
||||||
}
|
}
|
||||||
let _ = write!(f, "overline");
|
try!(dest.write_str("overline"));
|
||||||
space = true;
|
space = true;
|
||||||
}
|
}
|
||||||
if self.line_through {
|
if self.line_through {
|
||||||
if space {
|
if space {
|
||||||
let _ = write!(f, " ");
|
try!(dest.write_str(" "));
|
||||||
}
|
}
|
||||||
let _ = write!(f, "line-through");
|
try!(dest.write_str("line-through"));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1420,13 +1525,26 @@ pub mod longhands {
|
||||||
pub use self::computed_value::T as SpecifiedValue;
|
pub use self::computed_value::T as SpecifiedValue;
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
use util::cursor::Cursor;
|
use util::cursor::Cursor;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Copy, Show)]
|
#[derive(Clone, PartialEq, Eq, Copy, Show)]
|
||||||
pub enum T {
|
pub enum T {
|
||||||
AutoCursor,
|
AutoCursor,
|
||||||
SpecifiedCursor(Cursor),
|
SpecifiedCursor(Cursor),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToCss for T {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
match *self {
|
||||||
|
T::AutoCursor => dest.write_str("auto"),
|
||||||
|
T::SpecifiedCursor(c) => c.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
pub fn get_initial_value() -> computed_value::T {
|
||||||
computed_value::T::AutoCursor
|
computed_value::T::AutoCursor
|
||||||
|
@ -1479,8 +1597,8 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
|
||||||
<%self:longhand name="box-shadow">
|
<%self:longhand name="box-shadow">
|
||||||
use cssparser;
|
use cssparser::{self, ToCss};
|
||||||
use std::fmt;
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
pub type SpecifiedValue = Vec<SpecifiedBoxShadow>;
|
pub type SpecifiedValue = Vec<SpecifiedBoxShadow>;
|
||||||
|
|
||||||
|
@ -1494,15 +1612,39 @@ pub mod longhands {
|
||||||
pub inset: bool,
|
pub inset: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for SpecifiedBoxShadow {
|
impl ToCss for Vec<SpecifiedBoxShadow> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
if self.inset {
|
let mut iter = self.iter();
|
||||||
let _ = write!(f, "inset ");
|
if let Some(shadow) = iter.next() {
|
||||||
|
try!(shadow.to_css(dest));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("none"));
|
||||||
|
return Ok(())
|
||||||
}
|
}
|
||||||
let _ = write!(f, "{:?} {:?} {:?} {:?}", self.offset_x, self.offset_y,
|
for shadow in iter {
|
||||||
self.blur_radius, self.spread_radius);
|
try!(dest.write_str(", "));
|
||||||
|
try!(shadow.to_css(dest));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedBoxShadow {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
if self.inset {
|
||||||
|
try!(dest.write_str("inset "));
|
||||||
|
}
|
||||||
|
try!(self.blur_radius.to_css(dest));
|
||||||
|
try!(dest.write_str(" "));
|
||||||
|
try!(self.spread_radius.to_css(dest));
|
||||||
|
try!(dest.write_str(" "));
|
||||||
|
try!(self.offset_x.to_css(dest));
|
||||||
|
try!(dest.write_str(" "));
|
||||||
|
try!(self.offset_y.to_css(dest));
|
||||||
|
|
||||||
if let Some(ref color) = self.color {
|
if let Some(ref color) = self.color {
|
||||||
let _ = write!(f, "{:?}", color);
|
try!(dest.write_str(" "));
|
||||||
|
try!(color.to_css(dest));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1631,6 +1773,9 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
|
||||||
<%self:longhand name="clip">
|
<%self:longhand name="clip">
|
||||||
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
// NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
|
// NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
|
||||||
|
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
@ -1657,6 +1802,44 @@ pub mod longhands {
|
||||||
|
|
||||||
pub type SpecifiedValue = Option<SpecifiedClipRect>;
|
pub type SpecifiedValue = Option<SpecifiedClipRect>;
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedClipRect {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
try!(dest.write_str("rect("));
|
||||||
|
|
||||||
|
try!(self.top.to_css(dest));
|
||||||
|
try!(dest.write_str(", "));
|
||||||
|
|
||||||
|
if let Some(right) = self.right {
|
||||||
|
try!(right.to_css(dest));
|
||||||
|
try!(dest.write_str(", "));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("auto, "));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(bottom) = self.right {
|
||||||
|
try!(bottom.to_css(dest));
|
||||||
|
try!(dest.write_str(", "));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("auto, "));
|
||||||
|
}
|
||||||
|
|
||||||
|
try!(self.left.to_css(dest));
|
||||||
|
|
||||||
|
try!(dest.write_str(")"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for Option<SpecifiedClipRect> {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
if let Some(ref rect) = *self {
|
||||||
|
rect.to_css(dest)
|
||||||
|
} else {
|
||||||
|
dest.write_str("auto")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
pub fn get_initial_value() -> computed_value::T {
|
||||||
None
|
None
|
||||||
|
@ -1714,6 +1897,8 @@ pub mod longhands {
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use values::specified::Angle;
|
use values::specified::Angle;
|
||||||
use values::CSSFloat;
|
use values::CSSFloat;
|
||||||
|
use cssparser::ToCss;
|
||||||
|
use text_writer::{self, TextWriter};
|
||||||
|
|
||||||
// TODO(pcwalton): `blur`, `drop-shadow`
|
// TODO(pcwalton): `blur`, `drop-shadow`
|
||||||
#[derive(Clone, PartialEq, Show)]
|
#[derive(Clone, PartialEq, Show)]
|
||||||
|
@ -1728,11 +1913,48 @@ pub mod longhands {
|
||||||
Sepia(CSSFloat),
|
Sepia(CSSFloat),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToCss for Filter {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
match *self {
|
||||||
|
Filter::Brightness(value) => try!(write!(dest, "brightness({})", value)),
|
||||||
|
Filter::Contrast(value) => try!(write!(dest, "contrast({})", value)),
|
||||||
|
Filter::Grayscale(value) => try!(write!(dest, "grayscale({})", value)),
|
||||||
|
Filter::HueRotate(value) => {
|
||||||
|
try!(dest.write_str("hue-rotate("));
|
||||||
|
try!(value.to_css(dest));
|
||||||
|
try!(dest.write_str(")"));
|
||||||
|
}
|
||||||
|
Filter::Invert(value) => try!(write!(dest, "invert({})", value)),
|
||||||
|
Filter::Opacity(value) => try!(write!(dest, "opacity({})", value)),
|
||||||
|
Filter::Saturate(value) => try!(write!(dest, "saturate({})", value)),
|
||||||
|
Filter::Sepia(value) => try!(write!(dest, "sepia({})", value)),
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Show)]
|
#[derive(Clone, PartialEq, Show)]
|
||||||
pub struct T {
|
pub struct T {
|
||||||
pub filters: Vec<Filter>,
|
pub filters: Vec<Filter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToCss for T {
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
|
||||||
|
let mut iter = self.filters.iter();
|
||||||
|
if let Some(filter) = iter.next() {
|
||||||
|
try!(filter.to_css(dest));
|
||||||
|
} else {
|
||||||
|
try!(dest.write_str("none"));
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
for filter in iter {
|
||||||
|
try!(dest.write_str(" "));
|
||||||
|
try!(filter.to_css(dest));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl T {
|
impl T {
|
||||||
/// Creates a new filter pipeline.
|
/// Creates a new filter pipeline.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1775,6 +1997,9 @@ pub mod longhands {
|
||||||
|
|
||||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||||
let mut filters = Vec::new();
|
let mut filters = Vec::new();
|
||||||
|
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
|
return Ok(SpecifiedValue::new(filters))
|
||||||
|
}
|
||||||
loop {
|
loop {
|
||||||
if let Ok(function_name) = input.try(|input| input.expect_function()) {
|
if let Ok(function_name) = input.try(|input| input.expect_function()) {
|
||||||
filters.push(try!(input.parse_nested_block(|input| {
|
filters.push(try!(input.parse_nested_block(|input| {
|
||||||
|
@ -1790,6 +2015,8 @@ pub mod longhands {
|
||||||
_ => Err(())
|
_ => Err(())
|
||||||
}
|
}
|
||||||
})));
|
})));
|
||||||
|
} else if filters.is_empty() {
|
||||||
|
return Err(())
|
||||||
} else {
|
} else {
|
||||||
return Ok(SpecifiedValue::new(filters))
|
return Ok(SpecifiedValue::new(filters))
|
||||||
}
|
}
|
||||||
|
@ -2239,7 +2466,7 @@ pub mod shorthands {
|
||||||
(true, 2, None, None) => {
|
(true, 2, None, None) => {
|
||||||
Ok(Longhands {
|
Ok(Longhands {
|
||||||
list_style_position: position,
|
list_style_position: position,
|
||||||
list_style_image: Some(None),
|
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2253,14 +2480,14 @@ pub mod shorthands {
|
||||||
(true, 1, Some(list_style_type), None) => {
|
(true, 1, Some(list_style_type), None) => {
|
||||||
Ok(Longhands {
|
Ok(Longhands {
|
||||||
list_style_position: position,
|
list_style_position: position,
|
||||||
list_style_image: Some(None),
|
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||||
list_style_type: Some(list_style_type),
|
list_style_type: Some(list_style_type),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(true, 1, None, None) => {
|
(true, 1, None, None) => {
|
||||||
Ok(Longhands {
|
Ok(Longhands {
|
||||||
list_style_position: position,
|
list_style_position: position,
|
||||||
list_style_image: Some(None),
|
list_style_image: Some(list_style_image::SpecifiedValue::None),
|
||||||
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
list_style_type: Some(list_style_type::SpecifiedValue::none),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2448,12 +2675,12 @@ pub enum DeclaredValue<T> {
|
||||||
// depending on whether the property is inherited.
|
// depending on whether the property is inherited.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Show> DeclaredValue<T> {
|
impl<T: ToCss> DeclaredValue<T> {
|
||||||
pub fn specified_value(&self) -> Option<String> {
|
pub fn specified_value(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
&DeclaredValue::SpecifiedValue(ref inner) => Some(format!("{:?}", inner)),
|
&DeclaredValue::SpecifiedValue(ref inner) => inner.to_css_string(),
|
||||||
&DeclaredValue::Initial => None,
|
&DeclaredValue::Initial => "initial".to_owned(),
|
||||||
&DeclaredValue::Inherit => Some("inherit".to_owned()),
|
&DeclaredValue::Inherit => "inherit".to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2491,8 +2718,7 @@ impl PropertyDeclaration {
|
||||||
% for property in LONGHANDS:
|
% for property in LONGHANDS:
|
||||||
% if property.derived_from is None:
|
% if property.derived_from is None:
|
||||||
&PropertyDeclaration::${property.camel_case}(ref value) =>
|
&PropertyDeclaration::${property.camel_case}(ref value) =>
|
||||||
value.specified_value()
|
value.specified_value(),
|
||||||
.unwrap_or_else(|| format!("{:?}", longhands::${property.ident}::get_initial_value())),
|
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
decl => panic!("unsupported property declaration: {:?}", decl.name()),
|
decl => panic!("unsupported property declaration: {:?}", decl.name()),
|
||||||
|
|
2
ports/cef/Cargo.lock
generated
2
ports/cef/Cargo.lock
generated
|
@ -132,7 +132,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/servo/rust-cssparser#42714934cbe83dab349190695503a09ae23f9528"
|
source = "git+https://github.com/servo/rust-cssparser#d7d50ae2a7da4aca1b2c4d248139510c8e9a25c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
2
ports/gonk/Cargo.lock
generated
2
ports/gonk/Cargo.lock
generated
|
@ -103,7 +103,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/servo/rust-cssparser#42714934cbe83dab349190695503a09ae23f9528"
|
source = "git+https://github.com/servo/rust-cssparser#d7d50ae2a7da4aca1b2c4d248139510c8e9a25c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue