diff options
author | bors-servo <release+servo@mozilla.com> | 2013-09-09 22:09:44 -0700 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2013-09-09 22:09:44 -0700 |
commit | 62f0d19fabe218cbd720892283de2122820ea01e (patch) | |
tree | 812f63f0f59a18096dcbabe9985b9ea3a7f90366 /src/components/script/dom/node.rs | |
parent | ae0d531dd6857d62777190bd91248600c21c9900 (diff) | |
parent | 0d4cfd0eb93456d9ead4fa77fcc5990511745240 (diff) | |
download | servo-62f0d19fabe218cbd720892283de2122820ea01e.tar.gz servo-62f0d19fabe218cbd720892283de2122820ea01e.zip |
auto merge of #880 : ILyoan/servo/appendChild, r=jdm
Diffstat (limited to 'src/components/script/dom/node.rs')
-rw-r--r-- | src/components/script/dom/node.rs | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 6ed81517567..e137d4c31d0 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -5,7 +5,7 @@ //! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements. use dom::bindings::node; -use dom::bindings::utils::{WrapperCache, DOMString, null_string, str, ErrorResult}; +use dom::bindings::utils::{WrapperCache, DOMString, null_string, str, ErrorResult, NotFound, HierarchyRequest}; use dom::bindings::utils::{BindingObject, CacheableWrapper, rust_box}; use dom::bindings; use dom::characterdata::CharacterData; @@ -263,6 +263,10 @@ impl<'self, View> AbstractNode<View> { self.transmute_mut(f) } + pub fn is_doctype(self) -> bool { + self.type_id() == DoctypeNodeTypeId + } + pub fn is_comment(self) -> bool { self.type_id() == CommentNodeTypeId } @@ -499,19 +503,19 @@ impl Node<ScriptView> { } pub fn GetFirstChild(&self) -> Option<AbstractNode<ScriptView>> { - None + self.first_child } pub fn GetLastChild(&self) -> Option<AbstractNode<ScriptView>> { - None + self.last_child } pub fn GetPreviousSibling(&self) -> Option<AbstractNode<ScriptView>> { - None + self.prev_sibling } pub fn GetNextSibling(&self) -> Option<AbstractNode<ScriptView>> { - None + self.next_sibling } pub fn GetNodeValue(&self) -> DOMString { @@ -553,16 +557,68 @@ impl Node<ScriptView> { fail!("stub") } - pub fn AppendChild(&mut self, _node: AbstractNode<ScriptView>, _rv: &mut ErrorResult) -> AbstractNode<ScriptView> { - fail!("stub") + pub fn AppendChild(&mut self, + abstract_self: AbstractNode<ScriptView>, + node: AbstractNode<ScriptView>, + rv: &mut ErrorResult) -> AbstractNode<ScriptView> { + fn is_hierarchy_request_err(this_node: AbstractNode<ScriptView>, + new_child: AbstractNode<ScriptView>) -> bool { + if new_child.is_doctype() { + return true; + } + if !this_node.is_element() { + // FIXME: This should also work for Document and DocumentFragments when they inherit from node. + // per jgraham + return true; + } + if this_node == new_child { + return true; + } + for ancestor in this_node.ancestors() { + if ancestor == new_child { + return true; + } + } + false + } + + if is_hierarchy_request_err(abstract_self, node) { + *rv = Err(HierarchyRequest); + } + + // TODO: Should we handle WRONG_DOCUMENT_ERR here? + + if rv.is_ok() { + // If the node already exists it is removed from current parent node. + node.parent_node().map(|parent| parent.remove_child(node)); + abstract_self.add_child(node); + } + node } pub fn ReplaceChild(&mut self, _node: AbstractNode<ScriptView>, _child: AbstractNode<ScriptView>, _rv: &mut ErrorResult) -> AbstractNode<ScriptView> { fail!("stub") } - pub fn RemoveChild(&mut self, _node: AbstractNode<ScriptView>, _rv: &mut ErrorResult) -> AbstractNode<ScriptView> { - fail!("stub") + pub fn RemoveChild(&mut self, + abstract_self: AbstractNode<ScriptView>, + node: AbstractNode<ScriptView>, + rv: &mut ErrorResult) -> AbstractNode<ScriptView> { + fn is_not_found_err(this_node: AbstractNode<ScriptView>, + old_child: AbstractNode<ScriptView>) -> bool { + match old_child.parent_node() { + Some(parent) if parent == this_node => false, + _ => true + } + } + + if is_not_found_err(abstract_self, node) { + *rv = Err(NotFound); + } + if rv.is_ok() { + abstract_self.remove_child(node); + } + node } pub fn Normalize(&mut self) { |