mirror of
https://github.com/servo/servo.git
synced 2025-06-21 07:38:59 +01:00
style: Refactor XBL rule matching to add another API to iterate the Stylists.
This will allow us to query the relevant stylists for invalidation. Bug: 1375969 Reviewed-By: TYLin MozReview-Commit-ID: EIIzbr2pEqN
This commit is contained in:
parent
9d1b26de1f
commit
02b61ed1a1
2 changed files with 54 additions and 39 deletions
|
@ -31,6 +31,7 @@ use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use stylearc::Arc;
|
use stylearc::Arc;
|
||||||
|
use stylist::Stylist;
|
||||||
use thread_state;
|
use thread_state;
|
||||||
|
|
||||||
pub use style_traits::UnsafeNode;
|
pub use style_traits::UnsafeNode;
|
||||||
|
@ -623,15 +624,34 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets declarations from XBL bindings from the element. Only gecko element could have this.
|
/// Implements Gecko's `nsBindingManager::WalkRules`.
|
||||||
fn get_declarations_from_xbl_bindings<V>(&self,
|
///
|
||||||
_pseudo_element: Option<&PseudoElement>,
|
/// Returns whether to cut off the inheritance.
|
||||||
_applicable_declarations: &mut V)
|
fn each_xbl_stylist<F>(&self, _: F) -> bool
|
||||||
-> bool
|
where
|
||||||
where V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock> {
|
F: FnMut(&Stylist),
|
||||||
|
{
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets declarations from XBL bindings from the element.
|
||||||
|
fn get_declarations_from_xbl_bindings<V>(
|
||||||
|
&self,
|
||||||
|
pseudo_element: Option<&PseudoElement>,
|
||||||
|
applicable_declarations: &mut V
|
||||||
|
) -> bool
|
||||||
|
where
|
||||||
|
V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock>
|
||||||
|
{
|
||||||
|
self.each_xbl_stylist(|stylist| {
|
||||||
|
stylist.push_applicable_declarations_as_xbl_only_stylist(
|
||||||
|
self,
|
||||||
|
pseudo_element,
|
||||||
|
applicable_declarations
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the current existing CSS transitions, by |property, end value| pairs in a HashMap.
|
/// Gets the current existing CSS transitions, by |property, end value| pairs in a HashMap.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
fn get_css_transitions_info(&self)
|
fn get_css_transitions_info(&self)
|
||||||
|
|
|
@ -80,7 +80,6 @@ use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingCo
|
||||||
use selectors::matching::{RelevantLinkStatus, VisitedHandlingMode};
|
use selectors::matching::{RelevantLinkStatus, VisitedHandlingMode};
|
||||||
use selectors::sink::Push;
|
use selectors::sink::Push;
|
||||||
use shared_lock::Locked;
|
use shared_lock::Locked;
|
||||||
use smallvec::VecLike;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -91,6 +90,7 @@ use std::ptr;
|
||||||
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
|
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
|
||||||
use stylearc::Arc;
|
use stylearc::Arc;
|
||||||
use stylesheets::UrlExtraData;
|
use stylesheets::UrlExtraData;
|
||||||
|
use stylist::Stylist;
|
||||||
|
|
||||||
/// A simple wrapper over a non-null Gecko node (`nsINode`) pointer.
|
/// A simple wrapper over a non-null Gecko node (`nsINode`) pointer.
|
||||||
///
|
///
|
||||||
|
@ -423,23 +423,21 @@ impl<'lb> GeckoXBLBinding<'lb> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Gecko's nsXBLBinding::WalkRules().
|
fn each_xbl_stylist<F>(self, mut f: &mut F)
|
||||||
fn get_declarations_for<E, V>(&self,
|
where
|
||||||
element: &E,
|
F: FnMut(&Stylist),
|
||||||
pseudo_element: Option<&PseudoElement>,
|
{
|
||||||
applicable_declarations: &mut V)
|
if let Some(base) = self.base_binding() {
|
||||||
where E: TElement,
|
base.each_xbl_stylist(f);
|
||||||
V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock> {
|
|
||||||
if let Some(base_binding) = self.base_binding() {
|
|
||||||
base_binding.get_declarations_for(element, pseudo_element, applicable_declarations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let raw_data = unsafe { bindings::Gecko_XBLBinding_GetRawServoStyleSet(self.0) };
|
let raw_data = unsafe {
|
||||||
|
bindings::Gecko_XBLBinding_GetRawServoStyleSet(self.0)
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(raw_data) = raw_data {
|
if let Some(raw_data) = raw_data {
|
||||||
let data = PerDocumentStyleData::from_ffi(&*raw_data).borrow();
|
let data = PerDocumentStyleData::from_ffi(&*raw_data).borrow();
|
||||||
data.stylist.push_applicable_declarations_as_xbl_only_stylist(element,
|
f(&data.stylist);
|
||||||
pseudo_element,
|
|
||||||
applicable_declarations);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1112,30 +1110,27 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
self.may_have_animations() && unsafe { Gecko_ElementHasCSSTransitions(self.0) }
|
self.may_have_animations() && unsafe { Gecko_ElementHasCSSTransitions(self.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Gecko's nsBindingManager::WalkRules(). Returns whether to cut off the
|
fn each_xbl_stylist<F>(&self, mut f: F) -> bool
|
||||||
// inheritance.
|
where
|
||||||
fn get_declarations_from_xbl_bindings<V>(&self,
|
F: FnMut(&Stylist),
|
||||||
pseudo_element: Option<&PseudoElement>,
|
{
|
||||||
applicable_declarations: &mut V)
|
// Walk the binding scope chain, starting with the binding attached to
|
||||||
-> bool
|
// our content, up till we run out of scopes or we get cut off.
|
||||||
where V: Push<ApplicableDeclarationBlock> + VecLike<ApplicableDeclarationBlock> {
|
//
|
||||||
// Walk the binding scope chain, starting with the binding attached to our content, up
|
// If we are a NAC pseudo-element, we want to get rules from our
|
||||||
// till we run out of scopes or we get cut off.
|
// rule_hash_target, that is, our originating element.
|
||||||
|
|
||||||
// If we are NAC, we want to get rules from our rule_hash_target.
|
|
||||||
let mut current = Some(self.rule_hash_target());
|
let mut current = Some(self.rule_hash_target());
|
||||||
|
|
||||||
while let Some(element) = current {
|
while let Some(element) = current {
|
||||||
if let Some(binding) = element.get_xbl_binding() {
|
if let Some(binding) = element.get_xbl_binding() {
|
||||||
binding.get_declarations_for(self,
|
binding.each_xbl_stylist(&mut f);
|
||||||
pseudo_element,
|
|
||||||
applicable_declarations);
|
|
||||||
|
|
||||||
// If we're not looking at our original element, allow the binding to cut off
|
// If we're not looking at our original element, allow the
|
||||||
// style inheritance.
|
// binding to cut off style inheritance.
|
||||||
if element != *self {
|
if element != *self {
|
||||||
if !binding.inherits_style() {
|
if !binding.inherits_style() {
|
||||||
// Go no further; we're not inheriting style from anything above here.
|
// Go no further; we're not inheriting style from
|
||||||
|
// anything above here.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1149,8 +1144,8 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
current = element.get_xbl_binding_parent();
|
current = element.get_xbl_binding_parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If current has something, this means we cut off inheritance at some point in the
|
// If current has something, this means we cut off inheritance at some
|
||||||
// loop.
|
// point in the loop.
|
||||||
current.is_some()
|
current.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue