From e8182afa1452769ae41710537d663357fff2acff Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 26 Jan 2018 00:52:40 -0500 Subject: [PATCH] Bug 1276438 part 3. Align the .body setter with the spec a bit better. r=mystor There are two changes here: 1) We allow setting .body even if the root element is not an . This is what the spec says to do, and what we used to do before the changes in bug 366200. No tests for this yet, pending https://github.com/whatwg/html/issues/3403 getting resolved. 2) We use GetBody(), not GetBodyElement(), to look for an existing thing to replace. This matters if there are s involved. MozReview-Commit-ID: JCaQGHKgzE7 --- dom/base/nsDocument.cpp | 8 ++- .../dom-tree-accessors/Document.body.html | 50 +++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 29a5d00514e5..00a7872c782c 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -6826,18 +6826,16 @@ nsIDocument::SetBody(nsGenericHTMLElement* newBody, ErrorResult& rv) nsCOMPtr root = GetRootElement(); // The body element must be either a body tag or a frameset tag. And we must - // have a html root tag, otherwise GetBody will not return the newly set - // body. + // have a root element to be able to add kids to it. if (!newBody || !newBody->IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset) || - !root || !root->IsHTMLElement() || - !root->IsHTMLElement(nsGkAtoms::html)) { + !root) { rv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); return; } // Use DOM methods so that we pass through the appropriate security checks. - nsCOMPtr currentBody = GetBodyElement(); + nsCOMPtr currentBody = GetBody(); if (currentBody) { root->ReplaceChild(*newBody, *currentBody, rv); } else { diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html index 07f1edf939c6..7d8548885a67 100644 --- a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html +++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html @@ -166,4 +166,54 @@ test(function() { doc.body = new_frameset; assert_equals(doc.body, new_frameset, "test6-3, append frameset to a new document"); }, "Setting document.body to a new frameset element."); + +test(function() { + var doc = createDocument(); + var html = doc.appendChild(doc.createElement("html")); + var f = + html.appendChild(doc.createElement("frameset")); + assert_equals(doc.body, f); + + var b = doc.createElement("body"); + doc.body = b; + + assert_equals(f.parentNode, null, + "Frameset should have been removed from the tree"); + assert_equals(doc.body, b, "Body should be the new doc.body"); +}, "Setting document.body to a body will replace an existing frameset if there is one."); + +test(function() { + var doc = createDocument(); + var html = doc.appendChild(doc.createElement("html")); + var b = + html.appendChild(doc.createElement("body")); + assert_equals(doc.body, b); + + var f = doc.createElement("frameset"); + doc.body = f; + + assert_equals(b.parentNode, null, + "Body should have been removed from the tree"); + assert_equals(doc.body, f, "Frameset should be the new doc.body"); +}, "Setting document.body to a frameset will replace an existing body if there is one."); + +test(function() { + var doc = createDocument(); + var html = doc.appendChild(doc.createElement("html")); + var b = + html.appendChild(doc.createElement("body")); + var f1 = html.appendChild(doc.createElement("frameset")); + assert_equals(doc.body, b); + + var f2 = doc.createElement("frameset"); + doc.body = f2; + + assert_equals(b.parentNode, null, + "Body should have been removed from the tree"); + assert_equals(f1.parentNode, html, + "Frameset following body should still be in the tree."); + assert_equals(doc.body, f2, "New frameset should be the new doc.body"); + assert_equals(f2.nextSibling, f1, "New frameset should have replaced the body"); +}, "Setting document.body to a frameset will replace the first existing body/frameset."); +