improvement: body element check (#37442)

Created a new method `HTMLElement::is_body_element` that replaces
`HTMLBodyElement::is_the_html_body_element`.

Testing: Existing WPT tests should pass.
Fixes: https://github.com/servo/servo/issues/37429

---------

Signed-off-by: iamlockon <xdddxyyyxzzz123@gmail.com>
This commit is contained in:
Jay Wang 2025-06-15 13:11:32 +09:00 committed by GitHub
parent c74a422e4c
commit 96adb1e959
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 24 additions and 28 deletions

View file

@ -145,7 +145,6 @@ use crate::dom::hashchangeevent::HashChangeEvent;
use crate::dom::htmlanchorelement::HTMLAnchorElement;
use crate::dom::htmlareaelement::HTMLAreaElement;
use crate::dom::htmlbaseelement::HTMLBaseElement;
use crate::dom::htmlbodyelement::HTMLBodyElement;
use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmlembedelement::HTMLEmbedElement;
@ -2490,12 +2489,11 @@ impl Document {
}
pub(crate) fn get_body_attribute(&self, local_name: &LocalName) -> DOMString {
match self
.GetBody()
.and_then(DomRoot::downcast::<HTMLBodyElement>)
{
Some(ref body) => body.upcast::<Element>().get_string_attribute(local_name),
None => DOMString::new(),
match self.GetBody() {
Some(ref body) if body.is_body_element() => {
body.upcast::<Element>().get_string_attribute(local_name)
},
_ => DOMString::new(),
}
}
@ -2505,10 +2503,7 @@ impl Document {
value: DOMString,
can_gc: CanGc,
) {
if let Some(ref body) = self
.GetBody()
.and_then(DomRoot::downcast::<HTMLBodyElement>)
{
if let Some(ref body) = self.GetBody().filter(|elem| elem.is_body_element()) {
let body = body.upcast::<Element>();
let value = body.parse_attribute(&ns!(), local_name, value);
body.set_attribute(local_name, value, can_gc);

View file

@ -55,17 +55,6 @@ impl HTMLBodyElement {
can_gc,
)
}
/// <https://drafts.csswg.org/cssom-view/#the-html-body-element>
pub(crate) fn is_the_html_body_element(&self) -> bool {
let self_node = self.upcast::<Node>();
let root_elem = self.upcast::<Element>().root_element();
let root_node = root_elem.upcast::<Node>();
root_node.is_parent_of(self_node) &&
self_node
.preceding_siblings()
.all(|n| !n.is::<HTMLBodyElement>())
}
}
impl HTMLBodyElementMethods<crate::DomTypeHolder> for HTMLBodyElement {

View file

@ -439,7 +439,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
/// <https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetparent>
fn GetOffsetParent(&self, can_gc: CanGc) -> Option<DomRoot<Element>> {
if self.is::<HTMLBodyElement>() || self.is::<HTMLHtmlElement>() {
if self.is_body_element() || self.is::<HTMLHtmlElement>() {
return None;
}
@ -452,7 +452,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsettop
fn OffsetTop(&self, can_gc: CanGc) -> i32 {
if self.is::<HTMLBodyElement>() {
if self.is_body_element() {
return 0;
}
@ -465,7 +465,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
// https://drafts.csswg.org/cssom-view/#dom-htmlelement-offsetleft
fn OffsetLeft(&self, can_gc: CanGc) -> i32 {
if self.is::<HTMLBodyElement>() {
if self.is_body_element() {
return 0;
}
@ -817,6 +817,19 @@ impl HTMLElement {
}
}
/// <https://html.spec.whatwg.org/multipage/#the-body-element-2>
pub(crate) fn is_body_element(&self) -> bool {
let self_node = self.upcast::<Node>();
self_node.GetParentNode().is_some_and(|parent| {
let parent_node = parent.upcast::<Node>();
(self_node.is::<HTMLBodyElement>() || self_node.is::<HTMLFrameSetElement>()) &&
parent_node.is::<HTMLHtmlElement>() &&
self_node
.preceding_siblings()
.all(|n| !n.is::<HTMLBodyElement>() && !n.is::<HTMLFrameSetElement>())
})
}
/// <https://html.spec.whatwg.org/multipage/#category-submit>
pub(crate) fn is_submittable_element(&self) -> bool {
match self.upcast::<Node>().type_id() {

View file

@ -92,7 +92,6 @@ use crate::dom::element::{CustomElementCreationMode, Element, ElementCreator, Se
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlbodyelement::HTMLBodyElement;
use crate::dom::htmlcanvaselement::{HTMLCanvasElement, LayoutHTMLCanvasElementHelpers};
use crate::dom::htmlcollection::HTMLCollection;
use crate::dom::htmlelement::HTMLElement;
@ -958,8 +957,8 @@ impl Node {
let in_quirks_mode = document.quirks_mode() == QuirksMode::Quirks;
let is_root = self.downcast::<Element>().is_some_and(|e| e.is_root());
let is_body_element = self
.downcast::<HTMLBodyElement>()
.is_some_and(|e| e.is_the_html_body_element());
.downcast::<HTMLElement>()
.is_some_and(|e| e.is_body_element());
// "4. If the element is the root element and document is not in quirks mode
// return max(viewport scrolling area width/height, viewport width/height)."