mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
style: Restyle pseudo-elements as well on part attribute changes
Refactor a bit the code to unify how we deal with this conditional restyling (we had similar code for MustCascadeChildrenIfInheritResetStyle). Differential Revision: https://phabricator.services.mozilla.com/D172890
This commit is contained in:
parent
398df68d38
commit
78c1c53ccd
6 changed files with 132 additions and 180 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
//! Per-node data used in style calculation.
|
||||
|
||||
use crate::computed_value_flags::ComputedValueFlags;
|
||||
use crate::context::{SharedStyleContext, StackLimitChecker};
|
||||
use crate::dom::TElement;
|
||||
use crate::invalidation::element::invalidator::InvalidationResult;
|
||||
|
@ -193,8 +194,6 @@ impl ElementStyles {
|
|||
|
||||
/// Whether this element uses viewport units.
|
||||
pub fn viewport_unit_usage(&self) -> ViewportUnitUsage {
|
||||
use crate::computed_value_flags::ComputedValueFlags;
|
||||
|
||||
fn usage_from_flags(flags: ComputedValueFlags) -> ViewportUnitUsage {
|
||||
if flags.intersects(ComputedValueFlags::USES_VIEWPORT_UNITS_ON_CONTAINER_QUERIES) {
|
||||
return ViewportUnitUsage::FromQuery;
|
||||
|
@ -366,52 +365,88 @@ impl ElementData {
|
|||
|
||||
/// Returns the kind of restyling that we're going to need to do on this
|
||||
/// element, based of the stored restyle hint.
|
||||
pub fn restyle_kind(&self, shared_context: &SharedStyleContext) -> RestyleKind {
|
||||
pub fn restyle_kind(&self, shared_context: &SharedStyleContext) -> Option<RestyleKind> {
|
||||
if shared_context.traversal_flags.for_animation_only() {
|
||||
return self.restyle_kind_for_animation(shared_context);
|
||||
}
|
||||
|
||||
if !self.has_styles() {
|
||||
return RestyleKind::MatchAndCascade;
|
||||
let style = match self.styles.primary {
|
||||
Some(ref s) => s,
|
||||
None => return Some(RestyleKind::MatchAndCascade),
|
||||
};
|
||||
|
||||
let hint = self.hint;
|
||||
if hint.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if self.hint.match_self() {
|
||||
return RestyleKind::MatchAndCascade;
|
||||
let needs_to_match_self = hint.intersects(RestyleHint::RESTYLE_SELF) ||
|
||||
(hint.intersects(RestyleHint::RESTYLE_SELF_IF_PSEUDO) && style.is_pseudo_style());
|
||||
if needs_to_match_self {
|
||||
return Some(RestyleKind::MatchAndCascade);
|
||||
}
|
||||
|
||||
if self.hint.has_replacements() {
|
||||
if hint.has_replacements() {
|
||||
debug_assert!(
|
||||
!self.hint.has_animation_hint(),
|
||||
!hint.has_animation_hint(),
|
||||
"Animation only restyle hint should have already processed"
|
||||
);
|
||||
return RestyleKind::CascadeWithReplacements(self.hint & RestyleHint::replacements());
|
||||
return Some(RestyleKind::CascadeWithReplacements(
|
||||
hint & RestyleHint::replacements(),
|
||||
));
|
||||
}
|
||||
|
||||
debug_assert!(
|
||||
self.hint.has_recascade_self(),
|
||||
"We definitely need to do something: {:?}!",
|
||||
self.hint
|
||||
);
|
||||
return RestyleKind::CascadeOnly;
|
||||
let needs_to_recascade_self = hint.intersects(RestyleHint::RECASCADE_SELF) ||
|
||||
(hint.intersects(RestyleHint::RECASCADE_SELF_IF_INHERIT_RESET_STYLE) &&
|
||||
style.flags.contains(ComputedValueFlags::INHERITS_RESET_STYLE));
|
||||
if needs_to_recascade_self {
|
||||
return Some(RestyleKind::CascadeOnly);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the kind of restyling for animation-only restyle.
|
||||
fn restyle_kind_for_animation(&self, shared_context: &SharedStyleContext) -> RestyleKind {
|
||||
fn restyle_kind_for_animation(
|
||||
&self,
|
||||
shared_context: &SharedStyleContext,
|
||||
) -> Option<RestyleKind> {
|
||||
debug_assert!(shared_context.traversal_flags.for_animation_only());
|
||||
debug_assert!(
|
||||
self.has_styles(),
|
||||
"Unstyled element shouldn't be traversed during \
|
||||
animation-only traversal"
|
||||
"animation traversal doesn't care about unstyled elements"
|
||||
);
|
||||
|
||||
// return either CascadeWithReplacements or CascadeOnly in case of
|
||||
// animation-only restyle. I.e. animation-only restyle never does
|
||||
// selector matching.
|
||||
if self.hint.has_animation_hint() {
|
||||
return RestyleKind::CascadeWithReplacements(self.hint & RestyleHint::for_animations());
|
||||
// FIXME: We should ideally restyle here, but it is a hack to work around our weird
|
||||
// animation-only traversal stuff: If we're display: none and the rules we could
|
||||
// match could change, we consider our style up-to-date. This is because re-cascading with
|
||||
// and old style doesn't guarantee returning the correct animation style (that's
|
||||
// bug 1393323). So if our display changed, and it changed from display: none, we would
|
||||
// incorrectly forget about it and wouldn't be able to correctly style our descendants
|
||||
// later.
|
||||
// XXX Figure out if this still makes sense.
|
||||
let hint = self.hint;
|
||||
if self.styles.is_display_none() && hint.intersects(RestyleHint::RESTYLE_SELF) {
|
||||
return None;
|
||||
}
|
||||
|
||||
return RestyleKind::CascadeOnly;
|
||||
let style = self.styles.primary();
|
||||
// Return either CascadeWithReplacements or CascadeOnly in case of
|
||||
// animation-only restyle. I.e. animation-only restyle never does
|
||||
// selector matching.
|
||||
if hint.has_animation_hint() {
|
||||
return Some(RestyleKind::CascadeWithReplacements(
|
||||
hint & RestyleHint::for_animations(),
|
||||
));
|
||||
}
|
||||
|
||||
let needs_to_recascade_self = hint.intersects(RestyleHint::RECASCADE_SELF) ||
|
||||
(hint.intersects(RestyleHint::RECASCADE_SELF_IF_INHERIT_RESET_STYLE) &&
|
||||
style.flags.contains(ComputedValueFlags::INHERITS_RESET_STYLE));
|
||||
if needs_to_recascade_self {
|
||||
return Some(RestyleKind::CascadeOnly);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
/// Drops any restyle state from the element.
|
||||
|
@ -482,7 +517,13 @@ impl ElementData {
|
|||
) {
|
||||
return false;
|
||||
}
|
||||
if !self.styles.primary().get_box().clone_container_type().is_normal() {
|
||||
if !self
|
||||
.styles
|
||||
.primary()
|
||||
.get_box()
|
||||
.clone_container_type()
|
||||
.is_normal()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue