1 /* 2 * Copyright 2012 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 IHTMLLinkElement IHTMLLinkElement_iface; 24 25 nsIDOMHTMLLinkElement *nslink; 26 } HTMLLinkElement; 27 28 static inline HTMLLinkElement *impl_from_IHTMLLinkElement(IHTMLLinkElement *iface) 29 { 30 return CONTAINING_RECORD(iface, HTMLLinkElement, IHTMLLinkElement_iface); 31 } 32 33 static HRESULT WINAPI HTMLLinkElement_QueryInterface(IHTMLLinkElement *iface, 34 REFIID riid, void **ppv) 35 { 36 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 37 38 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv); 39 } 40 41 static ULONG WINAPI HTMLLinkElement_AddRef(IHTMLLinkElement *iface) 42 { 43 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 44 45 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface); 46 } 47 48 static ULONG WINAPI HTMLLinkElement_Release(IHTMLLinkElement *iface) 49 { 50 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 51 52 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface); 53 } 54 55 static HRESULT WINAPI HTMLLinkElement_GetTypeInfoCount(IHTMLLinkElement *iface, UINT *pctinfo) 56 { 57 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 58 59 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo); 60 } 61 62 static HRESULT WINAPI HTMLLinkElement_GetTypeInfo(IHTMLLinkElement *iface, UINT iTInfo, 63 LCID lcid, ITypeInfo **ppTInfo) 64 { 65 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 66 67 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, 68 ppTInfo); 69 } 70 71 static HRESULT WINAPI HTMLLinkElement_GetIDsOfNames(IHTMLLinkElement *iface, REFIID riid, 72 LPOLESTR *rgszNames, UINT cNames, 73 LCID lcid, DISPID *rgDispId) 74 { 75 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 76 77 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, 78 cNames, lcid, rgDispId); 79 } 80 81 static HRESULT WINAPI HTMLLinkElement_Invoke(IHTMLLinkElement *iface, DISPID dispIdMember, 82 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 83 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 84 { 85 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 86 87 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, 88 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 89 } 90 91 static HRESULT WINAPI HTMLLinkElement_put_href(IHTMLLinkElement *iface, BSTR v) 92 { 93 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 94 nsAString href_str; 95 nsresult nsres; 96 97 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 98 99 nsAString_InitDepend(&href_str, v); 100 nsres = nsIDOMHTMLLinkElement_SetHref(This->nslink, &href_str); 101 nsAString_Finish(&href_str); 102 103 return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL; 104 } 105 106 static HRESULT WINAPI HTMLLinkElement_get_href(IHTMLLinkElement *iface, BSTR *p) 107 { 108 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 109 nsAString href_str; 110 nsresult nsres; 111 112 TRACE("(%p)->(%p)\n", This, p); 113 114 nsAString_Init(&href_str, NULL); 115 nsres = nsIDOMHTMLLinkElement_GetHref(This->nslink, &href_str); 116 return return_nsstr(nsres, &href_str, p); 117 } 118 119 static HRESULT WINAPI HTMLLinkElement_put_rel(IHTMLLinkElement *iface, BSTR v) 120 { 121 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 122 nsAString rel_str; 123 nsresult nsres; 124 125 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 126 127 nsAString_InitDepend(&rel_str, v); 128 nsres = nsIDOMHTMLLinkElement_SetRel(This->nslink, &rel_str); 129 nsAString_Finish(&rel_str); 130 131 return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL; 132 } 133 134 static HRESULT WINAPI HTMLLinkElement_get_rel(IHTMLLinkElement *iface, BSTR *p) 135 { 136 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 137 nsAString rel_str; 138 nsresult nsres; 139 140 TRACE("(%p)->(%p)\n", This, p); 141 142 nsAString_Init(&rel_str, NULL); 143 nsres = nsIDOMHTMLLinkElement_GetRel(This->nslink, &rel_str); 144 return return_nsstr(nsres, &rel_str, p); 145 } 146 147 static HRESULT WINAPI HTMLLinkElement_put_rev(IHTMLLinkElement *iface, BSTR v) 148 { 149 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 150 nsAString nsstr; 151 nsresult nsres; 152 153 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 154 155 nsAString_InitDepend(&nsstr, v); 156 nsres = nsIDOMHTMLLinkElement_SetRev(This->nslink, &nsstr); 157 nsAString_Finish(&nsstr); 158 if(NS_FAILED(nsres)) { 159 ERR("SetRev failed: %08x\n", nsres); 160 return E_FAIL; 161 } 162 163 return S_OK; 164 } 165 166 static HRESULT WINAPI HTMLLinkElement_get_rev(IHTMLLinkElement *iface, BSTR *p) 167 { 168 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 169 nsAString nsstr; 170 nsresult nsres; 171 172 TRACE("(%p)->(%p)\n", This, p); 173 174 nsAString_Init(&nsstr, NULL); 175 nsres = nsIDOMHTMLLinkElement_GetRev(This->nslink, &nsstr); 176 return return_nsstr(nsres, &nsstr, p); 177 } 178 179 static HRESULT WINAPI HTMLLinkElement_put_type(IHTMLLinkElement *iface, BSTR v) 180 { 181 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 182 nsAString type_str; 183 nsresult nsres; 184 185 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 186 187 nsAString_InitDepend(&type_str, v); 188 nsres = nsIDOMHTMLLinkElement_SetType(This->nslink, &type_str); 189 nsAString_Finish(&type_str); 190 191 return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL; 192 } 193 194 static HRESULT WINAPI HTMLLinkElement_get_type(IHTMLLinkElement *iface, BSTR *p) 195 { 196 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 197 nsAString type_str; 198 nsresult nsres; 199 200 TRACE("(%p)->(%p)\n", This, p); 201 202 nsAString_Init(&type_str, NULL); 203 nsres = nsIDOMHTMLLinkElement_GetType(This->nslink, &type_str); 204 return return_nsstr(nsres, &type_str, p); 205 } 206 207 static HRESULT WINAPI HTMLLinkElement_get_readyState(IHTMLLinkElement *iface, BSTR *p) 208 { 209 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 210 FIXME("(%p)->(%p)\n", This, p); 211 return E_NOTIMPL; 212 } 213 214 static HRESULT WINAPI HTMLLinkElement_put_onreadystatechange(IHTMLLinkElement *iface, VARIANT v) 215 { 216 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 217 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); 218 return E_NOTIMPL; 219 } 220 221 static HRESULT WINAPI HTMLLinkElement_get_onreadystatechange(IHTMLLinkElement *iface, VARIANT *p) 222 { 223 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 224 FIXME("(%p)->(%p)\n", This, p); 225 return E_NOTIMPL; 226 } 227 228 static HRESULT WINAPI HTMLLinkElement_put_onload(IHTMLLinkElement *iface, VARIANT v) 229 { 230 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 231 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); 232 return E_NOTIMPL; 233 } 234 235 static HRESULT WINAPI HTMLLinkElement_get_onload(IHTMLLinkElement *iface, VARIANT *p) 236 { 237 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 238 FIXME("(%p)->(%p)\n", This, p); 239 return E_NOTIMPL; 240 } 241 242 static HRESULT WINAPI HTMLLinkElement_put_onerror(IHTMLLinkElement *iface, VARIANT v) 243 { 244 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 245 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); 246 return E_NOTIMPL; 247 } 248 249 static HRESULT WINAPI HTMLLinkElement_get_onerror(IHTMLLinkElement *iface, VARIANT *p) 250 { 251 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 252 FIXME("(%p)->(%p)\n", This, p); 253 return E_NOTIMPL; 254 } 255 256 static HRESULT WINAPI HTMLLinkElement_get_styleSheet(IHTMLLinkElement *iface, IHTMLStyleSheet **p) 257 { 258 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 259 FIXME("(%p)->(%p)\n", This, p); 260 return E_NOTIMPL; 261 } 262 263 static HRESULT WINAPI HTMLLinkElement_put_disabled(IHTMLLinkElement *iface, VARIANT_BOOL v) 264 { 265 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 266 nsresult nsres; 267 268 TRACE("(%p)->(%x)\n", This, v); 269 270 nsres = nsIDOMHTMLLinkElement_SetDisabled(This->nslink, !!v); 271 return SUCCEEDED(nsres) ? S_OK : E_FAIL; 272 } 273 274 static HRESULT WINAPI HTMLLinkElement_get_disabled(IHTMLLinkElement *iface, VARIANT_BOOL *p) 275 { 276 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 277 cpp_bool ret; 278 nsresult nsres; 279 280 TRACE("(%p)->(%p)\n", This, p); 281 282 nsres = nsIDOMHTMLLinkElement_GetDisabled(This->nslink, &ret); 283 if(NS_FAILED(nsres)) 284 return E_FAIL; 285 286 *p = ret ? VARIANT_TRUE : VARIANT_FALSE; 287 return S_OK; 288 } 289 290 static HRESULT WINAPI HTMLLinkElement_put_media(IHTMLLinkElement *iface, BSTR v) 291 { 292 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 293 nsresult nsres; 294 nsAString str; 295 296 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 297 298 nsAString_InitDepend(&str, v); 299 300 nsres = nsIDOMHTMLLinkElement_SetMedia(This->nslink, &str); 301 nsAString_Finish(&str); 302 303 if(NS_FAILED(nsres)) { 304 ERR("Set Media(%s) failed: %08x\n", debugstr_w(v), nsres); 305 return E_FAIL; 306 } 307 return S_OK; 308 } 309 310 static HRESULT WINAPI HTMLLinkElement_get_media(IHTMLLinkElement *iface, BSTR *p) 311 { 312 HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface); 313 nsresult nsres; 314 nsAString str; 315 316 TRACE("(%p)->(%p)\n", This, p); 317 318 nsAString_Init(&str, NULL); 319 nsres = nsIDOMHTMLLinkElement_GetMedia(This->nslink, &str); 320 321 return return_nsstr(nsres, &str, p); 322 } 323 324 static const IHTMLLinkElementVtbl HTMLLinkElementVtbl = { 325 HTMLLinkElement_QueryInterface, 326 HTMLLinkElement_AddRef, 327 HTMLLinkElement_Release, 328 HTMLLinkElement_GetTypeInfoCount, 329 HTMLLinkElement_GetTypeInfo, 330 HTMLLinkElement_GetIDsOfNames, 331 HTMLLinkElement_Invoke, 332 HTMLLinkElement_put_href, 333 HTMLLinkElement_get_href, 334 HTMLLinkElement_put_rel, 335 HTMLLinkElement_get_rel, 336 HTMLLinkElement_put_rev, 337 HTMLLinkElement_get_rev, 338 HTMLLinkElement_put_type, 339 HTMLLinkElement_get_type, 340 HTMLLinkElement_get_readyState, 341 HTMLLinkElement_put_onreadystatechange, 342 HTMLLinkElement_get_onreadystatechange, 343 HTMLLinkElement_put_onload, 344 HTMLLinkElement_get_onload, 345 HTMLLinkElement_put_onerror, 346 HTMLLinkElement_get_onerror, 347 HTMLLinkElement_get_styleSheet, 348 HTMLLinkElement_put_disabled, 349 HTMLLinkElement_get_disabled, 350 HTMLLinkElement_put_media, 351 HTMLLinkElement_get_media 352 }; 353 354 static inline HTMLLinkElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface) 355 { 356 return CONTAINING_RECORD(iface, HTMLLinkElement, element.node); 357 } 358 359 static HRESULT HTMLLinkElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) 360 { 361 HTMLLinkElement *This = impl_from_HTMLDOMNode(iface); 362 363 if(IsEqualGUID(&IID_IHTMLLinkElement, riid)) { 364 TRACE("(%p)->(IID_IHTMLLinkElement %p)\n", This, ppv); 365 *ppv = &This->IHTMLLinkElement_iface; 366 }else { 367 return HTMLElement_QI(&This->element.node, riid, ppv); 368 } 369 370 IUnknown_AddRef((IUnknown*)*ppv); 371 return S_OK; 372 } 373 374 static HRESULT HTMLLinkElementImpl_put_disabled(HTMLDOMNode *iface, VARIANT_BOOL v) 375 { 376 HTMLLinkElement *This = impl_from_HTMLDOMNode(iface); 377 return IHTMLLinkElement_put_disabled(&This->IHTMLLinkElement_iface, v); 378 } 379 380 static HRESULT HTMLLinkElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BOOL *p) 381 { 382 HTMLLinkElement *This = impl_from_HTMLDOMNode(iface); 383 return IHTMLLinkElement_get_disabled(&This->IHTMLLinkElement_iface, p); 384 } 385 386 static void HTMLLinkElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb) 387 { 388 HTMLLinkElement *This = impl_from_HTMLDOMNode(iface); 389 390 if(This->nslink) 391 note_cc_edge((nsISupports*)This->nslink, "This->nslink", cb); 392 } 393 394 static void HTMLLinkElement_unlink(HTMLDOMNode *iface) 395 { 396 HTMLLinkElement *This = impl_from_HTMLDOMNode(iface); 397 398 if(This->nslink) { 399 nsIDOMHTMLLinkElement *nslink = This->nslink; 400 401 This->nslink = NULL; 402 nsIDOMHTMLLinkElement_Release(nslink); 403 } 404 } 405 static const NodeImplVtbl HTMLLinkElementImplVtbl = { 406 HTMLLinkElement_QI, 407 HTMLElement_destructor, 408 HTMLElement_cpc, 409 HTMLElement_clone, 410 HTMLElement_handle_event, 411 HTMLElement_get_attr_col, 412 NULL, 413 NULL, 414 HTMLLinkElementImpl_put_disabled, 415 HTMLLinkElementImpl_get_disabled, 416 NULL, 417 NULL, 418 NULL, 419 NULL, 420 NULL, 421 HTMLLinkElement_traverse, 422 HTMLLinkElement_unlink 423 }; 424 425 static const tid_t HTMLLinkElement_iface_tids[] = { 426 HTMLELEMENT_TIDS, 427 IHTMLLinkElement_tid, 428 0 429 }; 430 static dispex_static_data_t HTMLLinkElement_dispex = { 431 NULL, 432 DispHTMLLinkElement_tid, 433 NULL, 434 HTMLLinkElement_iface_tids 435 }; 436 437 HRESULT HTMLLinkElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem) 438 { 439 HTMLLinkElement *ret; 440 nsresult nsres; 441 442 ret = heap_alloc_zero(sizeof(*ret)); 443 if(!ret) 444 return E_OUTOFMEMORY; 445 446 ret->IHTMLLinkElement_iface.lpVtbl = &HTMLLinkElementVtbl; 447 ret->element.node.vtbl = &HTMLLinkElementImplVtbl; 448 449 HTMLElement_Init(&ret->element, doc, nselem, &HTMLLinkElement_dispex); 450 451 nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLLinkElement, (void**)&ret->nslink); 452 assert(nsres == NS_OK); 453 454 *elem = &ret->element; 455 return S_OK; 456 } 457