mshtml: Reimplement IHTMLStyle::get_backgroundPositionY using background-position...
[wine] / dlls / msxml3 / attribute.c
1 /*
2  *    DOM Attribute implementation
3  *
4  * Copyright 2006 Huw Davies
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #define COBJMACROS
22
23 #include "config.h"
24
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 # include <libxml/HTMLtree.h>
30 #endif
31
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winuser.h"
35 #include "ole2.h"
36 #include "msxml6.h"
37
38 #include "msxml_private.h"
39
40 #include "wine/debug.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43
44 #ifdef HAVE_LIBXML2
45
46 typedef struct _domattr
47 {
48     xmlnode node;
49     IXMLDOMAttribute IXMLDOMAttribute_iface;
50     LONG ref;
51 } domattr;
52
53 static inline domattr *impl_from_IXMLDOMAttribute( IXMLDOMAttribute *iface )
54 {
55     return CONTAINING_RECORD(iface, domattr, IXMLDOMAttribute_iface);
56 }
57
58 static HRESULT WINAPI domattr_QueryInterface(
59     IXMLDOMAttribute *iface,
60     REFIID riid,
61     void** ppvObject )
62 {
63     domattr *This = impl_from_IXMLDOMAttribute( iface );
64     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
65
66     if ( IsEqualGUID( riid, &IID_IXMLDOMAttribute ) ||
67          IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
68          IsEqualGUID( riid, &IID_IDispatch ) ||
69          IsEqualGUID( riid, &IID_IUnknown ) )
70     {
71         *ppvObject = iface;
72     }
73     else if(node_query_interface(&This->node, riid, ppvObject))
74     {
75         return *ppvObject ? S_OK : E_NOINTERFACE;
76     }
77     else
78     {
79         FIXME("Unsupported interface %s\n", debugstr_guid(riid));
80         return E_NOINTERFACE;
81     }
82
83     IXMLDOMText_AddRef((IUnknown*)*ppvObject);
84     return S_OK;
85 }
86
87 static ULONG WINAPI domattr_AddRef(
88     IXMLDOMAttribute *iface )
89 {
90     domattr *This = impl_from_IXMLDOMAttribute( iface );
91     return InterlockedIncrement( &This->ref );
92 }
93
94 static ULONG WINAPI domattr_Release(
95     IXMLDOMAttribute *iface )
96 {
97     domattr *This = impl_from_IXMLDOMAttribute( iface );
98     ULONG ref;
99
100     ref = InterlockedDecrement( &This->ref );
101     if ( ref == 0 )
102     {
103         destroy_xmlnode(&This->node);
104         heap_free( This );
105     }
106
107     return ref;
108 }
109
110 static HRESULT WINAPI domattr_GetTypeInfoCount(
111     IXMLDOMAttribute *iface,
112     UINT* pctinfo )
113 {
114     domattr *This = impl_from_IXMLDOMAttribute( iface );
115
116     TRACE("(%p)->(%p)\n", This, pctinfo);
117
118     *pctinfo = 1;
119
120     return S_OK;
121 }
122
123 static HRESULT WINAPI domattr_GetTypeInfo(
124     IXMLDOMAttribute *iface,
125     UINT iTInfo, LCID lcid,
126     ITypeInfo** ppTInfo )
127 {
128     domattr *This = impl_from_IXMLDOMAttribute( iface );
129     HRESULT hr;
130
131     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
132
133     hr = get_typeinfo(IXMLDOMAttribute_tid, ppTInfo);
134
135     return hr;
136 }
137
138 static HRESULT WINAPI domattr_GetIDsOfNames(
139     IXMLDOMAttribute *iface,
140     REFIID riid, LPOLESTR* rgszNames,
141     UINT cNames, LCID lcid, DISPID* rgDispId )
142 {
143     domattr *This = impl_from_IXMLDOMAttribute( iface );
144     ITypeInfo *typeinfo;
145     HRESULT hr;
146
147     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
148           lcid, rgDispId);
149
150     if(!rgszNames || cNames == 0 || !rgDispId)
151         return E_INVALIDARG;
152
153     hr = get_typeinfo(IXMLDOMAttribute_tid, &typeinfo);
154     if(SUCCEEDED(hr))
155     {
156         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
157         ITypeInfo_Release(typeinfo);
158     }
159
160     return hr;
161 }
162
163 static HRESULT WINAPI domattr_Invoke(
164     IXMLDOMAttribute *iface,
165     DISPID dispIdMember, REFIID riid, LCID lcid,
166     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
167     EXCEPINFO* pExcepInfo, UINT* puArgErr )
168 {
169     domattr *This = impl_from_IXMLDOMAttribute( iface );
170     ITypeInfo *typeinfo;
171     HRESULT hr;
172
173     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
174           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
175
176     hr = get_typeinfo(IXMLDOMAttribute_tid, &typeinfo);
177     if(SUCCEEDED(hr))
178     {
179         hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMAttribute_iface, dispIdMember, wFlags,
180                 pDispParams, pVarResult, pExcepInfo, puArgErr);
181         ITypeInfo_Release(typeinfo);
182     }
183     return hr;
184 }
185
186 static HRESULT WINAPI domattr_get_nodeName(
187     IXMLDOMAttribute *iface,
188     BSTR* p )
189 {
190     domattr *This = impl_from_IXMLDOMAttribute( iface );
191
192     TRACE("(%p)->(%p)\n", This, p);
193
194     return node_get_nodeName(&This->node, p);
195 }
196
197 static HRESULT WINAPI domattr_get_nodeValue(
198     IXMLDOMAttribute *iface,
199     VARIANT* value)
200 {
201     domattr *This = impl_from_IXMLDOMAttribute( iface );
202
203     TRACE("(%p)->(%p)\n", This, value);
204
205     return node_get_content(&This->node, value);
206 }
207
208 static HRESULT WINAPI domattr_put_nodeValue(
209     IXMLDOMAttribute *iface,
210     VARIANT value)
211 {
212     domattr *This = impl_from_IXMLDOMAttribute( iface );
213
214     TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
215
216     return node_put_value_escaped(&This->node, &value);
217 }
218
219 static HRESULT WINAPI domattr_get_nodeType(
220     IXMLDOMAttribute *iface,
221     DOMNodeType* domNodeType )
222 {
223     domattr *This = impl_from_IXMLDOMAttribute( iface );
224
225     TRACE("(%p)->(%p)\n", This, domNodeType);
226
227     *domNodeType = NODE_ATTRIBUTE;
228     return S_OK;
229 }
230
231 static HRESULT WINAPI domattr_get_parentNode(
232     IXMLDOMAttribute *iface,
233     IXMLDOMNode** parent )
234 {
235     domattr *This = impl_from_IXMLDOMAttribute( iface );
236     TRACE("(%p)->(%p)\n", This, parent);
237     if (!parent) return E_INVALIDARG;
238     *parent = NULL;
239     return S_FALSE;
240 }
241
242 static HRESULT WINAPI domattr_get_childNodes(
243     IXMLDOMAttribute *iface,
244     IXMLDOMNodeList** outList)
245 {
246     domattr *This = impl_from_IXMLDOMAttribute( iface );
247
248     TRACE("(%p)->(%p)\n", This, outList);
249
250     return node_get_child_nodes(&This->node, outList);
251 }
252
253 static HRESULT WINAPI domattr_get_firstChild(
254     IXMLDOMAttribute *iface,
255     IXMLDOMNode** domNode)
256 {
257     domattr *This = impl_from_IXMLDOMAttribute( iface );
258
259     TRACE("(%p)->(%p)\n", This, domNode);
260
261     return node_get_first_child(&This->node, domNode);
262 }
263
264 static HRESULT WINAPI domattr_get_lastChild(
265     IXMLDOMAttribute *iface,
266     IXMLDOMNode** domNode)
267 {
268     domattr *This = impl_from_IXMLDOMAttribute( iface );
269
270     TRACE("(%p)->(%p)\n", This, domNode);
271
272     return node_get_last_child(&This->node, domNode);
273 }
274
275 static HRESULT WINAPI domattr_get_previousSibling(
276     IXMLDOMAttribute *iface,
277     IXMLDOMNode** domNode)
278 {
279     domattr *This = impl_from_IXMLDOMAttribute( iface );
280
281     TRACE("(%p)->(%p)\n", This, domNode);
282
283     return return_null_node(domNode);
284 }
285
286 static HRESULT WINAPI domattr_get_nextSibling(
287     IXMLDOMAttribute *iface,
288     IXMLDOMNode** domNode)
289 {
290     domattr *This = impl_from_IXMLDOMAttribute( iface );
291
292     TRACE("(%p)->(%p)\n", This, domNode);
293
294     return return_null_node(domNode);
295 }
296
297 static HRESULT WINAPI domattr_get_attributes(
298     IXMLDOMAttribute *iface,
299     IXMLDOMNamedNodeMap** attributeMap)
300 {
301     domattr *This = impl_from_IXMLDOMAttribute( iface );
302
303     TRACE("(%p)->(%p)\n", This, attributeMap);
304
305     return return_null_ptr((void**)attributeMap);
306 }
307
308 static HRESULT WINAPI domattr_insertBefore(
309     IXMLDOMAttribute *iface,
310     IXMLDOMNode* newNode, VARIANT refChild,
311     IXMLDOMNode** outOldNode)
312 {
313     domattr *This = impl_from_IXMLDOMAttribute( iface );
314
315     FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode);
316
317     return node_insert_before(&This->node, newNode, &refChild, outOldNode);
318 }
319
320 static HRESULT WINAPI domattr_replaceChild(
321     IXMLDOMAttribute *iface,
322     IXMLDOMNode* newNode,
323     IXMLDOMNode* oldNode,
324     IXMLDOMNode** outOldNode)
325 {
326     domattr *This = impl_from_IXMLDOMAttribute( iface );
327
328     FIXME("(%p)->(%p %p %p) needs tests\n", This, newNode, oldNode, outOldNode);
329
330     return node_replace_child(&This->node, newNode, oldNode, outOldNode);
331 }
332
333 static HRESULT WINAPI domattr_removeChild(
334     IXMLDOMAttribute *iface,
335     IXMLDOMNode *child, IXMLDOMNode **oldChild)
336 {
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);
340 }
341
342 static HRESULT WINAPI domattr_appendChild(
343     IXMLDOMAttribute *iface,
344     IXMLDOMNode *child, IXMLDOMNode **outChild)
345 {
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);
349 }
350
351 static HRESULT WINAPI domattr_hasChildNodes(
352     IXMLDOMAttribute *iface,
353     VARIANT_BOOL *ret)
354 {
355     domattr *This = impl_from_IXMLDOMAttribute( iface );
356     TRACE("(%p)->(%p)\n", This, ret);
357     return node_has_childnodes(&This->node, ret);
358 }
359
360 static HRESULT WINAPI domattr_get_ownerDocument(
361     IXMLDOMAttribute *iface,
362     IXMLDOMDocument **doc)
363 {
364     domattr *This = impl_from_IXMLDOMAttribute( iface );
365     TRACE("(%p)->(%p)\n", This, doc);
366     return node_get_owner_doc(&This->node, doc);
367 }
368
369 static HRESULT WINAPI domattr_cloneNode(
370     IXMLDOMAttribute *iface,
371     VARIANT_BOOL deep, IXMLDOMNode** outNode)
372 {
373     domattr *This = impl_from_IXMLDOMAttribute( iface );
374     TRACE("(%p)->(%d %p)\n", This, deep, outNode);
375     return node_clone( &This->node, deep, outNode );
376 }
377
378 static HRESULT WINAPI domattr_get_nodeTypeString(
379     IXMLDOMAttribute *iface,
380     BSTR* p)
381 {
382     domattr *This = impl_from_IXMLDOMAttribute( iface );
383     static const WCHAR attributeW[] = {'a','t','t','r','i','b','u','t','e',0};
384
385     TRACE("(%p)->(%p)\n", This, p);
386
387     return return_bstr(attributeW, p);
388 }
389
390 static HRESULT WINAPI domattr_get_text(
391     IXMLDOMAttribute *iface,
392     BSTR* p)
393 {
394     domattr *This = impl_from_IXMLDOMAttribute( iface );
395     TRACE("(%p)->(%p)\n", This, p);
396     return node_get_text(&This->node, p);
397 }
398
399 static HRESULT WINAPI domattr_put_text(
400     IXMLDOMAttribute *iface,
401     BSTR p)
402 {
403     domattr *This = impl_from_IXMLDOMAttribute( iface );
404     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
405     return node_put_text( &This->node, p );
406 }
407
408 static HRESULT WINAPI domattr_get_specified(
409     IXMLDOMAttribute *iface,
410     VARIANT_BOOL* isSpecified)
411 {
412     domattr *This = impl_from_IXMLDOMAttribute( iface );
413     FIXME("(%p)->(%p) stub!\n", This, isSpecified);
414     *isSpecified = VARIANT_TRUE;
415     return S_OK;
416 }
417
418 static HRESULT WINAPI domattr_get_definition(
419     IXMLDOMAttribute *iface,
420     IXMLDOMNode** definitionNode)
421 {
422     domattr *This = impl_from_IXMLDOMAttribute( iface );
423     FIXME("(%p)->(%p)\n", This, definitionNode);
424     return E_NOTIMPL;
425 }
426
427 static HRESULT WINAPI domattr_get_nodeTypedValue(
428     IXMLDOMAttribute *iface,
429     VARIANT* var1)
430 {
431     domattr *This = impl_from_IXMLDOMAttribute( iface );
432     FIXME("(%p)->(%p)\n", This, var1);
433     return return_null_var(var1);
434 }
435
436 static HRESULT WINAPI domattr_put_nodeTypedValue(
437     IXMLDOMAttribute *iface,
438     VARIANT typedValue)
439 {
440     domattr *This = impl_from_IXMLDOMAttribute( iface );
441     FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue));
442     return E_NOTIMPL;
443 }
444
445 static HRESULT WINAPI domattr_get_dataType(
446     IXMLDOMAttribute *iface,
447     VARIANT* typename)
448 {
449     domattr *This = impl_from_IXMLDOMAttribute( iface );
450     TRACE("(%p)->(%p)\n", This, typename);
451     return return_null_var( typename );
452 }
453
454 static HRESULT WINAPI domattr_put_dataType(
455     IXMLDOMAttribute *iface,
456     BSTR p)
457 {
458     domattr *This = impl_from_IXMLDOMAttribute( iface );
459
460     FIXME("(%p)->(%s)\n", This, debugstr_w(p));
461
462     if(!p)
463         return E_INVALIDARG;
464
465     return E_FAIL;
466 }
467
468 static HRESULT WINAPI domattr_get_xml(
469     IXMLDOMAttribute *iface,
470     BSTR* p)
471 {
472     domattr *This = impl_from_IXMLDOMAttribute( iface );
473
474     TRACE("(%p)->(%p)\n", This, p);
475
476     return node_get_xml(&This->node, FALSE, FALSE, p);
477 }
478
479 static HRESULT WINAPI domattr_transformNode(
480     IXMLDOMAttribute *iface,
481     IXMLDOMNode *node, BSTR *p)
482 {
483     domattr *This = impl_from_IXMLDOMAttribute( iface );
484     TRACE("(%p)->(%p %p)\n", This, node, p);
485     return node_transform_node(&This->node, node, p);
486 }
487
488 static HRESULT WINAPI domattr_selectNodes(
489     IXMLDOMAttribute *iface,
490     BSTR p, IXMLDOMNodeList** outList)
491 {
492     domattr *This = impl_from_IXMLDOMAttribute( iface );
493     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
494     return node_select_nodes(&This->node, p, outList);
495 }
496
497 static HRESULT WINAPI domattr_selectSingleNode(
498     IXMLDOMAttribute *iface,
499     BSTR p, IXMLDOMNode** outNode)
500 {
501     domattr *This = impl_from_IXMLDOMAttribute( iface );
502     TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
503     return node_select_singlenode(&This->node, p, outNode);
504 }
505
506 static HRESULT WINAPI domattr_get_parsed(
507     IXMLDOMAttribute *iface,
508     VARIANT_BOOL* isParsed)
509 {
510     domattr *This = impl_from_IXMLDOMAttribute( iface );
511     FIXME("(%p)->(%p) stub!\n", This, isParsed);
512     *isParsed = VARIANT_TRUE;
513     return S_OK;
514 }
515
516 static HRESULT WINAPI domattr_get_namespaceURI(
517     IXMLDOMAttribute *iface,
518     BSTR* p)
519 {
520     domattr *This = impl_from_IXMLDOMAttribute( iface );
521     TRACE("(%p)->(%p)\n", This, p);
522     return node_get_namespaceURI(&This->node, p);
523 }
524
525 static HRESULT WINAPI domattr_get_prefix(
526     IXMLDOMAttribute *iface,
527     BSTR* prefix)
528 {
529     domattr *This = impl_from_IXMLDOMAttribute( iface );
530     TRACE("(%p)->(%p)\n", This, prefix);
531     return node_get_prefix( &This->node, prefix );
532 }
533
534 static HRESULT WINAPI domattr_get_baseName(
535     IXMLDOMAttribute *iface,
536     BSTR* name)
537 {
538     domattr *This = impl_from_IXMLDOMAttribute( iface );
539     TRACE("(%p)->(%p)\n", This, name);
540     return node_get_base_name( &This->node, name );
541 }
542
543 static HRESULT WINAPI domattr_transformNodeToObject(
544     IXMLDOMAttribute *iface,
545     IXMLDOMNode* domNode, VARIANT var1)
546 {
547     domattr *This = impl_from_IXMLDOMAttribute( iface );
548     FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
549     return E_NOTIMPL;
550 }
551
552 static HRESULT WINAPI domattr_get_name(
553     IXMLDOMAttribute *iface,
554     BSTR *p)
555 {
556     domattr *This = impl_from_IXMLDOMAttribute( iface );
557
558     TRACE("(%p)->(%p)\n", This, p);
559
560     return node_get_nodeName(&This->node, p);
561 }
562
563 static HRESULT WINAPI domattr_get_value(
564     IXMLDOMAttribute *iface,
565     VARIANT *value)
566 {
567     domattr *This = impl_from_IXMLDOMAttribute( iface );
568
569     TRACE("(%p)->(%p)\n", This, value);
570
571     return node_get_content(&This->node, value);
572 }
573
574 static HRESULT WINAPI domattr_put_value(
575     IXMLDOMAttribute *iface,
576     VARIANT value)
577 {
578     domattr *This = impl_from_IXMLDOMAttribute( iface );
579
580     TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
581
582     return node_put_value(&This->node, &value);
583 }
584
585 static const struct IXMLDOMAttributeVtbl domattr_vtbl =
586 {
587     domattr_QueryInterface,
588     domattr_AddRef,
589     domattr_Release,
590     domattr_GetTypeInfoCount,
591     domattr_GetTypeInfo,
592     domattr_GetIDsOfNames,
593     domattr_Invoke,
594     domattr_get_nodeName,
595     domattr_get_nodeValue,
596     domattr_put_nodeValue,
597     domattr_get_nodeType,
598     domattr_get_parentNode,
599     domattr_get_childNodes,
600     domattr_get_firstChild,
601     domattr_get_lastChild,
602     domattr_get_previousSibling,
603     domattr_get_nextSibling,
604     domattr_get_attributes,
605     domattr_insertBefore,
606     domattr_replaceChild,
607     domattr_removeChild,
608     domattr_appendChild,
609     domattr_hasChildNodes,
610     domattr_get_ownerDocument,
611     domattr_cloneNode,
612     domattr_get_nodeTypeString,
613     domattr_get_text,
614     domattr_put_text,
615     domattr_get_specified,
616     domattr_get_definition,
617     domattr_get_nodeTypedValue,
618     domattr_put_nodeTypedValue,
619     domattr_get_dataType,
620     domattr_put_dataType,
621     domattr_get_xml,
622     domattr_transformNode,
623     domattr_selectNodes,
624     domattr_selectSingleNode,
625     domattr_get_parsed,
626     domattr_get_namespaceURI,
627     domattr_get_prefix,
628     domattr_get_baseName,
629     domattr_transformNodeToObject,
630     domattr_get_name,
631     domattr_get_value,
632     domattr_put_value
633 };
634
635 IUnknown* create_attribute( xmlNodePtr attribute )
636 {
637     domattr *This;
638
639     This = heap_alloc( sizeof *This );
640     if ( !This )
641         return NULL;
642
643     This->IXMLDOMAttribute_iface.lpVtbl = &domattr_vtbl;
644     This->ref = 1;
645
646     init_xmlnode(&This->node, attribute, (IXMLDOMNode*)&This->IXMLDOMAttribute_iface, NULL);
647
648     return (IUnknown*)&This->IXMLDOMAttribute_iface;
649 }
650
651 #endif