diff options
-rw-r--r-- | components/style/keyframes.rs | 9 | ||||
-rw-r--r-- | components/style/properties/declaration_block.rs | 77 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 28 |
3 files changed, 40 insertions, 74 deletions
diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs index 0fde0c64284..77cf7cc814d 100644 --- a/components/style/keyframes.rs +++ b/components/style/keyframes.rs @@ -362,10 +362,10 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> { context: self.context, }; let mut iter = DeclarationListParser::new(input, parser); - let mut declarations = Vec::new(); + let mut block = PropertyDeclarationBlock::new(); while let Some(declaration) = iter.next() { match declaration { - Ok(parsed) => parsed.expand(|d| declarations.push((d, Importance::Normal))), + Ok(parsed) => parsed.expand(|d| block.push(d, Importance::Normal)), Err(range) => { let pos = range.start; let message = format!("Unsupported keyframe property declaration: '{}'", @@ -377,10 +377,7 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> { } Ok(Arc::new(RwLock::new(Keyframe { selector: prelude, - block: Arc::new(RwLock::new(PropertyDeclarationBlock { - declarations: declarations, - important_count: 0, - })), + block: Arc::new(RwLock::new(block)), }))) } } diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index ff6047289a6..683aa580e1a 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -60,6 +60,14 @@ pub struct PropertyDeclarationBlock { } impl PropertyDeclarationBlock { + /// Create an empty block + pub fn new() -> Self { + PropertyDeclarationBlock { + declarations: Vec::new(), + important_count: 0, + } + } + /// Returns wheather this block contains any declaration with `!important`. /// /// This is based on the `important_count` counter, @@ -169,11 +177,21 @@ impl PropertyDeclarationBlock { } /// Adds or overrides the declaration for a given property in this block, - /// without taking into account any kind of priority. Returns whether the - /// declaration block is actually changed. + /// except if an existing declaration for the same property is more important. + pub fn push(&mut self, declaration: PropertyDeclaration, importance: Importance) { + self.push_common(declaration, importance, false); + } + + /// Adds or overrides the declaration for a given property in this block, + /// Returns whether the declaration block is actually changed. pub fn set_parsed_declaration(&mut self, declaration: PropertyDeclaration, importance: Importance) -> bool { + self.push_common(declaration, importance, true) + } + + fn push_common(&mut self, declaration: PropertyDeclaration, importance: Importance, + overwrite_more_important: bool) -> bool { for slot in &mut *self.declarations { if slot.0.id() == declaration.id() { match (slot.1, importance) { @@ -181,7 +199,11 @@ impl PropertyDeclarationBlock { self.important_count += 1; } (Importance::Important, Importance::Normal) => { - self.important_count -= 1; + if overwrite_more_important { + self.important_count -= 1; + } else { + return false + } } _ => if slot.0 == declaration { return false; @@ -276,39 +298,6 @@ impl PropertyDeclarationBlock { } } } - - /// Only keep the "winning" declaration for any given property, by importance then source order. - pub fn deduplicate(&mut self) { - let mut deduplicated = Vec::with_capacity(self.declarations.len()); - let mut seen_normal = PropertyDeclarationIdSet::new(); - let mut seen_important = PropertyDeclarationIdSet::new(); - - for (declaration, importance) in self.declarations.drain(..).rev() { - if importance.important() { - let id = declaration.id(); - if seen_important.contains(id) { - self.important_count -= 1; - continue - } - if seen_normal.contains(id) { - let previous_len = deduplicated.len(); - deduplicated.retain(|&(ref d, _)| PropertyDeclaration::id(d) != id); - debug_assert_eq!(deduplicated.len(), previous_len - 1); - } - seen_important.insert(id); - } else { - let id = declaration.id(); - if seen_normal.contains(id) || - seen_important.contains(id) { - continue - } - seen_normal.insert(id) - } - deduplicated.push((declaration, importance)) - } - deduplicated.reverse(); - self.declarations = deduplicated; - } } impl ToCss for PropertyDeclarationBlock { @@ -603,21 +592,14 @@ impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> { pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Parser) -> PropertyDeclarationBlock { - let mut declarations = Vec::new(); - let mut important_count = 0; + let mut block = PropertyDeclarationBlock::new(); let parser = PropertyDeclarationParser { context: context, }; let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { match declaration { - Ok((parsed, importance)) => { - let old_len = declarations.len(); - parsed.expand(|d| declarations.push((d, importance))); - if importance.important() { - important_count += declarations.len() - old_len; - } - } + Ok((parsed, importance)) => parsed.expand(|d| block.push(d, importance)), Err(range) => { let pos = range.start; let message = format!("Unsupported property declaration: '{}'", @@ -626,10 +608,5 @@ pub fn parse_property_declaration_list(context: &ParserContext, } } } - let mut block = PropertyDeclarationBlock { - declarations: declarations, - important_count: important_count, - }; - block.deduplicate(); block } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index d331293e530..a700e2a33aa 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -251,18 +251,13 @@ pub extern "C" fn Servo_AnimationValues_Uncompute(value: RawServoAnimationValueB -> RawServoDeclarationBlockStrong { let value = unsafe { value.as_ref().unwrap() }; - let uncomputed_values = value.into_iter() - .map(|v| { - let raw_anim = unsafe { v.as_ref().unwrap() }; - let anim = AnimationValue::as_arc(&raw_anim); - (anim.uncompute(), Importance::Normal) - }) - .collect(); - - Arc::new(RwLock::new(PropertyDeclarationBlock { - declarations: uncomputed_values, - important_count: 0, - })).into_strong() + let mut block = PropertyDeclarationBlock::new(); + for v in value.iter() { + let raw_anim = unsafe { v.as_ref().unwrap() }; + let anim = AnimationValue::as_arc(&raw_anim); + block.push(anim.uncompute(), Importance::Normal); + } + Arc::new(RwLock::new(block)).into_strong() } macro_rules! get_property_id_from_nscsspropertyid { @@ -715,12 +710,9 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false) { Ok(parsed) => { - let mut declarations = Vec::new(); - parsed.expand(|d| declarations.push((d, Importance::Normal))); - Arc::new(RwLock::new(PropertyDeclarationBlock { - declarations: declarations, - important_count: 0, - })).into_strong() + let mut block = PropertyDeclarationBlock::new(); + parsed.expand(|d| block.push(d, Importance::Normal)); + Arc::new(RwLock::new(block)).into_strong() } Err(_) => RawServoDeclarationBlockStrong::null() } |