mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +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
91
components/style/author_styles.rs
Normal file
91
components/style/author_styles.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! A set of author stylesheets and their computed representation, such as the
|
||||
//! ones used for ShadowRoot and XBL.
|
||||
|
||||
use context::QuirksMode;
|
||||
use dom::TElement;
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
|
||||
use invalidation::media_queries::ToMediaListKey;
|
||||
use media_queries::Device;
|
||||
use shared_lock::SharedRwLockReadGuard;
|
||||
use stylesheet_set::AuthorStylesheetSet;
|
||||
use stylesheets::StylesheetInDocument;
|
||||
use stylist::CascadeData;
|
||||
|
||||
|
||||
/// A set of author stylesheets and their computed representation, such as the
|
||||
/// ones used for ShadowRoot and XBL.
|
||||
pub struct AuthorStyles<S>
|
||||
where
|
||||
S: StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
/// The sheet collection, which holds the sheet pointers, the invalidations,
|
||||
/// and all that stuff.
|
||||
pub stylesheets: AuthorStylesheetSet<S>,
|
||||
/// The actual cascade data computed from the stylesheets.
|
||||
pub data: CascadeData,
|
||||
/// The quirks mode of the last stylesheet flush, used because XBL sucks and
|
||||
/// we should really fix it, see bug 1406875.
|
||||
pub quirks_mode: QuirksMode,
|
||||
}
|
||||
|
||||
impl<S> AuthorStyles<S>
|
||||
where
|
||||
S: StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
/// Create an empty AuthorStyles.
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
stylesheets: AuthorStylesheetSet::new(),
|
||||
data: CascadeData::new(),
|
||||
quirks_mode: QuirksMode::NoQuirks,
|
||||
}
|
||||
}
|
||||
|
||||
/// Flush the pending sheet changes, updating `data` as appropriate.
|
||||
///
|
||||
/// TODO(emilio): Need a host element and a snapshot map to do invalidation
|
||||
/// properly.
|
||||
#[inline]
|
||||
pub fn flush<E>(
|
||||
&mut self,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
)
|
||||
where
|
||||
E: TElement,
|
||||
S: ToMediaListKey,
|
||||
{
|
||||
let flusher = self.stylesheets.flush::<E>(
|
||||
/* host = */ None,
|
||||
/* snapshot_map = */ None,
|
||||
);
|
||||
|
||||
if flusher.sheets.dirty() {
|
||||
self.quirks_mode = quirks_mode;
|
||||
}
|
||||
|
||||
// Ignore OOM.
|
||||
let _ = self.data.rebuild(
|
||||
device,
|
||||
quirks_mode,
|
||||
flusher.sheets,
|
||||
guard,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
unsafe impl HasFFI for AuthorStyles<::gecko::data::GeckoStyleSheet> {
|
||||
type FFIType = ::gecko_bindings::bindings::RawServoAuthorStyles;
|
||||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
unsafe impl HasSimpleFFI for AuthorStyles<::gecko::data::GeckoStyleSheet> {}
|
||||
#[cfg(feature = "gecko")]
|
||||
unsafe impl HasBoxFFI for AuthorStyles<::gecko::data::GeckoStyleSheet> {}
|
|
@ -754,7 +754,7 @@ pub trait TElement
|
|||
fn each_xbl_cascade_data<'a, F>(&self, _: F) -> bool
|
||||
where
|
||||
Self: 'a,
|
||||
F: FnMut(AtomicRef<'a, CascadeData>, QuirksMode),
|
||||
F: FnMut(&'a CascadeData, QuirksMode),
|
||||
{
|
||||
false
|
||||
}
|
||||
|
@ -766,7 +766,7 @@ pub trait TElement
|
|||
fn each_applicable_non_document_style_rule_data<'a, F>(&self, mut f: F) -> bool
|
||||
where
|
||||
Self: 'a,
|
||||
F: FnMut(AtomicRef<'a, CascadeData>, QuirksMode),
|
||||
F: FnMut(&'a CascadeData, QuirksMode),
|
||||
{
|
||||
let cut_off_inheritance = self.each_xbl_cascade_data(&mut f);
|
||||
|
||||
|
|
|
@ -17,13 +17,14 @@
|
|||
use CaseSensitivityExt;
|
||||
use app_units::Au;
|
||||
use applicable_declarations::ApplicableDeclarationBlock;
|
||||
use atomic_refcell::{AtomicRefCell, AtomicRef, AtomicRefMut};
|
||||
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
||||
use author_styles::AuthorStyles;
|
||||
use context::{QuirksMode, SharedStyleContext, PostAnimationTasks, UpdateAnimationsTasks};
|
||||
use data::ElementData;
|
||||
use dom::{LayoutIterator, NodeInfo, OpaqueNode, TElement, TDocument, TNode};
|
||||
use element_state::{ElementState, DocumentState};
|
||||
use font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult};
|
||||
use gecko::data::PerDocumentStyleData;
|
||||
use gecko::data::GeckoStyleSheet;
|
||||
use gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||
use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement};
|
||||
use gecko::snapshot_helpers;
|
||||
|
@ -431,20 +432,19 @@ impl<'lb> GeckoXBLBinding<'lb> {
|
|||
|
||||
fn each_xbl_cascade_data<F>(&self, f: &mut F)
|
||||
where
|
||||
F: FnMut(AtomicRef<'lb, CascadeData>, QuirksMode),
|
||||
F: FnMut(&'lb CascadeData, QuirksMode),
|
||||
{
|
||||
if let Some(base) = self.base_binding() {
|
||||
base.each_xbl_cascade_data(f);
|
||||
}
|
||||
|
||||
let raw_data = unsafe {
|
||||
bindings::Gecko_XBLBinding_GetRawServoStyleSet(self.0)
|
||||
let data = unsafe {
|
||||
bindings::Gecko_XBLBinding_GetRawServoStyles(self.0)
|
||||
};
|
||||
|
||||
if let Some(raw_data) = raw_data {
|
||||
let data = PerDocumentStyleData::from_ffi(&*raw_data).borrow();
|
||||
let quirks_mode = data.stylist.quirks_mode();
|
||||
f(AtomicRef::map(data, |d| d.stylist.author_cascade_data()), quirks_mode);
|
||||
if let Some(data) = data {
|
||||
let data: &'lb _ = AuthorStyles::<GeckoStyleSheet>::from_ffi(data);
|
||||
f(&data.data, data.quirks_mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1378,7 +1378,7 @@ impl<'le> TElement for GeckoElement<'le> {
|
|||
fn each_xbl_cascade_data<'a, F>(&self, mut f: F) -> bool
|
||||
where
|
||||
'le: 'a,
|
||||
F: FnMut(AtomicRef<'a, CascadeData>, QuirksMode),
|
||||
F: FnMut(&'a CascadeData, QuirksMode),
|
||||
{
|
||||
// Walk the binding scope chain, starting with the binding attached to
|
||||
// our content, up till we run out of scopes or we get cut off.
|
||||
|
|
|
@ -36,6 +36,7 @@ impl<T> nsTArray<T> {
|
|||
debug_assert!(!self.mBuffer.is_null());
|
||||
unsafe { mem::transmute(self.mBuffer) }
|
||||
}
|
||||
|
||||
// unsafe, since header may be in shared static or something
|
||||
unsafe fn header_mut<'a>(&'a mut self) -> &'a mut nsTArrayHeader {
|
||||
debug_assert!(!self.mBuffer.is_null());
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
//! changes.
|
||||
|
||||
use Atom;
|
||||
use atomic_refcell::AtomicRef;
|
||||
use context::{QuirksMode, SharedStyleContext};
|
||||
use data::ElementData;
|
||||
use dom::TElement;
|
||||
|
@ -57,7 +56,7 @@ where
|
|||
/// changes.
|
||||
pub struct StateAndAttrInvalidationProcessor<'a, 'b: 'a, E: TElement> {
|
||||
shared_context: &'a SharedStyleContext<'b>,
|
||||
shadow_rule_datas: &'a [(AtomicRef<'b, CascadeData>, QuirksMode)],
|
||||
shadow_rule_datas: &'a [(&'b CascadeData, QuirksMode)],
|
||||
cut_off_inheritance: bool,
|
||||
element: E,
|
||||
data: &'a mut ElementData,
|
||||
|
@ -68,7 +67,7 @@ impl<'a, 'b: 'a, E: TElement> StateAndAttrInvalidationProcessor<'a, 'b, E> {
|
|||
/// Creates a new StateAndAttrInvalidationProcessor.
|
||||
pub fn new(
|
||||
shared_context: &'a SharedStyleContext<'b>,
|
||||
shadow_rule_datas: &'a [(AtomicRef<'b, CascadeData>, QuirksMode)],
|
||||
shadow_rule_datas: &'a [(&'b CascadeData, QuirksMode)],
|
||||
cut_off_inheritance: bool,
|
||||
element: E,
|
||||
data: &'a mut ElementData,
|
||||
|
|
|
@ -87,6 +87,7 @@ mod macros;
|
|||
pub mod applicable_declarations;
|
||||
#[allow(missing_docs)] // TODO.
|
||||
#[cfg(feature = "servo")] pub mod attr;
|
||||
pub mod author_styles;
|
||||
pub mod bezier;
|
||||
pub mod bloom;
|
||||
pub mod context;
|
||||
|
|
|
@ -583,6 +583,20 @@ impl<S> AuthorStylesheetSet<S>
|
|||
where
|
||||
S: StylesheetInDocument + PartialEq + 'static,
|
||||
{
|
||||
/// Create a new empty AuthorStylesheetSet.
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
collection: Default::default(),
|
||||
invalidations: StylesheetInvalidationSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether anything has changed since the last time this was flushed.
|
||||
pub fn dirty(&self) -> bool {
|
||||
self.collection.dirty
|
||||
}
|
||||
|
||||
fn collection_for(
|
||||
&mut self,
|
||||
_sheet: &S,
|
||||
|
@ -593,6 +607,17 @@ where
|
|||
|
||||
sheet_set_methods!("AuthorStylesheetSet");
|
||||
|
||||
/// Iterate over the list of stylesheets.
|
||||
pub fn iter(&self) -> StylesheetCollectionIterator<S> {
|
||||
self.collection.iter()
|
||||
}
|
||||
|
||||
/// Mark the sheet set dirty, as appropriate.
|
||||
pub fn force_dirty(&mut self) {
|
||||
self.invalidations.invalidate_fully();
|
||||
self.collection.set_data_validity_at_least(DataValidity::FullyInvalid);
|
||||
}
|
||||
|
||||
/// Flush the stylesheets for this author set.
|
||||
///
|
||||
/// `host` is the root of the affected subtree, like the shadow host, for
|
||||
|
|
|
@ -1983,7 +1983,8 @@ pub struct CascadeData {
|
|||
}
|
||||
|
||||
impl CascadeData {
|
||||
fn new() -> Self {
|
||||
/// Creates an empty `CascadeData`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
normal_rules: ElementAndPseudoRules::default(),
|
||||
slotted_rules: None,
|
||||
|
@ -2005,7 +2006,7 @@ impl CascadeData {
|
|||
|
||||
/// Rebuild the cascade data from a given SheetCollection, incrementally if
|
||||
/// possible.
|
||||
fn rebuild<'a, S>(
|
||||
pub fn rebuild<'a, S>(
|
||||
&mut self,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
|
@ -2281,7 +2282,7 @@ impl CascadeData {
|
|||
|
||||
/// Returns whether all the media-feature affected values matched before and
|
||||
/// match now in the given stylesheet.
|
||||
fn media_feature_affected_matches<S>(
|
||||
pub fn media_feature_affected_matches<S>(
|
||||
&self,
|
||||
stylesheet: &S,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue