Move CSSStyleDeclaration.GetPropertyValue logic to style

This commit is contained in:
Simon Sapin 2016-10-07 16:27:43 +02:00
parent 37340d0c26
commit bd37f4e694
3 changed files with 59 additions and 60 deletions

View file

@ -104,55 +104,24 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
fn GetPropertyValue(&self, mut property: DOMString) -> DOMString { 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 { if self.readonly {
// Readonly style declarations are used for getComputedStyle. // 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()); return self.get_computed_style(&property).unwrap_or(DOMString::new());
} }
// Step 2 let style_attribute = self.owner.style_attribute().borrow();
if let Some(shorthand) = Shorthand::from_name(&property) { let style_attribute = if let Some(ref style_attribute) = *style_attribute {
let style_attribute = owner.style_attribute().borrow(); style_attribute.read()
let style_attribute = if let Some(ref style_attribute) = *style_attribute { } else {
style_attribute.read() // No style attribute is like an empty style attribute: no matching declaration.
} else { return DOMString::new()
// shorthand.longhands() is never empty, so with no style attribute };
// step 2.2.2 would do this:
return DOMString::new()
};
// Step 2.1 let mut string = String::new();
let mut list = vec![]; style_attribute.property_value_to_css(&property, &mut string).unwrap();
DOMString::from(string)
// 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(),
})
} }
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority

View file

@ -6,6 +6,7 @@ use cssparser::{DeclarationListParser, parse_important, ToCss};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter}; use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
use error_reporting::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use parser::{ParserContext, ParserContextExtraData, log_css_error}; use parser::{ParserContext, ParserContextExtraData, log_css_error};
use std::ascii::AsciiExt;
use std::boxed::Box as StdBox; use std::boxed::Box as StdBox;
use std::fmt; use std::fmt;
use stylesheets::Origin; use stylesheets::Origin;
@ -66,16 +67,54 @@ impl PropertyDeclarationBlock {
pub fn get(&self, property_name: &str) -> Option< &(PropertyDeclaration, Importance)> { pub fn get(&self, property_name: &str) -> Option< &(PropertyDeclaration, Importance)> {
self.declarations.iter().find(|&&(ref decl, _)| decl.matches(property_name)) self.declarations.iter().find(|&&(ref decl, _)| decl.matches(property_name))
} }
}
impl PropertyDeclarationBlock { /// Find the value of the given property in this block and serialize it
// Take a declaration block known to contain a single property, ///
// and serialize it /// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
pub fn to_css_single_value<W>(&self, dest: &mut W, name: &str) pub fn property_value_to_css<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result
-> fmt::Result where W: fmt::Write { 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<W>(&self, property_name: &str, dest: &mut W) -> fmt::Result
where W: fmt::Write {
match self.declarations.len() { match self.declarations.len() {
0 => Err(fmt::Error), 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) self.declarations[0].0.to_css(dest)
} }
_ => { _ => {
@ -84,7 +123,7 @@ impl PropertyDeclarationBlock {
-> &PropertyDeclaration { -> &PropertyDeclaration {
&dec.0 &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)) { if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) {
return Err(fmt::Error) return Err(fmt::Error)
} }

View file

@ -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<Item=&'a PropertyDeclaration>, 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. /// 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. /// 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, pub fn serialize_shorthand_to_buffer<'a, W, I>(self,