2 * DOM Attribute implementation
4 * Copyright 2006 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_NO_STATUS
30 # include <libxml/parser.h>
31 //# include <libxml/xmlerror.h>
32 //# include <libxml/HTMLtree.h>
37 //#include "winuser.h"
41 #include "msxml_private.h"
43 #include <wine/debug.h>
45 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
49 static const xmlChar xmlns
[] = "xmlns";
51 typedef struct _domattr
54 IXMLDOMAttribute IXMLDOMAttribute_iface
;
58 static const tid_t domattr_se_tids
[] = {
64 static inline domattr
*impl_from_IXMLDOMAttribute( IXMLDOMAttribute
*iface
)
66 return CONTAINING_RECORD(iface
, domattr
, IXMLDOMAttribute_iface
);
69 static HRESULT WINAPI
domattr_QueryInterface(
70 IXMLDOMAttribute
*iface
,
74 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
75 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
77 if ( IsEqualGUID( riid
, &IID_IXMLDOMAttribute
) ||
78 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
79 IsEqualGUID( riid
, &IID_IDispatch
) ||
80 IsEqualGUID( riid
, &IID_IUnknown
) )
84 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
86 return *ppvObject
? S_OK
: E_NOINTERFACE
;
88 else if(IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
90 return node_create_supporterrorinfo(domattr_se_tids
, ppvObject
);
94 TRACE("Unsupported interface %s\n", debugstr_guid(riid
));
99 IXMLDOMAttribute_AddRef(iface
);
103 static ULONG WINAPI
domattr_AddRef(
104 IXMLDOMAttribute
*iface
)
106 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
107 ULONG ref
= InterlockedIncrement( &This
->ref
);
108 TRACE("(%p)->(%d)\n", This
, ref
);
112 static ULONG WINAPI
domattr_Release(
113 IXMLDOMAttribute
*iface
)
115 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
116 ULONG ref
= InterlockedDecrement( &This
->ref
);
118 TRACE("(%p)->(%d)\n", This
, ref
);
121 destroy_xmlnode(&This
->node
);
128 static HRESULT WINAPI
domattr_GetTypeInfoCount(
129 IXMLDOMAttribute
*iface
,
132 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
133 return IDispatchEx_GetTypeInfoCount(&This
->node
.dispex
.IDispatchEx_iface
, pctinfo
);
136 static HRESULT WINAPI
domattr_GetTypeInfo(
137 IXMLDOMAttribute
*iface
,
138 UINT iTInfo
, LCID lcid
,
139 ITypeInfo
** ppTInfo
)
141 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
142 return IDispatchEx_GetTypeInfo(&This
->node
.dispex
.IDispatchEx_iface
,
143 iTInfo
, lcid
, ppTInfo
);
146 static HRESULT WINAPI
domattr_GetIDsOfNames(
147 IXMLDOMAttribute
*iface
,
148 REFIID riid
, LPOLESTR
* rgszNames
,
149 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
151 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
152 return IDispatchEx_GetIDsOfNames(&This
->node
.dispex
.IDispatchEx_iface
,
153 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
156 static HRESULT WINAPI
domattr_Invoke(
157 IXMLDOMAttribute
*iface
,
158 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
159 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
160 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
162 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
163 return IDispatchEx_Invoke(&This
->node
.dispex
.IDispatchEx_iface
,
164 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
167 static HRESULT WINAPI
domattr_get_nodeName(
168 IXMLDOMAttribute
*iface
,
171 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
173 TRACE("(%p)->(%p)\n", This
, p
);
175 return node_get_nodeName(&This
->node
, p
);
178 static HRESULT WINAPI
domattr_get_nodeValue(
179 IXMLDOMAttribute
*iface
,
182 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
184 TRACE("(%p)->(%p)\n", This
, value
);
186 return node_get_content(&This
->node
, value
);
189 static HRESULT WINAPI
domattr_put_nodeValue(
190 IXMLDOMAttribute
*iface
,
193 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
195 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&value
));
197 return node_put_value_escaped(&This
->node
, &value
);
200 static HRESULT WINAPI
domattr_get_nodeType(
201 IXMLDOMAttribute
*iface
,
202 DOMNodeType
* domNodeType
)
204 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
206 TRACE("(%p)->(%p)\n", This
, domNodeType
);
208 *domNodeType
= NODE_ATTRIBUTE
;
212 static HRESULT WINAPI
domattr_get_parentNode(
213 IXMLDOMAttribute
*iface
,
214 IXMLDOMNode
** parent
)
216 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
217 TRACE("(%p)->(%p)\n", This
, parent
);
218 if (!parent
) return E_INVALIDARG
;
223 static HRESULT WINAPI
domattr_get_childNodes(
224 IXMLDOMAttribute
*iface
,
225 IXMLDOMNodeList
** outList
)
227 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
229 TRACE("(%p)->(%p)\n", This
, outList
);
231 return node_get_child_nodes(&This
->node
, outList
);
234 static HRESULT WINAPI
domattr_get_firstChild(
235 IXMLDOMAttribute
*iface
,
236 IXMLDOMNode
** domNode
)
238 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
240 TRACE("(%p)->(%p)\n", This
, domNode
);
242 return node_get_first_child(&This
->node
, domNode
);
245 static HRESULT WINAPI
domattr_get_lastChild(
246 IXMLDOMAttribute
*iface
,
247 IXMLDOMNode
** domNode
)
249 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
251 TRACE("(%p)->(%p)\n", This
, domNode
);
253 return node_get_last_child(&This
->node
, domNode
);
256 static HRESULT WINAPI
domattr_get_previousSibling(
257 IXMLDOMAttribute
*iface
,
258 IXMLDOMNode
** domNode
)
260 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
262 TRACE("(%p)->(%p)\n", This
, domNode
);
264 return return_null_node(domNode
);
267 static HRESULT WINAPI
domattr_get_nextSibling(
268 IXMLDOMAttribute
*iface
,
269 IXMLDOMNode
** domNode
)
271 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
273 TRACE("(%p)->(%p)\n", This
, domNode
);
275 return return_null_node(domNode
);
278 static HRESULT WINAPI
domattr_get_attributes(
279 IXMLDOMAttribute
*iface
,
280 IXMLDOMNamedNodeMap
** attributeMap
)
282 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
284 TRACE("(%p)->(%p)\n", This
, attributeMap
);
286 return return_null_ptr((void**)attributeMap
);
289 static HRESULT WINAPI
domattr_insertBefore(
290 IXMLDOMAttribute
*iface
,
291 IXMLDOMNode
* newNode
, VARIANT refChild
,
292 IXMLDOMNode
** old_node
)
294 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
298 FIXME("(%p)->(%p %s %p) needs test\n", This
, newNode
, debugstr_variant(&refChild
), old_node
);
300 if (!newNode
) return E_INVALIDARG
;
302 hr
= IXMLDOMNode_get_nodeType(newNode
, &type
);
303 if (hr
!= S_OK
) return hr
;
305 TRACE("new node type %d\n", type
);
309 case NODE_CDATA_SECTION
:
312 case NODE_PROCESSING_INSTRUCTION
:
313 if (old_node
) *old_node
= NULL
;
316 return node_insert_before(&This
->node
, newNode
, &refChild
, old_node
);
320 static HRESULT WINAPI
domattr_replaceChild(
321 IXMLDOMAttribute
*iface
,
322 IXMLDOMNode
* newNode
,
323 IXMLDOMNode
* oldNode
,
324 IXMLDOMNode
** outOldNode
)
326 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
328 FIXME("(%p)->(%p %p %p) needs tests\n", This
, newNode
, oldNode
, outOldNode
);
330 return node_replace_child(&This
->node
, newNode
, oldNode
, outOldNode
);
333 static HRESULT WINAPI
domattr_removeChild(
334 IXMLDOMAttribute
*iface
,
335 IXMLDOMNode
*child
, IXMLDOMNode
**oldChild
)
337 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
338 TRACE("(%p)->(%p %p)\n", This
, child
, oldChild
);
339 return node_remove_child(&This
->node
, child
, oldChild
);
342 static HRESULT WINAPI
domattr_appendChild(
343 IXMLDOMAttribute
*iface
,
344 IXMLDOMNode
*child
, IXMLDOMNode
**outChild
)
346 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
347 TRACE("(%p)->(%p %p)\n", This
, child
, outChild
);
348 return node_append_child(&This
->node
, child
, outChild
);
351 static HRESULT WINAPI
domattr_hasChildNodes(
352 IXMLDOMAttribute
*iface
,
355 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
356 TRACE("(%p)->(%p)\n", This
, ret
);
357 return node_has_childnodes(&This
->node
, ret
);
360 static HRESULT WINAPI
domattr_get_ownerDocument(
361 IXMLDOMAttribute
*iface
,
362 IXMLDOMDocument
**doc
)
364 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
365 TRACE("(%p)->(%p)\n", This
, doc
);
366 return node_get_owner_doc(&This
->node
, doc
);
369 static HRESULT WINAPI
domattr_cloneNode(
370 IXMLDOMAttribute
*iface
,
371 VARIANT_BOOL deep
, IXMLDOMNode
** outNode
)
373 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
374 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
375 return node_clone( &This
->node
, deep
, outNode
);
378 static HRESULT WINAPI
domattr_get_nodeTypeString(
379 IXMLDOMAttribute
*iface
,
382 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
383 static const WCHAR attributeW
[] = {'a','t','t','r','i','b','u','t','e',0};
385 TRACE("(%p)->(%p)\n", This
, p
);
387 return return_bstr(attributeW
, p
);
390 static HRESULT WINAPI
domattr_get_text(
391 IXMLDOMAttribute
*iface
,
394 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
395 TRACE("(%p)->(%p)\n", This
, p
);
396 return node_get_text(&This
->node
, p
);
399 static HRESULT WINAPI
domattr_put_text(
400 IXMLDOMAttribute
*iface
,
403 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
404 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
405 return node_put_text( &This
->node
, p
);
408 static HRESULT WINAPI
domattr_get_specified(
409 IXMLDOMAttribute
*iface
,
410 VARIANT_BOOL
* isSpecified
)
412 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
413 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
414 *isSpecified
= VARIANT_TRUE
;
418 static HRESULT WINAPI
domattr_get_definition(
419 IXMLDOMAttribute
*iface
,
420 IXMLDOMNode
** definitionNode
)
422 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
423 FIXME("(%p)->(%p)\n", This
, definitionNode
);
427 static HRESULT WINAPI
domattr_get_nodeTypedValue(
428 IXMLDOMAttribute
*iface
,
431 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
432 IXMLDOMDocument
*doc
;
435 TRACE("(%p)->(%p)\n", This
, value
);
437 hr
= IXMLDOMAttribute_get_ownerDocument(iface
, &doc
);
440 IXMLDOMDocument3
*doc3
;
442 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IXMLDOMDocument3
, (void**)&doc3
);
443 IXMLDOMDocument_Release(doc
);
449 hr
= IXMLDOMDocument3_get_schemas(doc3
, &schemas
);
450 IXMLDOMDocument3_Release(doc3
);
453 return IXMLDOMAttribute_get_value(iface
, value
);
456 FIXME("need to query schema for attribute type\n");
457 VariantClear(&schemas
);
462 return return_null_var(value
);
465 static HRESULT WINAPI
domattr_put_nodeTypedValue(
466 IXMLDOMAttribute
*iface
,
469 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
470 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&typedValue
));
474 static HRESULT WINAPI
domattr_get_dataType(
475 IXMLDOMAttribute
*iface
,
478 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
479 TRACE("(%p)->(%p)\n", This
, typename
);
480 return return_null_var( typename
);
483 static HRESULT WINAPI
domattr_put_dataType(
484 IXMLDOMAttribute
*iface
,
487 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
489 FIXME("(%p)->(%s)\n", This
, debugstr_w(p
));
497 static HRESULT WINAPI
domattr_get_xml(
498 IXMLDOMAttribute
*iface
,
501 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
503 TRACE("(%p)->(%p)\n", This
, p
);
505 return node_get_xml(&This
->node
, FALSE
, p
);
508 static HRESULT WINAPI
domattr_transformNode(
509 IXMLDOMAttribute
*iface
,
510 IXMLDOMNode
*node
, BSTR
*p
)
512 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
513 TRACE("(%p)->(%p %p)\n", This
, node
, p
);
514 return node_transform_node(&This
->node
, node
, p
);
517 static HRESULT WINAPI
domattr_selectNodes(
518 IXMLDOMAttribute
*iface
,
519 BSTR p
, IXMLDOMNodeList
** outList
)
521 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
522 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outList
);
523 return node_select_nodes(&This
->node
, p
, outList
);
526 static HRESULT WINAPI
domattr_selectSingleNode(
527 IXMLDOMAttribute
*iface
,
528 BSTR p
, IXMLDOMNode
** outNode
)
530 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
531 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outNode
);
532 return node_select_singlenode(&This
->node
, p
, outNode
);
535 static HRESULT WINAPI
domattr_get_parsed(
536 IXMLDOMAttribute
*iface
,
537 VARIANT_BOOL
* isParsed
)
539 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
540 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
541 *isParsed
= VARIANT_TRUE
;
545 static HRESULT WINAPI
domattr_get_namespaceURI(
546 IXMLDOMAttribute
*iface
,
549 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
550 xmlNsPtr ns
= This
->node
.node
->ns
;
552 TRACE("(%p)->(%p)\n", This
, p
);
561 /* special case for default namespace definition */
562 if (xmlStrEqual(This
->node
.node
->name
, xmlns
))
563 *p
= bstr_from_xmlChar(xmlns
);
564 else if (xmlStrEqual(ns
->prefix
, xmlns
))
565 *p
= SysAllocStringLen(NULL
, 0);
567 *p
= bstr_from_xmlChar(ns
->href
);
570 TRACE("uri: %s\n", debugstr_w(*p
));
572 return *p
? S_OK
: S_FALSE
;
575 static HRESULT WINAPI
domattr_get_prefix(
576 IXMLDOMAttribute
*iface
,
579 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
580 xmlNsPtr ns
= This
->node
.node
->ns
;
582 TRACE("(%p)->(%p)\n", This
, prefix
);
584 if (!prefix
) return E_INVALIDARG
;
590 /* special case for default namespace definition */
591 if (xmlStrEqual(This
->node
.node
->name
, xmlns
))
592 *prefix
= bstr_from_xmlChar(xmlns
);
594 *prefix
= bstr_from_xmlChar(ns
->prefix
);
597 TRACE("prefix: %s\n", debugstr_w(*prefix
));
599 return *prefix
? S_OK
: S_FALSE
;
602 static HRESULT WINAPI
domattr_get_baseName(
603 IXMLDOMAttribute
*iface
,
606 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
607 TRACE("(%p)->(%p)\n", This
, name
);
608 return node_get_base_name( &This
->node
, name
);
611 static HRESULT WINAPI
domattr_transformNodeToObject(
612 IXMLDOMAttribute
*iface
,
613 IXMLDOMNode
* domNode
, VARIANT var1
)
615 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
616 FIXME("(%p)->(%p %s)\n", This
, domNode
, debugstr_variant(&var1
));
620 static HRESULT WINAPI
domattr_get_name(
621 IXMLDOMAttribute
*iface
,
624 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
626 TRACE("(%p)->(%p)\n", This
, p
);
628 return node_get_nodeName(&This
->node
, p
);
631 static HRESULT WINAPI
domattr_get_value(
632 IXMLDOMAttribute
*iface
,
635 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
637 TRACE("(%p)->(%p)\n", This
, value
);
639 return node_get_content(&This
->node
, value
);
642 static HRESULT WINAPI
domattr_put_value(
643 IXMLDOMAttribute
*iface
,
646 domattr
*This
= impl_from_IXMLDOMAttribute( iface
);
648 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&value
));
650 return node_put_value_escaped(&This
->node
, &value
);
653 static const struct IXMLDOMAttributeVtbl domattr_vtbl
=
655 domattr_QueryInterface
,
658 domattr_GetTypeInfoCount
,
660 domattr_GetIDsOfNames
,
662 domattr_get_nodeName
,
663 domattr_get_nodeValue
,
664 domattr_put_nodeValue
,
665 domattr_get_nodeType
,
666 domattr_get_parentNode
,
667 domattr_get_childNodes
,
668 domattr_get_firstChild
,
669 domattr_get_lastChild
,
670 domattr_get_previousSibling
,
671 domattr_get_nextSibling
,
672 domattr_get_attributes
,
673 domattr_insertBefore
,
674 domattr_replaceChild
,
677 domattr_hasChildNodes
,
678 domattr_get_ownerDocument
,
680 domattr_get_nodeTypeString
,
683 domattr_get_specified
,
684 domattr_get_definition
,
685 domattr_get_nodeTypedValue
,
686 domattr_put_nodeTypedValue
,
687 domattr_get_dataType
,
688 domattr_put_dataType
,
690 domattr_transformNode
,
692 domattr_selectSingleNode
,
694 domattr_get_namespaceURI
,
696 domattr_get_baseName
,
697 domattr_transformNodeToObject
,
703 static const tid_t domattr_iface_tids
[] = {
704 IXMLDOMAttribute_tid
,
708 static dispex_static_data_t domattr_dispex
= {
710 IXMLDOMAttribute_tid
,
715 IUnknown
* create_attribute( xmlNodePtr attribute
)
719 This
= heap_alloc( sizeof *This
);
723 This
->IXMLDOMAttribute_iface
.lpVtbl
= &domattr_vtbl
;
726 init_xmlnode(&This
->node
, attribute
, (IXMLDOMNode
*)&This
->IXMLDOMAttribute_iface
, &domattr_dispex
);
728 return (IUnknown
*)&This
->IXMLDOMAttribute_iface
;