mshtml: Implement IHTMLWindow4::get_frameElement.
[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     const IHTMLFrameBase2Vtbl  *lpIHTMLFrameBase2Vtbl;
37
38     LONG ref;
39
40     nsIDOMHTMLIFrameElement *nsiframe;
41 } HTMLIFrame;
42
43 #define HTMLFRAMEBASE2(x)  (&(x)->lpIHTMLFrameBase2Vtbl)
44
45 #define HTMLFRAMEBASE2_THIS(iface) DEFINE_THIS(HTMLIFrame, IHTMLFrameBase2, iface)
46
47 static HRESULT WINAPI HTMLIFrameBase2_QueryInterface(IHTMLFrameBase2 *iface, REFIID riid, void **ppv)
48 {
49     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
50
51     return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->framebase.element.node), riid, ppv);
52 }
53
54 static ULONG WINAPI HTMLIFrameBase2_AddRef(IHTMLFrameBase2 *iface)
55 {
56     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
57
58     return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->framebase.element.node));
59 }
60
61 static ULONG WINAPI HTMLIFrameBase2_Release(IHTMLFrameBase2 *iface)
62 {
63     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
64
65     return IHTMLDOMNode_Release(HTMLDOMNODE(&This->framebase.element.node));
66 }
67
68 static HRESULT WINAPI HTMLIFrameBase2_GetTypeInfoCount(IHTMLFrameBase2 *iface, UINT *pctinfo)
69 {
70     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
71     FIXME("(%p)\n", This);
72     return E_NOTIMPL;
73 }
74
75 static HRESULT WINAPI HTMLIFrameBase2_GetTypeInfo(IHTMLFrameBase2 *iface, UINT iTInfo,
76         LCID lcid, ITypeInfo **ppTInfo)
77 {
78     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
79     FIXME("(%p)\n", This);
80     return E_NOTIMPL;
81 }
82
83 static HRESULT WINAPI HTMLIFrameBase2_GetIDsOfNames(IHTMLFrameBase2 *iface, REFIID riid,
84         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
85 {
86     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
87     FIXME("(%p)\n", This);
88     return E_NOTIMPL;
89 }
90
91 static HRESULT WINAPI HTMLIFrameBase2_Invoke(IHTMLFrameBase2 *iface, DISPID dispIdMember,
92         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
93         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
94 {
95     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
96     FIXME("(%p)\n", This);
97     return E_NOTIMPL;
98 }
99
100 static HRESULT WINAPI HTMLIFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface, IHTMLWindow2 **p)
101 {
102     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
103
104     TRACE("(%p)->(%p)\n", This, p);
105
106     if(This->framebase.content_window) {
107         IHTMLWindow2_AddRef(HTMLWINDOW2(This->framebase.content_window));
108         *p = HTMLWINDOW2(This->framebase.content_window);
109     }else {
110         WARN("NULL content window\n");
111         *p = NULL;
112     }
113     return S_OK;
114 }
115
116 static HRESULT WINAPI HTMLIFrameBase2_put_onload(IHTMLFrameBase2 *iface, VARIANT v)
117 {
118     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
119     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
120     return E_NOTIMPL;
121 }
122
123 static HRESULT WINAPI HTMLIFrameBase2_get_onload(IHTMLFrameBase2 *iface, VARIANT *p)
124 {
125     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
126     FIXME("(%p)->(%p)\n", This, p);
127     return E_NOTIMPL;
128 }
129
130 static HRESULT WINAPI HTMLIFrameBase2_put_onreadystatechange(IHTMLFrameBase2 *iface, VARIANT v)
131 {
132     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
133     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
134     return E_NOTIMPL;
135 }
136
137 static HRESULT WINAPI HTMLIFrameBase2_get_onreadystatechange(IHTMLFrameBase2 *iface, VARIANT *p)
138 {
139     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
140     FIXME("(%p)->(%p)\n", This, p);
141     return E_NOTIMPL;
142 }
143
144 static HRESULT WINAPI HTMLIFrameBase2_get_readyState(IHTMLFrameBase2 *iface, BSTR *p)
145 {
146     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
147     FIXME("(%p)->(%p)\n", This, p);
148     return E_NOTIMPL;
149 }
150
151 static HRESULT WINAPI HTMLIFrameBase2_put_allowTransparency(IHTMLFrameBase2 *iface, VARIANT_BOOL v)
152 {
153     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
154     FIXME("(%p)->(%x)\n", This, v);
155     return E_NOTIMPL;
156 }
157
158 static HRESULT WINAPI HTMLIFrameBase2_get_allowTransparency(IHTMLFrameBase2 *iface, VARIANT_BOOL *p)
159 {
160     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
161     FIXME("(%p)->(%p)\n", This, p);
162     return E_NOTIMPL;
163 }
164
165 #undef HTMLFRAMEBASE2_THIS
166
167 static const IHTMLFrameBase2Vtbl HTMLIFrameBase2Vtbl = {
168     HTMLIFrameBase2_QueryInterface,
169     HTMLIFrameBase2_AddRef,
170     HTMLIFrameBase2_Release,
171     HTMLIFrameBase2_GetTypeInfoCount,
172     HTMLIFrameBase2_GetTypeInfo,
173     HTMLIFrameBase2_GetIDsOfNames,
174     HTMLIFrameBase2_Invoke,
175     HTMLIFrameBase2_get_contentWindow,
176     HTMLIFrameBase2_put_onload,
177     HTMLIFrameBase2_get_onload,
178     HTMLIFrameBase2_put_onreadystatechange,
179     HTMLIFrameBase2_get_onreadystatechange,
180     HTMLIFrameBase2_get_readyState,
181     HTMLIFrameBase2_put_allowTransparency,
182     HTMLIFrameBase2_get_allowTransparency
183 };
184
185 #define HTMLIFRAME_NODE_THIS(iface) DEFINE_THIS2(HTMLIFrame, framebase.element.node, iface)
186
187 static HRESULT HTMLIFrame_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
188 {
189     HTMLIFrame *This = HTMLIFRAME_NODE_THIS(iface);
190
191     *ppv = NULL;
192
193     if(IsEqualGUID(&IID_IHTMLFrameBase2, riid)) {
194         TRACE("(%p)->(IID_IHTMLFrameBase2 %p)\n", This, ppv);
195         *ppv = HTMLFRAMEBASE2(This);
196     }else {
197         return HTMLFrameBase_QI(&This->framebase, riid, ppv);
198     }
199
200     IUnknown_AddRef((IUnknown*)*ppv);
201     return S_OK;
202 }
203
204 static void HTMLIFrame_destructor(HTMLDOMNode *iface)
205 {
206     HTMLIFrame *This = HTMLIFRAME_NODE_THIS(iface);
207
208     if(This->nsiframe)
209         nsIDOMHTMLIFrameElement_Release(This->nsiframe);
210
211     HTMLFrameBase_destructor(&This->framebase);
212 }
213
214 #undef HTMLIFRAME_NODE_THIS
215
216 static const NodeImplVtbl HTMLIFrameImplVtbl = {
217     HTMLIFrame_QI,
218     HTMLIFrame_destructor
219 };
220
221 static const tid_t HTMLIFrame_iface_tids[] = {
222     IHTMLDOMNode_tid,
223     IHTMLDOMNode2_tid,
224     IHTMLElement_tid,
225     IHTMLElement2_tid,
226     IHTMLElement3_tid,
227     IHTMLFrameBase_tid,
228     IHTMLFrameBase2_tid,
229     0
230 };
231
232 static dispex_static_data_t HTMLIFrame_dispex = {
233     NULL,
234     DispHTMLIFrame_tid,
235     NULL,
236     HTMLIFrame_iface_tids
237 };
238
239 static HTMLWindow *get_content_window(nsIDOMHTMLIFrameElement *nsiframe)
240 {
241     HTMLWindow *ret;
242     nsIDOMWindow *nswindow;
243     nsIDOMDocument *nsdoc;
244     nsresult nsres;
245
246     nsres = nsIDOMHTMLIFrameElement_GetContentDocument(nsiframe, &nsdoc);
247     if(NS_FAILED(nsres)) {
248         ERR("GetContentDocument failed: %08x\n", nsres);
249         return NULL;
250     }
251
252     if(!nsdoc) {
253         FIXME("NULL contentDocument\n");
254         return NULL;
255     }
256
257     nswindow = get_nsdoc_window(nsdoc);
258     nsIDOMDocument_Release(nsdoc);
259     if(!nswindow)
260         return NULL;
261
262     ret = nswindow_to_window(nswindow);
263     nsIDOMWindow_Release(nswindow);
264     if(!ret)
265         ERR("Could not get window object\n");
266
267     return ret;
268 }
269
270 HTMLElement *HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLWindow *content_window)
271 {
272     HTMLIFrame *ret;
273     nsresult nsres;
274
275     ret = heap_alloc_zero(sizeof(HTMLIFrame));
276
277     ret->lpIHTMLFrameBase2Vtbl = &HTMLIFrameBase2Vtbl;
278     ret->framebase.element.node.vtbl = &HTMLIFrameImplVtbl;
279
280     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLIFrameElement, (void**)&ret->nsiframe);
281     if(NS_FAILED(nsres))
282         ERR("Could not get nsIDOMHTMLIFrameElement iface: %08x\n", nsres);
283
284     if(!content_window)
285         content_window = get_content_window(ret->nsiframe);
286
287     HTMLFrameBase_Init(&ret->framebase, doc, nselem, content_window, &HTMLIFrame_dispex);
288
289     return &ret->framebase.element;
290 }