1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
2 | /* |
---|
3 | * bonobo-ui-node.c: Code to manipulate BonoboUINode objects |
---|
4 | * |
---|
5 | * Author: |
---|
6 | * Havoc Pennington <hp@redhat.com> |
---|
7 | * |
---|
8 | * Copyright 2000 Red Hat, Inc. |
---|
9 | */ |
---|
10 | |
---|
11 | #include "config.h" |
---|
12 | #include <bonobo/bonobo-ui-node.h> |
---|
13 | #include <stdlib.h> |
---|
14 | #include <string.h> |
---|
15 | |
---|
16 | #include <gnome-xml/parser.h> |
---|
17 | #include <gnome-xml/parserInternals.h> |
---|
18 | #include <gnome-xml/xmlmemory.h> |
---|
19 | |
---|
20 | /* Having this struct here makes debugging nicer. */ |
---|
21 | struct _BonoboUINode { |
---|
22 | xmlNode real_node; |
---|
23 | }; |
---|
24 | |
---|
25 | #define XML_NODE(x) (&(x)->real_node) |
---|
26 | #define BNODE(x) ((BonoboUINode *)(x)) |
---|
27 | |
---|
28 | /** |
---|
29 | * bonobo_ui_node_new: |
---|
30 | * @name: The name for the node |
---|
31 | * |
---|
32 | * Creates a new node with name @name |
---|
33 | * |
---|
34 | * Return value: a new node pointer |
---|
35 | **/ |
---|
36 | BonoboUINode* |
---|
37 | bonobo_ui_node_new (const char *name) |
---|
38 | { |
---|
39 | return BNODE (xmlNewNode (NULL, name)); |
---|
40 | } |
---|
41 | |
---|
42 | /** |
---|
43 | * bonobo_ui_node_new_child: |
---|
44 | * @parent: the parent |
---|
45 | * @name: the name of the new child |
---|
46 | * |
---|
47 | * Create a new node as a child of @parent with name @name |
---|
48 | * |
---|
49 | * Return value: pointer to the new child |
---|
50 | **/ |
---|
51 | BonoboUINode* |
---|
52 | bonobo_ui_node_new_child (BonoboUINode *parent, |
---|
53 | const char *name) |
---|
54 | { |
---|
55 | return BNODE (xmlNewChild (XML_NODE (parent), NULL, name, NULL)); |
---|
56 | } |
---|
57 | |
---|
58 | /** |
---|
59 | * bonobo_ui_node_copy: |
---|
60 | * @node: the node |
---|
61 | * @recursive: whether to dup children too. |
---|
62 | * |
---|
63 | * Copy an XML node, if @recursive do a deep copy, otherwise just dup the node itself. |
---|
64 | * |
---|
65 | * Return value: a copy of the node |
---|
66 | **/ |
---|
67 | BonoboUINode* |
---|
68 | bonobo_ui_node_copy (BonoboUINode *node, |
---|
69 | gboolean recursive) |
---|
70 | { |
---|
71 | return BNODE (xmlCopyNode (XML_NODE (node), recursive)); |
---|
72 | } |
---|
73 | |
---|
74 | /** |
---|
75 | * bonobo_ui_node_free: |
---|
76 | * @node: a node. |
---|
77 | * |
---|
78 | * Frees the memory associated with the @node and unlink it from the tree |
---|
79 | **/ |
---|
80 | void |
---|
81 | bonobo_ui_node_free (BonoboUINode *node) |
---|
82 | { |
---|
83 | xmlFreeNode (XML_NODE (node)); |
---|
84 | } |
---|
85 | |
---|
86 | /** |
---|
87 | * bonobo_ui_node_set_data: |
---|
88 | * @node: the node |
---|
89 | * @data: user data |
---|
90 | * |
---|
91 | * Associates some user data with the node pointer |
---|
92 | **/ |
---|
93 | void |
---|
94 | bonobo_ui_node_set_data (BonoboUINode *node, |
---|
95 | gpointer data) |
---|
96 | { |
---|
97 | XML_NODE (node)->_private = data; |
---|
98 | } |
---|
99 | |
---|
100 | /** |
---|
101 | * bonobo_ui_node_get_data: |
---|
102 | * @node: the node |
---|
103 | * |
---|
104 | * Gets user data associated with @node |
---|
105 | * |
---|
106 | * Return value: the user data, see bonobo_ui_node_set_data |
---|
107 | **/ |
---|
108 | gpointer |
---|
109 | bonobo_ui_node_get_data (BonoboUINode *node) |
---|
110 | { |
---|
111 | return XML_NODE (node)->_private; |
---|
112 | } |
---|
113 | |
---|
114 | static xmlAttrPtr |
---|
115 | get_attr (xmlNode *node, const char *name) |
---|
116 | { |
---|
117 | xmlAttrPtr prop; |
---|
118 | |
---|
119 | if ((node == NULL) || (name == NULL)) return(NULL); |
---|
120 | /* |
---|
121 | * Check on the properties attached to the node |
---|
122 | */ |
---|
123 | prop = node->properties; |
---|
124 | while (prop != NULL) { |
---|
125 | if (!xmlStrcmp(prop->name, name)) { |
---|
126 | return(prop); |
---|
127 | } |
---|
128 | prop = prop->next; |
---|
129 | } |
---|
130 | |
---|
131 | return(NULL); |
---|
132 | } |
---|
133 | |
---|
134 | /** |
---|
135 | * bonobo_ui_node_set_attr: |
---|
136 | * @node: The node |
---|
137 | * @name: the name of the attr |
---|
138 | * @value: the value for the attr |
---|
139 | * |
---|
140 | * Set the attribute of @name on @node to @value overriding any |
---|
141 | * previous values of that attr. |
---|
142 | **/ |
---|
143 | void |
---|
144 | bonobo_ui_node_set_attr (BonoboUINode *node, |
---|
145 | const char *name, |
---|
146 | const char *value) |
---|
147 | { |
---|
148 | if (value == NULL) { |
---|
149 | xmlAttrPtr attr = get_attr (XML_NODE (node), name); |
---|
150 | if (attr) |
---|
151 | xmlRemoveProp (attr); |
---|
152 | } else { |
---|
153 | xmlSetProp (XML_NODE (node), name, value); |
---|
154 | } |
---|
155 | } |
---|
156 | |
---|
157 | /** |
---|
158 | * bonobo_ui_node_get_attr: |
---|
159 | * @node: the node |
---|
160 | * @name: the name of the attr to get |
---|
161 | * |
---|
162 | * Fetch the value of an attr of name @name from @node |
---|
163 | * see also: bonobo_ui_node_free_string |
---|
164 | * |
---|
165 | * Return value: the attr text. |
---|
166 | **/ |
---|
167 | char* |
---|
168 | bonobo_ui_node_get_attr (BonoboUINode *node, |
---|
169 | const char *name) |
---|
170 | { |
---|
171 | return xmlGetProp (XML_NODE (node), name); |
---|
172 | } |
---|
173 | |
---|
174 | /** |
---|
175 | * bonobo_ui_node_has_attr: |
---|
176 | * @node: the node |
---|
177 | * @name: the name of the attr to detect |
---|
178 | * |
---|
179 | * Determines whether the @node has an attribute of name @name |
---|
180 | * |
---|
181 | * Return value: TRUE if the attr exists |
---|
182 | **/ |
---|
183 | gboolean |
---|
184 | bonobo_ui_node_has_attr (BonoboUINode *node, |
---|
185 | const char *name) |
---|
186 | { |
---|
187 | return get_attr (XML_NODE (node), name) != NULL; |
---|
188 | } |
---|
189 | |
---|
190 | /** |
---|
191 | * bonobo_ui_node_remove_attr: |
---|
192 | * @node: the node |
---|
193 | * @name: name of the attribute |
---|
194 | * |
---|
195 | * remove any attribute with name @name from @node |
---|
196 | **/ |
---|
197 | void |
---|
198 | bonobo_ui_node_remove_attr (BonoboUINode *node, |
---|
199 | const char *name) |
---|
200 | { |
---|
201 | xmlAttrPtr attr = get_attr (XML_NODE (node), name); |
---|
202 | if (attr) |
---|
203 | xmlRemoveProp (attr); |
---|
204 | } |
---|
205 | |
---|
206 | /** |
---|
207 | * bonobo_ui_node_add_child: |
---|
208 | * @parent: the parent |
---|
209 | * @child: the new child |
---|
210 | * |
---|
211 | * Add a @child node to the @parent node ( after the other children ) |
---|
212 | **/ |
---|
213 | void |
---|
214 | bonobo_ui_node_add_child (BonoboUINode *parent, |
---|
215 | BonoboUINode *child) |
---|
216 | { |
---|
217 | xmlAddChild (XML_NODE (parent), XML_NODE (child)); |
---|
218 | } |
---|
219 | |
---|
220 | /** |
---|
221 | * bonobo_ui_node_insert_before: |
---|
222 | * @sibling: the node to insert |
---|
223 | * @prev_sibling: the placeholder for insertion |
---|
224 | * |
---|
225 | * Insert a @sibling before @prev_sibling in a node list |
---|
226 | **/ |
---|
227 | void |
---|
228 | bonobo_ui_node_insert_before (BonoboUINode *sibling, |
---|
229 | BonoboUINode *prev_sibling) |
---|
230 | { |
---|
231 | xmlAddPrevSibling (XML_NODE (sibling), XML_NODE (prev_sibling)); |
---|
232 | } |
---|
233 | |
---|
234 | /** |
---|
235 | * bonobo_ui_node_unlink: |
---|
236 | * @node: the node |
---|
237 | * |
---|
238 | * Unlink @node from its tree, ie. disassociate it with its parent |
---|
239 | **/ |
---|
240 | void |
---|
241 | bonobo_ui_node_unlink (BonoboUINode *node) |
---|
242 | { |
---|
243 | xmlUnlinkNode (XML_NODE (node)); |
---|
244 | } |
---|
245 | |
---|
246 | /** |
---|
247 | * bonobo_ui_node_replace: |
---|
248 | * @old_node: node to be replaced |
---|
249 | * @new_node: node to replace with |
---|
250 | * |
---|
251 | * Replace @old_node with @new_node in the tree. @old_node is |
---|
252 | * left unlinked and floating with its children. |
---|
253 | **/ |
---|
254 | void |
---|
255 | bonobo_ui_node_replace (BonoboUINode *old_node, |
---|
256 | BonoboUINode *new_node) |
---|
257 | { |
---|
258 | /* libxml has these args indisputably backward */ |
---|
259 | xmlReplaceNode (XML_NODE (new_node), |
---|
260 | XML_NODE (old_node)); |
---|
261 | } |
---|
262 | |
---|
263 | /** |
---|
264 | * bonobo_ui_node_set_content: |
---|
265 | * @node: the node |
---|
266 | * @content: the new content |
---|
267 | * |
---|
268 | * Set the textual content of @node to @content |
---|
269 | **/ |
---|
270 | void |
---|
271 | bonobo_ui_node_set_content (BonoboUINode *node, |
---|
272 | const char *content) |
---|
273 | { |
---|
274 | xmlNodeSetContent (XML_NODE (node), content); |
---|
275 | } |
---|
276 | |
---|
277 | /** |
---|
278 | * bonobo_ui_node_get_content: |
---|
279 | * @node: the node |
---|
280 | * |
---|
281 | * see also: bonobo_ui_node_free_string |
---|
282 | * |
---|
283 | * Return value: the content of @node |
---|
284 | **/ |
---|
285 | char * |
---|
286 | bonobo_ui_node_get_content (BonoboUINode *node) |
---|
287 | { |
---|
288 | return xmlNodeGetContent (XML_NODE (node)); |
---|
289 | } |
---|
290 | |
---|
291 | /** |
---|
292 | * bonobo_ui_node_next: |
---|
293 | * @node: the node |
---|
294 | * |
---|
295 | * accesses the next node. |
---|
296 | * |
---|
297 | * Return value: the node after @node in the list |
---|
298 | **/ |
---|
299 | BonoboUINode* |
---|
300 | bonobo_ui_node_next (BonoboUINode *node) |
---|
301 | { |
---|
302 | return BNODE (XML_NODE (node)->next); |
---|
303 | } |
---|
304 | |
---|
305 | /** |
---|
306 | * bonobo_ui_node_prev: |
---|
307 | * @node: the node |
---|
308 | * |
---|
309 | * accesses the previous node. |
---|
310 | * |
---|
311 | * Return value: the node before @node in the list |
---|
312 | **/ |
---|
313 | BonoboUINode* |
---|
314 | bonobo_ui_node_prev (BonoboUINode *node) |
---|
315 | { |
---|
316 | return BNODE (XML_NODE (node)->prev); |
---|
317 | } |
---|
318 | |
---|
319 | /** |
---|
320 | * bonobo_ui_node_children: |
---|
321 | * @node: the node |
---|
322 | * |
---|
323 | * accesses the node's children. |
---|
324 | * |
---|
325 | * Return value: the first child of @node |
---|
326 | **/ |
---|
327 | BonoboUINode* |
---|
328 | bonobo_ui_node_children (BonoboUINode *node) |
---|
329 | { |
---|
330 | return BNODE (XML_NODE (node)->xmlChildrenNode); |
---|
331 | } |
---|
332 | |
---|
333 | /** |
---|
334 | * bonobo_ui_node_parent: |
---|
335 | * @node: the node |
---|
336 | * |
---|
337 | * accesses the node's parent. |
---|
338 | * |
---|
339 | * Return value: the parent node of @node |
---|
340 | **/ |
---|
341 | BonoboUINode* |
---|
342 | bonobo_ui_node_parent (BonoboUINode *node) |
---|
343 | { |
---|
344 | return BNODE (XML_NODE (node)->parent); |
---|
345 | } |
---|
346 | |
---|
347 | /** |
---|
348 | * bonobo_ui_node_get_name: |
---|
349 | * @node: the node |
---|
350 | * |
---|
351 | * Return value: the name of @node |
---|
352 | **/ |
---|
353 | const char* |
---|
354 | bonobo_ui_node_get_name (BonoboUINode *node) |
---|
355 | { |
---|
356 | return XML_NODE (node)->name; |
---|
357 | } |
---|
358 | |
---|
359 | /** |
---|
360 | * bonobo_ui_node_has_name: |
---|
361 | * @node: the node |
---|
362 | * @name: a name the node might have |
---|
363 | * |
---|
364 | * accesses the node's name. |
---|
365 | * |
---|
366 | * Return value: TRUE if @node has name == @name |
---|
367 | **/ |
---|
368 | gboolean |
---|
369 | bonobo_ui_node_has_name (BonoboUINode *node, |
---|
370 | const char *name) |
---|
371 | { |
---|
372 | return strcmp (XML_NODE (node)->name, name) == 0; |
---|
373 | } |
---|
374 | |
---|
375 | /** |
---|
376 | * bonobo_ui_node_free_string: |
---|
377 | * @str: the string to free. |
---|
378 | * |
---|
379 | * Frees a string returned by any of the get routines. |
---|
380 | **/ |
---|
381 | void |
---|
382 | bonobo_ui_node_free_string (char *str) |
---|
383 | { |
---|
384 | if (str) |
---|
385 | xmlFree (str); |
---|
386 | } |
---|
387 | |
---|
388 | /** |
---|
389 | * bonobo_ui_node_to_string: |
---|
390 | * @node: the node tree |
---|
391 | * @recurse: whether to dump its children as well |
---|
392 | * |
---|
393 | * Convert the Node to its XML string representation |
---|
394 | * see also: bonobo_ui_node_free_string |
---|
395 | * |
---|
396 | * Return value: the string representation or NULL on error |
---|
397 | **/ |
---|
398 | char * |
---|
399 | bonobo_ui_node_to_string (BonoboUINode *node, |
---|
400 | gboolean recurse) |
---|
401 | { |
---|
402 | xmlDoc *doc; |
---|
403 | xmlChar *mem = NULL; |
---|
404 | int size; |
---|
405 | |
---|
406 | doc = xmlNewDoc ("1.0"); |
---|
407 | g_return_val_if_fail (doc != NULL, NULL); |
---|
408 | |
---|
409 | doc->xmlRootNode = XML_NODE(bonobo_ui_node_copy (node, TRUE)); |
---|
410 | g_return_val_if_fail (doc->xmlRootNode != NULL, NULL); |
---|
411 | |
---|
412 | if (!recurse && bonobo_ui_node_children (BNODE (doc->xmlRootNode))) { |
---|
413 | BonoboUINode *tmp; |
---|
414 | while ((tmp = bonobo_ui_node_children (BNODE (doc->xmlRootNode)))) { |
---|
415 | xmlUnlinkNode (XML_NODE(tmp)); |
---|
416 | bonobo_ui_node_free (tmp); |
---|
417 | } |
---|
418 | } |
---|
419 | |
---|
420 | xmlDocDumpMemory (doc, &mem, &size); |
---|
421 | |
---|
422 | g_return_val_if_fail (mem != NULL, NULL); |
---|
423 | |
---|
424 | xmlFreeDoc (doc); |
---|
425 | |
---|
426 | return mem; |
---|
427 | } |
---|
428 | |
---|
429 | /** |
---|
430 | * bonobo_ui_node_from_string: |
---|
431 | * @xml: the xml string |
---|
432 | * |
---|
433 | * Parses a string into an XML tree |
---|
434 | * |
---|
435 | * Return value: the xml tree. |
---|
436 | **/ |
---|
437 | BonoboUINode* |
---|
438 | bonobo_ui_node_from_string (const char *xml) |
---|
439 | { |
---|
440 | /* We have crap error reporting for this function */ |
---|
441 | xmlDoc *doc; |
---|
442 | BonoboUINode *node; |
---|
443 | |
---|
444 | doc = xmlParseDoc ((char *)xml); |
---|
445 | if (!doc) |
---|
446 | return NULL; |
---|
447 | |
---|
448 | node = BNODE (doc->xmlRootNode); |
---|
449 | bonobo_ui_node_strip (&node); |
---|
450 | |
---|
451 | xmlUnlinkNode (XML_NODE (node)); |
---|
452 | doc->xmlRootNode = NULL; |
---|
453 | |
---|
454 | xmlFreeDoc (doc); |
---|
455 | |
---|
456 | return node; |
---|
457 | } |
---|
458 | |
---|
459 | /** |
---|
460 | * bonobo_ui_node_from_file: |
---|
461 | * @fname: the filename containing the xml |
---|
462 | * |
---|
463 | * Loads and parses the filename into an XML tree |
---|
464 | * |
---|
465 | * Return value: the xml tree. |
---|
466 | **/ |
---|
467 | BonoboUINode* |
---|
468 | bonobo_ui_node_from_file (const char *fname) |
---|
469 | { |
---|
470 | /* Error reporting blows here too (because it blows |
---|
471 | * in libxml) |
---|
472 | */ |
---|
473 | xmlDoc *doc; |
---|
474 | BonoboUINode *node; |
---|
475 | |
---|
476 | g_return_val_if_fail (fname != NULL, NULL); |
---|
477 | |
---|
478 | doc = xmlParseFile (fname); |
---|
479 | |
---|
480 | g_return_val_if_fail (doc != NULL, NULL); |
---|
481 | |
---|
482 | node = BNODE (doc->xmlRootNode); |
---|
483 | bonobo_ui_node_strip (&node); |
---|
484 | |
---|
485 | xmlUnlinkNode (XML_NODE (node)); |
---|
486 | doc->xmlRootNode = NULL; |
---|
487 | |
---|
488 | xmlFreeDoc (doc); |
---|
489 | |
---|
490 | return node; |
---|
491 | } |
---|
492 | |
---|
493 | /** |
---|
494 | * bonobo_ui_node_transparent: |
---|
495 | * @node: the node |
---|
496 | * |
---|
497 | * Determines whether @node is transparent. A node is |
---|
498 | * transparent if it has no content and either no attributes |
---|
499 | * or a single 'name' attribute. |
---|
500 | * |
---|
501 | * Return value: TRUE if transparent |
---|
502 | **/ |
---|
503 | gboolean |
---|
504 | bonobo_ui_node_transparent (BonoboUINode *node) |
---|
505 | { |
---|
506 | xmlNode *n = XML_NODE (node); |
---|
507 | gboolean ret = FALSE; |
---|
508 | |
---|
509 | g_return_val_if_fail (n != NULL, TRUE); |
---|
510 | |
---|
511 | if (n->content) { |
---|
512 | ret = FALSE; |
---|
513 | |
---|
514 | } else if (!n->properties) { |
---|
515 | if (!strcmp (XML_NODE (node)->name, "placeholder")) |
---|
516 | ret = TRUE; |
---|
517 | else if (!strcmp (XML_NODE (node)->name, "menu")) |
---|
518 | ret = TRUE; |
---|
519 | |
---|
520 | } else if (!n->properties->next) { |
---|
521 | if (!strcmp (n->properties->name, "name")) |
---|
522 | ret = TRUE; |
---|
523 | } |
---|
524 | |
---|
525 | return ret; |
---|
526 | } |
---|
527 | |
---|
528 | /** |
---|
529 | * bonobo_ui_node_copy_attrs: |
---|
530 | * @src: the attr source node |
---|
531 | * @dest: where to dump the attrs. |
---|
532 | * |
---|
533 | * This function copies all the attributes from @src to @dest |
---|
534 | * effectively cloning the @src node as @dest |
---|
535 | **/ |
---|
536 | void |
---|
537 | bonobo_ui_node_copy_attrs (BonoboUINode *src, |
---|
538 | BonoboUINode *dest) |
---|
539 | { |
---|
540 | xmlAttr *attr; |
---|
541 | |
---|
542 | for (attr = XML_NODE (src)->properties; attr; attr = attr->next) { |
---|
543 | char *txt = xmlGetProp (XML_NODE (src), attr->name); |
---|
544 | |
---|
545 | g_assert (txt != NULL); |
---|
546 | |
---|
547 | xmlSetProp (XML_NODE (dest), attr->name, txt); |
---|
548 | |
---|
549 | xmlFree (txt); |
---|
550 | } |
---|
551 | } |
---|
552 | |
---|
553 | static gboolean |
---|
554 | do_strip (xmlNode *node) |
---|
555 | { |
---|
556 | xmlNode *l, *next; |
---|
557 | gboolean suspicious = FALSE; |
---|
558 | |
---|
559 | if (!node) |
---|
560 | return FALSE; |
---|
561 | |
---|
562 | switch (node->type) { |
---|
563 | case XML_DOCUMENT_FRAG_NODE: |
---|
564 | case XML_ELEMENT_NODE: |
---|
565 | case XML_TEXT_NODE: |
---|
566 | case XML_ENTITY_NODE: |
---|
567 | case XML_ENTITY_REF_NODE: { |
---|
568 | xmlAttr *a, *nexta; |
---|
569 | |
---|
570 | node->nsDef = NULL; |
---|
571 | node->ns = NULL; |
---|
572 | node->doc = NULL; |
---|
573 | |
---|
574 | for (a = node->properties; a; a = nexta) { |
---|
575 | nexta = a->next; |
---|
576 | a->ns = NULL; |
---|
577 | do_strip (a->val); |
---|
578 | } |
---|
579 | |
---|
580 | for (l = node->xmlChildrenNode; l; l = next) { |
---|
581 | next = l->next; |
---|
582 | do_strip (l); |
---|
583 | } |
---|
584 | break; |
---|
585 | } |
---|
586 | |
---|
587 | case XML_ATTRIBUTE_NODE: { |
---|
588 | xmlAttr *attr = (xmlAttr *)node; |
---|
589 | attr->ns = NULL; |
---|
590 | do_strip (attr->val); |
---|
591 | break; |
---|
592 | } |
---|
593 | |
---|
594 | case XML_PI_NODE: |
---|
595 | case XML_COMMENT_NODE: |
---|
596 | case XML_DOCUMENT_NODE: |
---|
597 | case XML_HTML_DOCUMENT_NODE: |
---|
598 | case XML_DOCUMENT_TYPE_NODE: |
---|
599 | case XML_NOTATION_NODE: |
---|
600 | case XML_CDATA_SECTION_NODE: |
---|
601 | suspicious = TRUE; |
---|
602 | break; |
---|
603 | } |
---|
604 | |
---|
605 | if (suspicious) { |
---|
606 | /* g_warning ("node looks suspicious %d: '%s'", |
---|
607 | node->type, |
---|
608 | bonobo_ui_node_to_string (BNODE (node), TRUE));*/ |
---|
609 | xmlUnlinkNode (node); |
---|
610 | bonobo_ui_node_free (BNODE (node)); |
---|
611 | return TRUE; |
---|
612 | } else |
---|
613 | return FALSE; |
---|
614 | } |
---|
615 | |
---|
616 | /** |
---|
617 | * bonobo_ui_node_strip: |
---|
618 | * @node: a pointer to the node's pointer |
---|
619 | * |
---|
620 | * This function is used to purge unwanted content from |
---|
621 | * a set of nodes, and particularly clean up stray Doc and |
---|
622 | * NS pointers that cause serious trouble later. |
---|
623 | **/ |
---|
624 | void |
---|
625 | bonobo_ui_node_strip (BonoboUINode **node) |
---|
626 | { |
---|
627 | BonoboUINode *next, *l; |
---|
628 | |
---|
629 | for (l = *node; l; l = next) { |
---|
630 | next = bonobo_ui_node_next (l); |
---|
631 | if (l == *node && do_strip (XML_NODE (l))) |
---|
632 | *node = next; |
---|
633 | } |
---|
634 | } |
---|