aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/node.rs
diff options
context:
space:
mode:
authorMs2ger <ms2ger@gmail.com>2013-10-25 20:04:05 +0200
committerMs2ger <ms2ger@gmail.com>2013-10-29 21:48:28 +0100
commit2ca1eede9a6549a64b2e40a654571bc257b57963 (patch)
tree9740eab1ab7ad6ad0d11f11ba2b9f79c136be42f /src/components/script/dom/node.rs
parent2c3d5ec79f62744be530d6bc9ea7210a1116c828 (diff)
downloadservo-2ca1eede9a6549a64b2e40a654571bc257b57963.tar.gz
servo-2ca1eede9a6549a64b2e40a654571bc257b57963.zip
Implement insertBefore and reimplement appendChild.
Diffstat (limited to 'src/components/script/dom/node.rs')
-rw-r--r--src/components/script/dom/node.rs172
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>> {