summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2010-08-30 13:06:19 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2010-08-30 13:06:19 +0000
commitb657c277f517f4ab0a4da21e4f8c4cb6f8f53013 (patch)
tree4ce25caee01c0a2a2ebbe052999b5eb8a2fbe2e3 /src/core
parent229af12d7ab2c071a6888eb8ffc49bb0bbeb9ddd (diff)
downloadlibdom-b657c277f517f4ab0a4da21e4f8c4cb6f8f53013.tar.gz
libdom-b657c277f517f4ab0a4da21e4f8c4cb6f8f53013.tar.bz2
Merge branches/struggleyb/libdom-html to trunk.
A few additional fixes to reduce the number of regressions to single figures. svn path=/trunk/dom/; revision=10724
Diffstat (limited to 'src/core')
-rw-r--r--src/core/attr.c266
-rw-r--r--src/core/attr.h5
-rw-r--r--src/core/document.c5
-rw-r--r--src/core/document.h29
-rw-r--r--src/core/document_type.c2
-rw-r--r--src/core/document_type.h6
-rw-r--r--src/core/element.c55
-rw-r--r--src/core/element.h42
-rw-r--r--src/core/node.c29
-rw-r--r--src/core/node.h2
10 files changed, 426 insertions, 15 deletions
diff --git a/src/core/attr.c b/src/core/attr.c
index f1c4f54..4cd9e76 100644
--- a/src/core/attr.c
+++ b/src/core/attr.c
@@ -19,12 +19,13 @@
#include "core/document.h"
#include "core/entity_ref.h"
#include "core/node.h"
+#include "core/element.h"
#include "utils/utils.h"
struct dom_element;
/**
- * DOM node attribute
+ * DOM attribute node
*/
struct dom_attr {
struct dom_node_internal base; /**< Base node */
@@ -35,6 +36,16 @@ struct dom_attr {
struct dom_type_info *schema_type_info; /**< Type information */
bool is_id; /**< Whether this attribute is a ID attribute */
+
+ dom_attr_type type; /**< The type of this attribute */
+
+ union {
+ unsigned long lvalue;
+ unsigned short svalue;
+ bool bvalue;
+ } value; /**< The special type value of this attribute */
+
+ bool read_only; /**< Whether this attribute is readonly */
};
/* The vtable for dom_attr node */
@@ -62,7 +73,7 @@ static struct dom_node_protect_vtable attr_protect_vtable = {
* \param name The (local) name of the node to create
* \param namespace The namespace URI of the attribute, or NULL
* \param prefix The namespace prefix of the attribute, or NULL
- * \param specified Whtether this attribute is specified
+ * \param specified Whether this attribute is specified
* \param result Pointer to location to receive created attribute
* \return DOM_NO_ERR on success,
* DOM_NO_MEM_ERR on memory exhaustion.
@@ -127,6 +138,9 @@ dom_exception _dom_attr_initialise(dom_attr *a,
a->specified = specified;
a->schema_type_info = NULL;
a->is_id = false;
+ /* The attribute type is unset when it is created */
+ a->type = DOM_ATTR_UNSET;
+ a->read_only = false;
*result = a;
@@ -165,6 +179,206 @@ void _dom_attr_destroy(struct dom_document *doc, struct dom_attr *attr)
_dom_document_alloc(doc, attr, 0);
}
+/*-----------------------------------------------------------------------*/
+/* Following are our implementation specific APIs */
+
+/**
+ * Get the Attr Node type
+ *
+ * \param a The attribute node
+ * \return the type
+ */
+dom_attr_type dom_attr_get_type(dom_attr *a)
+{
+ return a->type;
+}
+
+/**
+ * Get the integer value of this attribute
+ *
+ * \param a The attribute object
+ * \param value The returned value
+ * \return DOM_NO_ERR on success,
+ * DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a integer
+ * attribute
+ */
+dom_exception dom_attr_get_integer(dom_attr *a, unsigned long *value)
+{
+ if (a->type != DOM_ATTR_INTEGER)
+ return DOM_ATTR_WRONG_TYPE_ERR;
+
+ *value = a->value.lvalue;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Set the integer value of this attribute
+ *
+ * \param a The attribute object
+ * \param value The new value
+ * \return DOM_NO_ERR on success,
+ * DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a integer
+ * attribute
+ */
+dom_exception dom_attr_set_integer(dom_attr *a, unsigned long value)
+{
+ /* If this is the first set method, we should fix this attribute
+ * type */
+ if (a->type == DOM_ATTR_UNSET)
+ a->type = DOM_ATTR_INTEGER;
+
+ if (a->type != DOM_ATTR_INTEGER)
+ return DOM_ATTR_WRONG_TYPE_ERR;
+
+ if (a->value.lvalue == value)
+ return DOM_NO_ERR;
+
+ a->value.lvalue = value;
+
+ struct dom_document *doc = dom_node_get_owner(a);
+ struct dom_node_internal *ele = dom_node_get_parent(a);
+ bool success = true;
+ dom_exception err;
+ err = _dom_dispatch_attr_modified_event(doc, ele, NULL, NULL,
+ (dom_event_target *) a, NULL,
+ DOM_MUTATION_MODIFICATION, &success);
+ if (err != DOM_NO_ERR)
+ return err;
+
+ success = true;
+ err = _dom_dispatch_subtree_modified_event(doc,
+ (dom_event_target *) a, &success);
+ return err;
+}
+
+/**
+ * Get the short value of this attribute
+ *
+ * \param a The attribute object
+ * \param value The returned value
+ * \return DOM_NO_ERR on success,
+ * DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a short
+ * attribute
+ */
+dom_exception dom_attr_get_short(dom_attr *a, unsigned short *value)
+{
+ if (a->type != DOM_ATTR_SHORT)
+ return DOM_ATTR_WRONG_TYPE_ERR;
+
+ *value = a->value.svalue;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Set the short value of this attribute
+ *
+ * \param a The attribute object
+ * \param value The new value
+ * \return DOM_NO_ERR on success,
+ * DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a short
+ * attribute
+ */
+dom_exception dom_attr_set_short(dom_attr *a, unsigned short value)
+{
+ /* If this is the first set method, we should fix this attribute
+ * type */
+ if (a->type == DOM_ATTR_UNSET)
+ a->type = DOM_ATTR_SHORT;
+
+ if (a->type != DOM_ATTR_SHORT)
+ return DOM_ATTR_WRONG_TYPE_ERR;
+
+ if (a->value.svalue == value)
+ return DOM_NO_ERR;
+
+ a->value.svalue = value;
+
+ struct dom_document *doc = dom_node_get_owner(a);
+ struct dom_node_internal *ele = dom_node_get_parent(a);
+ bool success = true;
+ dom_exception err;
+ err = _dom_dispatch_attr_modified_event(doc, ele, NULL, NULL,
+ (dom_event_target *) a, NULL,
+ DOM_MUTATION_MODIFICATION, &success);
+ if (err != DOM_NO_ERR)
+ return err;
+
+ success = true;
+ err = _dom_dispatch_subtree_modified_event(doc,
+ (dom_event_target *) a, &success);
+ return err;
+}
+
+/**
+ * Get the bool value of this attribute
+ *
+ * \param a The attribute object
+ * \param value The returned value
+ * \return DOM_NO_ERR on success,
+ * DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a bool
+ * attribute
+ */
+dom_exception dom_attr_get_bool(dom_attr *a, bool *value)
+{
+ if (a->type != DOM_ATTR_BOOL)
+ return DOM_ATTR_WRONG_TYPE_ERR;
+
+ *value = a->value.bvalue;
+
+ return DOM_NO_ERR;
+}
+
+/**
+ * Set the bool value of this attribute
+ *
+ * \param a The attribute object
+ * \param value The new value
+ * \return DOM_NO_ERR on success,
+ * DOM_ATTR_WRONG_TYPE_ERR if the attribute node is not a bool
+ * attribute
+ */
+dom_exception dom_attr_set_bool(dom_attr *a, bool value)
+{
+ /* If this is the first set method, we should fix this attribute
+ * type */
+ if (a->type == DOM_ATTR_UNSET)
+ a->type = DOM_ATTR_BOOL;
+
+ if (a->type != DOM_ATTR_BOOL)
+ return DOM_ATTR_WRONG_TYPE_ERR;
+
+ if (a->value.bvalue == value)
+ return DOM_NO_ERR;
+
+ a->value.bvalue = value;
+
+ struct dom_document *doc = dom_node_get_owner(a);
+ struct dom_node_internal *ele = dom_node_get_parent(a);
+ bool success = true;
+ dom_exception err;
+ err = _dom_dispatch_attr_modified_event(doc, ele, NULL, NULL,
+ (dom_event_target *) a, NULL,
+ DOM_MUTATION_MODIFICATION, &success);
+ if (err != DOM_NO_ERR)
+ return err;
+
+ success = true;
+ err = _dom_dispatch_subtree_modified_event(doc,
+ (dom_event_target *) a, &success);
+ return err;
+}
+
+/**
+ * Set the node as a readonly attribute
+ *
+ * \param a The attribute
+ */
+void dom_attr_mark_readonly(dom_attr *a)
+{
+ a->read_only = true;
+}
/* -------------------------------------------------------------------- */
@@ -227,6 +441,18 @@ dom_exception _dom_attr_get_value(struct dom_attr *attr,
return err;
}
+ /* Force unknown types to strings, if necessary */
+ if (attr->type == DOM_ATTR_UNSET && a->first_child != NULL) {
+ attr->type = DOM_ATTR_STRING;
+ }
+
+ /* If this attribute node is not a string one, we just return an empty
+ * string */
+ if (attr->type != DOM_ATTR_STRING) {
+ *result = value;
+ return DOM_NO_ERR;
+ }
+
/* Traverse children, building a string representation as we go */
for (c = a->first_child; c != NULL; c = c->next) {
if (c->type == DOM_TEXT_NODE && c->value != NULL) {
@@ -298,10 +524,33 @@ dom_exception _dom_attr_set_value(struct dom_attr *attr,
if (_dom_node_readonly(a))
return DOM_NO_MODIFICATION_ALLOWED_ERR;
+ /* If this is the first set method, we should fix this attribute
+ * type */
+ if (attr->type == DOM_ATTR_UNSET)
+ attr->type = DOM_ATTR_STRING;
+
+ if (attr->type != DOM_ATTR_STRING)
+ return DOM_ATTR_WRONG_TYPE_ERR;
+
+ dom_string *name = NULL;
+
+ err = _dom_attr_get_name(attr, &name);
+ if (err != DOM_NO_ERR)
+ return err;
+
+ dom_string *parsed = NULL;
+ err = dom_element_parse_attribute(a->parent, name, value, &parsed);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(name);
+ return err;
+ }
+
/* Create text node containing new value */
- err = dom_document_create_text_node(a->owner, value, &text);
+ err = dom_document_create_text_node(a->owner, parsed, &text);
if (err != DOM_NO_ERR)
return err;
+
+ dom_string_unref(parsed);
/* Destroy children of this node */
for (c = a->first_child; c != NULL; c = d) {
@@ -561,3 +810,14 @@ void _dom_attr_set_specified(struct dom_attr *attr, bool specified)
attr->specified = specified;
}
+/**
+ * Whether this attribute node is readonly
+ *
+ * \param a The node
+ * \return true if this Attr is readonly, false otherwise
+ */
+bool _dom_attr_readonly(const dom_attr *a)
+{
+ return a->read_only;
+}
+
diff --git a/src/core/attr.h b/src/core/attr.h
index ab51247..b94715a 100644
--- a/src/core/attr.h
+++ b/src/core/attr.h
@@ -8,7 +8,7 @@
#ifndef dom_internal_core_attr_h_
#define dom_internal_core_attr_h_
-#include <dom/core/exceptions.h>
+#include <dom/core/attr.h>
struct dom_document;
struct dom_string;
@@ -24,7 +24,7 @@ dom_exception _dom_attr_initialise(struct dom_attr *a,
struct dom_document *doc, struct lwc_string_s *name,
struct lwc_string_s *namespace, struct lwc_string_s *prefix,
bool specified, struct dom_attr **result);
-void _dom_attr_finalise(dom_document *doc, struct dom_attr *attr);
+void _dom_attr_finalise(struct dom_document *doc, struct dom_attr *attr);
/* Virtual functions for dom_attr */
dom_exception _dom_attr_get_name(struct dom_attr *attr,
@@ -117,5 +117,6 @@ dom_exception _dom_attr_copy(struct dom_node_internal *new,
void _dom_attr_set_isid(struct dom_attr *attr, bool is_id);
void _dom_attr_set_specified(struct dom_attr *attr, bool specified);
+bool _dom_attr_readonly(const dom_attr *a);
#endif
diff --git a/src/core/document.c b/src/core/document.c
index 74fb534..ad25bd7 100644
--- a/src/core/document.c
+++ b/src/core/document.c
@@ -76,13 +76,14 @@ static dom_exception dom_document_dup_node(dom_document *doc,
* \param pw Pointer to client-specific private data
* \param doc Pointer to location to receive created document
* \param daf The default action fetcher
+ * \param daf The default action fetcher
* \return DOM_NO_ERR on success, DOM_NO_MEM_ERR on memory exhaustion.
*
* ::impl will have its reference count increased.
*
* The returned document will already be referenced.
*/
-dom_exception dom_document_create(struct dom_implementation *impl,
+dom_exception _dom_document_create(struct dom_implementation *impl,
dom_alloc alloc, void *pw,
dom_events_default_action_fetcher daf,
struct dom_document **doc)
@@ -186,6 +187,8 @@ bool _dom_document_finalise(struct dom_document *doc)
lwc_string_unref(doc->id_name);
_dom_document_event_internal_finalise(doc, &doc->dei);
+
+ _dom_document_event_internal_finalise(doc, &doc->dei);
return true;
}
diff --git a/src/core/document.h b/src/core/document.h
index a7cab6d..e657530 100644
--- a/src/core/document.h
+++ b/src/core/document.h
@@ -12,6 +12,7 @@
#include <stddef.h>
#include <dom/core/node.h>
+#include <dom/core/document.h>
#include "core/string.h"
#include "core/node.h"
@@ -66,6 +67,12 @@ struct dom_document {
/**< The DocumentEVent interface */
};
+/* Create a DOM document */
+dom_exception _dom_document_create(struct dom_implementation *impl,
+ dom_alloc alloc, void *pw,
+ dom_events_default_action_fetcher daf,
+ struct dom_document **doc);
+
/* Initialise the document */
dom_exception _dom_document_initialise(struct dom_document *doc,
struct dom_implementation *impl, dom_alloc alloc, void *pw,
@@ -194,6 +201,28 @@ dom_exception _dom_document_rename_node(struct dom_document *doc,
_dom_document_rename_node
/* End of vtable */
+/**
+ * The internal used vtable for document
+ */
+struct dom_document_protected_vtable {
+ struct dom_node_protect_vtable base;
+ dom_exception (*dom_document_get_base)(dom_document *doc,
+ struct dom_string **base_uri);
+ /* Get the document's base uri */
+};
+
+typedef struct dom_document_protected_vtable dom_document_protected_vtable;
+
+/* Get the document's base URI */
+static inline dom_exception dom_document_get_base(dom_document *doc,
+ struct dom_string **base_uri)
+{
+ struct dom_node_internal *node = (struct dom_node_internal *) doc;
+ return ((dom_document_protected_vtable *) node->vtable)->
+ dom_document_get_base(doc, base_uri);
+}
+#define dom_document_get_base(d, b) dom_document_get_base( \
+ (dom_document *) (d), (struct dom_string **) (b))
/* Following comes the protected vtable */
void _dom_document_destroy(struct dom_node_internal *node);
diff --git a/src/core/document_type.c b/src/core/document_type.c
index c8b3ff2..4b07e3f 100644
--- a/src/core/document_type.c
+++ b/src/core/document_type.c
@@ -64,7 +64,7 @@ static struct dom_node_protect_vtable dt_protect_vtable = {
* explicitly. The client must unref the doctype once it has
* finished with it.
*/
-dom_exception dom_document_type_create(struct dom_string *qname,
+dom_exception _dom_document_type_create(struct dom_string *qname,
struct dom_string *public_id, struct dom_string *system_id,
dom_alloc alloc, void *pw,
struct dom_document_type **doctype)
diff --git a/src/core/document_type.h b/src/core/document_type.h
index 50dd5ea..93db617 100644
--- a/src/core/document_type.h
+++ b/src/core/document_type.h
@@ -12,6 +12,12 @@ struct dom_document_type;
struct dom_resource_mgr;
struct dom_implementation;
+/* Create a DOM document type */
+dom_exception _dom_document_type_create(struct dom_string *qname,
+ struct dom_string *public_id,
+ struct dom_string *system_id,
+ dom_alloc alloc, void *pw,
+ struct dom_document_type **doctype);
/* Destroy a document type */
void _dom_document_type_destroy(struct dom_node_internal *doctypenode);
dom_exception _dom_document_type_initialise(struct dom_document_type *doctype,
diff --git a/src/core/element.c b/src/core/element.c
index 9c1263a..1069e60 100644
--- a/src/core/element.c
+++ b/src/core/element.c
@@ -35,14 +35,17 @@
#define CHAINS_NAMESPACE 7
#define CHAINS_NS_ATTRIBUTES 31
-static struct dom_element_vtable element_vtable = {
+struct dom_element_vtable _dom_element_vtable = {
{
DOM_NODE_VTABLE_ELEMENT
},
DOM_ELEMENT_VTABLE
};
-static struct dom_node_protect_vtable element_protect_vtable = {
+static struct dom_element_protected_vtable element_protect_vtable = {
+ {
+ DOM_NODE_PROTECT_VTABLE_ELEMENT
+ },
DOM_ELEMENT_PROTECT_VTABLE
};
@@ -145,7 +148,7 @@ dom_exception _dom_element_create(struct dom_document *doc,
return DOM_NO_MEM_ERR;
/* Initialise the vtables */
- (*result)->base.base.vtable = &element_vtable;
+ (*result)->base.base.vtable = &_dom_element_vtable;
(*result)->base.vtable = &element_protect_vtable;
return _dom_element_initialise(doc, *result, name, namespace, prefix);
@@ -1109,6 +1112,44 @@ dom_exception _dom_element_lookup_namespace(dom_node_internal *node,
/*----------------------------------------------------------------------*/
/* The protected virtual functions */
+/**
+ * The virtual function to parse some dom attribute
+ *
+ * \param ele The element object
+ * \param name The name of the attribute
+ * \param value The new value of the attribute
+ * \param parsed The parsed value of the attribute
+ * \return DOM_NO_ERR on success.
+ *
+ * @note: This virtual method is provided to serve as a template method.
+ * When any attribute is set or added, the attribute's value should be
+ * checked to make sure that it is a valid one. And the child class of
+ * dom_element may to do some special stuff on the attribute is set. Take
+ * some integer attribute as example:
+ *
+ * 1. The client call dom_element_set_attribute("size", "10.1"), but the
+ * size attribute may only accept an integer, and only the specific
+ * dom_element know this. And the dom_attr_set_value method, which is
+ * called by dom_element_set_attribute should call the this virtual
+ * template method.
+ * 2. The overload virtual function of following one will truncate the
+ * "10.1" to "10" to make sure it is a integer. And of course, the
+ * overload method may also save the integer as a 'int' C type for
+ * later easy accessing by any client.
+ */
+dom_exception _dom_element_parse_attribute(dom_element *ele,
+ struct dom_string *name, struct dom_string *value,
+ struct dom_string **parsed)
+{
+ UNUSED(ele);
+ UNUSED(name);
+
+ dom_string_ref(value);
+ *parsed = value;
+
+ return DOM_NO_ERR;
+}
+
/* The destroy virtual function of dom_element */
void __dom_element_destroy(struct dom_node_internal *node)
{
@@ -1296,9 +1337,13 @@ dom_exception _dom_element_set_attr(struct dom_element *element,
if (err != DOM_NO_ERR)
return err;
+ /* Set its parent, so that value parsing works */
+ dom_node_set_parent(attr, element);
+
/* Set its value */
err = dom_attr_set_value(attr, value);
if (err != DOM_NO_ERR) {
+ dom_node_set_parent(attr, NULL);
dom_node_unref(attr);
return err;
}
@@ -1310,6 +1355,7 @@ dom_exception _dom_element_set_attr(struct dom_element *element,
(dom_event_target *) attr, name,
DOM_MUTATION_ADDITION, &success);
if (err != DOM_NO_ERR) {
+ dom_node_set_parent(attr, NULL);
dom_node_unref(attr);
return err;
}
@@ -1319,6 +1365,7 @@ dom_exception _dom_element_set_attr(struct dom_element *element,
(dom_event_target *) element,
DOM_MUTATION_ADDITION, &success);
if (err != DOM_NO_ERR) {
+ dom_node_set_parent(attr, NULL);
dom_node_unref(attr);
return err;
}
@@ -1326,11 +1373,11 @@ dom_exception _dom_element_set_attr(struct dom_element *element,
added = _dom_hash_add(hs, str, attr, false);
if (added == false) {
/* If we failed at this step, there must be no memory */
+ dom_node_set_parent(attr, NULL);
dom_node_unref(attr);
return DOM_NO_MEM_ERR;
}
- dom_node_set_parent(attr, element);
dom_node_unref(attr);
dom_node_remove_pending(attr);
diff --git a/src/core/element.h b/src/core/element.h
index 51e1268..8a64314 100644
--- a/src/core/element.h
+++ b/src/core/element.h
@@ -10,7 +10,9 @@
#include <stdbool.h>
-#include <dom/core/exceptions.h>
+#include <dom/core/element.h>
+
+#include "core/node.h"
struct dom_document;
struct dom_element;
@@ -175,8 +177,41 @@ dom_exception _dom_element_lookup_namespace(dom_node_internal *node,
_dom_node_set_user_data, \
_dom_node_get_user_data
+/**
+ * The internal used vtable for element
+ */
+struct dom_element_protected_vtable {
+ struct dom_node_protect_vtable base;
+
+ dom_exception (*dom_element_parse_attribute)(dom_element *ele,
+ struct dom_string *name, struct dom_string *value,
+ struct dom_string **parsed);
+ /**< Called by dom_attr_set_value, and used to check
+ * whether the new attribute value is valid and
+ * return a valid on if it is not
+ */
+};
+
+typedef struct dom_element_protected_vtable dom_element_protected_vtable;
+
+/* Parse the attribute's value */
+static inline dom_exception dom_element_parse_attribute(dom_element *ele,
+ struct dom_string *name, struct dom_string *value,
+ struct dom_string **parsed)
+{
+ struct dom_node_internal *node = (struct dom_node_internal *) ele;
+ return ((dom_element_protected_vtable *) node->vtable)->
+ dom_element_parse_attribute(ele, name, value, parsed);
+}
+#define dom_element_parse_attribute(e, n, v, p) dom_element_parse_attribute( \
+ (dom_element *) (e), (struct dom_string *) (n), \
+ (struct dom_string *) (v), (struct dom_string **) (p))
+
/* The protected virtual function */
+dom_exception _dom_element_parse_attribute(dom_element *ele,
+ struct dom_string *name, struct dom_string *value,
+ struct dom_string **parsed);
void __dom_element_destroy(dom_node_internal *node);
dom_exception _dom_element_alloc(struct dom_document *doc,
struct dom_node_internal *n, struct dom_node_internal **ret);
@@ -184,6 +219,9 @@ dom_exception _dom_element_copy(struct dom_node_internal *new,
struct dom_node_internal *old);
#define DOM_ELEMENT_PROTECT_VTABLE \
+ _dom_element_parse_attribute
+
+#define DOM_NODE_PROTECT_VTABLE_ELEMENT \
__dom_element_destroy, \
_dom_element_alloc, \
_dom_element_copy
@@ -192,4 +230,6 @@ dom_exception _dom_element_copy(struct dom_node_internal *new,
dom_exception _dom_element_get_id(struct dom_element *ele,
struct lwc_string_s **id);
+extern struct dom_element_vtable _dom_element_vtable;
+
#endif
diff --git a/src/core/node.c b/src/core/node.c
index 5f35f61..ef2baf2 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -1491,10 +1491,10 @@ dom_exception _dom_node_has_attributes(dom_node_internal *node, bool *result)
dom_exception _dom_node_get_base(dom_node_internal *node,
struct dom_string **result)
{
- UNUSED(node);
- UNUSED(result);
+ struct dom_document *doc = node->owner;
+ assert(doc != NULL);
- return DOM_NOT_SUPPORTED_ERR;
+ return dom_document_get_base(doc, result);
}
/**
@@ -2072,6 +2072,10 @@ bool _dom_node_readonly(const dom_node_internal *node)
if (n->type == DOM_DOCUMENT_TYPE_NODE ||
n->type == DOM_NOTATION_NODE)
return true;
+
+ /* Some Attr node are readonly */
+ if (n->type == DOM_ATTRIBUTE_NODE)
+ return _dom_attr_readonly((const dom_attr *) n);
/* Entity ns and their descendants are read only
* EntityReference ns and their descendants are read only */
@@ -2363,6 +2367,25 @@ void _dom_node_unref_intern_string(dom_node_internal *node,
}
/**
+ * Create a lwc_string using the node's owner's lwc_context
+ *
+ * \param node The node object
+ * \param data The string data
+ * \param len The length of the string data
+ * \param str The returned lwc_string
+ * \return DOM_NO_ERR on success, appropirate dom_exception on failure.
+ */
+dom_exception _dom_node_create_lwcstring(dom_node_internal *node,
+ const uint8_t *data, size_t len, struct lwc_string_s **str)
+{
+ dom_document *doc = dom_node_get_owner(node);
+
+ assert(doc != NULL);
+
+ return _dom_document_create_lwcstring(doc, data, len, str);
+}
+
+/**
* Try to destroy this node.
*
* \param node The node to destroy
diff --git a/src/core/node.h b/src/core/node.h
index 4144b6e..70187d6 100644
--- a/src/core/node.h
+++ b/src/core/node.h
@@ -286,6 +286,8 @@ dom_exception _dom_node_get_intern_string(dom_node_internal *node,
struct dom_string *str, struct lwc_string_s **intern);
void _dom_node_unref_intern_string(dom_node_internal *node,
struct lwc_string_s *inter);
+dom_exception _dom_node_create_lwcstring(dom_node_internal *node,
+ const uint8_t *data, size_t len, struct lwc_string_s **str);
/* Try to destroy the node, if its refcnt is not zero, then append it to the
* owner document's pending list */