r13621 tlsa - in /trunk/libdom/src/core: element.c element.h

netsurf at semichrome.net netsurf at semichrome.net
Sat Mar 24 20:21:07 GMT 2012


Author: tlsa
Date: Sat Mar 24 15:21:07 2012
New Revision: 13621

URL: http://source.netsurf-browser.org?rev=13621&view=rev
Log:
Generate element's class list.

Modified:
    trunk/libdom/src/core/element.c
    trunk/libdom/src/core/element.h

Modified: trunk/libdom/src/core/element.c
URL: http://source.netsurf-browser.org/trunk/libdom/src/core/element.c?rev=13621&r1=13620&r2=13621&view=diff
==============================================================================
--- trunk/libdom/src/core/element.c (original)
+++ trunk/libdom/src/core/element.c Sat Mar 24 15:21:07 2012
@@ -59,6 +59,95 @@
 	struct dom_string *namespace;
 } dom_attr_list;
 
+
+/**
+ * Destroy element's class cache
+ *
+ * \param ele  The element
+ */
+static void _dom_element_destroy_classes(struct dom_element *ele)
+{
+	/* Destroy the pre-separated class names */
+	if (ele->classes != NULL) {
+		unsigned int class;
+		for (class = 0; class < ele->n_classes; class++) {
+			lwc_string_unref(ele->classes[class]);
+		}
+		free(ele->classes);
+	}
+
+	ele->n_classes = 0;
+	ele->classes = NULL;
+}
+
+
+/**
+ * Create element's class cache from class attribute value
+ *
+ * \param ele    The element
+ * \param value  The class attribute value
+ *
+ * Destroys any existing cached classes.
+ */
+static dom_exception _dom_element_create_classes(struct dom_element *ele,
+		const char *value)
+{
+	const char *pos;
+	lwc_string **classes = NULL;
+	uint32_t n_classes = 0;
+
+	/* Any existing cached classes are replaced; destroy them */
+	_dom_element_destroy_classes(ele);
+
+	/* Count number of classes */
+	for (pos = value; *pos != '\0'; ) {
+		if (*pos != ' ') {
+			while (*pos != ' ' && *pos != '\0')
+				pos++;
+			n_classes++;
+		} else {
+			while (*pos == ' ')
+				pos++;
+		}
+	}
+
+	/* If there are some, unpack them */
+	if (n_classes > 0) {
+		classes = malloc(n_classes * sizeof(lwc_string *));
+		if (classes == NULL)
+			return DOM_NO_MEM_ERR;
+
+		for (pos = value, n_classes = 0;
+				*pos != '\0'; ) {
+			if (*pos != ' ') {
+				const char *s = pos;
+				while (*pos != ' ' && *pos != '\0')
+					pos++;
+				if (lwc_intern_string(s, pos - s, 
+						&classes[n_classes]) !=
+						lwc_error_ok)
+					goto error;
+				n_classes++;
+			} else {
+				while (*pos == ' ')
+					pos++;
+			}
+		}
+	}
+
+	ele->classes = classes;
+	ele->n_classes = n_classes;
+
+	return DOM_NO_ERR;
+error:
+	while (n_classes > 0)
+		lwc_string_unref(classes[--n_classes]);
+
+	free(classes);
+		
+	return DOM_NO_MEM_ERR;
+}
+
 /* Attribute linked list releated functions */
 
 /**
@@ -179,6 +268,42 @@
 }
 
 /**
+ * Destroy an attribute list node, and its attribute
+ *
+ * \param n  The attribute list node to destroy
+ */
+static void _dom_element_attr_list_node_destroy(dom_attr_list *n)
+{
+	dom_node_internal *a;
+	dom_document *doc;
+
+	assert(n != NULL);
+	assert(n->attr != NULL);
+	assert(n->name != NULL);
+
+	a = (dom_node_internal *) n->attr;
+
+	/* Need to destroy classes cache, when removing class attribute */
+	doc = a->owner;
+	if (n->namespace == NULL &&
+			dom_string_isequal(n->name, doc->class_string)) {
+		dom_node_internal *a = (dom_node_internal *)(n->attr);
+		_dom_element_destroy_classes((dom_element *)(a->parent));
+	}
+
+	/* Destroy rest of list node */
+	dom_string_unref(n->name);
+
+	if (n->namespace != NULL)
+		dom_string_unref(n->namespace);
+
+	a->parent = NULL;
+	dom_node_try_destroy(a);
+
+	free(n);
+}
+
+/**
  * Create an attribute list node
  *
  * \param attr       The attribute to create a list node for
@@ -204,32 +329,27 @@
 	new_list_node->name = name;
 	new_list_node->namespace = namespace;
 
+	if (namespace == NULL) {
+		dom_node_internal *a = (dom_node_internal *) attr;
+		dom_string *value;
+
+		if (DOM_NO_ERR != _dom_attr_get_value(attr, &value)) {
+			_dom_element_attr_list_node_destroy(new_list_node);
+			return NULL;
+		}
+
+		if (DOM_NO_ERR != _dom_element_create_classes(
+				(dom_element *)(a->parent),
+				dom_string_data(value))) {
+			_dom_element_attr_list_node_destroy(new_list_node);
+			dom_string_unref(value);
+			return NULL;
+		}
+
+		dom_string_unref(value);
+	}
+
 	return new_list_node;
-}
-
-/**
- * Destroy an attribute list node, and its attribute
- *
- * \param n  The attribute list node to destroy
- */
-static void _dom_element_attr_list_node_destroy(dom_attr_list *n)
-{
-	dom_node_internal *a;
-
-	assert(n != NULL);
-	assert(n->attr != NULL);
-	assert(n->name != NULL);
-
-	dom_string_unref(n->name);
-
-	if (n->namespace != NULL)
-		dom_string_unref(n->namespace);
-
-	a = (dom_node_internal *) n->attr;
-	a->parent = NULL;
-	dom_node_try_destroy(a);
-
-	free(n);
 }
 
 /**
@@ -331,27 +451,6 @@
 	} while (attr != list);
 
 	return new_list;
-}
-
-
-/**
- * Destroy element's class cache
- *
- * \param ele  The element
- */
-static void _dom_element_destroy_classes(struct dom_element *ele)
-{
-	/* Destroy the pre-separated class names */
-	if (ele->classes != NULL) {
-		unsigned int class;
-		for (class = 0; class < ele->n_classes; class++) {
-			lwc_string_unref(ele->classes[class]);
-		}
-		free(ele->classes);
-	}
-
-	ele->n_classes = 0;
-	ele->classes = NULL;
 }
 
 static dom_exception _dom_element_get_attr(struct dom_element *element,

Modified: trunk/libdom/src/core/element.h
URL: http://source.netsurf-browser.org/trunk/libdom/src/core/element.h?rev=13621&r1=13620&r2=13621&view=diff
==============================================================================
--- trunk/libdom/src/core/element.h (original)
+++ trunk/libdom/src/core/element.h Sat Mar 24 15:21:07 2012
@@ -72,6 +72,7 @@
 dom_exception _dom_element_get_elements_by_tag_name(
 		struct dom_element *element, dom_string *name,
 		struct dom_nodelist **result);
+
 dom_exception _dom_element_get_attribute_ns(struct dom_element *element, 
 		dom_string *namespace, dom_string *localname, 
 		dom_string **value);




More information about the netsurf-commits mailing list