diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 77aee91ce48..f11cabd7989 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -104,55 +104,24 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue fn GetPropertyValue(&self, mut property: DOMString) -> DOMString { - let owner = &self.owner; - - // Step 1 - property.make_ascii_lowercase(); - let property = Atom::from(property); - if self.readonly { // Readonly style declarations are used for getComputedStyle. + property.make_ascii_lowercase(); + let property = Atom::from(property); return self.get_computed_style(&property).unwrap_or(DOMString::new()); } - // Step 2 - if let Some(shorthand) = Shorthand::from_name(&property) { - let style_attribute = owner.style_attribute().borrow(); - let style_attribute = if let Some(ref style_attribute) = *style_attribute { - style_attribute.read() - } else { - // shorthand.longhands() is never empty, so with no style attribute - // step 2.2.2 would do this: - return DOMString::new() - }; + let style_attribute = self.owner.style_attribute().borrow(); + let style_attribute = if let Some(ref style_attribute) = *style_attribute { + style_attribute.read() + } else { + // No style attribute is like an empty style attribute: no matching declaration. + return DOMString::new() + }; - // Step 2.1 - let mut list = vec![]; - - // Step 2.2 - for longhand in shorthand.longhands() { - // Step 2.2.1 - let declaration = style_attribute.get(longhand); - - // Step 2.2.2 & 2.2.3 - match declaration { - Some(&(ref declaration, _importance)) => list.push(declaration), - None => return DOMString::new(), - } - } - - // Step 2.3 - // TODO: important is hardcoded to false because method does not implement it yet - let serialized_value = shorthand.serialize_shorthand_value_to_string( - list, Importance::Normal); - return DOMString::from(serialized_value); - } - - // Step 3 & 4 - owner.get_inline_style_declaration(&property, |d| match d { - Some(declaration) => DOMString::from(declaration.0.value()), - None => DOMString::new(), - }) + let mut string = String::new(); + style_attribute.property_value_to_css(&property, &mut string).unwrap(); + DOMString::from(string) } // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index c13a75d2a88..44af1a75ef0 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -6,6 +6,7 @@ use cssparser::{DeclarationListParser, parse_important, ToCss}; use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter}; use error_reporting::ParseErrorReporter; use parser::{ParserContext, ParserContextExtraData, log_css_error}; +use std::ascii::AsciiExt; use std::boxed::Box as StdBox; use std::fmt; use stylesheets::Origin; @@ -66,16 +67,54 @@ impl PropertyDeclarationBlock { pub fn get(&self, property_name: &str) -> Option< &(PropertyDeclaration, Importance)> { self.declarations.iter().find(|&&(ref decl, _)| decl.matches(property_name)) } -} -impl PropertyDeclarationBlock { - // Take a declaration block known to contain a single property, - // and serialize it - pub fn to_css_single_value(&self, dest: &mut W, name: &str) - -> fmt::Result where W: fmt::Write { + /// Find the value of the given property in this block and serialize it + /// + /// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue + pub fn property_value_to_css(&self, property_name: &str, dest: &mut W) -> fmt::Result + where W: fmt::Write { + // Step 1 + let property = property_name.to_ascii_lowercase(); + + // Step 2 + if let Some(shorthand) = Shorthand::from_name(&property) { + // Step 2.1 + let mut list = Vec::new(); + + // Step 2.2 + for longhand in shorthand.longhands() { + // Step 2.2.1 + let declaration = self.get(longhand); + + // Step 2.2.2 & 2.2.3 + match declaration { + Some(&(ref declaration, _importance)) => list.push(declaration), + None => return Ok(()), + } + } + + // Step 2.3 + // TODO: importance is hardcoded because method does not implement it yet + let importance = Importance::Normal; + let appendable_value = shorthand.get_shorthand_appendable_value(list).unwrap(); + return append_declaration_value(dest, appendable_value, importance) + } + + if let Some(&(ref value, _importance)) = self.get(property_name) { + // Step 3 + value.to_css(dest) + } else { + // Step 4 + Ok(()) + } + } + + /// Take a declaration block known to contain a single property and serialize it. + pub fn single_value_to_css(&self, property_name: &str, dest: &mut W) -> fmt::Result + where W: fmt::Write { match self.declarations.len() { 0 => Err(fmt::Error), - 1 if self.declarations[0].0.name().eq_str_ignore_ascii_case(name) => { + 1 if self.declarations[0].0.name().eq_str_ignore_ascii_case(property_name) => { self.declarations[0].0.to_css(dest) } _ => { @@ -84,7 +123,7 @@ impl PropertyDeclarationBlock { -> &PropertyDeclaration { &dec.0 } - let shorthand = try!(Shorthand::from_name(name).ok_or(fmt::Error)); + let shorthand = try!(Shorthand::from_name(property_name).ok_or(fmt::Error)); if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) { return Err(fmt::Error) } diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 49fa22055df..27bdf9200db 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -410,15 +410,6 @@ impl Shorthand { } } - /// Serializes possible shorthand value to String. - pub fn serialize_shorthand_value_to_string<'a, I>(self, declarations: I, importance: Importance) -> String - where I: IntoIterator, I::IntoIter: Clone { - let appendable_value = self.get_shorthand_appendable_value(declarations).unwrap(); - let mut result = String::new(); - append_declaration_value(&mut result, appendable_value, importance).unwrap(); - result - } - /// Serializes possible shorthand name with value to input buffer given a list of longhand declarations. /// On success, returns true if shorthand value is written and false if no shorthand value is present. pub fn serialize_shorthand_to_buffer<'a, W, I>(self,