xref: /reactos/dll/win32/mshtml/htmlframe.c (revision 1734f297)
1 /*
2  * Copyright 2010 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 typedef struct {
22     HTMLFrameBase framebase;
23     IHTMLFrameElement3 IHTMLFrameElement3_iface;
24 } HTMLFrameElement;
25 
26 static inline HTMLFrameElement *impl_from_IHTMLFrameElement3(IHTMLFrameElement3 *iface)
27 {
28     return CONTAINING_RECORD(iface, HTMLFrameElement, IHTMLFrameElement3_iface);
29 }
30 
31 static HRESULT WINAPI HTMLFrameElement3_QueryInterface(IHTMLFrameElement3 *iface,
32         REFIID riid, void **ppv)
33 {
34     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
35 
36     return IHTMLDOMNode_QueryInterface(&This->framebase.element.node.IHTMLDOMNode_iface, riid, ppv);
37 }
38 
39 static ULONG WINAPI HTMLFrameElement3_AddRef(IHTMLFrameElement3 *iface)
40 {
41     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
42 
43     return IHTMLDOMNode_AddRef(&This->framebase.element.node.IHTMLDOMNode_iface);
44 }
45 
46 static ULONG WINAPI HTMLFrameElement3_Release(IHTMLFrameElement3 *iface)
47 {
48     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
49 
50     return IHTMLDOMNode_Release(&This->framebase.element.node.IHTMLDOMNode_iface);
51 }
52 
53 static HRESULT WINAPI HTMLFrameElement3_GetTypeInfoCount(IHTMLFrameElement3 *iface, UINT *pctinfo)
54 {
55     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
56     return IDispatchEx_GetTypeInfoCount(&This->framebase.element.node.event_target.dispex.IDispatchEx_iface,
57             pctinfo);
58 }
59 
60 static HRESULT WINAPI HTMLFrameElement3_GetTypeInfo(IHTMLFrameElement3 *iface, UINT iTInfo,
61         LCID lcid, ITypeInfo **ppTInfo)
62 {
63     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
64     return IDispatchEx_GetTypeInfo(&This->framebase.element.node.event_target.dispex.IDispatchEx_iface, iTInfo,
65             lcid, ppTInfo);
66 }
67 
68 static HRESULT WINAPI HTMLFrameElement3_GetIDsOfNames(IHTMLFrameElement3 *iface, REFIID riid,
69         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
70 {
71     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
72     return IDispatchEx_GetIDsOfNames(&This->framebase.element.node.event_target.dispex.IDispatchEx_iface, riid,
73             rgszNames, cNames, lcid, rgDispId);
74 }
75 
76 static HRESULT WINAPI HTMLFrameElement3_Invoke(IHTMLFrameElement3 *iface, DISPID dispIdMember,
77         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
78         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
79 {
80     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
81     return IDispatchEx_Invoke(&This->framebase.element.node.event_target.dispex.IDispatchEx_iface, dispIdMember,
82             riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
83 }
84 
85 static HRESULT WINAPI HTMLFrameElement3_get_contentDocument(IHTMLFrameElement3 *iface, IDispatch **p)
86 {
87     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
88     IHTMLDocument2 *doc;
89     HRESULT hres;
90 
91     TRACE("(%p)->(%p)\n", This, p);
92 
93     if(!This->framebase.content_window) {
94         FIXME("NULL window\n");
95         return E_FAIL;
96     }
97 
98     hres = IHTMLWindow2_get_document(&This->framebase.content_window->base.IHTMLWindow2_iface, &doc);
99     if(FAILED(hres))
100         return hres;
101 
102     *p = doc ? (IDispatch*)doc : NULL;
103     return S_OK;
104 }
105 
106 static HRESULT WINAPI HTMLFrameElement3_put_src(IHTMLFrameElement3 *iface, BSTR v)
107 {
108     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
109     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
110     return E_NOTIMPL;
111 }
112 
113 static HRESULT WINAPI HTMLFrameElement3_get_src(IHTMLFrameElement3 *iface, BSTR *p)
114 {
115     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
116     FIXME("(%p)->(%p)\n", This, p);
117     return E_NOTIMPL;
118 }
119 
120 static HRESULT WINAPI HTMLFrameElement3_put_longDesc(IHTMLFrameElement3 *iface, BSTR v)
121 {
122     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
123     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
124     return E_NOTIMPL;
125 }
126 
127 static HRESULT WINAPI HTMLFrameElement3_get_longDesc(IHTMLFrameElement3 *iface, BSTR *p)
128 {
129     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
130     FIXME("(%p)->(%p)\n", This, p);
131     return E_NOTIMPL;
132 }
133 
134 static HRESULT WINAPI HTMLFrameElement3_put_frameBorder(IHTMLFrameElement3 *iface, BSTR v)
135 {
136     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
137     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
138     return E_NOTIMPL;
139 }
140 
141 static HRESULT WINAPI HTMLFrameElement3_get_frameBorder(IHTMLFrameElement3 *iface, BSTR *p)
142 {
143     HTMLFrameElement *This = impl_from_IHTMLFrameElement3(iface);
144     FIXME("(%p)->(%p)\n", This, p);
145     return E_NOTIMPL;
146 }
147 
148 static const IHTMLFrameElement3Vtbl HTMLFrameElement3Vtbl = {
149     HTMLFrameElement3_QueryInterface,
150     HTMLFrameElement3_AddRef,
151     HTMLFrameElement3_Release,
152     HTMLFrameElement3_GetTypeInfoCount,
153     HTMLFrameElement3_GetTypeInfo,
154     HTMLFrameElement3_GetIDsOfNames,
155     HTMLFrameElement3_Invoke,
156     HTMLFrameElement3_get_contentDocument,
157     HTMLFrameElement3_put_src,
158     HTMLFrameElement3_get_src,
159     HTMLFrameElement3_put_longDesc,
160     HTMLFrameElement3_get_longDesc,
161     HTMLFrameElement3_put_frameBorder,
162     HTMLFrameElement3_get_frameBorder
163 };
164 
165 static inline HTMLFrameElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
166 {
167     return CONTAINING_RECORD(iface, HTMLFrameElement, framebase.element.node);
168 }
169 
170 static HRESULT HTMLFrameElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
171 {
172     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
173 
174     if(IsEqualGUID(&IID_IHTMLFrameElement3, riid)) {
175         TRACE("(%p)->(IID_IHTMLFrameElement3 %p)\n", This, ppv);
176         *ppv = &This->IHTMLFrameElement3_iface;
177     }else {
178         return HTMLFrameBase_QI(&This->framebase, riid, ppv);
179     }
180 
181     IUnknown_AddRef((IUnknown*)*ppv);
182     return S_OK;
183 }
184 
185 static void HTMLFrameElement_destructor(HTMLDOMNode *iface)
186 {
187     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
188 
189     HTMLFrameBase_destructor(&This->framebase);
190 }
191 
192 static HRESULT HTMLFrameElement_get_document(HTMLDOMNode *iface, IDispatch **p)
193 {
194     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
195 
196     if(!This->framebase.content_window || !This->framebase.content_window->base.inner_window->doc) {
197         *p = NULL;
198         return S_OK;
199     }
200 
201     *p = (IDispatch*)&This->framebase.content_window->base.inner_window->doc->basedoc.IHTMLDocument2_iface;
202     IDispatch_AddRef(*p);
203     return S_OK;
204 }
205 
206 static HRESULT HTMLFrameElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
207 {
208     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
209 
210     return IHTMLFrameBase2_get_readyState(&This->framebase.IHTMLFrameBase2_iface, p);
211 }
212 
213 static HRESULT HTMLFrameElement_get_dispid(HTMLDOMNode *iface, BSTR name,
214         DWORD grfdex, DISPID *pid)
215 {
216     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
217 
218     if(!This->framebase.content_window)
219         return DISP_E_UNKNOWNNAME;
220 
221     return search_window_props(This->framebase.content_window->base.inner_window, name, grfdex, pid);
222 }
223 
224 static HRESULT HTMLFrameElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
225         WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
226 {
227     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
228 
229     if(!This->framebase.content_window) {
230         ERR("no content window to invoke on\n");
231         return E_FAIL;
232     }
233 
234     return IDispatchEx_InvokeEx(&This->framebase.content_window->base.IDispatchEx_iface, id, lcid,
235             flags, params, res, ei, caller);
236 }
237 
238 static HRESULT HTMLFrameElement_bind_to_tree(HTMLDOMNode *iface)
239 {
240     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
241     nsIDOMDocument *nsdoc;
242     nsresult nsres;
243     HRESULT hres;
244 
245     nsres = nsIDOMHTMLFrameElement_GetContentDocument(This->framebase.nsframe, &nsdoc);
246     if(NS_FAILED(nsres) || !nsdoc) {
247         ERR("GetContentDocument failed: %08x\n", nsres);
248         return E_FAIL;
249     }
250 
251     hres = set_frame_doc(&This->framebase, nsdoc);
252     nsIDOMDocument_Release(nsdoc);
253     return hres;
254 }
255 
256 static void HTMLFrameElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
257 {
258     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
259 
260     if(This->framebase.nsframe)
261         note_cc_edge((nsISupports*)This->framebase.nsframe, "This->nsframe", cb);
262 }
263 
264 static void HTMLFrameElement_unlink(HTMLDOMNode *iface)
265 {
266     HTMLFrameElement *This = impl_from_HTMLDOMNode(iface);
267 
268     if(This->framebase.nsframe) {
269         nsIDOMHTMLFrameElement *nsframe = This->framebase.nsframe;
270 
271         This->framebase.nsframe = NULL;
272         nsIDOMHTMLFrameElement_Release(nsframe);
273     }
274 }
275 
276 static const NodeImplVtbl HTMLFrameElementImplVtbl = {
277     HTMLFrameElement_QI,
278     HTMLFrameElement_destructor,
279     HTMLElement_cpc,
280     HTMLElement_clone,
281     HTMLElement_handle_event,
282     HTMLElement_get_attr_col,
283     NULL,
284     NULL,
285     NULL,
286     NULL,
287     HTMLFrameElement_get_document,
288     HTMLFrameElement_get_readystate,
289     HTMLFrameElement_get_dispid,
290     HTMLFrameElement_invoke,
291     HTMLFrameElement_bind_to_tree,
292     HTMLFrameElement_traverse,
293     HTMLFrameElement_unlink
294 };
295 
296 static const tid_t HTMLFrameElement_iface_tids[] = {
297     HTMLELEMENT_TIDS,
298     IHTMLFrameBase_tid,
299     IHTMLFrameBase2_tid,
300     IHTMLFrameElement3_tid,
301     0
302 };
303 
304 static dispex_static_data_t HTMLFrameElement_dispex = {
305     NULL,
306     DispHTMLFrameElement_tid,
307     NULL,
308     HTMLFrameElement_iface_tids
309 };
310 
311 HRESULT HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
312 {
313     HTMLFrameElement *ret;
314 
315     ret = heap_alloc_zero(sizeof(HTMLFrameElement));
316     if(!ret)
317         return E_OUTOFMEMORY;
318 
319     ret->framebase.element.node.vtbl = &HTMLFrameElementImplVtbl;
320     ret->IHTMLFrameElement3_iface.lpVtbl = &HTMLFrameElement3Vtbl;
321 
322     HTMLFrameBase_Init(&ret->framebase, doc, nselem, &HTMLFrameElement_dispex);
323 
324     *elem = &ret->framebase.element;
325     return S_OK;
326 }
327