summaryrefslogtreecommitdiff
path: root/src/core/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/node.c')
-rw-r--r--src/core/node.c111
1 files changed, 81 insertions, 30 deletions
diff --git a/src/core/node.c b/src/core/node.c
index d4d0519..4f15617 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -5,6 +5,7 @@
* Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
*/
+#include <dom/core/document.h>
#include <dom/core/string.h>
#include "core/document.h"
@@ -12,58 +13,108 @@
#include "utils/utils.h"
/**
- * Create a DOM node
+ * Create a DOM node of the given type
*
- * \param doc The document which owns the node
- * \param type The node type required
- * \param name The node name, or NULL
- * \param value The node value, or NULL
- * \param node Pointer to location to receive created node
- * \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion
+ * \param doc The owning document
+ * \param type The type of node to create
+ * \param name The node name, or NULL
+ * \param value The node value, or NULL
+ * \param result Pointer to location to receive created node
+ * \return DOM_NO_ERR on success, appropriate error otherwise
+ *
+ * ::doc, ::name and ::value will have their reference counts increased.
*
- * The returned node will be referenced, so there is no need for the caller
- * to explicitly reference it.
+ * The created node will already be referenced.
*/
dom_exception dom_node_create(struct dom_document *doc, dom_node_type type,
struct dom_string *name, struct dom_string *value,
- struct dom_node **node)
+ struct dom_node **result)
{
- struct dom_node *n;
+ struct dom_node *node;
+ dom_exception err;
+
+ /* If there's a type-specific constructor, use that */
+ switch (type) {
+ case DOM_ELEMENT_NODE:
+ return dom_document_create_element(doc, name,
+ (struct dom_element **) result);
+ case DOM_ATTRIBUTE_NODE:
+ return dom_document_create_attribute(doc, name,
+ (struct dom_attr **) result);
+ case DOM_TEXT_NODE:
+ return dom_document_create_text_node(doc, value,
+ (struct dom_text **) result);
+ case DOM_CDATA_SECTION_NODE:
+ return dom_document_create_cdata_section(doc, value,
+ (struct dom_text **) result);
+ case DOM_COMMENT_NODE:
+ return dom_document_create_comment(doc, value,
+ (struct dom_characterdata **) result);
+ default:
+ break;
+ }
- n = dom_document_alloc(doc, NULL, sizeof(struct dom_node));
- if (n == NULL)
+ /* Otherwise, this is a generic node, so build it ourselves */
+ node = dom_document_alloc(doc, NULL, sizeof(struct dom_node));
+ if (node == NULL)
return DOM_NO_MEM_ERR;
+ /* Initialise node contents */
+ err = dom_node_initialise(node, doc, type, name, value);
+ if (err != DOM_NO_ERR) {
+ dom_document_alloc(doc, node, 0);
+ return err;
+ }
+
+ *result = node;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Initialise a DOM node
+ *
+ * \param node The node to initialise
+ * \param doc The document which owns the node
+ * \param type The node type required
+ * \param name The node name, or NULL
+ * \param value The node value, or NULL
+ * \return DOM_NO_ERR on success.
+ *
+ * ::doc, ::name and ::value will have their reference counts increased.
+ */
+dom_exception dom_node_initialise(struct dom_node *node,
+ struct dom_document *doc, dom_node_type type,
+ struct dom_string *name, struct dom_string *value)
+{
if (name != NULL)
dom_string_ref(name);
- n->name = name;
+ node->name = name;
if (value != NULL)
dom_string_ref(value);
- n->value = value;
+ node->value = value;
- n->type = type;
+ node->type = type;
- n->parent = NULL;
- n->first_child = NULL;
- n->last_child = NULL;
- n->previous = NULL;
- n->next = NULL;
- n->attributes = NULL;
+ node->parent = NULL;
+ node->first_child = NULL;
+ node->last_child = NULL;
+ node->previous = NULL;
+ node->next = NULL;
+ node->attributes = NULL;
dom_node_ref((struct dom_node *) doc);
- n->owner = doc;
+ node->owner = doc;
/** \todo Namespace handling */
- n->namespace = NULL;
- n->prefix = NULL;
- n->localname = NULL;
-
- n->user_data = NULL;
+ node->namespace = NULL;
+ node->prefix = NULL;
+ node->localname = NULL;
- n->refcnt = 1;
+ node->user_data = NULL;
- *node = n;
+ node->refcnt = 1;
return DOM_NO_ERR;
}