diff options
Diffstat (limited to 'src/dom/event.c')
-rw-r--r-- | src/dom/event.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/dom/event.c b/src/dom/event.c new file mode 100644 index 0000000..152fd34 --- /dev/null +++ b/src/dom/event.c @@ -0,0 +1,164 @@ +/* + * This file is part of LibNSLayout + * Licensed under the ISC License, http://opensource.org/licenses/ISC + * Copyright 2015 Michael Drake <tlsa@netsurf-browser.org> + */ + +/** \file src/dom/event.c + * DOM mutation handling + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "layout.h" +#include "dom/event.h" +#include "util/dom-str.h" +#include "util/util.h" + +static const char *nsl__dom_node_type_to_string(dom_node_type type) +{ + const char *str[] = { + "ELEMENT_NODE", + "ATTRIBUTE_NODE", + "TEXT_NODE", + "CDATA_SECTION_NODE", + "ENTITY_REFERENCE_NODE", + "ENTITY_NODE", + "PROCESSING_INSTRUCTION_NODE", + "COMMENT_NODE", + "DOCUMENT_NODE", + "DOCUMENT_TYPE_NODE", + "DOCUMENT_FRAGMENT_NODE", + "NOTATION_NODE" + }; + assert(DOM_NODE_TYPE_COUNT == 12); + + return str[type - 1]; +} + +static void nsl__dom_event_handler(struct dom_event *evt, void *pw) +{ + dom_event_target *node = NULL; + dom_node_type node_type; + dom_string *name = NULL; + dom_string *type = NULL; + dom_exception exc; + + UNUSED(pw); + + printf(" DOM Event: "); + + /* Ugly test to see what events come out */ + exc = dom_event_get_target(evt, &node); + if ((exc != DOM_NO_ERR) || (node == NULL)) { + printf("FAILED to get target node!\n"); + goto fail; + } + + exc = dom_node_get_node_type(node, &node_type); + if (exc != DOM_NO_ERR) { + printf("FAILED to get target node type!\n"); + goto fail; + } + + if (node_type == DOM_ELEMENT_NODE) { + exc = dom_node_get_node_name(node, &name); + if ((exc != DOM_NO_ERR) || (name == NULL)) { + printf("FAILED to get target node name!\n"); + goto fail; + } + } + + exc = dom_event_get_type(evt, &type); + if ((exc != DOM_NO_ERR) || (type == NULL)) { + printf("FAILED to get event type!\n"); + goto fail; + } + + if (node_type == DOM_ELEMENT_NODE) { + printf("<%s> %s", + dom_string_data(name), + dom_string_data(type)); + } else { + printf("%s %s", + nsl__dom_node_type_to_string(node_type), + dom_string_data(type)); + } + +fail: + if (type != NULL) dom_string_unref(type); + if (name != NULL) dom_string_unref(name); + if (node != NULL) dom_node_unref(node); + + printf("\n"); +} + +/* Exported function, documented in src/dom/event.h */ +nslayout_error nsl_dom_event_layout_init(nslayout_layout *layout) +{ + dom_exception exc; + + /* TODO: Somehow register with libdom to get DOM change notifications. + * + * At the moment, for testing, the client calls our event + * handler directly. It looks as though libdom needs its + * DOM event handling improved. Either add DOM mutation + * observer support, or add some specific client notification + * system, like other rendering engines. + */ + + exc = dom_event_listener_create(layout->doc, nsl__dom_event_handler, + layout, &layout->listener); + if (exc != DOM_NO_ERR) { + /* TODO: free stuff, return value */ + printf("Failed to register event handler!\n"); + return NSLAYOUT_NO_MEM; + } + exc = dom_event_target_add_event_listener( + layout->doc, nsl_dom_str_node_inserted, + layout->listener, false); + if (exc != DOM_NO_ERR) { + /* TODO: free stuff, return value */ + printf("Failed to register event handler!\n"); + return NSLAYOUT_NO_MEM; + } + exc = dom_event_target_add_event_listener( + layout->doc, nsl_dom_str_subtree_modified, + layout->listener, false); + if (exc != DOM_NO_ERR) { + /* TODO: free stuff, return value */ + printf("Failed to register event handler!\n"); + return NSLAYOUT_NO_MEM; + } + + return NSLAYOUT_OK; +} + +/* Exported function, documented in src/dom/event.h */ +nslayout_error nsl_dom_event_layout_fini(nslayout_layout *layout) +{ + dom_exception exc; + + exc = dom_event_target_remove_event_listener( + layout->doc, nsl_dom_str_node_inserted, + layout->listener, false); + if (exc != DOM_NO_ERR) { + /* TODO: free stuff, return value */ + printf("Failed to remove event handler!\n"); + return NSLAYOUT_NO_MEM; + } + exc = dom_event_target_remove_event_listener( + layout->doc, nsl_dom_str_subtree_modified, + layout->listener, false); + if (exc != DOM_NO_ERR) { + /* TODO: free stuff, return value */ + printf("Failed to remove event handler!\n"); + return NSLAYOUT_NO_MEM; + } + dom_event_listener_unref(layout->listener); + + return NSLAYOUT_OK; +} |