diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index b7e01242793..da82eae2a8c 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -156,6 +156,7 @@ DOMInterfaces = { 'createElement', 'createTextNode', 'title', + 'body', ], }, diff --git a/src/components/script/dom/bindings/codegen/Document.webidl b/src/components/script/dom/bindings/codegen/Document.webidl index 10d212910fc..ade88958b36 100644 --- a/src/components/script/dom/bindings/codegen/Document.webidl +++ b/src/components/script/dom/bindings/codegen/Document.webidl @@ -100,7 +100,7 @@ partial interface Document { [SetterThrows] attribute DOMString title; // attribute DOMString dir; - //(HTML only) attribute HTMLElement? body; + attribute HTMLElement? body; //(HTML only)readonly attribute HTMLHeadElement? head; //(HTML only)readonly attribute HTMLCollection images; //(HTML only)readonly attribute HTMLCollection embeds; diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index 0e366f76a80..511620aead0 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -5,12 +5,12 @@ use dom::comment::Comment; use dom::bindings::codegen::DocumentBinding; use dom::bindings::utils::{Reflectable, Reflector, Traceable, reflect_dom_object}; -use dom::bindings::utils::{ErrorResult, Fallible, NotSupported, InvalidCharacter}; +use dom::bindings::utils::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest}; use dom::bindings::utils::DOMString; use dom::bindings::utils::{xml_name_type, InvalidXMLName}; use dom::documentfragment::DocumentFragment; use dom::element::{Element}; -use dom::element::{HTMLHeadElementTypeId, HTMLTitleElementTypeId}; +use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId, HTMLBodyElementTypeId, HTMLFrameSetElementTypeId}; use dom::event::{AbstractEvent, Event}; use dom::htmlcollection::HTMLCollection; use dom::htmldocument::HTMLDocument; @@ -295,6 +295,63 @@ impl Document { Ok(()) } + fn get_html_element(&self) -> Option { + do self.GetDocumentElement().filtered |root| { + match root.type_id() { + ElementNodeTypeId(HTMLHtmlElementTypeId) => true, + _ => false + } + } + } + + pub fn GetBody(&self, _: AbstractDocument) -> Option { + match self.get_html_element() { + None => None, + Some(root) => { + do root.children().find |child| { + match child.type_id() { + ElementNodeTypeId(HTMLBodyElementTypeId) | + ElementNodeTypeId(HTMLFrameSetElementTypeId) => true, + _ => false + } + } + } + } + } + + // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body + pub fn SetBody(&self, abstract_self: AbstractDocument, new_body: Option) -> ErrorResult { + // Step 1. + match new_body { + Some(node) => { + match node.type_id() { + ElementNodeTypeId(HTMLBodyElementTypeId) | ElementNodeTypeId(HTMLFrameSetElementTypeId) => {} + _ => return Err(HierarchyRequest) + } + } + None => return Err(HierarchyRequest) + } + + // Step 2. + let old_body: Option = self.GetBody(abstract_self); + if old_body == new_body { + return Ok(()); + } + + // Step 3. + match self.get_html_element() { + // Step 4. + None => return Err(HierarchyRequest), + Some(root) => { + match old_body { + Some(child) => { root.ReplaceChild(new_body.unwrap(), child); } + None => { root.AppendChild(new_body.unwrap()); } + } + } + } + Ok(()) + } + pub fn GetElementsByName(&self, name: DOMString) -> @mut HTMLCollection { self.createHTMLCollection(|elem| elem.get_attr(None, "name").is_some() && eq_slice(elem.get_attr(None, "name").unwrap(), name)) diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 53296d12da7..f9f11a280c7 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -496,6 +496,10 @@ impl AbstractNode { self.node().AppendChild(self, node) } + pub fn ReplaceChild(self, node: AbstractNode, child: AbstractNode) -> Fallible { + self.mut_node().ReplaceChild(node, child) + } + pub fn RemoveChild(self, node: AbstractNode) -> Fallible { self.node().RemoveChild(self, node) } diff --git a/src/test/html/content/test_document_body.html b/src/test/html/content/test_document_body.html new file mode 100644 index 00000000000..880a36370f5 --- /dev/null +++ b/src/test/html/content/test_document_body.html @@ -0,0 +1,75 @@ + + + + + + + +