atl80: Added AtlComModuleRegisterServer implementation (based on AtlModuleRegisterSer...
[wine] / dlls / mshtml / htmlframebase.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 #include <assert.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
28
29 #include "mshtml_private.h"
30 #include "binding.h"
31
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
35
36 static const WCHAR autoW[] = {'a','u','t','o',0};
37 static const WCHAR yesW[] = {'y','e','s',0};
38 static const WCHAR noW[] = {'n','o',0};
39 static const WCHAR pxW[] = {'p','x',0};
40
41 HRESULT set_frame_doc(HTMLFrameBase *frame, nsIDOMDocument *nsdoc)
42 {
43     nsIDOMWindow *nswindow;
44     HTMLOuterWindow *window;
45     nsresult nsres;
46     HRESULT hres = S_OK;
47
48     if(frame->content_window)
49         return S_OK;
50
51     nsres = nsIDOMDocument_GetDefaultView(nsdoc, &nswindow);
52     if(NS_FAILED(nsres) || !nswindow)
53         return E_FAIL;
54
55     window = nswindow_to_window(nswindow);
56     if(!window)
57         hres = HTMLOuterWindow_Create(frame->element.node.doc->basedoc.doc_obj, nswindow,
58                 frame->element.node.doc->basedoc.window, &window);
59     nsIDOMWindow_Release(nswindow);
60     if(FAILED(hres))
61         return hres;
62
63     frame->content_window = window;
64     window->frame_element = frame;
65     return S_OK;
66 }
67
68 static inline HTMLFrameBase *impl_from_IHTMLFrameBase(IHTMLFrameBase *iface)
69 {
70     return CONTAINING_RECORD(iface, HTMLFrameBase, IHTMLFrameBase_iface);
71 }
72
73 static HRESULT WINAPI HTMLFrameBase_QueryInterface(IHTMLFrameBase *iface, REFIID riid, void **ppv)
74 {
75     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
76
77     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
78 }
79
80 static ULONG WINAPI HTMLFrameBase_AddRef(IHTMLFrameBase *iface)
81 {
82     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
83
84     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
85 }
86
87 static ULONG WINAPI HTMLFrameBase_Release(IHTMLFrameBase *iface)
88 {
89     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
90
91     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
92 }
93
94 static HRESULT WINAPI HTMLFrameBase_GetTypeInfoCount(IHTMLFrameBase *iface, UINT *pctinfo)
95 {
96     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
97
98     return IDispatchEx_GetTypeInfoCount(&This->element.node.dispex.IDispatchEx_iface, pctinfo);
99 }
100
101 static HRESULT WINAPI HTMLFrameBase_GetTypeInfo(IHTMLFrameBase *iface, UINT iTInfo,
102         LCID lcid, ITypeInfo **ppTInfo)
103 {
104     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
105
106     return IDispatchEx_GetTypeInfo(&This->element.node.dispex.IDispatchEx_iface, iTInfo, lcid,
107             ppTInfo);
108 }
109
110 static HRESULT WINAPI HTMLFrameBase_GetIDsOfNames(IHTMLFrameBase *iface, REFIID riid,
111         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
112 {
113     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
114
115     return IDispatchEx_GetIDsOfNames(&This->element.node.dispex.IDispatchEx_iface, riid, rgszNames,
116             cNames, lcid, rgDispId);
117 }
118
119 static HRESULT WINAPI HTMLFrameBase_Invoke(IHTMLFrameBase *iface, DISPID dispIdMember,
120         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
121         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
122 {
123     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
124
125     return IDispatchEx_Invoke(&This->element.node.dispex.IDispatchEx_iface, dispIdMember, riid,
126             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
127 }
128
129 static HRESULT WINAPI HTMLFrameBase_put_src(IHTMLFrameBase *iface, BSTR v)
130 {
131     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
132
133     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
134
135     if(!This->content_window || !This->element.node.doc || !This->element.node.doc->basedoc.window) {
136         FIXME("detached element\n");
137         return E_FAIL;
138     }
139
140     return navigate_url(This->content_window, v, This->element.node.doc->basedoc.window->uri, BINDING_NAVIGATED);
141 }
142
143 static HRESULT WINAPI HTMLFrameBase_get_src(IHTMLFrameBase *iface, BSTR *p)
144 {
145     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
146     FIXME("(%p)->(%p)\n", This, p);
147     return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI HTMLFrameBase_put_name(IHTMLFrameBase *iface, BSTR v)
151 {
152     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
153     nsAString name_str;
154     nsresult nsres;
155
156     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
157
158     if(!This->nsframe && !This->nsiframe) {
159         ERR("No attached ns frame object\n");
160         return E_UNEXPECTED;
161     }
162
163     nsAString_InitDepend(&name_str, v);
164     if(This->nsframe)
165         nsres = nsIDOMHTMLFrameElement_SetName(This->nsframe, &name_str);
166     else
167         nsres = nsIDOMHTMLIFrameElement_SetName(This->nsiframe, &name_str);
168     nsAString_Finish(&name_str);
169     if(NS_FAILED(nsres)) {
170         ERR("SetName failed: %08x\n", nsres);
171         return E_FAIL;
172     }
173
174     return S_OK;
175 }
176
177 static HRESULT WINAPI HTMLFrameBase_get_name(IHTMLFrameBase *iface, BSTR *p)
178 {
179     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
180     nsAString nsstr;
181     nsresult nsres;
182
183     TRACE("(%p)->(%p)\n", This, p);
184
185     if(!This->nsframe && !This->nsiframe) {
186         ERR("No attached ns frame object\n");
187         return E_UNEXPECTED;
188     }
189
190     nsAString_Init(&nsstr, NULL);
191     if(This->nsframe)
192         nsres = nsIDOMHTMLFrameElement_GetName(This->nsframe, &nsstr);
193     else
194         nsres = nsIDOMHTMLIFrameElement_GetName(This->nsiframe, &nsstr);
195     return return_nsstr(nsres, &nsstr, p);
196 }
197
198 static HRESULT WINAPI HTMLFrameBase_put_border(IHTMLFrameBase *iface, VARIANT v)
199 {
200     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
201     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
202     return E_NOTIMPL;
203 }
204
205 static HRESULT WINAPI HTMLFrameBase_get_border(IHTMLFrameBase *iface, VARIANT *p)
206 {
207     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
208     FIXME("(%p)->(%p)\n", This, p);
209     return E_NOTIMPL;
210 }
211
212 static HRESULT WINAPI HTMLFrameBase_put_frameBorder(IHTMLFrameBase *iface, BSTR v)
213 {
214     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
215     nsAString nsstr;
216     nsresult nsres;
217
218     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
219
220     if(!This->nsframe && !This->nsiframe) {
221         ERR("No attached ns frame object\n");
222         return E_UNEXPECTED;
223     }
224
225     nsAString_InitDepend(&nsstr, v);
226     if(This->nsframe)
227         nsres = nsIDOMHTMLFrameElement_SetFrameBorder(This->nsframe, &nsstr);
228     else
229         nsres = nsIDOMHTMLIFrameElement_SetFrameBorder(This->nsiframe, &nsstr);
230     nsAString_Finish(&nsstr);
231     if(NS_FAILED(nsres)) {
232         ERR("SetFrameBorder failed: %08x\n", nsres);
233         return E_FAIL;
234     }
235
236     return S_OK;
237 }
238
239 static HRESULT WINAPI HTMLFrameBase_get_frameBorder(IHTMLFrameBase *iface, BSTR *p)
240 {
241     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
242     nsAString nsstr;
243     nsresult nsres;
244
245     TRACE("(%p)->(%p)\n", This, p);
246
247     if(!This->nsframe && !This->nsiframe) {
248         ERR("No attached ns frame object\n");
249         return E_UNEXPECTED;
250     }
251
252     nsAString_Init(&nsstr, NULL);
253     if(This->nsframe)
254         nsres = nsIDOMHTMLFrameElement_GetFrameBorder(This->nsframe, &nsstr);
255     else
256         nsres = nsIDOMHTMLIFrameElement_GetFrameBorder(This->nsiframe, &nsstr);
257     return return_nsstr(nsres, &nsstr, p);
258 }
259
260 static HRESULT WINAPI HTMLFrameBase_put_frameSpacing(IHTMLFrameBase *iface, VARIANT v)
261 {
262     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
263     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
264     return E_NOTIMPL;
265 }
266
267 static HRESULT WINAPI HTMLFrameBase_get_frameSpacing(IHTMLFrameBase *iface, VARIANT *p)
268 {
269     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
270     FIXME("(%p)->(%p)\n", This, p);
271     return E_NOTIMPL;
272 }
273
274 static HRESULT WINAPI HTMLFrameBase_put_marginWidth(IHTMLFrameBase *iface, VARIANT v)
275 {
276     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
277     nsAString nsstr;
278     nsresult nsres;
279
280     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
281
282     if(V_VT(&v) != VT_BSTR) {
283         FIXME("unsupported %s\n", debugstr_variant(&v));
284         return E_NOTIMPL;
285     }
286
287     nsAString_InitDepend(&nsstr, V_BSTR(&v));
288     if(This->nsframe)
289         nsres = nsIDOMHTMLFrameElement_SetMarginWidth(This->nsframe, &nsstr);
290     else
291         nsres = nsIDOMHTMLIFrameElement_SetMarginWidth(This->nsiframe, &nsstr);
292     nsAString_Finish(&nsstr);
293     return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
294 }
295
296 static HRESULT WINAPI HTMLFrameBase_get_marginWidth(IHTMLFrameBase *iface, VARIANT *p)
297 {
298     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
299     nsAString nsstr;
300     nsresult nsres;
301     HRESULT hres = S_OK;
302
303     TRACE("(%p)->(%p)\n", This, p);
304
305     nsAString_Init(&nsstr, NULL);
306     if(This->nsframe)
307         nsres = nsIDOMHTMLFrameElement_GetMarginWidth(This->nsframe, &nsstr);
308     else
309         nsres = nsIDOMHTMLIFrameElement_GetMarginWidth(This->nsiframe, &nsstr);
310     if(NS_SUCCEEDED(nsres)) {
311         const PRUnichar *str, *end;
312
313         nsAString_GetData(&nsstr, &str);
314
315         if(*str) {
316             BSTR ret;
317
318             end = strstrW(str, pxW);
319             if(!end)
320                 end = str+strlenW(str);
321             ret = SysAllocStringLen(str, end-str);
322             if(ret) {
323                 V_VT(p) = VT_BSTR;
324                 V_BSTR(p) = ret;
325             }else {
326                 hres = E_OUTOFMEMORY;
327             }
328         }else {
329             V_VT(p) = VT_BSTR;
330             V_BSTR(p) = NULL;
331         }
332     }else {
333         ERR("GetMarginWidth failed: %08x\n", nsres);
334         hres = E_FAIL;
335     }
336
337     nsAString_Finish(&nsstr);
338     return hres;
339 }
340
341 static HRESULT WINAPI HTMLFrameBase_put_marginHeight(IHTMLFrameBase *iface, VARIANT v)
342 {
343     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
344     nsAString nsstr;
345     nsresult nsres;
346
347     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
348
349     if(V_VT(&v) != VT_BSTR) {
350         FIXME("unsupported %s\n", debugstr_variant(&v));
351         return E_NOTIMPL;
352     }
353
354     nsAString_InitDepend(&nsstr, V_BSTR(&v));
355     if(This->nsframe)
356         nsres = nsIDOMHTMLFrameElement_SetMarginHeight(This->nsframe, &nsstr);
357     else
358         nsres = nsIDOMHTMLIFrameElement_SetMarginHeight(This->nsiframe, &nsstr);
359     nsAString_Finish(&nsstr);
360     return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
361 }
362
363 static HRESULT WINAPI HTMLFrameBase_get_marginHeight(IHTMLFrameBase *iface, VARIANT *p)
364 {
365     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
366     nsAString nsstr;
367     nsresult nsres;
368     HRESULT hres = S_OK;
369
370     TRACE("(%p)->(%p)\n", This, p);
371
372     nsAString_Init(&nsstr, NULL);
373     if(This->nsframe)
374         nsres = nsIDOMHTMLFrameElement_GetMarginHeight(This->nsframe, &nsstr);
375     else
376         nsres = nsIDOMHTMLIFrameElement_GetMarginHeight(This->nsiframe, &nsstr);
377     if(NS_SUCCEEDED(nsres)) {
378         const PRUnichar *str, *end;
379
380         nsAString_GetData(&nsstr, &str);
381
382         if(*str) {
383             BSTR ret;
384
385             end = strstrW(str, pxW);
386             if(!end)
387                 end = str+strlenW(str);
388             ret = SysAllocStringLen(str, end-str);
389             if(ret) {
390                 V_VT(p) = VT_BSTR;
391                 V_BSTR(p) = ret;
392             }else {
393                 hres = E_OUTOFMEMORY;
394             }
395         }else {
396             V_VT(p) = VT_BSTR;
397             V_BSTR(p) = NULL;
398         }
399     }else {
400         ERR("SetMarginHeight failed: %08x\n", nsres);
401         hres = E_FAIL;
402     }
403
404     nsAString_Finish(&nsstr);
405     return hres;
406 }
407
408 static HRESULT WINAPI HTMLFrameBase_put_noResize(IHTMLFrameBase *iface, VARIANT_BOOL v)
409 {
410     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
411     FIXME("(%p)->(%x)\n", This, v);
412     return E_NOTIMPL;
413 }
414
415 static HRESULT WINAPI HTMLFrameBase_get_noResize(IHTMLFrameBase *iface, VARIANT_BOOL *p)
416 {
417     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
418     FIXME("(%p)->(%p)\n", This, p);
419     return E_NOTIMPL;
420 }
421
422 static HRESULT WINAPI HTMLFrameBase_put_scrolling(IHTMLFrameBase *iface, BSTR v)
423 {
424     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
425     nsAString nsstr;
426     nsresult nsres;
427
428     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
429
430     if(!(!strcmpiW(v, yesW) || !strcmpiW(v, noW) || !strcmpiW(v, autoW)))
431         return E_INVALIDARG;
432
433     if(This->nsframe) {
434         nsAString_InitDepend(&nsstr, v);
435         nsres = nsIDOMHTMLFrameElement_SetScrolling(This->nsframe, &nsstr);
436     }else if(This->nsiframe) {
437         nsAString_InitDepend(&nsstr, v);
438         nsres = nsIDOMHTMLIFrameElement_SetScrolling(This->nsiframe, &nsstr);
439     }else {
440         ERR("No attached ns frame object\n");
441         return E_UNEXPECTED;
442     }
443     nsAString_Finish(&nsstr);
444
445     if(NS_FAILED(nsres)) {
446         ERR("SetScrolling failed: 0x%08x\n", nsres);
447         return E_FAIL;
448     }
449
450     return S_OK;
451 }
452
453 static HRESULT WINAPI HTMLFrameBase_get_scrolling(IHTMLFrameBase *iface, BSTR *p)
454 {
455     HTMLFrameBase *This = impl_from_IHTMLFrameBase(iface);
456     nsAString nsstr;
457     const PRUnichar *strdata;
458     nsresult nsres;
459
460     TRACE("(%p)->(%p)\n", This, p);
461
462     if(This->nsframe) {
463         nsAString_Init(&nsstr, NULL);
464         nsres = nsIDOMHTMLFrameElement_GetScrolling(This->nsframe, &nsstr);
465     }else if(This->nsiframe) {
466         nsAString_Init(&nsstr, NULL);
467         nsres = nsIDOMHTMLIFrameElement_GetScrolling(This->nsiframe, &nsstr);
468     }else {
469         ERR("No attached ns frame object\n");
470         return E_UNEXPECTED;
471     }
472
473     if(NS_FAILED(nsres)) {
474         ERR("GetScrolling failed: 0x%08x\n", nsres);
475         nsAString_Finish(&nsstr);
476         return E_FAIL;
477     }
478
479     nsAString_GetData(&nsstr, &strdata);
480
481     if(*strdata)
482         *p = SysAllocString(strdata);
483     else
484         *p = SysAllocString(autoW);
485
486     nsAString_Finish(&nsstr);
487
488     return *p ? S_OK : E_OUTOFMEMORY;
489 }
490
491 static const IHTMLFrameBaseVtbl HTMLFrameBaseVtbl = {
492     HTMLFrameBase_QueryInterface,
493     HTMLFrameBase_AddRef,
494     HTMLFrameBase_Release,
495     HTMLFrameBase_GetTypeInfoCount,
496     HTMLFrameBase_GetTypeInfo,
497     HTMLFrameBase_GetIDsOfNames,
498     HTMLFrameBase_Invoke,
499     HTMLFrameBase_put_src,
500     HTMLFrameBase_get_src,
501     HTMLFrameBase_put_name,
502     HTMLFrameBase_get_name,
503     HTMLFrameBase_put_border,
504     HTMLFrameBase_get_border,
505     HTMLFrameBase_put_frameBorder,
506     HTMLFrameBase_get_frameBorder,
507     HTMLFrameBase_put_frameSpacing,
508     HTMLFrameBase_get_frameSpacing,
509     HTMLFrameBase_put_marginWidth,
510     HTMLFrameBase_get_marginWidth,
511     HTMLFrameBase_put_marginHeight,
512     HTMLFrameBase_get_marginHeight,
513     HTMLFrameBase_put_noResize,
514     HTMLFrameBase_get_noResize,
515     HTMLFrameBase_put_scrolling,
516     HTMLFrameBase_get_scrolling
517 };
518
519 static inline HTMLFrameBase *impl_from_IHTMLFrameBase2(IHTMLFrameBase2 *iface)
520 {
521     return CONTAINING_RECORD(iface, HTMLFrameBase, IHTMLFrameBase2_iface);
522 }
523
524 static HRESULT WINAPI HTMLFrameBase2_QueryInterface(IHTMLFrameBase2 *iface, REFIID riid, void **ppv)
525 {
526     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
527
528     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
529 }
530
531 static ULONG WINAPI HTMLFrameBase2_AddRef(IHTMLFrameBase2 *iface)
532 {
533     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
534
535     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
536 }
537
538 static ULONG WINAPI HTMLFrameBase2_Release(IHTMLFrameBase2 *iface)
539 {
540     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
541
542     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
543 }
544
545 static HRESULT WINAPI HTMLFrameBase2_GetTypeInfoCount(IHTMLFrameBase2 *iface, UINT *pctinfo)
546 {
547     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
548     FIXME("(%p)\n", This);
549     return E_NOTIMPL;
550 }
551
552 static HRESULT WINAPI HTMLFrameBase2_GetTypeInfo(IHTMLFrameBase2 *iface, UINT iTInfo,
553         LCID lcid, ITypeInfo **ppTInfo)
554 {
555     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
556     FIXME("(%p)\n", This);
557     return E_NOTIMPL;
558 }
559
560 static HRESULT WINAPI HTMLFrameBase2_GetIDsOfNames(IHTMLFrameBase2 *iface, REFIID riid,
561         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
562 {
563     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
564     FIXME("(%p)\n", This);
565     return E_NOTIMPL;
566 }
567
568 static HRESULT WINAPI HTMLFrameBase2_Invoke(IHTMLFrameBase2 *iface, DISPID dispIdMember,
569         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
570         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
571 {
572     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
573     FIXME("(%p)\n", This);
574     return E_NOTIMPL;
575 }
576
577 static HRESULT WINAPI HTMLFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface, IHTMLWindow2 **p)
578 {
579     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
580
581     TRACE("(%p)->(%p)\n", This, p);
582
583     if(This->content_window) {
584         IHTMLWindow2_AddRef(&This->content_window->base.IHTMLWindow2_iface);
585         *p = &This->content_window->base.IHTMLWindow2_iface;
586     }else {
587         WARN("NULL content window\n");
588         *p = NULL;
589     }
590     return S_OK;
591 }
592
593 static HRESULT WINAPI HTMLFrameBase2_put_onload(IHTMLFrameBase2 *iface, VARIANT v)
594 {
595     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
596     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
597     return E_NOTIMPL;
598 }
599
600 static HRESULT WINAPI HTMLFrameBase2_get_onload(IHTMLFrameBase2 *iface, VARIANT *p)
601 {
602     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
603     FIXME("(%p)->(%p)\n", This, p);
604     return E_NOTIMPL;
605 }
606
607 static HRESULT WINAPI HTMLFrameBase2_put_onreadystatechange(IHTMLFrameBase2 *iface, VARIANT v)
608 {
609     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
610     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
611     return E_NOTIMPL;
612 }
613
614 static HRESULT WINAPI HTMLFrameBase2_get_onreadystatechange(IHTMLFrameBase2 *iface, VARIANT *p)
615 {
616     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
617     FIXME("(%p)->(%p)\n", This, p);
618     return E_NOTIMPL;
619 }
620
621 static HRESULT WINAPI HTMLFrameBase2_get_readyState(IHTMLFrameBase2 *iface, BSTR *p)
622 {
623     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
624
625     TRACE("(%p)->(%p)\n", This, p);
626
627     if(!This->content_window || !This->content_window->base.inner_window->doc) {
628         FIXME("no document associated\n");
629         return E_FAIL;
630     }
631
632     return IHTMLDocument2_get_readyState(&This->content_window->base.inner_window->doc->basedoc.IHTMLDocument2_iface, p);
633 }
634
635 static HRESULT WINAPI HTMLFrameBase2_put_allowTransparency(IHTMLFrameBase2 *iface, VARIANT_BOOL v)
636 {
637     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
638     FIXME("(%p)->(%x)\n", This, v);
639     return E_NOTIMPL;
640 }
641
642 static HRESULT WINAPI HTMLFrameBase2_get_allowTransparency(IHTMLFrameBase2 *iface, VARIANT_BOOL *p)
643 {
644     HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface);
645     FIXME("(%p)->(%p)\n", This, p);
646     return E_NOTIMPL;
647 }
648
649 static const IHTMLFrameBase2Vtbl HTMLFrameBase2Vtbl = {
650     HTMLFrameBase2_QueryInterface,
651     HTMLFrameBase2_AddRef,
652     HTMLFrameBase2_Release,
653     HTMLFrameBase2_GetTypeInfoCount,
654     HTMLFrameBase2_GetTypeInfo,
655     HTMLFrameBase2_GetIDsOfNames,
656     HTMLFrameBase2_Invoke,
657     HTMLFrameBase2_get_contentWindow,
658     HTMLFrameBase2_put_onload,
659     HTMLFrameBase2_get_onload,
660     HTMLFrameBase2_put_onreadystatechange,
661     HTMLFrameBase2_get_onreadystatechange,
662     HTMLFrameBase2_get_readyState,
663     HTMLFrameBase2_put_allowTransparency,
664     HTMLFrameBase2_get_allowTransparency
665 };
666
667 HRESULT HTMLFrameBase_QI(HTMLFrameBase *This, REFIID riid, void **ppv)
668 {
669     if(IsEqualGUID(&IID_IHTMLFrameBase, riid)) {
670         TRACE("(%p)->(IID_IHTMLFrameBase %p)\n", This, ppv);
671         *ppv = &This->IHTMLFrameBase_iface;
672     }else if(IsEqualGUID(&IID_IHTMLFrameBase2, riid)) {
673         TRACE("(%p)->(IID_IHTMLFrameBase2 %p)\n", This, ppv);
674         *ppv = &This->IHTMLFrameBase2_iface;
675     }else {
676         return HTMLElement_QI(&This->element.node, riid, ppv);
677     }
678
679     IUnknown_AddRef((IUnknown*)*ppv);
680     return S_OK;
681 }
682
683 void HTMLFrameBase_destructor(HTMLFrameBase *This)
684 {
685     if(This->content_window)
686         This->content_window->frame_element = NULL;
687
688     HTMLElement_destructor(&This->element.node);
689 }
690
691 void HTMLFrameBase_Init(HTMLFrameBase *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem,
692         dispex_static_data_t *dispex_data)
693 {
694     nsresult nsres;
695
696     This->IHTMLFrameBase_iface.lpVtbl = &HTMLFrameBaseVtbl;
697     This->IHTMLFrameBase2_iface.lpVtbl = &HTMLFrameBase2Vtbl;
698
699     HTMLElement_Init(&This->element, doc, nselem, dispex_data);
700
701     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLFrameElement, (void**)&This->nsframe);
702     if(NS_FAILED(nsres)) {
703         This->nsframe = NULL;
704         nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLIFrameElement, (void**)&This->nsiframe);
705         assert(nsres == NS_OK && (nsIDOMNode*)This->nsiframe == This->element.node.nsnode);
706     }else {
707         assert((nsIDOMNode*)This->nsframe == This->element.node.nsnode);
708         This->nsiframe = NULL;
709     }
710
711     /* Share the reference with nsnode */
712     nsIDOMNode_Release(This->element.node.nsnode);
713 }