summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/events/event_target.c159
-rw-r--r--src/events/event_target.h11
2 files changed, 52 insertions, 118 deletions
diff --git a/src/events/event_target.c b/src/events/event_target.c
index c4a2f90..7f941e2 100644
--- a/src/events/event_target.c
+++ b/src/events/event_target.c
@@ -19,68 +19,31 @@
#include "utils/utils.h"
#include "utils/validate.h"
-/* The number of chains in the hash table used for hash event types */
-#define CHAINS 11
-
-static uint32_t event_target_hash(void *key, void *pw)
+static void event_target_destroy_listeners(struct listener_entry *list)
{
- UNUSED(pw);
-
- return dom_string_hash(key);
-}
+ struct listener_entry *next = NULL;
-static void event_target_destroy_key(void *key, void *pw)
-{
- UNUSED(pw);
+ if (list == NULL)
+ return;
- dom_string_unref(key);
-}
-
-static void event_target_destroy_value(void *value, void *pw)
-{
- struct listener_entry *le = NULL;
- struct list_entry *i = (struct list_entry *) value;
-
- UNUSED(pw);
-
- while (i != i->next) {
- le = (struct listener_entry *) i->next;
- list_del(i->next);
- dom_event_listener_unref(le->listener);
- free(le);
+ while (list != (struct listener_entry *) list->list.next) {
+ next = (struct listener_entry *) list->list.next;
+ list_del(list->list.next);
+ dom_event_listener_unref(list->listener);
+ dom_string_unref(list->type);
+ free(list);
}
- le = (struct listener_entry *) i;
- list_del(i);
- dom_event_listener_unref(le->listener);
- free(le);
-}
-
-static bool event_target_key_isequal(void *key1, void *key2, void *pw)
-{
- UNUSED(pw);
-
- return dom_string_isequal(key1, key2);
+ dom_event_listener_unref(list->listener);
+ dom_string_unref(list->type);
+ free(list);
}
-static const dom_hash_vtable event_target_vtable = {
- event_target_hash,
- NULL,
- event_target_destroy_key,
- NULL,
- event_target_destroy_value,
- event_target_key_isequal
-};
-
/* Initialise this EventTarget */
dom_exception _dom_event_target_internal_initialise(
dom_event_target_internal *eti)
{
- eti->listeners = _dom_hash_create(CHAINS, &event_target_vtable, NULL);
- if (eti->listeners == NULL)
- return DOM_NO_MEM_ERR;
-
- eti->ns_listeners = NULL;
+ eti->listeners = NULL;
return DOM_NO_ERR;
}
@@ -88,12 +51,7 @@ dom_exception _dom_event_target_internal_initialise(
/* Finalise this EventTarget */
void _dom_event_target_internal_finalise(dom_event_target_internal *eti)
{
- _dom_hash_destroy(eti->listeners);
-
- /* TODO: Now, we did not support the EventListener with namespace,
- * when we support it, we should deal with the ns_listeners hash
- * table, too.
- */
+ event_target_destroy_listeners(eti->listeners);
}
/*-------------------------------------------------------------------------*/
@@ -114,7 +72,6 @@ dom_exception _dom_event_target_add_event_listener(
bool capture)
{
struct listener_entry *le = NULL;
- dom_string *t = NULL;
le = malloc(sizeof(struct listener_entry));
if (le == NULL)
@@ -122,22 +79,15 @@ dom_exception _dom_event_target_add_event_listener(
/* Initialise the listener_entry */
list_init(&le->list);
+ le->type = dom_string_ref(type);
le->listener = listener;
dom_event_listener_ref(listener);
le->capture = capture;
- t = dom_string_ref(type);
-
- /* Find the type of this event */
- struct list_entry *item = (struct list_entry *) _dom_hash_get(
- eti->listeners, t);
- if (item == NULL) {
- /* If there is no item in the hash table, we should add the
- * first */
- _dom_hash_add(eti->listeners, t, &le->list, false);
+ if (eti->listeners == NULL) {
+ eti->listeners = le;
} else {
- /* Append this listener to the end of the list */
- list_append(item, &le->list);
+ list_append(&eti->listeners->list, &le->list);
}
return DOM_NO_ERR;
@@ -157,28 +107,22 @@ dom_exception _dom_event_target_remove_event_listener(
dom_string *type, struct dom_event_listener *listener,
bool capture)
{
- struct listener_entry *le = NULL;
+ if (eti->listeners != NULL) {
+ struct listener_entry *le = eti->listeners;
- /* Find the type of this event */
- struct list_entry *item = (struct list_entry *) _dom_hash_get(
- eti->listeners, type);
- if (item == NULL) {
- /* There is no such event listener */
- return DOM_NO_ERR;
- } else {
- struct list_entry *i = item;
do {
- le = (struct listener_entry *) i;
- if (le->listener == listener &&
+ if (dom_string_isequal(le->type, type) &&
+ le->listener == listener &&
le->capture == capture) {
- /* We found the listener */
- list_del(i);
+ list_del(&le->list);
dom_event_listener_unref(le->listener);
+ dom_string_unref(le->type);
free(le);
break;
}
- i = i->next;
- } while(i != item);
+
+ le = (struct listener_entry *) le->list.next;
+ } while (le != eti->listeners);
}
return DOM_NO_ERR;
@@ -255,38 +199,33 @@ dom_exception _dom_event_target_dispatch(dom_event_target *et,
struct dom_event *evt, dom_event_flow_phase phase,
bool *success)
{
- dom_string *t = evt->type;
+ if (eti->listeners != NULL) {
+ struct listener_entry *le = eti->listeners;
- struct list_entry *item = (struct list_entry *) _dom_hash_get(
- eti->listeners, t);
- if (item == NULL) {
- /* There is no such event listener */
- return DOM_NO_ERR;
- } else {
- /* Call the handler for each listener */
- struct list_entry *i = item;
- /* Fill the Event fields */
evt->current = et;
+
do {
- struct listener_entry *le =
- (struct listener_entry *) i;
- assert(le->listener->handler != NULL);
- if ((le->capture == true &&
- phase == DOM_CAPTURING_PHASE) ||
- (le->capture == false &&
+ if (dom_string_isequal(le->type, evt->type)) {
+ assert(le->listener->handler != NULL);
+
+ if ((le->capture &&
+ phase == DOM_CAPTURING_PHASE) ||
+ (le->capture == false &&
phase == DOM_BUBBLING_PHASE) ||
- (evt->target == evt->current &&
+ (evt->target == evt->current &&
phase == DOM_AT_TARGET)) {
- /* We found the listener */
- le->listener->handler(evt, le->listener->pw);
- /* If the handler call
- * stopImmediatedPropagation, we should
- * break */
- if (evt->stop_now == true)
- break;
+ le->listener->handler(evt,
+ le->listener->pw);
+ /* If the handler called
+ * stopImmediatePropagation, we should
+ * break */
+ if (evt->stop_now == true)
+ break;
+ }
}
- i = i->next;
- } while(i != item);
+
+ le = (struct listener_entry *) le->list.next;
+ } while (le != eti->listeners);
}
if (evt->prevent_default == true)
diff --git a/src/events/event_target.h b/src/events/event_target.h
index fad39d6..4415a2a 100644
--- a/src/events/event_target.h
+++ b/src/events/event_target.h
@@ -17,7 +17,6 @@
#include "events/dispatch.h"
#include "utils/list.h"
-#include "utils/hashtable.h"
/**
* Listener Entry
@@ -26,6 +25,7 @@ struct listener_entry {
struct list_entry list;
/**< The listener list registered at the same
* EventTarget */
+ dom_string *type; /**< Event type */
dom_event_listener *listener; /**< The EventListener */
bool capture; /**< Whether this listener is in capture phase */
};
@@ -34,13 +34,8 @@ struct listener_entry {
* EventTarget internal class
*/
struct dom_event_target_internal {
- struct dom_hash_table *listeners;
- /**< The listeners of this EventTarget.
- * The listeners are organized by the
- * type of events they listen for
- */
- struct dom_hash_table *ns_listeners;
- /**< The listeners with namespace of thie EventTarget */
+ struct listener_entry *listeners;
+ /**< The listeners of this EventTarget. */
};
typedef struct dom_event_target_internal dom_event_target_internal;