diff --git a/components/script/dom/css2properties.rs b/components/script/dom/css2properties.rs index a2b5c818885..cb2a8f61a5e 100644 --- a/components/script/dom/css2properties.rs +++ b/components/script/dom/css2properties.rs @@ -73,15 +73,189 @@ impl<'a> CSS2PropertiesMethods for JSRef<'a, CSS2Properties> { css_getter!(BackgroundAttachment, "background-attachment") css_setter!(SetBackgroundAttachment, "background-attachment") + css_getter!(Border, "border") + css_setter!(SetBorder, "border") + + css_getter!(BorderColor, "border-color") + css_setter!(SetBorderColor, "border-color") + + css_getter!(BorderStyle, "border-style") + css_setter!(SetBorderStyle, "border-style") + + css_getter!(BorderWidth, "border-width") + css_setter!(SetBorderWidth, "border-width") + + css_getter!(BorderBottom, "border-bottom") + css_setter!(SetBorderBottom, "border-bottom") + + css_getter!(BorderBottomColor, "border-bottom-color") + css_setter!(SetBorderBottomColor, "border-bottom-color") + + css_getter!(BorderBottomStyle, "border-bottom-style") + css_setter!(SetBorderBottomStyle, "border-bottom-style") + + css_getter!(BorderBottomWidth, "border-bottom-width") + css_setter!(SetBorderBottomWidth, "border-bottom-width") + + css_getter!(BorderLeft, "border-left") + css_setter!(SetBorderLeft, "border-left") + + css_getter!(BorderLeftColor, "border-left-color") + css_setter!(SetBorderLeftColor, "border-left-color") + + css_getter!(BorderLeftStyle, "border-left-style") + css_setter!(SetBorderLeftStyle, "border-left-style") + + css_getter!(BorderLeftWidth, "border-left-width") + css_setter!(SetBorderLeftWidth, "border-left-width") + + css_getter!(BorderRight, "border-right") + css_setter!(SetBorderRight, "border-right") + + css_getter!(BorderRightColor, "border-right-color") + css_setter!(SetBorderRightColor, "border-right-color") + + css_getter!(BorderRightStyle, "border-right-style") + css_setter!(SetBorderRightStyle, "border-right-style") + + css_getter!(BorderRightWidth, "border-right-width") + css_setter!(SetBorderRightWidth, "border-right-width") + + css_getter!(BorderTop, "border-top") + css_setter!(SetBorderTop, "border-top") + + css_getter!(BorderTopColor, "border-top-color") + css_setter!(SetBorderTopColor, "border-top-color") + + css_getter!(BorderTopStyle, "border-top-style") + css_setter!(SetBorderTopStyle, "border-top-style") + + css_getter!(BorderTopWidth, "border-top-width") + css_setter!(SetBorderTopWidth, "border-top-width") + + css_getter!(Content, "content") + css_setter!(SetContent, "content") + css_getter!(Display, "display") css_setter!(SetDisplay, "display") css_getter!(Width, "width") css_setter!(SetWidth, "width") + css_getter!(MinWidth, "min-width") + css_setter!(SetMinWidth, "min-width") + + css_getter!(MaxWidth, "max-width") + css_setter!(SetMaxWidth, "max-width") + css_getter!(Height, "height") css_setter!(SetHeight, "height") + css_getter!(MinHeight, "min-height") + css_setter!(SetMinHeight, "min-height") + + css_getter!(MaxHeight, "max-height") + css_setter!(SetMaxHeight, "max-height") + + css_getter!(Clear, "clear") + css_setter!(SetClear, "clear") + + css_getter!(Direction, "direction") + css_setter!(SetDirection, "direction") + + css_getter!(LineHeight, "line-height") + css_setter!(SetLineHeight, "line-height") + + css_getter!(VerticalAlign, "vertical-align") + css_setter!(SetVerticalAlign, "vertical-align") + + css_getter!(Visibility, "visibility") + css_setter!(SetVisibility, "visibility") + + css_getter!(Overflow, "overflow") + css_setter!(SetOverflow, "overflow") + + css_getter!(TableLayout, "table-layout") + css_setter!(SetTableLayout, "table-layout") + + css_getter!(WhiteSpace, "white-space") + css_setter!(SetWhiteSpace, "white-space") + + css_getter!(WritingMode, "writing-mode") + css_setter!(SetWritingMode, "writing-mode") + + css_getter!(TextAlign, "text-align") + css_setter!(SetTextAlign, "text-align") + + css_getter!(TextDecoration, "text-decoration") + css_setter!(SetTextDecoration, "text-decoration") + + css_getter!(TextOrientation, "text-orientation") + css_setter!(SetTextOrientation, "text-orientation") + + css_getter!(Font, "font") + css_setter!(SetFont, "font") + + css_getter!(FontFamily, "font-family") + css_setter!(SetFontFamily, "font-family") + + css_getter!(FontSize, "font-size") + css_setter!(SetFontSize, "font-size") + + css_getter!(FontStyle, "font-style") + css_setter!(SetFontStyle, "font-style") + + css_getter!(FontVariant, "font-variant") + css_setter!(SetFontVariant, "font-variant") + + css_getter!(FontWeight, "font-weight") + css_setter!(SetFontWeight, "font-weight") + + css_getter!(Margin, "margin") + css_setter!(SetMargin, "margin") + + css_getter!(MarginBottom, "margin-bottom") + css_setter!(SetMarginBottom, "margin-bottom") + + css_getter!(MarginLeft, "margin-left") + css_setter!(SetMarginLeft, "margin-left") + + css_getter!(MarginRight, "margin-right") + css_setter!(SetMarginRight, "margin-right") + + css_getter!(MarginTop, "margin-top") + css_setter!(SetMarginTop, "margin-top") + + css_getter!(Padding, "padding") + css_setter!(SetPadding, "padding") + + css_getter!(PaddingBottom, "padding-bottom") + css_setter!(SetPaddingBottom, "padding-bottom") + + css_getter!(PaddingLeft, "padding-left") + css_setter!(SetPaddingLeft, "padding-left") + + css_getter!(PaddingRight, "padding-right") + css_setter!(SetPaddingRight, "padding-right") + + css_getter!(PaddingTop, "padding-top") + css_setter!(SetPaddingTop, "padding-top") + + css_getter!(Position, "position") + css_setter!(SetPosition, "position") + + css_getter!(Top, "top") + css_setter!(SetTop, "top") + + css_getter!(Bottom, "bottom") + css_setter!(SetBottom, "bottom") + + css_getter!(Left, "left") + css_setter!(SetLeft, "left") + + css_getter!(Right, "right") + css_setter!(SetRight, "right") + fn IndexedGetter(self, index: u32, found: &mut bool) -> DOMString { let decl: JSRef = CSSStyleDeclarationCast::from_ref(self); decl.IndexedGetter(index, found) diff --git a/components/script/dom/webidls/CSS2Properties.webidl b/components/script/dom/webidls/CSS2Properties.webidl index 69efb8a066d..603cc18dfd2 100644 --- a/components/script/dom/webidls/CSS2Properties.webidl +++ b/components/script/dom/webidls/CSS2Properties.webidl @@ -9,14 +9,95 @@ */ interface CSS2Properties : CSSStyleDeclaration { - [TreatNullAs=EmptyString] attribute DOMString color; - [TreatNullAs=EmptyString] attribute DOMString display; [TreatNullAs=EmptyString] attribute DOMString background; [TreatNullAs=EmptyString] attribute DOMString backgroundColor; [TreatNullAs=EmptyString] attribute DOMString backgroundPosition; [TreatNullAs=EmptyString] attribute DOMString backgroundRepeat; [TreatNullAs=EmptyString] attribute DOMString backgroundImage; [TreatNullAs=EmptyString] attribute DOMString backgroundAttachment; - [TreatNullAs=EmptyString] attribute DOMString width; + + [TreatNullAs=EmptyString] attribute DOMString border; + [TreatNullAs=EmptyString] attribute DOMString borderColor; + [TreatNullAs=EmptyString] attribute DOMString borderStyle; + [TreatNullAs=EmptyString] attribute DOMString borderWidth; + [TreatNullAs=EmptyString] attribute DOMString borderBottom; + [TreatNullAs=EmptyString] attribute DOMString borderBottomColor; + [TreatNullAs=EmptyString] attribute DOMString borderBottomStyle; + [TreatNullAs=EmptyString] attribute DOMString borderBottomWidth; + [TreatNullAs=EmptyString] attribute DOMString borderLeft; + [TreatNullAs=EmptyString] attribute DOMString borderLeftColor; + [TreatNullAs=EmptyString] attribute DOMString borderLeftStyle; + [TreatNullAs=EmptyString] attribute DOMString borderLeftWidth; + [TreatNullAs=EmptyString] attribute DOMString borderRight; + [TreatNullAs=EmptyString] attribute DOMString borderRightColor; + [TreatNullAs=EmptyString] attribute DOMString borderRightStyle; + [TreatNullAs=EmptyString] attribute DOMString borderRightWidth; + [TreatNullAs=EmptyString] attribute DOMString borderTop; + [TreatNullAs=EmptyString] attribute DOMString borderTopColor; + [TreatNullAs=EmptyString] attribute DOMString borderTopStyle; + [TreatNullAs=EmptyString] attribute DOMString borderTopWidth; + + [TreatNullAs=EmptyString] attribute DOMString content; + + [TreatNullAs=EmptyString] attribute DOMString color; + + [TreatNullAs=EmptyString] attribute DOMString display; + + [TreatNullAs=EmptyString] attribute DOMString visibility; + + //[TreatNullAs=EmptyString] attribute DOMString float; //XXXjdm need BinaryName annotation + + [TreatNullAs=EmptyString] attribute DOMString clear; + + [TreatNullAs=EmptyString] attribute DOMString direction; + + [TreatNullAs=EmptyString] attribute DOMString lineHeight; + + [TreatNullAs=EmptyString] attribute DOMString verticalAlign; + + [TreatNullAs=EmptyString] attribute DOMString overflow; + + [TreatNullAs=EmptyString] attribute DOMString tableLayout; + + [TreatNullAs=EmptyString] attribute DOMString whiteSpace; + + [TreatNullAs=EmptyString] attribute DOMString writingMode; + + [TreatNullAs=EmptyString] attribute DOMString textAlign; + [TreatNullAs=EmptyString] attribute DOMString textDecoration; + [TreatNullAs=EmptyString] attribute DOMString textOrientation; + + [TreatNullAs=EmptyString] attribute DOMString font; + [TreatNullAs=EmptyString] attribute DOMString fontFamily; + [TreatNullAs=EmptyString] attribute DOMString fontSize; + [TreatNullAs=EmptyString] attribute DOMString fontStyle; + [TreatNullAs=EmptyString] attribute DOMString fontVariant; + [TreatNullAs=EmptyString] attribute DOMString fontWeight; + + [TreatNullAs=EmptyString] attribute DOMString margin; + [TreatNullAs=EmptyString] attribute DOMString marginBottom; + [TreatNullAs=EmptyString] attribute DOMString marginLeft; + [TreatNullAs=EmptyString] attribute DOMString marginRight; + [TreatNullAs=EmptyString] attribute DOMString marginTop; + + [TreatNullAs=EmptyString] attribute DOMString padding; + [TreatNullAs=EmptyString] attribute DOMString paddingBottom; + [TreatNullAs=EmptyString] attribute DOMString paddingLeft; + [TreatNullAs=EmptyString] attribute DOMString paddingRight; + [TreatNullAs=EmptyString] attribute DOMString paddingTop; + + [TreatNullAs=EmptyString] attribute DOMString position; + + [TreatNullAs=EmptyString] attribute DOMString top; + [TreatNullAs=EmptyString] attribute DOMString right; + [TreatNullAs=EmptyString] attribute DOMString left; + [TreatNullAs=EmptyString] attribute DOMString bottom; + [TreatNullAs=EmptyString] attribute DOMString height; + [TreatNullAs=EmptyString] attribute DOMString minHeight; + [TreatNullAs=EmptyString] attribute DOMString maxHeight; + + [TreatNullAs=EmptyString] attribute DOMString width; + [TreatNullAs=EmptyString] attribute DOMString minWidth; + [TreatNullAs=EmptyString] attribute DOMString maxWidth; }; diff --git a/components/style/legacy.rs b/components/style/legacy.rs index 504471d7b04..027f238093d 100644 --- a/components/style/legacy.rs +++ b/components/style/legacy.rs @@ -9,6 +9,7 @@ use self::UnsignedIntegerAttribute::*; use self::SimpleColorAttribute::*; use node::{TElement, TElementAttributes, TNode}; +use properties::common_types::specified::CSSColor; use properties::DeclaredValue::SpecifiedValue; use properties::PropertyDeclaration::*; use properties::{CSSFloat, specified}; @@ -214,7 +215,7 @@ impl PresentationalHintSynthesis for Stylist { None => {} Some(color) => { matching_rules_list.vec_push(DeclarationBlock::from_declaration( - BackgroundColorDeclaration(SpecifiedValue(Color::RGBA(color))))); + BackgroundColorDeclaration(SpecifiedValue(CSSColor { parsed: Color::RGBA(color), authored: None })))); *shareable = false } } diff --git a/components/style/properties/common_types.rs b/components/style/properties/common_types.rs index f757e8f075b..3d3fd9294e8 100644 --- a/components/style/properties/common_types.rs +++ b/components/style/properties/common_types.rs @@ -13,6 +13,7 @@ pub type CSSFloat = f64; pub mod specified { use std::ascii::AsciiExt; use std::f64::consts::PI; + use std::fmt; use std::fmt::{Formatter, FormatError, Show}; use url::Url; use cssparser; @@ -20,7 +21,7 @@ pub mod specified { use cssparser::ast::*; use parsing_utils::{mod, BufferedIter, ParserIter}; use super::{Au, CSSFloat}; - #[deriving(Clone)] + #[deriving(Clone, PartialEq)] pub struct CSSColor { pub parsed: cssparser::Color, pub authored: Option, @@ -30,7 +31,7 @@ pub mod specified { let parsed = cssparser::Color::parse(component_value); parsed.map(|parsed| { let authored = match component_value { - &Ident(ref s) | &QuotedString(ref s) => Some(s.clone()), + &Ident(ref s) => Some(s.clone()), _ => None, }; CSSColor { @@ -40,8 +41,8 @@ pub mod specified { }) } } - impl Show for CSSColor { - fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> { + impl fmt::Show for CSSColor { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.authored { Some(ref s) => write!(f, "{}", s), None => write!(f, "{}", self.parsed), @@ -50,6 +51,32 @@ pub mod specified { } #[deriving(Clone)] + pub struct CSSRGBA { + pub parsed: cssparser::RGBA, + pub authored: Option, + } + impl fmt::Show for CSSRGBA { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.authored { + Some(ref s) => write!(f, "{}", s), + None => write!(f, "{}", self.parsed), + } + } + } + + #[deriving(Clone, PartialEq)] + pub struct CSSImage(pub Option); + impl fmt::Show for CSSImage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let &CSSImage(ref url) = self; + match url { + &Some(ref image) => write!(f, "{}", image), + &None => write!(f, "none"), + } + } + } + + #[deriving(Clone, PartialEq)] pub enum Length { Au(Au), // application units Em(CSSFloat), @@ -69,8 +96,8 @@ pub mod specified { // Vmin(CSSFloat), // Vmax(CSSFloat), } - impl Show for Length { - fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> { + impl fmt::Show for Length { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { &Length::Au(length) => write!(f, "{}", length), &Length::Em(length) => write!(f, "{}em", length), @@ -123,16 +150,16 @@ pub mod specified { } } - #[deriving(Clone)] + #[deriving(Clone, PartialEq)] pub enum LengthOrPercentage { Length(Length), Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0] } - impl Show for LengthOrPercentage { - fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> { + impl fmt::Show for LengthOrPercentage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &LengthOrPercentage::Length(length) => write!(f, "{}", length), - &LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage), + &LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.), } } } @@ -167,11 +194,11 @@ pub mod specified { Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0] Auto, } - impl Show for LengthOrPercentageOrAuto { - fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> { + impl fmt::Show for LengthOrPercentageOrAuto { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &LengthOrPercentageOrAuto::Length(length) => write!(f, "{}", length), - &LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage), + &LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.), &LengthOrPercentageOrAuto::Auto => write!(f, "auto"), } } @@ -207,11 +234,11 @@ pub mod specified { Percentage(CSSFloat), // [0 .. 100%] maps to [0.0 .. 1.0] None, } - impl Show for LengthOrPercentageOrNone { - fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> { + impl fmt::Show for LengthOrPercentageOrNone { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &LengthOrPercentageOrNone::Length(length) => write!(f, "{}", length), - &LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage), + &LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.), &LengthOrPercentageOrNone::None => write!(f, "none"), } } @@ -319,7 +346,7 @@ pub mod specified { } /// Specified values for an image according to CSS-IMAGES. - #[deriving(Clone)] + #[deriving(Clone, PartialEq)] pub enum Image { Url(Url), LinearGradient(LinearGradient), @@ -328,7 +355,7 @@ pub mod specified { impl Show for Image { fn fmt(&self, f: &mut Formatter) -> Result<(), FormatError> { match self { - &Image::Url(ref url) => write!(f, "url({})", url), + &Image::Url(ref url) => write!(f, "url(\"{}\")", url), &Image::LinearGradient(ref grad) => write!(f, "linear-gradient({})", grad), } } @@ -368,7 +395,7 @@ pub mod specified { } /// Specified values for a CSS linear gradient. - #[deriving(Clone)] + #[deriving(Clone, PartialEq)] pub struct LinearGradient { /// The angle or corner of the gradient. pub angle_or_corner: AngleOrCorner, @@ -404,7 +431,7 @@ pub mod specified { } /// Specified values for one color stop in a linear gradient. - #[deriving(Clone)] + #[deriving(Clone, PartialEq)] pub struct ColorStop { /// The color of this stop. pub color: CSSColor, @@ -661,7 +688,7 @@ pub mod computed { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &LengthOrPercentage::Length(length) => write!(f, "{}", length), - &LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage), + &LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.), } } } @@ -687,7 +714,7 @@ pub mod computed { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &LengthOrPercentageOrAuto::Length(length) => write!(f, "{}", length), - &LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage), + &LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.), &LengthOrPercentageOrAuto::Auto => write!(f, "auto"), } } @@ -715,7 +742,7 @@ pub mod computed { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &LengthOrPercentageOrNone::Length(length) => write!(f, "{}", length), - &LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage), + &LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.), &LengthOrPercentageOrNone::None => write!(f, "none"), } } @@ -743,7 +770,7 @@ pub mod computed { impl fmt::Show for Image { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &Image::Url(ref url) => write!(f, "url({})", url), + &Image::Url(ref url) => write!(f, "url(\"{}\")", url), &Image::LinearGradient(ref grad) => write!(f, "linear-gradient({})", grad), } } diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index 2e14259e720..d4b78651b33 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -564,14 +564,15 @@ pub mod longhands { Normal, Length(specified::Length), Number(CSSFloat), - // percentage are the same as em. + Percentage(CSSFloat), } impl fmt::Show for SpecifiedValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &SpecifiedValue::Normal => write!(f, "normal"), - &SpecifiedValue::Length(length) => write!(f, "{}%", length), + &SpecifiedValue::Length(length) => write!(f, "{}", length), &SpecifiedValue::Number(number) => write!(f, "{}", number), + &SpecifiedValue::Percentage(number) => write!(f, "{}%", number * 100.), } } } @@ -582,7 +583,7 @@ pub mod longhands { &ast::Number(ref value) if value.value >= 0. => Ok(SpecifiedValue::Number(value.value)), &ast::Percentage(ref value) if value.value >= 0. => - Ok(SpecifiedValue::Length(specified::Length::Em(value.value / 100.))), + Ok(SpecifiedValue::Percentage(value.value / 100.)), &Dimension(ref value, ref unit) if value.value >= 0. => specified::Length::parse_dimension(value.value, unit.as_slice()) .map(SpecifiedValue::Length), @@ -619,6 +620,7 @@ pub mod longhands { SpecifiedValue::Normal => T::Normal, SpecifiedValue::Length(value) => T::Length(computed::compute_Au(value, context)), SpecifiedValue::Number(value) => T::Number(value), + SpecifiedValue::Percentage(value) => T::Length(computed::compute_Au(specified::Length::Em(value), context)), } } @@ -731,7 +733,7 @@ pub mod longhands { impl fmt::Show for ContentItem { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &ContentItem::StringContent(ref s) => write!(f, "{}", s), + &ContentItem::StringContent(ref s) => write!(f, "\"{}\"", s), } } } @@ -749,9 +751,9 @@ pub mod longhands { &T::none => write!(f, "none"), &T::Content(ref content) => { for c in content.iter() { - let _ = write!(f, "{} ", c); + let _ = write!(f, "{}", c); } - Ok(()) + Ok(()) } } } @@ -833,13 +835,15 @@ pub mod longhands { <%self:single_component_value name="background-image"> use super::common_types::specified as common_specified; + use super::super::common_types::specified::CSSImage as CSSImage; pub mod computed_value { use super::super::super::common_types::computed; - #[deriving(Clone, PartialEq)] pub type T = Option; + //#[deriving(Clone, PartialEq)] + //pub type T = super::SpecifiedValue; } #[deriving(Clone)] - pub type SpecifiedValue = Option; + pub type SpecifiedValue = common_specified::CSSImage; #[inline] pub fn get_initial_value() -> computed_value::T { None @@ -848,13 +852,13 @@ pub mod longhands { -> Result { match component_value { &ast::Ident(ref value) if value.as_slice().eq_ignore_ascii_case("none") => { - Ok(None) + Ok(CSSImage(None)) } _ => { match common_specified::Image::from_component_value(component_value, base_url) { Err(err) => Err(err), - Ok(result) => Ok(Some(result)), + Ok(result) => Ok(CSSImage(Some(result))), } } } @@ -862,8 +866,8 @@ pub mod longhands { pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context) -> computed_value::T { match value { - None => None, - Some(image) => Some(image.to_computed_value(context)), + CSSImage(None) => None, + CSSImage(Some(image)) => Some(image.to_computed_value(context)), } } @@ -882,9 +886,7 @@ pub mod longhands { } impl fmt::Show for T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let _ = write!(f, "{}", self.horizontal); - let _ = write!(f, "{}", self.vertical); - Ok(()) + write!(f, "{} {}", self.horizontal, self.vertical) } } } @@ -896,9 +898,7 @@ pub mod longhands { } impl fmt::Show for SpecifiedValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let _ = write!(f, "{}", self.horizontal); - let _ = write!(f, "{}", self.vertical); - Ok(()) + write!(f, "{} {}", self.horizontal, self.vertical) } } @@ -1004,19 +1004,32 @@ pub mod longhands { ${new_style_struct("Color", is_inherited=True)} <%self:raw_longhand name="color"> - pub use super::computed_as_specified as to_computed_value; - pub type SpecifiedValue = RGBA; + use super::super::common_types::specified::{CSSColor, CSSRGBA}; + #[inline] + pub fn to_computed_value(value: SpecifiedValue, _context: &computed::Context) + -> computed_value::T { + value.parsed + } + + pub type SpecifiedValue = CSSRGBA; pub mod computed_value { - pub type T = super::SpecifiedValue; + use cssparser; + pub type T = cssparser::RGBA; } #[inline] pub fn get_initial_value() -> computed_value::T { RGBA { red: 0., green: 0., blue: 0., alpha: 1. } /* black */ } pub fn parse_specified(input: &[ComponentValue], _base_url: &Url) -> Result, ()> { - match one_component_value(input).and_then(Color::parse) { - Ok(Color::RGBA(rgba)) => Ok(DeclaredValue::SpecifiedValue(rgba)), - Ok(Color::CurrentColor) => Ok(DeclaredValue::Inherit), + match one_component_value(input).and_then(CSSColor::parse) { + Ok(CSSColor { parsed: Color::RGBA(rgba), authored }) => { + let rgba = CSSRGBA { + parsed: rgba, + authored: authored, + }; + Ok(DeclaredValue::SpecifiedValue(rgba)) + } + Ok(CSSColor { parsed: Color::CurrentColor, .. }) => Ok(DeclaredValue::Inherit), Err(()) => Err(()), } } @@ -1058,7 +1071,7 @@ pub mod longhands { /*impl fmt::Show for T { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for font in self.iter() { - write!(f, "{} ", font); + write!(f, "{}", font); } Ok(()) } @@ -1344,14 +1357,23 @@ pub mod longhands { } impl fmt::Show for SpecifiedValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut space = false; if self.underline { - let _ = write!(f, "underline "); + let _ = write!(f, "underline"); + space = true; } if self.overline { - let _ = write!(f, "overline "); + if space { + let _ = write!(f, " "); + } + let _ = write!(f, "overline"); + space = true; } if self.line_through { - let _ = write!(f, "line-through "); + if space { + let _ = write!(f, " "); + } + let _ = write!(f, "line-through"); } Ok(()) } @@ -1753,7 +1775,7 @@ pub mod longhands { offset_y: computed::compute_Au(value.offset_y, context), blur_radius: computed::compute_Au(value.blur_radius, context), spread_radius: computed::compute_Au(value.spread_radius, context), - color: value.color.unwrap_or(cssparser::Color::CurrentColor), + color: value.color.map(|color| color.parsed).unwrap_or(cssparser::Color::CurrentColor), inset: value.inset, } }).collect() @@ -1809,8 +1831,8 @@ pub mod longhands { // Try to parse a color. match specified::CSSColor::parse(value) { - Ok(the_color) if color.is_none() => { - color = Some(the_color); + Ok(ref the_color) if color.is_none() => { + color = Some(the_color.clone()); continue } Ok(_) => return Err(()), @@ -3013,7 +3035,13 @@ pub fn cascade(applicable_declarations: &[DeclarationBlock], } } PropertyDeclaration::ColorDeclaration(ref value) => { - context.color = get_specified!(get_color, color, value); + context.color = match *value { + DeclaredValue::SpecifiedValue(ref specified_value) => specified_value.parsed, + DeclaredValue::Initial => longhands::color::get_initial_value(), + DeclaredValue::Inherit => inherited_style.get_color().color.clone(), + + }; +//get_specified!(get_color, color, value); } PropertyDeclaration::DisplayDeclaration(ref value) => { context.display = get_specified!(get_box, display, value); diff --git a/tests/content/cssprops.js b/tests/content/cssprops.js new file mode 100644 index 00000000000..21d0224535f --- /dev/null +++ b/tests/content/cssprops.js @@ -0,0 +1,537 @@ +function run_tests(properties) { + for (var property in Object.keys(properties)) { + var name = Object.keys(properties)[property]; + var generator = create_value_generator(properties[name]); + var prop = properties[name].property || name; + //setTimeout(function(name, generator, prop) { + while (run_test(name, generator, prop)) { + } + //}, 0, name, generator, prop); + } +} + +function generate_inline_style(name, value) { + if (value) { + return {'declaration': name + ": " + value, + 'value': value, + 'result': value}; + } + return null; +} + +function all_values(values) { + var results = []; + for (var i = 0; i < values.length; i++) { + var value = values[i]; + if (typeof value == "function") { + var f = value(); + var result; + while ((result = f()) != null) { + if (typeof result == "object" && 'serialized' in result) { + results.push(result.serialized); //XXXjdm push actual and expect serialized + } else { + results.push(result); + } + } + } else if (typeof value == "string") { + results.push(value); + } else if (value instanceof Array) { + var subresults = []; + for (var j = 0; j < value.length; j++) { + var subresult = all_values(value[j], true); + if (!(subresult instanceof Array)) { + subresult = [subresult]; + } + subresults.push(subresult); + } + if (subresults.length > 1) { + function choose_slices(vecs) { + if (vecs.length == 1) { + return vecs[0].map(function(v) { return [v]; }); + } + var slice_results = []; + var rest = choose_slices(vecs.slice(1, vecs.length)); + for (var a = 0; a < vecs[0].length; a++) { + for (var b = 0; b < rest.length; b++) { + slice_results.push([vecs[0][a]].concat(rest[b])); + } + } + return slice_results; + } + + subresults = choose_slices(subresults).map(function (a) { return a.join(' ') }); + } + for (var j = 0; j < subresults.length; j++) { + results = results.concat(subresults[j]); + } + } else if (value instanceof Object && 'serialized' in value) { + results.push(value.serialized); //XXXjdm push actual and expect serialized + } else if (typeof value == "number") { + results.push(value.toString()); + } else { + throw "unexpected value type: " + typeof(value); + } + } + return results; +} + +function create_value_generator(property) { + var results = all_values(property.values); + return iterable(results); +} + +function to_idl(property) { + return property.replace(/-\w/g, function(x){return x.toUpperCase()}).split('-').join(''); +} + +function run_test(property, generator, prop) { + //console.log("testing " + property + ' ' + to_idl(property)); + var elem = document.createElement('div'); + document.getElementById('parent').appendChild(elem); + var style = generate_inline_style(property, generator()); + if (style && to_idl(prop) in elem.style) { + elem.setAttribute('style', style.declaration); + is(elem.style[to_idl(prop)], style.result, property + ' raw inline style declaration'); + elem.setAttribute('style', ''); + elem.style[to_idl(prop)] = style.value; + is(elem.style[to_idl(prop)], style.result, property + ' style property'); + } + document.getElementById('parent').removeChild(elem); + return style != null; +} + +function iterable(values) { + var i = 0; + return function() { + if (i < values.length) { + return values[i++]; + } + return null; + } +} + +function color() { + var colors = ['black', 'red', 'rgb(50, 75, 100)', 'rgba(5, 7, 10, 0.9)']; + return iterable(colors); +} + +function percentage() { + var values = ["5%", {actual: ".5%", serialized: "0.5%"}]; + return iterable(values); +} + +function length() { + var values = ["1px", {actual: ".1em", serialized: "0.1em"}]; + return iterable(values); +} + +function degree() { + var values = ["87deg"]; + return iterable(values); +} + +function uri() { + var values = ["url(\"http://localhost/\")", + {actual: "url(http://localhost/)", + serialized: "url(\"http://localhost/\")"}]; + return iterable(values); +} + +function border_style() { + var values = ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', + 'inset', 'outset']; + return iterable(values); +} + +function integer() { + var values = ['0', '101', '-51']; + return iterable(values); +} + +function shape() { + var values = ['rect(1em, auto, 0.5px, 2000em)']; + return iterable(values); +} + +function string() { + var values = ['"string"', {actual: "'string'", serialized: '"string"'}]; + return iterable(values); +} + +function counter() { + var values = ['counter(par-num)', 'counter(par-num, upper-roman)']; + return iterable(values); +} + +function attr() { + var values = ['attr(foo-bar)', 'attr(foo_bar)']; + return iterable(values); +} + +function family_name() { + var values = ['Gill,', '"Lucida" Grande,', 'Red/Black,']; + return iterable(values); +} + +function generic_family() { + var values = ['serif', 'sans-serif']; + return iterable(values); +} + +function absolute_size() { + var values = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large']; + return iterable(values); +} + +function relative_size() { + var values = ['larger', 'smaller']; + return iterable(values); +} + +function number() { + var values = ['0', {'actual': '-0', serialized: '0'}, '1000', '-5123', '0.9', '-0.09']; + return iterable(values); +} + +var properties = { + 'background-attachment': { + 'values': ['scroll', 'fixed', 'inherit'], + 'initial': 'scroll', + }, + 'background-color': { + 'values': [color, 'transparent', 'inherit'], + 'initial': 'transparent', + }, + 'background-image': { + 'values': [uri, 'none', 'inherit'], + 'initial': 'none', + }, + 'background-position': { + 'values': [[[percentage, length, 'left', 'center', 'right'], + [percentage, length, 'top', 'center', 'bottom']], + [['left', 'center', 'right'], + ['top', 'center', 'bottom']], + 'inherit'], + 'initial': '0% 0%', + }, + 'background-repeat': { + 'values': ['repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'inherit'], + 'initial': 'repeat', + }, + //background + 'border-collapse': { + 'values': ['collapse', 'separate', 'inherit'], + 'initial': 'separate', + }, + //border-color + 'border-spacing': { + 'values': [length, 'inherit'], + 'initial': '0', + }, + //border-style + //border-top, border-right, border-bottom, border-left + 'border-top-color': { + 'values': [color, 'transparent', 'inherit'], + 'initial': 'black', //FIXME + }, + 'border-right-color': { + 'values': [color, 'transparent', 'inherit'], + 'initial': 'black', //FIXME + }, + 'border-bottom-color': { + 'values': [color, 'transparent', 'inherit'], + 'initial': 'black', //FIXME + }, + 'border-left-color': { + 'values': [color, 'transparent', 'inherit'], + 'initial': 'black', //FIXME + }, + 'border-top-style': { + 'values': [border_style, 'inherit'], + 'initial': null, + }, + 'border-right-style': { + 'values': [border_style, 'inherit'], + 'initial': null, + }, + 'border-bottom-style': { + 'values': [border_style, 'inherit'], + 'initial': null, + }, + 'border-left-style': { + 'values': [border_style, 'inherit'], + 'initial': null, + }, + 'border-top-width': { + 'values': ['thin', 'medium', 'thick', length, 'inherit'], + 'initial': 'medium', + }, + 'border-right-width': { + 'values': ['thin', 'medium', 'thick', length, 'inherit'], + 'initial': 'medium', + }, + 'border-bottom-width': { + 'values': ['thin', 'medium', 'thick', length, 'inherit'], + 'initial': 'medium', + }, + 'border-left-width': { + 'values': ['thin', 'medium', 'thick', length, 'inherit'], + 'initial': 'medium', + }, + //border-width + //border + 'bottom': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 'auto', + }, + 'caption-side': { + 'values': ['top', 'bottom', 'inherit'], + 'initial': 'top', + }, + 'clear': { + 'values': ['none', 'left', 'right', 'both', 'inherit'], + 'initial': 'none', + }, + 'clip': { + 'values': [shape, 'auto', 'inherit'], + 'initial': 'auto', + }, + 'color': { + 'values': [color, 'inherit'], + 'initial': 'black', //FIXME depends on user agent + }, + 'content': { + 'values': ['normal', 'none', string, uri, counter, attr, 'inherit'], //FIXME + 'initial': 'normal', + }, + //counter-increment + //counter-reset + 'cursor': { + 'values': [/*uri,*/ 'auto', 'crosshair', 'default', 'pointer', 'move', 'e-resize', 'ne-resize', + 'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize', 'text', + 'wait', 'help', 'progress', 'inherit'], + 'initial': 'auto', + }, + 'direction': { + 'values': ['ltr', 'rtl', 'inherit'], + 'initial': 'ltr', + }, + 'display': { + 'values': ['inline', 'block', 'list-item', 'inline-block', 'table', 'inline-table', + 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', + 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none', + 'inherit'], + 'initial': 'inline', + }, + 'empty-cells': { + 'values': ['show', 'hide', 'inherit'], + 'initial': 'show', + }, + 'float': { + 'values': ['left', 'right', 'none', 'inherit'], + 'initial': 'none', + 'property': 'cssFloat', + }, + 'font-family': { + 'values': [[family_name, generic_family], 'inherit'], + 'initial': 'sans-serif', //FIXME depends on user agent + }, + 'font-size': { + 'values': [absolute_size, relative_size, length, percentage, 'inherit'], + 'initial': 'medium', + }, + 'font-style': { + 'values': ['normal', 'italic', 'oblique', 'inherit'], + 'initial': 'normal', + }, + 'font-variant': { + 'values': ['normal', 'small-caps', 'inherit'], + 'initial': 'normal', + }, + 'font-weight': { + 'values': ['normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 300, 400, 500, 600, + 700, 800, 900, 'inherit'], + 'initial': 'normal', + }, + //font + 'height': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 'auto', + }, + 'left': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 'auto', + }, + 'letter-spacing': { + 'values': ['normal', length, 'inherit'], + 'initial': 'normal', + }, + 'line-height': { + 'values': ['normal', number, length, percentage, 'inherit'], + 'initial': 'normal', + }, + 'list-style-image': { + 'values': [uri, 'none', 'inherit'], + 'initial': 'none', + }, + 'list-style-position': { + 'values': ['inside', 'outside', 'inherit'], + 'initial': 'outside', + }, + 'list-style-type': { + 'values': ['disc', 'circle', 'square', 'decimal', 'decimal-leading-zero', 'lower-roman', + 'upper-roman', 'lower-greek', 'lower-latin', 'upper-latin', 'armenian', 'georgian', + 'lower-alpha', 'upper-alpha', 'none', 'inherit'], + 'initial': 'disc', + }, + //list-style + 'margin-right': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 0, + }, + 'margin-left': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 0, + }, + 'margin-top': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 0, + }, + 'margin-bottom': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 0, + }, + //margin + 'max-height': { + 'values': [length, percentage, 'none', 'inherit'], + 'initial': 'none', + }, + 'max-width': { + 'values': [length, percentage, 'none', 'inherit'], + 'initial': 'none', + }, + 'min-height': { + 'values': [length, percentage, 'inherit'], + 'initial': 0, + }, + 'min-width': { + 'values': [length, percentage, 'inherit'], + 'initial': 0, + }, + 'orphans': { + 'values': [integer, 'inherit'], + 'initial': 2, + }, + 'outline-color': { + 'values': [color, 'invert', 'inherit'], + 'initial': 'invert', + }, + 'outline-style': { + 'values': [border_style, 'inherit'], + 'initial': 'none', + }, + 'outline-width': { + 'values': ['thin', 'medium', 'thick', length, 'inherit'], + 'initial': 'medium', + }, + //outline + 'overflow': { + 'values': ['visible', 'hidden', 'scroll', 'auto', 'inherit'], + 'initial': 'visible', + }, + 'padding-top': { + 'values': [length, percentage, 'inherit'], + 'initial': 0, + }, + 'padding-right': { + 'values': [length, percentage, 'inherit'], + 'initial': 0, + }, + 'padding-bottom': { + 'values': [length, percentage, 'inherit'], + 'initial': 0, + }, + 'padding-left': { + 'values': [length, percentage, 'inherit'], + 'initial': 0, + }, + //padding + 'page-break-after': { + 'values': ['auto', 'always', 'avoid', 'left', 'right', 'inherit'], + 'initial': 'auto', + }, + 'page-break-before': { + 'values': ['auto', 'always', 'avoid', 'left', 'right', 'inherit'], + 'initial': 'auto', + }, + 'page-break-inside': { + 'values': ['avoid', 'auto', 'inherit'], + 'initial': 'auto', + }, + 'position': { + 'values': ['static', 'relative', 'absolute', 'fixed', 'inherit'], + 'initial': 'static', + }, + //FIXME quotes + 'right': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 'auto', + }, + 'table-layout': { + 'values': ['auto', 'fixed', 'inherit'], + 'initial': 'auto', + }, + 'text-align': { + 'values': ['left', 'right', 'center', 'justify', 'inherit'], + 'initial': null, + }, + 'text-decoration': { + 'values': ['none', 'underline', 'overline', 'line-through', 'blink', 'inherit'], + 'initial': 'none', + }, + 'text-indent': { + 'values': [length, percentage, 'inherit'], + 'initial': 0, + }, + 'text-transform': { + 'values': ['capitalize', 'uppercase', 'lowercase', 'none', 'inherit'], + 'initial': 'none', + }, + 'top': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 'auto', + }, + 'unicode-bidi': { + 'values': ['normal', 'embed', 'bidi-override', 'inherit'], + 'initial': 'normal', + }, + 'vertical-align': { + 'values': ['baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom', + percentage, length, 'inherit'], + 'initial': 'baseline', + }, + 'visibility': { + 'values': ['visible', 'hidden', 'collapse', 'inherit'], + 'initial': 'visible', + }, + 'white-space': { + 'values': ['normal', 'pre', 'nowrap', 'pre-wrap', 'pre-line', 'inherit'], + 'initial': 'normal', + }, + 'widows': { + 'values': [integer, 'inherit'], + 'initial': 2, + }, + 'width': { + 'values': [length, percentage, 'auto', 'inherit'], + 'initial': 'auto', + }, + 'word-spacing': { + 'values': ['normal', length, 'inherit'], + 'initial': 'normal', + }, + 'z-index': { + 'values': ['auto', integer, 'inherit'], + 'initial': 'auto', + }, +}; diff --git a/tests/content/harness.js b/tests/content/harness.js index 2738ca2e6a6..8931e4bf65f 100644 --- a/tests/content/harness.js +++ b/tests/content/harness.js @@ -12,17 +12,17 @@ function expect(num) { function _fail(s, m) { _tests++; // string split to avoid problems with tests that end up printing the value of window._fail. - window.alert(_oneline("TEST-UNEXPECTED" + "-FAIL | " + s + ": " + m)); + console.log(_oneline("TEST-UNEXPECTED" + "-FAIL | " + s + ": " + m)); } function _pass(s, m) { _tests++; - window.alert(_oneline("TEST-PASS | " + s + ": " + m)); + //console.log(_oneline("TEST-PASS | " + s + ": " + m)); } function _printer(opstr, op) { return function (a, b, msg) { - let f = op(a,b) ? _pass : _fail; + var f = op(a,b) ? _pass : _fail; if (!msg) msg = ""; f(a + " " + opstr + " " + b, msg); }; diff --git a/tests/content/test_htmlelement_style.html b/tests/content/test_htmlelement_style.html new file mode 100644 index 00000000000..da821228252 --- /dev/null +++ b/tests/content/test_htmlelement_style.html @@ -0,0 +1,12 @@ + + + + + + +
+ + +