mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Run rustfmt on selectors, servo_arc, and style.
This was generated with: ./mach cargo fmt --package selectors && ./mach cargo fmt --package servo_arc && ./mach cargo fmt --package style Using rustfmt 0.4.1-nightly (a4462d1 2018-03-26)
This commit is contained in:
parent
f7ae1a37e3
commit
c99bcdd4b8
181 changed files with 9981 additions and 7933 deletions
|
@ -42,11 +42,7 @@ pub struct DocumentStateInvalidationProcessor<'a, E: TElement, I> {
|
|||
impl<'a, E: TElement, I> DocumentStateInvalidationProcessor<'a, E, I> {
|
||||
/// Creates a new DocumentStateInvalidationProcessor.
|
||||
#[inline]
|
||||
pub fn new(
|
||||
rules: I,
|
||||
document_states_changed: DocumentState,
|
||||
quirks_mode: QuirksMode,
|
||||
) -> Self {
|
||||
pub fn new(rules: I, document_states_changed: DocumentState, quirks_mode: QuirksMode) -> Self {
|
||||
let mut matching_context = MatchingContext::new_for_visited(
|
||||
MatchingMode::Normal,
|
||||
None,
|
||||
|
@ -59,7 +55,11 @@ impl<'a, E: TElement, I> DocumentStateInvalidationProcessor<'a, E, I> {
|
|||
document_state: document_states_changed,
|
||||
};
|
||||
|
||||
Self { rules, document_states_changed, matching_context }
|
||||
Self {
|
||||
rules,
|
||||
document_states_changed,
|
||||
matching_context,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ use std::fmt;
|
|||
/// still need to take the ElementWrapper approach for attribute-dependent
|
||||
/// style. So we do it the same both ways for now to reduce complexity, but it's
|
||||
/// worth measuring the performance impact (if any) of the mStateMask approach.
|
||||
pub trait ElementSnapshot : Sized {
|
||||
pub trait ElementSnapshot: Sized {
|
||||
/// The state of the snapshot, if any.
|
||||
fn state(&self) -> Option<ElementState>;
|
||||
|
||||
|
@ -158,7 +158,7 @@ where
|
|||
_setter: &mut F,
|
||||
) -> bool
|
||||
where
|
||||
F: FnMut(&Self, ElementSelectorFlags),
|
||||
F: FnMut(&Self, ElementSelectorFlags),
|
||||
{
|
||||
// Some pseudo-classes need special handling to evaluate them against
|
||||
// the snapshot.
|
||||
|
@ -167,11 +167,11 @@ where
|
|||
NonTSPseudoClass::MozAny(ref selectors) => {
|
||||
use selectors::matching::matches_complex_selector;
|
||||
return context.nest(|context| {
|
||||
selectors.iter().any(|s| {
|
||||
matches_complex_selector(s.iter(), self, context, _setter)
|
||||
})
|
||||
selectors
|
||||
.iter()
|
||||
.any(|s| matches_complex_selector(s.iter(), self, context, _setter))
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// :dir is implemented in terms of state flags, but which state flag
|
||||
// it maps to depends on the argument to :dir. That means we can't
|
||||
|
@ -194,7 +194,7 @@ where
|
|||
None => self.element.state(),
|
||||
};
|
||||
return state.contains(selector_flag);
|
||||
}
|
||||
},
|
||||
|
||||
// For :link and :visited, we don't actually want to test the
|
||||
// element state directly.
|
||||
|
@ -203,10 +203,10 @@ where
|
|||
// match.
|
||||
NonTSPseudoClass::Link => {
|
||||
return self.is_link() && context.visited_handling().matches_unvisited()
|
||||
}
|
||||
},
|
||||
NonTSPseudoClass::Visited => {
|
||||
return self.is_link() && context.visited_handling().matches_visited()
|
||||
}
|
||||
},
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
NonTSPseudoClass::MozTableBorderNonzero => {
|
||||
|
@ -215,7 +215,7 @@ where
|
|||
return snapshot.mIsTableBorderNonzero();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
NonTSPseudoClass::MozBrowserFrame => {
|
||||
|
@ -224,34 +224,27 @@ where
|
|||
return snapshot.mIsMozBrowserFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// :lang() needs to match using the closest ancestor xml:lang="" or
|
||||
// lang="" attribtue from snapshots.
|
||||
NonTSPseudoClass::Lang(ref lang_arg) => {
|
||||
return self.element.match_element_lang(Some(self.get_lang()), lang_arg);
|
||||
}
|
||||
return self.element
|
||||
.match_element_lang(Some(self.get_lang()), lang_arg);
|
||||
},
|
||||
|
||||
_ => {}
|
||||
_ => {},
|
||||
}
|
||||
|
||||
let flag = pseudo_class.state_flag();
|
||||
if flag.is_empty() {
|
||||
return self.element.match_non_ts_pseudo_class(
|
||||
pseudo_class,
|
||||
context,
|
||||
&mut |_, _| {},
|
||||
)
|
||||
return self.element
|
||||
.match_non_ts_pseudo_class(pseudo_class, context, &mut |_, _| {});
|
||||
}
|
||||
match self.snapshot().and_then(|s| s.state()) {
|
||||
Some(snapshot_state) => snapshot_state.intersects(flag),
|
||||
None => {
|
||||
self.element.match_non_ts_pseudo_class(
|
||||
pseudo_class,
|
||||
context,
|
||||
&mut |_, _| {},
|
||||
)
|
||||
}
|
||||
None => self.element
|
||||
.match_non_ts_pseudo_class(pseudo_class, context, &mut |_, _| {}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,26 +327,24 @@ where
|
|||
match self.snapshot() {
|
||||
Some(snapshot) if snapshot.has_attrs() => {
|
||||
snapshot.attr_matches(ns, local_name, operation)
|
||||
}
|
||||
_ => self.element.attr_matches(ns, local_name, operation)
|
||||
},
|
||||
_ => self.element.attr_matches(ns, local_name, operation),
|
||||
}
|
||||
}
|
||||
|
||||
fn has_id(&self, id: &Atom, case_sensitivity: CaseSensitivity) -> bool {
|
||||
match self.snapshot() {
|
||||
Some(snapshot) if snapshot.has_attrs() => {
|
||||
snapshot.id_attr().map_or(false, |atom| case_sensitivity.eq_atom(&atom, id))
|
||||
}
|
||||
_ => self.element.has_id(id, case_sensitivity)
|
||||
Some(snapshot) if snapshot.has_attrs() => snapshot
|
||||
.id_attr()
|
||||
.map_or(false, |atom| case_sensitivity.eq_atom(&atom, id)),
|
||||
_ => self.element.has_id(id, case_sensitivity),
|
||||
}
|
||||
}
|
||||
|
||||
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
|
||||
match self.snapshot() {
|
||||
Some(snapshot) if snapshot.has_attrs() => {
|
||||
snapshot.has_class(name, case_sensitivity)
|
||||
}
|
||||
_ => self.element.has_class(name, case_sensitivity)
|
||||
Some(snapshot) if snapshot.has_attrs() => snapshot.has_class(name, case_sensitivity),
|
||||
_ => self.element.has_class(name, case_sensitivity),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,12 +357,14 @@ where
|
|||
}
|
||||
|
||||
fn pseudo_element_originating_element(&self) -> Option<Self> {
|
||||
self.element.pseudo_element_originating_element()
|
||||
self.element
|
||||
.pseudo_element_originating_element()
|
||||
.map(|e| ElementWrapper::new(e, self.snapshot_map))
|
||||
}
|
||||
|
||||
fn assigned_slot(&self) -> Option<Self> {
|
||||
self.element.assigned_slot()
|
||||
self.element
|
||||
.assigned_slot()
|
||||
.map(|e| ElementWrapper::new(e, self.snapshot_map))
|
||||
}
|
||||
|
||||
|
|
|
@ -92,17 +92,22 @@ impl Dependency {
|
|||
return None;
|
||||
}
|
||||
|
||||
Some(self.selector.combinator_at_match_order(self.selector_offset - 1))
|
||||
Some(
|
||||
self.selector
|
||||
.combinator_at_match_order(self.selector_offset - 1),
|
||||
)
|
||||
}
|
||||
|
||||
/// The kind of invalidation that this would generate.
|
||||
pub fn invalidation_kind(&self) -> DependencyInvalidationKind {
|
||||
match self.combinator() {
|
||||
None => DependencyInvalidationKind::Element,
|
||||
Some(Combinator::Child) |
|
||||
Some(Combinator::Descendant) => DependencyInvalidationKind::Descendants,
|
||||
Some(Combinator::LaterSibling) |
|
||||
Some(Combinator::NextSibling) => DependencyInvalidationKind::Siblings,
|
||||
Some(Combinator::Child) | Some(Combinator::Descendant) => {
|
||||
DependencyInvalidationKind::Descendants
|
||||
},
|
||||
Some(Combinator::LaterSibling) | Some(Combinator::NextSibling) => {
|
||||
DependencyInvalidationKind::Siblings
|
||||
},
|
||||
// TODO(emilio): We could look at the selector itself to see if it's
|
||||
// an eager pseudo, and return only Descendants here if not.
|
||||
Some(Combinator::PseudoElement) => DependencyInvalidationKind::ElementAndDescendants,
|
||||
|
@ -196,15 +201,14 @@ impl InvalidationMap {
|
|||
|
||||
/// Returns the number of dependencies stored in the invalidation map.
|
||||
pub fn len(&self) -> usize {
|
||||
self.state_affecting_selectors.len() +
|
||||
self.document_state_selectors.len() +
|
||||
self.other_attribute_affecting_selectors.len() +
|
||||
self.id_to_selector.iter().fold(0, |accum, (_, ref v)| {
|
||||
accum + v.len()
|
||||
}) +
|
||||
self.class_to_selector.iter().fold(0, |accum, (_, ref v)| {
|
||||
accum + v.len()
|
||||
})
|
||||
self.state_affecting_selectors.len() + self.document_state_selectors.len() +
|
||||
self.other_attribute_affecting_selectors.len() +
|
||||
self.id_to_selector
|
||||
.iter()
|
||||
.fold(0, |accum, (_, ref v)| accum + v.len()) +
|
||||
self.class_to_selector
|
||||
.iter()
|
||||
.fold(0, |accum, (_, ref v)| accum + v.len())
|
||||
}
|
||||
|
||||
/// Clears this map, leaving it empty.
|
||||
|
@ -283,22 +287,26 @@ impl InvalidationMap {
|
|||
}
|
||||
|
||||
if !compound_visitor.state.is_empty() {
|
||||
self.state_affecting_selectors
|
||||
.insert(StateDependency {
|
||||
self.state_affecting_selectors.insert(
|
||||
StateDependency {
|
||||
dep: Dependency {
|
||||
selector: selector.clone(),
|
||||
selector_offset: sequence_start,
|
||||
},
|
||||
state: compound_visitor.state,
|
||||
}, quirks_mode)?;
|
||||
},
|
||||
quirks_mode,
|
||||
)?;
|
||||
}
|
||||
|
||||
if compound_visitor.other_attributes {
|
||||
self.other_attribute_affecting_selectors
|
||||
.insert(Dependency {
|
||||
self.other_attribute_affecting_selectors.insert(
|
||||
Dependency {
|
||||
selector: selector.clone(),
|
||||
selector_offset: sequence_start,
|
||||
}, quirks_mode)?;
|
||||
},
|
||||
quirks_mode,
|
||||
)?;
|
||||
}
|
||||
|
||||
combinator = iter.next_sequence();
|
||||
|
@ -310,10 +318,11 @@ impl InvalidationMap {
|
|||
}
|
||||
|
||||
if !document_state.is_empty() {
|
||||
self.document_state_selectors.try_push(DocumentStateDependency {
|
||||
state: document_state,
|
||||
selector: selector.clone(),
|
||||
})?;
|
||||
self.document_state_selectors
|
||||
.try_push(DocumentStateDependency {
|
||||
state: document_state,
|
||||
selector: selector.clone(),
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -365,22 +374,20 @@ impl<'a> SelectorVisitor for CompoundSelectorDependencyCollector<'a> {
|
|||
match *s {
|
||||
Component::ID(ref id) => {
|
||||
self.ids.push(id.clone());
|
||||
}
|
||||
},
|
||||
Component::Class(ref class) => {
|
||||
self.classes.push(class.clone());
|
||||
}
|
||||
},
|
||||
Component::NonTSPseudoClass(ref pc) => {
|
||||
self.other_attributes |= pc.is_attr_based();
|
||||
self.state |= match *pc {
|
||||
#[cfg(feature = "gecko")]
|
||||
NonTSPseudoClass::Dir(ref dir) => {
|
||||
dir_selector_to_state(dir)
|
||||
}
|
||||
NonTSPseudoClass::Dir(ref dir) => dir_selector_to_state(dir),
|
||||
_ => pc.state_flag(),
|
||||
};
|
||||
*self.document_state |= pc.document_state_flag();
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
true
|
||||
|
|
|
@ -22,12 +22,16 @@ where
|
|||
/// Whether an invalidation that contains only an eager pseudo-element
|
||||
/// selector like ::before or ::after triggers invalidation of the element
|
||||
/// that would originate it.
|
||||
fn invalidates_on_eager_pseudo_element(&self) -> bool { false }
|
||||
fn invalidates_on_eager_pseudo_element(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Whether the invalidation processor only cares about light-tree
|
||||
/// descendants of a given element, that is, doesn't invalidate
|
||||
/// pseudo-elements, NAC, or XBL anon content.
|
||||
fn light_tree_only(&self) -> bool { false }
|
||||
fn light_tree_only(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The matching context that should be used to process invalidations.
|
||||
fn matching_context(&mut self) -> &mut MatchingContext<'a, E::Impl>;
|
||||
|
@ -72,8 +76,7 @@ pub struct DescendantInvalidationLists<'a> {
|
|||
|
||||
impl<'a> DescendantInvalidationLists<'a> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.dom_descendants.is_empty() &&
|
||||
self.slotted_descendants.is_empty()
|
||||
self.dom_descendants.is_empty() && self.slotted_descendants.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +91,7 @@ where
|
|||
element: E,
|
||||
stack_limit_checker: Option<&'a StackLimitChecker>,
|
||||
processor: &'a mut P,
|
||||
_marker: ::std::marker::PhantomData<&'b ()>
|
||||
_marker: ::std::marker::PhantomData<&'b ()>,
|
||||
}
|
||||
|
||||
/// A vector of invalidations, optimized for small invalidation sets.
|
||||
|
@ -154,12 +157,8 @@ impl<'a> Invalidation<'a> {
|
|||
//
|
||||
// We should be able to do better here!
|
||||
match self.selector.combinator_at_parse_order(self.offset - 1) {
|
||||
Combinator::Descendant |
|
||||
Combinator::LaterSibling |
|
||||
Combinator::PseudoElement => true,
|
||||
Combinator::SlotAssignment |
|
||||
Combinator::NextSibling |
|
||||
Combinator::Child => false,
|
||||
Combinator::Descendant | Combinator::LaterSibling | Combinator::PseudoElement => true,
|
||||
Combinator::SlotAssignment | Combinator::NextSibling | Combinator::Child => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,12 +168,13 @@ impl<'a> Invalidation<'a> {
|
|||
}
|
||||
|
||||
match self.selector.combinator_at_parse_order(self.offset - 1) {
|
||||
Combinator::Child |
|
||||
Combinator::Descendant |
|
||||
Combinator::PseudoElement => InvalidationKind::Descendant(DescendantInvalidationKind::Dom),
|
||||
Combinator::SlotAssignment => InvalidationKind::Descendant(DescendantInvalidationKind::Slotted),
|
||||
Combinator::NextSibling |
|
||||
Combinator::LaterSibling => InvalidationKind::Sibling,
|
||||
Combinator::Child | Combinator::Descendant | Combinator::PseudoElement => {
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Dom)
|
||||
},
|
||||
Combinator::SlotAssignment => {
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Slotted)
|
||||
},
|
||||
Combinator::NextSibling | Combinator::LaterSibling => InvalidationKind::Sibling,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,9 +275,17 @@ where
|
|||
);
|
||||
|
||||
debug!("Collected invalidations (self: {}): ", invalidated_self);
|
||||
debug!(" > self: {}, {:?}", self_invalidations.len(), self_invalidations);
|
||||
debug!(
|
||||
" > self: {}, {:?}",
|
||||
self_invalidations.len(),
|
||||
self_invalidations
|
||||
);
|
||||
debug!(" > descendants: {:?}", descendant_invalidations);
|
||||
debug!(" > siblings: {}, {:?}", sibling_invalidations.len(), sibling_invalidations);
|
||||
debug!(
|
||||
" > siblings: {}, {:?}",
|
||||
sibling_invalidations.len(),
|
||||
sibling_invalidations
|
||||
);
|
||||
|
||||
let invalidated_self_from_collection = invalidated_self;
|
||||
|
||||
|
@ -307,10 +315,7 @@ where
|
|||
///
|
||||
/// Returns whether any sibling's style or any sibling descendant's style
|
||||
/// was invalidated.
|
||||
fn invalidate_siblings(
|
||||
&mut self,
|
||||
sibling_invalidations: &mut InvalidationVector<'b>,
|
||||
) -> bool {
|
||||
fn invalidate_siblings(&mut self, sibling_invalidations: &mut InvalidationVector<'b>) -> bool {
|
||||
if sibling_invalidations.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
@ -319,19 +324,14 @@ where
|
|||
let mut any_invalidated = false;
|
||||
|
||||
while let Some(sibling) = current {
|
||||
let mut sibling_invalidator = TreeStyleInvalidator::new(
|
||||
sibling,
|
||||
self.stack_limit_checker,
|
||||
self.processor,
|
||||
);
|
||||
let mut sibling_invalidator =
|
||||
TreeStyleInvalidator::new(sibling, self.stack_limit_checker, self.processor);
|
||||
|
||||
let mut invalidations_for_descendants =
|
||||
DescendantInvalidationLists::default();
|
||||
let invalidated_sibling =
|
||||
sibling_invalidator.process_sibling_invalidations(
|
||||
&mut invalidations_for_descendants,
|
||||
sibling_invalidations,
|
||||
);
|
||||
let mut invalidations_for_descendants = DescendantInvalidationLists::default();
|
||||
let invalidated_sibling = sibling_invalidator.process_sibling_invalidations(
|
||||
&mut invalidations_for_descendants,
|
||||
sibling_invalidations,
|
||||
);
|
||||
|
||||
if invalidated_sibling {
|
||||
sibling_invalidator.processor.invalidated_self(sibling);
|
||||
|
@ -340,9 +340,7 @@ where
|
|||
any_invalidated |= invalidated_sibling;
|
||||
|
||||
any_invalidated |=
|
||||
sibling_invalidator.invalidate_descendants(
|
||||
&invalidations_for_descendants,
|
||||
);
|
||||
sibling_invalidator.invalidate_descendants(&invalidations_for_descendants);
|
||||
|
||||
if sibling_invalidations.is_empty() {
|
||||
break;
|
||||
|
@ -387,38 +385,30 @@ where
|
|||
sibling_invalidations: &mut InvalidationVector<'b>,
|
||||
descendant_invalidation_kind: DescendantInvalidationKind,
|
||||
) -> bool {
|
||||
let mut invalidations_for_descendants =
|
||||
DescendantInvalidationLists::default();
|
||||
let mut invalidations_for_descendants = DescendantInvalidationLists::default();
|
||||
|
||||
let mut invalidated_child = false;
|
||||
let invalidated_descendants = {
|
||||
let mut child_invalidator = TreeStyleInvalidator::new(
|
||||
child,
|
||||
self.stack_limit_checker,
|
||||
self.processor,
|
||||
let mut child_invalidator =
|
||||
TreeStyleInvalidator::new(child, self.stack_limit_checker, self.processor);
|
||||
|
||||
invalidated_child |= child_invalidator.process_sibling_invalidations(
|
||||
&mut invalidations_for_descendants,
|
||||
sibling_invalidations,
|
||||
);
|
||||
|
||||
invalidated_child |=
|
||||
child_invalidator.process_sibling_invalidations(
|
||||
&mut invalidations_for_descendants,
|
||||
sibling_invalidations,
|
||||
);
|
||||
|
||||
invalidated_child |=
|
||||
child_invalidator.process_descendant_invalidations(
|
||||
invalidations,
|
||||
&mut invalidations_for_descendants,
|
||||
sibling_invalidations,
|
||||
descendant_invalidation_kind,
|
||||
);
|
||||
invalidated_child |= child_invalidator.process_descendant_invalidations(
|
||||
invalidations,
|
||||
&mut invalidations_for_descendants,
|
||||
sibling_invalidations,
|
||||
descendant_invalidation_kind,
|
||||
);
|
||||
|
||||
if invalidated_child {
|
||||
child_invalidator.processor.invalidated_self(child);
|
||||
}
|
||||
|
||||
child_invalidator.invalidate_descendants(
|
||||
&invalidations_for_descendants,
|
||||
)
|
||||
child_invalidator.invalidate_descendants(&invalidations_for_descendants)
|
||||
};
|
||||
|
||||
// The child may not be a flattened tree child of the current element,
|
||||
|
@ -433,16 +423,12 @@ where
|
|||
invalidated_child || invalidated_descendants
|
||||
}
|
||||
|
||||
fn invalidate_nac(
|
||||
&mut self,
|
||||
invalidations: &[Invalidation<'b>],
|
||||
) -> bool {
|
||||
fn invalidate_nac(&mut self, invalidations: &[Invalidation<'b>]) -> bool {
|
||||
let mut any_nac_root = false;
|
||||
|
||||
let element = self.element;
|
||||
element.each_anonymous_content_child(|nac| {
|
||||
any_nac_root |=
|
||||
self.invalidate_pseudo_element_or_nac(nac, invalidations);
|
||||
any_nac_root |= self.invalidate_pseudo_element_or_nac(nac, invalidations);
|
||||
});
|
||||
|
||||
any_nac_root
|
||||
|
@ -480,10 +466,7 @@ where
|
|||
any_descendant
|
||||
}
|
||||
|
||||
fn invalidate_slotted_elements(
|
||||
&mut self,
|
||||
invalidations: &[Invalidation<'b>],
|
||||
) -> bool {
|
||||
fn invalidate_slotted_elements(&mut self, invalidations: &[Invalidation<'b>]) -> bool {
|
||||
if invalidations.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
@ -519,10 +502,7 @@ where
|
|||
any
|
||||
}
|
||||
|
||||
fn invalidate_non_slotted_descendants(
|
||||
&mut self,
|
||||
invalidations: &[Invalidation<'b>],
|
||||
) -> bool {
|
||||
fn invalidate_non_slotted_descendants(&mut self, invalidations: &[Invalidation<'b>]) -> bool {
|
||||
if invalidations.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
@ -543,30 +523,25 @@ where
|
|||
// where we rely on iterating every element that ends up in the composed
|
||||
// doc, but we could fix that invalidating per subtree.
|
||||
if let Some(root) = self.element.shadow_root() {
|
||||
any_descendant |=
|
||||
self.invalidate_dom_descendants_of(root.as_node(), invalidations);
|
||||
any_descendant |= self.invalidate_dom_descendants_of(root.as_node(), invalidations);
|
||||
}
|
||||
|
||||
// This is needed for XBL (technically) unconditionally, because XBL
|
||||
// bindings do not block combinators in any way. However this is kinda
|
||||
// broken anyway, since we should be looking at XBL rules too.
|
||||
if let Some(anon_content) = self.element.xbl_binding_anonymous_content() {
|
||||
any_descendant |=
|
||||
self.invalidate_dom_descendants_of(anon_content, invalidations);
|
||||
any_descendant |= self.invalidate_dom_descendants_of(anon_content, invalidations);
|
||||
}
|
||||
|
||||
if let Some(before) = self.element.before_pseudo_element() {
|
||||
any_descendant |=
|
||||
self.invalidate_pseudo_element_or_nac(before, invalidations);
|
||||
any_descendant |= self.invalidate_pseudo_element_or_nac(before, invalidations);
|
||||
}
|
||||
|
||||
let node = self.element.as_node();
|
||||
any_descendant |=
|
||||
self.invalidate_dom_descendants_of(node, invalidations);
|
||||
any_descendant |= self.invalidate_dom_descendants_of(node, invalidations);
|
||||
|
||||
if let Some(after) = self.element.after_pseudo_element() {
|
||||
any_descendant |=
|
||||
self.invalidate_pseudo_element_or_nac(after, invalidations);
|
||||
any_descendant |= self.invalidate_pseudo_element_or_nac(after, invalidations);
|
||||
}
|
||||
|
||||
any_descendant |= self.invalidate_nac(invalidations);
|
||||
|
@ -576,20 +551,18 @@ where
|
|||
|
||||
/// Given the descendant invalidation lists, go through the current
|
||||
/// element's descendants, and invalidate style on them.
|
||||
fn invalidate_descendants(
|
||||
&mut self,
|
||||
invalidations: &DescendantInvalidationLists<'b>,
|
||||
) -> bool {
|
||||
fn invalidate_descendants(&mut self, invalidations: &DescendantInvalidationLists<'b>) -> bool {
|
||||
if invalidations.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
debug!("StyleTreeInvalidator::invalidate_descendants({:?})",
|
||||
self.element);
|
||||
debug!(
|
||||
"StyleTreeInvalidator::invalidate_descendants({:?})",
|
||||
self.element
|
||||
);
|
||||
debug!(" > {:?}", invalidations);
|
||||
|
||||
let should_process =
|
||||
self.processor.should_process_descendants(self.element);
|
||||
let should_process = self.processor.should_process_descendants(self.element);
|
||||
|
||||
if !should_process {
|
||||
return false;
|
||||
|
@ -604,10 +577,8 @@ where
|
|||
|
||||
let mut any_descendant = false;
|
||||
|
||||
any_descendant |=
|
||||
self.invalidate_non_slotted_descendants(&invalidations.dom_descendants);
|
||||
any_descendant |=
|
||||
self.invalidate_slotted_elements(&invalidations.slotted_descendants);
|
||||
any_descendant |= self.invalidate_non_slotted_descendants(&invalidations.dom_descendants);
|
||||
any_descendant |= self.invalidate_slotted_elements(&invalidations.slotted_descendants);
|
||||
|
||||
any_descendant
|
||||
}
|
||||
|
@ -704,14 +675,16 @@ where
|
|||
sibling_invalidations: &mut InvalidationVector<'b>,
|
||||
invalidation_kind: InvalidationKind,
|
||||
) -> SingleInvalidationResult {
|
||||
debug!("TreeStyleInvalidator::process_invalidation({:?}, {:?}, {:?})",
|
||||
self.element, invalidation, invalidation_kind);
|
||||
debug!(
|
||||
"TreeStyleInvalidator::process_invalidation({:?}, {:?}, {:?})",
|
||||
self.element, invalidation, invalidation_kind
|
||||
);
|
||||
|
||||
let matching_result = matches_compound_selector_from(
|
||||
&invalidation.selector,
|
||||
invalidation.offset,
|
||||
self.processor.matching_context(),
|
||||
&self.element
|
||||
&self.element,
|
||||
);
|
||||
|
||||
let mut invalidated_self = false;
|
||||
|
@ -721,34 +694,33 @@ where
|
|||
debug!(" > Invalidation matched completely");
|
||||
matched = true;
|
||||
invalidated_self = true;
|
||||
}
|
||||
CompoundSelectorMatchingResult::Matched { next_combinator_offset } => {
|
||||
let next_combinator =
|
||||
invalidation.selector.combinator_at_parse_order(next_combinator_offset);
|
||||
},
|
||||
CompoundSelectorMatchingResult::Matched {
|
||||
next_combinator_offset,
|
||||
} => {
|
||||
let next_combinator = invalidation
|
||||
.selector
|
||||
.combinator_at_parse_order(next_combinator_offset);
|
||||
matched = true;
|
||||
|
||||
if matches!(next_combinator, Combinator::PseudoElement) {
|
||||
// This will usually be the very next component, except for
|
||||
// the fact that we store compound selectors the other way
|
||||
// around, so there could also be state pseudo-classes.
|
||||
let pseudo_selector =
|
||||
invalidation.selector
|
||||
.iter_raw_parse_order_from(next_combinator_offset + 1)
|
||||
.skip_while(|c| matches!(**c, Component::NonTSPseudoClass(..)))
|
||||
.next()
|
||||
.unwrap();
|
||||
let pseudo_selector = invalidation
|
||||
.selector
|
||||
.iter_raw_parse_order_from(next_combinator_offset + 1)
|
||||
.skip_while(|c| matches!(**c, Component::NonTSPseudoClass(..)))
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
let pseudo = match *pseudo_selector {
|
||||
Component::PseudoElement(ref pseudo) => pseudo,
|
||||
_ => {
|
||||
unreachable!(
|
||||
"Someone seriously messed up selector parsing: \
|
||||
{:?} at offset {:?}: {:?}",
|
||||
invalidation.selector,
|
||||
next_combinator_offset,
|
||||
pseudo_selector,
|
||||
)
|
||||
}
|
||||
_ => unreachable!(
|
||||
"Someone seriously messed up selector parsing: \
|
||||
{:?} at offset {:?}: {:?}",
|
||||
invalidation.selector, next_combinator_offset, pseudo_selector,
|
||||
),
|
||||
};
|
||||
|
||||
// FIXME(emilio): This is not ideal, and could not be
|
||||
|
@ -765,21 +737,21 @@ where
|
|||
//
|
||||
// Note that we'll also restyle the pseudo-element because
|
||||
// it would match this invalidation.
|
||||
if self.processor.invalidates_on_eager_pseudo_element() &&
|
||||
pseudo.is_eager() {
|
||||
if self.processor.invalidates_on_eager_pseudo_element() && pseudo.is_eager() {
|
||||
invalidated_self = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let next_invalidation = Invalidation {
|
||||
selector: invalidation.selector,
|
||||
offset: next_combinator_offset + 1,
|
||||
matched_by_any_previous: false,
|
||||
};
|
||||
|
||||
debug!(" > Invalidation matched, next: {:?}, ({:?})",
|
||||
next_invalidation, next_combinator);
|
||||
debug!(
|
||||
" > Invalidation matched, next: {:?}, ({:?})",
|
||||
next_invalidation, next_combinator
|
||||
);
|
||||
|
||||
let next_invalidation_kind = next_invalidation.kind();
|
||||
|
||||
|
@ -842,32 +814,39 @@ where
|
|||
//
|
||||
// [div div div, div div, div]
|
||||
//
|
||||
let can_skip_pushing =
|
||||
next_invalidation_kind == invalidation_kind &&
|
||||
let can_skip_pushing = next_invalidation_kind == invalidation_kind &&
|
||||
invalidation.matched_by_any_previous &&
|
||||
next_invalidation.effective_for_next();
|
||||
|
||||
if can_skip_pushing {
|
||||
debug!(" > Can avoid push, since the invalidation had \
|
||||
already been matched before");
|
||||
debug!(
|
||||
" > Can avoid push, since the invalidation had \
|
||||
already been matched before"
|
||||
);
|
||||
} else {
|
||||
match next_invalidation_kind {
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Dom) => {
|
||||
descendant_invalidations.dom_descendants.push(next_invalidation);
|
||||
}
|
||||
descendant_invalidations
|
||||
.dom_descendants
|
||||
.push(next_invalidation);
|
||||
},
|
||||
InvalidationKind::Descendant(DescendantInvalidationKind::Slotted) => {
|
||||
descendant_invalidations.slotted_descendants.push(next_invalidation);
|
||||
}
|
||||
descendant_invalidations
|
||||
.slotted_descendants
|
||||
.push(next_invalidation);
|
||||
},
|
||||
InvalidationKind::Sibling => {
|
||||
sibling_invalidations.push(next_invalidation);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
CompoundSelectorMatchingResult::NotMatched => {}
|
||||
},
|
||||
CompoundSelectorMatchingResult::NotMatched => {},
|
||||
}
|
||||
|
||||
SingleInvalidationResult { invalidated_self, matched, }
|
||||
SingleInvalidationResult {
|
||||
invalidated_self,
|
||||
matched,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,9 +67,8 @@ impl RestyleHint {
|
|||
/// Returns whether we need to restyle this element.
|
||||
pub fn has_non_animation_invalidations(&self) -> bool {
|
||||
self.intersects(
|
||||
RestyleHint::RESTYLE_SELF |
|
||||
RestyleHint::RECASCADE_SELF |
|
||||
(Self::replacements() & !Self::for_animations())
|
||||
RestyleHint::RESTYLE_SELF | RestyleHint::RECASCADE_SELF |
|
||||
(Self::replacements() & !Self::for_animations()),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -84,23 +83,24 @@ impl RestyleHint {
|
|||
return Self::empty();
|
||||
}
|
||||
|
||||
debug_assert!(!self.has_animation_hint(),
|
||||
"There should not be any animation restyle hints \
|
||||
during normal traversal");
|
||||
debug_assert!(
|
||||
!self.has_animation_hint(),
|
||||
"There should not be any animation restyle hints \
|
||||
during normal traversal"
|
||||
);
|
||||
|
||||
// Else we should clear ourselves, and return the propagated hint.
|
||||
mem::replace(self, Self::empty())
|
||||
.propagate_for_non_animation_restyle()
|
||||
mem::replace(self, Self::empty()).propagate_for_non_animation_restyle()
|
||||
}
|
||||
|
||||
/// Returns a new `CascadeHint` appropriate for children of the current
|
||||
/// element.
|
||||
fn propagate_for_non_animation_restyle(&self) -> Self {
|
||||
if self.contains(RestyleHint::RESTYLE_DESCENDANTS) {
|
||||
return Self::restyle_subtree()
|
||||
return Self::restyle_subtree();
|
||||
}
|
||||
if self.contains(RestyleHint::RECASCADE_DESCENDANTS) {
|
||||
return Self::recascade_subtree()
|
||||
return Self::recascade_subtree();
|
||||
}
|
||||
Self::empty()
|
||||
}
|
||||
|
@ -119,7 +119,8 @@ impl RestyleHint {
|
|||
/// The replacements for the animation cascade levels.
|
||||
#[inline]
|
||||
pub fn for_animations() -> Self {
|
||||
RestyleHint::RESTYLE_SMIL | RestyleHint::RESTYLE_CSS_ANIMATIONS | RestyleHint::RESTYLE_CSS_TRANSITIONS
|
||||
RestyleHint::RESTYLE_SMIL | RestyleHint::RESTYLE_CSS_ANIMATIONS |
|
||||
RestyleHint::RESTYLE_CSS_TRANSITIONS
|
||||
}
|
||||
|
||||
/// Returns whether the hint specifies that the currently element must be
|
||||
|
@ -199,8 +200,10 @@ impl From<nsRestyleHint> for RestyleHint {
|
|||
|
||||
let mut hint = RestyleHint::empty();
|
||||
|
||||
debug_assert!(raw.0 & eRestyle_LaterSiblings.0 == 0,
|
||||
"Handle later siblings manually if necessary plz.");
|
||||
debug_assert!(
|
||||
raw.0 & eRestyle_LaterSiblings.0 == 0,
|
||||
"Handle later siblings manually if necessary plz."
|
||||
);
|
||||
|
||||
if (raw.0 & (eRestyle_Self.0 | eRestyle_Subtree.0)) != 0 {
|
||||
raw.0 &= !eRestyle_Self.0;
|
||||
|
|
|
@ -92,12 +92,10 @@ impl<'a, 'b: 'a, E: TElement> StateAndAttrInvalidationProcessor<'a, 'b, E> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Whether we should process the descendants of a given element for style
|
||||
/// invalidation.
|
||||
pub fn should_process_descendants(data: &ElementData) -> bool {
|
||||
!data.styles.is_display_none() &&
|
||||
!data.hint.contains(RestyleHint::RESTYLE_DESCENDANTS)
|
||||
!data.styles.is_display_none() && !data.hint.contains(RestyleHint::RESTYLE_DESCENDANTS)
|
||||
}
|
||||
|
||||
/// Propagates the bits after invalidating a descendant child.
|
||||
|
@ -136,14 +134,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a, E: 'a> InvalidationProcessor<'a, E> for StateAndAttrInvalidationProcessor<'a, 'b, E>
|
||||
impl<'a, 'b: 'a, E: 'a> InvalidationProcessor<'a, E>
|
||||
for StateAndAttrInvalidationProcessor<'a, 'b, E>
|
||||
where
|
||||
E: TElement,
|
||||
{
|
||||
/// We need to invalidate style on an eager pseudo-element, in order to
|
||||
/// process changes that could otherwise end up in ::before or ::after
|
||||
/// content being generated.
|
||||
fn invalidates_on_eager_pseudo_element(&self) -> bool { true }
|
||||
fn invalidates_on_eager_pseudo_element(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn matching_context(&mut self) -> &mut MatchingContext<'a, E::Impl> {
|
||||
&mut self.matching_context
|
||||
|
@ -158,8 +159,7 @@ where
|
|||
) -> bool {
|
||||
debug_assert!(element.has_snapshot(), "Why bothering?");
|
||||
|
||||
let wrapper =
|
||||
ElementWrapper::new(element, &*self.shared_context.snapshot_map);
|
||||
let wrapper = ElementWrapper::new(element, &*self.shared_context.snapshot_map);
|
||||
|
||||
let state_changes = wrapper.state_changes();
|
||||
let snapshot = wrapper.snapshot().expect("has_snapshot lied");
|
||||
|
@ -223,12 +223,11 @@ where
|
|||
classes_removed
|
||||
);
|
||||
|
||||
let lookup_element =
|
||||
if element.implemented_pseudo_element().is_some() {
|
||||
element.pseudo_element_originating_element().unwrap()
|
||||
} else {
|
||||
element
|
||||
};
|
||||
let lookup_element = if element.implemented_pseudo_element().is_some() {
|
||||
element.pseudo_element_originating_element().unwrap()
|
||||
} else {
|
||||
element
|
||||
};
|
||||
|
||||
let invalidated_self = {
|
||||
let mut collector = Collector {
|
||||
|
@ -255,7 +254,8 @@ where
|
|||
|
||||
for (cascade_data, origin) in self.shared_context.stylist.iter_origins() {
|
||||
if document_origins.contains(origin.into()) {
|
||||
collector.collect_dependencies_in_invalidation_map(cascade_data.invalidation_map());
|
||||
collector
|
||||
.collect_dependencies_in_invalidation_map(cascade_data.invalidation_map());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,7 @@ where
|
|||
|
||||
fn should_process_descendants(&mut self, element: E) -> bool {
|
||||
if element == self.element {
|
||||
return should_process_descendants(&self.data)
|
||||
return should_process_descendants(&self.data);
|
||||
}
|
||||
|
||||
match element.borrow_data() {
|
||||
|
@ -329,10 +329,7 @@ where
|
|||
E: TElement,
|
||||
'selectors: 'a,
|
||||
{
|
||||
fn collect_dependencies_in_invalidation_map(
|
||||
&mut self,
|
||||
map: &'selectors InvalidationMap,
|
||||
) {
|
||||
fn collect_dependencies_in_invalidation_map(&mut self, map: &'selectors InvalidationMap) {
|
||||
let quirks_mode = self.matching_context.quirks_mode();
|
||||
let removed_id = self.removed_id;
|
||||
if let Some(ref id) = removed_id {
|
||||
|
@ -360,30 +357,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
let should_examine_attribute_selector_map =
|
||||
self.snapshot.other_attr_changed() ||
|
||||
let should_examine_attribute_selector_map = self.snapshot.other_attr_changed() ||
|
||||
(self.snapshot.class_changed() && map.has_class_attribute_selectors) ||
|
||||
(self.snapshot.id_changed() && map.has_id_attribute_selectors);
|
||||
|
||||
if should_examine_attribute_selector_map {
|
||||
self.collect_dependencies_in_map(
|
||||
&map.other_attribute_affecting_selectors
|
||||
)
|
||||
self.collect_dependencies_in_map(&map.other_attribute_affecting_selectors)
|
||||
}
|
||||
|
||||
let state_changes = self.state_changes;
|
||||
if !state_changes.is_empty() {
|
||||
self.collect_state_dependencies(
|
||||
&map.state_affecting_selectors,
|
||||
state_changes,
|
||||
)
|
||||
self.collect_state_dependencies(&map.state_affecting_selectors, state_changes)
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_dependencies_in_map(
|
||||
&mut self,
|
||||
map: &'selectors SelectorMap<Dependency>,
|
||||
) {
|
||||
fn collect_dependencies_in_map(&mut self, map: &'selectors SelectorMap<Dependency>) {
|
||||
map.lookup_with_additional(
|
||||
self.lookup_element,
|
||||
self.matching_context.quirks_mode(),
|
||||
|
@ -410,12 +398,14 @@ where
|
|||
if !dependency.state.intersects(state_changes) {
|
||||
return true;
|
||||
}
|
||||
let visited_dependent =
|
||||
if dependency.state.intersects(ElementState::IN_VISITED_OR_UNVISITED_STATE) {
|
||||
VisitedDependent::Yes
|
||||
} else {
|
||||
VisitedDependent::No
|
||||
};
|
||||
let visited_dependent = if dependency
|
||||
.state
|
||||
.intersects(ElementState::IN_VISITED_OR_UNVISITED_STATE)
|
||||
{
|
||||
VisitedDependent::Yes
|
||||
} else {
|
||||
VisitedDependent::No
|
||||
};
|
||||
self.scan_dependency(&dependency.dep, visited_dependent);
|
||||
true
|
||||
},
|
||||
|
@ -431,27 +421,28 @@ where
|
|||
) -> bool {
|
||||
let element = &self.element;
|
||||
let wrapper = &self.wrapper;
|
||||
self.matching_context.with_visited_handling_mode(visited_handling_mode, |mut context| {
|
||||
let matches_now = matches_selector(
|
||||
&dependency.selector,
|
||||
dependency.selector_offset,
|
||||
None,
|
||||
element,
|
||||
&mut context,
|
||||
&mut |_, _| {},
|
||||
);
|
||||
self.matching_context
|
||||
.with_visited_handling_mode(visited_handling_mode, |mut context| {
|
||||
let matches_now = matches_selector(
|
||||
&dependency.selector,
|
||||
dependency.selector_offset,
|
||||
None,
|
||||
element,
|
||||
&mut context,
|
||||
&mut |_, _| {},
|
||||
);
|
||||
|
||||
let matched_then = matches_selector(
|
||||
&dependency.selector,
|
||||
dependency.selector_offset,
|
||||
None,
|
||||
wrapper,
|
||||
&mut context,
|
||||
&mut |_, _| {},
|
||||
);
|
||||
let matched_then = matches_selector(
|
||||
&dependency.selector,
|
||||
dependency.selector_offset,
|
||||
None,
|
||||
wrapper,
|
||||
&mut context,
|
||||
&mut |_, _| {},
|
||||
);
|
||||
|
||||
matched_then != matches_now
|
||||
})
|
||||
matched_then != matches_now
|
||||
})
|
||||
}
|
||||
|
||||
fn scan_dependency(
|
||||
|
@ -459,20 +450,17 @@ where
|
|||
dependency: &'selectors Dependency,
|
||||
is_visited_dependent: VisitedDependent,
|
||||
) {
|
||||
debug!("TreeStyleInvalidator::scan_dependency({:?}, {:?}, {:?})",
|
||||
self.element,
|
||||
dependency,
|
||||
is_visited_dependent,
|
||||
debug!(
|
||||
"TreeStyleInvalidator::scan_dependency({:?}, {:?}, {:?})",
|
||||
self.element, dependency, is_visited_dependent,
|
||||
);
|
||||
|
||||
if !self.dependency_may_be_relevant(dependency) {
|
||||
return;
|
||||
}
|
||||
|
||||
let should_account_for_dependency = self.check_dependency(
|
||||
VisitedHandlingMode::AllLinksVisitedAndUnvisited,
|
||||
dependency,
|
||||
);
|
||||
let should_account_for_dependency =
|
||||
self.check_dependency(VisitedHandlingMode::AllLinksVisitedAndUnvisited, dependency);
|
||||
|
||||
if should_account_for_dependency {
|
||||
return self.note_dependency(dependency);
|
||||
|
@ -494,13 +482,9 @@ where
|
|||
//
|
||||
// NOTE: This thing is actually untested because testing it is flaky,
|
||||
// see the tests that were added and then backed out in bug 1328509.
|
||||
if is_visited_dependent == VisitedDependent::Yes &&
|
||||
self.element.is_link()
|
||||
{
|
||||
let should_account_for_dependency = self.check_dependency(
|
||||
VisitedHandlingMode::RelevantLinkVisited,
|
||||
dependency,
|
||||
);
|
||||
if is_visited_dependent == VisitedDependent::Yes && self.element.is_link() {
|
||||
let should_account_for_dependency =
|
||||
self.check_dependency(VisitedHandlingMode::RelevantLinkVisited, dependency);
|
||||
|
||||
if should_account_for_dependency {
|
||||
return self.note_dependency(dependency);
|
||||
|
@ -518,10 +502,7 @@ where
|
|||
}
|
||||
|
||||
debug_assert_ne!(dependency.selector_offset, 0);
|
||||
debug_assert_ne!(
|
||||
dependency.selector_offset,
|
||||
dependency.selector.len()
|
||||
);
|
||||
debug_assert_ne!(dependency.selector_offset, dependency.selector.len());
|
||||
|
||||
let invalidation = Invalidation::new(
|
||||
&dependency.selector,
|
||||
|
@ -532,17 +513,23 @@ where
|
|||
DependencyInvalidationKind::Element => unreachable!(),
|
||||
DependencyInvalidationKind::ElementAndDescendants => {
|
||||
self.invalidates_self = true;
|
||||
self.descendant_invalidations.dom_descendants.push(invalidation);
|
||||
}
|
||||
self.descendant_invalidations
|
||||
.dom_descendants
|
||||
.push(invalidation);
|
||||
},
|
||||
DependencyInvalidationKind::Descendants => {
|
||||
self.descendant_invalidations.dom_descendants.push(invalidation);
|
||||
}
|
||||
self.descendant_invalidations
|
||||
.dom_descendants
|
||||
.push(invalidation);
|
||||
},
|
||||
DependencyInvalidationKind::Siblings => {
|
||||
self.sibling_invalidations.push(invalidation);
|
||||
}
|
||||
},
|
||||
DependencyInvalidationKind::SlottedElements => {
|
||||
self.descendant_invalidations.slotted_descendants.push(invalidation);
|
||||
}
|
||||
self.descendant_invalidations
|
||||
.slotted_descendants
|
||||
.push(invalidation);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ impl MediaListKey {
|
|||
|
||||
/// A trait to get a given `MediaListKey` for a given item that can hold a
|
||||
/// `MediaList`.
|
||||
pub trait ToMediaListKey : Sized {
|
||||
pub trait ToMediaListKey: Sized {
|
||||
/// Get a `MediaListKey` for this item. This key needs to uniquely identify
|
||||
/// the item.
|
||||
#[allow(unsafe_code)]
|
||||
|
@ -73,14 +73,16 @@ impl EffectiveMediaQueryResults {
|
|||
/// Returns whether a given item was known to be effective when the results
|
||||
/// were cached.
|
||||
pub fn was_effective<T>(&self, item: &T) -> bool
|
||||
where T: ToMediaListKey,
|
||||
where
|
||||
T: ToMediaListKey,
|
||||
{
|
||||
self.set.contains(&item.to_media_list_key())
|
||||
}
|
||||
|
||||
/// Notices that an effective item has been seen, and caches it as matching.
|
||||
pub fn saw_effective<T>(&mut self, item: &T)
|
||||
where T: ToMediaListKey,
|
||||
where
|
||||
T: ToMediaListKey,
|
||||
{
|
||||
// NOTE(emilio): We can't assert that we don't cache the same item twice
|
||||
// because of stylesheet reusing... shrug.
|
||||
|
@ -97,19 +99,12 @@ impl NestedRuleIterationCondition for PotentiallyEffectiveMediaRules {
|
|||
_: &SharedRwLockReadGuard,
|
||||
_: &Device,
|
||||
_: QuirksMode,
|
||||
_: &ImportRule)
|
||||
-> bool
|
||||
{
|
||||
_: &ImportRule,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn process_media(
|
||||
_: &SharedRwLockReadGuard,
|
||||
_: &Device,
|
||||
_: QuirksMode,
|
||||
_: &MediaRule)
|
||||
-> bool
|
||||
{
|
||||
fn process_media(_: &SharedRwLockReadGuard, _: &Device, _: QuirksMode, _: &MediaRule) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -118,9 +113,8 @@ impl NestedRuleIterationCondition for PotentiallyEffectiveMediaRules {
|
|||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
rule: &DocumentRule)
|
||||
-> bool
|
||||
{
|
||||
rule: &DocumentRule,
|
||||
) -> bool {
|
||||
use stylesheets::EffectiveRules;
|
||||
EffectiveRules::process_document(guard, device, quirks_mode, rule)
|
||||
}
|
||||
|
@ -130,9 +124,8 @@ impl NestedRuleIterationCondition for PotentiallyEffectiveMediaRules {
|
|||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
rule: &SupportsRule)
|
||||
-> bool
|
||||
{
|
||||
rule: &SupportsRule,
|
||||
) -> bool {
|
||||
use stylesheets::EffectiveRules;
|
||||
EffectiveRules::process_supports(guard, device, quirks_mode, rule)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,10 @@ enum Invalidation {
|
|||
/// An element with a given class name.
|
||||
Class(Atom),
|
||||
/// An element with a given local name.
|
||||
LocalName { name: SelectorLocalName, lower_name: SelectorLocalName },
|
||||
LocalName {
|
||||
name: SelectorLocalName,
|
||||
lower_name: SelectorLocalName,
|
||||
},
|
||||
}
|
||||
|
||||
impl Invalidation {
|
||||
|
@ -64,7 +67,7 @@ impl Invalidation {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Invalidation::ID(ref id) => {
|
||||
if let Some(ref element_id) = element.id() {
|
||||
if case_sensitivity.eq_atom(element_id, id) {
|
||||
|
@ -79,14 +82,17 @@ impl Invalidation {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Invalidation::LocalName { ref name, ref lower_name } => {
|
||||
},
|
||||
Invalidation::LocalName {
|
||||
ref name,
|
||||
ref lower_name,
|
||||
} => {
|
||||
// This could look at the quirks mode of the document, instead
|
||||
// of testing against both names, but it's probably not worth
|
||||
// it.
|
||||
let local_name = element.local_name();
|
||||
return *local_name == **name || *local_name == **lower_name
|
||||
}
|
||||
return *local_name == **name || *local_name == **lower_name;
|
||||
},
|
||||
}
|
||||
|
||||
false
|
||||
|
@ -132,9 +138,8 @@ impl StylesheetInvalidationSet {
|
|||
&mut self,
|
||||
device: &Device,
|
||||
stylesheet: &S,
|
||||
guard: &SharedRwLockReadGuard
|
||||
)
|
||||
where
|
||||
guard: &SharedRwLockReadGuard,
|
||||
) where
|
||||
S: StylesheetInDocument,
|
||||
{
|
||||
debug!("StylesheetInvalidationSet::collect_invalidations_for");
|
||||
|
@ -143,8 +148,7 @@ impl StylesheetInvalidationSet {
|
|||
return;
|
||||
}
|
||||
|
||||
if !stylesheet.enabled() ||
|
||||
!stylesheet.is_effective_for_device(device, guard) {
|
||||
if !stylesheet.enabled() || !stylesheet.is_effective_for_device(device, guard) {
|
||||
debug!(" > Stylesheet was not effective");
|
||||
return; // Nothing to do here.
|
||||
}
|
||||
|
@ -158,8 +162,14 @@ impl StylesheetInvalidationSet {
|
|||
}
|
||||
}
|
||||
|
||||
debug!(" > resulting subtree invalidations: {:?}", self.invalid_scopes);
|
||||
debug!(" > resulting self invalidations: {:?}", self.invalid_elements);
|
||||
debug!(
|
||||
" > resulting subtree invalidations: {:?}",
|
||||
self.invalid_scopes
|
||||
);
|
||||
debug!(
|
||||
" > resulting self invalidations: {:?}",
|
||||
self.invalid_elements
|
||||
);
|
||||
debug!(" > fully_invalid: {}", self.fully_invalid);
|
||||
}
|
||||
|
||||
|
@ -167,15 +177,15 @@ impl StylesheetInvalidationSet {
|
|||
/// `document_element` is provided.
|
||||
///
|
||||
/// Returns true if any invalidations ocurred.
|
||||
pub fn flush<E>(
|
||||
&mut self,
|
||||
document_element: Option<E>,
|
||||
snapshots: Option<&SnapshotMap>,
|
||||
) -> bool
|
||||
pub fn flush<E>(&mut self, document_element: Option<E>, snapshots: Option<&SnapshotMap>) -> bool
|
||||
where
|
||||
E: TElement,
|
||||
{
|
||||
debug!("Stylist::flush({:?}, snapshots: {})", document_element, snapshots.is_some());
|
||||
debug!(
|
||||
"Stylist::flush({:?}, snapshots: {})",
|
||||
document_element,
|
||||
snapshots.is_some()
|
||||
);
|
||||
let have_invalidations = match document_element {
|
||||
Some(e) => self.process_invalidations(e, snapshots),
|
||||
None => false,
|
||||
|
@ -196,10 +206,8 @@ impl StylesheetInvalidationSet {
|
|||
E: TElement,
|
||||
{
|
||||
debug!(
|
||||
"Stylist::process_invalidations({:?}, {:?}, {:?})",
|
||||
element,
|
||||
self.invalid_scopes,
|
||||
self.invalid_elements,
|
||||
"Stylist::process_invalidations({:?}, {:?}, {:?})",
|
||||
element, self.invalid_scopes, self.invalid_elements,
|
||||
);
|
||||
|
||||
{
|
||||
|
@ -209,8 +217,7 @@ impl StylesheetInvalidationSet {
|
|||
};
|
||||
|
||||
if self.fully_invalid {
|
||||
debug!("process_invalidations: fully_invalid({:?})",
|
||||
element);
|
||||
debug!("process_invalidations: fully_invalid({:?})", element);
|
||||
data.hint.insert(RestyleHint::restyle_subtree());
|
||||
return true;
|
||||
}
|
||||
|
@ -221,8 +228,11 @@ impl StylesheetInvalidationSet {
|
|||
return false;
|
||||
}
|
||||
|
||||
let case_sensitivity =
|
||||
element.as_node().owner_doc().quirks_mode().classes_and_ids_case_sensitivity();
|
||||
let case_sensitivity = element
|
||||
.as_node()
|
||||
.owner_doc()
|
||||
.quirks_mode()
|
||||
.classes_and_ids_case_sensitivity();
|
||||
self.process_invalidations_in_subtree(element, snapshots, case_sensitivity)
|
||||
}
|
||||
|
||||
|
@ -252,8 +262,10 @@ impl StylesheetInvalidationSet {
|
|||
}
|
||||
|
||||
if data.hint.contains_subtree() {
|
||||
debug!("process_invalidations_in_subtree: {:?} was already invalid",
|
||||
element);
|
||||
debug!(
|
||||
"process_invalidations_in_subtree: {:?} was already invalid",
|
||||
element
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -261,8 +273,10 @@ impl StylesheetInvalidationSet {
|
|||
let snapshot = element_wrapper.as_ref().and_then(|e| e.snapshot());
|
||||
for invalidation in &self.invalid_scopes {
|
||||
if invalidation.matches(element, snapshot, case_sensitivity) {
|
||||
debug!("process_invalidations_in_subtree: {:?} matched subtree {:?}",
|
||||
element, invalidation);
|
||||
debug!(
|
||||
"process_invalidations_in_subtree: {:?} matched subtree {:?}",
|
||||
element, invalidation
|
||||
);
|
||||
data.hint.insert(RestyleHint::restyle_subtree());
|
||||
return true;
|
||||
}
|
||||
|
@ -273,8 +287,10 @@ impl StylesheetInvalidationSet {
|
|||
if !data.hint.contains(RestyleHint::RESTYLE_SELF) {
|
||||
for invalidation in &self.invalid_elements {
|
||||
if invalidation.matches(element, snapshot, case_sensitivity) {
|
||||
debug!("process_invalidations_in_subtree: {:?} matched self {:?}",
|
||||
element, invalidation);
|
||||
debug!(
|
||||
"process_invalidations_in_subtree: {:?} matched self {:?}",
|
||||
element, invalidation
|
||||
);
|
||||
data.hint.insert(RestyleHint::RESTYLE_SELF);
|
||||
self_invalid = true;
|
||||
break;
|
||||
|
@ -295,40 +311,45 @@ impl StylesheetInvalidationSet {
|
|||
}
|
||||
|
||||
if any_children_invalid {
|
||||
debug!("Children of {:?} changed, setting dirty descendants",
|
||||
element);
|
||||
debug!(
|
||||
"Children of {:?} changed, setting dirty descendants",
|
||||
element
|
||||
);
|
||||
unsafe { element.set_dirty_descendants() }
|
||||
}
|
||||
|
||||
return self_invalid || any_children_invalid
|
||||
return self_invalid || any_children_invalid;
|
||||
}
|
||||
|
||||
fn scan_component(
|
||||
component: &Component<SelectorImpl>,
|
||||
invalidation: &mut Option<Invalidation>)
|
||||
{
|
||||
invalidation: &mut Option<Invalidation>,
|
||||
) {
|
||||
match *component {
|
||||
Component::LocalName(LocalName { ref name, ref lower_name }) => {
|
||||
Component::LocalName(LocalName {
|
||||
ref name,
|
||||
ref lower_name,
|
||||
}) => {
|
||||
if invalidation.as_ref().map_or(true, |s| !s.is_id_or_class()) {
|
||||
*invalidation = Some(Invalidation::LocalName {
|
||||
name: name.clone(),
|
||||
lower_name: lower_name.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
Component::Class(ref class) => {
|
||||
if invalidation.as_ref().map_or(true, |s| !s.is_id()) {
|
||||
*invalidation = Some(Invalidation::Class(class.clone()));
|
||||
}
|
||||
}
|
||||
},
|
||||
Component::ID(ref id) => {
|
||||
if invalidation.is_none() {
|
||||
*invalidation = Some(Invalidation::ID(id.clone()));
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// Ignore everything else, at least for now.
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,7 +368,10 @@ impl StylesheetInvalidationSet {
|
|||
/// of the selector, to reduce the amount of traversal we need to do
|
||||
/// when flushing invalidations.
|
||||
fn collect_invalidations(&mut self, selector: &Selector<SelectorImpl>) {
|
||||
debug!("StylesheetInvalidationSet::collect_invalidations({:?})", selector);
|
||||
debug!(
|
||||
"StylesheetInvalidationSet::collect_invalidations({:?})",
|
||||
selector
|
||||
);
|
||||
|
||||
let mut element_invalidation: Option<Invalidation> = None;
|
||||
let mut subtree_invalidation: Option<Invalidation> = None;
|
||||
|
@ -369,7 +393,7 @@ impl StylesheetInvalidationSet {
|
|||
None => break,
|
||||
Some(combinator) => {
|
||||
scan_for_subtree_invalidation = combinator.is_ancestor();
|
||||
}
|
||||
},
|
||||
}
|
||||
scan_for_element_invalidation = false;
|
||||
}
|
||||
|
@ -408,44 +432,41 @@ impl StylesheetInvalidationSet {
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Document(..) |
|
||||
Namespace(..) |
|
||||
Import(..) |
|
||||
Media(..) |
|
||||
Supports(..) => {
|
||||
},
|
||||
Document(..) | Namespace(..) | Import(..) | Media(..) | Supports(..) => {
|
||||
// Do nothing, relevant nested rules are visited as part of the
|
||||
// iteration.
|
||||
}
|
||||
},
|
||||
FontFace(..) => {
|
||||
// Do nothing, @font-face doesn't affect computed style
|
||||
// information. We'll restyle when the font face loads, if
|
||||
// needed.
|
||||
}
|
||||
},
|
||||
Keyframes(ref lock) => {
|
||||
let keyframes_rule = lock.read_with(guard);
|
||||
if device.animation_name_may_be_referenced(&keyframes_rule.name) {
|
||||
debug!(" > Found @keyframes rule potentially referenced \
|
||||
from the page, marking the whole tree invalid.");
|
||||
debug!(
|
||||
" > Found @keyframes rule potentially referenced \
|
||||
from the page, marking the whole tree invalid."
|
||||
);
|
||||
self.fully_invalid = true;
|
||||
} else {
|
||||
// Do nothing, this animation can't affect the style of
|
||||
// existing elements.
|
||||
}
|
||||
}
|
||||
CounterStyle(..) |
|
||||
Page(..) |
|
||||
Viewport(..) |
|
||||
FontFeatureValues(..) => {
|
||||
debug!(" > Found unsupported rule, marking the whole subtree \
|
||||
invalid.");
|
||||
},
|
||||
CounterStyle(..) | Page(..) | Viewport(..) | FontFeatureValues(..) => {
|
||||
debug!(
|
||||
" > Found unsupported rule, marking the whole subtree \
|
||||
invalid."
|
||||
);
|
||||
|
||||
// TODO(emilio): Can we do better here?
|
||||
//
|
||||
// At least in `@page`, we could check the relevant media, I
|
||||
// guess.
|
||||
self.fully_invalid = true;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue