summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2017-02-05 22:41:04 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2017-02-05 22:41:04 +0000
commitf18b7ad86fe25e32cac7d9bca1abe92c46437535 (patch)
tree6ec3bf938c0b7a20600151085325b04ea349f173
parent39f7357b388d2e00d307419ccd2d761180eb5c5c (diff)
downloadlibnslayout-f18b7ad86fe25e32cac7d9bca1abe92c46437535.tar.gz
libnslayout-f18b7ad86fe25e32cac7d9bca1abe92c46437535.tar.bz2
dom watcher: Add callback for dom mutation watching.
-rw-r--r--src/dom/watcher.c76
-rw-r--r--src/dom/watcher.h36
-rw-r--r--src/layout.c38
3 files changed, 137 insertions, 13 deletions
diff --git a/src/dom/watcher.c b/src/dom/watcher.c
index cb775c6..d515cf6 100644
--- a/src/dom/watcher.c
+++ b/src/dom/watcher.c
@@ -31,8 +31,10 @@
* A dom watcher object
*/
struct nsl_dom_watcher {
- dom_document *document;
- dom_event_listener *listener; /**< DOM event listener object */
+ dom_document *document; /**< DOM document */
+ dom_event_listener *listener; /**< DOM event listener object */
+ nsl_dom_watcher_cb watcher_cb; /**< Client callback */
+ void *pw; /**< Client data */
};
/**
@@ -44,17 +46,65 @@ struct nsl_dom_watcher {
static void nsl__dom_event_handler(struct dom_event *evt, void *pw)
{
const struct nsl_dom_watcher *watcher = pw;
-
- UNUSED(watcher);
+ enum nsl_dom_watcher_type type;
+ dom_event_target *node = NULL;
+ dom_string *evt_type = NULL;
+ dom_node_type node_type;
+ dom_exception exc;
nsl_dom_debug_dump_event(evt);
- /* TODO: Based on event type:
- * 1. call to do (re)selection:
- * a. all nodes?
- * b. just this node?
- * 2. call to update layout, if needed.
- */
+ 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;
+ }
+
+ exc = dom_event_get_type(evt, &evt_type);
+ if ((exc != DOM_NO_ERR) || (evt_type == NULL)) {
+ printf("FAILED to get event type!\n");
+ goto fail;
+ }
+
+ if (dom_string_isequal(evt_type,
+ nsl_dom_str_node_inserted)) {
+ type = NSL_DOM_WATCHER_NODE_INSERTED;
+
+ } else if (dom_string_isequal(evt_type,
+ nsl_dom_str_node_removed)) {
+ type = NSL_DOM_WATCHER_NODE_REMOVED;
+
+ } else if (dom_string_isequal(evt_type,
+ nsl_dom_str_subtree_modified)) {
+ type = NSL_DOM_WATCHER_SUBTREE_MODIFIED;
+
+ } else if (dom_string_isequal(evt_type,
+ nsl_dom_str_attr_modified)) {
+ type = NSL_DOM_WATCHER_ATTR_MODIFIED;
+
+ } else if (dom_string_isequal(evt_type,
+ nsl_dom_str_characterdata_modified)) {
+ type = NSL_DOM_WATCHER_CHAR_DATA_MODIFIED;
+ } else {
+ printf("FAILED: unrecognised event type: '%s'",
+ dom_string_data(evt_type));
+ goto fail;
+ }
+
+ dom_string_unref(evt_type);
+
+ watcher->watcher_cb(type, node, node_type, watcher->pw);
+ return;
+
+fail:
+ if (evt_type != NULL) dom_string_unref(evt_type);
+ if (node != NULL) dom_node_unref(node);
}
@@ -144,7 +194,9 @@ error:
/* Exported function, documented in src/dom/watcher.h */
nslayout_error nsl_dom_watcher_create(
struct nsl_dom_watcher **watcher_out,
- dom_document *document)
+ dom_document *document,
+ nsl_dom_watcher_cb watcher_cb,
+ void *pw)
{
struct nsl_dom_watcher *watcher;
nslayout_error err;
@@ -155,6 +207,8 @@ nslayout_error nsl_dom_watcher_create(
}
watcher->document = document;
+ watcher->watcher_cb = watcher_cb;
+ watcher->pw = pw;
err = nsl__dom_listener_create(&watcher->listener, watcher);
if (err != NSLAYOUT_OK) {
diff --git a/src/dom/watcher.h b/src/dom/watcher.h
index a6f2568..0883fd2 100644
--- a/src/dom/watcher.h
+++ b/src/dom/watcher.h
@@ -15,15 +15,49 @@ struct dom_document;
struct nsl_dom_watcher;
/**
+ * DOM watcher's mutation types
+ */
+enum nsl_dom_watcher_type {
+ NSL_DOM_WATCHER_NODE_INSERTED,
+ NSL_DOM_WATCHER_NODE_REMOVED,
+ NSL_DOM_WATCHER_SUBTREE_MODIFIED,
+ NSL_DOM_WATCHER_ATTR_MODIFIED,
+ NSL_DOM_WATCHER_CHAR_DATA_MODIFIED,
+ NSL_DOM_WATCHER__COUNT,
+};
+
+
+/**
+ * Callback function for dom modifications.
+ *
+ * \param[in] type The mutation type.
+ * \param[in] node The target node. (Caller yields ownership.)
+ * \param[in] node_type The type of node.
+ * \param[in] pw The dom watcher owner's private data.
+ * \return NSLAYOUT_OK on success, appropriate error otherwise.
+ */
+typedef nslayout_error (*nsl_dom_watcher_cb)(
+ enum nsl_dom_watcher_type type,
+ dom_event_target *node,
+ dom_node_type node_type,
+ void *pw);
+
+
+/**
* Create DOM change watcher for a DOM document.
*
* \param[out] watcher_out Returns a dom watcher object for layout.
* \param[in] document DOM document to create watcher for.
+ * \param[in] watcher_cb Function to call when dom modification happens.
+ * \param[in] pw Private data passed back to `watcher_cb`.
* \return NSLAYOUT_OK on success, appropriate error otherwise.
*/
nslayout_error nsl_dom_watcher_create(
struct nsl_dom_watcher **watcher_out,
- dom_document *document);
+ dom_document *document,
+ nsl_dom_watcher_cb watcher_cb,
+ void *pw);
+
/**
* Destroy a document change DOM change watcher.
diff --git a/src/layout.c b/src/layout.c
index d894f13..e4824bf 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -14,6 +14,7 @@
#include "libnslayout/nslayout.h"
#include "layout.h"
+#include "util/util.h"
#include "dom/watcher.h"
#include "util/dom-str.h"
@@ -46,6 +47,40 @@ nslayout_error nslayout_fini(void)
}
+/**
+ * Callback function for dom modifications.
+ *
+ * \param[in] type The mutation type.
+ * \param[in] node The target node. (Caller yields ownership.)
+ * \param[in] node_type The type of node.
+ * \param[in] pw The layout object.
+ * \return NSLAYOUT_OK on success, appropriate error otherwise.
+ */
+static nslayout_error nsl_layout_dom_watcher_cb(
+ enum nsl_dom_watcher_type type,
+ dom_event_target *node,
+ dom_node_type node_type,
+ void *pw)
+{
+ nslayout_layout *layout = pw;
+
+ UNUSED(type);
+ UNUSED(layout);
+ UNUSED(node_type);
+
+ /* TODO: Based on event type:
+ * 1. call to do (re)selection:
+ * a. all nodes?
+ * b. just this node?
+ * 2. call to update layout, if needed.
+ */
+
+ dom_node_unref(node);
+
+ return NSLAYOUT_OK;
+}
+
+
/* Publically exported function, documented in include/libnslayout/nslayout.h */
nslayout_error nslayout_layout_create(
dom_document *doc,
@@ -75,7 +110,8 @@ nslayout_error nslayout_layout_create(
l->cb = cb;
l->pw = pw;
- err = nsl_dom_watcher_create(&l->watcher, l->document);
+ err = nsl_dom_watcher_create(&l->watcher, l->document,
+ nsl_layout_dom_watcher_cb, l);
if (err != NSLAYOUT_OK) {
return err;
}