summaryrefslogtreecommitdiff
path: root/src/events/dispatch.c
blob: 64664c794b51e35a092362aba7ba78b4864fddae (plain)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*
 * This file is part of libdom.
 * Licensed under the MIT License,
 *                http://www.opensource.org/licenses/mit-license.php
 * Copyright 2009 Bo Yang <struggleyb.nku@gmail.com>
 */

#include <assert.h>

#include "core/document.h"
#include "events/dispatch.h"
#include "events/mutation_event.h"

#include "utils/utils.h"

/**
 * Dispatch a DOMNodeInserted/DOMNodeRemoved event
 *
 * \param doc      The document object
 * \param et       The EventTarget object
 * \param type     "DOMNodeInserted" or "DOMNodeRemoved"
 * \param related  The parent of the removed/inserted node
 * \param success  Whether this event's default action get called
 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
 */
dom_exception __dom_dispatch_node_change_event(dom_document *doc,
		dom_event_target *et, dom_event_target *related, 
		dom_mutation_type change, bool *success)
{
	struct dom_mutation_event *evt;
	dom_string *type = NULL;
	dom_exception err;

	err = _dom_mutation_event_create(doc, &evt);
	if (err != DOM_NO_ERR)
		return err;
	
	if (change == DOM_MUTATION_ADDITION) {
		type = dom_string_ref(doc->_memo_domnodeinserted);
	} else if (change == DOM_MUTATION_REMOVAL) {
		type = dom_string_ref(doc->_memo_domnoderemoved);
	} else {
		assert("Should never be here" == NULL);
	}

	/* Initialise the event with corresponding parameters */
	err = dom_mutation_event_init(evt, type, true, false, 
			related, NULL, NULL, NULL, change);
	dom_string_unref(type);
	if (err != DOM_NO_ERR) {
		goto cleanup;
	}

	err = dom_event_target_dispatch_event(et, evt, success);
	if (err != DOM_NO_ERR)
		goto cleanup;
	
cleanup:
	_dom_mutation_event_destroy(evt);

	return err;
}

/**
 * Dispatch a DOMNodeInsertedIntoDocument/DOMNodeRemovedFromDocument event
 *
 * \param doc      The document object
 * \param et       The EventTarget object
 * \param type     "DOMNodeInserted" or "DOMNodeRemoved"
 * \param success  Whether this event's default action get called
 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
 */
dom_exception __dom_dispatch_node_change_document_event(dom_document *doc,
		dom_event_target *et, dom_mutation_type change, bool *success)
{
	struct dom_mutation_event *evt;
	dom_string *type = NULL;
	dom_exception err;

	err = _dom_mutation_event_create(doc, &evt);
	if (err != DOM_NO_ERR)
		return err;

	if (change == DOM_MUTATION_ADDITION) {
		type = dom_string_ref(doc->_memo_domnodeinsertedintodocument);
	} else if (change == DOM_MUTATION_REMOVAL) {
		type = dom_string_ref(doc->_memo_domnoderemovedfromdocument);
	} else {
		assert("Should never be here" == NULL);
	}

	/* Initialise the event with corresponding parameters */
	err = dom_mutation_event_init(evt, type, true, false, NULL,
			NULL, NULL, NULL, change);
	dom_string_unref(type);
	if (err != DOM_NO_ERR)
		goto cleanup;

	err = dom_event_target_dispatch_event(et, evt, success);
	if (err != DOM_NO_ERR)
		goto cleanup;
	
cleanup:
	_dom_mutation_event_destroy(evt);

	return err;
}

/**
 * Dispatch a DOMAttrModified event
 *
 * \param doc        The Document object
 * \param et         The EventTarget
 * \param prev       The previous value before change
 * \param new        The new value after change
 * \param related    The related EventTarget
 * \param attr_name  The Attribute name
 * \param change     How this attribute change
 * \param success    Whether this event's default handler get called
 * \return DOM_NO_ERR on success, appropirate dom_exception on failure.
 */
dom_exception __dom_dispatch_attr_modified_event(dom_document *doc,
		dom_event_target *et, dom_string *prev, dom_string *new,
		dom_event_target *related, dom_string *attr_name, 
		dom_mutation_type change, bool *success)
{
	struct dom_mutation_event *evt;
	dom_string *type = NULL;
	dom_exception err;

	err = _dom_mutation_event_create(doc, &evt);
	if (err != DOM_NO_ERR)
		return err;
	
	type = dom_string_ref(doc->_memo_domattrmodified);

	/* Initialise the event with corresponding parameters */
	err = dom_mutation_event_init(evt, type, true, false, related, 
			prev, new, attr_name, change);
	dom_string_unref(type);
	if (err != DOM_NO_ERR) {
		goto cleanup;
	}

	err = dom_event_target_dispatch_event(et, evt, success);

cleanup:
	_dom_mutation_event_destroy(evt);

	return err;
}

/**
 * Dispatch a DOMCharacterDataModified event
 *
 * \param et       The EventTarget object
 * \param prev     The preValue of the DOMCharacterData
 * \param new      The newValue of the DOMCharacterData
 * \param success  Whether this event's default handler get called
 * \return DOM_NO_ERR on success, appropirate dom_exception on failure.
 *
 * TODO:
 * The character_data object may be a part of a Attr node, if so, another 
 * DOMAttrModified event should be dispatched, too. But for now, we did not
 * support any XML feature, so just leave it as this.
 */
dom_exception __dom_dispatch_characterdata_modified_event(
		dom_document *doc, dom_event_target *et,
		dom_string *prev, dom_string *new, bool *success)
{
	struct dom_mutation_event *evt;
	dom_string *type = NULL;
	dom_exception err;

	err = _dom_mutation_event_create(doc, &evt);
	if (err != DOM_NO_ERR)
		return err;
	
	type = dom_string_ref(doc->_memo_domcharacterdatamodified);

	err = dom_mutation_event_init(evt, type, true, false, et, prev, 
			new, NULL, DOM_MUTATION_MODIFICATION);
	dom_string_unref(type);
	if (err != DOM_NO_ERR) {
		goto cleanup;
	}

	err = dom_event_target_dispatch_event(et, evt, success);

cleanup:
	_dom_mutation_event_destroy(evt);

	return err;
}

/**
 * Dispatch a DOMSubtreeModified event
 *
 * \param doc      The Document
 * \param et       The EventTarget object
 * \param success  Whether this event's default handler get called
 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
 */
dom_exception __dom_dispatch_subtree_modified_event(dom_document *doc,
		dom_event_target *et, bool *success)
{
	struct dom_mutation_event *evt;
	dom_string *type = NULL;
	dom_exception err;

	err = _dom_mutation_event_create(doc, &evt);
	if (err != DOM_NO_ERR)
		return err;
	
	type = dom_string_ref(doc->_memo_domsubtreemodified);

	err = dom_mutation_event_init(evt, type, true, false, et, NULL, 
			NULL, NULL, DOM_MUTATION_MODIFICATION);
	dom_string_unref(type);
	if (err != DOM_NO_ERR) {
		goto cleanup;
	}

	err = dom_event_target_dispatch_event(et, evt, success);

cleanup:
	_dom_mutation_event_destroy(evt);

	return err;
}

/**
 * Dispatch a generic event
 *
 * \param doc         The Document
 * \param et          The EventTarget object
 * \param name        The name of the event
 * \param len         The length of the name string
 * \param bubble      Whether this event bubbles
 * \param cancelable  Whether this event can be cancelable
 * \param success     Whether this event's default handler get called
 * \return DOM_NO_ERR on success, appropriate dom_exception on failure.
 */
dom_exception _dom_dispatch_generic_event(dom_document *doc,
		dom_event_target *et, dom_string *event_name,
		bool bubble, bool cancelable, bool *success)
{
	struct dom_event *evt;
	dom_exception err;

	err = _dom_event_create(doc, &evt);
	if (err != DOM_NO_ERR)
		return err;
	
	err = dom_event_init(evt, event_name, bubble, cancelable);

	if (err != DOM_NO_ERR) {
		goto cleanup;
	}

	err = dom_event_target_dispatch_event(et, evt, success);

cleanup:
	_dom_event_destroy(evt);

	return err;
}