Annotation of win32/gnome/gdome2-x.x.x/libgdome/gdomecore/gdome-xml-node.c, revision 1.2

1.1       paf         1: /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
                      2: /* gdome-xml-node.c
                      3:  *
                      4:  * Copyright (C) 1999 Raph Levien <raph@acm.org>
                      5:  * Copyright (C) 2000 Mathieu Lacage <mathieu@gnu.org>
                      6:  * Copyright (C) 2000 Anders Carlsson <andersca@gnu.org>
                      7:  * Copyright (C) 2001 Paolo Casarini <paolo@casarini.org>
                      8:  *
                      9:  * This library is free software; you can redistribute it and/or
                     10:  * modify it under the terms of the GNU Lesser General Public
                     11:  * License as published by the Free Software Foundation; either
                     12:  * version 2.1 of the License, or (at your option) any later version.
                     13:  * 
                     14:  * This library is distributed in the hope that it will be useful,
                     15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     17:  * Lesser General Public License for more details.
                     18:  * 
                     19:  * You should have received a copy of the GNU Lesser General Public
                     20:  * License along with this library; if not, write to the Free Software
                     21:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     22:  */
                     23: 
                     24: #ifdef HAVE_CONFIG_H
                     25: #  include <config.h>
                     26: #endif
                     27: //paf #include <sys/time.h>
                     28: //paf #include <unistd.h>
                     29: #include <stdlib.h>
                     30: #include <string.h>
                     31: #include "gdome.h"
                     32: #include "gdome-events.h"
                     33: #include "gdome-refdebug.h"
                     34: #include "gdome-treegc.h"
                     35: #include <libxml/tree.h>
                     36: #include <libxml/parser.h>
                     37: #include <libxml/xmlmemory.h>
                     38: #include <libxml/hash.h>
                     39: #include "gdome-xml-util.h"
                     40: #include "gdome-xml-xmlmemory.h"
                     41: #include "gdome-xml-xmlutil.h"
                     42: #include "gdome-xml-xmldtdutil.h"
                     43: #include "gdome-xml-str.h"
                     44: #include "gdome-evt-event.h"
                     45: #include "gdome-evt-eventl.h"
                     46: #include "gdome-evt-mevent.h"
                     47: #include "gdome-evt-propagation.h"
                     48: #include "gdome-xml-nodel.h"
                     49: #include "gdome-xml-node.h"
                     50: #include "gdome-xml-document.h"
                     51: #include "gdome-xml-element.h"
                     52: #include "gdome-xml-attribute.h"
                     53: #include "gdome-xml-cdata.h"
                     54: #include "gdome-xml-entityref.h"
                     55: #include "gdome-xml-text.h"
                     56: #include "gdome-xml-cdatas.h"
                     57: #include "gdome-xml-comment.h"
                     58: #include "gdome-xml-entity.h"
                     59: #include "gdome-xml-pi.h"
                     60: #include "gdome-xml-notation.h"
                     61: #include "gdome-xml-documentt.h"
                     62: #include "gdome-xml-documentf.h"
                     63: #include "gdome-xml-domimpl.h"
                     64: #include "gdome-xpath.h"
                     65: #include "gdome-xml-xpns.h"
                     66: 
                     67: /* indexed by node type 
                     68:   first one is NULL because there 
                     69:    is no node type number 0 
                     70:    cf: spec p25 (DOM 1). interface Node.
                     71: */
                     72: const void * gdome_xml_vtabs[] = {
                     73:  NULL, 
                     74:  &gdome_xml_el_vtab,
                     75:  &gdome_xml_a_vtab,
                     76:  &gdome_xml_t_vtab,
                     77:  &gdome_xml_cds_vtab,
                     78:  &gdome_xml_er_vtab,
                     79:  &gdome_xml_ent_vtab,
                     80:  &gdome_xml_pi_vtab,
                     81:  &gdome_xml_c_vtab,
                     82:  &gdome_xml_doc_vtab, 
                     83:  &gdome_xml_dt_vtab,
                     84:  &gdome_xml_df_vtab,
                     85:  &gdome_xml_not_vtab,
                     86:  &gdome_xml_doc_vtab,
                     87:   &gdome_xml_dt_vtab,
                     88:   NULL,
                     89:   NULL,
                     90:   &gdome_xml_ent_vtab
                     91: };
                     92: 
                     93: /***************
                     94:  * Virtual Table
                     95:  **************/
                     96: const GdomeNodeVtab gdome_xml_n_vtab = 
                     97: {
                     98:  gdome_xml_n_ref,
                     99:  gdome_xml_n_unref,
                    100:  gdome_xml_n_query_interface,
                    101:  gdome_xml_n_nodeName,
                    102:  gdome_xml_n_nodeValue,
                    103:  gdome_xml_n_set_nodeValue,
                    104:  gdome_xml_n_nodeType,
                    105:  gdome_xml_n_parentNode,
                    106:  gdome_xml_n_childNodes,
                    107:  gdome_xml_n_firstChild,
                    108:  gdome_xml_n_lastChild,
                    109:  gdome_xml_n_previousSibling,
                    110:  gdome_xml_n_nextSibling,
                    111:  gdome_xml_n_attributes,
                    112:  gdome_xml_n_ownerDocument,
                    113:  gdome_xml_n_insertBefore,
                    114:  gdome_xml_n_replaceChild,
                    115:  gdome_xml_n_removeChild,
                    116:  gdome_xml_n_appendChild,
                    117:  gdome_xml_n_hasChildNodes,
                    118:  gdome_xml_n_cloneNode,
                    119:  gdome_xml_n_normalize,
                    120:  gdome_xml_n_isSupported,
                    121:  gdome_xml_n_namespaceURI,
                    122:  gdome_xml_n_prefix,
                    123:  gdome_xml_n_set_prefix,
                    124:   gdome_xml_n_localName,
                    125:   gdome_xml_n_hasAttributes,
                    126:  gdome_xml_n_addEventListener,
                    127:  gdome_xml_n_removeEventListener,
                    128:   gdome_xml_n_dispatchEvent,
                    129:  gdome_xml_n_subTreeDispatchEvent,
                    130:   gdome_xml_n_canAppend
                    131: };
                    132: 
                    133: 
                    134: /* function to get the xmlNode from a GdomeNode */
                    135: xmlNode *
                    136: gdome_xml_n_get_xmlNode (GdomeNode *node)
                    137: {
                    138:  Gdome_xml_Node *xmlnode;
                    139: 
                    140:  xmlnode = (Gdome_xml_Node *)node;
                    141: 
                    142:  return xmlnode->n;
                    143: }
                    144: 
                    145: /***********************************************************
                    146:  ***** Constructor and Reference Count Implementation ******
                    147:  ***********************************************************/
                    148: 
                    149: /**
                    150:  * gdome_xml_n_mkref:
                    151:  * @n:  The libxml node of which a Gdome reference is wanted
                    152:  *
                    153:  * Constructor of the Node structure.
                    154:  * Returns: the reference to the Gdome node wanted.
                    155:  */
                    156: GdomeNode *
                    157: gdome_xml_n_mkref (xmlNode *n) {
                    158:  Gdome_xml_Node *result = NULL;
                    159:  xmlElementType type;
                    160: 
                    161:  if (n == NULL)
                    162:    return NULL;
                    163: 
                    164:  type = n->type;
                    165:  if (n->_private && type != XML_NAMESPACE_DECL) {
                    166:    result = (Gdome_xml_Node *)n->_private;
                    167:    result->refcnt++;
                    168:  } else {
                    169:    switch (type) {
                    170:    case XML_ELEMENT_NODE:
                    171:    case XML_TEXT_NODE:
                    172:    case XML_CDATA_SECTION_NODE:
                    173:    case XML_ENTITY_REF_NODE:
                    174:    case XML_PI_NODE:
                    175:    case XML_COMMENT_NODE:
                    176:    case XML_NOTATION_NODE:
                    177:    case XML_DOCUMENT_FRAG_NODE:
                    178:    case XML_ATTRIBUTE_NODE:
                    179:    case XML_ENTITY_DECL: /*libxml use this instead of XML_ENTITY_NODE*/
                    180:      result = g_new (Gdome_xml_Node, 1);
                    181: 
                    182:      result->refcnt = 1;
                    183:       result->vtab = (GdomeNodeVtab *)gdome_xml_vtabs[n->type];
                    184:       result->super.user_data = NULL;
                    185:       result->n = n;
                    186:       if (type == XML_NOTATION_NODE || type == XML_ENTITY_NODE || type == XML_ENTITY_DECL)
                    187:         result->accessType = GDOME_READONLY_NODE;
                    188:       else
                    189:         result->accessType = GDOME_READWRITE_NODE;
                    190:       result->ll = NULL;
                    191: 
                    192:      n->_private = result;
                    193: 
                    194: #ifdef DEBUG_REFCNT
                    195:       gdome_refdbg_addRef ((void *)result, GDOME_REFDBG_NODE);
                    196: #endif
                    197:       gdome_treegc_addNode ((GdomeNode *)result);
                    198: 
                    199:       break;
                    200:     case XML_DOCUMENT_TYPE_NODE:
                    201:     case XML_DTD_NODE:
                    202:       return (GdomeNode *)gdome_xml_dt_mkref ((xmlDtd *)n);
                    203:    case XML_HTML_DOCUMENT_NODE:
                    204:    case XML_DOCUMENT_NODE:
                    205:       return (GdomeNode *)gdome_xml_doc_mkref ((xmlDoc *)n);
                    206:    case XML_NAMESPACE_DECL:
                    207:      return (GdomeNode *)gdome_xml_xpns_mkref ((xmlNs *)n);
                    208:    default:
                    209:      g_warning ("gdome_xml_n_mkref: invalid node type");
                    210:      break;
                    211:    }
                    212:  }
                    213:  return (GdomeNode *)result;
                    214: }
                    215: 
                    216: /**
                    217:  * gdome_xml_n_ref:
                    218:  * @self:  Node Object ref
                    219:  * @exc:  Exception Object ref
                    220:  *
                    221:  * Increase the reference count of the specified Node.
                    222:  */
                    223: void
                    224: gdome_xml_n_ref (GdomeNode *self, GdomeException *exc) {
                    225:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    226: 
                    227:   g_return_if_fail (priv != NULL);
                    228:   g_return_if_fail (GDOME_XML_IS_N (priv));
                    229:   g_return_if_fail (exc != NULL);
                    230: 
                    231:  priv->refcnt++;
                    232: }
                    233: 
                    234: /**
                    235:  * gdome_xml_n_unref:
                    236:  * @self:  Node Object ref
                    237:  * @exc:  Exception Object ref
                    238:  *
                    239:  * Decrease the reference count of the specified Node. Free the Node structure
                    240:  * if the Node will have zero reference.
                    241:  */
                    242: void
                    243: gdome_xml_n_unref (GdomeNode *self, GdomeException *exc) {
                    244:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    245:   xmlElementType type;
                    246: 
                    247:   g_return_if_fail (priv != NULL);
                    248:  g_return_if_fail (GDOME_XML_IS_N (priv));
                    249:   g_return_if_fail (exc != NULL);
                    250: 
                    251:   type = gdome_xmlGetType (priv->n);
                    252:   switch (type) {
                    253:   case XML_DOCUMENT_TYPE_NODE:
                    254:   case XML_DTD_NODE:
                    255:     return gdome_xml_dt_unref (self, exc);
                    256:   case XML_DOCUMENT_NODE:
                    257:     return gdome_xml_doc_unref (self, exc);
                    258:   default:
                    259:     if (priv->refcnt > 0)
                    260:       priv->refcnt--;
                    261: 
                    262:     if (priv->refcnt == 0 && priv->ll == NULL) {
                    263:       xmlNode *n = (xmlNode *)priv->n;
                    264: 
                    265:      gdome_treegc_delNode (self);
                    266: 
                    267:       n->_private = NULL;
                    268:      if (type != XML_NOTATION_NODE &&
                    269:          type != XML_ENTITY_DECL &&
                    270:          n->parent == NULL)
                    271:        gdome_xmlFreeSubtree (n);
                    272:      else {
                    273:        if (type == XML_ATTRIBUTE_NODE)
                    274:          if (gdome_xmlIsNsDecl ((xmlAttr *)n))
                    275:            gdome_xmlFreeSubtree (n);
                    276:      }
                    277: 
                    278: #ifdef DEBUG_REFCNT
                    279:       gdome_refdbg_delRef ((void *)self, GDOME_REFDBG_NODE);
                    280: #endif
                    281:       g_free (self);
                    282:     }
                    283:   }
                    284: }
                    285: 
                    286: /**
                    287:  * gdome_xml_n_query_interface:
                    288:  * @self:  Node Object ref
                    289:  * @interface:  interface needed
                    290:  * @exc:  Exception Object ref
                    291:  *
                    292:  * Returns: a reference to this object that implements the @interface needed,
                    293:  *          or %NULL if the @interface is not supported by this Object.
                    294:  */
                    295: gpointer
                    296: gdome_xml_n_query_interface (GdomeNode *self, const char *interface, GdomeException *exc)
                    297: {
                    298:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    299: 
                    300:   g_return_val_if_fail (priv != NULL, NULL);
                    301:   g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    302:   g_return_val_if_fail (interface != NULL, NULL);
                    303:   g_return_val_if_fail (exc != NULL, NULL);
                    304: 
                    305:   if (!strcmp (interface, "Node") ||
                    306:       !strcmp (interface, "EventTarget")) {
                    307:     priv->refcnt++;
                    308:     return self;
                    309:   }
                    310:   else
                    311:     return NULL;
                    312: }
                    313: 
                    314: /**************************************
                    315:  ***** Attributes implementation ******
                    316:  **************************************/
                    317: 
                    318: /**
                    319:  * gdome_xml_n_attributes:
                    320:  * @self:  Node Object ref
                    321:  * @exc:  Exception Object ref
                    322:  *
                    323:  * Returns: a NamedNodeMap containing the attributes of this node (if it is an
                    324:  * Element) or %NULL otherwise.
                    325:  */
                    326: GdomeNamedNodeMap *
                    327: gdome_xml_n_attributes (GdomeNode *self, GdomeException *exc)
                    328: {
                    329:  g_return_val_if_fail (self != NULL, NULL);
                    330:  g_return_val_if_fail (GDOME_XML_IS_N (self), NULL);
                    331:  g_return_val_if_fail (exc != NULL, NULL);
                    332: 
                    333:  if (GDOME_XML_IS_EL (self))
                    334:    return gdome_el_attributes((GdomeElement *)self, exc);
                    335: 
                    336:  return NULL;
                    337: }
                    338: 
                    339: /**
                    340:  * gdome_xml_n_childNodes:
                    341:  * @self:  Node Object ref
                    342:  * @exc:  Exception Object ref
                    343:  *
                    344:  * Returns: a NodeList that contains all children of this node. If there are no
                    345:  * children, this is a NodeList containing no nodes.  Note that attributes are
                    346:  * not considered to be children of element nodes - use gdome_n_attributes to
                    347:  * obtain the attributes.
                    348:  */
                    349: GdomeNodeList *
                    350: gdome_xml_n_childNodes (GdomeNode *self, GdomeException *exc)
                    351: {
                    352:  g_return_val_if_fail (self != NULL, NULL);
                    353:  g_return_val_if_fail (GDOME_XML_IS_N (self), NULL);
                    354:  g_return_val_if_fail (exc != NULL, NULL);
                    355: 
                    356:   if (GDOME_XML_IS_NS(self))
                    357:    return NULL;
                    358: 
                    359:   return gdome_xml_nl_mkref ((GdomeNode*)self, NULL, NULL, GDOME_READONLY_NODE);
                    360: }
                    361: 
                    362: /**
                    363:  * gdome_xml_n_firstChild:
                    364:  * @self:  Node Object ref
                    365:  * @exc:  Exception Object ref
                    366:  * 
                    367:  * Returns: the first child of this node. If there is no such node,
                    368:  * this returns %NULL.
                    369:  */
                    370: GdomeNode *
                    371: gdome_xml_n_firstChild (GdomeNode *self, GdomeException *exc)
                    372: {
                    373:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    374: 
                    375:  g_return_val_if_fail (priv != NULL, NULL);
                    376:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    377:  g_return_val_if_fail (exc != NULL, NULL);
                    378: 
                    379:   switch (gdome_xmlGetType (priv->n)) {
                    380:   case XML_DOCUMENT_TYPE_NODE:
                    381:   case XML_DTD_NODE:
                    382:   case XML_PI_NODE:
                    383:   case XML_COMMENT_NODE:
                    384:   case XML_TEXT_NODE:
                    385:   case XML_CDATA_SECTION_NODE:
                    386:   case XML_NOTATION_NODE:
                    387:   case XML_NAMESPACE_DECL:
                    388:     return NULL;
                    389:   case XML_DOCUMENT_NODE:
                    390:   case XML_DOCUMENT_FRAG_NODE:
                    391:   case XML_ENTITY_REF_NODE:
                    392:   case XML_ELEMENT_NODE:
                    393:   case XML_ATTRIBUTE_NODE:
                    394:   case XML_ENTITY_NODE:
                    395:   case XML_ENTITY_DECL:
                    396:     return gdome_xml_n_mkref (gdome_xmlGetFirstChild (priv->n));
                    397:   default:
                    398:     g_warning ("gdome_xml_n_firstChild: invalid node type");
                    399:     return NULL;
                    400:   }
                    401: }
                    402: 
                    403: /**
                    404:  * gdome_xml_n_lastChild:
                    405:  * @self:  Node Object ref
                    406:  * @exc:  Exception Object ref
                    407:  *
                    408:  * Returns: the last child of this node. If there is no such node,
                    409:  * this returns %NULL.
                    410:  */
                    411: GdomeNode *
                    412: gdome_xml_n_lastChild (GdomeNode *self, GdomeException *exc)
                    413: {
                    414:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    415: 
                    416:  g_return_val_if_fail (priv != NULL, NULL);
                    417:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    418:  g_return_val_if_fail (exc != NULL, NULL);
                    419: 
                    420:   switch (gdome_xmlGetType (priv->n)) {
                    421:   case XML_DOCUMENT_TYPE_NODE:
                    422:   case XML_DTD_NODE:
                    423:   case XML_PI_NODE:
                    424:   case XML_COMMENT_NODE:
                    425:   case XML_TEXT_NODE:
                    426:   case XML_CDATA_SECTION_NODE:
                    427:   case XML_NOTATION_NODE:
                    428:   case XML_NAMESPACE_DECL:
                    429:     return NULL;
                    430:   case XML_DOCUMENT_NODE:
                    431:   case XML_DOCUMENT_FRAG_NODE:
                    432:   case XML_ENTITY_REF_NODE:
                    433:   case XML_ELEMENT_NODE:
                    434:   case XML_ATTRIBUTE_NODE:
                    435:   case XML_ENTITY_NODE:
                    436:   case XML_ENTITY_DECL:
                    437:     return gdome_xml_n_mkref (gdome_xmlGetLastChild (priv->n));
                    438:   default:
                    439:     g_warning ("gdome_xml_n_lastChild: invalid node type");
                    440:     return NULL;
                    441:   }
                    442: }
                    443: 
                    444: /**
                    445:  * gdome_xml_n_localName:
                    446:  * @self:  Node Objects ref
                    447:  * @exc:  Exception Object ref
                    448:  *
                    449:  * Returns: the local part of the qualified name of this node.
                    450:  * For nodes of any type other than %GDOME_ELEMENT_NODE and
                    451:  * %GDOME_ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, this is
                    452:  * always %NULL.
                    453:  */
                    454: GdomeDOMString *
                    455: gdome_xml_n_localName (GdomeNode *self, GdomeException *exc)
                    456: {
                    457:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    458: 
                    459:  g_return_val_if_fail (priv != NULL, NULL);
                    460:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    461:  g_return_val_if_fail (exc != NULL, NULL);
                    462: 
                    463:  if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
                    464:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE) &&
                    465:     gdome_xmlGetNs(priv->n) != NULL)
                    466:    return gdome_xml_str_mkref_dup ((gchar *)gdome_xmlGetName (priv->n));
                    467:  else
                    468:    return NULL;
                    469: }
                    470: 
                    471: /**
                    472:  * gdome_xml_n_namespaceURI:
                    473:  * @self:  Node Objects ref
                    474:  * @exc:  Exception Object ref
                    475:  *
                    476:  * Returns: the namespace URI of this node, or %NULL if it is unspecified.
                    477:  * For nodes of any type other than %GDOME_ELEMENT_NODE and
                    478:  * %GDOME_ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, this is
                    479:  * always %NULL.
                    480:  */
                    481: GdomeDOMString *
                    482: gdome_xml_n_namespaceURI (GdomeNode *self, GdomeException *exc)
                    483: {
                    484:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    485: 
                    486:  g_return_val_if_fail (priv != NULL, NULL);
                    487:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    488:  g_return_val_if_fail (exc != NULL, NULL);
                    489: 
                    490:  if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
                    491:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE ||
                    492:      gdome_xmlGetType(priv->n) == XML_NAMESPACE_DECL) &&
                    493:     gdome_xmlGetNs(priv->n) != NULL)
                    494:    return gdome_xml_str_mkref_dup ((gchar *)gdome_xmlGetNsURI (priv->n));
                    495:  else
                    496:    return NULL;
                    497: }
                    498: 
                    499: /**
                    500:  * gdome_xml_n_nextSibling:
                    501:  * @self:  Node Object ref
                    502:  * @exc:  Exception Object ref
                    503:  *
                    504:  * Returns: the node immediately following this node. If there is no such
                    505:  * node, this returns %NULL.
                    506:  */
                    507: GdomeNode *
                    508: gdome_xml_n_nextSibling (GdomeNode *self, GdomeException *exc)
                    509: {
                    510:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    511: 
                    512:  g_return_val_if_fail (priv != NULL, NULL);
                    513:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    514:  g_return_val_if_fail (exc != NULL, NULL);
                    515: 
                    516:  if(GDOME_XML_IS_A (priv) || GDOME_XML_IS_NS (priv))
                    517:    return NULL;
                    518:  else
                    519:    return gdome_xml_n_mkref (gdome_xmlGetNext (priv->n));
                    520: }
                    521: 
                    522: /**
                    523:  * gdome_xml_n_nodeName:
                    524:  * @self:  Node Object ref
                    525:  * @exc:  Exception Object ref
                    526:  *
                    527:  * Returns: the name of this node, depending on its type.
                    528:  */
                    529: GdomeDOMString *
                    530: gdome_xml_n_nodeName (GdomeNode *self, GdomeException *exc)
                    531: {
                    532:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    533:  GdomeDOMString *ret = NULL;
                    534: 
                    535:  g_return_val_if_fail (priv != NULL, NULL);
                    536:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    537:  g_return_val_if_fail (exc != NULL, NULL);
                    538: 
                    539:  switch (gdome_xmlGetType (priv->n)) {
                    540:  case XML_ATTRIBUTE_NODE:
                    541:    ret = gdome_a_name((GdomeAttr *)self, exc);
                    542:    break;
                    543:  case XML_ELEMENT_NODE:
                    544:    ret = gdome_el_tagName((GdomeElement *)self, exc);
                    545:    break;
                    546:   case XML_DOCUMENT_TYPE_NODE:
                    547:   case XML_DTD_NODE:
                    548:     ret = gdome_dt_name((GdomeDocumentType *)self, exc);
                    549:     break;
                    550:   case XML_PI_NODE:
                    551:     ret = gdome_pi_target((GdomeProcessingInstruction *)self, exc);
                    552:    break;
                    553:   case XML_ENTITY_NODE:
                    554:   case XML_ENTITY_DECL: /*libxml use this instead of XML_ENTITY_NODE*/
                    555:  case XML_ENTITY_REF_NODE:
                    556:  case XML_NOTATION_NODE:
                    557:    ret = gdome_xml_str_mkref_dup((gchar *)gdome_xmlGetName (priv->n));
                    558:    break;
                    559:  case XML_CDATA_SECTION_NODE:
                    560:    ret = gdome_xml_str_mkref_dup("#cdata-section");
                    561:    break;
                    562:  case XML_COMMENT_NODE:
                    563:    ret = gdome_xml_str_mkref_dup("#comment");
                    564:    break;
                    565:  case XML_DOCUMENT_NODE:
                    566:    ret = gdome_xml_str_mkref_dup("#document");
                    567:    break;
                    568:  case XML_DOCUMENT_FRAG_NODE:
                    569:    ret = gdome_xml_str_mkref_dup("#document-fragment");
                    570:    break;
                    571:  case XML_TEXT_NODE:
                    572:    ret = gdome_xml_str_mkref_dup("#text");
                    573:    break;
                    574:   case XML_NAMESPACE_DECL:
                    575:     ret = gdome_xml_str_mkref_dup(gdome_xmlGetNsPrefix(priv->n));
                    576:    break;
                    577:  default:
                    578:    g_warning ("gdome_n_name: wrong Node Type.");
                    579:  }
                    580: 
                    581:  return ret;
                    582: }
                    583: 
                    584: /**
                    585:  * gdome_xml_n_nodeType:
                    586:  * @self:  Node Object ref
                    587:  * @exc:  Exception Object ref
                    588:  *
                    589:  * Returns: an integer bigger than %0 representing the type of the underlying
                    590:  * object or %0 on error.
                    591:  */
                    592: unsigned short
                    593: gdome_xml_n_nodeType (GdomeNode *self, GdomeException *exc)
                    594: {
                    595:   Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    596:   xmlElementType type;
                    597: 
                    598:  g_return_val_if_fail (priv != NULL, 0);
                    599:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
                    600:  g_return_val_if_fail (exc != NULL, 0);
                    601: 
                    602:   type = gdome_xmlGetType(priv->n);
                    603:   if (type == XML_DTD_NODE)
                    604:     return XML_DOCUMENT_TYPE_NODE;
                    605:   else if (type == XML_ENTITY_DECL)
                    606:     return XML_ENTITY_NODE;
                    607:  else if (type == XML_NAMESPACE_DECL)
                    608:    return GDOME_XPATH_NAMESPACE_NODE;
                    609:   else
                    610:     return type;
                    611: }
                    612: 
                    613: /**
                    614:  * gdome_xml_n_nodeValue:
                    615:  * @self:  Node Object ref
                    616:  * @exc:  Exception Object ref
                    617:  *
                    618:  * Returns: the value of this node, depending on its type.
                    619:  */
                    620: GdomeDOMString *
                    621: gdome_xml_n_nodeValue (GdomeNode *self, GdomeException *exc)
                    622: {
                    623:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    624:  GdomeDOMString *ret = NULL;
                    625: 
                    626:  g_return_val_if_fail (priv != NULL, 0);
                    627:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    628:  g_return_val_if_fail (exc != NULL, 0);
                    629: 
                    630:  switch (gdome_xmlGetType (priv->n)) {
                    631:  case XML_ATTRIBUTE_NODE:
                    632:    ret = gdome_a_value ((GdomeAttr *)self, exc);
                    633:    break;
                    634:   case XML_PI_NODE:
                    635:     ret = gdome_pi_data ((GdomeProcessingInstruction *)self, exc);
                    636:     break;
                    637:  case XML_CDATA_SECTION_NODE:
                    638:  case XML_COMMENT_NODE:
                    639:  case XML_TEXT_NODE:
1.2     ! paf       640:    ret = gdome_xml_str_mkref_xml (xmlNodeGetContent (priv->n));
1.1       paf       641:    break;
                    642:  case XML_ELEMENT_NODE:
                    643:  case XML_ENTITY_NODE:
                    644:  case XML_ENTITY_REF_NODE:
                    645:  case XML_DOCUMENT_NODE:
                    646:  case XML_DOCUMENT_TYPE_NODE:
                    647:  case XML_DOCUMENT_FRAG_NODE:
                    648:   case XML_NOTATION_NODE:
                    649:   case XML_DTD_NODE:
                    650:   case XML_ENTITY_DECL:
                    651:  case XML_NAMESPACE_DECL:
                    652:    break;
                    653:  default:
                    654:    g_warning ("could not recognize the Node Type.");
                    655:  }
                    656: 
                    657:  return ret;
                    658: }
                    659: 
                    660: /**
                    661:  * gdome_xml_n_ownerDocument:
                    662:  * @self:  Node Objects ref
                    663:  * @exc:  Exception Object ref
                    664:  *
                    665:  * Returns: the documment object associated with this node. This is also the
                    666:  * Document object used to create new nodes. When this node is a Document or a
                    667:  * DocumentType which is not used with any Document yet, this is %NULL.
                    668:  */
                    669: GdomeDocument *
                    670: gdome_xml_n_ownerDocument (GdomeNode *self, GdomeException *exc)
                    671: {
                    672:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    673: 
                    674:  g_return_val_if_fail (priv != NULL, NULL);
                    675:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    676:  g_return_val_if_fail (exc != NULL, NULL);
                    677: 
                    678:   if (gdome_xmlGetType (priv->n) == XML_DOCUMENT_NODE)
                    679:     return NULL;
                    680:   else
                    681:     return (GdomeDocument *)gdome_xml_n_mkref ((xmlNode *)gdome_xmlGetOwner (priv->n));
                    682: }
                    683: 
                    684: /**
                    685:  * gdome_xml_n_parentNode:
                    686:  * @self: Node Object ref
                    687:  * @exc: Exception Object ref
                    688:  *
                    689:  * Returns: the parent of this node. All nodes, except Attr,
                    690:  * Document, DocumentFragment, Entity, and Notation may have a parent. However,
                    691:  * if a node has just been created and not yet added to the tree, or if it has
                    692:  * been removed from the tree, this is %NULL.
                    693:  */
                    694: GdomeNode *
                    695: gdome_xml_n_parentNode (GdomeNode *self, GdomeException *exc)
                    696: {
                    697:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    698: 
                    699:  g_return_val_if_fail (priv != NULL, NULL);
                    700:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    701:  g_return_val_if_fail (exc != NULL, NULL);
                    702: 
                    703:  if(GDOME_XML_IS_TREE_N (priv))
                    704:    return gdome_xml_n_mkref (gdome_xmlGetParent (priv->n));
                    705:  else
                    706:    return NULL;
                    707: }
                    708: 
                    709: /**
                    710:  * gdome_xml_n_prefix:
                    711:  * @self:  Node Objects ref
                    712:  * @exc:  Exception Object ref
                    713:  *
                    714:  * Returns: the namespace prefix of this node, or %NULL if it is unspecified.
                    715:  * For nodes of any type other than %GDOME_ELEMENT_NODE and
                    716:  * %GDOME_ATTRIBUTE_NODE and nodes created with a DOM Level 1 method, this is
                    717:  * always %NULL.
                    718:  */
                    719: GdomeDOMString *
                    720: gdome_xml_n_prefix (GdomeNode *self, GdomeException *exc)
                    721: {
                    722:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    723: 
                    724:  g_return_val_if_fail (priv != NULL, 0);
                    725:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
                    726:  g_return_val_if_fail (exc != NULL, 0);
                    727: 
                    728:  if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
                    729:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE ||
                    730:      gdome_xmlGetType(priv->n) == XML_NAMESPACE_DECL) &&
                    731:     gdome_xmlGetNs(priv->n) != NULL)
                    732:    return gdome_xml_str_mkref_dup ((gchar *)gdome_xmlGetNsPrefix (priv->n));
                    733:  else
                    734:    return NULL;
                    735: }
                    736: 
                    737: /**
                    738:  * gdome_xml_n_previousSibling:
                    739:  * @self:  Node Object ref
                    740:  * @exc:  Exception Object ref
                    741:  *
                    742:  * Returns: the node immediately preceding this node. If there is no such
                    743:  * node, this returns %NULL.
                    744:  */
                    745: GdomeNode *
                    746: gdome_xml_n_previousSibling (GdomeNode *self, GdomeException *exc)
                    747: {
                    748:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    749: 
                    750:  g_return_val_if_fail (priv != NULL, NULL);
                    751:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    752:  g_return_val_if_fail (exc != NULL, NULL);
                    753: 
                    754:  if(GDOME_XML_IS_A (priv) || GDOME_XML_IS_NS (priv))
                    755:    return NULL;
                    756:  else
                    757:    return gdome_xml_n_mkref (gdome_xmlGetPrev (priv->n));
                    758: }
                    759: 
                    760: /**
                    761:  * gdome_xml_n_set_nodeValue:
                    762:  * @self:  Node Object ref
                    763:  * @nodeValue:  The new value for this node.
                    764:  * @exc:  Exception Object ref
                    765:  *
                    766:  * Sets The value of this node, depending on its type.
                    767:  *
                    768:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
                    769:  */
                    770: void
                    771: gdome_xml_n_set_nodeValue (GdomeNode *self, GdomeDOMString *nodeValue, GdomeException *exc)
                    772: {
                    773:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    774: 
                    775:  g_return_if_fail (priv != NULL);
                    776:  g_return_if_fail (GDOME_XML_IS_N (priv));
                    777:  g_return_if_fail (nodeValue != NULL);
                    778:   g_return_if_fail (exc != NULL);
                    779: 
                    780:   if (GDOME_ISREADONLY (priv)) {
                    781:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
                    782:     return;
                    783:   }
                    784: 
                    785:  switch (gdome_xmlGetType(priv->n)) {
                    786:  case XML_ATTRIBUTE_NODE:
                    787:    gdome_xml_a_set_value ((GdomeAttr *)self, nodeValue, exc);
                    788:    break;
                    789:   case XML_PI_NODE:
                    790:     gdome_xml_pi_set_data ((GdomeProcessingInstruction *)self, nodeValue, exc);
                    791:     break;
                    792:  case XML_CDATA_SECTION_NODE:
                    793:  case XML_COMMENT_NODE:
                    794:   case XML_TEXT_NODE:
                    795:     gdome_xml_cd_set_data ((GdomeCharacterData *)self, nodeValue, exc);
                    796:    break;
                    797:  case XML_ELEMENT_NODE:
                    798:  case XML_ENTITY_NODE:
                    799:  case XML_ENTITY_REF_NODE:
                    800:  case XML_DOCUMENT_NODE:
                    801:  case XML_DOCUMENT_TYPE_NODE:
                    802:  case XML_DOCUMENT_FRAG_NODE:
                    803:   case XML_NOTATION_NODE:
                    804:   case XML_DTD_NODE:
                    805:   case XML_NAMESPACE_DECL:
                    806:    break;
                    807:  default:
                    808:    g_warning ("could not recognize the Node Type.");
                    809:   }
                    810: }
                    811: 
                    812: /**
                    813:  * gdome_xml_n_set_prefix:
                    814:  * @self:  Node Object ref
                    815:  * @prefix:  The new prefix for this node.
                    816:  * @exc:  Exception Object ref
                    817:  *
                    818:  * Sets a new nemaspace prefix for this node.
                    819:  *
                    820:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
                    821:  * %GDOME_NAMESPACE_ERR: Raised if the specified @prefix is malformed per the
                    822:  * Namespaces in XML specification, if the namespaceURI of this node is %NULL,
                    823:  * if the specified prefix is "xml" and the namespaceURI of this node is
                    824:  * different from "http://www.w3.org/XML/1998/namespace", if this node is an
                    825:  * attribute and the specified prefix is "xmlns" and the namespaceURI of this
                    826:  * node is different from "http://www.w3.org/2000/xmlns/", or if this node is
                    827:  * an attribute and the qualifiedName of this node is "xmlns".
                    828:  */
                    829: void
                    830: gdome_xml_n_set_prefix (GdomeNode *self, GdomeDOMString *prefix, GdomeException *exc)
                    831: {
                    832:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    833:  xmlNs *ns;
                    834: 
                    835:  g_return_if_fail (priv != NULL);
                    836:  g_return_if_fail (GDOME_XML_IS_N (priv));
                    837:  g_return_if_fail (prefix != NULL);
                    838:  g_return_if_fail (exc != NULL);
                    839: 
                    840:   if (GDOME_ISREADONLY (priv)) {
                    841:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
                    842:     return;
                    843:   }
                    844: 
                    845:   if((gdome_xmlGetType(priv->n) == XML_ELEMENT_NODE ||
                    846:      gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE) &&
                    847:     gdome_xmlGetNs(priv->n) != NULL &&
                    848:      !xmlStrEqual(gdome_xmlGetNsPrefix (priv->n), (xmlChar *)prefix->str)) {
                    849: 
                    850:    /* tests for NAMESPACE_ERR */
                    851:     gchar *nsURI = (gchar *)gdome_xmlGetNsURI (priv->n);
                    852:    if (nsURI == NULL ||
                    853:        (!strcmp (prefix->str, "xml") &&
                    854:         strcmp (nsURI, "http://www.w3.org/XML/1998/namespace")) ||
                    855:        (gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE &&
                    856:         !strcmp (prefix->str, "xmlns") &&
                    857:         strcmp (nsURI, GDOME_XMLNS_NAMESPACE)) ||
                    858:        (gdome_xmlGetType(priv->n) == XML_ATTRIBUTE_NODE &&
                    859:         !strcmp (gdome_xmlGetName(priv->n), "xmlns"))) {
                    860:      *exc = GDOME_NAMESPACE_ERR;
                    861:      return;
                    862:    }
                    863:    ns = gdome_xmlNewNs (priv->n->doc, gdome_xmlGetNsURI (priv->n), (xmlChar *)prefix->str);
                    864:    gdome_xmlSetNs(priv->n, ns);
                    865:  }
                    866: }
                    867: 
                    868: /**************************************
                    869:  ******* Methods implementation *******
                    870:  **************************************/
                    871: 
                    872: /**
                    873:  * gdome_xml_n_appendChild:
                    874:  * @self:  Node Object ref
                    875:  * @newChild:  The node to add
                    876:  * @exc:  Exception Object ref
                    877:  *
                    878:  * Adds the node @newChild to the end of the list of children of this node.
                    879:  * If the @newChild is already in the tree, it is first removed. If it is a
                    880:  * DocumentFragment node, the entire contents of the document fragment are
                    881:  * moved into the child list of this node
                    882:  *
                    883:  * %GDOME_HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
                    884:  * allow children of the type of the @newChild node, or if the node to append is
                    885:  * one of this node's ancestors or this node itself.
                    886:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newChild was created from a different
                    887:  * document than the one that created this node.
                    888:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
                    889:  * Returns: the node added.
                    890:  */
                    891: GdomeNode *
                    892: gdome_xml_n_appendChild (GdomeNode *self, GdomeNode *newChild, GdomeException *exc)
                    893: {
                    894:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    895:  Gdome_xml_Node *new_priv = (Gdome_xml_Node *)newChild;
                    896:  GdomeMutationEvent *mev;
                    897:  xmlNode *ret;
                    898: 
                    899:  g_return_val_if_fail (priv != NULL, NULL);
                    900:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    901:  g_return_val_if_fail (new_priv != NULL, NULL);
                    902:  g_return_val_if_fail (GDOME_XML_IS_N (new_priv), NULL);
                    903:  g_return_val_if_fail (exc != NULL, NULL);
                    904: 
                    905:  if (!gdome_xml_n_canAppend (self, newChild, exc)) {
                    906:    *exc = GDOME_HIERARCHY_REQUEST_ERR;
                    907:    return NULL;
                    908:  }
                    909: 
                    910:  if (gdome_xmlGetOwner(new_priv->n) != gdome_xmlGetOwner(priv->n)) {
                    911:    *exc = GDOME_WRONG_DOCUMENT_ERR;
                    912:    return NULL;
                    913:  }
                    914: 
                    915:  if (GDOME_ISREADONLY (priv)) {
                    916:    *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
                    917:    return NULL;
                    918:  }
                    919: 
                    920:  /* If the newChild is already in the tree, it is first removed. */
                    921:  if (gdome_xmlGetParent(new_priv->n) != NULL)
                    922:    gdome_xmlUnlinkChild(gdome_xmlGetParent(new_priv->n), new_priv->n);
                    923: 
                    924:  ret = gdome_xmlAppendChild(priv->n, new_priv->n);
                    925: 
                    926:  /* Delete children list for DocumentFragment Node */
                    927:  if (gdome_xmlGetType (new_priv->n) == XML_DOCUMENT_FRAG_NODE) {
                    928:    gdome_xmlSetFirstChild(new_priv->n, NULL);
                    929:    gdome_xmlSetLastChild(new_priv->n, NULL);
                    930:  }
                    931: 
                    932:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_EVENT_TYPE)) {
                    933:    /* Fire DOMNodeInserted */
                    934:    mev = gdome_evt_mevnt_mkref ();
                    935:    gdome_xml_n_ref (self, exc);
                    936:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_EVENT_TYPE,
                    937:                                             TRUE, FALSE, self,
                    938:                                             NULL, NULL, NULL, 0, exc);
                    939:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
                    940:    gdome_xml_n_unref (self, exc);
                    941:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                    942:  }
                    943: 
                    944:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE)) {
                    945:    /* Fire DOMNodeInsertedIntoDocument */
                    946:    mev = gdome_evt_mevnt_mkref ();
                    947:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE,
                    948:                                             FALSE, FALSE, NULL,
                    949:                                             NULL, NULL, NULL, 0, exc);
                    950:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
                    951:    gdome_xml_n_subTreeDispatchEvent (newChild, (GdomeEvent *)mev, exc);
                    952:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                    953:  }
                    954:  
                    955:  if (gdome_xml_n_eventEnabledByCode (self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
                    956:    /* Fire DOMSubtreeModified */
                    957:    mev = gdome_evt_mevnt_mkref ();
                    958:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
                    959:                                             TRUE, FALSE, NULL,
                    960:                                             NULL, NULL, NULL, 0, exc);
                    961:    gdome_xml_n_dispatchEvent (self, (GdomeEvent *)mev, exc);
                    962:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                    963:  }
                    964:  
                    965:  return gdome_xml_n_mkref (ret);
                    966: }
                    967: 
                    968: /**
                    969:  * gdome_xml_n_cloneNode:
                    970:  * @self:  Node Object ref
                    971:  * @deep:  If true, recursively clone the subtree under the specified node;
                    972:  *         if false, clone only the node itself (and its attributes, if it is
                    973:  *         an Element).
                    974:  * @exc:  Exception Object ref
                    975:  *
                    976:  * Makes a duplicate of this node, i.e., serves as a generic copy
                    977:  * constructor for nodes. The duplicate node has no parent; (parentNode is
                    978:  * %NULL).
                    979:  * %GDOME_DOCUMENT_TYPE_NODE, %GDOME_NOTATION_NODE and %GDOME_ENTITY_NODE
                    980:  * nodes are not supported.
                    981:  *
                    982:  * %GDOME_NOT_SUPPORTED_ERR: Raised if the type of node being cloned is not
                    983:  * supported.
                    984:  * Returns: the duplicate node.
                    985:  */
                    986: GdomeNode *
                    987: gdome_xml_n_cloneNode (GdomeNode *self, GdomeBoolean deep, GdomeException *exc)
                    988: {
                    989:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                    990:   xmlNode *n = NULL;
                    991:   xmlElementType type;
                    992: 
                    993:  g_return_val_if_fail (priv != NULL, NULL);
                    994:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                    995:  g_return_val_if_fail (exc != NULL, NULL);
                    996: 
                    997:   type = gdome_xmlGetType (priv->n);
                    998:   if (type == XML_ENTITY_NODE ||
                    999:       type == XML_ENTITY_DECL ||
                   1000:      type == XML_NOTATION_NODE ||
                   1001:      type == XML_DOCUMENT_TYPE_NODE ||
                   1002:      type == XML_DTD_NODE ||
                   1003:      type == XML_NAMESPACE_DECL )
                   1004:    *exc = GDOME_NOT_SUPPORTED_ERR;
                   1005:  else if (type == XML_DOCUMENT_NODE)
                   1006:    n = (xmlNode *)xmlCopyDoc ((xmlDoc *)priv->n, deep);
                   1007:  else if (type == XML_ATTRIBUTE_NODE) {
                   1008:    n = (xmlNode *)xmlCopyProp (NULL, (xmlAttr *)priv->n);
                   1009:    if (gdome_xmlGetOwner (n) == NULL)
                   1010:      gdome_xmlSetOwner (n , gdome_xmlGetOwner (priv->n));
                   1011:  }
                   1012:  else
                   1013:    n = xmlDocCopyNode (priv->n, gdome_xmlGetOwner(priv->n), deep);
                   1014: 
                   1015:  if (*exc)
                   1016:    return NULL;
                   1017:   else
                   1018:    return gdome_xml_n_mkref (n);
                   1019: }
                   1020: 
                   1021: /**
                   1022:  * gdome_xml_n_hasAttributes:
                   1023:  * @self:  Node Object ref
                   1024:  * @exc:  Exception Object ref
                   1025:  *
                   1026:  * Returns: %TRUE if this node has any attributes, %FALSE otherwise.
                   1027:  */
                   1028: GdomeBoolean
                   1029: gdome_xml_n_hasAttributes (GdomeNode *self, GdomeException *exc) {
                   1030:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1031: 
                   1032:  g_return_val_if_fail (priv != NULL, 0);
                   1033:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
                   1034:  g_return_val_if_fail (exc != NULL, 0);
                   1035: 
                   1036:  if (GDOME_XML_IS_EL (priv))
                   1037:    return (gdome_xmlGetAttrList (priv->n) != NULL);
                   1038:  else
                   1039:     return FALSE;
                   1040: }
                   1041: 
                   1042: /**
                   1043:  * gdome_xml_n_hasChildNodes:
                   1044:  * @self:  Node Object ref
                   1045:  * @exc:  Exception Object ref
                   1046:  *
                   1047:  * Returns: %TRUE if this node has any children, %FALSE otherwise.
                   1048:  */
                   1049: GdomeBoolean
                   1050: gdome_xml_n_hasChildNodes (GdomeNode *self, GdomeException *exc) {
                   1051:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1052: 
                   1053:  g_return_val_if_fail (priv != NULL, 0);
                   1054:  g_return_val_if_fail (GDOME_XML_IS_N (priv), 0);
                   1055:   g_return_val_if_fail (exc != NULL, 0);
                   1056: 
                   1057:   switch (gdome_xmlGetType (priv->n)) {
                   1058:   case XML_DOCUMENT_TYPE_NODE:
                   1059:   case XML_DTD_NODE:
                   1060:   case XML_PI_NODE:
                   1061:   case XML_COMMENT_NODE:
                   1062:   case XML_TEXT_NODE:
                   1063:   case XML_CDATA_SECTION_NODE:
                   1064:   case XML_NOTATION_NODE:
                   1065:  case XML_NAMESPACE_DECL:
                   1066:     return FALSE;
                   1067:   case XML_DOCUMENT_NODE:
                   1068:   case XML_DOCUMENT_FRAG_NODE:
                   1069:   case XML_ENTITY_REF_NODE:
                   1070:   case XML_ELEMENT_NODE:
                   1071:   case XML_ATTRIBUTE_NODE:
                   1072:   case XML_ENTITY_NODE:
                   1073:   case XML_ENTITY_DECL:
                   1074:    return (gdome_xmlGetFirstChild (priv->n) != NULL);
                   1075:   default:
                   1076:     g_warning ("gdome_xml_n_hasChildNodes: invalid node type");
                   1077:     return FALSE;
                   1078:   }
                   1079: }
                   1080: 
                   1081: /**
                   1082:  * gdome_xml_n_insertBefore:
                   1083:  * @self:  Node Object ref
                   1084:  * @newChild:  The new node to put in the child list
                   1085:  * @refChild:  the reference node, i.e., the node before which the new node
                   1086:  *             must be inserted.
                   1087:  * @exc:  Exception Object ref
                   1088:  *
                   1089:  * Inserts the node @newChild before the existing child node @refChild. If
                   1090:  * @refChild is %NULL, insert @newChild at the end of the list of children.
                   1091:  * If @newChild is a DocumentFragment node, all of its children are inserted,
                   1092:  * in the same order, before @refChild. If the @newChild is already in the
                   1093:  * tree, it is first removed.
                   1094:  *
                   1095:  * %GDOME_HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
                   1096:  * allow children of the type of the @newChild node, or if the node to insert is
                   1097:  * one of this node's ancestors or this node itself.
                   1098:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newChild was created from a different
                   1099:  * document than the one that created this node.
                   1100:  * %GDOME_NOT_FOUND_ERR: Raised if @refChild is not a child of this node.
                   1101:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
                   1102:  * Returns: the node being inserted.
                   1103:  */
                   1104: GdomeNode *
                   1105: gdome_xml_n_insertBefore (GdomeNode *self, GdomeNode *newChild, GdomeNode *refChild, GdomeException *exc)
                   1106: {
                   1107:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1108:  Gdome_xml_Node *new_priv = (Gdome_xml_Node *)newChild;
                   1109:  Gdome_xml_Node *ref_priv = (Gdome_xml_Node *)refChild;
                   1110:  GdomeMutationEvent *mev;
                   1111:  xmlNode *ret = NULL;
                   1112: 
                   1113:  g_return_val_if_fail (priv != NULL, NULL);
                   1114:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                   1115:  g_return_val_if_fail (new_priv != NULL, NULL);
                   1116:  g_return_val_if_fail (GDOME_XML_IS_N (new_priv), NULL);
                   1117:  g_return_val_if_fail (exc != NULL, NULL);
                   1118: 
                   1119:  if (!gdome_xml_n_canAppend (self, newChild, exc)) {
                   1120:    *exc = GDOME_HIERARCHY_REQUEST_ERR;
                   1121:    return NULL;
                   1122:  }
                   1123: 
                   1124:  if (gdome_xmlGetOwner(new_priv->n) != gdome_xmlGetOwner(priv->n)) {
                   1125:    *exc = GDOME_WRONG_DOCUMENT_ERR;
                   1126:    return NULL;
                   1127:  }
                   1128: 
                   1129:   if (GDOME_ISREADONLY (priv)) {
                   1130:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
                   1131:     return NULL;
                   1132:   }
                   1133: 
                   1134:   /* If refChild is null, insert newChild at the end of the list of children.*/
                   1135:  if(ref_priv == NULL)
                   1136:    return gdome_xml_n_appendChild (self, newChild, exc);
                   1137:  else
                   1138:    g_return_val_if_fail (GDOME_XML_IS_N (ref_priv), NULL);
                   1139: 
                   1140:  /* If the newChild is already in the tree, it is first removed. */
                   1141:   if (gdome_xmlGetParent(new_priv->n) != NULL) {
                   1142:    if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_EVENT_TYPE)) {
                   1143:      /* Fire DOMNodeRemoved */
                   1144:      mev = gdome_evt_mevnt_mkref ();
                   1145:      gdome_xml_n_ref (self, exc);
                   1146:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_EVENT_TYPE,
                   1147:                                               TRUE, FALSE, self,
                   1148:                                               NULL, NULL, NULL, 0, exc);
                   1149:      gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
                   1150:      gdome_xml_n_unref (self, exc);
                   1151:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1152:    }
                   1153: 
                   1154:    if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE)) {
                   1155:      /* Fire DOMNodeRemovedFromDocument */
                   1156:      mev = gdome_evt_mevnt_mkref ();
                   1157:      gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE,
                   1158:                                               FALSE, FALSE, NULL,
                   1159:                                               NULL, NULL, NULL, 0, exc);
                   1160:      gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
                   1161:      gdome_xml_n_subTreeDispatchEvent (newChild, (GdomeEvent *)mev, exc);
                   1162:      gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1163:    }
                   1164: 
                   1165:     gdome_xmlUnlinkChild(gdome_xmlGetParent(new_priv->n), new_priv->n);
                   1166:   }
                   1167: 
                   1168:  if ((ret = gdome_xmlInsertBeforeChild(priv->n, new_priv->n, ref_priv->n)) == NULL) {
                   1169:    *exc = GDOME_NOT_FOUND_ERR;
                   1170:    return NULL;
                   1171:   }
                   1172: 
                   1173:   /* Unlink children list for DocumentFragment Node */
                   1174:   if (gdome_xmlGetType (new_priv->n) == XML_DOCUMENT_FRAG_NODE) {
                   1175:     gdome_xmlSetFirstChild(new_priv->n, NULL);
                   1176:     gdome_xmlSetLastChild(new_priv->n, NULL);
                   1177:   }
                   1178: 
                   1179:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_EVENT_TYPE)) {
                   1180:    /* Fire DOMNodeInserted */
                   1181:    mev = gdome_evt_mevnt_mkref ();
                   1182:    gdome_xml_n_ref (self, exc);
                   1183:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_EVENT_TYPE,
                   1184:                                             TRUE, FALSE, self,
                   1185:                                             NULL, NULL, NULL, 0, exc);
                   1186:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
                   1187:    gdome_xml_n_unref (self, exc);
                   1188:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1189:  }
                   1190: 
                   1191:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE)) {
                   1192:    /* Fire DOMNodeInsertedIntoDocument */
                   1193:    mev = gdome_evt_mevnt_mkref ();
                   1194:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_INSERTED_INTO_DOCUMENT_EVENT_TYPE,
                   1195:                                             FALSE, FALSE, NULL,
                   1196:                                             NULL, NULL, NULL, 0, exc);
                   1197:    gdome_xml_n_dispatchEvent (newChild, (GdomeEvent *)mev, exc);
                   1198:    gdome_xml_n_subTreeDispatchEvent (newChild, (GdomeEvent *)mev, exc);
                   1199:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1200:  }
                   1201:  
                   1202:  if (gdome_xml_n_eventEnabledByCode (self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
                   1203:    /* Fire DOMSubtreeModified */
                   1204:    mev = gdome_evt_mevnt_mkref ();
                   1205:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
                   1206:                                             TRUE, FALSE, NULL,
                   1207:                                             NULL, NULL, NULL, 0, exc);
                   1208:    gdome_xml_n_dispatchEvent (self, (GdomeEvent *)mev, exc);
                   1209:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1210:  }
                   1211: 
                   1212:  return gdome_xml_n_mkref (ret);
                   1213: }
                   1214: 
                   1215: /**
                   1216:  * gdome_xml_n_isSupported:
                   1217:  * @self:  Node Object ref
                   1218:  * @feature:  The name of the feature to test.
                   1219:  * @version:  This is the version number of the feature to test. In Level 2,
                   1220:  *            version 1, this is the string "2.0". If the version is not
                   1221:  *            specified, supporting any version of the feature will cause the
                   1222:  *            method to return %TRUE.
                   1223:  * @exc:  Exception Object ref
                   1224:  *
                   1225:  * Tests whether the DOM implementation implements a specific feature and that
                   1226:  * feature is supported by this node.
                   1227:  * Returns: %TRUE if the specified feature is supported on this node, %FALSE
                   1228:  * otherwise.
                   1229:  */
                   1230: GdomeBoolean
                   1231: gdome_xml_n_isSupported (GdomeNode *self, GdomeDOMString *feature, GdomeDOMString *version, GdomeException *exc)
                   1232: {
                   1233:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1234:  GdomeBoolean ret;
                   1235:   GdomeDOMImplementation *domimpl;
                   1236: 
                   1237:  g_return_val_if_fail (priv != NULL, FALSE);
                   1238:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
                   1239:  g_return_val_if_fail (feature != NULL, FALSE);
                   1240:  g_return_val_if_fail (exc != NULL, FALSE);
                   1241: 
                   1242:  if (version == NULL)
                   1243:    return TRUE;
                   1244: 
                   1245:  domimpl = gdome_xml_di_mkref();
                   1246:  ret = gdome_xml_di_hasFeature (domimpl, feature, version, exc);
                   1247:  gdome_xml_di_unref (domimpl, exc);
                   1248: 
                   1249:   return ret;
                   1250: }
                   1251: 
                   1252: /**
                   1253:  * gdome_xml_n_normalize:
                   1254:  * @self:  Node Object ref
                   1255:  * @exc:  Exception Object ref
                   1256:  *
                   1257:  * Puts all Text nodes in the full depth of the sub-tree underneath this Node,
                   1258:  * including attribute nodes, into a "normal" form where only structure (e.g.,
                   1259:  * elements, comments, processing instructions, CDATA sections, and entity
                   1260:  * references) separates Text nodes, i.e., there are neither adjacent Text
                   1261:  * nodes nor empty Text nodes.
                   1262:  */
                   1263: void
                   1264: gdome_xml_n_normalize (GdomeNode *self, GdomeException *exc)
                   1265: {
                   1266:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1267:  GdomeNode *child = NULL, *new_child = NULL;
                   1268:  GdomeNode *next = NULL, *new_next = NULL;
                   1269:  GdomeDOMString *str = NULL;
                   1270:  GdomeNode *result = NULL;
                   1271: 
                   1272:  g_return_if_fail (priv != NULL);
                   1273:  g_return_if_fail (GDOME_XML_IS_N (priv));
                   1274:  g_return_if_fail (exc != NULL);
                   1275: 
                   1276:  /* this is a generic implementation, not optimized for speed */
                   1277:  child = gdome_n_firstChild (self, exc);
                   1278:  while (child != NULL) {
                   1279:    unsigned short type;
                   1280: 
                   1281:    type = gdome_n_nodeType (child, exc);
                   1282:    if (type == GDOME_TEXT_NODE) {
                   1283:      next = gdome_n_nextSibling (child, exc);
                   1284:      while (next != NULL) {
                   1285:        if (gdome_n_nodeType (next, exc) != GDOME_TEXT_NODE) {
                   1286:          gdome_n_unref (next, exc);
                   1287:          break;
                   1288:        }
                   1289:        str = gdome_cd_data ((GdomeCharacterData *)next, exc);
                   1290:        gdome_cd_appendData ((GdomeCharacterData *)child, str, exc);
                   1291:        gdome_str_unref (str);
                   1292:        new_next = gdome_n_nextSibling (next, exc);
                   1293:        result = gdome_n_removeChild (self, next, exc);
                   1294:        gdome_n_unref (result, exc);
                   1295:        gdome_n_unref (next, exc);
                   1296:        next = new_next;
                   1297:      }
                   1298:    } else if (type == GDOME_ELEMENT_NODE) {
                   1299:      GdomeNamedNodeMap *nnm;
                   1300:      gulong i, n;
                   1301: 
                   1302:      gdome_n_normalize (child, exc);
                   1303:      nnm = gdome_n_attributes (child, exc);
                   1304:      n = gdome_nnm_length (nnm, exc);
                   1305:      for (i = 0; i < n; i++) {
                   1306:        GdomeNode *attr;
                   1307: 
                   1308:        attr = gdome_nnm_item (nnm, i, exc);
                   1309:        gdome_n_normalize (attr, exc);
                   1310:        gdome_n_unref (attr, exc);
                   1311:      }
                   1312:      gdome_nnm_unref (nnm, exc);
                   1313:    }
                   1314:    new_child = gdome_n_nextSibling (child, exc);
                   1315:    gdome_n_unref (child, exc);
                   1316:    child = new_child;
                   1317:  }
                   1318: }
                   1319: 
                   1320: /**
                   1321:  * gdome_xml_n_removeChild:
                   1322:  * @self:  Node Object ref
                   1323:  * @oldChild:  The node being removed
                   1324:  * @exc:  Exception Object ref
                   1325:  *
                   1326:  * Removes the child node indicated by @oldChild from the list of children, and
                   1327:  * returns it.
                   1328:  *
                   1329:  * %GDOME_NOT_FOUND_ERR: Raised if @oldChild is not a child of this node.
                   1330:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
                   1331:  * Returns: the node removed.
                   1332:  */
                   1333: GdomeNode *
                   1334: gdome_xml_n_removeChild (GdomeNode *self, GdomeNode *oldChild, GdomeException *exc)
                   1335: {
                   1336:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1337:  Gdome_xml_Node *old_priv = (Gdome_xml_Node *)oldChild;
                   1338:  GdomeMutationEvent *mev;
                   1339:  xmlNode *ret;
                   1340: 
                   1341:  g_return_val_if_fail (priv != NULL, NULL);
                   1342:  g_return_val_if_fail (GDOME_XML_IS_N (priv), NULL);
                   1343:  g_return_val_if_fail (old_priv != NULL, NULL);
                   1344:  g_return_val_if_fail (GDOME_XML_IS_TREE_N (old_priv), NULL);
                   1345:  g_return_val_if_fail (exc != NULL, NULL);
                   1346: 
                   1347:   if (GDOME_ISREADONLY (priv)) {
                   1348:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
                   1349:     return NULL;
                   1350:   }
                   1351: 
                   1352:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_EVENT_TYPE)) {
                   1353:    /* Fire DOMNodeRemoved */
                   1354:    mev = gdome_evt_mevnt_mkref ();
                   1355:    gdome_xml_n_ref (self, exc);
                   1356:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_EVENT_TYPE,
                   1357:                                             TRUE, FALSE, self,
                   1358:                                             NULL, NULL, NULL, 0, exc);
                   1359:    gdome_xml_n_dispatchEvent (oldChild, (GdomeEvent *)mev, exc);
                   1360:    gdome_xml_n_unref (self, exc);
                   1361:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1362:  }
                   1363: 
                   1364:  if (gdome_xml_n_eventEnabledByCode (self, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE)) {
                   1365:    /* Fire DOMNodeRemovedFromDocument */
                   1366:    mev = gdome_evt_mevnt_mkref ();
                   1367:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_NODE_REMOVED_FROM_DOCUMENT_EVENT_TYPE,
                   1368:                                             FALSE, FALSE, NULL,
                   1369:                                             NULL, NULL, NULL, 0, exc);
                   1370:    gdome_xml_n_dispatchEvent (oldChild, (GdomeEvent *)mev, exc);
                   1371:    gdome_xml_n_subTreeDispatchEvent (oldChild, (GdomeEvent *)mev, exc);
                   1372:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1373:  }
                   1374: 
                   1375:  if (gdome_xml_n_eventEnabledByCode (self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
                   1376:    /* Fire DOMSubtreeModified */
                   1377:    mev = gdome_evt_mevnt_mkref ();
                   1378:    gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
                   1379:                                             TRUE, FALSE, NULL,
                   1380:                                             NULL, NULL, NULL, 0, exc);
                   1381:    gdome_xml_n_dispatchEvent (self, (GdomeEvent *)mev, exc);
                   1382:    gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
                   1383:  }
                   1384: 
                   1385:   if ((ret = gdome_xmlUnlinkChild(priv->n, old_priv->n)) == NULL) {
                   1386:    *exc = GDOME_NOT_FOUND_ERR;
                   1387:    return NULL;
                   1388:   }
                   1389: 
                   1390:   return gdome_xml_n_mkref (ret);
                   1391: }
                   1392: 
                   1393: /**
                   1394:  * gdome_xml_n_replaceChild:
                   1395:  * @self:  Node Object ref
                   1396:  * @newChild:  The new node to put in the child list
                   1397:  * @oldChild:  The node being replaced in the list
                   1398:  * @exc:  Exception Object ref
                   1399:  *
                   1400:  * Replaces the child node @oldChild with @newChild in the list of children,
                   1401:  * and returns the @oldChild node. If @newChild is a DocumentFragment object,
                   1402:  * @oldChild is replaced by all of the DocumentFragment children, which are
                   1403:  * inserted in the same order. If the @newChild is already in the tree, it is
                   1404:  * first removed.
                   1405:  *
                   1406:  * %GDOME_HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does
                   1407:  * not allow children of the type of the @newChild node, or if the node to put
                   1408:  * in is one of this node's ancestors or this node itself.
                   1409:  * %GDOME_WRONG_DOCUMENT_ERR: Raised if @newChild was created from a different
                   1410:  * document than the one that created this node.
                   1411:  * %GDOME_NOT_FOUND_ERR: Raised if @oldChild is not a child of this node.
                   1412:  * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
                   1413:  * Returns: the node replaced.
                   1414:  */
                   1415: GdomeNode *
                   1416: gdome_xml_n_replaceChild (GdomeNode *self, GdomeNode *newChild, GdomeNode *oldChild, GdomeException *exc)
                   1417: {
                   1418:  GdomeNode *ret = NULL;
                   1419:  GdomeNode *refChild = NULL;
                   1420: 
                   1421:  g_return_val_if_fail (self != NULL, NULL);
                   1422:  g_return_val_if_fail (GDOME_XML_IS_N (self), NULL);
                   1423:  g_return_val_if_fail (newChild != NULL, NULL);
                   1424:  g_return_val_if_fail (GDOME_XML_IS_N (newChild), NULL);
                   1425:  g_return_val_if_fail (oldChild != NULL, NULL);
                   1426:  g_return_val_if_fail (GDOME_XML_IS_N (oldChild), NULL);
                   1427:  g_return_val_if_fail (exc != NULL, NULL);
                   1428: 
                   1429:   if (GDOME_ISREADONLY (self)) {
                   1430:     *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
                   1431:     return NULL;
                   1432:   }
                   1433: 
                   1434:   refChild = gdome_n_nextSibling (oldChild, exc);
                   1435:  if (gdome_n_removeChild (self, oldChild, exc)) {
                   1436:    if (gdome_n_insertBefore (self, newChild, refChild, exc)) {
                   1437:      gdome_n_unref (newChild, exc);
                   1438:       ret = oldChild;
                   1439:    } else {
                   1440:      gdome_n_unref (oldChild, exc);
                   1441:      ret = NULL;
                   1442:    }
                   1443:  }
                   1444: 
                   1445:  if (refChild)
                   1446:    gdome_n_unref (refChild, exc);
                   1447: 
                   1448:   return ret;
                   1449: }
                   1450: 
                   1451: /**
                   1452:  * gdome_xml_n_addEventListener:
                   1453:  * @self:  Node Object ref
                   1454:  * @type:  the event type for which the user is registering
                   1455:  * @listener:  the listener parameter takes an interface implemented by the
                   1456:  *             user which contains the methods to be called when the event occurs.
                   1457:  * @useCapture:  if %TRUE, useCapture indicates that the user wishes to initiate
                   1458:  *               capture. After initiating capture, all events of the specified
                   1459:  *               type will be dispatched to the registered EventListener before
                   1460:  *               being dispatched to any EventTargets beneath them in the tree.
                   1461:  *               Events which are bubbling upward through the tree will not
                   1462:  *               trigger an EventListener designated to use capture.
                   1463:  * @exc:  Exception Object ref
                   1464:  *
                   1465:  * This method allows the registration of event listeners on the event target.
                   1466:  * If an EventListener is added to an EventTarget while it is processing an
                   1467:  * event, it will not be triggered by the current actions but may be triggered
                   1468:  * during a later stage of event flow, such as the bubbling phase.
                   1469:  * If multiple identical EventListeners are registered on the same EventTarget
                   1470:  * with the same parameters the duplicate instances are discarded. They do not
                   1471:  * cause the EventListener to be called twice and since they are discarded
                   1472:  * they do not need to be removed with the removeEventListener method.
                   1473:  */
                   1474: void
                   1475: gdome_xml_n_addEventListener (GdomeNode *self, GdomeDOMString *type,
                   1476:                               GdomeEventListener *listener, GdomeBoolean useCapture,
                   1477:                               GdomeException *exc)
                   1478: {
                   1479:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1480:  Gdome_xml_ListenerList *ll = NULL;
                   1481:  Gdome_xml_ListenerList *temp;
                   1482:   guint32 codeType;
                   1483: 
                   1484:  g_return_if_fail (priv != NULL);
                   1485:  g_return_if_fail (GDOME_XML_IS_N (priv));
                   1486:  g_return_if_fail (listener != NULL);
                   1487:  g_return_if_fail (type != NULL);
                   1488:  g_return_if_fail (exc != NULL);
                   1489: 
                   1490:  /* duplicate instances are discarted */
                   1491:   codeType = gdome_evt_evnt_codeOfName (type->str);
                   1492:  temp = priv->ll;
                   1493:  while (temp) {
                   1494:    if (temp->listener == listener &&
                   1495:        temp->type == codeType &&
                   1496:        temp->useCapture == useCapture) {
                   1497:      return;
                   1498:    }
                   1499:    temp = temp->next;
                   1500:  }
                   1501: 
                   1502:  /* create a new ListenerList entry*/
                   1503:  ll = g_new (Gdome_xml_ListenerList, 1);
                   1504:  ll->type = codeType;
                   1505:  gdome_evt_evntl_ref (listener, exc);
                   1506:  ll->listener = listener;
                   1507:  ll->useCapture = useCapture;
                   1508: 
                   1509:  /* add it at begin of the ListenerList of the target */
                   1510:  ll->next = priv->ll;
                   1511:  priv->ll = ll;
                   1512: }
                   1513: 
                   1514: /**
                   1515:  * gdome_xml_n_removeEventListener:
                   1516:  * @self:  Node Object ref
                   1517:  * @type:  Specifies the event type of the EventListener being removed.
                   1518:  * @listener:  The EventListener parameter indicates the EventListener to be
                   1519:  *             removed.
                   1520:  * @useCapture:  Specifies whether the EventListener being removed was
                   1521:  *               registered as a capturing listener or not. If a listener was
                   1522:  *               registered twice, one with capture and one without, each must
                   1523:  *               be removed separately. Removal of a capturing listener does
                   1524:  *               not affect a non-capturing version of the same listener, and
                   1525:  *               vice versa.
                   1526:  * @exc:  Exception Object ref
                   1527:  *
                   1528:  * This method allows the removal of event listeners from the event target. If
                   1529:  * an EventListener is removed from an EventTarget while it is processing an
                   1530:  * event, it will not be triggered by the current actions. EventListeners can
                   1531:  * never be invoked after being removed. Calling removeEventListener with
                   1532:  * arguments which do not identify any currently registered EventListener on
                   1533:  * the EventTarget has no effect.
                   1534:  */
                   1535: void
                   1536: gdome_xml_n_removeEventListener (GdomeNode *self, GdomeDOMString *type, 
                   1537:                                 GdomeEventListener *listener, GdomeBoolean useCapture, 
                   1538:                                 GdomeException *exc)
                   1539: {
                   1540:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1541:   Gdome_xml_ListenerList *temp, *prev = NULL;
                   1542:   guint32 codeType;
                   1543: 
                   1544:  g_return_if_fail (priv != NULL);
                   1545:  g_return_if_fail (GDOME_XML_IS_N (priv));
                   1546:  g_return_if_fail (listener != NULL);
                   1547:  g_return_if_fail (type != NULL);
                   1548:  g_return_if_fail (exc != NULL);
                   1549: 
                   1550:   codeType = gdome_evt_evnt_codeOfName (type->str);
                   1551:   temp = priv->ll;
                   1552:  while (temp) {
                   1553:     if (useCapture == temp->useCapture &&
                   1554:         temp->listener == listener &&
                   1555:         temp->type == codeType) {
                   1556:         if (prev)
                   1557:           prev->next = temp->next;
                   1558:         else {
                   1559:           g_assert (priv->ll == temp);
                   1560:           priv->ll = priv->ll->next;
                   1561:         }
                   1562:         temp->next = NULL;
                   1563:         gdome_evt_evntl_unref (listener, exc);
                   1564:         g_free (temp);
                   1565:         break;
                   1566:     }
                   1567:     prev = temp;
                   1568:    temp = temp->next;
                   1569:  }
                   1570: }
                   1571: 
                   1572: 
                   1573: /**
                   1574:  * gdome_xml_n_dispatchEvent:
                   1575:  * @self:  Node Object ref
                   1576:  * @evt:  Specifies the event type, behavior, and contextual information to be
                   1577:  *        used in processing the event.
                   1578:  * @exc:  Exception Object ref
                   1579:  *
                   1580:  * This method allows the dispatch of events into the implementations event
                   1581:  * model. Events dispatched in this manner will have the same capturing and
                   1582:  * bubbling behavior as events dispatched directly by the implementation. The
                   1583:  * target of the event is the EventTarget on which dispatchEvent is called.
                   1584:  *
                   1585:  * GDOME_UNSPECIFIED_EVENT_TYPE_ERR: Raised if the Event's type was not
                   1586:  * specified by initializing the event before dispatchEvent was called.
                   1587:  * Specification of the Event's type as %NULL or an empty string will also
                   1588:  * trigger this exception.
                   1589:  * Returns: if preventDefault was called the value is %FALSE, else the value
                   1590:  *          is %TRUE.
                   1591:  */
                   1592: GdomeBoolean
                   1593: gdome_xml_n_dispatchEvent (GdomeNode *self, GdomeEvent *evt, GdomeException *exc)
                   1594: {
                   1595:   Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1596:   Gdome_evt_Event *ev_priv = (Gdome_evt_Event *)evt;
                   1597: 
                   1598:  g_return_val_if_fail (priv != NULL, FALSE);
                   1599:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
                   1600:  g_return_val_if_fail (evt != NULL, FALSE);
                   1601:   g_return_val_if_fail (exc != NULL, FALSE);
                   1602: 
                   1603:   if (ev_priv->type == 0) {
                   1604:     *exc = GDOME_EVENT_EXCEPTION + GDOME_UNSPECIFIED_EVENT_TYPE_ERR;
                   1605:     return FALSE;
                   1606:   }
                   1607: 
                   1608:   gdome_xml_n_ref (self, exc);
                   1609:  ev_priv->target = self;
                   1610:   gdome_evt_fireEvent (evt);
                   1611:   gdome_xml_n_unref (self, exc);
                   1612:  
                   1613:  return !ev_priv->default_prevented;
                   1614: }
                   1615: 
                   1616: /**
                   1617:  * gdome_xml_n_subTreeDispatchEvent:
                   1618:  * @self:  Node Object ref
                   1619:  * @evt:  Specifies the event type, behavior, and contextual information to be
                   1620:  *        used in processing the event.
                   1621:  * @exc:  Exception Object ref
                   1622:  *
                   1623:  * This method allows the dispatch of events into the implementations event
                   1624:  * model. Events dispatched in this manner will have the same capturing and
                   1625:  * bubbling behavior as events dispatched directly by the implementation. The
                   1626:  * target of the event is any nodes in the subtree of the EventTarget on which
                   1627:  * dispatchEvent is called.
                   1628:  *
                   1629:  * GDOME_UNSPECIFIED_EVENT_TYPE_ERR: Raised if the Event's type was not
                   1630:  * specified by initializing the event before dispatchEvent was called.
                   1631:  * Specification of the Event's type as %NULL or an empty string will also
                   1632:  * trigger this exception.
                   1633:  */
                   1634: void
                   1635: gdome_xml_n_subTreeDispatchEvent (GdomeNode *self, GdomeEvent *evt, GdomeException *exc)
                   1636: {
                   1637:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1638:   GdomeNode *child, *temp;
                   1639: 
                   1640:  g_return_if_fail (priv != NULL);
                   1641:  g_return_if_fail (GDOME_XML_IS_N (priv));
                   1642:   g_return_if_fail (evt != NULL);
                   1643:  g_return_if_fail (exc != NULL);
                   1644: 
                   1645:  child = gdome_xml_n_firstChild (self, exc);
                   1646: 
                   1647:  while (child) {
                   1648:    gdome_xml_n_dispatchEvent (child, evt, exc);
                   1649:    gdome_xml_n_subTreeDispatchEvent (child, evt, exc);
                   1650:    temp = gdome_xml_n_nextSibling (child, exc);
                   1651:    gdome_xml_n_unref (child, exc);
                   1652:    child = temp;
                   1653:  }
                   1654: }
                   1655: 
                   1656: /**
                   1657:  * gdome_xml_n_canAppend:
                   1658:  * @self:  Node Object ref
                   1659:  * @newChild:  The Node Object ref of the node to test
                   1660:  * @exc:  Exception Object ref
                   1661:  *
                   1662:  * Tests if a @newChild can be added in the child list of this node.
                   1663:  * Returns: %TRUE if @newChild can be added, %FALSE otherwise.
                   1664:  */
                   1665: GdomeBoolean
                   1666: gdome_xml_n_canAppend (GdomeNode *self, GdomeNode *newChild, GdomeException *exc)
                   1667: {
                   1668:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1669:  Gdome_xml_Node *new_priv = (Gdome_xml_Node *)newChild;
                   1670:  xmlElementType new_type;
                   1671:   GdomeBoolean ret = TRUE;
                   1672: 
                   1673:  g_return_val_if_fail (priv != NULL, FALSE);
                   1674:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
                   1675:  g_return_val_if_fail (new_priv != NULL, FALSE);
                   1676:  g_return_val_if_fail (GDOME_XML_IS_N (new_priv), FALSE);
                   1677:  g_return_val_if_fail (exc != NULL, FALSE);
                   1678: 
                   1679:   /* Check if self can have a child of newChild type */
                   1680:   new_type = gdome_xmlGetType (new_priv->n);
                   1681:   if (new_type == XML_DOCUMENT_FRAG_NODE)
                   1682:    return TRUE;
                   1683:  switch (gdome_xmlGetType (priv->n)) {
                   1684:  case XML_DOCUMENT_TYPE_NODE:
                   1685:   case XML_DTD_NODE:
                   1686:  case XML_PI_NODE:
                   1687:  case XML_COMMENT_NODE:
                   1688:   case XML_TEXT_NODE:
                   1689:   case XML_CDATA_SECTION_NODE:
                   1690:   case XML_NOTATION_NODE:
                   1691:    ret = FALSE;
                   1692:     break;
                   1693:  case XML_DOCUMENT_NODE:
                   1694:     /* Element (max of one), ProcessingInstruction, Comment, DocumentType (max of one) */
                   1695:    if ((new_type != XML_ELEMENT_NODE &&
                   1696:         new_type != XML_PI_NODE &&
                   1697:         new_type != XML_COMMENT_NODE &&
                   1698:         new_type != XML_DTD_NODE &&
                   1699:         new_type != XML_DOCUMENT_TYPE_NODE) ||
                   1700:        (new_type == XML_ELEMENT_NODE &&
                   1701:         xmlDocGetRootElement ((xmlDoc *)priv->n) != NULL) ||
                   1702:        ((new_type == XML_DTD_NODE ||
                   1703:          new_type == XML_DOCUMENT_TYPE_NODE) &&
                   1704:         ((xmlDoc *)priv->n)->intSubset != NULL))
                   1705:      ret = FALSE;
                   1706:     break;
                   1707:   case XML_DOCUMENT_FRAG_NODE:
                   1708:   case XML_ENTITY_REF_NODE:
                   1709:   case XML_ELEMENT_NODE:
                   1710:   case XML_ENTITY_NODE:
                   1711:  case XML_ENTITY_DECL:
                   1712:    /* Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference */
                   1713:    if (new_type != XML_ELEMENT_NODE &&
                   1714:        new_type != XML_PI_NODE &&
                   1715:        new_type != XML_COMMENT_NODE &&
                   1716:        new_type != XML_TEXT_NODE &&
                   1717:        new_type != XML_CDATA_SECTION_NODE &&
                   1718:        new_type != XML_ENTITY_REF_NODE)
                   1719:      ret = FALSE;
                   1720:     break;
                   1721:  case XML_ATTRIBUTE_NODE:
                   1722:     /* Text, EntityReference */
                   1723:    if (new_type != XML_TEXT_NODE &&
                   1724:        new_type != XML_ENTITY_REF_NODE)
                   1725:      ret = FALSE;
                   1726:     break;
                   1727:   default:
                   1728:     g_warning ("gdome_xml_n_canAppend: invalid node type");
                   1729:    ret = FALSE;
                   1730:     break;
                   1731:  }
                   1732: 
                   1733:   /* Check if newChild is an ancestor of self */
                   1734:  if (ret) {
                   1735:    xmlNode *p = priv->n;
                   1736:    while (p != NULL) {
                   1737:      if (p == new_priv->n) {
                   1738:        ret = FALSE;
                   1739:        break;
                   1740:      }
                   1741:      p = gdome_xmlGetParent (p);
                   1742:    }
                   1743:  }
                   1744: 
                   1745:   return ret;
                   1746: }
                   1747: 
                   1748: /**
                   1749:  * gdome_xml_n_eventEnabledByCode:
                   1750:  * @self:  Node Objects ref
                   1751:  * @code:  The event type to check
                   1752:  *
                   1753:  * Returns: TRUE if the specified event type is enabled
                   1754:  */
                   1755: GdomeBoolean
                   1756: gdome_xml_n_eventEnabledByCode (GdomeNode *self, guint32 code)
                   1757: {
                   1758:  Gdome_xml_Node *priv = (Gdome_xml_Node *)self;
                   1759:  GdomeException exc = 0;
                   1760:  GdomeDocument *doc;
                   1761:  GdomeBoolean res;
                   1762: 
                   1763:  g_return_val_if_fail (priv != NULL, FALSE);
                   1764:  g_return_val_if_fail (GDOME_XML_IS_N (priv), FALSE);
                   1765: 
                   1766:   doc = gdome_xml_doc_mkref (gdome_xmlGetOwnerOrSelf (priv->n));
                   1767:  g_assert(doc != NULL);
                   1768: 
                   1769:  res = gdome_xml_doc_eventEnabledByCode (doc, code);
                   1770: 
                   1771:  gdome_doc_unref(doc, &exc);
                   1772:  g_assert(exc == 0);
                   1773: 
                   1774:  return res;
                   1775: }

E-mail: