summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/element.c11
-rw-r--r--src/core/element.h4
-rw-r--r--src/core/namednodemap.c175
3 files changed, 171 insertions, 19 deletions
diff --git a/src/core/element.c b/src/core/element.c
index a0f0b51..1b351ce 100644
--- a/src/core/element.c
+++ b/src/core/element.c
@@ -883,3 +883,14 @@ dom_exception dom_element_has_attributes(struct dom_element *element,
return DOM_NO_ERR;
}
+/**
+ * Retrieve a pointer to the first attribute attached to an element
+ *
+ * \param element The element to retrieve the first attribute from
+ * \return Pointer to first attribute, or NULL if none.
+ */
+struct dom_node *dom_element_get_first_attribute(struct dom_element *element)
+{
+ return (struct dom_node *) element->attributes;
+}
+
diff --git a/src/core/element.h b/src/core/element.h
index f51b9ae..95e7cfe 100644
--- a/src/core/element.h
+++ b/src/core/element.h
@@ -15,6 +15,7 @@
struct dom_document;
struct dom_element;
struct dom_namednodemap;
+struct dom_node;
struct dom_string;
dom_exception dom_element_create(struct dom_document *doc,
@@ -28,4 +29,7 @@ dom_exception dom_element_get_attributes(struct dom_element *element,
dom_exception dom_element_has_attributes(struct dom_element *element,
bool *result);
+
+struct dom_node *dom_element_get_first_attribute(struct dom_element *element);
+
#endif
diff --git a/src/core/namednodemap.c b/src/core/namednodemap.c
index c049a6c..2d1fbc8 100644
--- a/src/core/namednodemap.c
+++ b/src/core/namednodemap.c
@@ -5,10 +5,14 @@
* Copyright 2007 John-Mark Bell <jmb@netsurf-browser.org>
*/
+#include <dom/core/element.h>
#include <dom/core/node.h>
+#include <dom/core/string.h>
#include "core/document.h"
+#include "core/element.h"
#include "core/namednodemap.h"
+#include "core/node.h"
#include "utils/utils.h"
@@ -118,10 +122,29 @@ void dom_namednodemap_unref(struct dom_namednodemap *map)
dom_exception dom_namednodemap_get_length(struct dom_namednodemap *map,
unsigned long *length)
{
- UNUSED(map);
- UNUSED(length);
+ struct dom_node *cur;
+ unsigned long len = 0;
+
+ switch (map->type) {
+ case DOM_ATTRIBUTE_NODE:
+ cur = dom_element_get_first_attribute(
+ (struct dom_element *) map->head);
+ break;
+ case DOM_NOTATION_NODE:
+ case DOM_ENTITY_NODE:
+ /** \todo handle notation and entity nodes */
+ default:
+ return DOM_NOT_SUPPORTED_ERR;
+ break;
+ }
- return DOM_NOT_SUPPORTED_ERR;
+ for (; cur != NULL; cur = cur->next) {
+ len++;
+ }
+
+ *length = len;
+
+ return DOM_NO_ERR;
}
/**
@@ -138,11 +161,33 @@ dom_exception dom_namednodemap_get_length(struct dom_namednodemap *map,
dom_exception dom_namednodemap_get_named_item(struct dom_namednodemap *map,
struct dom_string *name, struct dom_node **node)
{
- UNUSED(map);
- UNUSED(name);
- UNUSED(node);
+ struct dom_node *cur;
+
+ switch (map->type) {
+ case DOM_ATTRIBUTE_NODE:
+ cur = dom_element_get_first_attribute(
+ (struct dom_element *) map->head);
+ break;
+ case DOM_NOTATION_NODE:
+ case DOM_ENTITY_NODE:
+ /** \todo handle notation and entity nodes */
+ default:
+ return DOM_NOT_SUPPORTED_ERR;
+ break;
+ }
- return DOM_NOT_SUPPORTED_ERR;
+ for (; cur != NULL; cur = cur->next) {
+ if (dom_string_cmp(cur->name, name) == 0) {
+ break;
+ }
+ }
+
+ if (cur != NULL) {
+ dom_node_ref(cur);
+ }
+ *node = cur;
+
+ return DOM_NO_ERR;
}
/**
@@ -172,11 +217,45 @@ dom_exception dom_namednodemap_get_named_item(struct dom_namednodemap *map,
dom_exception dom_namednodemap_set_named_item(struct dom_namednodemap *map,
struct dom_node *arg, struct dom_node **node)
{
- UNUSED(map);
- UNUSED(arg);
- UNUSED(node);
+ dom_exception err;
+
+ /* Ensure arg and map belong to the same document */
+ if (arg->owner != map->owner)
+ return DOM_WRONG_DOCUMENT_ERR;
+
+ /* Ensure map is writable */
+ if (_dom_node_readonly(map->head))
+ return DOM_NO_MODIFICATION_ALLOWED_ERR;
+
+ /* Ensure arg isn't attached to another element */
+ if (arg->type == DOM_ATTRIBUTE_NODE && arg->parent != NULL &&
+ arg->parent != map->head)
+ return DOM_INUSE_ATTRIBUTE_ERR;
+
+ /* Ensure arg is permitted in the map */
+ if (arg->type != map->type)
+ return DOM_HIERARCHY_REQUEST_ERR;
+
+ /* Now delegate to the container-specific function.
+ * NamedNodeMaps are live, so this is fine. */
+ switch (map->type) {
+ case DOM_ATTRIBUTE_NODE:
+ err = dom_element_set_attribute_node(
+ (struct dom_element *) map->head,
+ (struct dom_attr *) arg,
+ (struct dom_attr **) node);
+ break;
+ case DOM_NOTATION_NODE:
+ case DOM_ENTITY_NODE:
+ /** \todo handle notation and entity nodes */
+ default:
+ err = DOM_NOT_SUPPORTED_ERR;
+ break;
+ }
- return DOM_NOT_SUPPORTED_ERR;
+ /* Reference counting is handled by the container-specific call */
+
+ return err;
}
/**
@@ -197,11 +276,44 @@ dom_exception dom_namednodemap_remove_named_item(
struct dom_namednodemap *map, struct dom_string *name,
struct dom_node **node)
{
- UNUSED(map);
- UNUSED(name);
- UNUSED(node);
+ dom_exception err;
+
+ /* Ensure map is writable */
+ if (_dom_node_readonly(map->head))
+ return DOM_NO_MODIFICATION_ALLOWED_ERR;
+
+ /* Now delegate to the container-specific function.
+ * NamedNodeMaps are live, so this is fine. */
+ switch (map->type) {
+ case DOM_ATTRIBUTE_NODE:
+ {
+ struct dom_attr *attr;
+
+ err = dom_element_get_attribute_node(
+ (struct dom_element *) map->head,
+ name, &attr);
+ if (err == DOM_NO_ERR) {
+ err = dom_element_remove_attribute_node(
+ (struct dom_element *) map->head,
+ attr, (struct dom_attr **) node);
+ if (err == DOM_NO_ERR) {
+ /* No longer want attr */
+ dom_node_unref((struct dom_node *) attr);
+ }
+ }
+ }
+ break;
+ case DOM_NOTATION_NODE:
+ case DOM_ENTITY_NODE:
+ /** \todo handle notation and entity nodes */
+ default:
+ err = DOM_NOT_SUPPORTED_ERR;
+ break;
+ }
- return DOM_NOT_SUPPORTED_ERR;
+ /* Reference counting is handled by the container-specific call */
+
+ return err;
}
/**
@@ -221,11 +333,36 @@ dom_exception dom_namednodemap_remove_named_item(
dom_exception dom_namednodemap_item(struct dom_namednodemap *map,
unsigned long index, struct dom_node **node)
{
- UNUSED(map);
- UNUSED(index);
- UNUSED(node);
+ struct dom_node *cur;
+ unsigned long count = 0;
+
+ switch (map->type) {
+ case DOM_ATTRIBUTE_NODE:
+ cur = dom_element_get_first_attribute(
+ (struct dom_element *) map->head);
+ break;
+ case DOM_NOTATION_NODE:
+ case DOM_ENTITY_NODE:
+ /** \todo handle notation and entity nodes */
+ default:
+ return DOM_NOT_SUPPORTED_ERR;
+ break;
+ }
- return DOM_NOT_SUPPORTED_ERR;
+ for (; cur != NULL; cur = cur->next) {
+ count++;
+
+ if ((index + 1) == count) {
+ break;
+ }
+ }
+
+ if (cur != NULL) {
+ dom_node_ref(cur);
+ }
+ *node = cur;
+
+ return DOM_NO_ERR;
}
/**