diff options
-rw-r--r-- | components/style/traversal.rs | 13 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 20 |
2 files changed, 26 insertions, 7 deletions
diff --git a/components/style/traversal.rs b/components/style/traversal.rs index af943c50336..694a4aff53f 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -418,6 +418,19 @@ pub fn recalc_style_at<E, D>(traversal: &D, (element.has_dirty_descendants() || !propagated_hint.is_empty() || inherited_style_changed) { preprocess_children(traversal, element, propagated_hint, inherited_style_changed); } + + // Make sure the dirty descendants bit is not set for the root of a + // display:none subtree, even if the style didn't change (since, if + // the style did change, we'd have already cleared it in compute_style). + // + // This keeps the tree in a valid state without requiring the DOM to + // check display:none on the parent when inserting new children (which + // can be moderately expensive). Instead, DOM implementations can + // unconditionally set the dirty descendants bit on any styled parent, + // and let the traversal sort it out. + if data.styles().is_display_none() { + unsafe { element.unset_dirty_descendants(); } + } } // Computes style, returning true if the inherited styles changed for this diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index fb2faa5ae67..623a6d35365 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -874,11 +874,15 @@ unsafe fn maybe_restyle<'a>(data: &'a mut AtomicRefMut<ElementData>, element: Ge pub extern "C" fn Servo_Element_GetSnapshot(element: RawGeckoElementBorrowed) -> *mut structs::ServoElementSnapshot { let element = GeckoElement(element); - let mut data = unsafe { element.ensure_data().borrow_mut() }; - let snapshot = if let Some(restyle_data) = unsafe { maybe_restyle(&mut data, element) } { - restyle_data.snapshot.ensure(|| element.create_snapshot()).borrow_mut_raw() - } else { - ptr::null_mut() + let snapshot = match element.mutate_data() { + None => ptr::null_mut(), + Some(mut data) => { + if let Some(restyle_data) = unsafe { maybe_restyle(&mut data, element) } { + restyle_data.snapshot.ensure(|| element.create_snapshot()).borrow_mut_raw() + } else { + ptr::null_mut() + } + }, }; debug!("Servo_Element_GetSnapshot: {:?}: {:?}", element, snapshot); @@ -891,11 +895,13 @@ pub extern "C" fn Servo_NoteExplicitHints(element: RawGeckoElementBorrowed, change_hint: nsChangeHint) { let element = GeckoElement(element); let damage = GeckoRestyleDamage::new(change_hint); - let mut data = unsafe { element.ensure_data().borrow_mut() }; debug!("Servo_NoteExplicitHints: {:?}, restyle_hint={:?}, change_hint={:?}", element, restyle_hint, change_hint); - if let Some(restyle_data) = unsafe { maybe_restyle(&mut data, element) } { + let mut maybe_data = element.mutate_data(); + let maybe_restyle_data = + maybe_data.as_mut().and_then(|d| unsafe { maybe_restyle(d, element) }); + if let Some(restyle_data) = maybe_restyle_data { let restyle_hint: RestyleHint = restyle_hint.into(); restyle_data.hint.insert(&restyle_hint.into()); restyle_data.damage |= damage; |