diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index 579e82f0d8e..11bc35897ac 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -633,6 +633,10 @@ extern "C" { extern "C" { pub fn Gecko_UnsetNodeFlags(node: RawGeckoNodeBorrowed, flags: u32); } +extern "C" { + pub fn Gecko_SetOwnerDocumentNeedsStyleFlush(element: + RawGeckoElementBorrowed); +} extern "C" { pub fn Gecko_GetStyleContext(node: RawGeckoNodeBorrowed, aPseudoTagOrNull: *mut nsIAtom) @@ -1125,10 +1129,6 @@ extern "C" { extern "C" { pub fn Servo_Element_ClearData(node: RawGeckoElementBorrowed); } -extern "C" { - pub fn Servo_Element_ShouldTraverse(node: RawGeckoElementBorrowed) - -> bool; -} extern "C" { pub fn Servo_StyleSheet_Empty(parsing_mode: SheetParsingMode) -> RawServoStyleSheetStrong; @@ -1472,7 +1472,7 @@ extern "C" { extern "C" { pub fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, set: RawServoStyleSetBorrowed, - root_behavior: TraversalRootBehavior); + root_behavior: TraversalRootBehavior) -> bool; } extern "C" { pub fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed); diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index ce1e1d123ca..d15fefc6bdb 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -28,6 +28,7 @@ use style::gecko::selector_parser::{SelectorImpl, PseudoElement}; use style::gecko::traversal::RecalcStyleOnly; use style::gecko::wrapper::DUMMY_BASE_URL; use style::gecko::wrapper::GeckoElement; +use style::gecko_bindings::bindings; use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong}; use style::gecko_bindings::bindings::{RawServoStyleRuleBorrowed, RawServoStyleRuleStrong}; use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned}; @@ -163,14 +164,19 @@ fn traverse_subtree(element: GeckoElement, raw_data: RawServoStyleSetBorrowed, } } +/// Traverses the subtree rooted at `root` for restyling. Returns whether a +/// Gecko post-traversal (to perform lazy frame construction, or consume any +/// RestyleData, or drop any ElementData) is required. #[no_mangle] pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, raw_data: RawServoStyleSetBorrowed, - behavior: structs::TraversalRootBehavior) -> () { + behavior: structs::TraversalRootBehavior) -> bool { let element = GeckoElement(root); debug!("Servo_TraverseSubtree: {:?}", element); traverse_subtree(element, raw_data, behavior == structs::TraversalRootBehavior::UnstyledChildrenOnly); + + element.has_dirty_descendants() || element.mutate_data().unwrap().has_restyle() } #[no_mangle] @@ -341,24 +347,6 @@ pub extern "C" fn Servo_Element_ClearData(element: RawGeckoElementBorrowed) -> ( GeckoElement(element).clear_data(); } -#[no_mangle] -pub extern "C" fn Servo_Element_ShouldTraverse(element: RawGeckoElementBorrowed) -> bool { - let element = GeckoElement(element); - debug_assert!(!element.has_dirty_descendants(), - "only call Servo_Element_ShouldTraverse if you know the element \ - does not have dirty descendants"); - let result = match element.borrow_data() { - // Note that we check for has_restyle here rather than has_current_styles, - // because we also want the traversal code to trigger if there's restyle - // damage. We really only need the Gecko post-traversal in that case, so - // the servo traversal will be a no-op, but it's cheap enough that we - // don't bother distinguishing the two cases. - Some(d) => !d.has_styles() || d.has_restyle(), - None => true, - }; - result -} - #[no_mangle] pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyleSheetStrong { let url = ServoUrl::parse("about:blank").unwrap(); @@ -1077,6 +1065,7 @@ unsafe fn maybe_restyle<'a>(data: &'a mut AtomicRefMut, element: Ge if curr.has_dirty_descendants() { break; } curr.set_dirty_descendants(); } + bindings::Gecko_SetOwnerDocumentNeedsStyleFlush(element.0); // Ensure and return the RestyleData. Some(data.ensure_restyle())