Bug 1466963: Add a before-change callback to remove_property. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 05 Jun 2018 21:13:48 +0200
changeset 804468 be95a8e48f6b5c5e872d6821fce7fb20b3c164c5
parent 804467 f714a8062c5740e2d5701e2cc33db0eb293ac6e9
child 804469 d4eedc3d0727bc30c556d01c890d13f79f5d50f4
push id112373
push userbmo:emilio@crisal.io
push dateTue, 05 Jun 2018 22:12:13 +0000
reviewersxidorn
bugs1466963
milestone62.0a1
Bug 1466963: Add a before-change callback to remove_property. r?xidorn MozReview-Commit-ID: 4vyN9iLT7e3
servo/components/style/properties/declaration_block.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/properties/declaration_block.rs
+++ b/servo/components/style/properties/declaration_block.rs
@@ -562,41 +562,53 @@ impl PropertyDeclarationBlock {
         self.declarations.push(declaration);
         self.declarations_importance.push(importance.important());
         true
     }
 
     /// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty>
     ///
     /// Returns whether any declaration was actually removed.
-    pub fn remove_property(&mut self, property: &PropertyId) -> bool {
+    pub fn remove_property<C>(
+        &mut self,
+        property: &PropertyId,
+        mut before_change_callback: C,
+    ) -> bool
+    where
+        C: FnMut(&Self),
+    {
         let longhand_id = property.longhand_id();
         if let Some(id) = longhand_id {
             if !self.longhands.contains(id) {
                 return false
             }
         }
         let mut removed_at_least_one = false;
-        let longhands = &mut self.longhands;
-        let declarations_importance = &mut self.declarations_importance;
         let mut i = 0;
-        self.declarations.retain(|declaration| {
-            let id = declaration.id();
-            let remove = id.is_or_is_longhand_of(property);
-            if remove {
+        let mut len = self.len();
+        while i < len {
+            {
+                let id = self.declarations[i].id();
+                if !id.is_or_is_longhand_of(property) {
+                    i += 1;
+                    continue;
+                }
+
+                if !removed_at_least_one {
+                    before_change_callback(&*self);
+                }
                 removed_at_least_one = true;
                 if let PropertyDeclarationId::Longhand(id) = id {
-                    longhands.remove(id);
+                    self.longhands.remove(id);
                 }
-                declarations_importance.remove(i);
-            } else {
-                i += 1;
+                self.declarations_importance.remove(i);
             }
-            !remove
-        });
+            self.declarations.remove(i);
+            len -= 1;
+        }
 
         if longhand_id.is_some() {
             debug_assert!(removed_at_least_one);
         }
         removed_at_least_one
     }
 
     /// Take a declaration block known to contain a single property and serialize it.
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -3609,17 +3609,17 @@ pub unsafe extern "C" fn Servo_Declarati
     )
 }
 
 fn remove_property(
     declarations: RawServoDeclarationBlockBorrowed,
     property_id: PropertyId
 ) -> bool {
     write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
-        decls.remove_property(&property_id)
+        decls.remove_property(&property_id, |_| {})
     })
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn Servo_DeclarationBlock_RemoveProperty(
     declarations: RawServoDeclarationBlockBorrowed,
     property: *const nsACString,
 ) -> bool {