r3557 jmb - /trunk/dom/src/core/node.c

netsurf at semichrome.net netsurf at semichrome.net
Sat Sep 22 02:28:55 BST 2007


Author: jmb
Date: Sat Sep 22 02:28:54 2007
New Revision: 3557

URL: http://source.netsurf-browser.org?rev=3557&view=rev
Log:
Implement dom_node_replace_child()

Modified:
    trunk/dom/src/core/node.c

Modified: trunk/dom/src/core/node.c
URL: http://source.netsurf-browser.org/trunk/dom/src/core/node.c?rev=3557&r1=3556&r2=3557&view=diff
==============================================================================
--- trunk/dom/src/core/node.c (original)
+++ trunk/dom/src/core/node.c Sat Sep 22 02:28:54 2007
@@ -39,6 +39,8 @@
 		struct dom_node *next);
 static inline void _dom_node_detach_range(struct dom_node *first, 
 		struct dom_node *last);
+static inline void _dom_node_replace(struct dom_node *old, 
+		struct dom_node *replacement);
 
 /**
  * Destroy a DOM node
@@ -716,12 +718,59 @@
 		struct dom_node *new_child, struct dom_node *old_child,
 		struct dom_node **result)
 {
-	UNUSED(node);
-	UNUSED(new_child);
-	UNUSED(old_child);
-	UNUSED(result);
-
-	return DOM_NOT_SUPPORTED_ERR;
+	/* We don't support replacement of DocumentType or root Elements */
+	if (node->type == DOM_DOCUMENT_NODE && 
+			(new_child->type == DOM_DOCUMENT_TYPE_NODE || 
+			new_child->type == DOM_ELEMENT_NODE))
+		return DOM_NOT_SUPPORTED_ERR;
+
+	/* Ensure that new_child and node are owned by the same document */
+	if (new_child->owner != node->owner)
+		return DOM_WRONG_DOCUMENT_ERR;
+
+	/* Ensure node isn't read only */
+	if (_dom_node_readonly(node))
+		return DOM_NO_MODIFICATION_ALLOWED_ERR;
+
+	/* Ensure that old_child is a child of node */
+	if (old_child->parent != node)
+		return DOM_NOT_FOUND_ERR;
+
+	/* Ensure that new_child is not an ancestor of node, nor node itself */
+	for (struct dom_node *n = node; n != NULL; n = n->parent) {
+		if (n == new_child)
+			return DOM_HIERARCHY_REQUEST_ERR;
+	}
+
+	/* Ensure that new_child is permitted as a child of node */
+	if (!_dom_node_permitted_child(node, new_child))
+		return DOM_HIERARCHY_REQUEST_ERR;
+
+	/* Attempting to replace a node with itself is a NOP */
+	if (new_child == old_child) {
+		dom_node_ref(old_child);
+		*result = old_child;
+
+		return DOM_NO_ERR;
+	}
+
+	/* If new_child is already in the tree and 
+	 * its parent isn't read only, remove it */
+	if (new_child->parent != NULL) {
+		if (_dom_node_readonly(new_child->parent))
+			return DOM_NO_MODIFICATION_ALLOWED_ERR;
+
+		_dom_node_detach(new_child);
+	}
+
+	/* Perform the replacement */
+	_dom_node_replace(old_child, new_child);
+
+	/* Sort out the return value */
+	dom_node_ref(old_child);
+	*result = old_child;
+
+	return DOM_NO_ERR;
 }
 
 /**
@@ -1507,3 +1556,32 @@
 		n->parent = NULL;
 }
 
+/**
+ * Replace a node in the tree
+ *
+ * \param old          Node to replace
+ * \param replacement  Replacement node
+ *
+ * This is not implemented in terms of attach/detach in case 
+ * we want to perform any special replacement-related behaviour 
+ * at a later date.
+ */
+inline void _dom_node_replace(struct dom_node *old,
+		struct dom_node *replacement)
+{
+	replacement->previous = old->previous;
+	replacement->next = old->next;
+
+	if (old->previous != NULL)
+		old->previous->next = replacement;
+	else
+		old->parent->first_child = replacement;
+
+	if (old->next != NULL)
+		old->next->previous = replacement;
+	else
+		old->parent->last_child = replacement;
+
+	replacement->parent = old->parent;
+}
+




More information about the netsurf-commits mailing list