diff options
author | Bo Yang <struggleyb.nku@gmail.com> | 2009-08-13 09:33:24 +0000 |
---|---|---|
committer | Bo Yang <struggleyb.nku@gmail.com> | 2009-08-13 09:33:24 +0000 |
commit | 13fadb12fb400818e0ccb4c38b3bfce70ccfdad2 (patch) | |
tree | 19c55b39d97567a37b88b49aaaac13b21b9f24ee /src/core | |
parent | bf6bc398bd40e39a016725550f5b8446a01ee2d1 (diff) | |
download | libdom-13fadb12fb400818e0ccb4c38b3bfce70ccfdad2.tar.gz libdom-13fadb12fb400818e0ccb4c38b3bfce70ccfdad2.tar.bz2 |
Merge the Events module (branches/struggleyb/libdom-events) back to trunk. :)
svn path=/trunk/dom/; revision=9236
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/characterdata.c | 58 | ||||
-rw-r--r-- | src/core/document.c | 21 | ||||
-rw-r--r-- | src/core/document.h | 11 | ||||
-rw-r--r-- | src/core/element.c | 222 | ||||
-rw-r--r-- | src/core/implementation.c | 3 | ||||
-rw-r--r-- | src/core/node.c | 85 | ||||
-rw-r--r-- | src/core/node.h | 5 | ||||
-rw-r--r-- | src/core/string.c | 26 | ||||
-rw-r--r-- | src/core/string.h | 10 |
9 files changed, 396 insertions, 45 deletions
diff --git a/src/core/characterdata.c b/src/core/characterdata.c index f5b4094..6bb542d 100644 --- a/src/core/characterdata.c +++ b/src/core/characterdata.c @@ -10,11 +10,13 @@ #include <dom/core/characterdata.h> #include <dom/core/string.h> +#include <dom/events/events.h> #include "core/characterdata.h" #include "core/document.h" #include "core/node.h" #include "utils/utils.h" +#include "events/mutation_event.h" /* The virtual functions for dom_characterdata, we make this vtable * public to each child class */ @@ -128,6 +130,15 @@ dom_exception _dom_characterdata_set_data(struct dom_characterdata *cdata, return DOM_NO_MODIFICATION_ALLOWED_ERR; } + /* Dispatch a DOMCharacterDataModified event */ + dom_exception err; + struct dom_document *doc = dom_node_get_owner(cdata); + bool success = true; + err = _dom_dispatch_characterdata_modified_event(doc, c, c->value, + data, &success); + if (err != DOM_NO_ERR) + return err; + if (c->value != NULL) { dom_string_unref(c->value); } @@ -135,7 +146,8 @@ dom_exception _dom_characterdata_set_data(struct dom_characterdata *cdata, dom_string_ref(data); c->value = data; - return DOM_NO_ERR; + success = true; + return _dom_dispatch_subtree_modified_event(doc, c->parent, &success); } /** @@ -223,13 +235,22 @@ dom_exception _dom_characterdata_append_data(struct dom_characterdata *cdata, return err; } + /* Dispatch a DOMCharacterDataModified event */ + struct dom_document *doc = dom_node_get_owner(cdata); + bool success = true; + err = _dom_dispatch_characterdata_modified_event(doc, c, c->value, + temp, &success); + if (err != DOM_NO_ERR) + return err; + if (c->value != NULL) { dom_string_unref(c->value); } c->value = temp; - return DOM_NO_ERR; + success = true; + return _dom_dispatch_subtree_modified_event(doc, c->parent, &success); } /** @@ -270,13 +291,22 @@ dom_exception _dom_characterdata_insert_data(struct dom_characterdata *cdata, return err; } + /* Dispatch a DOMCharacterDataModified event */ + struct dom_document *doc = dom_node_get_owner(cdata); + bool success = true; + err = _dom_dispatch_characterdata_modified_event(doc, c, c->value, + temp, &success); + if (err != DOM_NO_ERR) + return err; + if (c->value != NULL) { dom_string_unref(c->value); } c->value = temp; - return DOM_NO_ERR; + success = true; + return _dom_dispatch_subtree_modified_event(doc, c->parent, &success); } /** @@ -319,13 +349,22 @@ dom_exception _dom_characterdata_delete_data(struct dom_characterdata *cdata, return err; } + /* Dispatch a DOMCharacterDataModified event */ + struct dom_document *doc = dom_node_get_owner(cdata); + bool success = true; + err = _dom_dispatch_characterdata_modified_event(doc, c, c->value, + temp, &success); + if (err != DOM_NO_ERR) + return err; + if (c->value != NULL) { dom_string_unref(c->value); } c->value = temp; - return DOM_NO_ERR; + success = true; + return _dom_dispatch_subtree_modified_event(doc, c->parent, &success); } /** @@ -370,13 +409,22 @@ dom_exception _dom_characterdata_replace_data(struct dom_characterdata *cdata, return err; } + /* Dispatch a DOMCharacterDataModified event */ + struct dom_document *doc = dom_node_get_owner(cdata); + bool success = true; + err = _dom_dispatch_characterdata_modified_event(doc, c, c->value, temp, + &success); + if (err != DOM_NO_ERR) + return err; + if (c->value != NULL) { dom_string_unref(c->value); } c->value = temp; - return DOM_NO_ERR; + success = true; + return _dom_dispatch_subtree_modified_event(doc, c->parent, &success); } diff --git a/src/core/document.c b/src/core/document.c index 6bd0045..b15eef3 100644 --- a/src/core/document.c +++ b/src/core/document.c @@ -76,6 +76,7 @@ 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 ctx The intern string context of this document + * \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. @@ -84,6 +85,7 @@ static dom_exception dom_document_dup_node(dom_document *doc, */ dom_exception dom_document_create(struct dom_implementation *impl, dom_alloc alloc, void *pw, struct lwc_context_s *ctx, + dom_events_default_action_fetcher daf, struct dom_document **doc) { struct dom_document *d; @@ -103,7 +105,7 @@ dom_exception dom_document_create(struct dom_implementation *impl, * reaches zero. Documents own themselves (this simplifies the * rest of the code, as it doesn't need to special case Documents) */ - err = _dom_document_initialise(d, impl, alloc, pw, ctx); + err = _dom_document_initialise(d, impl, alloc, pw, ctx, daf); if (err != DOM_NO_ERR) { /* Clean up document */ alloc(d, 0, pw); @@ -118,7 +120,8 @@ dom_exception dom_document_create(struct dom_implementation *impl, /* Initialise the document */ dom_exception _dom_document_initialise(struct dom_document *doc, struct dom_implementation *impl, dom_alloc alloc, void *pw, - struct lwc_context_s *ctx) + struct lwc_context_s *ctx, + dom_events_default_action_fetcher daf) { assert(ctx != NULL); assert(alloc != NULL); @@ -150,7 +153,8 @@ dom_exception _dom_document_initialise(struct dom_document *doc, doc->id_name = NULL; - return err; + /* We should not pass a NULL when all things hook up */ + return _dom_document_event_internal_initialise(doc, &doc->dei, daf); } @@ -185,6 +189,8 @@ bool _dom_document_finalise(struct dom_document *doc) if (doc->id_name != NULL) lwc_context_string_unref(doc->context, doc->id_name); lwc_context_unref(doc->context); + + _dom_document_event_internal_finalise(doc, &doc->dei); return true; } @@ -1302,7 +1308,7 @@ dom_exception _dom_document_create_string(struct dom_document *doc, return dom_string_create(doc->alloc, doc->pw, data, len, result); } -/* +/** * Create a lwc_string * * \param doc The document object @@ -1324,6 +1330,13 @@ dom_exception _dom_document_create_lwcstring(struct dom_document *doc, return _dom_exception_from_lwc_error(lerr); } +/* Unref a lwc_string created by this document */ +void _dom_document_unref_lwcstring(struct dom_document *doc, + struct lwc_string_s *str) +{ + lwc_context_string_unref(doc->context, str); +} + /* Simple accessor for lwc_context of this document */ struct lwc_context_s *_dom_document_get_intern_context( struct dom_document *doc) diff --git a/src/core/document.h b/src/core/document.h index 145eddf..ea961a2 100644 --- a/src/core/document.h +++ b/src/core/document.h @@ -21,6 +21,8 @@ #include "utils/resource_mgr.h" #include "utils/list.h" +#include "events/document_event.h" + struct dom_document; struct dom_namednodemap; struct dom_node; @@ -61,12 +63,16 @@ struct dom_document { /**< The deletion pending list */ struct lwc_string_s *id_name; /**< The ID attribute's name */ + + dom_document_event_internal dei; + /**< The DocumentEVent interface */ }; /* Initialise the document */ dom_exception _dom_document_initialise(struct dom_document *doc, struct dom_implementation *impl, dom_alloc alloc, void *pw, - struct lwc_context_s *ctx); + struct lwc_context_s *ctx, + dom_events_default_action_fetcher daf); /* Finalise the document */ bool _dom_document_finalise(struct dom_document *doc); @@ -77,6 +83,9 @@ dom_exception _dom_document_create_string(struct dom_document *doc, /* Create a lwc_string from C string */ dom_exception _dom_document_create_lwcstring(struct dom_document *doc, const uint8_t *data, size_t len, struct lwc_string_s **result); +/* Unref a lwc_string of this document */ +void _dom_document_unref_lwcstring(struct dom_document *doc, + struct lwc_string_s *str); /* Create a dom_string from a lwc_string */ dom_exception _dom_document_create_string_from_lwcstring( struct dom_document *doc, struct lwc_string_s *str, diff --git a/src/core/element.c b/src/core/element.c index 54bb9d1..7609b94 100644 --- a/src/core/element.c +++ b/src/core/element.c @@ -16,6 +16,7 @@ #include <dom/core/node.h> #include <dom/core/string.h> #include <dom/core/document.h> +#include <dom/events/events.h> #include "core/attr.h" #include "core/document.h" @@ -26,6 +27,7 @@ #include "utils/namespace.h" #include "utils/utils.h" #include "utils/hashtable.h" +#include "events/mutation_event.h" /* The three numbers are just random ones, maybe we should change it after some * more consideration */ @@ -67,8 +69,6 @@ static dom_exception _dom_element_has_attr(struct dom_element *element, static dom_exception _dom_element_set_id_attr(struct dom_element *element, struct dom_hash_table *hs, struct dom_string *name, bool is_id); -static unsigned int _dom_element_hash_lwcstring(void *key); - /* The operation set for namednodemap */ static dom_exception attributes_get_length(void *priv, @@ -114,6 +114,7 @@ static void *_value(void *value, void *value_pw, dom_alloc alloc, static void *_nsattributes(void *value, void *value_pw, dom_alloc alloc, void *pw, bool clone); + /*----------------------------------------------------------------------*/ /* Constructors and Destructors */ @@ -183,14 +184,14 @@ dom_exception _dom_element_initialise(struct dom_element *el, assert(doc != NULL); err = _dom_document_create_hashtable(doc, CHAINS_ATTRIBUTES, - _dom_element_hash_lwcstring, &el->attributes); + _dom_hash_hash_lwcstring, &el->attributes); if (err != DOM_NO_ERR) { _dom_document_alloc(doc, el, 0); return err; } err = _dom_document_create_hashtable(doc, CHAINS_NAMESPACE, - _dom_element_hash_lwcstring, &el->ns_attributes); + _dom_hash_hash_lwcstring, &el->ns_attributes); if (err != DOM_NO_ERR) { _dom_document_alloc(doc, el, 0); _dom_document_alloc(doc, el->attributes, 0); @@ -540,7 +541,7 @@ dom_exception _dom_element_set_attribute_ns(struct dom_element *element, doc = dom_node_get_owner(element); assert(doc != NULL); err = _dom_document_create_hashtable(doc, CHAINS_NS_ATTRIBUTES, - _dom_element_hash_lwcstring, &attrs); + _dom_hash_hash_lwcstring, &attrs); if (err != DOM_NO_ERR) return err; @@ -686,7 +687,7 @@ dom_exception _dom_element_set_attribute_node_ns(struct dom_element *element, doc = dom_node_get_owner(element); assert(doc != NULL); err = _dom_document_create_hashtable(doc, CHAINS_NS_ATTRIBUTES, - _dom_element_hash_lwcstring, &attrs); + _dom_hash_hash_lwcstring, &attrs); if (err != DOM_NO_ERR) return err; @@ -1218,7 +1219,7 @@ dom_exception _dom_element_get_attr(struct dom_element *element, struct dom_string **value) { void *a; - dom_exception err; + dom_exception err = DOM_NO_ERR; lwc_string *str; /* Looking for name */ @@ -1232,10 +1233,10 @@ dom_exception _dom_element_get_attr(struct dom_element *element, if (a == NULL) { *value = NULL; } else { - dom_attr_get_value(((struct dom_attr *) a), value); + err = dom_attr_get_value(((struct dom_attr *) a), value); } - return DOM_NO_ERR; + return err; } /** @@ -1275,6 +1276,28 @@ dom_exception _dom_element_set_attr(struct dom_element *element, /* Found an existing attribute, so replace its value */ dom_exception err; + /* Dispatch a DOMAttrModified event */ + dom_string *old = NULL; + struct dom_document *doc = dom_node_get_owner(element); + bool success = true; + err = dom_attr_get_value(a, &old); + /* TODO: We did not support some node type such as entity + * reference, in that case, we should ignore the error to + * make sure the event model work as excepted. */ + if (err != DOM_NO_ERR && err != DOM_NOT_SUPPORTED_ERR) + return err; + err = _dom_dispatch_attr_modified_event(doc, e, old, value, a, + name, DOM_MUTATION_MODIFICATION, &success); + dom_string_unref(old); + if (err != DOM_NO_ERR) + return err; + + success = true; + err = _dom_dispatch_subtree_modified_event(doc, + (dom_event_target *) e, &success); + if (err != DOM_NO_ERR) + return err; + err = dom_attr_set_value((struct dom_attr *) a, value); if (err != DOM_NO_ERR) return err; @@ -1294,6 +1317,26 @@ dom_exception _dom_element_set_attr(struct dom_element *element, return err; } + /* Dispatch a DOMAttrModified event */ + struct dom_document *doc = dom_node_get_owner(element); + bool success = true; + err = _dom_dispatch_attr_modified_event(doc, e, NULL, value, + (dom_event_target *) attr, name, + DOM_MUTATION_ADDITION, &success); + if (err != DOM_NO_ERR) { + dom_node_unref(attr); + return err; + } + + err = _dom_dispatch_node_change_event(doc, + (dom_event_target *) attr, + (dom_event_target *) element, + DOM_MUTATION_ADDITION, &success); + if (err != DOM_NO_ERR) { + dom_node_unref(attr); + return err; + } + added = _dom_hash_add(hs, str, attr, false); if (added == false) { /* If we failed at this step, there must be no memory */ @@ -1304,6 +1347,12 @@ dom_exception _dom_element_set_attr(struct dom_element *element, dom_node_set_parent(attr, element); dom_node_unref(attr); dom_node_remove_pending(attr); + + success = true; + err = _dom_dispatch_subtree_modified_event(doc, + (dom_event_target *) element, &success); + if (err != DOM_NO_ERR) + return err; } return DOM_NO_ERR; @@ -1334,13 +1383,51 @@ dom_exception _dom_element_remove_attr(struct dom_element *element, if (err != DOM_NO_ERR) return err; - a = (dom_node_internal *) _dom_hash_del(hs, str); + a = (dom_node_internal *) _dom_hash_get(hs, str); /* Detach attr node from list */ if (a != NULL) { + /* Disptach DOMNodeRemoval event */ + bool success = true; + struct dom_document *doc = dom_node_get_owner(element); + err = _dom_dispatch_node_change_event(doc, + (dom_event_target *) a, + (dom_event_target *) element, + DOM_MUTATION_REMOVAL, &success); + if (err != DOM_NO_ERR) + return err; + + /* Delete the attribute node */ + _dom_hash_del(hs, str); + /* Claim a reference for later event dispatch */ + dom_node_ref(a); + /* And destroy attr */ dom_node_set_parent(a, NULL); dom_node_try_destroy(a); + + /* Dispatch a DOMAttrModified event */ + success = true; + dom_string *old = NULL; + err = dom_attr_get_value(a, &old); + /* TODO: We did not support some node type such as entity + * reference, in that case, we should ignore the error to + * make sure the event model work as excepted. */ + if (err != DOM_NO_ERR && err != DOM_NOT_SUPPORTED_ERR) + return err; + err = _dom_dispatch_attr_modified_event(doc, e, old, NULL, a, + name, DOM_MUTATION_REMOVAL, &success); + dom_string_unref(old); + /* Release the reference */ + dom_node_unref(a); + if (err != DOM_NO_ERR) + return err; + + success = true; + err = _dom_dispatch_subtree_modified_event(doc, + (dom_event_target *) e, &success); + if (err != DOM_NO_ERR) + return err; } /** \todo defaulted attribute handling */ @@ -1437,14 +1524,50 @@ dom_exception _dom_element_set_attr_node(struct dom_element *element, if (err != DOM_NO_ERR) return err; - a = _dom_hash_del(hs, str); + a = _dom_hash_get(hs, str); *result = NULL; if (a != NULL) { + /* Disptach DOMNodeRemoval event */ + bool success = true; + struct dom_document *doc = dom_node_get_owner(element); + err = _dom_dispatch_node_change_event(doc, + (dom_event_target *) a, + (dom_event_target *) element, + DOM_MUTATION_REMOVAL, &success); + if (err != DOM_NO_ERR) + return err; + + _dom_hash_del(hs, str); dom_node_ref(a); *result = (dom_attr *) a; dom_node_set_parent(a, NULL); dom_node_mark_pending(a); + + /* Dispatch a DOMAttrModified event */ + dom_string *old = NULL; + success = true; + err = dom_attr_get_value(a, &old); + /* TODO: We did not support some node type such as entity + * reference, in that case, we should ignore the error to + * make sure the event model work as excepted. */ + if (err != DOM_NO_ERR && err != DOM_NOT_SUPPORTED_ERR) { + dom_node_unref(a); + return err; + } + err = _dom_dispatch_attr_modified_event(doc, e, old, NULL, + (dom_event_target *) a, name, + DOM_MUTATION_REMOVAL, &success); + dom_string_unref(old); + dom_node_unref(a); + if (err != DOM_NO_ERR) + return err; + + success = true; + err = _dom_dispatch_subtree_modified_event(doc, + (dom_event_target *) e, &success); + if (err != DOM_NO_ERR) + return err; } added = _dom_hash_add(hs, str, attr, false); @@ -1455,10 +1578,39 @@ dom_exception _dom_element_set_attr_node(struct dom_element *element, dom_node_set_parent(attr, element); dom_node_remove_pending(attr); + /* Dispatch a DOMAttrModified event */ + dom_string *new = NULL; + struct dom_document *doc = dom_node_get_owner(element); + bool success = true; + err = dom_attr_get_value(attr, &new); + /* TODO: We did not support some node type such as entity reference, in + * that case, we should ignore the error to make sure the event model + * work as excepted. */ + if (err != DOM_NO_ERR && err != DOM_NOT_SUPPORTED_ERR) + return err; + err = _dom_dispatch_attr_modified_event(doc, e, NULL, new, + (dom_event_target *) attr, name, + DOM_MUTATION_ADDITION, &success); + dom_string_unref(new); + if (err != DOM_NO_ERR) + return err; + + err = _dom_dispatch_node_change_event(doc, (dom_event_target *) attr, + (dom_event_target *) element, DOM_MUTATION_ADDITION, + &success); + if (err != DOM_NO_ERR) + return err; + /* Cleanup */ if (name != NULL) dom_string_unref(name); + success = true; + err = _dom_dispatch_subtree_modified_event(doc, + (dom_event_target *) element, &success); + if (err != DOM_NO_ERR) + return err; + return DOM_NO_ERR; } @@ -1500,7 +1652,7 @@ dom_exception _dom_element_remove_attr_node(struct dom_element *element, if (err != DOM_NO_ERR) return err; - a = _dom_hash_del(hs, str); + a = _dom_hash_get(hs, str); /* Now, cleaup the dom_string and lwc_string */ dom_string_unref(name); @@ -1512,16 +1664,53 @@ dom_exception _dom_element_remove_attr_node(struct dom_element *element, return DOM_NOT_FOUND_ERR; } + /* Dispatch a DOMNodeRemoved event */ + bool success = true; + struct dom_document *doc = dom_node_get_owner(element); + err = _dom_dispatch_node_change_event(doc, (dom_event_target *) a, + (dom_event_target *) element, DOM_MUTATION_REMOVAL, + &success); + if (err != DOM_NO_ERR) + return err; + + /* Delete the attribute node */ + _dom_hash_del(hs, str); + dom_node_ref(a); + + /* Dispatch a DOMAttrModified event */ + dom_string *old = NULL; + success = true; + err = dom_attr_get_value(a, &old); + /* TODO: We did not support some node type such as entity reference, in + * that case, we should ignore the error to make sure the event model + * work as excepted. */ + if (err != DOM_NO_ERR && err != DOM_NOT_SUPPORTED_ERR) { + dom_node_unref(a); + return err; + } + err = _dom_dispatch_attr_modified_event(doc, e, old, NULL, + (dom_event_target *) a, name, + DOM_MUTATION_REMOVAL, &success); + dom_string_unref(old); + dom_node_unref(a); + if (err != DOM_NO_ERR) + return err; + /* When a Node is removed, it should be destroy. When its refcnt is not * zero, it will be added to the document's deletion pending list. * When a Node is removed, its parent should be NULL, but its owner * should remain to be the document. */ - dom_node_ref(a); *result = (dom_attr *) a; dom_node_set_parent(a, NULL); dom_node_mark_pending(a); + success = true; + err = _dom_dispatch_subtree_modified_event(doc, (dom_event_target *) e, + &success); + if (err != DOM_NO_ERR) + return err; + return DOM_NO_ERR; } @@ -1704,13 +1893,6 @@ dom_exception _dom_element_get_id(struct dom_element *ele, lwc_string **id) } -/* The hash function for attributes and id tables */ -unsigned int _dom_element_hash_lwcstring(void *key) -{ - lwc_string *lstr = (lwc_string *) key; - - return lwc_string_hash_value(lstr); -} /*-------------- The dom_namednodemap functions -------------------------*/ diff --git a/src/core/implementation.c b/src/core/implementation.c index e2b6763..30e1eb3 100644 --- a/src/core/implementation.c +++ b/src/core/implementation.c @@ -122,10 +122,11 @@ dom_exception dom_implementation_create_document( struct dom_string *namespace, struct dom_string *qname, struct dom_document_type *doctype, dom_alloc alloc, void *pw, struct lwc_context_s *ctx, + dom_events_default_action_fetcher daf, struct dom_document **doc) { return impl->create_document(impl, namespace, qname, doctype, alloc, - pw, ctx, doc); + pw, ctx, daf, doc); } /** diff --git a/src/core/node.c b/src/core/node.c index 1c0b28f..1bdcade 100644 --- a/src/core/node.c +++ b/src/core/node.c @@ -17,6 +17,7 @@ #include <dom/core/nodelist.h> #include <dom/core/implementation.h> #include <dom/core/document_type.h> +#include <dom/events/events.h> #include "core/string.h" #include "core/namednodemap.h" @@ -33,15 +34,16 @@ #include "core/text.h" #include "utils/utils.h" #include "utils/resource_mgr.h" +#include "events/mutation_event.h" static bool _dom_node_permitted_child(const dom_node_internal *parent, const dom_node_internal *child); -static inline void _dom_node_attach(dom_node_internal *node, +static inline dom_exception _dom_node_attach(dom_node_internal *node, dom_node_internal *parent, dom_node_internal *previous, dom_node_internal *next); static inline void _dom_node_detach(dom_node_internal *node); -static inline void _dom_node_attach_range(dom_node_internal *first, +static inline dom_exception _dom_node_attach_range(dom_node_internal *first, dom_node_internal *last, dom_node_internal *parent, dom_node_internal *previous, @@ -51,7 +53,6 @@ static inline void _dom_node_detach_range(dom_node_internal *first, static inline void _dom_node_replace(dom_node_internal *old, dom_node_internal *replacement); - static struct dom_node_vtable node_vtable = { DOM_NODE_VTABLE }; @@ -249,7 +250,7 @@ dom_exception _dom_node_initialise_generic( dom_node_mark_pending(node); } - return DOM_NO_ERR; + return _dom_event_target_internal_initialise(doc, &node->eti); } /** @@ -331,7 +332,14 @@ void _dom_node_finalise_generic(dom_node_internal *node, dom_alloc alloc, if (node->name != NULL) lwc_context_string_unref(ctx, node->name); - /* Detach from the pending list, if we are in it */ + /* If the node has no owner document, we need not to finalise its + * dom_event_target_internal structure. + */ + if (node->owner != NULL) + _dom_event_target_internal_finalise(node->owner, &node->eti); + + /* Detach from the pending list, if we are in it, + * this part of code should always be the end of this function. */ if (node->pending_list.prev != &node->pending_list) { assert (node->pending_list.next != &node->pending_list); list_del(&node->pending_list); @@ -351,7 +359,8 @@ void _dom_node_finalise_generic(dom_node_internal *node, dom_alloc alloc, */ void _dom_node_ref(dom_node_internal *node) { - node->refcnt++; + if (node != NULL) + node->refcnt++; } @@ -816,6 +825,8 @@ dom_exception _dom_node_insert_before(dom_node_internal *node, dom_node_internal *new_child, dom_node_internal *ref_child, dom_node_internal **result) { + dom_exception err; + /* Ensure that new_child and node are owned by the same document */ if ((new_child->type == DOM_DOCUMENT_TYPE_NODE && new_child->owner != NULL && @@ -874,24 +885,29 @@ dom_exception _dom_node_insert_before(dom_node_internal *node, return DOM_HIERARCHY_REQUEST_ERR; if (new_child->first_child != NULL) { - _dom_node_attach_range(new_child->first_child, + err = _dom_node_attach_range(new_child->first_child, new_child->last_child, node, ref_child == NULL ? node->last_child : ref_child->previous, ref_child == NULL ? NULL : ref_child); + if (err != DOM_NO_ERR) + return err; new_child->first_child = NULL; new_child->last_child = NULL; } } else { - _dom_node_attach(new_child, + err = _dom_node_attach(new_child, node, ref_child == NULL ? node->last_child : ref_child->previous, ref_child == NULL ? NULL : ref_child); + if (err != DOM_NO_ERR) + return err; + } /* DocumentType nodes are created outside the Document so, @@ -1059,6 +1075,14 @@ dom_exception _dom_node_remove_child(dom_node_internal *node, if (_dom_node_readonly(node)) return DOM_NO_MODIFICATION_ALLOWED_ERR; + /* Dispatch a DOMNodeRemoval event */ + dom_exception err; + bool success = true; + err = _dom_dispatch_node_change_event(node->owner, old_child, node, + DOM_MUTATION_REMOVAL, &success); + if (err != DOM_NO_ERR) + return err; + /* Detach the node */ _dom_node_detach(old_child); @@ -1070,6 +1094,12 @@ dom_exception _dom_node_remove_child(dom_node_internal *node, dom_node_try_destroy(old_child); *result = old_child; + success = true; + err = _dom_dispatch_subtree_modified_event(node->owner, node, + &success); + if (err != DOM_NO_ERR) + return err; + return DOM_NO_ERR; } @@ -2048,7 +2078,8 @@ dom_exception _dom_node_copy(dom_node_internal *new, dom_node_internal *old) * so it should be put in the pending list. */ dom_node_mark_pending(new); - return DOM_NO_ERR; + /* Intialise the EventTarget interface */ + return _dom_event_target_internal_initialise(new->owner, &new->eti); } @@ -2162,11 +2193,13 @@ bool _dom_node_readonly(const dom_node_internal *node) * \param parent Node to attach ::node as child of * \param previous Previous node in sibling list, or NULL if none * \param next Next node in sibling list, or NULL if none + * \return DOM_NO_ERR on success, appropriate dom_exception on failure. */ -void _dom_node_attach(dom_node_internal *node, dom_node_internal *parent, - dom_node_internal *previous, dom_node_internal *next) +dom_exception _dom_node_attach(dom_node_internal *node, + dom_node_internal *parent, dom_node_internal *previous, + dom_node_internal *next) { - _dom_node_attach_range(node, node, parent, previous, next); + return _dom_node_attach_range(node, node, parent, previous, next); } /** @@ -2191,10 +2224,11 @@ void _dom_node_detach(dom_node_internal *node) * \param parent Node to attach range to * \param previous Previous node in sibling list, or NULL if none * \param next Next node in sibling list, or NULL if none + * \return DOM_NO_ERR on success, appropriate dom_exception on failure. * * The range is assumed to be a linked list of sibling nodes. */ -void _dom_node_attach_range(dom_node_internal *first, +dom_exception _dom_node_attach_range(dom_node_internal *first, dom_node_internal *last, dom_node_internal *parent, dom_node_internal *previous, @@ -2213,9 +2247,24 @@ void _dom_node_attach_range(dom_node_internal *first, else parent->last_child = last; + dom_exception err; + bool success = true; for (dom_node_internal *n = first; n != last->next; n = n->next) { n->parent = parent; + /* Dispatch a DOMNodeInserted event */ + err = _dom_dispatch_node_change_event(parent->owner, n, parent, + DOM_MUTATION_ADDITION, &success); + if (err != DOM_NO_ERR) + return err; } + + success = true; + err = _dom_dispatch_subtree_modified_event(parent->owner, parent, + &success); + if (err != DOM_NO_ERR) + return err; + + return DOM_NO_ERR; } /** @@ -2239,10 +2288,20 @@ void _dom_node_detach_range(dom_node_internal *first, else last->parent->last_child = first->previous; + bool success = true; + dom_node_internal *parent = first->parent; for (dom_node_internal *n = first; n != last->next; n = n->next) { + /* Dispatch a DOMNodeRemoval event */ + _dom_dispatch_node_change_event(n->owner, n, n->parent, + DOM_MUTATION_REMOVAL, &success); + n->parent = NULL; } + success = true; + _dom_dispatch_subtree_modified_event(parent->owner, parent, + &success); + first->previous = NULL; last->next = NULL; } diff --git a/src/core/node.h b/src/core/node.h index 68776da..c1a4192 100644 --- a/src/core/node.h +++ b/src/core/node.h @@ -15,6 +15,9 @@ #include <dom/core/node.h> #include <dom/functypes.h> +#include "events/event_target.h" +#include "events/mutation_event.h" + #include "utils/list.h" /** @@ -76,6 +79,8 @@ struct dom_node_internal { uint32_t refcnt; /**< Reference count */ struct list_entry pending_list; /**< The document delete pending list */ + + dom_event_target_internal eti; /**< The EventTarget interface */ }; dom_node_internal * _dom_node_create(struct dom_document *doc); diff --git a/src/core/string.c b/src/core/string.c index 081e03d..7442c66 100644 --- a/src/core/string.c +++ b/src/core/string.c @@ -56,7 +56,8 @@ static struct dom_string empty_string = { */ void dom_string_ref(struct dom_string *str) { - str->refcnt++; + if (str != NULL) + str->refcnt++; } /** @@ -963,3 +964,26 @@ int _dom_lwc_string_compare_raw(struct lwc_string_s *s1, return memcmp(rs1, rs2, len); } +/** + * Get the raw character data of the dom_string. + * + * \param str The dom_string object + * \return The C string pointer + * + * @note: This function is just provided for the convenience of accessing the + * raw C string character, no change on the result string is allowed. + */ +char *_dom_string_data(struct dom_string *str) +{ + return (char *) str->ptr; +} + +/* Get the string length of this dom_string + * + * \param str The dom_string object + */ +size_t _dom_string_length(struct dom_string *str) +{ + return str->len; +} + diff --git a/src/core/string.h b/src/core/string.h index 8372688..46704d8 100644 --- a/src/core/string.h +++ b/src/core/string.h @@ -28,5 +28,15 @@ int _dom_lwc_string_compare_raw(struct lwc_string_s *s1, /* Map the lwc_error to dom_exception */ dom_exception _dom_exception_from_lwc_error(lwc_error err); +/** + * Get the raw character data of the dom_string. + * @note: This function is just provided for the convenience of accessing the + * raw C string character, no change on the result string is allowed. + */ +char *_dom_string_data(struct dom_string *str); + +/* Get the string length of this dom_string */ +size_t _dom_string_length(struct dom_string *str); + #endif |