Annotation of win32/gnome/gdome2-x.x.x/libgdome/gdomecore/gdome-xml-attribute.c, revision 1.1
1.1 ! paf 1: /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
! 2: /* gdome-xml-attribute.c
! 3: *
! 4: * Copyright (C) 1999 Raph Levien <raph@acm.org>
! 5: * Copyright (C) 2000 Mathieu Lacage <mathieu@gnu.org>
! 6: * Copyright (C) 2001 Paolo Casarini <paolo@casarini.org>
! 7: *
! 8: * This library is free software; you can redistribute it and/or
! 9: * modify it under the terms of the GNU Lesser General Public
! 10: * License as published by the Free Software Foundation; either
! 11: * version 2.1 of the License, or (at your option) any later version.
! 12: *
! 13: * This library is distributed in the hope that it will be useful,
! 14: * but WITHOUT ANY WARRANTY; without even the implied warranty of
! 15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
! 16: * Lesser General Public License for more details.
! 17: *
! 18: * You should have received a copy of the GNU Lesser General Public
! 19: * License along with this library; if not, write to the Free Software
! 20: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
! 21: */
! 22:
! 23: #include <string.h>
! 24: #include "gdome.h"
! 25: #include "gdome-events.h"
! 26: #include "gdome-treegc.h"
! 27: #include <libxml/tree.h>
! 28: #include <libxml/parser.h>
! 29: #include <libxml/xmlmemory.h>
! 30: #include "gdome-xml-util.h"
! 31: #include "gdome-xml-str.h"
! 32: #include "gdome-xml-node.h"
! 33: #include "gdome-evt-event.h"
! 34: #include "gdome-evt-mevent.h"
! 35: #include "gdome-xml-attribute.h"
! 36: #include "gdome-xml-xmlutil.h"
! 37: #include "gdome-xml-document.h"
! 38:
! 39: const GdomeAttrVtab gdome_xml_a_vtab = {
! 40: {
! 41: gdome_xml_n_ref,
! 42: gdome_xml_n_unref,
! 43: gdome_xml_a_query_interface,
! 44: gdome_xml_n_nodeName,
! 45: gdome_xml_n_nodeValue,
! 46: gdome_xml_n_set_nodeValue,
! 47: gdome_xml_n_nodeType,
! 48: gdome_xml_n_parentNode,
! 49: gdome_xml_n_childNodes,
! 50: gdome_xml_n_firstChild,
! 51: gdome_xml_n_lastChild,
! 52: gdome_xml_n_previousSibling,
! 53: gdome_xml_n_nextSibling,
! 54: gdome_xml_n_attributes,
! 55: gdome_xml_n_ownerDocument,
! 56: gdome_xml_n_insertBefore,
! 57: gdome_xml_n_replaceChild,
! 58: gdome_xml_n_removeChild,
! 59: gdome_xml_n_appendChild,
! 60: gdome_xml_n_hasChildNodes,
! 61: gdome_xml_n_cloneNode,
! 62: gdome_xml_n_normalize,
! 63: gdome_xml_n_isSupported,
! 64: gdome_xml_n_namespaceURI,
! 65: gdome_xml_n_prefix,
! 66: gdome_xml_n_set_prefix,
! 67: gdome_xml_n_localName,
! 68: gdome_xml_n_hasAttributes,
! 69: gdome_xml_n_addEventListener,
! 70: gdome_xml_n_removeEventListener,
! 71: gdome_xml_n_dispatchEvent,
! 72: gdome_xml_n_subTreeDispatchEvent
! 73: },
! 74: gdome_xml_a_name,
! 75: gdome_xml_a_ownerElement,
! 76: gdome_xml_a_specified,
! 77: gdome_xml_a_value,
! 78: gdome_xml_a_set_value
! 79: };
! 80:
! 81: /**
! 82: * gdome_xml_a_query_interface:
! 83: * @self: Attr Object ref
! 84: * @interface: interface needed
! 85: * @exc: Exception Object ref
! 86: *
! 87: * Returns: a reference to this object that implements the @interface needed,
! 88: * or %NULL if the @interface is not supported by this Object.
! 89: */
! 90: gpointer
! 91: gdome_xml_a_query_interface (GdomeNode *self, const char *interface, GdomeException *exc)
! 92: {
! 93: Gdome_xml_Attr *priv = (Gdome_xml_Attr *)self;
! 94:
! 95: g_return_val_if_fail (priv != NULL, NULL);
! 96: g_return_val_if_fail (GDOME_XML_IS_A (priv), NULL);
! 97: g_return_val_if_fail (interface != NULL, NULL);
! 98: g_return_val_if_fail (exc != NULL, NULL);
! 99:
! 100: if (!strcmp (interface, "Node") ||
! 101: !strcmp (interface, "Attr") ||
! 102: !strcmp (interface, "EventTarget")) {
! 103: priv->refcnt++;
! 104: return self;
! 105: }
! 106: else
! 107: return NULL;
! 108: }
! 109:
! 110: /**
! 111: * gdome_xml_a_mkref_ns
! 112: * @n: The libxml namespace of which a Gdome reference is wanted
! 113: *
! 114: * Constructor of Attribute wrapper to namespace declaration
! 115: * Returns: the reference to the Gdome Attribute node.
! 116: */
! 117: GdomeNode *
! 118: gdome_xml_a_mkref_ns (xmlNode *node, xmlNs *ns) {
! 119: Gdome_xml_Attr *result = NULL;
! 120: xmlAttr *a;
! 121:
! 122: if (ns == NULL)
! 123: return NULL;
! 124:
! 125: if (ns->type == XML_NAMESPACE_DECL) {
! 126: a = gdome_xmlNewNsDecl(node, ns->prefix, ns->href);
! 127: result = g_new (Gdome_xml_Attr, 1);
! 128: result->refcnt = 1;
! 129: result->vtab = &gdome_xml_a_vtab;
! 130: result->super.user_data = NULL;
! 131: result->n = a;
! 132: result->accessType = GDOME_READONLY_NODE;
! 133: result->ll = NULL;
! 134:
! 135: gdome_treegc_addNode ((GdomeNode *)result);
! 136:
! 137: a->_private = result;
! 138:
! 139: } else {
! 140: g_warning ("gdome_xml_a_mkref_ns: invalid node type");
! 141: result = NULL;
! 142: }
! 143:
! 144: return (GdomeNode *)result;
! 145: }
! 146:
! 147: /**
! 148: * gdome_xml_a_unref_ns:
! 149: * @self: Attr Object ref
! 150: * @exc: Exception Object ref
! 151: *
! 152: * Decrease the reference count of an namespace declaration attribute.
! 153: * Free the Node structure if the Node will have zero reference
! 154: */
! 155: void
! 156: gdome_xml_a_unref_ns (GdomeNode *self, GdomeException *exc) {
! 157: Gdome_xml_Attr *priv = (Gdome_xml_Attr *)self;
! 158:
! 159: g_return_if_fail (priv != NULL);
! 160: g_return_if_fail (GDOME_XML_IS_A (priv));
! 161: g_return_if_fail (exc != NULL);
! 162:
! 163: if (priv->refcnt > 0)
! 164: priv->refcnt--;
! 165:
! 166: if (priv->refcnt == 0) {
! 167: gdome_treegc_delNode (self);
! 168: g_free (self);
! 169: }
! 170: }
! 171:
! 172: /**
! 173: * gdome_xml_a_name:
! 174: * @self: Attr Object ref
! 175: * @exc: Exception Object ref
! 176: *
! 177: * Returns: the qualified name of this attribute.
! 178: */
! 179: GdomeDOMString *
! 180: gdome_xml_a_name (GdomeAttr *self, GdomeException *exc) {
! 181: Gdome_xml_Attr *priv = (Gdome_xml_Attr *)self;
! 182: GdomeDOMString *ret = NULL;
! 183:
! 184: g_return_val_if_fail (priv != NULL, NULL);
! 185: g_return_val_if_fail (GDOME_XML_IS_A (priv), NULL);
! 186: g_return_val_if_fail (exc != NULL, NULL);
! 187:
! 188: if(gdome_xmlGetNs((xmlNode *)priv->n) != NULL)
! 189: ret = gdome_xml_str_mkref_own (g_strdup_printf("%s:%s",
! 190: (gchar *) gdome_xmlGetNsPrefix((xmlNode *)priv->n),
! 191: (gchar *) gdome_xmlGetName((xmlNode *)priv->n)));
! 192: else
! 193: ret = gdome_xml_str_mkref_dup((gchar *)gdome_xmlGetName ((xmlNode *)priv->n));
! 194:
! 195: return ret;
! 196: }
! 197:
! 198: /**
! 199: * gdome_xml_a_ownerElement:
! 200: * @self: Attr Object ref
! 201: * @exc: Exception Object ref
! 202: *
! 203: * Returns: the Element node this attribute is attached to or %NULL if this
! 204: * attribute is not in use.
! 205: */
! 206: GdomeElement *
! 207: gdome_xml_a_ownerElement (GdomeAttr *self, GdomeException *exc) {
! 208: Gdome_xml_Attr *priv = (Gdome_xml_Attr *)self;
! 209:
! 210: g_return_val_if_fail (priv != NULL, NULL);
! 211: g_return_val_if_fail (GDOME_XML_IS_A (priv), NULL);
! 212: g_return_val_if_fail (exc != NULL, NULL);
! 213:
! 214: return (GdomeElement *)gdome_xml_n_mkref (gdome_xmlGetParent ((xmlNode *)priv->n));
! 215: }
! 216:
! 217: /**
! 218: * gdome_xml_a_specified:
! 219: * @self: Attr Object ref
! 220: * @exc: Exception Object ref
! 221: *
! 222: * NOT IMPLEMENTED
! 223: * Returns: %TRUE
! 224: */
! 225: GdomeBoolean
! 226: gdome_xml_a_specified (GdomeAttr *self, GdomeException *exc)
! 227: {
! 228: /* FIXME: probably flesh out when dealing with validation. */
! 229:
! 230: return TRUE;
! 231: }
! 232:
! 233: /**
! 234: * gdome_xml_a_value:
! 235: * @self: Attr Object ref
! 236: * @exc: Exception Object ref
! 237: *
! 238: * Returns: the value of this attribute.
! 239: */
! 240: GdomeDOMString *
! 241: gdome_xml_a_value (GdomeAttr *self, GdomeException *exc) {
! 242: Gdome_xml_Attr *priv = (Gdome_xml_Attr *)self;
! 243: xmlChar *value = NULL;
! 244:
! 245: g_return_val_if_fail (priv != NULL, NULL);
! 246: g_return_val_if_fail (GDOME_XML_IS_A (priv), NULL);
! 247: g_return_val_if_fail (exc != NULL, NULL);
! 248:
! 249: value = xmlNodeGetContent ((xmlNode *)priv->n);
! 250:
! 251: if (value != NULL)
! 252: return gdome_xml_str_mkref_xml (value);
! 253: else
! 254: return gdome_xml_str_mkref ("");
! 255: }
! 256:
! 257: /**
! 258: * gdome_xml_a_set_value:
! 259: * @self: Attr Object ref
! 260: * @value: The new value to set
! 261: * @exc: Exception Object ref
! 262: *
! 263: * Sets the value of this attribute.
! 264: *
! 265: * %GDOME_NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
! 266: */
! 267: void
! 268: gdome_xml_a_set_value (GdomeAttr *self, GdomeDOMString *value, GdomeException *exc) {
! 269: Gdome_xml_Attr *priv = (Gdome_xml_Attr *)self;
! 270: GdomeMutationEvent *mev;
! 271: GdomeDOMString *prevValue, *attrName;
! 272: GdomeElement *parent;
! 273:
! 274: g_return_if_fail (priv != NULL);
! 275: g_return_if_fail (GDOME_XML_IS_A (priv));
! 276: g_return_if_fail (value != NULL);
! 277: g_return_if_fail (exc != NULL);
! 278:
! 279: if (GDOME_ISREADONLY (priv)) {
! 280: *exc = GDOME_NO_MODIFICATION_ALLOWED_ERR;
! 281: return;
! 282: }
! 283:
! 284: prevValue = gdome_xml_a_value (self, exc);
! 285: gdome_xmlSetAttrValue (priv->n, (xmlChar *)value->str);
! 286:
! 287: /* Fire of events if the Attr is owned by an someone */
! 288: parent = gdome_xml_a_ownerElement (self, exc);
! 289: if (parent != NULL) {
! 290: if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_ATTR_MODIFIED_EVENT_TYPE)) {
! 291: /* Fire DOMAttrModified */
! 292: mev = gdome_evt_mevnt_mkref ();
! 293: attrName = gdome_xml_a_name (self, exc);
! 294: gdome_xml_str_ref (value);
! 295: gdome_evt_mevnt_initMutationEventByCode (mev, DOM_ATTR_MODIFIED_EVENT_TYPE,
! 296: TRUE, FALSE, (GdomeNode *)self,
! 297: prevValue, value, attrName, GDOME_MODIFICATION, exc);
! 298: gdome_xml_n_dispatchEvent ((GdomeNode *)parent, (GdomeEvent *)mev, exc);
! 299: gdome_xml_str_unref (value);
! 300: gdome_xml_str_unref (attrName);
! 301: gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
! 302: }
! 303:
! 304: if (gdome_xml_n_eventEnabledByCode((GdomeNode *) self, DOM_SUBTREE_MODIFIED_EVENT_TYPE)) {
! 305: /* Fire DOMSubtreeModified */
! 306: mev = gdome_evt_mevnt_mkref ();
! 307: gdome_evt_mevnt_initMutationEventByCode (mev, DOM_SUBTREE_MODIFIED_EVENT_TYPE,
! 308: TRUE, FALSE, NULL,
! 309: NULL, NULL, NULL, 0, exc);
! 310: gdome_xml_n_dispatchEvent ((GdomeNode *)parent, (GdomeEvent *)mev, exc);
! 311: gdome_xml_n_unref ((GdomeNode *)parent, exc);
! 312: gdome_evt_mevnt_unref ((GdomeEvent *)mev, exc);
! 313: }
! 314: }
! 315:
! 316: if (prevValue != NULL)
! 317: gdome_xml_str_unref (prevValue);
! 318: }
E-mail: