aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2024-12-19 20:24:42 +0100
committerGitHub <noreply@github.com>2024-12-19 19:24:42 +0000
commit50c9c727788bfb3b7b108eacd404321542598530 (patch)
tree000321dfeb4c9c5ea4f8ce2945ee40255b26fc74 /components
parentb7460bcb844e3c6e6c887cc9f3d818f0454b0ea3 (diff)
downloadservo-50c9c727788bfb3b7b108eacd404321542598530.tar.gz
servo-50c9c727788bfb3b7b108eacd404321542598530.zip
layout: Lay out Shadow DOM elements (#34701)
When an element is a shadow root, lay out the shadow root elements instead of the non-shadow children. This fixes some tests and introduces some failures, due to bugs in the Shadow DOM implementation. In general, this is very low impact as the Shadow DOM is still disabled by default. At least this gets elements rendering when the preference is turned on though. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components')
-rw-r--r--components/layout_2020/dom_traversal.rs5
-rw-r--r--components/script/dom/element.rs21
2 files changed, 18 insertions, 8 deletions
diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs
index f5f27fa7e08..7c7697be740 100644
--- a/components/layout_2020/dom_traversal.rs
+++ b/components/layout_2020/dom_traversal.rs
@@ -10,6 +10,7 @@ use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSaf
use script_layout_interface::{LayoutElementType, LayoutNodeType};
use selectors::Element as SelectorsElement;
use servo_arc::Arc as ServoArc;
+use style::dom::{TElement, TShadowRoot};
use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
use style::values::generics::counters::{Content, ContentItem};
@@ -467,6 +468,10 @@ pub(crate) fn iter_child_nodes<'dom, Node>(parent: Node) -> impl Iterator<Item =
where
Node: NodeExt<'dom>,
{
+ if let Some(shadow) = parent.as_element().and_then(|e| e.shadow_root()) {
+ return iter_child_nodes(shadow.as_node());
+ };
+
let mut next = parent.first_child();
std::iter::from_fn(move || {
next.inspect(|child| {
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 44838256cf5..2bef3e3508f 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -558,19 +558,24 @@ impl Element {
};
shadow_root.bind_to_tree(&bind_context);
- self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
+ let node = self.upcast::<Node>();
+ node.dirty(NodeDamage::OtherNodeDamage);
+ node.rev_version();
Ok(shadow_root)
}
pub fn detach_shadow(&self) {
- if let Some(ref shadow_root) = self.shadow_root() {
- self.upcast::<Node>().note_dirty_descendants();
- shadow_root.detach();
- self.ensure_rare_data().shadow_root = None;
- } else {
- debug_assert!(false, "Trying to detach a non-attached shadow root");
- }
+ let Some(ref shadow_root) = self.shadow_root() else {
+ unreachable!("Trying to detach a non-attached shadow root");
+ };
+
+ let node = self.upcast::<Node>();
+ node.note_dirty_descendants();
+ node.rev_version();
+
+ shadow_root.detach();
+ self.ensure_rare_data().shadow_root = None;
}
// https://html.spec.whatwg.org/multipage/#translation-mode