Gitweb links:
...log
http://git.netsurf-browser.org/libdom.git/shortlog/2e707ef487896b68494ecb...
...commit
http://git.netsurf-browser.org/libdom.git/commit/2e707ef487896b68494ecb07...
...tree
http://git.netsurf-browser.org/libdom.git/tree/2e707ef487896b68494ecb07f0...
The branch, tlsa/faster-strings has been updated
via 2e707ef487896b68494ecb07f0047be164e4ae8e (commit)
via 4ef9aeab25b67fa27e951473c78f33a600503ee4 (commit)
via 737cb995c1b2bf144ee5087a011418b1f9b8aa69 (commit)
via 2196dd1c1d5a78e82e8b57d77008a0486011bec9 (commit)
via 7e9681b5e1829e533d9cce3b28ee94ecf2daff24 (commit)
via b4a245f67fe6c40f3aa8ddfe627d28e3513a9463 (commit)
from a37713d9b0d49e9996b6eba9789e6f4ace88cb85 (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 -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
include/dom/html/html_elements.h | 3 +-
src/core/node.c | 99 ++++++++++++++++++++++++++++----------
2 files changed, 76 insertions(+), 26 deletions(-)
diff --git a/include/dom/html/html_elements.h b/include/dom/html/html_elements.h
index 5774657..1e6b3fc 100644
--- a/include/dom/html/html_elements.h
+++ b/include/dom/html/html_elements.h
@@ -91,4 +91,5 @@ DOM_HTML_ELEMENT_LIST
#endif
#undef DOM_HTML_ELEMENT_LIST
-#endif
\ No newline at end of file
+#endif
+
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