diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 4abe0aca207..ac465b2fc95 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1089,9 +1089,6 @@ impl Stylist { /// /// Also, the device that arrives here may need to take the viewport rules /// into account. - /// - /// For Gecko, this is called when XBL bindings are used by different - /// documents. pub fn set_device( &mut self, mut device: Device, @@ -1119,14 +1116,22 @@ impl Stylist { } self.device = device; - self.media_features_change_changed_style(guards) + self.media_features_change_changed_style(guards, &self.device) } /// Returns whether, given a media feature change, any previously-applicable - /// style has become non-applicable, or vice-versa for each origin. + /// style has become non-applicable, or vice-versa for each origin, using + /// `device`. + /// + /// Passing `device` is needed because this is used for XBL in Gecko, which + /// can be stale in various ways, so we need to pass the device of the + /// document itself, which is what is kept up-to-date. + /// + /// Arguably XBL should use something more lightweight than a Stylist. pub fn media_features_change_changed_style( &self, guards: &StylesheetGuards, + device: &Device, ) -> OriginSet { debug!("Stylist::media_features_change_changed_style"); @@ -1145,7 +1150,7 @@ impl Stylist { let affected_changed = !origin_cascade_data.media_feature_affected_matches( stylesheet, guard, - &self.device, + device, self.quirks_mode ); diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 83c8613b000..ae33eec8241 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -120,7 +120,7 @@ use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong}; use style::gecko_bindings::sugar::refptr::RefPtr; use style::gecko_properties; use style::invalidation::element::restyle_hints; -use style::media_queries::{Device, MediaList, parse_media_query_list}; +use style::media_queries::{MediaList, parse_media_query_list}; use style::parser::{Parse, ParserContext, self}; use style::properties::{ComputedValues, DeclarationSource, Importance}; use style::properties::{LonghandId, LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, PropertyId}; @@ -1122,10 +1122,10 @@ pub extern "C" fn Servo_StyleSet_AppendStyleSheet( #[no_mangle] pub unsafe extern "C" fn Servo_StyleSet_MediumFeaturesChanged( - raw_data: RawServoStyleSetBorrowed, - viewport_units_used: *mut bool, + document_set: RawServoStyleSetBorrowed, + non_document_sets: *const nsTArray<*mut structs::ServoStyleSet>, may_affect_default_style: bool, -) -> u8 { +) -> structs::MediumFeaturesChangedResult { let global_style_data = &*GLOBAL_STYLE_DATA; let guard = global_style_data.shared_lock.read(); @@ -1136,48 +1136,58 @@ pub unsafe extern "C" fn Servo_StyleSet_MediumFeaturesChanged( // // We need to ensure the default computed values are up to date though, // because those can influence the result of media query evaluation. - // - // FIXME(emilio, bug 1369984): do the computation conditionally, to do it - // less often. - let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); + let mut document_data = + PerDocumentStyleData::from_ffi(document_set).borrow_mut(); - *viewport_units_used = data.stylist.device().used_viewport_size(); if may_affect_default_style { - // FIXME(emilio): It's a shame we do this too for XBL stuff, but we need - // to right now to evaluate relative units in media queries correctly. - // - // We should instead just pass the `Device` reference from the master - // stylist, but that looked kinda gross... Maybe it's not actually. - data.stylist.device_mut().reset_computed_values(); + document_data.stylist.device_mut().reset_computed_values(); } let guards = StylesheetGuards::same(&guard); + let origins_in_which_rules_changed = - data.stylist.media_features_change_changed_style(&guards); + document_data.stylist.media_features_change_changed_style( + &guards, + document_data.stylist.device(), + ); - // We'd like to return `OriginFlags` here, but bindgen bitfield enums don't - // work as return values with the Linux 32-bit ABI at the moment because - // they wrap the value in a struct, so for now just unwrap it. - OriginFlags::from(origins_in_which_rules_changed).0 -} + let affects_document_rules = !origins_in_which_rules_changed.is_empty(); + if affects_document_rules { + document_data.stylist.force_stylesheet_origins_dirty(origins_in_which_rules_changed); + } -#[no_mangle] -pub extern "C" fn Servo_StyleSet_SetDevice( - raw_data: RawServoStyleSetBorrowed, - pres_context: RawGeckoPresContextOwned -) -> u8 { - let global_style_data = &*GLOBAL_STYLE_DATA; - let guard = global_style_data.shared_lock.read(); + let mut affects_non_document_rules = false; + for non_document_style_set in &**non_document_sets { + let non_document_data = &*(**non_document_style_set).mRawSet.mPtr; + let non_document_data = + mem::transmute::<&structs::RawServoStyleSet, &bindings::RawServoStyleSet>(non_document_data); + let mut non_document_data = + PerDocumentStyleData::from_ffi(non_document_data).borrow_mut(); - let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); - let device = Device::new(pres_context); - let guards = StylesheetGuards::same(&guard); - let origins_in_which_rules_changed = - data.stylist.set_device(device, &guards); + let origins_changed = + non_document_data.stylist.media_features_change_changed_style( + &guards, + document_data.stylist.device(), + ); + if !origins_changed.is_empty() { + affects_non_document_rules = true; + // XBL stylesets are rebuilt entirely, so we need to mark them + // dirty from here instead of going through the stylist + // force_origin_dirty stuff, which would be useless. + // + // FIXME(emilio, bug 1436059): This is super-hacky, make XBL / + // Shadow DOM not use a style set at all. + (**non_document_style_set).mStylistState = structs::StylistState_StyleSheetsDirty; + } + } - // We'd like to return `OriginFlags` here, but bindgen bitfield enums don't - // work as return values with the Linux 32-bit ABI at the moment because - // they wrap the value in a struct, so for now just unwrap it. - OriginFlags::from(origins_in_which_rules_changed).0 + let uses_viewport_units = + document_data.stylist.device().used_viewport_size(); + + structs::MediumFeaturesChangedResult { + mAffectsDocumentRules: affects_document_rules, + mAffectsNonDocumentRules: affects_non_document_rules, + mUsesViewportUnits: uses_viewport_units, + } } #[no_mangle]