mirror of
https://github.com/servo/servo.git
synced 2025-09-27 23:30:08 +01:00
layout: Support storing layout data for two-level nested pseudo-elements (#38678)
Add basic support for storing layout data for pseudo-elements nested to up to two levels. This removes the last unstored layout result and fixes a double-borrow issue. This change does not add properly parsing nor styling of these element types, but does prepare for those changes which must come from stylo. Testing: This fixes a intermittent panic in `tests/wpt/tests/css/css-lists/nested-marker-styling.html` Fixes: #38177. Closes: #38183. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
43da933247
commit
99ce81cf64
10 changed files with 273 additions and 177 deletions
|
@ -4,10 +4,10 @@
|
|||
|
||||
use bitflags::bitflags;
|
||||
use layout_api::combine_id_with_fragment_type;
|
||||
use layout_api::wrapper_traits::PseudoElementChain;
|
||||
use malloc_size_of::malloc_size_of_is_0;
|
||||
use malloc_size_of_derive::MallocSizeOf;
|
||||
use style::dom::OpaqueNode;
|
||||
use style::selector_parser::PseudoElement;
|
||||
|
||||
/// This data structure stores fields that are common to all non-base
|
||||
/// Fragment types and should generally be the first member of all
|
||||
|
@ -114,23 +114,29 @@ malloc_size_of_is_0!(FragmentFlags);
|
|||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
|
||||
pub(crate) struct Tag {
|
||||
pub(crate) node: OpaqueNode,
|
||||
pub(crate) pseudo: Option<PseudoElement>,
|
||||
pub(crate) pseudo_element_chain: PseudoElementChain,
|
||||
}
|
||||
|
||||
impl Tag {
|
||||
/// Create a new Tag for a non-pseudo element. This is mainly used for
|
||||
/// matching existing tags, since it does not accept an `info` argument.
|
||||
pub(crate) fn new(node: OpaqueNode) -> Self {
|
||||
Tag { node, pseudo: None }
|
||||
Tag {
|
||||
node,
|
||||
pseudo_element_chain: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new Tag for a pseudo element. This is mainly used for
|
||||
/// matching existing tags, since it does not accept an `info` argument.
|
||||
pub(crate) fn new_pseudo(node: OpaqueNode, pseudo: Option<PseudoElement>) -> Self {
|
||||
Tag { node, pseudo }
|
||||
pub(crate) fn new_pseudo(node: OpaqueNode, pseudo_element_chain: PseudoElementChain) -> Self {
|
||||
Tag {
|
||||
node,
|
||||
pseudo_element_chain,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_display_list_fragment_id(self) -> u64 {
|
||||
combine_id_with_fragment_type(self.node.id(), self.pseudo.into())
|
||||
combine_id_with_fragment_type(self.node.id(), self.pseudo_element_chain.primary.into())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,8 +71,15 @@ impl FragmentTree {
|
|||
|
||||
fragment_tree.find(|fragment, _level, containing_block| {
|
||||
if let Some(tag) = fragment.tag() {
|
||||
invalid_animating_nodes.remove(&AnimationSetKey::new(tag.node, tag.pseudo));
|
||||
invalid_image_animating_nodes.remove(&AnimationSetKey::new(tag.node, tag.pseudo));
|
||||
// TODO: Support animations on nested pseudo-elements.
|
||||
invalid_animating_nodes.remove(&AnimationSetKey::new(
|
||||
tag.node,
|
||||
tag.pseudo_element_chain.primary,
|
||||
));
|
||||
invalid_image_animating_nodes.remove(&AnimationSetKey::new(
|
||||
tag.node,
|
||||
tag.pseudo_element_chain.primary,
|
||||
));
|
||||
}
|
||||
|
||||
fragment.set_containing_block(containing_block);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue