1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/*
* 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/watcher.c
* DOM mutation handling
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "layout.h"
#include "dom/debug.h"
#include "dom/watcher.h"
#include "util/dom-str.h"
#include "util/util.h"
/**
* LibDOM event handler
*
* \param[in] evt The LibDOM event object
* \param[in] pw Pointer to our nslayout_layout object
*/
static void nsl__dom_event_handler(struct dom_event *evt, void *pw)
{
UNUSED(pw);
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.
*/
}
/* Exported function, documented in src/dom/watcher.h */
nslayout_error nsl_dom_watcher_add_for_layout(nslayout_layout *layout)
{
dom_exception exc;
/* TODO: LibDOM mutation event listeners are really slow.
* Need to find a better way to get DOM change notifications.
* LibDOM probably needs to gain Mutation Observer support.
*/
assert(layout->listener == NULL);
exc = dom_event_listener_create(nsl__dom_event_handler,
layout, &layout->listener);
if (exc != DOM_NO_ERR) {
goto error;
}
exc = dom_event_target_add_event_listener(
layout->doc, nsl_dom_str_node_inserted,
layout->listener, false);
if (exc != DOM_NO_ERR) {
goto error;
}
exc = dom_event_target_add_event_listener(
layout->doc, nsl_dom_str_subtree_modified,
layout->listener, false);
if (exc != DOM_NO_ERR) {
goto error;
}
exc = dom_event_target_add_event_listener(
layout->doc, nsl_dom_str_node_removed,
layout->listener, false);
if (exc != DOM_NO_ERR) {
goto error;
}
exc = dom_event_target_add_event_listener(
layout->doc, nsl_dom_str_attr_modified,
layout->listener, false);
if (exc != DOM_NO_ERR) {
goto error;
}
exc = dom_event_target_add_event_listener(
layout->doc, nsl_dom_str_characterdata_modified,
layout->listener, false);
if (exc != DOM_NO_ERR) {
goto error;
}
return NSLAYOUT_OK;
error:
nsl_dom_watcher_remove_for_layout(layout);
return NSL_DOM_ERR(exc);
}
/* Exported function, documented in src/dom/event.h */
nslayout_error nsl_dom_watcher_remove_for_layout(nslayout_layout *layout)
{
dom_exception exc;
/* Passing NULL as type, removes listener for all event types. */
exc = dom_event_target_remove_event_listener(
layout->doc, NULL, layout->listener, false);
if (exc != DOM_NO_ERR) {
return NSL_DOM_ERR(exc);
}
dom_event_listener_unref(layout->listener);
layout->listener = NULL;
return NSLAYOUT_OK;
}
|