2 * Copyright 2006 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
30 #include "mshtml_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
34 #define HTMLDOMNODE_THIS(iface) DEFINE_THIS(HTMLDOMNode, HTMLDOMNode, iface)
36 static HRESULT WINAPI
HTMLDOMNode_QueryInterface(IHTMLDOMNode
*iface
,
37 REFIID riid
, void **ppv
)
39 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
41 return This
->vtbl
->qi(This
, riid
, ppv
);
44 static ULONG WINAPI
HTMLDOMNode_AddRef(IHTMLDOMNode
*iface
)
46 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
47 LONG ref
= InterlockedIncrement(&This
->ref
);
49 TRACE("(%p) ref=%d\n", This
, ref
);
54 static ULONG WINAPI
HTMLDOMNode_Release(IHTMLDOMNode
*iface
)
56 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
57 LONG ref
= InterlockedDecrement(&This
->ref
);
59 TRACE("(%p) ref=%d\n", This
, ref
);
62 This
->vtbl
->destructor(This
);
69 static HRESULT WINAPI
HTMLDOMNode_GetTypeInfoCount(IHTMLDOMNode
*iface
, UINT
*pctinfo
)
71 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
72 FIXME("(%p)->(%p)\n", This
, pctinfo
);
76 static HRESULT WINAPI
HTMLDOMNode_GetTypeInfo(IHTMLDOMNode
*iface
, UINT iTInfo
,
77 LCID lcid
, ITypeInfo
**ppTInfo
)
79 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
80 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
84 static HRESULT WINAPI
HTMLDOMNode_GetIDsOfNames(IHTMLDOMNode
*iface
, REFIID riid
,
85 LPOLESTR
*rgszNames
, UINT cNames
,
86 LCID lcid
, DISPID
*rgDispId
)
88 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
89 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
94 static HRESULT WINAPI
HTMLDOMNode_Invoke(IHTMLDOMNode
*iface
, DISPID dispIdMember
,
95 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
96 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
98 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
99 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
100 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
104 static HRESULT WINAPI
HTMLDOMNode_get_nodeType(IHTMLDOMNode
*iface
, long *p
)
106 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
109 TRACE("(%p)->(%p)\n", This
, p
);
111 nsIDOMNode_GetNodeType(This
->nsnode
, &type
);
123 * According to MSDN only ELEMENT_NODE and TEXT_NODE are supported.
124 * It needs more tests.
126 FIXME("type %u\n", type
);
133 static HRESULT WINAPI
HTMLDOMNode_get_parentNode(IHTMLDOMNode
*iface
, IHTMLDOMNode
**p
)
135 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
136 FIXME("(%p)->(%p)\n", This
, p
);
140 static HRESULT WINAPI
HTMLDOMNode_hasChildNodes(IHTMLDOMNode
*iface
, VARIANT_BOOL
*fChildren
)
142 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
143 FIXME("(%p)->(%p)\n", This
, fChildren
);
147 static HRESULT WINAPI
HTMLDOMNode_get_childNodes(IHTMLDOMNode
*iface
, IDispatch
**p
)
149 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
150 FIXME("(%p)->(%p)\n", This
, p
);
154 static HRESULT WINAPI
HTMLDOMNode_get_attributes(IHTMLDOMNode
*iface
, IDispatch
**p
)
156 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
157 FIXME("(%p)->(%p)\n", This
, p
);
161 static HRESULT WINAPI
HTMLDOMNode_insertBefore(IHTMLDOMNode
*iface
, IHTMLDOMNode
*newChild
,
162 VARIANT refChild
, IHTMLDOMNode
**node
)
164 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
165 FIXME("(%p)->(%p v %p)\n", This
, newChild
, node
);
169 static HRESULT WINAPI
HTMLDOMNode_removeChild(IHTMLDOMNode
*iface
, IHTMLDOMNode
*newChild
,
172 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
173 FIXME("(%p)->(%p %p)\n", This
, newChild
, node
);
177 static HRESULT WINAPI
HTMLDOMNode_replaceChild(IHTMLDOMNode
*iface
, IHTMLDOMNode
*newChild
,
178 IHTMLDOMNode
*oldChild
, IHTMLDOMNode
**node
)
180 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
181 FIXME("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, node
);
185 static HRESULT WINAPI
HTMLDOMNode_cloneNode(IHTMLDOMNode
*iface
, VARIANT_BOOL fDeep
,
186 IHTMLDOMNode
**clonedNode
)
188 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
189 FIXME("(%p)->(%x %p)\n", This
, fDeep
, clonedNode
);
193 static HRESULT WINAPI
HTMLDOMNode_removeNode(IHTMLDOMNode
*iface
, VARIANT_BOOL fDeep
,
194 IHTMLDOMNode
**removed
)
196 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
197 FIXME("(%p)->(%x %p)\n", This
, fDeep
, removed
);
201 static HRESULT WINAPI
HTMLDOMNode_swapNode(IHTMLDOMNode
*iface
, IHTMLDOMNode
*otherNode
,
202 IHTMLDOMNode
**swappedNode
)
204 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
205 FIXME("(%p)->(%p %p)\n", This
, otherNode
, swappedNode
);
209 static HRESULT WINAPI
HTMLDOMNode_replaceNode(IHTMLDOMNode
*iface
, IHTMLDOMNode
*replacement
,
210 IHTMLDOMNode
**replaced
)
212 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
213 FIXME("(%p)->(%p %p)\n", This
, replacement
, replaced
);
217 static HRESULT WINAPI
HTMLDOMNode_appendChild(IHTMLDOMNode
*iface
, IHTMLDOMNode
*newChild
,
220 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
221 FIXME("(%p)->(%p %p)\n", This
, newChild
, node
);
225 static HRESULT WINAPI
HTMLDOMNode_get_nodeName(IHTMLDOMNode
*iface
, BSTR
*p
)
227 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
229 TRACE("(%p)->(%p)\n", This
, p
);
235 const PRUnichar
*name
;
238 nsAString_Init(&name_str
, NULL
);
239 nsres
= nsIDOMNode_GetNodeName(This
->nsnode
, &name_str
);
241 if(NS_SUCCEEDED(nsres
)) {
242 nsAString_GetData(&name_str
, &name
);
243 *p
= SysAllocString(name
);
245 ERR("GetNodeName failed: %08x\n", nsres
);
248 nsAString_Finish(&name_str
);
254 static HRESULT WINAPI
HTMLDOMNode_put_nodeValue(IHTMLDOMNode
*iface
, VARIANT v
)
256 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
257 FIXME("(%p)->()\n", This
);
261 static HRESULT WINAPI
HTMLDOMNode_get_nodeValue(IHTMLDOMNode
*iface
, VARIANT
*p
)
263 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
264 FIXME("(%p)->(%p)\n", This
, p
);
268 static HRESULT WINAPI
HTMLDOMNode_get_firstChild(IHTMLDOMNode
*iface
, IHTMLDOMNode
**p
)
270 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
271 nsIDOMNode
*nschild
= NULL
;
273 TRACE("(%p)->(%p)\n", This
, p
);
275 nsIDOMNode_GetFirstChild(This
->nsnode
, &nschild
);
277 *p
= HTMLDOMNODE(get_node(This
->doc
, nschild
, TRUE
));
278 IHTMLDOMNode_AddRef(*p
);
286 static HRESULT WINAPI
HTMLDOMNode_get_lastChild(IHTMLDOMNode
*iface
, IHTMLDOMNode
**p
)
288 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
289 FIXME("(%p)->(%p)\n", This
, p
);
293 static HRESULT WINAPI
HTMLDOMNode_get_previousSibling(IHTMLDOMNode
*iface
, IHTMLDOMNode
**p
)
295 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
296 FIXME("(%p)->(%p)\n", This
, p
);
300 static HRESULT WINAPI
HTMLDOMNode_get_nextSibling(IHTMLDOMNode
*iface
, IHTMLDOMNode
**p
)
302 HTMLDOMNode
*This
= HTMLDOMNODE_THIS(iface
);
303 FIXME("(%p)->(%p)\n", This
, p
);
307 #undef HTMLDOMNODE_THIS
309 static const IHTMLDOMNodeVtbl HTMLDOMNodeVtbl
= {
310 HTMLDOMNode_QueryInterface
,
313 HTMLDOMNode_GetTypeInfoCount
,
314 HTMLDOMNode_GetTypeInfo
,
315 HTMLDOMNode_GetIDsOfNames
,
317 HTMLDOMNode_get_nodeType
,
318 HTMLDOMNode_get_parentNode
,
319 HTMLDOMNode_hasChildNodes
,
320 HTMLDOMNode_get_childNodes
,
321 HTMLDOMNode_get_attributes
,
322 HTMLDOMNode_insertBefore
,
323 HTMLDOMNode_removeChild
,
324 HTMLDOMNode_replaceChild
,
325 HTMLDOMNode_cloneNode
,
326 HTMLDOMNode_removeNode
,
327 HTMLDOMNode_swapNode
,
328 HTMLDOMNode_replaceNode
,
329 HTMLDOMNode_appendChild
,
330 HTMLDOMNode_get_nodeName
,
331 HTMLDOMNode_put_nodeValue
,
332 HTMLDOMNode_get_nodeValue
,
333 HTMLDOMNode_get_firstChild
,
334 HTMLDOMNode_get_lastChild
,
335 HTMLDOMNode_get_previousSibling
,
336 HTMLDOMNode_get_nextSibling
339 #define HTMLDOMNODE2_THIS(iface) DEFINE_THIS(HTMLDOMNode, HTMLDOMNode2, iface)
341 static HRESULT WINAPI
HTMLDOMNode2_QueryInterface(IHTMLDOMNode2
*iface
,
342 REFIID riid
, void **ppv
)
344 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
346 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(This
), riid
, ppv
);
349 static ULONG WINAPI
HTMLDOMNode2_AddRef(IHTMLDOMNode2
*iface
)
351 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
353 return IHTMLDOMNode_AddRef(HTMLDOMNODE(This
));
356 static ULONG WINAPI
HTMLDOMNode2_Release(IHTMLDOMNode2
*iface
)
358 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
360 return IHTMLDOMNode_Release(HTMLDOMNODE(This
));
363 static HRESULT WINAPI
HTMLDOMNode2_GetTypeInfoCount(IHTMLDOMNode2
*iface
, UINT
*pctinfo
)
365 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
366 FIXME("(%p)->(%p)\n", This
, pctinfo
);
370 static HRESULT WINAPI
HTMLDOMNode2_GetTypeInfo(IHTMLDOMNode2
*iface
, UINT iTInfo
,
371 LCID lcid
, ITypeInfo
**ppTInfo
)
373 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
374 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
378 static HRESULT WINAPI
HTMLDOMNode2_GetIDsOfNames(IHTMLDOMNode2
*iface
, REFIID riid
,
379 LPOLESTR
*rgszNames
, UINT cNames
,
380 LCID lcid
, DISPID
*rgDispId
)
382 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
383 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
388 static HRESULT WINAPI
HTMLDOMNode2_Invoke(IHTMLDOMNode2
*iface
, DISPID dispIdMember
,
389 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
390 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
392 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
393 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
394 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
398 static HRESULT WINAPI
HTMLDOMNode2_get_ownerDocument(IHTMLDOMNode2
*iface
, IDispatch
**p
)
400 HTMLDOMNode
*This
= HTMLDOMNODE2_THIS(iface
);
401 FIXME("(%p)->(%p)\n", This
, p
);
405 #undef HTMLDOMNODE2_THIS
407 static const IHTMLDOMNode2Vtbl HTMLDOMNode2Vtbl
= {
408 HTMLDOMNode2_QueryInterface
,
410 HTMLDOMNode2_Release
,
411 HTMLDOMNode2_GetTypeInfoCount
,
412 HTMLDOMNode2_GetTypeInfo
,
413 HTMLDOMNode2_GetIDsOfNames
,
415 HTMLDOMNode2_get_ownerDocument
418 HRESULT
HTMLDOMNode_QI(HTMLDOMNode
*This
, REFIID riid
, void **ppv
)
422 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
423 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
424 *ppv
= HTMLDOMNODE(This
);
425 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
426 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
427 *ppv
= HTMLDOMNODE(This
);
428 }else if(IsEqualGUID(&IID_IDispatchEx
, riid
)) {
429 if(This
->dispex
.data
) {
430 TRACE("(%p)->(IID_IDispatchEx %p)\n", This
, ppv
);
431 *ppv
= DISPATCHEX(&This
->dispex
);
433 FIXME("(%p)->(IID_IDispatchEx %p)\n", This
, ppv
);
434 return E_NOINTERFACE
;
436 }else if(IsEqualGUID(&IID_IHTMLDOMNode
, riid
)) {
437 TRACE("(%p)->(IID_IHTMLDOMNode %p)\n", This
, ppv
);
438 *ppv
= HTMLDOMNODE(This
);
439 }else if(IsEqualGUID(&IID_IHTMLDOMNode2
, riid
)) {
440 TRACE("(%p)->(IID_IHTMLDOMNode2 %p)\n", This
, ppv
);
441 *ppv
= HTMLDOMNODE2(This
);
445 IUnknown_AddRef((IUnknown
*)*ppv
);
449 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
450 return E_NOINTERFACE
;
453 void HTMLDOMNode_destructor(HTMLDOMNode
*This
)
456 nsIDOMNode_Release(This
->nsnode
);
457 if(This
->event_target
)
458 release_event_target(This
->event_target
);
461 static const NodeImplVtbl HTMLDOMNodeImplVtbl
= {
463 HTMLDOMNode_destructor
466 static HTMLDOMNode
*create_node(HTMLDocument
*doc
, nsIDOMNode
*nsnode
)
471 nsIDOMNode_GetNodeType(nsnode
, &node_type
);
475 ret
= &HTMLElement_Create(nsnode
)->node
;
478 ret
= HTMLDOMTextNode_Create(nsnode
);
481 ret
= heap_alloc_zero(sizeof(HTMLDOMNode
));
482 ret
->vtbl
= &HTMLDOMNodeImplVtbl
;
485 ret
->lpHTMLDOMNodeVtbl
= &HTMLDOMNodeVtbl
;
486 ret
->lpHTMLDOMNode2Vtbl
= &HTMLDOMNode2Vtbl
;
490 nsIDOMNode_AddRef(nsnode
);
491 ret
->nsnode
= nsnode
;
493 TRACE("type %d ret %p\n", node_type
, ret
);
500 * List looks really ugly here. We should use a better data structure or
501 * (better) find a way to store HTMLDOMelement pointer in nsIDOMNode.
504 HTMLDOMNode
*get_node(HTMLDocument
*This
, nsIDOMNode
*nsnode
, BOOL create
)
506 HTMLDOMNode
*iter
= This
->nodes
, *ret
;
509 if(iter
->nsnode
== nsnode
)
517 ret
= create_node(This
, nsnode
);
519 ret
->next
= This
->nodes
;
525 void release_nodes(HTMLDocument
*This
)
527 HTMLDOMNode
*iter
, *next
;
532 for(iter
= This
->nodes
; iter
; iter
= next
) {
535 IHTMLDOMNode_Release(HTMLDOMNODE(iter
));