mirror of
https://github.com/servo/servo.git
synced 2025-07-23 23:33:43 +01:00
Fix IS_IN_SHADOW_TREE flag for descendants after Node::remove call (#34803)
* Consider a UnbindContext to be tree-connected if its in a shadow root Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Properly track whether a node is in a shadow tree after removing subtree Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Update WPT expectations Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
e8f75c9aea
commit
1ab55e6b11
3 changed files with 34 additions and 15 deletions
|
@ -316,17 +316,28 @@ impl Node {
|
|||
|
||||
/// Clean up flags and unbind from tree.
|
||||
pub fn complete_remove_subtree(root: &Node, context: &UnbindContext) {
|
||||
for node in root.traverse_preorder(ShadowIncluding::Yes) {
|
||||
// Out-of-document elements never have the descendants flag set.
|
||||
node.set_flag(
|
||||
NodeFlags::IS_IN_DOC |
|
||||
NodeFlags::IS_CONNECTED |
|
||||
NodeFlags::HAS_DIRTY_DESCENDANTS |
|
||||
NodeFlags::HAS_SNAPSHOT |
|
||||
NodeFlags::HANDLED_SNAPSHOT,
|
||||
false,
|
||||
);
|
||||
// Flags that reset when a node is disconnected
|
||||
const RESET_FLAGS: NodeFlags = NodeFlags::IS_IN_DOC
|
||||
.union(NodeFlags::IS_CONNECTED)
|
||||
.union(NodeFlags::HAS_DIRTY_DESCENDANTS)
|
||||
.union(NodeFlags::HAS_SNAPSHOT)
|
||||
.union(NodeFlags::HANDLED_SNAPSHOT);
|
||||
|
||||
for node in root.traverse_preorder(ShadowIncluding::No) {
|
||||
node.set_flag(RESET_FLAGS | NodeFlags::IS_IN_SHADOW_TREE, false);
|
||||
|
||||
// If the element has a shadow root attached to it then we traverse that as well,
|
||||
// but without touching the IS_IN_SHADOW_TREE flags of the children
|
||||
if let Some(shadow_root) = node.downcast::<Element>().and_then(Element::shadow_root) {
|
||||
for node in shadow_root
|
||||
.upcast::<Node>()
|
||||
.traverse_preorder(ShadowIncluding::Yes)
|
||||
{
|
||||
node.set_flag(RESET_FLAGS, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for node in root.traverse_preorder(ShadowIncluding::Yes) {
|
||||
node.clean_up_style_and_layout_data();
|
||||
|
||||
|
@ -608,6 +619,11 @@ impl Node {
|
|||
self.flags.get().contains(NodeFlags::IS_CONNECTED)
|
||||
}
|
||||
|
||||
/// Return true iff the node's root is a Document or a ShadowRoot
|
||||
pub fn is_connected_to_tree(&self) -> bool {
|
||||
self.is_connected() || self.is_in_shadow_tree()
|
||||
}
|
||||
|
||||
/// Returns the type ID of this node.
|
||||
pub fn type_id(&self) -> NodeTypeId {
|
||||
match *self.eventtarget.type_id() {
|
||||
|
@ -3559,6 +3575,8 @@ pub struct UnbindContext<'a> {
|
|||
/// The next sibling of the inclusive ancestor that was removed.
|
||||
pub next_sibling: Option<&'a Node>,
|
||||
/// Whether the tree is connected.
|
||||
///
|
||||
/// A tree is connected iff it's root is a Document or a ShadowRoot.
|
||||
pub tree_connected: bool,
|
||||
/// Whether the tree is in doc.
|
||||
pub tree_in_doc: bool,
|
||||
|
@ -3577,7 +3595,7 @@ impl<'a> UnbindContext<'a> {
|
|||
parent,
|
||||
prev_sibling,
|
||||
next_sibling,
|
||||
tree_connected: parent.is_connected(),
|
||||
tree_connected: parent.is_connected_to_tree(),
|
||||
tree_in_doc: parent.is_in_doc(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue