mshtml: Added noscript tag handling tests.
[wine] / dlls / mshtml / htmliframe.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27
28 #include "mshtml_private.h"
29
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
33
34 typedef struct {
35     HTMLFrameBase framebase;
36     IHTMLIFrameElement IHTMLIFrameElement_iface;
37     IHTMLIFrameElement2 IHTMLIFrameElement2_iface;
38     IHTMLIFrameElement3 IHTMLIFrameElement3_iface;
39 } HTMLIFrame;
40
41 static inline HTMLIFrame *impl_from_IHTMLIFrameElement(IHTMLIFrameElement *iface)
42 {
43     return CONTAINING_RECORD(iface, HTMLIFrame, IHTMLIFrameElement_iface);
44 }
45
46 static HRESULT WINAPI HTMLIFrameElement_QueryInterface(IHTMLIFrameElement *iface,
47         REFIID riid, void **ppv)
48 {
49     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
50
51     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
52 }
53
54 static ULONG WINAPI HTMLIFrameElement_AddRef(IHTMLIFrameElement *iface)
55 {
56     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
57
58     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
59 }
60
61 static ULONG WINAPI HTMLIFrameElement_Release(IHTMLIFrameElement *iface)
62 {
63     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
64
65     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
66 }
67
68 static HRESULT WINAPI HTMLIFrameElement_GetTypeInfoCount(IHTMLIFrameElement *iface, UINT *pctinfo)
69 {
70     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
71     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
72             pctinfo);
73 }
74
75 static HRESULT WINAPI HTMLIFrameElement_GetTypeInfo(IHTMLIFrameElement *iface, UINT iTInfo,
76         LCID lcid, ITypeInfo **ppTInfo)
77 {
78     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
79     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
80             lcid, ppTInfo);
81 }
82
83 static HRESULT WINAPI HTMLIFrameElement_GetIDsOfNames(IHTMLIFrameElement *iface, REFIID riid,
84         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
85 {
86     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
87     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
88             rgszNames, cNames, lcid, rgDispId);
89 }
90
91 static HRESULT WINAPI HTMLIFrameElement_Invoke(IHTMLIFrameElement *iface, DISPID dispIdMember,
92         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
93         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
94 {
95     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
96     return IDispatchEx_Invoke(&This->framebase.element.node.dispex.IDispatchEx_iface, dispIdMember,
97             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
98 }
99
100 static HRESULT WINAPI HTMLIFrameElement_put_vspace(IHTMLIFrameElement *iface, LONG v)
101 {
102     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
103     FIXME("(%p)->(%d)\n", This, v);
104     return E_NOTIMPL;
105 }
106
107 static HRESULT WINAPI HTMLIFrameElement_get_vspace(IHTMLIFrameElement *iface, LONG *p)
108 {
109     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
110     FIXME("(%p)->(%p)\n", This, p);
111     return E_NOTIMPL;
112 }
113
114 static HRESULT WINAPI HTMLIFrameElement_put_hspace(IHTMLIFrameElement *iface, LONG v)
115 {
116     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
117     FIXME("(%p)->(%d)\n", This, v);
118     return E_NOTIMPL;
119 }
120
121 static HRESULT WINAPI HTMLIFrameElement_get_hspace(IHTMLIFrameElement *iface, LONG *p)
122 {
123     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
124     FIXME("(%p)->(%p)\n", This, p);
125     return E_NOTIMPL;
126 }
127
128 static HRESULT WINAPI HTMLIFrameElement_put_align(IHTMLIFrameElement *iface, BSTR v)
129 {
130     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
131     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
132     return E_NOTIMPL;
133 }
134
135 static HRESULT WINAPI HTMLIFrameElement_get_align(IHTMLIFrameElement *iface, BSTR *p)
136 {
137     HTMLIFrame *This = impl_from_IHTMLIFrameElement(iface);
138     FIXME("(%p)->(%p)\n", This, p);
139     return E_NOTIMPL;
140 }
141
142 static const IHTMLIFrameElementVtbl HTMLIFrameElementVtbl = {
143     HTMLIFrameElement_QueryInterface,
144     HTMLIFrameElement_AddRef,
145     HTMLIFrameElement_Release,
146     HTMLIFrameElement_GetTypeInfoCount,
147     HTMLIFrameElement_GetTypeInfo,
148     HTMLIFrameElement_GetIDsOfNames,
149     HTMLIFrameElement_Invoke,
150     HTMLIFrameElement_put_vspace,
151     HTMLIFrameElement_get_vspace,
152     HTMLIFrameElement_put_hspace,
153     HTMLIFrameElement_get_hspace,
154     HTMLIFrameElement_put_align,
155     HTMLIFrameElement_get_align
156 };
157
158 static inline HTMLIFrame *impl_from_IHTMLIFrameElement2(IHTMLIFrameElement2 *iface)
159 {
160     return CONTAINING_RECORD(iface, HTMLIFrame, IHTMLIFrameElement2_iface);
161 }
162
163 static HRESULT WINAPI HTMLIFrameElement2_QueryInterface(IHTMLIFrameElement2 *iface,
164         REFIID riid, void **ppv)
165 {
166     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
167
168     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
169 }
170
171 static ULONG WINAPI HTMLIFrameElement2_AddRef(IHTMLIFrameElement2 *iface)
172 {
173     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
174
175     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
176 }
177
178 static ULONG WINAPI HTMLIFrameElement2_Release(IHTMLIFrameElement2 *iface)
179 {
180     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
181
182     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
183 }
184
185 static HRESULT WINAPI HTMLIFrameElement2_GetTypeInfoCount(IHTMLIFrameElement2 *iface, UINT *pctinfo)
186 {
187     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
188     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
189             pctinfo);
190 }
191
192 static HRESULT WINAPI HTMLIFrameElement2_GetTypeInfo(IHTMLIFrameElement2 *iface, UINT iTInfo,
193         LCID lcid, ITypeInfo **ppTInfo)
194 {
195     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
196     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
197             lcid, ppTInfo);
198 }
199
200 static HRESULT WINAPI HTMLIFrameElement2_GetIDsOfNames(IHTMLIFrameElement2 *iface, REFIID riid,
201         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
202 {
203     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
204     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
205             rgszNames, cNames, lcid, rgDispId);
206 }
207
208 static HRESULT WINAPI HTMLIFrameElement2_Invoke(IHTMLIFrameElement2 *iface, DISPID dispIdMember,
209         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
210         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
211 {
212     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
213     return IDispatchEx_Invoke(&This->framebase.element.node.dispex.IDispatchEx_iface, dispIdMember,
214             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
215 }
216
217 static HRESULT WINAPI HTMLIFrameElement2_put_height(IHTMLIFrameElement2 *iface, VARIANT v)
218 {
219     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
220     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
221     return E_NOTIMPL;
222 }
223
224 static HRESULT WINAPI HTMLIFrameElement2_get_height(IHTMLIFrameElement2 *iface, VARIANT *p)
225 {
226     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
227     FIXME("(%p)->(%p)\n", This, p);
228     return E_NOTIMPL;
229 }
230
231 static HRESULT WINAPI HTMLIFrameElement2_put_width(IHTMLIFrameElement2 *iface, VARIANT v)
232 {
233     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
234     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
235     return E_NOTIMPL;
236 }
237
238 static HRESULT WINAPI HTMLIFrameElement2_get_width(IHTMLIFrameElement2 *iface, VARIANT *p)
239 {
240     HTMLIFrame *This = impl_from_IHTMLIFrameElement2(iface);
241     FIXME("(%p)->(%p)\n", This, p);
242     return E_NOTIMPL;
243 }
244
245 static const IHTMLIFrameElement2Vtbl HTMLIFrameElement2Vtbl = {
246     HTMLIFrameElement2_QueryInterface,
247     HTMLIFrameElement2_AddRef,
248     HTMLIFrameElement2_Release,
249     HTMLIFrameElement2_GetTypeInfoCount,
250     HTMLIFrameElement2_GetTypeInfo,
251     HTMLIFrameElement2_GetIDsOfNames,
252     HTMLIFrameElement2_Invoke,
253     HTMLIFrameElement2_put_height,
254     HTMLIFrameElement2_get_height,
255     HTMLIFrameElement2_put_width,
256     HTMLIFrameElement2_get_width
257 };
258
259 static inline HTMLIFrame *impl_from_IHTMLIFrameElement3(IHTMLIFrameElement3 *iface)
260 {
261     return CONTAINING_RECORD(iface, HTMLIFrame, IHTMLIFrameElement3_iface);
262 }
263
264 static HRESULT WINAPI HTMLIFrameElement3_QueryInterface(IHTMLIFrameElement3 *iface,
265         REFIID riid, void **ppv)
266 {
267     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
268
269     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
270 }
271
272 static ULONG WINAPI HTMLIFrameElement3_AddRef(IHTMLIFrameElement3 *iface)
273 {
274     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
275
276     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
277 }
278
279 static ULONG WINAPI HTMLIFrameElement3_Release(IHTMLIFrameElement3 *iface)
280 {
281     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
282
283     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
284 }
285
286 static HRESULT WINAPI HTMLIFrameElement3_GetTypeInfoCount(IHTMLIFrameElement3 *iface, UINT *pctinfo)
287 {
288     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
289     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.dispex.IDispatchEx_iface,
290             pctinfo);
291 }
292
293 static HRESULT WINAPI HTMLIFrameElement3_GetTypeInfo(IHTMLIFrameElement3 *iface, UINT iTInfo,
294         LCID lcid, ITypeInfo **ppTInfo)
295 {
296     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
297     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.dispex.IDispatchEx_iface, iTInfo,
298             lcid, ppTInfo);
299 }
300
301 static HRESULT WINAPI HTMLIFrameElement3_GetIDsOfNames(IHTMLIFrameElement3 *iface, REFIID riid,
302         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
303 {
304     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
305     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.dispex.IDispatchEx_iface, riid,
306             rgszNames, cNames, lcid, rgDispId);
307 }
308
309 static HRESULT WINAPI HTMLIFrameElement3_Invoke(IHTMLIFrameElement3 *iface, DISPID dispIdMember,
310         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
311         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
312 {
313     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
314     return IDispatchEx_Invoke(&This->framebase.element.node.dispex.IDispatchEx_iface, dispIdMember,
315             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
316 }
317
318 static HRESULT WINAPI HTMLIFrameElement3_get_contentDocument(IHTMLIFrameElement3 *iface, IDispatch **p)
319 {
320     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
321     FIXME("(%p)->(%p)\n", This, p);
322     return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI HTMLIFrameElement3_put_src(IHTMLIFrameElement3 *iface, BSTR v)
326 {
327     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
328     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
329     return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI HTMLIFrameElement3_get_src(IHTMLIFrameElement3 *iface, BSTR *p)
333 {
334     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
335     FIXME("(%p)->(%p)\n", This, p);
336     return E_NOTIMPL;
337 }
338
339 static HRESULT WINAPI HTMLIFrameElement3_put_longDesc(IHTMLIFrameElement3 *iface, BSTR v)
340 {
341     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
342     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
343     return E_NOTIMPL;
344 }
345
346 static HRESULT WINAPI HTMLIFrameElement3_get_longDesc(IHTMLIFrameElement3 *iface, BSTR *p)
347 {
348     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
349     FIXME("(%p)->(%p)\n", This, p);
350     return E_NOTIMPL;
351 }
352
353 static HRESULT WINAPI HTMLIFrameElement3_put_frameBorder(IHTMLIFrameElement3 *iface, BSTR v)
354 {
355     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
356     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
357     return E_NOTIMPL;
358 }
359
360 static HRESULT WINAPI HTMLIFrameElement3_get_frameBorder(IHTMLIFrameElement3 *iface, BSTR *p)
361 {
362     HTMLIFrame *This = impl_from_IHTMLIFrameElement3(iface);
363     FIXME("(%p)->(%p)\n", This, p);
364     return E_NOTIMPL;
365 }
366
367 static const IHTMLIFrameElement3Vtbl HTMLIFrameElement3Vtbl = {
368     HTMLIFrameElement3_QueryInterface,
369     HTMLIFrameElement3_AddRef,
370     HTMLIFrameElement3_Release,
371     HTMLIFrameElement3_GetTypeInfoCount,
372     HTMLIFrameElement3_GetTypeInfo,
373     HTMLIFrameElement3_GetIDsOfNames,
374     HTMLIFrameElement3_Invoke,
375     HTMLIFrameElement3_get_contentDocument,
376     HTMLIFrameElement3_put_src,
377     HTMLIFrameElement3_get_src,
378     HTMLIFrameElement3_put_longDesc,
379     HTMLIFrameElement3_get_longDesc,
380     HTMLIFrameElement3_put_frameBorder,
381     HTMLIFrameElement3_get_frameBorder
382 };
383
384 static inline HTMLIFrame *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
385 {
386     return CONTAINING_RECORD(iface, HTMLIFrame, framebase.element.node);
387 }
388
389 static HRESULT HTMLIFrame_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
390 {
391     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
392
393     if(IsEqualGUID(&IID_IHTMLIFrameElement, riid)) {
394         TRACE("(%p)->(IID_IHTMLIFrameElement %p)\n", This, ppv);
395         *ppv = &This->IHTMLIFrameElement_iface;
396     }else if(IsEqualGUID(&IID_IHTMLIFrameElement2, riid)) {
397         TRACE("(%p)->(IID_IHTMLIFrameElement2 %p)\n", This, ppv);
398         *ppv = &This->IHTMLIFrameElement2_iface;
399     }else if(IsEqualGUID(&IID_IHTMLIFrameElement3, riid)) {
400         TRACE("(%p)->(IID_IHTMLIFrameElement3 %p)\n", This, ppv);
401         *ppv = &This->IHTMLIFrameElement3_iface;
402     }else {
403         return HTMLFrameBase_QI(&This->framebase, riid, ppv);
404     }
405
406     IUnknown_AddRef((IUnknown*)*ppv);
407     return S_OK;
408 }
409
410 static void HTMLIFrame_destructor(HTMLDOMNode *iface)
411 {
412     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
413
414     HTMLFrameBase_destructor(&This->framebase);
415 }
416
417 static HRESULT HTMLIFrame_get_document(HTMLDOMNode *iface, IDispatch **p)
418 {
419     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
420
421     if(!This->framebase.content_window || !This->framebase.content_window->base.inner_window->doc) {
422         *p = NULL;
423         return S_OK;
424     }
425
426     *p = (IDispatch*)&This->framebase.content_window->base.inner_window->doc->basedoc.IHTMLDocument2_iface;
427     IDispatch_AddRef(*p);
428     return S_OK;
429 }
430
431 static HRESULT HTMLIFrame_get_dispid(HTMLDOMNode *iface, BSTR name,
432         DWORD grfdex, DISPID *pid)
433 {
434     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
435
436     if(!This->framebase.content_window)
437         return DISP_E_UNKNOWNNAME;
438
439     return search_window_props(This->framebase.content_window->base.inner_window, name, grfdex, pid);
440 }
441
442 static HRESULT HTMLIFrame_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
443         WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
444 {
445     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
446
447     if(!This->framebase.content_window) {
448         ERR("no content window to invoke on\n");
449         return E_FAIL;
450     }
451
452     return IDispatchEx_InvokeEx(&This->framebase.content_window->base.IDispatchEx_iface, id, lcid,
453             flags, params, res, ei, caller);
454 }
455
456 static HRESULT HTMLIFrame_get_readystate(HTMLDOMNode *iface, BSTR *p)
457 {
458     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
459
460     return IHTMLFrameBase2_get_readyState(&This->framebase.IHTMLFrameBase2_iface, p);
461 }
462
463 static HRESULT HTMLIFrame_bind_to_tree(HTMLDOMNode *iface)
464 {
465     HTMLIFrame *This = impl_from_HTMLDOMNode(iface);
466     nsIDOMDocument *nsdoc;
467     nsresult nsres;
468     HRESULT hres;
469
470     nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->framebase.nsiframe, &nsdoc);
471     if(NS_FAILED(nsres) || !nsdoc) {
472         ERR("GetContentDocument failed: %08x\n", nsres);
473         return E_FAIL;
474     }
475
476     hres = set_frame_doc(&This->framebase, nsdoc);
477     nsIDOMDocument_Release(nsdoc);
478     return hres;
479 }
480
481 static const NodeImplVtbl HTMLIFrameImplVtbl = {
482     HTMLIFrame_QI,
483     HTMLIFrame_destructor,
484     HTMLElement_clone,
485     HTMLElement_handle_event,
486     HTMLElement_get_attr_col,
487     NULL,
488     NULL,
489     NULL,
490     NULL,
491     HTMLIFrame_get_document,
492     HTMLIFrame_get_readystate,
493     HTMLIFrame_get_dispid,
494     HTMLIFrame_invoke,
495     HTMLIFrame_bind_to_tree
496 };
497
498 static const tid_t HTMLIFrame_iface_tids[] = {
499     HTMLELEMENT_TIDS,
500     IHTMLFrameBase_tid,
501     IHTMLFrameBase2_tid,
502     IHTMLIFrameElement_tid,
503     IHTMLIFrameElement2_tid,
504     IHTMLIFrameElement3_tid,
505     0
506 };
507
508 static dispex_static_data_t HTMLIFrame_dispex = {
509     NULL,
510     DispHTMLIFrame_tid,
511     NULL,
512     HTMLIFrame_iface_tids
513 };
514
515 HRESULT HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
516 {
517     HTMLIFrame *ret;
518
519     ret = heap_alloc_zero(sizeof(HTMLIFrame));
520     if(!ret)
521         return E_OUTOFMEMORY;
522
523     ret->IHTMLIFrameElement_iface.lpVtbl = &HTMLIFrameElementVtbl;
524     ret->IHTMLIFrameElement2_iface.lpVtbl = &HTMLIFrameElement2Vtbl;
525     ret->IHTMLIFrameElement3_iface.lpVtbl = &HTMLIFrameElement3Vtbl;
526     ret->framebase.element.node.vtbl = &HTMLIFrameImplVtbl;
527
528     HTMLFrameBase_Init(&ret->framebase, doc, nselem, &HTMLIFrame_dispex);
529
530     *elem = &ret->framebase.element;
531     return S_OK;
532 }