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