mshtml: Parse and store onload attributes.
[wine/wine-jacek.git] / dlls / mshtml / htmlnode.c
blob64cabe46da70c93914c2b8008ed52f214740f77c
1 /*
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
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
28 #include "wine/debug.h"
30 #include "mshtml_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
34 #define NSSUPPORTS(x) ((nsISupports*) &(x)->lpSupportsVtbl)
36 #define HTMLDOMNODE_THIS(iface) DEFINE_THIS(HTMLDOMNode, HTMLDOMNode, iface)
38 static HRESULT WINAPI HTMLDOMNode_QueryInterface(IHTMLDOMNode *iface,
39 REFIID riid, void **ppv)
41 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
43 return This->vtbl->qi(This, riid, ppv);
46 static ULONG WINAPI HTMLDOMNode_AddRef(IHTMLDOMNode *iface)
48 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
49 LONG ref = InterlockedIncrement(&This->ref);
51 TRACE("(%p) ref=%d\n", This, ref);
53 return ref;
56 static ULONG WINAPI HTMLDOMNode_Release(IHTMLDOMNode *iface)
58 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
59 LONG ref = InterlockedDecrement(&This->ref);
61 TRACE("(%p) ref=%d\n", This, ref);
63 if(!ref) {
64 This->vtbl->destructor(This);
65 heap_free(This);
68 return ref;
71 static HRESULT WINAPI HTMLDOMNode_GetTypeInfoCount(IHTMLDOMNode *iface, UINT *pctinfo)
73 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
74 FIXME("(%p)->(%p)\n", This, pctinfo);
75 return E_NOTIMPL;
78 static HRESULT WINAPI HTMLDOMNode_GetTypeInfo(IHTMLDOMNode *iface, UINT iTInfo,
79 LCID lcid, ITypeInfo **ppTInfo)
81 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
82 FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
83 return E_NOTIMPL;
86 static HRESULT WINAPI HTMLDOMNode_GetIDsOfNames(IHTMLDOMNode *iface, REFIID riid,
87 LPOLESTR *rgszNames, UINT cNames,
88 LCID lcid, DISPID *rgDispId)
90 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
91 FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
92 lcid, rgDispId);
93 return E_NOTIMPL;
96 static HRESULT WINAPI HTMLDOMNode_Invoke(IHTMLDOMNode *iface, DISPID dispIdMember,
97 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
98 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
100 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
101 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
102 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
103 return E_NOTIMPL;
106 static HRESULT WINAPI HTMLDOMNode_get_nodeType(IHTMLDOMNode *iface, long *p)
108 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
109 FIXME("(%p)->(%p)\n", This, p);
110 return E_NOTIMPL;
113 static HRESULT WINAPI HTMLDOMNode_get_parentNode(IHTMLDOMNode *iface, IHTMLDOMNode **p)
115 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
116 FIXME("(%p)->(%p)\n", This, p);
117 return E_NOTIMPL;
120 static HRESULT WINAPI HTMLDOMNode_hasChildNodes(IHTMLDOMNode *iface, VARIANT_BOOL *fChildren)
122 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
123 FIXME("(%p)->(%p)\n", This, fChildren);
124 return E_NOTIMPL;
127 static HRESULT WINAPI HTMLDOMNode_get_childNodes(IHTMLDOMNode *iface, IDispatch **p)
129 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
130 FIXME("(%p)->(%p)\n", This, p);
131 return E_NOTIMPL;
134 static HRESULT WINAPI HTMLDOMNode_get_attributes(IHTMLDOMNode *iface, IDispatch **p)
136 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
137 FIXME("(%p)->(%p)\n", This, p);
138 return E_NOTIMPL;
141 static HRESULT WINAPI HTMLDOMNode_insertBefore(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
142 VARIANT refChild, IHTMLDOMNode **node)
144 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
145 FIXME("(%p)->(%p v %p)\n", This, newChild, node);
146 return E_NOTIMPL;
149 static HRESULT WINAPI HTMLDOMNode_removeChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
150 IHTMLDOMNode **node)
152 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
153 FIXME("(%p)->(%p %p)\n", This, newChild, node);
154 return E_NOTIMPL;
157 static HRESULT WINAPI HTMLDOMNode_replaceChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
158 IHTMLDOMNode *oldChild, IHTMLDOMNode **node)
160 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
161 FIXME("(%p)->(%p %p %p)\n", This, newChild, oldChild, node);
162 return E_NOTIMPL;
165 static HRESULT WINAPI HTMLDOMNode_cloneNode(IHTMLDOMNode *iface, VARIANT_BOOL fDeep,
166 IHTMLDOMNode **clonedNode)
168 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
169 FIXME("(%p)->(%x %p)\n", This, fDeep, clonedNode);
170 return E_NOTIMPL;
173 static HRESULT WINAPI HTMLDOMNode_removeNode(IHTMLDOMNode *iface, VARIANT_BOOL fDeep,
174 IHTMLDOMNode **removed)
176 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
177 FIXME("(%p)->(%x %p)\n", This, fDeep, removed);
178 return E_NOTIMPL;
181 static HRESULT WINAPI HTMLDOMNode_swapNode(IHTMLDOMNode *iface, IHTMLDOMNode *otherNode,
182 IHTMLDOMNode **swappedNode)
184 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
185 FIXME("(%p)->(%p %p)\n", This, otherNode, swappedNode);
186 return E_NOTIMPL;
189 static HRESULT WINAPI HTMLDOMNode_replaceNode(IHTMLDOMNode *iface, IHTMLDOMNode *replacement,
190 IHTMLDOMNode **replaced)
192 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
193 FIXME("(%p)->(%p %p)\n", This, replacement, replaced);
194 return E_NOTIMPL;
197 static HRESULT WINAPI HTMLDOMNode_appendChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
198 IHTMLDOMNode **node)
200 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
201 FIXME("(%p)->(%p %p)\n", This, newChild, node);
202 return E_NOTIMPL;
205 static HRESULT WINAPI HTMLDOMNode_get_nodeName(IHTMLDOMNode *iface, BSTR *p)
207 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
209 TRACE("(%p)->(%p)\n", This, p);
211 *p = NULL;
213 if(This->nsnode) {
214 nsAString name_str;
215 const PRUnichar *name;
216 nsresult nsres;
218 nsAString_Init(&name_str, NULL);
219 nsres = nsIDOMNode_GetNodeName(This->nsnode, &name_str);
221 if(NS_SUCCEEDED(nsres)) {
222 nsAString_GetData(&name_str, &name);
223 *p = SysAllocString(name);
224 }else {
225 ERR("GetNodeName failed: %08x\n", nsres);
228 nsAString_Finish(&name_str);
231 return S_OK;
234 static HRESULT WINAPI HTMLDOMNode_put_nodeValue(IHTMLDOMNode *iface, VARIANT v)
236 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
237 FIXME("(%p)->()\n", This);
238 return E_NOTIMPL;
241 static HRESULT WINAPI HTMLDOMNode_get_nodeValue(IHTMLDOMNode *iface, VARIANT *p)
243 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
244 FIXME("(%p)->(%p)\n", This, p);
245 return E_NOTIMPL;
248 static HRESULT WINAPI HTMLDOMNode_get_firstChild(IHTMLDOMNode *iface, IHTMLDOMNode **p)
250 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
251 FIXME("(%p)->(%p)\n", This, p);
252 return E_NOTIMPL;
255 static HRESULT WINAPI HTMLDOMNode_get_lastChild(IHTMLDOMNode *iface, IHTMLDOMNode **p)
257 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
258 FIXME("(%p)->(%p)\n", This, p);
259 return E_NOTIMPL;
262 static HRESULT WINAPI HTMLDOMNode_get_previousSibling(IHTMLDOMNode *iface, IHTMLDOMNode **p)
264 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
265 FIXME("(%p)->(%p)\n", This, p);
266 return E_NOTIMPL;
269 static HRESULT WINAPI HTMLDOMNode_get_nextSibling(IHTMLDOMNode *iface, IHTMLDOMNode **p)
271 HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
272 FIXME("(%p)->(%p)\n", This, p);
273 return E_NOTIMPL;
276 static const IHTMLDOMNodeVtbl HTMLDOMNodeVtbl = {
277 HTMLDOMNode_QueryInterface,
278 HTMLDOMNode_AddRef,
279 HTMLDOMNode_Release,
280 HTMLDOMNode_GetTypeInfoCount,
281 HTMLDOMNode_GetTypeInfo,
282 HTMLDOMNode_GetIDsOfNames,
283 HTMLDOMNode_Invoke,
284 HTMLDOMNode_get_nodeType,
285 HTMLDOMNode_get_parentNode,
286 HTMLDOMNode_hasChildNodes,
287 HTMLDOMNode_get_childNodes,
288 HTMLDOMNode_get_attributes,
289 HTMLDOMNode_insertBefore,
290 HTMLDOMNode_removeChild,
291 HTMLDOMNode_replaceChild,
292 HTMLDOMNode_cloneNode,
293 HTMLDOMNode_removeNode,
294 HTMLDOMNode_swapNode,
295 HTMLDOMNode_replaceNode,
296 HTMLDOMNode_appendChild,
297 HTMLDOMNode_get_nodeName,
298 HTMLDOMNode_put_nodeValue,
299 HTMLDOMNode_get_nodeValue,
300 HTMLDOMNode_get_firstChild,
301 HTMLDOMNode_get_lastChild,
302 HTMLDOMNode_get_previousSibling,
303 HTMLDOMNode_get_nextSibling
306 HRESULT HTMLDOMNode_QI(HTMLDOMNode *This, REFIID riid, void **ppv)
308 *ppv = NULL;
310 if(IsEqualGUID(&IID_IUnknown, riid)) {
311 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
312 *ppv = HTMLDOMNODE(This);
313 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
314 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
315 *ppv = HTMLDOMNODE(This);
316 }else if(IsEqualGUID(&IID_IHTMLDOMNode, riid)) {
317 TRACE("(%p)->(IID_IHTMLDOMNode %p)\n", This, ppv);
318 *ppv = HTMLDOMNODE(This);
321 if(*ppv) {
322 IUnknown_AddRef((IUnknown*)*ppv);
323 return S_OK;
326 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
327 return E_NOINTERFACE;
330 void HTMLDOMNode_destructor(HTMLDOMNode *This)
332 if(This->nsnode)
333 nsIDOMNode_Release(This->nsnode);
334 if(This->event_target)
335 release_event_target(This->event_target);
338 static const NodeImplVtbl HTMLDOMNodeImplVtbl = {
339 HTMLDOMNode_QI,
340 HTMLDOMNode_destructor
343 static HTMLDOMNode *create_node(HTMLDocument *doc, nsIDOMNode *nsnode)
345 HTMLDOMNode *ret;
346 PRUint16 node_type;
348 nsIDOMNode_GetNodeType(nsnode, &node_type);
350 switch(node_type) {
351 case ELEMENT_NODE:
352 ret = &HTMLElement_Create(nsnode)->node;
353 break;
354 default:
355 ret = heap_alloc(sizeof(HTMLDOMNode));
356 ret->vtbl = &HTMLDOMNodeImplVtbl;
359 ret->lpHTMLDOMNodeVtbl = &HTMLDOMNodeVtbl;
360 ret->ref = 1;
361 ret->doc = doc;
362 ret->event_target = NULL;
364 nsIDOMNode_AddRef(nsnode);
365 ret->nsnode = nsnode;
367 return ret;
371 * FIXME
372 * List looks really ugly here. We should use a better data structure or
373 * (better) find a way to store HTMLDOMelement pointer in nsIDOMNode.
376 HTMLDOMNode *get_node(HTMLDocument *This, nsIDOMNode *nsnode, BOOL create)
378 HTMLDOMNode *iter = This->nodes, *ret;
380 while(iter) {
381 if(iter->nsnode == nsnode)
382 break;
383 iter = iter->next;
386 if(iter || !create)
387 return iter;
389 ret = create_node(This, nsnode);
391 ret->next = This->nodes;
392 This->nodes = ret;
394 return ret;
397 void release_nodes(HTMLDocument *This)
399 HTMLDOMNode *iter, *next;
401 if(!This->nodes)
402 return;
404 for(iter = This->nodes; iter; iter = next) {
405 next = iter->next;
406 iter->doc = NULL;
407 IHTMLDOMNode_Release(HTMLDOMNODE(iter));