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 HTMLElement element; 23 24 IHTMLStyleElement IHTMLStyleElement_iface; 25 26 nsIDOMHTMLStyleElement *nsstyle; 27 IHTMLStyleSheet *style_sheet; 28 } HTMLStyleElement; 29 30 static inline HTMLStyleElement *impl_from_IHTMLStyleElement(IHTMLStyleElement *iface) 31 { 32 return CONTAINING_RECORD(iface, HTMLStyleElement, IHTMLStyleElement_iface); 33 } 34 35 static HRESULT WINAPI HTMLStyleElement_QueryInterface(IHTMLStyleElement *iface, 36 REFIID riid, void **ppv) 37 { 38 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 39 40 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv); 41 } 42 43 static ULONG WINAPI HTMLStyleElement_AddRef(IHTMLStyleElement *iface) 44 { 45 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 46 47 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface); 48 } 49 50 static ULONG WINAPI HTMLStyleElement_Release(IHTMLStyleElement *iface) 51 { 52 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 53 54 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface); 55 } 56 57 static HRESULT WINAPI HTMLStyleElement_GetTypeInfoCount(IHTMLStyleElement *iface, UINT *pctinfo) 58 { 59 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 60 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo); 61 } 62 63 static HRESULT WINAPI HTMLStyleElement_GetTypeInfo(IHTMLStyleElement *iface, UINT iTInfo, 64 LCID lcid, ITypeInfo **ppTInfo) 65 { 66 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 67 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, 68 ppTInfo); 69 } 70 71 static HRESULT WINAPI HTMLStyleElement_GetIDsOfNames(IHTMLStyleElement *iface, REFIID riid, 72 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 73 { 74 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 75 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, 76 cNames, lcid, rgDispId); 77 } 78 79 static HRESULT WINAPI HTMLStyleElement_Invoke(IHTMLStyleElement *iface, DISPID dispIdMember, 80 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 81 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 82 { 83 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 84 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, 85 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 86 } 87 88 static HRESULT WINAPI HTMLStyleElement_put_type(IHTMLStyleElement *iface, BSTR v) 89 { 90 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 91 nsAString type_str; 92 nsresult nsres; 93 94 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 95 96 nsAString_InitDepend(&type_str, v); 97 nsres = nsIDOMHTMLStyleElement_SetType(This->nsstyle, &type_str); 98 nsAString_Finish(&type_str); 99 if(NS_FAILED(nsres)) { 100 ERR("SetType failed: %08x\n", nsres); 101 return E_FAIL; 102 } 103 104 return S_OK; 105 } 106 107 static HRESULT WINAPI HTMLStyleElement_get_type(IHTMLStyleElement *iface, BSTR *p) 108 { 109 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 110 nsAString nsstr; 111 nsresult nsres; 112 113 TRACE("(%p)->(%p)\n", This, p); 114 115 nsAString_Init(&nsstr, NULL); 116 nsres = nsIDOMHTMLStyleElement_GetType(This->nsstyle, &nsstr); 117 return return_nsstr(nsres, &nsstr, p); 118 } 119 120 static HRESULT WINAPI HTMLStyleElement_get_readyState(IHTMLStyleElement *iface, BSTR *p) 121 { 122 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 123 FIXME("(%p)->(%p)\n", This, p); 124 return E_NOTIMPL; 125 } 126 127 static HRESULT WINAPI HTMLStyleElement_put_onreadystatechange(IHTMLStyleElement *iface, VARIANT v) 128 { 129 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 130 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); 131 return E_NOTIMPL; 132 } 133 134 static HRESULT WINAPI HTMLStyleElement_get_onreadystatechange(IHTMLStyleElement *iface, VARIANT *p) 135 { 136 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 137 FIXME("(%p)->(%p)\n", This, p); 138 return E_NOTIMPL; 139 } 140 141 static HRESULT WINAPI HTMLStyleElement_put_onload(IHTMLStyleElement *iface, VARIANT v) 142 { 143 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 144 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); 145 return E_NOTIMPL; 146 } 147 148 static HRESULT WINAPI HTMLStyleElement_get_onload(IHTMLStyleElement *iface, VARIANT *p) 149 { 150 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 151 FIXME("(%p)->(%p)\n", This, p); 152 return E_NOTIMPL; 153 } 154 155 static HRESULT WINAPI HTMLStyleElement_put_onerror(IHTMLStyleElement *iface, VARIANT v) 156 { 157 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 158 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); 159 return E_NOTIMPL; 160 } 161 162 static HRESULT WINAPI HTMLStyleElement_get_onerror(IHTMLStyleElement *iface, VARIANT *p) 163 { 164 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 165 FIXME("(%p)->(%p)\n", This, p); 166 return E_NOTIMPL; 167 } 168 169 static HRESULT WINAPI HTMLStyleElement_get_styleSheet(IHTMLStyleElement *iface, IHTMLStyleSheet **p) 170 { 171 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 172 173 TRACE("(%p)->(%p)\n", This, p); 174 175 if(!This->nsstyle) 176 return E_FAIL; 177 178 if(!This->style_sheet) { 179 nsIDOMStyleSheet *ss; 180 nsresult nsres; 181 182 nsres = nsIDOMHTMLStyleElement_GetDOMStyleSheet(This->nsstyle, &ss); 183 assert(nsres == NS_OK); 184 185 if(ss) { 186 This->style_sheet = HTMLStyleSheet_Create(ss); 187 nsIDOMStyleSheet_Release(ss); 188 if(!This->style_sheet) 189 return E_OUTOFMEMORY; 190 } 191 } 192 193 if(This->style_sheet) 194 IHTMLStyleSheet_AddRef(This->style_sheet); 195 *p = This->style_sheet; 196 return S_OK; 197 } 198 199 static HRESULT WINAPI HTMLStyleElement_put_disabled(IHTMLStyleElement *iface, VARIANT_BOOL v) 200 { 201 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 202 FIXME("(%p)->(%x)\n", This, v); 203 return E_NOTIMPL; 204 } 205 206 static HRESULT WINAPI HTMLStyleElement_get_disabled(IHTMLStyleElement *iface, VARIANT_BOOL *p) 207 { 208 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 209 FIXME("(%p)->(%p)\n", This, p); 210 return E_NOTIMPL; 211 } 212 213 static HRESULT WINAPI HTMLStyleElement_put_media(IHTMLStyleElement *iface, BSTR v) 214 { 215 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 216 nsAString media_str; 217 nsresult nsres; 218 219 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 220 221 nsAString_InitDepend(&media_str, v); 222 nsres = nsIDOMHTMLStyleElement_SetMedia(This->nsstyle, &media_str); 223 nsAString_Finish(&media_str); 224 if(NS_FAILED(nsres)) { 225 ERR("SetMedia failed: %08x\n", nsres); 226 return E_FAIL; 227 } 228 229 return S_OK; 230 } 231 232 static HRESULT WINAPI HTMLStyleElement_get_media(IHTMLStyleElement *iface, BSTR *p) 233 { 234 HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface); 235 nsAString nsstr; 236 nsresult nsres; 237 238 TRACE("(%p)->(%p)\n", This, p); 239 240 nsAString_Init(&nsstr, NULL); 241 nsres = nsIDOMHTMLStyleElement_GetMedia(This->nsstyle, &nsstr); 242 return return_nsstr(nsres, &nsstr, p); 243 } 244 245 static const IHTMLStyleElementVtbl HTMLStyleElementVtbl = { 246 HTMLStyleElement_QueryInterface, 247 HTMLStyleElement_AddRef, 248 HTMLStyleElement_Release, 249 HTMLStyleElement_GetTypeInfoCount, 250 HTMLStyleElement_GetTypeInfo, 251 HTMLStyleElement_GetIDsOfNames, 252 HTMLStyleElement_Invoke, 253 HTMLStyleElement_put_type, 254 HTMLStyleElement_get_type, 255 HTMLStyleElement_get_readyState, 256 HTMLStyleElement_put_onreadystatechange, 257 HTMLStyleElement_get_onreadystatechange, 258 HTMLStyleElement_put_onload, 259 HTMLStyleElement_get_onload, 260 HTMLStyleElement_put_onerror, 261 HTMLStyleElement_get_onerror, 262 HTMLStyleElement_get_styleSheet, 263 HTMLStyleElement_put_disabled, 264 HTMLStyleElement_get_disabled, 265 HTMLStyleElement_put_media, 266 HTMLStyleElement_get_media 267 }; 268 269 static inline HTMLStyleElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface) 270 { 271 return CONTAINING_RECORD(iface, HTMLStyleElement, element.node); 272 } 273 274 static HRESULT HTMLStyleElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) 275 { 276 HTMLStyleElement *This = impl_from_HTMLDOMNode(iface); 277 278 if(IsEqualGUID(&IID_IUnknown, riid)) { 279 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 280 *ppv = &This->IHTMLStyleElement_iface; 281 }else if(IsEqualGUID(&IID_IDispatch, riid)) { 282 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); 283 *ppv = &This->IHTMLStyleElement_iface; 284 }else if(IsEqualGUID(&IID_IHTMLStyleElement, riid)) { 285 TRACE("(%p)->(IID_IHTMLStyleElement %p)\n", This, ppv); 286 *ppv = &This->IHTMLStyleElement_iface; 287 }else { 288 return HTMLElement_QI(&This->element.node, riid, ppv); 289 } 290 291 IUnknown_AddRef((IUnknown*)*ppv); 292 return S_OK; 293 } 294 295 static void HTMLStyleElement_destructor(HTMLDOMNode *iface) 296 { 297 HTMLStyleElement *This = impl_from_HTMLDOMNode(iface); 298 299 if(This->style_sheet) { 300 IHTMLStyleSheet_Release(This->style_sheet); 301 This->style_sheet = NULL; 302 } 303 304 HTMLElement_destructor(iface); 305 } 306 307 static void HTMLStyleElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb) 308 { 309 HTMLStyleElement *This = impl_from_HTMLDOMNode(iface); 310 311 if(This->nsstyle) 312 note_cc_edge((nsISupports*)This->nsstyle, "This->nsstyle", cb); 313 } 314 315 static void HTMLStyleElement_unlink(HTMLDOMNode *iface) 316 { 317 HTMLStyleElement *This = impl_from_HTMLDOMNode(iface); 318 319 if(This->nsstyle) { 320 nsIDOMHTMLStyleElement *nsstyle = This->nsstyle; 321 322 This->nsstyle = NULL; 323 nsIDOMHTMLStyleElement_Release(nsstyle); 324 } 325 } 326 327 static const NodeImplVtbl HTMLStyleElementImplVtbl = { 328 HTMLStyleElement_QI, 329 HTMLStyleElement_destructor, 330 HTMLElement_cpc, 331 HTMLElement_clone, 332 HTMLElement_handle_event, 333 HTMLElement_get_attr_col, 334 NULL, 335 NULL, 336 NULL, 337 NULL, 338 NULL, 339 NULL, 340 NULL, 341 NULL, 342 NULL, 343 HTMLStyleElement_traverse, 344 HTMLStyleElement_unlink 345 }; 346 347 static const tid_t HTMLStyleElement_iface_tids[] = { 348 HTMLELEMENT_TIDS, 349 IHTMLStyleElement_tid, 350 0 351 }; 352 static dispex_static_data_t HTMLStyleElement_dispex = { 353 NULL, 354 DispHTMLStyleElement_tid, 355 NULL, 356 HTMLStyleElement_iface_tids 357 }; 358 359 HRESULT HTMLStyleElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem) 360 { 361 HTMLStyleElement *ret; 362 nsresult nsres; 363 364 ret = heap_alloc_zero(sizeof(*ret)); 365 if(!ret) 366 return E_OUTOFMEMORY; 367 368 ret->IHTMLStyleElement_iface.lpVtbl = &HTMLStyleElementVtbl; 369 ret->element.node.vtbl = &HTMLStyleElementImplVtbl; 370 371 HTMLElement_Init(&ret->element, doc, nselem, &HTMLStyleElement_dispex); 372 373 nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLStyleElement, (void**)&ret->nsstyle); 374 assert(nsres == NS_OK); 375 376 *elem = &ret->element; 377 return S_OK; 378 } 379