diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 101ac3ef2528..2ab50ba4073e 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -10,7 +10,7 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::element::{Element, StylePriority}; +use dom::element::Element; use dom::node::{Node, NodeDamage, window_from_node}; use dom::window::Window; use std::ascii::AsciiExt; @@ -18,7 +18,7 @@ use std::cell::Ref; use std::slice; use string_cache::Atom; use style::parser::ParserContextExtraData; -use style::properties::{PropertyDeclaration, Shorthand}; +use style::properties::{PropertyDeclaration, Shorthand, Importance}; use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute}; use style::selector_impl::PseudoElement; @@ -160,7 +160,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { } // TODO: important is hardcoded to false because method does not implement it yet - let serialized_value = shorthand.serialize_shorthand_value_to_string(Map(list.iter()), false); + let serialized_value = shorthand.serialize_shorthand_value_to_string( + Map(list.iter()), Importance::Normal); return DOMString::from(serialized_value); } @@ -222,8 +223,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { // Step 5 let priority = match &*priority { - "" => StylePriority::Normal, - p if p.eq_ignore_ascii_case("important") => StylePriority::Important, + "" => Importance::Normal, + p if p.eq_ignore_ascii_case("important") => Importance::Important, _ => return Ok(()), }; @@ -265,8 +266,8 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { // Step 4 let priority = match &*priority { - "" => StylePriority::Normal, - p if p.eq_ignore_ascii_case("important") => StylePriority::Important, + "" => Importance::Normal, + p if p.eq_ignore_ascii_case("important") => Importance::Important, _ => return Ok(()), }; diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 860818c024c1..cbaaaa91edf2 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -87,8 +87,8 @@ use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::element_state::*; use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; use style::parser::ParserContextExtraData; -use style::properties::DeclaredValue; use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size}; +use style::properties::{DeclaredValue, Importance}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::sink::Push; @@ -660,13 +660,6 @@ impl LayoutElementHelpers for LayoutJS { } } -#[derive(PartialEq, Eq, Copy, Clone, HeapSizeOf)] -pub enum StylePriority { - Important, - Normal, -} - - impl Element { pub fn html_element_in_html_document(&self) -> bool { self.namespace == ns!(html) && self.upcast::().is_in_html_doc() @@ -780,11 +773,12 @@ impl Element { pub fn update_inline_style(&self, declarations: Vec, - style_priority: StylePriority) { - fn update(element: &Element, mut declarations: Vec, style_priority: StylePriority) { + importance: Importance) { + fn update(element: &Element, mut declarations: Vec, + importance: Importance) { let mut inline_declarations = element.style_attribute().borrow_mut(); if let &mut Some(ref mut existing_declarations) = &mut *inline_declarations { - let existing_declarations = if style_priority == StylePriority::Important { + let existing_declarations = if importance.important() { &mut existing_declarations.important } else { &mut existing_declarations.normal @@ -813,7 +807,7 @@ impl Element { return; } - let (important, normal) = if style_priority == StylePriority::Important { + let (important, normal) = if importance.important() { (declarations, vec![]) } else { (vec![], declarations) @@ -825,17 +819,17 @@ impl Element { }); } - update(self, declarations, style_priority); + update(self, declarations, importance); self.sync_property_with_attrs_style(); } pub fn set_inline_style_property_priority(&self, properties: &[&str], - style_priority: StylePriority) { + importance: Importance) { { 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 { + let (from, to) = if importance == Importance::Important { (&mut declarations.normal, &mut declarations.important) } else { (&mut declarations.important, &mut declarations.normal) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index aaf9ddfe88c8..5db9379fc134 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -14,6 +14,8 @@ use std::ascii::AsciiExt; use std::boxed::Box as StdBox; use std::collections::HashSet; use std::fmt::{self, Write}; +use std::iter::{Iterator, Chain, Zip, Rev, Repeat, repeat}; +use std::slice; use std::sync::Arc; use app_units::Au; @@ -261,11 +263,26 @@ mod property_bit_field { % endif % endfor +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Importance { + /// Indicates a declaration without `!important`. + Normal, -use std::iter::{Iterator, Chain, Zip, Rev, Repeat, repeat}; -use std::slice; -/// Overridden declarations are skipped. + /// Indicates a declaration with `!important`. + Important, +} +impl Importance { + pub fn important(self) -> bool { + match self { + Importance::Normal => false, + Importance::Important => true, + } + } +} + +/// Overridden declarations are skipped. // FIXME (https://github.com/servo/servo/issues/3426) #[derive(Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -279,12 +296,12 @@ pub struct PropertyDeclarationBlock { impl PropertyDeclarationBlock { /// Provides an iterator of all declarations, with indication of !important value pub fn declarations(&self) -> Chain< - Zip>, Repeat>, - Zip>, Repeat> + Zip>, Repeat>, + Zip>, Repeat> > { // Declarations are stored in reverse order. - let normal = self.normal.iter().rev().zip(repeat(false)); - let important = self.important.iter().rev().zip(repeat(true)); + let normal = self.normal.iter().rev().zip(repeat(Importance::Normal)); + let important = self.important.iter().rev().zip(repeat(Importance::Important)); normal.chain(important) } } @@ -300,7 +317,7 @@ impl ToCss for PropertyDeclarationBlock { let mut already_serialized = Vec::new(); // Step 3 - for (declaration, important) in self.declarations() { + for (declaration, importance) in self.declarations() { // Step 3.1 let property = declaration.name(); @@ -326,11 +343,11 @@ impl ToCss for PropertyDeclarationBlock { let mut current_longhands = Vec::new(); let mut important_count = 0; - for &(longhand, longhand_important) in longhands.iter() { + for &(longhand, longhand_importance) in longhands.iter() { let longhand_name = longhand.name(); if properties.iter().any(|p| &longhand_name == *p) { current_longhands.push(longhand); - if longhand_important { + if longhand_importance.important() { important_count += 1; } } @@ -396,7 +413,7 @@ impl ToCss for PropertyDeclarationBlock { dest, &property.to_string(), AppendableValue::Declaration(declaration), - important, + importance, &mut is_first_serialization)); // Step 3.3.8 @@ -430,7 +447,7 @@ fn handle_first_serialization(dest: &mut W, is_first_serialization: &mut bool fn append_declaration_value<'a, W, I> (dest: &mut W, appendable_value: AppendableValue<'a, I>, - is_important: bool) + importance: Importance) -> fmt::Result where W: fmt::Write, I: Iterator { match appendable_value { @@ -445,7 +462,7 @@ fn append_declaration_value<'a, W, I> } } - if is_important { + if importance.important() { try!(write!(dest, " !important")); } @@ -455,7 +472,7 @@ fn append_declaration_value<'a, W, I> fn append_serialization<'a, W, I>(dest: &mut W, property_name: &str, appendable_value: AppendableValue<'a, I>, - is_important: bool, + importance: Importance, is_first_serialization: &mut bool) -> fmt::Result where W: fmt::Write, I: Iterator { @@ -465,7 +482,7 @@ fn append_serialization<'a, W, I>(dest: &mut W, // Overflow does not behave like a normal shorthand. When overflow-x and overflow-y are not of equal // values, they no longer use the shared property name "overflow" and must be handled differently if shorthands::is_overflow_shorthand(&appendable_value) { - return append_declaration_value(dest, appendable_value, is_important); + return append_declaration_value(dest, appendable_value, importance); } try!(write!(dest, "{}:", property_name)); @@ -484,7 +501,7 @@ fn append_serialization<'a, W, I>(dest: &mut W, &AppendableValue::DeclarationsForShorthand(..) => try!(write!(dest, " ")) } - try!(append_declaration_value(dest, appendable_value, is_important)); + try!(append_declaration_value(dest, appendable_value, importance)); write!(dest, ";") } @@ -514,14 +531,15 @@ struct PropertyDeclarationParser<'a, 'b: 'a> { /// Default methods reject all at rules. impl<'a, 'b> AtRuleParser for PropertyDeclarationParser<'a, 'b> { type Prelude = (); - type AtRule = (Vec, bool); + type AtRule = (Vec, Importance); } impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> { - type Declaration = (Vec, bool); + type Declaration = (Vec, Importance); - fn parse_value(&self, name: &str, input: &mut Parser) -> Result<(Vec, bool), ()> { + fn parse_value(&self, name: &str, input: &mut Parser) + -> Result<(Vec, Importance), ()> { let mut results = vec![]; try!(input.parse_until_before(Delimiter::Bang, |input| { match PropertyDeclaration::parse(name, self.context, input, &mut results) { @@ -529,8 +547,11 @@ impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> { _ => Err(()) } })); - let important = input.try(parse_important).is_ok(); - Ok((results, important)) + let importance = match input.try(parse_important) { + Ok(()) => Importance::Important, + Err(()) => Importance::Normal, + }; + Ok((results, importance)) } } @@ -545,8 +566,8 @@ pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Pars let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { match declaration { - Ok((results, important)) => { - if important { + Ok((results, importance)) => { + if importance.important() { important_declarations.extend(results); } else { normal_declarations.extend(results); @@ -675,11 +696,11 @@ impl Shorthand { } /// Serializes possible shorthand value to String. - pub fn serialize_shorthand_value_to_string<'a, I>(self, declarations: I, is_important: bool) -> String + pub fn serialize_shorthand_value_to_string<'a, I>(self, declarations: I, importance: Importance) -> String where I: Iterator + Clone { let appendable_value = self.get_shorthand_appendable_value(declarations).unwrap(); let mut result = String::new(); - append_declaration_value(&mut result, appendable_value, is_important).unwrap(); + append_declaration_value(&mut result, appendable_value, importance).unwrap(); result } @@ -700,7 +721,7 @@ impl Shorthand { dest, property_name, appendable_value, - false, + Importance::Normal, is_first_serialization ).and_then(|_| Ok(true)) }