diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 18aad5a2c20..9905d3a9eab 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -211,41 +211,32 @@ unsafe fn dummy_url_data() -> &'static RefPtr { RefPtr::from_ptr_ref(&DUMMY_URL_DATA) } -fn create_shared_context<'a>(global_style_data: &GlobalStyleData, - guard: &'a SharedRwLockReadGuard, - per_doc_data: &'a PerDocumentStyleDataImpl, - traversal_flags: TraversalFlags, - snapshot_map: &'a ServoElementSnapshotTable) - -> SharedStyleContext<'a> { +fn create_shared_context<'a>( + global_style_data: &GlobalStyleData, + guard: &'a SharedRwLockReadGuard, + per_doc_data: &'a PerDocumentStyleDataImpl, + traversal_flags: TraversalFlags, + snapshot_map: &'a ServoElementSnapshotTable, +) -> SharedStyleContext<'a> { SharedStyleContext { stylist: &per_doc_data.stylist, visited_styles_enabled: per_doc_data.visited_styles_enabled(), options: global_style_data.options.clone(), guards: StylesheetGuards::same(guard), timer: Timer::new(), - traversal_flags: traversal_flags, - snapshot_map: snapshot_map, + traversal_flags, + snapshot_map, } } -fn traverse_subtree(element: GeckoElement, - raw_data: RawServoStyleSetBorrowed, - traversal_flags: TraversalFlags, - snapshots: &ServoElementSnapshotTable) { - // When new content is inserted in a display:none subtree, we will call into - // servo to try to style it. Detect that here and bail out. - if let Some(parent) = element.traversal_parent() { - if parent.borrow_data().map_or(true, |d| d.styles.is_display_none()) { - debug!("{:?} has unstyled parent {:?} - ignoring call to traverse_subtree", element, parent); - return; - } - } - - let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); - debug_assert!(!per_doc_data.stylist.stylesheets_have_changed()); - - let global_style_data = &*GLOBAL_STYLE_DATA; - let guard = global_style_data.shared_lock.read(); +fn traverse_subtree( + element: GeckoElement, + global_style_data: &GlobalStyleData, + per_doc_data: &PerDocumentStyleDataImpl, + guard: &SharedRwLockReadGuard, + traversal_flags: TraversalFlags, + snapshots: &ServoElementSnapshotTable, +) { let shared_style_context = create_shared_context( &global_style_data, &guard, @@ -295,23 +286,50 @@ pub extern "C" fn Servo_TraverseSubtree( debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags); debug!("{:?}", ShowSubtreeData(element.as_node())); + if cfg!(debug_assertions) { + if let Some(parent) = element.traversal_parent() { + let data = + parent.borrow_data().expect("Styling element with unstyled parent"); + assert!( + !data.styles.is_display_none(), + "Styling element with display: none parent" + ); + } + } + let needs_animation_only_restyle = element.has_animation_only_dirty_descendants() || element.has_animation_restyle_hints(); + let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow(); + debug_assert!(!per_doc_data.stylist.stylesheets_have_changed()); + + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + + let was_initial_style = element.get_data().is_none(); + if needs_animation_only_restyle { debug!("Servo_TraverseSubtree doing animation-only restyle (aodd={})", element.has_animation_only_dirty_descendants()); - traverse_subtree(element, - raw_data, - traversal_flags | TraversalFlags::AnimationOnly, - unsafe { &*snapshots }); + traverse_subtree( + element, + &global_style_data, + &per_doc_data, + &guard, + traversal_flags | TraversalFlags::AnimationOnly, + unsafe { &*snapshots }, + ); } - traverse_subtree(element, - raw_data, - traversal_flags, - unsafe { &*snapshots }); + traverse_subtree( + element, + &global_style_data, + &per_doc_data, + &guard, + traversal_flags, + unsafe { &*snapshots }, + ); debug!("Servo_TraverseSubtree complete (dd={}, aodd={}, lfcd={}, lfc={}, data={:?})", element.has_dirty_descendants(), @@ -320,9 +338,14 @@ pub extern "C" fn Servo_TraverseSubtree( element.needs_frame(), element.borrow_data().unwrap()); - let element_was_restyled = - element.borrow_data().unwrap().contains_restyle_data(); - element_was_restyled + if was_initial_style { + debug_assert!(!element.borrow_data().unwrap().contains_restyle_data()); + false + } else { + let element_was_restyled = + element.borrow_data().unwrap().contains_restyle_data(); + element_was_restyled + } } /// Checks whether the rule tree has crossed its threshold for unused nodes, and @@ -740,10 +763,10 @@ pub extern "C" fn Servo_AnimationValue_Transform( } #[no_mangle] -pub extern "C" fn Servo_AnimationValue_DeepEqual(this: RawServoAnimationValueBorrowed, - other: RawServoAnimationValueBorrowed) - -> bool -{ +pub extern "C" fn Servo_AnimationValue_DeepEqual( + this: RawServoAnimationValueBorrowed, + other: RawServoAnimationValueBorrowed, +) -> bool { let this_value = AnimationValue::as_arc(&this); let other_value = AnimationValue::as_arc(&other); this_value == other_value