diff options
author | bors-servo <infra@servo.org> | 2023-05-04 11:35:25 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-04 11:35:25 +0200 |
commit | 4e37d07ea4f2bba124f78f17873fbb02c66d1cdb (patch) | |
tree | 7dc272f33fa36faf34423d42dfa2e4654be09843 /components/layout_thread_2020/dom_wrapper.rs | |
parent | f29834608aee21c1845737067c16f92adfb77f08 (diff) | |
parent | 72302e2dae6c4726ae657f7b5b8b048f9f64ccf2 (diff) | |
download | servo-4e37d07ea4f2bba124f78f17873fbb02c66d1cdb.tar.gz servo-4e37d07ea4f2bba124f78f17873fbb02c66d1cdb.zip |
Auto merge of #29699 - mrobinson:add-html-body-tag, r=mukilan
Detect body elements during layout
During layout it is often useful, for various specification reasons, to know if an element is the `<body>` element of an `<html>` element root. There are a couple places where a brittle heuristic is used to detect `<body>` elements. This information is going to be even more important to properly handle `<html>` elements that inherit their overflow property from their `<body>` children.
Implementing this properly requires updating the DOM wrapper interface. This check does reach up to the parent of thread-safe nodes, but this is essentially the same kind of operation that `parent_style()` does, so is ostensibly safe.
This change should not change any behavior and is just a preparation step for properly handle `<body>` overflow.
<!-- Please describe your changes on the following line: -->
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes do not require tests because it does not change behavior.
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components/layout_thread_2020/dom_wrapper.rs')
-rw-r--r-- | components/layout_thread_2020/dom_wrapper.rs | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/components/layout_thread_2020/dom_wrapper.rs b/components/layout_thread_2020/dom_wrapper.rs index e37bbd38274..2b5f30f3cd9 100644 --- a/components/layout_thread_2020/dom_wrapper.rs +++ b/components/layout_thread_2020/dom_wrapper.rs @@ -428,6 +428,40 @@ impl<'le> fmt::Debug for ServoLayoutElement<'le> { } } +impl<'dom> ServoLayoutElement<'dom> { + /// Returns true if this element is the body child of an html element root element. + fn is_body_element_of_html_element_root(&self) -> bool { + if self.element.local_name() != &local_name!("body") { + return false; + } + + self.parent_element() + .map(|element| { + element.is_root() && element.element.local_name() == &local_name!("html") + }) + .unwrap_or(false) + } + + /// Returns the parent element of this element, if it has one. + fn parent_element(&self) -> Option<Self> { + self.element + .upcast() + .composed_parent_node_ref() + .and_then(as_element) + } + + // Returns true is this is the root element. + fn is_root(&self) -> bool { + match self.as_node().parent_node() { + None => false, + Some(node) => match node.script_type_id() { + NodeTypeId::Document(_) => true, + _ => false, + }, + } + } +} + impl<'le> TElement for ServoLayoutElement<'le> { type ConcreteNode = ServoLayoutNode<'le>; type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>; @@ -679,11 +713,7 @@ impl<'le> TElement for ServoLayoutElement<'le> { } fn is_html_document_body_element(&self) -> bool { - // This is only used for the "tables inherit from body" quirk, which we - // don't implement. - // - // FIXME(emilio): We should be able to give the right answer though! - false + self.is_body_element_of_html_element_root() } fn synthesize_presentational_hints_for_legacy_attributes<V>( @@ -839,13 +869,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { } fn is_root(&self) -> bool { - match self.as_node().parent_node() { - None => false, - Some(node) => match node.script_type_id() { - NodeTypeId::Document(_) => true, - _ => false, - }, - } + ServoLayoutElement::is_root(self) } fn is_empty(&self) -> bool { @@ -981,11 +1005,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { } fn is_html_element_in_html_document(&self) -> bool { - if !self.element.is_html_element() { - return false; - } - - self.as_node().owner_doc().is_html_document() + self.element.is_html_element() && self.as_node().owner_doc().is_html_document() } } @@ -1361,6 +1381,10 @@ impl<'le> ThreadSafeLayoutElement<'le> for ServoThreadSafeLayoutElement<'le> { fn is_shadow_host(&self) -> bool { self.element.shadow_root().is_some() } + + fn is_body_element_of_html_element_root(&self) -> bool { + self.element.is_body_element_of_html_element_root() + } } /// This implementation of `::selectors::Element` is used for implementing lazy |