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