From ba2cea6270dc014bf2751f373404fa915d2c38b6 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sat, 1 Aug 2015 17:40:24 +0100 Subject: Add DOM event handler. Currently just prints the events it gets. --- src/dom/Makefile | 11 +++ src/dom/event.c | 164 +++++++++++++++++++++++++++++++++++++++++++ src/dom/event.h | 19 +++++ src/layout.c | 29 +++++++- src/layout.h | 2 + src/util/Makefile | 11 +++ src/util/dom-str.c | 54 ++++++++++++++ src/util/dom-str.h | 33 +++++++++ src/util/util.h | 22 ++++++ test/assert-tests.c | 1 + test/nslayout-object-tests.c | 4 ++ 11 files changed, 348 insertions(+), 2 deletions(-) create mode 100644 src/dom/Makefile create mode 100644 src/dom/event.c create mode 100644 src/dom/event.h create mode 100644 src/util/Makefile create mode 100644 src/util/dom-str.c create mode 100644 src/util/dom-str.h create mode 100644 src/util/util.h diff --git a/src/dom/Makefile b/src/dom/Makefile new file mode 100644 index 0000000..30e1847 --- /dev/null +++ b/src/dom/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for libnslayout +# +# Copyright 2015 Michael Drake +# +# Released under the ISC License (see COPYING file) + +# Sources +DIR_SOURCES := event.c + +include $(NSBUILD)/Makefile.subdir 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 + */ + +/** \file src/dom/event.c + * DOM mutation handling + */ + +#include +#include +#include +#include + +#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; +} diff --git a/src/dom/event.h b/src/dom/event.h new file mode 100644 index 0000000..f519f40 --- /dev/null +++ b/src/dom/event.h @@ -0,0 +1,19 @@ +/* + * This file is part of LibNSLayout + * Licensed under the ISC License, http://opensource.org/licenses/ISC + * Copyright 2015 Michael Drake + */ + +/** \file src/dom/event.h + * Layout object handling + */ + +#ifndef nslayout_dom_event_h_ +#define nslayout_dom_event_h_ + +#include + +nslayout_error nsl_dom_event_layout_init(nslayout_layout *layout); +nslayout_error nsl_dom_event_layout_fini(nslayout_layout *layout); + +#endif diff --git a/src/layout.c b/src/layout.c index b5d74c2..f1a1490 100644 --- a/src/layout.c +++ b/src/layout.c @@ -10,8 +10,25 @@ #include #include +#include #include "layout.h" +#include "dom/event.h" +#include "util/dom-str.h" + + +/* Publically exported function, documented in include/libnslayout/nslayout.h */ +nslayout_error nslayout_init(void) +{ + return nsl_dom_str_init(); +} + + +/* Publically exported function, documented in include/libnslayout/nslayout.h */ +nslayout_error nslayout_fini(void) +{ + return nsl_dom_str_fini(); +} /* Publically exported function, documented in include/libnslayout/nslayout.h */ @@ -23,13 +40,15 @@ nslayout_error nslayout_layout_create( void *pw, nslayout_layout **layout) { - nslayout_layout *l; + nslayout_layout *l = NULL; assert(doc != NULL); assert(css_ctx != NULL); assert(media != NULL); assert(cb != NULL); + printf("Called layout_create\n"); + l = calloc(1, sizeof(nslayout_layout)); if (l == NULL) { return NSLAYOUT_NO_MEM; @@ -42,6 +61,9 @@ nslayout_error nslayout_layout_create( l->cb = cb; l->pw = pw; + /* TODO: error handling */ + nsl_dom_event_layout_init(l); + *layout = l; return NSLAYOUT_OK; } @@ -51,9 +73,12 @@ nslayout_error nslayout_layout_create( nslayout_error nslayout_layout_destroy( nslayout_layout *layout) { - /* TODO: free/unref the stuff we own in the layout */ assert(layout != NULL); + /* TODO: free/unref the stuff we own in the layout */ + /* TODO: error handling */ + nsl_dom_event_layout_fini(layout); + free(layout); return NSLAYOUT_OK; } diff --git a/src/layout.h b/src/layout.h index 9946663..e71d5aa 100644 --- a/src/layout.h +++ b/src/layout.h @@ -19,6 +19,8 @@ struct nslayout_layout { css_media_type *media; nslayout_callback cb; void *pw; + + dom_event_listener *listener; }; #endif diff --git a/src/util/Makefile b/src/util/Makefile new file mode 100644 index 0000000..4f95e74 --- /dev/null +++ b/src/util/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for libnslayout +# +# Copyright 2015 Michael Drake +# +# Released under the ISC License (see COPYING file) + +# Sources +DIR_SOURCES := dom-str.c + +include $(NSBUILD)/Makefile.subdir diff --git a/src/util/dom-str.c b/src/util/dom-str.c new file mode 100644 index 0000000..b959afe --- /dev/null +++ b/src/util/dom-str.c @@ -0,0 +1,54 @@ +/* + * This file is part of LibNSLayout + * Licensed under the ISC License, http://opensource.org/licenses/ISC + * Copyright 2015 Michael Drake + */ + +/** \file src/util/dom-str.c + * Layout object handling + */ + +#include +#include + +#include "util/dom-str.h" +#include "util/util.h" + +dom_string *nsl_dom_str_node_inserted; +dom_string *nsl_dom_str_subtree_modified; + + +/* Exported function, documented in src/util/dom-str.h */ +nslayout_error nsl_dom_str_init(void) +{ + dom_exception exc; + + exc = dom_string_create((const uint8_t *)"DOMNodeInserted", + SLEN("DOMNodeInserted"), + &nsl_dom_str_node_inserted); + if (exc != DOM_NO_ERR) { + /* TODO: free stuff, return value */ + printf("Failed to create string!\n"); + return NSLAYOUT_NO_MEM; + } + exc = dom_string_create((const uint8_t *)"DOMSubtreeModified", + SLEN("DOMSubtreeModified"), + &nsl_dom_str_subtree_modified); + if (exc != DOM_NO_ERR) { + /* TODO: free stuff, return value */ + printf("Failed to create string!\n"); + return NSLAYOUT_NO_MEM; + } + + return NSLAYOUT_OK; +} + + +/* Exported function, documented in src/util/dom-str.h */ +nslayout_error nsl_dom_str_fini(void) +{ + dom_string_unref(nsl_dom_str_node_inserted); + dom_string_unref(nsl_dom_str_subtree_modified); + + return NSLAYOUT_OK; +} diff --git a/src/util/dom-str.h b/src/util/dom-str.h new file mode 100644 index 0000000..9a51ad5 --- /dev/null +++ b/src/util/dom-str.h @@ -0,0 +1,33 @@ +/* + * This file is part of LibNSLayout + * Licensed under the ISC License, http://opensource.org/licenses/ISC + * Copyright 2015 Michael Drake + */ + +/** \file src/util/dom-str.h + * Layout object handling + */ + +#ifndef nslayout_util_dom_str_h_ +#define nslayout_util_dom_str_h_ + +#include + +extern dom_string *nsl_dom_str_node_inserted; +extern dom_string *nsl_dom_str_subtree_modified; + +/** + * Create the internal DOM strings + * + * \return NSLAYOUT_OK on success, appropriate error otherwise. + */ +nslayout_error nsl_dom_str_init(void); + +/** + * Unref the internal DOM strings + * + * \return NSLAYOUT_OK on success, appropriate error otherwise. + */ +nslayout_error nsl_dom_str_fini(void); + +#endif diff --git a/src/util/util.h b/src/util/util.h new file mode 100644 index 0000000..c03691b --- /dev/null +++ b/src/util/util.h @@ -0,0 +1,22 @@ +/* + * This file is part of LibNSLayout + * Licensed under the ISC License, http://opensource.org/licenses/ISC + * Copyright 2015 Michael Drake + */ + +/** \file src/util/util.h + * Layout object handling + */ + +#ifndef nslayout_util_util_h_ +#define nslayout_util_util_h_ + +#ifndef UNUSED +#define UNUSED(x) (void)(x) +#endif + +#ifndef SLEN +#define SLEN(x) (sizeof((x)) - 1) +#endif + +#endif diff --git a/test/assert-tests.c b/test/assert-tests.c index 1b97814..44bc2f7 100644 --- a/test/assert-tests.c +++ b/test/assert-tests.c @@ -18,6 +18,7 @@ START_TEST (test_nslayout_layout_create_aborts1) { nslayout_layout *layout; + (void) nslayout_layout_create(NULL, NULL, NULL, NULL, NULL, &layout); } END_TEST diff --git a/test/nslayout-object-tests.c b/test/nslayout-object-tests.c index a2f9afc..612a983 100644 --- a/test/nslayout-object-tests.c +++ b/test/nslayout-object-tests.c @@ -44,6 +44,8 @@ START_TEST (test_nslayout_layout_create_ok) css_err = css_select_ctx_create(&css_ctx); ck_assert(css_err == CSS_OK); + ck_assert(nslayout_init() == NSLAYOUT_OK); + error = nslayout_layout_create(doc, css_ctx, &media, @@ -59,6 +61,8 @@ START_TEST (test_nslayout_layout_create_ok) fail_unless(error == NSLAYOUT_OK, "Unable to destroy layout"); + ck_assert(nslayout_fini() == NSLAYOUT_OK); + css_err = css_select_ctx_destroy(css_ctx); ck_assert(css_err == CSS_OK); -- cgit v1.2.3