Document.body should return the first body / frameset child of the html element
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Sep 2015 17:40:10 +0000 (17:40 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Sep 2015 17:40:10 +0000 (17:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148787
<rdar://problem/22566850>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Document.body should return the *first* body / frameset child of the html
element as per the specification:
https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2

Chrome and Firefox both behave correctly. However, WebKit was prioritizing
frameset over body. This patch fixes this.

No new tests, already covered by existing test.

* dom/Document.cpp:
(WebCore::Document::bodyOrFrameset):

LayoutTests:

Rebaseline test now that a new check is passing.

* http/tests/w3c/html/dom/documents/dom-tree-accessors/document.body-getter-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189354 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/w3c/html/dom/documents/dom-tree-accessors/document.body-getter-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp

index 26582a4..3bc1b01 100644 (file)
@@ -1,3 +1,15 @@
+2015-09-04  Chris Dumez  <cdumez@apple.com>
+
+        Document.body should return the first body / frameset child of the html element
+        https://bugs.webkit.org/show_bug.cgi?id=148787
+        <rdar://problem/22566850>
+
+        Reviewed by Ryosuke Niwa.
+
+        Rebaseline test now that a new check is passing.
+
+        * http/tests/w3c/html/dom/documents/dom-tree-accessors/document.body-getter-expected.txt:
+
 2015-09-04  Ryosuke Niwa  <rniwa@webkit.org>
 
         Import css/css-color-3
index 801faff..95598e3 100644 (file)
@@ -1,9 +1,9 @@
 
 PASS Childless document 
 PASS Childless html element 
-FAIL Body followed by frameset inside the html element assert_equals: expected Element node <body></body> but got Element node <frameset></frameset>
+PASS Body followed by frameset inside the html element 
 PASS Frameset followed by body inside the html element 
-FAIL Body followed by frameset inside a non-HTML html element assert_equals: expected null but got Element node <frameset></frameset>
+FAIL Body followed by frameset inside a non-HTML html element assert_equals: expected null but got Element node <body></body>
 FAIL Frameset followed by body inside a non-HTML html element assert_equals: expected null but got Element node <frameset></frameset>
 PASS Non-HTML body followed by body inside the html element 
 PASS Non-HTML frameset followed by body inside the html element 
index d434b85..a4fe275 100644 (file)
@@ -1,3 +1,23 @@
+2015-09-04  Chris Dumez  <cdumez@apple.com>
+
+        Document.body should return the first body / frameset child of the html element
+        https://bugs.webkit.org/show_bug.cgi?id=148787
+        <rdar://problem/22566850>
+
+        Reviewed by Ryosuke Niwa.
+
+        Document.body should return the *first* body / frameset child of the html
+        element as per the specification:
+        https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2
+
+        Chrome and Firefox both behave correctly. However, WebKit was prioritizing
+        frameset over body. This patch fixes this.
+
+        No new tests, already covered by existing test.
+
+        * dom/Document.cpp:
+        (WebCore::Document::bodyOrFrameset):
+
 2015-09-04  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         Fix the !ENABLE(VIDEO) build after r189023
index 0f637aa..897bae2 100644 (file)
@@ -2477,13 +2477,15 @@ HTMLBodyElement* Document::body() const
 
 HTMLElement* Document::bodyOrFrameset() const
 {
-    // If the document element contains both a frameset and a body, the frameset wins.
+    // Return the first body or frameset child of the html element.
     auto* element = documentElement();
     if (!element)
         return nullptr;
-    if (auto* frameset = childrenOfType<HTMLFrameSetElement>(*element).first())
-        return frameset;
-    return childrenOfType<HTMLBodyElement>(*element).first();
+    for (auto& child : childrenOfType<HTMLElement>(*element)) {
+        if (is<HTMLBodyElement>(child) || is<HTMLFrameSetElement>(child))
+            return &child;
+    }
+    return nullptr;
 }
 
 void Document::setBodyOrFrameset(PassRefPtr<HTMLElement> prpNewBody, ExceptionCode& ec)