Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Document's 'body' attribute #1431

Merged
merged 1 commit into from Dec 20, 2013
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -156,6 +156,7 @@ DOMInterfaces = {
'createElement',
'createTextNode',
'title',
'body',
],
},

@@ -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;
@@ -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<AbstractNode> {
do self.GetDocumentElement().filtered |root| {
match root.type_id() {
ElementNodeTypeId(HTMLHtmlElementTypeId) => true,
_ => false
}
}
}

pub fn GetBody(&self, _: AbstractDocument) -> Option<AbstractNode> {
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<AbstractNode>) -> 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<AbstractNode> = 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))
@@ -496,6 +496,10 @@ impl AbstractNode {
self.node().AppendChild(self, node)
}

pub fn ReplaceChild(self, node: AbstractNode, child: AbstractNode) -> Fallible<AbstractNode> {
self.mut_node().ReplaceChild(node, child)
}

pub fn RemoveChild(self, node: AbstractNode) -> Fallible<AbstractNode> {
self.node().RemoveChild(self, node)
}
@@ -0,0 +1,75 @@
<html>
<head>
<script src="harness.js"></script>
</head>
<body>
<script>
// test1: existing document's body
{
isnot(document.body, null, "test1-0, existing document's body");
is_a(document.body, HTMLBodyElement, "test1-1, exising document's body");
is(document.body && document.body.tagName, "BODY", "test1-2, existing document's body");
}

/* TODO: Depends on https://github.com/mozilla/servo/issues/1430
// test2: replace document's body with new body
{
let new_body = document.createElement("body");
isnot(new_body, null, "test2-0, replace document's body with new body");
document.body = new_body;
is(new_body, document.body, "test2-1, replace document's body with new body");
}
// test3: replace document's body with new frameset
{
let new_frameset = document.createElement("frameset");
isnot(new_frameset, null, "test2-0, replace document's body with new frameset");
document.body = new_frameset;
is(new_frameset, document.body, "test2-1, replace document's body with new frameset");
}
*/

// test4: append an invalid element to a new document
{
let new_document = new Document();
new_document.appendChild(new_document.createElement("html"));
let new_div = new_document.createElement("div");

isnot(new_div, null, "test4-0, append an invalid element to a new document");

new_document.body = new_div;
is(new_document.body, null, "test4-1, append an invalid element to a new document");
}

// test5: append body to a new document
{
let new_document = new Document();
new_document.appendChild(new_document.createElement("html"));
let new_body = new_document.createElement("body");

isnot(new_body, null, "test5-0, append body to a new document");
is_a(new_body, HTMLBodyElement, "test5-1, append body to a new document");
is(new_body && new_body.tagName, "BODY", "test5-2, append body to a new document");

new_document.body = new_body;
is(new_document.body, new_body, "test5-3, append body to a new document");
}

// test6: append frameset to a new document
{
let new_document = new Document();
new_document.appendChild(new_document.createElement("html"));
let new_frameset = new_document.createElement("frameset");

isnot(new_frameset, null, "test6-0, append frameset to a new document");
is_a(new_frameset, HTMLFrameSetElement, "test6-1, append frameset to a new document");
is(new_frameset && new_frameset.tagName, "FRAMESET", "test6-2, append frameset to a new document");

new_document.body = new_frameset;
is(new_document.body, new_frameset, "test6-3, append frameset to a new document");
}

finish();
</script>
</body>
</html>
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.