summaryrefslogtreecommitdiff
path: root/src/dom.h
blob: b439d604c0cbeb07cc31061fe4e12998c2ec7302 (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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
/* DOMC Document Object Model library in C
 * Copyright (c) 2001 Michael B. Allen <mba2000 ioplex.com>
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/* dom.h - internal interfaces
 */

#ifndef DOM_H
#define DOM_H


#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>

struct msgno_entry {
	int msgno;
	const char *msg;
};

const char *msgno_msg(int msgno);

extern struct msgno_entry dom_codes[];

#if defined(__sparc__)
  #include <sys/inttypes.h>
#elif defined(_WIN32)
  typedef unsigned __int64 uint64_t;
#else
  #include <stdint.h>
#endif

/* Enable this for hashing and fast access to large child node lists */
#define FAST_NODELIST 0

#if FAST_NODELIST
#include <mba/hashmap.h>
#endif

/* DOM_String
 */

typedef char DOM_String;

/* DOM_TimeStamp - Introduced in DOM Level 2
 */

typedef uint64_t DOM_TimeStamp;

/* DOM_Exception
 */

extern int *_DOM_Exception(void);

#define DOM_Exception (*_DOM_Exception())

/* DOM_EventException - Introduced in DOM Level 2
 */

#define DOM_UNSPECIFIED_EVENT_TYPE_ERR  dom_codes[13].msgno

/* DOM_Node
 */

typedef struct DOM_Node DOM_Node;
typedef struct DOM_NodeList DOM_NodeList;
typedef struct DOM_NodeList DOM_NamedNodeMap;
typedef struct NodeEntry NodeEntry;

typedef DOM_Node DOM_Attr;
typedef DOM_Node DOM_Element;
typedef DOM_Node DOM_CharacterData;
typedef DOM_CharacterData DOM_Text;
typedef DOM_CharacterData DOM_Comment;
typedef DOM_Text DOM_CDATASection;
typedef DOM_Node DOM_DocumentType;
typedef DOM_Node DOM_Notation;
typedef DOM_Node DOM_Entity;
typedef DOM_Node DOM_EntityReference;
typedef DOM_Node DOM_ProcessingInstruction;
typedef DOM_Node DOM_DocumentFragment;
typedef DOM_Node DOM_Document;
typedef DOM_Document DOM_DocumentLS;
/* Introduced in DOM Level 2: */
typedef DOM_Node DOM_EventTarget;
typedef struct ListenerEntry ListenerEntry;
typedef DOM_Document DOM_DocumentEvent;
typedef DOM_Document DOM_AbstractView;
typedef DOM_Document DOM_DocumentView;

#define DOM_ELEMENT_NODE                1
#define DOM_ATTRIBUTE_NODE              2
#define DOM_TEXT_NODE                   3
#define DOM_CDATA_SECTION_NODE          4
#define DOM_ENTITY_REFERENCE_NODE       5
#define DOM_ENTITY_NODE                 6
#define DOM_PROCESSING_INSTRUCTION_NODE 7
#define DOM_COMMENT_NODE                8
#define DOM_DOCUMENT_NODE               9
#define DOM_DOCUMENT_TYPE_NODE          10
#define DOM_DOCUMENT_FRAGMENT_NODE      11
#define DOM_NOTATION_NODE               12

/* events forward references - Introduced in DOM Level 2
 */

typedef struct DOM_Event DOM_Event;
typedef struct DOM_Event DOM_UIEvent;
typedef DOM_UIEvent DOM_TextEvent;
typedef struct DOM_Event DOM_MutationEvent;

typedef void DOM_EventListener;
typedef void (*DOM_EventListener_handleEvent)(DOM_EventListener *this, DOM_Event *evt);

struct ListenerEntry {
	DOM_String *type;
	DOM_EventListener *listener;
	DOM_EventListener_handleEvent listener_fn;
	int useCapture;
};

struct DOM_Node {
    DOM_String *nodeName;
    DOM_String *nodeValue;
    unsigned short nodeType;
    DOM_Node *parentNode;
    DOM_NodeList *childNodes;
    DOM_Node *firstChild;
    DOM_Node *lastChild;
    DOM_Node *previousSibling;
    DOM_Node *nextSibling;
    DOM_NamedNodeMap *attributes;
    DOM_Document *ownerDocument;
	/* Custom Fields */
	unsigned int listeners_len;
	ListenerEntry **listeners;
	unsigned short subtreeModified;
    union {
        struct {
            DOM_DocumentType *doctype;
            DOM_Element *documentElement;
			DOM_DocumentView *document;
			DOM_AbstractView *defaultView;
			DOM_Node *commonParent;
			DOM_String *version;
			DOM_String *encoding;
			int standalone;
        } Document;
        struct {
            DOM_String *name;
            DOM_NamedNodeMap *entities;
            DOM_NamedNodeMap *notations;
			DOM_String *publicId;
			DOM_String *systemId;
			DOM_String *internalSubset;
        } DocumentType;
        struct {
            DOM_String *tagName;
        } Element;
        struct {
            DOM_String *name;
            int specified;
            DOM_String *value;
			DOM_Element *ownerElement;
        } Attr;
        struct {
            DOM_String *data;
            int length;
        } CharacterData;
        struct {
            DOM_String *publicId;
            DOM_String *systemId;
        } Notation;
       struct {
            DOM_String *publicId;
            DOM_String *systemId;
            DOM_String *notationName;
        } Entity;
        struct {
            DOM_String *target;
            DOM_String *data;
        } ProcessingInstruction;
    } u;
    unsigned int rtfxRefCount;          /* Reference counting added for RTFX */
    void* userData;                     /* User data added for RTFX */
};

DOM_Node *DOM_Node_insertBefore(DOM_Node *node, DOM_Node *newChild, DOM_Node *refChild);
DOM_Node *DOM_Node_replaceChild(DOM_Node *node, DOM_Node *newChild, DOM_Node *oldChild);
DOM_Node *DOM_Node_removeChild(DOM_Node *node, DOM_Node *oldChild);
DOM_Node *DOM_Node_appendChild(DOM_Node *node, DOM_Node *newChild);
int DOM_Node_hasChildNodes(const DOM_Node *node);
DOM_Node *DOM_Node_cloneNode(DOM_Node *node, int deep);
DOM_String *DOM_Node_getNodeValue(DOM_Node *node);
void DOM_Node_setNodeValue(DOM_Node *node, DOM_String *value);

/* DOM_NodeList, DOM_NamedNodeMap
 */

struct NodeEntry {
	NodeEntry *prev;
	NodeEntry *next;
	DOM_Node *node;
};
struct DOM_NodeList {
    DOM_Document *_ownerDocument;
	DOM_Element *_ownerElement;
	int length;
	NodeEntry *first;
	NodeEntry *last;
	unsigned short filter;
	struct DOM_NodeList *list; /* Used for entities and notations */
#if FAST_NODELIST
	struct hashmap* _map;
#endif
    unsigned int rtfxRefCount; /* Reference counting added for RTFX */
};

DOM_Node *DOM_NodeList_item(const DOM_NodeList *nl, int index);

DOM_Node *DOM_NamedNodeMap_getNamedItem(const DOM_NamedNodeMap *map, const DOM_String *name);
DOM_Node *DOM_NamedNodeMap_setNamedItem(DOM_NamedNodeMap *map, DOM_Node *arg);
DOM_Node *DOM_NamedNodeMap_removeNamedItem(DOM_NamedNodeMap *map, const DOM_String *name);
DOM_Node *DOM_NamedNodeMap_item(const DOM_NamedNodeMap *map, int index);

/* DOM_Implementation
 */

int DOM_Implementation_hasFeature(DOM_String *feature, DOM_String *version);
DOM_DocumentType *DOM_Implementation_createDocumentType(DOM_String *qualifiedName,
										DOM_String *publicId, DOM_String *systemId);
DOM_Document *DOM_Implementation_createDocument(DOM_String *namespaceURI,
										DOM_String *qualifiedName, DOM_DocumentType *doctype);

/* DOM_Element
 */

DOM_String *DOM_Element_getAttribute(const DOM_Element *element, const DOM_String *name);
void DOM_Element_setAttribute(DOM_Element *element, const DOM_String *name,
										const DOM_String *value);
void DOM_Element_removeAttribute(DOM_Element *element, const DOM_String *name);
DOM_Attr *DOM_Element_getAttributeNode(const DOM_Element *element, const DOM_String *name);
DOM_Attr *DOM_Element_setAttributeNode(DOM_Element *element, DOM_Attr *newAttr);
DOM_Attr *DOM_Element_removeAttributeNode(DOM_Element *element, DOM_Attr *oldAttr);
DOM_NodeList *DOM_Element_getElementsByTagName(DOM_Element *element, const DOM_String *name);
void DOM_Element_normalize(DOM_Element *element);

/* DOM_CharacterData
 */

DOM_String *DOM_CharacterData_substringData(DOM_CharacterData *data,
										int offset, int count);
void DOM_CharacterData_appendData(DOM_CharacterData *data, const DOM_String *arg);
void DOM_CharacterData_insertData(DOM_CharacterData *data, int offset,
										const DOM_String *arg);
void DOM_CharacterData_deleteData(DOM_CharacterData *data, int offset, int count);
void DOM_CharacterData_replaceData(DOM_CharacterData *data, int offset, int count,
                                        const DOM_String *arg);
int DOM_CharacterData_getLength(DOM_CharacterData *data);

/* DOM_Text
 */

DOM_Text *DOM_Text_splitText(DOM_Text *text, int offset);

/* DOM_Document
 */

DOM_Element *DOM_Document_createElement(DOM_Document *doc, const DOM_String *tagName);
DOM_DocumentFragment *DOM_Document_createDocumentFragment(DOM_Document *doc);
DOM_Text *DOM_Document_createTextNode(DOM_Document *doc, const DOM_String *data);
DOM_Comment *DOM_Document_createComment(DOM_Document *doc, const DOM_String *data);
DOM_CDATASection *DOM_Document_createCDATASection(DOM_Document *doc, const DOM_String *data);
DOM_ProcessingInstruction *DOM_Document_createProcessingInstruction(DOM_Document *doc,
										const DOM_String *target, const DOM_String *data);
DOM_Attr *DOM_Document_createAttribute(DOM_Document *doc, const DOM_String *name);
DOM_EntityReference *DOM_Document_createEntityReference(DOM_Document *doc,
										const DOM_String *name);
DOM_NodeList *DOM_Document_getElementsByTagName(DOM_Document *doc, const DOM_String *tagname);

void DOM_Document_destroyNode(DOM_Document *doc, DOM_Node *node);
void DOM_Document_destroyNodeList(DOM_Document *doc, DOM_NodeList *nl, int free_nodes);

DOM_DocumentType *DOM_Document_getDoctype(DOM_Document *doc);
DOM_Element *DOM_Document_getDocumentElement(DOM_Document *doc);

/* DOM_DocumentLS - This does NOT resemble the Load/Save interfaces
 * described in the latest W3C drafts at all.
 */

int DOM_DocumentLS_save(DOM_DocumentLS *this, const char *uri, const DOM_Node *node);
int DOM_DocumentLS_fwrite(const DOM_DocumentLS *this, FILE *stream);

/* Events - Introduced in DOM Level 2
 * http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
 */

/* DOM_Event - Introduced in DOM Level 2
 */

#define DOM_EVENT_CAPTURING_PHASE 1
#define DOM_EVENT_AT_TARGET       2
#define DOM_EVENT_BUBBLING_PHASE  3

struct DOM_Event {
	const DOM_String *type;
	DOM_EventTarget *target;
	DOM_EventTarget *currentTarget;
	unsigned short eventPhase;
	int bubbles;
	int cancelable;
	DOM_TimeStamp timeStamp;
/* custom -- do not touch */
	int _pd;
	int _sp;
	unsigned int _modifiers;
/* UIEvent members */
	DOM_AbstractView *view;
	long detail;
/* TextEvent members */
	DOM_String *outputString;
	unsigned long keyVal;
	unsigned long virtKeyVal;
	int visibleOutputGenerated;
	int numPad;
/* MutationEvent members */
	DOM_Node *relatedNode;
	DOM_String *prevValue;
	DOM_String *newValue;
	DOM_String *attrName;
	unsigned short attrChange;
};

void DOM_Event_stopPropagation(DOM_Event *evt);
void DOM_Event_preventDefault(DOM_Event *evt);
void DOM_Event_initEvent(DOM_Event *evt, const DOM_String *eventTypeArg,
								int canBubbleArg, int cancelableArg);

/* DOM_DocumentEvent - Introduced in DOM Level 2
 */

DOM_Event *DOM_DocumentEvent_createEvent(DOM_DocumentEvent *doc,
								const DOM_String *eventType);
void DOM_DocumentEvent_destroyEvent(DOM_DocumentEvent *doc, DOM_Event *evt);

/* DOM_UIEvent
 */

void DOM_UIEvent_initUIEvent(DOM_UIEvent *evt,
								const DOM_String *typeArg,
								int canBubbleArg,
								int cancelableArg,
								DOM_AbstractView *viewArg,
								long detailArg);

/* DOM_EventTarget - Introduced in DOM Level 2
 */

void DOM_EventTarget_addEventListener(DOM_EventTarget *target,
								const DOM_String *type,
								DOM_EventListener *listener,
								DOM_EventListener_handleEvent listener_fn,
								int useCapture);
void DOM_EventTarget_removeEventListener(DOM_EventTarget *target,
								const DOM_String *type,
								DOM_EventListener *listener,
								DOM_EventListener_handleEvent listener_fn,
								int useCapture);
int DOM_EventTarget_dispatchEvent(DOM_EventTarget *target, DOM_Event *evt);

/* DOM_TextEvent - Introduced in DOM Level 3
 * http://www.w3.org/TR/2002/WD-DOM-Level-3-Events-20020208/events.html
 */

#define DOM_VK_UNDEFINED     0x0
#define DOM_VK_RIGHT_ALT     0x01
#define DOM_VK_LEFT_ALT      0x02
#define DOM_VK_LEFT_CONTROL  0x03
#define DOM_VK_RIGHT_CONTROL 0x04
#define DOM_VK_LEFT_SHIFT    0x05
#define DOM_VK_RIGHT_SHIFT   0x06
#define DOM_VK_LEFT_META     0x07
#define DOM_VK_RIGHT_META    0x08
#define DOM_VK_CAPS_LOCK     0x09
#define DOM_VK_DELETE        0x0A
#define DOM_VK_END           0x0B
#define DOM_VK_ENTER         0x0C
#define DOM_VK_ESCAPE        0x0D
#define DOM_VK_HOME          0x0E
#define DOM_VK_INSERT        0x0F
#define DOM_VK_NUM_LOCK      0x10
#define DOM_VK_PAUSE         0x11
#define DOM_VK_PRINTSCREEN   0x12
#define DOM_VK_SCROLL_LOCK   0x13
#define DOM_VK_LEFT          0x14
#define DOM_VK_RIGHT         0x15
#define DOM_VK_UP            0x16
#define DOM_VK_DOWN          0x17
#define DOM_VK_PAGE_DOWN     0x18
#define DOM_VK_PAGE_UP       0x19
#define DOM_VK_F1            0x1A
#define DOM_VK_F2            0x1B
#define DOM_VK_F3            0x1C
#define DOM_VK_F4            0x1D
#define DOM_VK_F5            0x1E
#define DOM_VK_F6            0x1F
#define DOM_VK_F7            0x20
#define DOM_VK_F8            0x21
#define DOM_VK_F9            0x22
#define DOM_VK_F10           0x23
#define DOM_VK_F11           0x24
#define DOM_VK_F12           0x25
#define DOM_VK_F13           0x26
#define DOM_VK_F14           0x27
#define DOM_VK_F15           0x28
#define DOM_VK_F16           0x29
#define DOM_VK_F17           0x2A
#define DOM_VK_F18           0x2B
#define DOM_VK_F19           0x2C
#define DOM_VK_F20           0x2D
#define DOM_VK_F21           0x2E
#define DOM_VK_F22           0x2F
#define DOM_VK_F23           0x30
#define DOM_VK_F24           0x31

int DOM_TextEvent_checkModifier(DOM_TextEvent *evt, unsigned int modifier);
void DOM_TextEvent_initTextEvent(DOM_TextEvent *evt, const DOM_String *typeArg,
										int canBubbleArg, int cancelableArg,
										DOM_AbstractView *viewArg, long detailArg,
										DOM_String *outputStringArg,
										unsigned int keyValArg,
										unsigned int virtKeyValArg,
										int visibleOutputGeneratedArg,
										int numPadArg);
void DOM_TextEvent_initModifier(DOM_TextEvent *evt, unsigned int modifier, int value);

/* Useful X KeySym to keyVal and virtKeyVal conversion functions
 * Add these .o's to the OBJS line in the Makefile to compile
 */

unsigned int keysym2ucs(unsigned short keysym);
unsigned int keysym2domvk(unsigned short keysym);

/* MutationEvent
 */

#define DOM_MUTATION_EVENT_MODIFICATION 1
#define DOM_MUTATION_EVENT_ADDITION     2
#define DOM_MUTATION_EVENT_REMOVAL      3

void DOM_MutationEvent_initMutationEvent(DOM_MutationEvent *evt,
										DOM_String *typeArg,
										int canBubbleArg,
										int cancelableArg,
										DOM_Node *relatedNodeArg,
										DOM_String *prevValueArg,
										DOM_String *newValueArg,
										DOM_String *attrNameArg,
										unsigned short attrChangeArg);
void DOM_MutationEvent_processSubtreeModified(DOM_EventTarget *subtree);

/* Temporary Functions
 */

void DOM_Node_printNode(DOM_Node *node);
void DOM_Node_printNode2(DOM_Node *node);

#define DOM_INDEX_SIZE_ERR              dom_codes[0].msgno
#define DOM_DOMSTRING_SIZE_ERR          dom_codes[1].msgno
#define DOM_HIERARCHY_REQUEST_ERR       dom_codes[2].msgno
#define DOM_WRONG_DOCUMENT_ERR          dom_codes[3].msgno
#define DOM_INVALID_CHARACTER_ERR       dom_codes[4].msgno
#define DOM_NO_DATA_ALLOWED_ERR         dom_codes[5].msgno
#define DOM_NO_MODIFICATION_ALLOWED_ERR dom_codes[6].msgno
#define DOM_NOT_FOUND_ERR               dom_codes[7].msgno
#define DOM_NOT_SUPPORTED_ERR           dom_codes[8].msgno
#define DOM_INUSE_ATTRIBUTE_ERR         dom_codes[9].msgno
#define DOM_XML_PARSER_ERR              dom_codes[10].msgno
#define DOM_CREATE_FAILED               dom_codes[11].msgno
#define DOM_CHARACTER_ENC_ERR           dom_codes[12].msgno
#define DOM_UNSPECIFIED_EVENT_TYPE_ERR  dom_codes[13].msgno
#define DOM_FILTERED_LIST_ERR           dom_codes[14].msgno

#define CANNOT_HAVE_CHILD_OF(p, c) !(child_matrix[(p)->nodeType - 1] & \
					(1 << ((c)->nodeType - 1)))
#define MODIFYING_DOC_ELEM(p, c) ((p)->nodeType == DOM_DOCUMENT_NODE && \
					(c)->nodeType == DOM_ELEMENT_NODE)
#define MODIFYING_DOCTYPE_ELEM(p, c) ((p)->nodeType == DOM_DOCUMENT_NODE && \
					(c)->nodeType == DOM_DOCUMENT_TYPE_NODE)
#define INVALID_HIER_REQ(p, c) (CANNOT_HAVE_CHILD_OF(p, c) || \
					(MODIFYING_DOC_ELEM(p, c) && (p)->u.Document.documentElement))

extern unsigned short child_matrix[];

DOM_NodeList *Document_createNodeList(DOM_Document *doc);
DOM_Node *NodeList_itemFiltered(const DOM_NodeList *list, int index, unsigned short nodeType);
NodeEntry *NodeList_insert(DOM_NodeList *nl, DOM_Node *newChild, DOM_Node *refChild);
NodeEntry *NodeList_replace(DOM_NodeList *nl, DOM_Node *newChild, DOM_Node *oldChild);
NodeEntry *NodeList_remove(DOM_NodeList *nl, DOM_Node *oldChild);
NodeEntry *NodeList_append(DOM_NodeList *nl, DOM_Node *newChild);
int NodeList_exists(DOM_NodeList *nl, DOM_Node *child);

DOM_NamedNodeMap *Document_createNamedNodeMap(DOM_Document *doc);

#endif /* DOM_H */