Gitweb links:
...log
http://git.netsurf-browser.org/libdom.git/shortlog/737cb995c1b2bf144ee508...
...commit
http://git.netsurf-browser.org/libdom.git/commit/737cb995c1b2bf144ee5087a...
...tree
http://git.netsurf-browser.org/libdom.git/tree/737cb995c1b2bf144ee5087a01...
The branch, master has been updated
via 737cb995c1b2bf144ee5087a011418b1f9b8aa69 (commit)
via 2196dd1c1d5a78e82e8b57d77008a0486011bec9 (commit)
via 7e9681b5e1829e533d9cce3b28ee94ecf2daff24 (commit)
via b4a245f67fe6c40f3aa8ddfe627d28e3513a9463 (commit)
from e137aa0f31bcc399658d266487494ef07be185fc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/libdom.git/commit/?id=737cb995c1b2bf144ee5...
commit 737cb995c1b2bf144ee5087a011418b1f9b8aa69
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
Further optimise event dispatch.
Only add event targets to the array of targets for capture/bubbling
if it is actually listening for the event type we're dispatching.
diff --git a/src/core/node.c b/src/core/node.c
index 3661521..8800a4b 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -2408,15 +2408,30 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
/* Add interested event listeners to array */
for (; target != NULL; target = target->parent) {
- if (target->eti.listeners == NULL) {
+ struct listener_entry *le = target->eti.listeners;
+ bool target_has_listener = false;
+
+ if (le == NULL) {
/* This event target isn't listening to anything */
continue;
}
- /* OK, add the event target to the array */
- /* TODO: We could check that the event type string matches
- * the types that registered listeners are listening for.
- */
+ /* Check whether the event target is listening for this
+ * event type */
+ do {
+ if (dom_string_isequal(le->type, evt->type)) {
+ target_has_listener = true;
+ break;
+ }
+ le = (struct listener_entry *) le->list.next;
+ } while (le != target->eti.listeners);
+
+ if (target_has_listener == false) {
+ continue;
+ }
+
+ /* The event target is listening for this event type,
+ * so add it to the array. */
if (ntargets == ntargets_allocated) {
err = _dom_event_targets_expand(&ntargets_allocated,
&targets);
commitdiff
http://git.netsurf-browser.org/libdom.git/commit/?id=2196dd1c1d5a78e82e8b...
commit 2196dd1c1d5a78e82e8b57d77008a0486011bec9
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
Optimise event dispatch.
- Only allocate array of event targets when there is at least one
target listening.
- Only add targets to the list if they have got at least one
listener registered.
diff --git a/src/core/node.c b/src/core/node.c
index 8111523..3661521 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -2316,6 +2316,39 @@ dom_exception _dom_node_remove_event_listener_ns(dom_event_target
*et,
namespace, type, listener, capture);
}
+
+/** Helper for allocating/expanding array of event targets */
+static inline dom_exception _dom_event_targets_expand(
+ uint32_t *ntargets_allocated,
+ dom_event_target ***targets)
+{
+ dom_event_target **t = *targets;
+ uint32_t size = *ntargets_allocated;
+
+ if (t == NULL) {
+ /* Create the event target list */
+ size = 64;
+ t = calloc(sizeof(*t), size);
+ if (targets == NULL) {
+ return DOM_NO_MEM_ERR;
+ }
+ } else {
+ /* Extend events target list */
+ dom_event_target **tmp = realloc(t, size * 2 * sizeof(*t));
+ if (tmp == NULL) {
+ return DOM_NO_MEM_ERR;
+ }
+ memset(tmp + size, 0, size * sizeof(*tmp));
+ t = tmp;
+ size *= 2;
+ }
+
+ *ntargets_allocated = size;
+ *targets = t;
+
+ return DOM_NO_ERR;
+}
+
/**
* Dispatch an event into the implementation's event model
*
@@ -2368,29 +2401,31 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
*success = true;
- /* Compose the event target list */
+ /* Initialise array of targets for capture/bubbling phases */
+ targets = NULL;
+ ntargets_allocated = 0;
ntargets = 0;
- ntargets_allocated = 64;
- targets = calloc(sizeof(*targets), ntargets_allocated);
- if (targets == NULL) {
- /** \todo Report memory exhaustion? */
- return DOM_NO_ERR;
- }
- while (target != NULL) {
+ /* Add interested event listeners to array */
+ for (; target != NULL; target = target->parent) {
+ if (target->eti.listeners == NULL) {
+ /* This event target isn't listening to anything */
+ continue;
+ }
+
+ /* OK, add the event target to the array */
+ /* TODO: We could check that the event type string matches
+ * the types that registered listeners are listening for.
+ */
if (ntargets == ntargets_allocated) {
- dom_event_target **newtargets = realloc(
- targets,
- ntargets_allocated * 2 * sizeof(*targets));
- if (newtargets == NULL)
+ err = _dom_event_targets_expand(&ntargets_allocated,
+ &targets);
+ if (err != DOM_NO_ERR) {
+ ret = err;
goto cleanup;
- memset(newtargets + ntargets_allocated,
- 0, ntargets_allocated * sizeof(*newtargets));
- targets = newtargets;
- ntargets_allocated *= 2;
+ }
}
targets[ntargets++] = (dom_event_target *)dom_node_ref(target);
- target = target->parent;
}
/* Fill the target of the event */
@@ -2462,8 +2497,8 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
dom_default_action_phase phase = DOM_DEFAULT_ACTION_END;
if (evt->prevent_default == true)
phase = DOM_DEFAULT_ACTION_PREVENTED;
- dom_default_action_callback cb = dei->actions(evt->type, phase,
- &pw);
+ dom_default_action_callback cb = dei->actions(
+ evt->type, phase, &pw);
if (cb != NULL) {
cb(evt, pw);
}
@@ -2477,7 +2512,9 @@ cleanup:
while (ntargets--) {
dom_node_unref(targets[ntargets]);
}
- free(targets);
+ if (targets != NULL) {
+ free(targets);
+ }
if (dei != NULL && dei->actions != NULL) {
dom_default_action_callback cb = dei->actions(evt->type,
commitdiff
http://git.netsurf-browser.org/libdom.git/commit/?id=7e9681b5e1829e533d9c...
commit 7e9681b5e1829e533d9cce3b28ee94ecf2daff24
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
Remove parameter documentation for non-existant parameter.
diff --git a/src/core/node.c b/src/core/node.c
index aceab34..8111523 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -2320,7 +2320,6 @@ dom_exception _dom_node_remove_event_listener_ns(dom_event_target
*et,
* Dispatch an event into the implementation's event model
*
* \param et The EventTarget object
- * \param eti Internal EventTarget
* \param evt The event object
* \param success Indicates whether any of the listeners which handled the
* event called Event.preventDefault(). If
commitdiff
http://git.netsurf-browser.org/libdom.git/commit/?id=b4a245f67fe6c40f3aa8...
commit b4a245f67fe6c40f3aa8ddfe627d28e3513a9463
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
Don't add target event to list of capture/bubbling event targets.
diff --git a/src/core/node.c b/src/core/node.c
index 45db915..aceab34 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -2377,8 +2377,6 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
/** \todo Report memory exhaustion? */
return DOM_NO_ERR;
}
- targets[ntargets++] = (dom_event_target *)dom_node_ref(et);
- target = target->parent;
while (target != NULL) {
if (ntargets == ntargets_allocated) {
@@ -2412,7 +2410,7 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
}
/* The capture phase */
- for (targetnr = ntargets; targetnr > 1; --targetnr) {
+ for (targetnr = ntargets; targetnr > 0; --targetnr) {
dom_node_internal *node =
(dom_node_internal *) targets[targetnr - 1];
@@ -2443,7 +2441,7 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
/* Bubbling phase */
evt->phase = DOM_BUBBLING_PHASE;
- for (targetnr = 1; targetnr < ntargets; ++targetnr) {
+ for (targetnr = 0; targetnr < ntargets; ++targetnr) {
dom_node_internal *node =
(dom_node_internal *) targets[targetnr];
err = _dom_event_target_dispatch(targets[targetnr],
-----------------------------------------------------------------------
Summary of changes:
src/core/node.c | 99 +++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 74 insertions(+), 25 deletions(-)
diff --git a/src/core/node.c b/src/core/node.c
index 45db915..8800a4b 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -2316,11 +2316,43 @@ dom_exception _dom_node_remove_event_listener_ns(dom_event_target
*et,
namespace, type, listener, capture);
}
+
+/** Helper for allocating/expanding array of event targets */
+static inline dom_exception _dom_event_targets_expand(
+ uint32_t *ntargets_allocated,
+ dom_event_target ***targets)
+{
+ dom_event_target **t = *targets;
+ uint32_t size = *ntargets_allocated;
+
+ if (t == NULL) {
+ /* Create the event target list */
+ size = 64;
+ t = calloc(sizeof(*t), size);
+ if (targets == NULL) {
+ return DOM_NO_MEM_ERR;
+ }
+ } else {
+ /* Extend events target list */
+ dom_event_target **tmp = realloc(t, size * 2 * sizeof(*t));
+ if (tmp == NULL) {
+ return DOM_NO_MEM_ERR;
+ }
+ memset(tmp + size, 0, size * sizeof(*tmp));
+ t = tmp;
+ size *= 2;
+ }
+
+ *ntargets_allocated = size;
+ *targets = t;
+
+ return DOM_NO_ERR;
+}
+
/**
* Dispatch an event into the implementation's event model
*
* \param et The EventTarget object
- * \param eti Internal EventTarget
* \param evt The event object
* \param success Indicates whether any of the listeners which handled the
* event called Event.preventDefault(). If
@@ -2369,31 +2401,46 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
*success = true;
- /* Compose the event target list */
+ /* Initialise array of targets for capture/bubbling phases */
+ targets = NULL;
+ ntargets_allocated = 0;
ntargets = 0;
- ntargets_allocated = 64;
- targets = calloc(sizeof(*targets), ntargets_allocated);
- if (targets == NULL) {
- /** \todo Report memory exhaustion? */
- return DOM_NO_ERR;
- }
- targets[ntargets++] = (dom_event_target *)dom_node_ref(et);
- target = target->parent;
- while (target != NULL) {
+ /* Add interested event listeners to array */
+ for (; target != NULL; target = target->parent) {
+ struct listener_entry *le = target->eti.listeners;
+ bool target_has_listener = false;
+
+ if (le == NULL) {
+ /* This event target isn't listening to anything */
+ continue;
+ }
+
+ /* Check whether the event target is listening for this
+ * event type */
+ do {
+ if (dom_string_isequal(le->type, evt->type)) {
+ target_has_listener = true;
+ break;
+ }
+ le = (struct listener_entry *) le->list.next;
+ } while (le != target->eti.listeners);
+
+ if (target_has_listener == false) {
+ continue;
+ }
+
+ /* The event target is listening for this event type,
+ * so add it to the array. */
if (ntargets == ntargets_allocated) {
- dom_event_target **newtargets = realloc(
- targets,
- ntargets_allocated * 2 * sizeof(*targets));
- if (newtargets == NULL)
+ err = _dom_event_targets_expand(&ntargets_allocated,
+ &targets);
+ if (err != DOM_NO_ERR) {
+ ret = err;
goto cleanup;
- memset(newtargets + ntargets_allocated,
- 0, ntargets_allocated * sizeof(*newtargets));
- targets = newtargets;
- ntargets_allocated *= 2;
+ }
}
targets[ntargets++] = (dom_event_target *)dom_node_ref(target);
- target = target->parent;
}
/* Fill the target of the event */
@@ -2412,7 +2459,7 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
}
/* The capture phase */
- for (targetnr = ntargets; targetnr > 1; --targetnr) {
+ for (targetnr = ntargets; targetnr > 0; --targetnr) {
dom_node_internal *node =
(dom_node_internal *) targets[targetnr - 1];
@@ -2443,7 +2490,7 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
/* Bubbling phase */
evt->phase = DOM_BUBBLING_PHASE;
- for (targetnr = 1; targetnr < ntargets; ++targetnr) {
+ for (targetnr = 0; targetnr < ntargets; ++targetnr) {
dom_node_internal *node =
(dom_node_internal *) targets[targetnr];
err = _dom_event_target_dispatch(targets[targetnr],
@@ -2465,8 +2512,8 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
dom_default_action_phase phase = DOM_DEFAULT_ACTION_END;
if (evt->prevent_default == true)
phase = DOM_DEFAULT_ACTION_PREVENTED;
- dom_default_action_callback cb = dei->actions(evt->type, phase,
- &pw);
+ dom_default_action_callback cb = dei->actions(
+ evt->type, phase, &pw);
if (cb != NULL) {
cb(evt, pw);
}
@@ -2480,7 +2527,9 @@ cleanup:
while (ntargets--) {
dom_node_unref(targets[ntargets]);
}
- free(targets);
+ if (targets != NULL) {
+ free(targets);
+ }
if (dei != NULL && dei->actions != NULL) {
dom_default_action_callback cb = dei->actions(evt->type,
--
Document Object Model library