aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-01-12 19:23:17 -0800
committerGitHub <noreply@github.com>2017-01-12 19:23:17 -0800
commitcc8bee8f8990e9bb23171fe65a259978749a9d2f (patch)
tree0feee01850dc9337d3bb8e915d1e2c2674550f68
parent6a04aea4a5a0da583e8cc7fc0f76c9bfea857538 (diff)
parente29cd8f53200480075a76fac2792a11df39c2a55 (diff)
downloadservo-cc8bee8f8990e9bb23171fe65a259978749a9d2f.tar.gz
servo-cc8bee8f8990e9bb23171fe65a259978749a9d2f.zip
Auto merge of #14997 - bholley:bug_1329845, r=heycam
stylo: Various crash fixes Corresponding gecko bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1329854 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14997) <!-- Reviewable:end -->
-rw-r--r--components/style/traversal.rs13
-rw-r--r--ports/geckolib/glue.rs20
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;