mirror of
https://github.com/servo/servo.git
synced 2025-08-12 08:55:32 +01:00
style: Make XBL / Shadow DOM use something more light-weight than a Stylist.
It's just a struct aggregating stylesheets + CascadeData, with a quirks_mode parameter because XBL sucks so bad. Bug: 1436059 Reviewed-by: xidorn MozReview-Commit-ID: 7q99tSNXo0K
This commit is contained in:
parent
a6113af873
commit
5e64cb3516
9 changed files with 225 additions and 44 deletions
|
@ -17,6 +17,7 @@ use std::iter;
|
|||
use std::mem;
|
||||
use std::ptr;
|
||||
use style::applicable_declarations::ApplicableDeclarationBlock;
|
||||
use style::author_styles::AuthorStyles;
|
||||
use style::context::{CascadeInputs, QuirksMode, SharedStyleContext, StyleContext};
|
||||
use style::context::ThreadLocalStyleContext;
|
||||
use style::counter_style;
|
||||
|
@ -51,6 +52,8 @@ use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSet
|
|||
use style::gecko_bindings::bindings::{RawServoStyleSheetContentsBorrowed, ServoComputedDataBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoStyleSheetContentsStrong, ServoStyleContextBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoAuthorStyles, RawServoAuthorStylesBorrowed};
|
||||
use style::gecko_bindings::bindings::{RawServoAuthorStylesBorrowedMut, RawServoAuthorStylesOwned};
|
||||
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
|
||||
use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut};
|
||||
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
|
||||
|
@ -1120,10 +1123,71 @@ pub extern "C" fn Servo_StyleSet_AppendStyleSheet(
|
|||
data.stylist.append_stylesheet(sheet, &guard);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_AuthorStyles_Create() -> *mut RawServoAuthorStyles {
|
||||
Box::into_raw(Box::new(AuthorStyles::<GeckoStyleSheet>::new())) as *mut _
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_AuthorStyles_Drop(
|
||||
styles: RawServoAuthorStylesOwned,
|
||||
) {
|
||||
let _ = styles.into_box::<AuthorStyles<_>>();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_AuthorStyles_AppendStyleSheet(
|
||||
styles: RawServoAuthorStylesBorrowedMut,
|
||||
sheet: *const ServoStyleSheet,
|
||||
) {
|
||||
let styles = AuthorStyles::<GeckoStyleSheet>::from_ffi_mut(styles);
|
||||
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
let sheet = GeckoStyleSheet::new(sheet);
|
||||
styles.stylesheets.append_stylesheet(None, sheet, &guard);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_AuthorStyles_ForceDirty(
|
||||
styles: RawServoAuthorStylesBorrowedMut,
|
||||
) {
|
||||
let styles = AuthorStyles::<GeckoStyleSheet>::from_ffi_mut(styles);
|
||||
styles.stylesheets.force_dirty();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_AuthorStyles_Flush(
|
||||
styles: RawServoAuthorStylesBorrowedMut,
|
||||
document_set: RawServoStyleSetBorrowed,
|
||||
) {
|
||||
let styles = AuthorStyles::<GeckoStyleSheet>::from_ffi_mut(styles);
|
||||
// Try to avoid the atomic borrow below if possible.
|
||||
if !styles.stylesheets.dirty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
|
||||
let document_data =
|
||||
PerDocumentStyleData::from_ffi(document_set).borrow();
|
||||
|
||||
let stylist = &document_data.stylist;
|
||||
|
||||
// TODO(emilio): This is going to need an element or something to do proper
|
||||
// invalidation in Shadow roots.
|
||||
styles.flush::<GeckoElement>(
|
||||
stylist.device(),
|
||||
stylist.quirks_mode(),
|
||||
&guard,
|
||||
);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_StyleSet_MediumFeaturesChanged(
|
||||
document_set: RawServoStyleSetBorrowed,
|
||||
non_document_sets: *const nsTArray<*mut structs::ServoStyleSet>,
|
||||
non_document_styles: *mut nsTArray<RawServoAuthorStylesBorrowedMut>,
|
||||
may_affect_default_style: bool,
|
||||
) -> structs::MediumFeaturesChangedResult {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
|
@ -1156,27 +1220,20 @@ pub unsafe extern "C" fn Servo_StyleSet_MediumFeaturesChanged(
|
|||
}
|
||||
|
||||
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 origins_changed =
|
||||
non_document_data.stylist.media_features_change_changed_style(
|
||||
&guards,
|
||||
for author_styles in &mut **non_document_styles {
|
||||
let author_styles =
|
||||
AuthorStyles::<GeckoStyleSheet>::from_ffi_mut(&mut *author_styles);
|
||||
let affected_style = author_styles.stylesheets.iter().any(|sheet| {
|
||||
!author_styles.data.media_feature_affected_matches(
|
||||
sheet,
|
||||
&guards.author,
|
||||
document_data.stylist.device(),
|
||||
);
|
||||
if !origins_changed.is_empty() {
|
||||
document_data.stylist.quirks_mode(),
|
||||
)
|
||||
});
|
||||
if affected_style {
|
||||
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;
|
||||
author_styles.stylesheets.force_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4930,19 +4987,25 @@ pub extern "C" fn Servo_ParseCounterStyleName(
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_InvalidateStyleForDocStateChanges(
|
||||
root: RawGeckoElementBorrowed,
|
||||
raw_style_sets: *const nsTArray<RawServoStyleSetBorrowed>,
|
||||
document_style: RawServoStyleSetBorrowed,
|
||||
non_document_styles: *const nsTArray<RawServoAuthorStylesBorrowed>,
|
||||
states_changed: u64,
|
||||
) {
|
||||
use style::invalidation::element::document_state::DocumentStateInvalidationProcessor;
|
||||
use style::invalidation::element::invalidator::TreeStyleInvalidator;
|
||||
|
||||
let mut borrows = SmallVec::<[_; 20]>::with_capacity((*raw_style_sets).len());
|
||||
for style_set in &**raw_style_sets {
|
||||
borrows.push(PerDocumentStyleData::from_ffi(*style_set).borrow());
|
||||
}
|
||||
let document_data = PerDocumentStyleData::from_ffi(document_style).borrow();
|
||||
|
||||
let iter =
|
||||
document_data.stylist.iter_origins().map(|(data, _origin)| data)
|
||||
.chain((*non_document_styles).iter().map(|author_styles| {
|
||||
let styles: &_ = AuthorStyles::<GeckoStyleSheet>::from_ffi(author_styles);
|
||||
&styles.data
|
||||
}));
|
||||
|
||||
let root = GeckoElement(root);
|
||||
let mut processor = DocumentStateInvalidationProcessor::new(
|
||||
borrows.iter().flat_map(|b| b.stylist.iter_origins().map(|(data, _origin)| data)),
|
||||
iter,
|
||||
DocumentState::from_bits_truncate(states_changed),
|
||||
root.as_node().owner_doc().quirks_mode(),
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue