aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_thread_2020/dom_wrapper.rs
diff options
context:
space:
mode:
authorbors-servo <infra@servo.org>2023-05-04 11:35:25 +0200
committerGitHub <noreply@github.com>2023-05-04 11:35:25 +0200
commit4e37d07ea4f2bba124f78f17873fbb02c66d1cdb (patch)
tree7dc272f33fa36faf34423d42dfa2e4654be09843 /components/layout_thread_2020/dom_wrapper.rs
parentf29834608aee21c1845737067c16f92adfb77f08 (diff)
parent72302e2dae6c4726ae657f7b5b8b048f9f64ccf2 (diff)
downloadservo-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.rs58
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