Add some wrapper types to propagate styles out of style resolver.

We'll use these next to propagate information about style reuse to the ElementDataFlags.

MozReview-Commit-ID: Dya6vgzydpL
This commit is contained in:
Bobby Holley 2017-09-13 12:22:18 -07:00
parent 9092e6b4c2
commit 7a7070e075
5 changed files with 118 additions and 57 deletions

View file

@ -49,12 +49,52 @@ struct MatchingResults {
relevant_link_found: bool,
}
/// The primary style of an element or an element-backed pseudo-element.
pub struct PrimaryStyle {
/// The style per se.
/// A style returned from the resolver machinery.
pub struct ResolvedStyle {
/// The style itself.
pub style: Arc<ComputedValues>,
}
/// The primary style of an element or an element-backed pseudo-element.
pub struct PrimaryStyle(pub ResolvedStyle);
/// A set of style returned from the resolver machinery.
pub struct ResolvedElementStyles {
/// Primary style.
pub primary: PrimaryStyle,
/// Pseudo styles.
pub pseudos: EagerPseudoStyles,
}
impl ResolvedStyle {
/// Creates a new ResolvedStyle.
pub fn new(style: Arc<ComputedValues>) -> Self {
ResolvedStyle { style }
}
}
impl PrimaryStyle {
/// Convenience accessor for the style.
pub fn style(&self) -> &ComputedValues {
&*self.0.style
}
}
impl From<ResolvedStyle> for Arc<ComputedValues> {
fn from(r: ResolvedStyle) -> Arc<ComputedValues> {
r.style
}
}
impl From<ResolvedElementStyles> for ElementStyles {
fn from(r: ResolvedElementStyles) -> ElementStyles {
ElementStyles {
primary: Some(r.primary.0.into()),
pseudos: r.pseudos,
}
}
}
fn with_default_parent_styles<E, F, R>(element: E, f: F) -> R
where
E: TElement,
@ -140,8 +180,8 @@ where
None
};
PrimaryStyle {
style: self.cascade_style_and_visited(
PrimaryStyle(
self.cascade_style_and_visited(
CascadeInputs {
rules: Some(primary_results.rule_node),
visited_rules,
@ -149,8 +189,8 @@ where
parent_style,
layout_parent_style,
/* pseudo = */ None,
),
}
)
)
}
/// Resolve the style of a given element, and all its eager pseudo-elements.
@ -158,7 +198,7 @@ where
&mut self,
parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
) -> ElementStyles {
) -> ResolvedElementStyles {
let primary_style =
self.resolve_primary_style(parent_style, layout_parent_style);
@ -166,10 +206,10 @@ where
if self.element.implemented_pseudo_element().is_none() {
let layout_parent_style_for_pseudo =
if primary_style.style.is_display_contents() {
if primary_style.style().is_display_contents() {
layout_parent_style
} else {
Some(&*primary_style.style)
Some(primary_style.style())
};
SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
let pseudo_style = self.resolve_pseudo_style(
@ -188,16 +228,15 @@ where
})
}
ElementStyles {
// FIXME(emilio): Remove the Option<>.
primary: Some(primary_style.style),
ResolvedElementStyles {
primary: primary_style,
pseudos: pseudo_styles,
}
}
/// Resolve an element's styles with the default inheritance parent/layout
/// parents.
pub fn resolve_style_with_default_parents(&mut self) -> ElementStyles {
pub fn resolve_style_with_default_parents(&mut self) -> ResolvedElementStyles {
with_default_parent_styles(self.element, |parent_style, layout_parent_style| {
self.resolve_style(parent_style, layout_parent_style)
})
@ -207,7 +246,7 @@ where
pub fn cascade_style_and_visited_with_default_parents(
&mut self,
inputs: CascadeInputs,
) -> Arc<ComputedValues> {
) -> ResolvedStyle {
with_default_parent_styles(self.element, |parent_style, layout_parent_style| {
self.cascade_style_and_visited(
inputs,
@ -224,7 +263,7 @@ where
parent_style: Option<&ComputedValues>,
layout_parent_style: Option<&ComputedValues>,
pseudo: Option<&PseudoElement>,
) -> Arc<ComputedValues> {
) -> ResolvedStyle {
let mut style_if_visited = None;
if parent_style.map_or(false, |s| s.get_visited_style().is_some()) ||
inputs.visited_rules.is_some() {
@ -237,38 +276,41 @@ where
pseudo,
));
}
self.cascade_style(
inputs.rules.as_ref(),
style_if_visited,
parent_style,
layout_parent_style,
CascadeVisitedMode::Unvisited,
pseudo,
)
ResolvedStyle {
style: self.cascade_style(
inputs.rules.as_ref(),
style_if_visited,
parent_style,
layout_parent_style,
CascadeVisitedMode::Unvisited,
pseudo,
)
}
}
/// Cascade the element and pseudo-element styles with the default parents.
pub fn cascade_styles_with_default_parents(
&mut self,
inputs: ElementCascadeInputs,
) -> ElementStyles {
) -> ResolvedElementStyles {
with_default_parent_styles(self.element, move |parent_style, layout_parent_style| {
let primary_style = PrimaryStyle {
style: self.cascade_style_and_visited(
let primary_style = PrimaryStyle(
self.cascade_style_and_visited(
inputs.primary,
parent_style,
layout_parent_style,
/* pseudo = */ None,
),
};
)
);
let mut pseudo_styles = EagerPseudoStyles::default();
if let Some(mut pseudo_array) = inputs.pseudos.into_array() {
let layout_parent_style_for_pseudo =
if primary_style.style.is_display_contents() {
if primary_style.style().is_display_contents() {
layout_parent_style
} else {
Some(&*primary_style.style)
Some(primary_style.style())
};
for (i, inputs) in pseudo_array.iter_mut().enumerate() {
@ -278,23 +320,23 @@ where
let style =
self.cascade_style_and_visited(
inputs,
Some(&*primary_style.style),
Some(&*primary_style.style()),
layout_parent_style_for_pseudo,
Some(&pseudo),
);
if !matches!(self.pseudo_resolution, PseudoElementResolution::Force) &&
eager_pseudo_is_definitely_not_generated(&pseudo, &style) {
eager_pseudo_is_definitely_not_generated(&pseudo, &style.style) {
continue;
}
pseudo_styles.set(&pseudo, style);
pseudo_styles.set(&pseudo, style.style);
}
}
}
ElementStyles {
primary: Some(primary_style.style),
ResolvedElementStyles {
primary: primary_style,
pseudos: pseudo_styles,
}
})
@ -307,7 +349,7 @@ where
layout_parent_style: Option<&ComputedValues>,
) -> Option<Arc<ComputedValues>> {
let rules = self.match_pseudo(
&originating_element_style.style,
originating_element_style.style(),
pseudo,
VisitedHandlingMode::AllLinksUnvisited
);
@ -317,9 +359,9 @@ where
};
let mut visited_rules = None;
if originating_element_style.style.get_visited_style().is_some() {
if originating_element_style.style().get_visited_style().is_some() {
visited_rules = self.match_pseudo(
&originating_element_style.style,
originating_element_style.style(),
pseudo,
VisitedHandlingMode::RelevantLinkVisited,
);
@ -330,10 +372,10 @@ where
rules: Some(rules),
visited_rules
},
Some(&originating_element_style.style),
Some(originating_element_style.style()),
layout_parent_style,
Some(pseudo),
))
).style)
}
fn match_primary(