mirror of
https://github.com/servo/servo.git
synced 2025-10-04 02:29:12 +01:00
style: Use CascadeFlags for what they're for.
Now that we have an Element around on cascade, we can stop using the cascade flags mechanism to pass various element-related state, like "is this element the root", or "should it use the item-based display fixup". That fixes handwaviness in the handling of those flags from style reparenting, and code duplication to handle tricky stuff like :visited. There are a number of other changes that are worth noticing: * skip_root_and_item_based_display_fixup is renamed to skip_item_display_fixup: TElement::is_root() already implies being the document element, which by definition is not native anonymous and not a pseudo-element. Thus, you never get fixed-up if your NAC or a pseudo, which is what the code tried to avoid, so the only fixup with a point is the item one, which is necessary. * The pseudo-element probing code was refactored to return early a Option::<CascadeInputs>::None, which is nicer than what it was doing. * The visited_links_enabled check has moved to selector-matching time. The rest of the checks aren't based on whether the element is a link, or are properly guarded by parent_style.visited_style().is_some() or visited_rules.is_some(). Thus you can transitively infer that no element will end up with a :visited style, not even from style reparenting. Anyway, the underlying reason why I want the element in StyleAdjuster is because we're going to implement an adjustment in there depending on the tag of the element (converting display: contents to display: none depending on the tag), so computing that information eagerly, including a hash lookup, wouldn't be nice.
This commit is contained in:
parent
104f5c2553
commit
cd04664fb9
11 changed files with 233 additions and 298 deletions
|
@ -9,9 +9,8 @@ use context::{CascadeInputs, ElementCascadeInputs, StyleContext};
|
|||
use data::{ElementStyles, EagerPseudoStyles};
|
||||
use dom::TElement;
|
||||
use log::LogLevel::Trace;
|
||||
use matching::{CascadeVisitedMode, MatchMethods};
|
||||
use properties::{AnimationRules, CascadeFlags, ComputedValues};
|
||||
use properties::cascade;
|
||||
use matching::MatchMethods;
|
||||
use properties::{AnimationRules, ComputedValues};
|
||||
use properties::longhands::display::computed_value::T as Display;
|
||||
use rule_tree::StrongRuleNode;
|
||||
use selector_parser::{PseudoElement, SelectorImpl};
|
||||
|
@ -161,7 +160,8 @@ where
|
|||
parent_style.map_or(false, |s| s.visited_style().is_some());
|
||||
|
||||
let visited_rules =
|
||||
if inside_link || self.element.is_link() {
|
||||
if self.context.shared.visited_styles_enabled &&
|
||||
(inside_link || self.element.is_link()) {
|
||||
let visited_matching_results =
|
||||
self.match_primary(VisitedHandlingMode::RelevantLinkVisited);
|
||||
Some(visited_matching_results.rule_node)
|
||||
|
@ -291,29 +291,37 @@ where
|
|||
layout_parent_style: Option<&ComputedValues>,
|
||||
pseudo: Option<&PseudoElement>,
|
||||
) -> ResolvedStyle {
|
||||
let mut style_if_visited = None;
|
||||
if parent_style.map_or(false, |s| s.visited_style().is_some()) ||
|
||||
inputs.visited_rules.is_some() {
|
||||
style_if_visited = Some(self.cascade_style(
|
||||
inputs.visited_rules.as_ref().or(inputs.rules.as_ref()),
|
||||
/* style_if_visited = */ None,
|
||||
parent_style,
|
||||
layout_parent_style,
|
||||
CascadeVisitedMode::Visited,
|
||||
pseudo,
|
||||
));
|
||||
}
|
||||
debug_assert!(
|
||||
self.element.implemented_pseudo_element().is_none() || pseudo.is_none(),
|
||||
"Pseudo-elements can't have other pseudos!"
|
||||
);
|
||||
debug_assert!(pseudo.map_or(true, |p| p.is_eager()));
|
||||
|
||||
ResolvedStyle(
|
||||
self.cascade_style(
|
||||
inputs.rules.as_ref(),
|
||||
style_if_visited,
|
||||
parent_style,
|
||||
layout_parent_style,
|
||||
CascadeVisitedMode::Unvisited,
|
||||
pseudo,
|
||||
)
|
||||
)
|
||||
let implemented_pseudo = self.element.implemented_pseudo_element();
|
||||
let pseudo = pseudo.or(implemented_pseudo.as_ref());
|
||||
|
||||
let mut conditions = Default::default();
|
||||
let values = self.context.shared.stylist.cascade_style_and_visited(
|
||||
Some(self.element),
|
||||
pseudo,
|
||||
inputs,
|
||||
&self.context.shared.guards,
|
||||
parent_style,
|
||||
parent_style,
|
||||
layout_parent_style,
|
||||
&self.context.thread_local.font_metrics_provider,
|
||||
Some(&self.context.thread_local.rule_cache),
|
||||
&mut conditions,
|
||||
);
|
||||
|
||||
self.context.thread_local.rule_cache.insert_if_possible(
|
||||
&self.context.shared.guards,
|
||||
&values,
|
||||
pseudo,
|
||||
&conditions
|
||||
);
|
||||
|
||||
ResolvedStyle(values)
|
||||
}
|
||||
|
||||
/// Cascade the element and pseudo-element styles with the default parents.
|
||||
|
@ -469,7 +477,7 @@ where
|
|||
) -> Option<StrongRuleNode> {
|
||||
debug!("Match pseudo {:?} for {:?}, visited: {:?}",
|
||||
self.element, pseudo_element, visited_handling);
|
||||
debug_assert!(pseudo_element.is_eager() || pseudo_element.is_lazy());
|
||||
debug_assert!(pseudo_element.is_eager());
|
||||
debug_assert!(self.element.implemented_pseudo_element().is_none(),
|
||||
"Element pseudos can't have any other pseudo.");
|
||||
|
||||
|
@ -524,87 +532,4 @@ where
|
|||
|
||||
Some(rule_node)
|
||||
}
|
||||
|
||||
fn cascade_style(
|
||||
&mut self,
|
||||
rules: Option<&StrongRuleNode>,
|
||||
style_if_visited: Option<Arc<ComputedValues>>,
|
||||
mut parent_style: Option<&ComputedValues>,
|
||||
layout_parent_style: Option<&ComputedValues>,
|
||||
cascade_visited: CascadeVisitedMode,
|
||||
pseudo: Option<&PseudoElement>,
|
||||
) -> Arc<ComputedValues> {
|
||||
debug_assert!(
|
||||
self.element.implemented_pseudo_element().is_none() || pseudo.is_none(),
|
||||
"Pseudo-elements can't have other pseudos!"
|
||||
);
|
||||
debug_assert!(pseudo.map_or(true, |p| p.is_eager()));
|
||||
|
||||
let mut cascade_flags = CascadeFlags::empty();
|
||||
|
||||
if self.element.skip_root_and_item_based_display_fixup() ||
|
||||
pseudo.map_or(false, |p| p.skip_item_based_display_fixup()) {
|
||||
cascade_flags.insert(CascadeFlags::SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP);
|
||||
}
|
||||
|
||||
if pseudo.is_none() && self.element.is_link() {
|
||||
cascade_flags.insert(CascadeFlags::IS_LINK);
|
||||
if self.element.is_visited_link() &&
|
||||
self.context.shared.visited_styles_enabled {
|
||||
cascade_flags.insert(CascadeFlags::IS_VISITED_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
if cascade_visited.visited_dependent_only() {
|
||||
// If this element is a link, we want its visited style to inherit
|
||||
// from the regular style of its parent, because only the
|
||||
// visitedness of the relevant link should influence style.
|
||||
if pseudo.is_some() || !self.element.is_link() {
|
||||
parent_style = parent_style.map(|s| {
|
||||
s.visited_style().unwrap_or(s)
|
||||
});
|
||||
}
|
||||
cascade_flags.insert(CascadeFlags::VISITED_DEPENDENT_ONLY);
|
||||
}
|
||||
if !self.element.is_native_anonymous() &&
|
||||
pseudo.is_none() &&
|
||||
self.element.is_root()
|
||||
{
|
||||
cascade_flags.insert(CascadeFlags::IS_ROOT_ELEMENT);
|
||||
}
|
||||
|
||||
let implemented_pseudo = self.element.implemented_pseudo_element();
|
||||
let pseudo = pseudo.or(implemented_pseudo.as_ref());
|
||||
|
||||
let mut conditions = Default::default();
|
||||
let values =
|
||||
cascade(
|
||||
self.context.shared.stylist.device(),
|
||||
pseudo,
|
||||
rules.unwrap_or(self.context.shared.stylist.rule_tree().root()),
|
||||
&self.context.shared.guards,
|
||||
parent_style,
|
||||
parent_style,
|
||||
layout_parent_style,
|
||||
style_if_visited,
|
||||
&self.context.thread_local.font_metrics_provider,
|
||||
cascade_flags,
|
||||
self.context.shared.quirks_mode(),
|
||||
Some(&self.context.thread_local.rule_cache),
|
||||
&mut conditions,
|
||||
Some(self.element),
|
||||
);
|
||||
|
||||
self.context
|
||||
.thread_local
|
||||
.rule_cache
|
||||
.insert_if_possible(
|
||||
&self.context.shared.guards,
|
||||
&values,
|
||||
pseudo,
|
||||
&conditions
|
||||
);
|
||||
|
||||
values
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue