Fix CSSStyleDeclaration.setPropertyPriority

Before, it was a complicated no-op. (`parse_style_attribute` expects
input like `a: b; c: d;`, when given just a name it return an empty
vector.)
This commit is contained in:
Simon Sapin 2015-07-24 23:48:27 +02:00
parent 1094ce202c
commit 1033886409
4 changed files with 64 additions and 44 deletions

View file

@ -192,7 +192,7 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
if let Some(longhand_properties) = longhand_properties { if let Some(longhand_properties) = longhand_properties {
// Step 2.1 & 2.2 & 2.3 // Step 2.1 & 2.2 & 2.3
if longhand_properties.iter() if longhand_properties.iter()
.map(|longhand| self.GetPropertyPriority(longhand.clone())) .map(|&longhand| self.GetPropertyPriority(longhand.to_owned()))
.all(|priority| priority == "important") { .all(|priority| priority == "important") {
return "important".to_owned(); return "important".to_owned();
@ -274,34 +274,25 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
return Err(Error::NoModificationAllowed); return Err(Error::NoModificationAllowed);
} }
// Step 2 // Step 2 & 3
let property = property.to_ascii_lowercase();
// Step 3
if !is_supported_property(&property) { if !is_supported_property(&property) {
return Ok(()); return Ok(());
} }
// Step 4 // Step 4
let priority = priority.to_ascii_lowercase(); let priority = match &*priority {
if priority != "important" && !priority.is_empty() { "" => StylePriority::Normal,
return Ok(()); p if p.eq_ignore_ascii_case("important") => StylePriority::Important,
} _ => return Ok(()),
};
let owner = self.owner.root(); let owner = self.owner.root();
let window = window_from_node(owner.r());
let decl_block = parse_style_attribute(&property, &window.r().get_url());
let element = ElementCast::from_ref(owner.r()); let element = ElementCast::from_ref(owner.r());
// Step 5 // Step 5 & 6
for decl in decl_block.normal.iter() { match longhands_from_shorthand(&property) {
// Step 6 Some(properties) => element.set_inline_style_property_priority(properties, priority),
let style_priority = if priority.is_empty() { None => element.set_inline_style_property_priority(&[&*property], priority)
StylePriority::Normal
} else {
StylePriority::Important
};
element.update_inline_style(decl.clone(), style_priority);
} }
let document = document_from_node(element); let document = document_from_node(element);
@ -328,21 +319,18 @@ impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration {
// Step 3 // Step 3
let value = self.GetPropertyValue(property.clone()); let value = self.GetPropertyValue(property.clone());
let longhand_properties = longhands_from_shorthand(&property); let owner = self.owner.root();
match longhand_properties { let elem = ElementCast::from_ref(owner.r());
match longhands_from_shorthand(&property) {
// Step 4
Some(longhands) => { Some(longhands) => {
// Step 4
for longhand in longhands.iter() { for longhand in longhands.iter() {
try!(self.RemoveProperty(longhand.clone())); elem.remove_inline_style_property(longhand)
} }
} }
// Step 5
None => { None => elem.remove_inline_style_property(&property)
// Step 5
let owner = self.owner.root();
let elem = ElementCast::from_ref(owner.r());
elem.remove_inline_style_property(property)
}
} }
// Step 6 // Step 6

View file

@ -581,8 +581,9 @@ pub trait ElementHelpers<'a> {
fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>>; fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>>;
fn summarize(self) -> Vec<AttrInfo>; fn summarize(self) -> Vec<AttrInfo>;
fn is_void(self) -> bool; fn is_void(self) -> bool;
fn remove_inline_style_property(self, property: DOMString); fn remove_inline_style_property(self, property: &str);
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority); fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority);
fn set_inline_style_property_priority(self, properties: &[&str], style_priority: StylePriority);
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>; fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>; fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>; fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>;
@ -652,7 +653,7 @@ impl<'a> ElementHelpers<'a> for &'a Element {
} }
} }
fn remove_inline_style_property(self, property: DOMString) { fn remove_inline_style_property(self, property: &str) {
let mut inline_declarations = self.style_attribute.borrow_mut(); let mut inline_declarations = self.style_attribute.borrow_mut();
if let &mut Some(ref mut declarations) = &mut *inline_declarations { if let &mut Some(ref mut declarations) = &mut *inline_declarations {
let index = declarations.normal let index = declarations.normal
@ -704,6 +705,28 @@ impl<'a> ElementHelpers<'a> for &'a Element {
}); });
} }
fn set_inline_style_property_priority(self, properties: &[&str], style_priority: StylePriority) {
let mut inline_declarations = self.style_attribute().borrow_mut();
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
let (from, to) = if style_priority == StylePriority::Important {
(&mut declarations.normal, &mut declarations.important)
} else {
(&mut declarations.normal, &mut declarations.important)
};
let from = Arc::make_unique(from);
let to = Arc::make_unique(to);
let mut new_from = Vec::new();
for declaration in from.drain(..) {
if properties.contains(&declaration.name()) {
to.push(declaration)
} else {
new_from.push(declaration)
}
}
mem::replace(from, new_from);
}
}
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration> { fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
let inline_declarations = self.style_attribute.borrow(); let inline_declarations = self.style_attribute.borrow();
inline_declarations.as_ref().and_then(|declarations| { inline_declarations.as_ref().and_then(|declarations| {

View file

@ -28,7 +28,7 @@ import sys
from mako.template import Template from mako.template import Template
from mako import exceptions from mako import exceptions
try: try:
print(Template(filename=os.environ['TEMPLATE']).render()) print(Template(filename=os.environ['TEMPLATE'], input_encoding='utf8').render().encode('utf8'))
except: except:
sys.stderr.write(exceptions.text_error_template().render().encode('utf8')) sys.stderr.write(exceptions.text_error_template().render().encode('utf8'))
sys.exit(1) sys.exit(1)

View file

@ -6543,11 +6543,12 @@ pub fn modify_style_for_inline_sides(style: &mut Arc<ComputedValues>,
} }
pub fn is_supported_property(property: &str) -> bool { pub fn is_supported_property(property: &str) -> bool {
match property { match_ignore_ascii_case! { property,
% for property in SHORTHANDS + LONGHANDS: % for property in SHORTHANDS + LONGHANDS[:-1]:
"${property.name}" => true, "${property.name}" => true,
% endfor % endfor
_ => false, "${LONGHANDS[-1].name}" => true
_ => false
} }
} }
@ -6579,16 +6580,24 @@ macro_rules! longhand_properties_idents {
} }
} }
pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> { // Extra space here because < seems to be removed by Mako when immediately followed by &.
match shorthand { // ↓
% for property in SHORTHANDS: pub fn longhands_from_shorthand(shorthand: &str) -> Option< &'static [&'static str]> {
"${property.name}" => Some(vec!( % for property in SHORTHANDS:
static ${property.ident.upper()}: &'static [&'static str] = &[
% for sub in property.sub_properties: % for sub in property.sub_properties:
"${sub.name}".to_owned(), "${sub.name}",
% endfor % endfor
)), ];
% endfor
match_ignore_ascii_case!{ shorthand,
% for property in SHORTHANDS[:-1]:
"${property.name}" => Some(${property.ident.upper()}),
% endfor % endfor
_ => None, % for property in SHORTHANDS[-1:]:
"${property.name}" => Some(${property.ident.upper()})
% endfor
_ => None
} }
} }