Bläddra i källkod

LibWeb: Frameset should be the body element if it comes before body

Fixes one WPT test: "Frameset followed by body inside the html element"
http://wpt.live/html/dom/documents/dom-tree-accessors/Document.body.html
ronak69 9 månader sedan
förälder
incheckning
5f9a36feac

+ 2 - 0
Tests/LibWeb/Text/expected/DOM/Document-body-element-frameset-before-body.txt

@@ -0,0 +1,2 @@
+BODY == BODY
+FRAMESET == FRAMESET

+ 17 - 0
Tests/LibWeb/Text/input/DOM/Document-body-element-frameset-before-body.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        var doc = document.implementation.createHTMLDocument("");
+        doc.removeChild(doc.documentElement);
+        var html = doc.appendChild(doc.createElement("html"));
+        html.appendChild(doc.createElement("body"));
+        html.appendChild(doc.createElement("frameset"));
+        println(`BODY == ${doc.body.tagName}`);
+        html.firstChild.remove();
+        html.firstChild.remove();
+        html.appendChild(doc.createElement("frameset"));
+        html.appendChild(doc.createElement("body"));
+        println(`FRAMESET == ${doc.body.tagName}`);
+    });
+</script>

+ 7 - 6
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -842,17 +842,18 @@ void Document::set_dir(String const& dir)
         html->set_dir(dir);
 }
 
+// https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2
 HTML::HTMLElement* Document::body()
 {
+    // The body element of a document is the first of the html element's children that is either
+    // a body element or a frameset element, or null if there is no such element.
     auto* html = html_element();
     if (!html)
         return nullptr;
-    auto* first_body = html->first_child_of_type<HTML::HTMLBodyElement>();
-    if (first_body)
-        return first_body;
-    auto* first_frameset = html->first_child_of_type<HTML::HTMLFrameSetElement>();
-    if (first_frameset)
-        return first_frameset;
+    for (auto* child = html->first_child(); child; child = child->next_sibling()) {
+        if (is<HTML::HTMLBodyElement>(*child) || is<HTML::HTMLFrameSetElement>(*child))
+            return static_cast<HTML::HTMLElement*>(child);
+    }
     return nullptr;
 }