diff options
Diffstat (limited to 'src/components/script/dom/node.rs')
-rw-r--r-- | src/components/script/dom/node.rs | 172 |
1 files changed, 136 insertions, 36 deletions
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 680f6fbab19..0929060086f 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -455,6 +455,12 @@ impl<'self, View> AbstractNode<View> { } } +impl AbstractNode<ScriptView> { + pub fn AppendChild(self, node: AbstractNode<ScriptView>) -> Fallible<AbstractNode<ScriptView>> { + self.node().AppendChild(self, node) + } +} + impl<View> Iterator<AbstractNode<View>> for AbstractNodeChildrenIterator<View> { fn next(&mut self) -> Option<AbstractNode<View>> { let node = self.current_node; @@ -691,6 +697,129 @@ impl Node<ScriptView> { } } + // http://dom.spec.whatwg.org/#concept-node-adopt + pub fn adopt(node: AbstractNode<ScriptView>, + document: AbstractDocument) { + // Step 1. + match node.parent_node() { + Some(parent) => parent.remove_child(node), + None => (), + } + + // Step 2. + if node.node().owner_doc() != document { + for descendant in node.traverse_preorder() { + descendant.mut_node().set_owner_doc(document); + } + } + + // Step 3. + // If node is an element, it is _affected by a base URL change_. + } + + // http://dom.spec.whatwg.org/#concept-node-pre-insert + pub fn pre_insert(node: AbstractNode<ScriptView>, + parent: AbstractNode<ScriptView>, + child: Option<AbstractNode<ScriptView>>) -> Fallible<AbstractNode<ScriptView>> { + fn is_inclusive_ancestor_of(node: AbstractNode<ScriptView>, + parent: AbstractNode<ScriptView>) -> bool { + node == parent || parent.ancestors().any(|ancestor| ancestor == node) + } + // Step 1. + match parent.type_id() { + // DocumentNodeTypeId | + DocumentFragmentNodeTypeId | + ElementNodeTypeId(*) => (), + _ => { + return Err(HierarchyRequest); + }, + } + + // Step 2. + if is_inclusive_ancestor_of(node, parent) { + return Err(HierarchyRequest); + } + + // Step 3. + match child { + Some(child) => { + if child.parent_node() != Some(parent) { + return Err(NotFound); + } + }, + None => (), + } + + // Step 4. + match node.type_id() { + DocumentFragmentNodeTypeId | + DoctypeNodeTypeId | + ElementNodeTypeId(_) | + TextNodeTypeId | + // ProcessingInstructionNodeTypeId | + CommentNodeTypeId => (), + /*_ => { XXX #838 + return Err(HierarchyRequest); + },*/ + } + + // Step 5. + match node.type_id() { + TextNodeTypeId => { + if false { // XXX #838 + return Err(HierarchyRequest); + } + }, + DoctypeNodeTypeId => { + if true { // XXX #838 + return Err(HierarchyRequest); + } + }, + _ => (), + } + + // Step 6. + // XXX #838 + + // Step 7-8. + let referenceChild = if child != Some(node) { + child + } else { + node.next_sibling() + }; + + // Step 9. + Node::adopt(node, parent.node().owner_doc()); + + // Step 10. + Node::insert(node, parent, referenceChild, false); + + // Step 11. + return Ok(node) + } + + pub fn insert(node: AbstractNode<ScriptView>, + parent: AbstractNode<ScriptView>, + child: Option<AbstractNode<ScriptView>>, + _suppressObserversFlag: bool) { + // Step 1-3: ranges. + // Step 4. + let nodes = match node.type_id() { + DocumentFragmentNodeTypeId => node.children().collect(), + _ => ~[node], + }; + + // Step 5: DocumentFragment, mutation records. + // Step 6: DocumentFragment. + // Step 7: mutation records. + // Step 8. + for node in nodes.iter() { + parent.add_child(*node, child); + } + + // Step 9: _node is inserted_. + } + // http://dom.spec.whatwg.org/#concept-node-replace-all pub fn replace_all(&mut self, abstract_self: AbstractNode<ScriptView>, @@ -740,8 +869,11 @@ impl Node<ScriptView> { Ok(()) } - pub fn InsertBefore(&mut self, _node: AbstractNode<ScriptView>, _child: Option<AbstractNode<ScriptView>>) -> Fallible<AbstractNode<ScriptView>> { - fail!("stub") + pub fn InsertBefore(&self, + node: AbstractNode<ScriptView>, + child: Option<AbstractNode<ScriptView>>) -> Fallible<AbstractNode<ScriptView>> { + self.wait_until_safe_to_modify_dom(); + return Node::pre_insert(node, node, child); } fn wait_until_safe_to_modify_dom(&self) { @@ -749,43 +881,11 @@ impl Node<ScriptView> { document.document().wait_until_safe_to_modify_dom(); } - pub fn AppendChild(&mut self, + pub fn AppendChild(&self, abstract_self: AbstractNode<ScriptView>, node: AbstractNode<ScriptView>) -> Fallible<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) { - return Err(HierarchyRequest); - } - - // TODO: Should we handle WRONG_DOCUMENT_ERR here? - self.wait_until_safe_to_modify_dom(); - - // 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.mut_node().add_to_doc(node, self.owner_doc()); - Ok(node) + return Node::pre_insert(node, abstract_self, None); } pub fn ReplaceChild(&mut self, _node: AbstractNode<ScriptView>, _child: AbstractNode<ScriptView>) -> Fallible<AbstractNode<ScriptView>> { |