mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
style: Process all the MediumFeatureChanges at the same time.
This avoids resetting the computed values all the time, and paves the way to avoid using a StyleSet on XBL bindings / Shadow DOM, which we should really really do because it's super overkill. There are some XBL bits that are kind of hacky, in particular the mStylistDirty, but they'll go away soon, since I want to redo how we store styles in XBL. The alternative, which was returning an array of indices or something was even more hacky I think. Bug: 1435939 Reviewed-by: xidorn MozReview-Commit-ID: 6tEl5gebXVF
This commit is contained in:
parent
9324feb994
commit
0907c21600
2 changed files with 58 additions and 43 deletions
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue