1 /* 2 * Copyright 2007 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 IHTMLAnchorElement IHTMLAnchorElement_iface; 25 26 nsIDOMHTMLAnchorElement *nsanchor; 27 } HTMLAnchorElement; 28 29 static HRESULT navigate_href_new_window(HTMLElement *element, nsAString *href_str, const WCHAR *target) 30 { 31 const PRUnichar *href; 32 IUri *uri; 33 HRESULT hres; 34 35 nsAString_GetData(href_str, &href); 36 hres = create_relative_uri(element->node.doc->basedoc.window, href, &uri); 37 if(FAILED(hres)) 38 return hres; 39 40 hres = navigate_new_window(element->node.doc->basedoc.window, uri, target, NULL, NULL); 41 IUri_Release(uri); 42 return hres; 43 } 44 45 HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_str, BOOL *use_new_window) 46 { 47 HTMLOuterWindow *top_window, *ret_window; 48 const PRUnichar *target; 49 HRESULT hres; 50 51 static const WCHAR _parentW[] = {'_','p','a','r','e','n','t',0}; 52 static const WCHAR _selfW[] = {'_','s','e','l','f',0}; 53 static const WCHAR _topW[] = {'_','t','o','p',0}; 54 55 *use_new_window = FALSE; 56 57 nsAString_GetData(target_str, &target); 58 TRACE("%s\n", debugstr_w(target)); 59 60 if(!*target || !strcmpiW(target, _selfW)) { 61 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); 62 return window; 63 } 64 65 if(!strcmpiW(target, _topW)) { 66 get_top_window(window, &top_window); 67 IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface); 68 return top_window; 69 } 70 71 if(!strcmpiW(target, _parentW)) { 72 if(!window->parent) { 73 WARN("Window has no parent, treat as self\n"); 74 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); 75 return window; 76 } 77 78 IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface); 79 return window->parent; 80 } 81 82 get_top_window(window, &top_window); 83 84 hres = get_frame_by_name(top_window, target, TRUE, &ret_window); 85 if(FAILED(hres) || !ret_window) { 86 *use_new_window = TRUE; 87 return NULL; 88 } 89 90 IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface); 91 return ret_window; 92 } 93 94 static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAString *target_str) 95 { 96 HTMLOuterWindow *window; 97 BOOL use_new_window; 98 const PRUnichar *href; 99 HRESULT hres; 100 101 window = get_target_window(element->node.doc->basedoc.window, target_str, &use_new_window); 102 if(!window) { 103 if(use_new_window) { 104 const PRUnichar *target; 105 nsAString_GetData(target_str, &target); 106 return navigate_href_new_window(element, href_str, target); 107 }else { 108 return S_OK; 109 } 110 } 111 112 nsAString_GetData(href_str, &href); 113 if(*href) { 114 hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED); 115 }else { 116 TRACE("empty href\n"); 117 hres = S_OK; 118 } 119 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); 120 return hres; 121 } 122 123 HRESULT handle_link_click_event(HTMLElement *element, nsAString *href_str, nsAString *target_str, 124 nsIDOMEvent *event, BOOL *prevent_default) 125 { 126 nsIDOMMouseEvent *mouse_event; 127 INT16 button; 128 nsresult nsres; 129 HRESULT hres; 130 131 TRACE("CLICK\n"); 132 133 nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event); 134 assert(nsres == NS_OK); 135 136 nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button); 137 assert(nsres == NS_OK); 138 139 nsIDOMMouseEvent_Release(mouse_event); 140 141 switch(button) { 142 case 0: 143 *prevent_default = TRUE; 144 hres = navigate_href(element, href_str, target_str); 145 break; 146 case 1: 147 *prevent_default = TRUE; 148 hres = navigate_href_new_window(element, href_str, NULL); 149 break; 150 default: 151 *prevent_default = FALSE; 152 hres = S_OK; 153 } 154 155 nsAString_Finish(href_str); 156 nsAString_Finish(target_str); 157 return hres; 158 } 159 160 static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface) 161 { 162 return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface); 163 } 164 165 static HRESULT WINAPI HTMLAnchorElement_QueryInterface(IHTMLAnchorElement *iface, 166 REFIID riid, void **ppv) 167 { 168 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 169 170 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv); 171 } 172 173 static ULONG WINAPI HTMLAnchorElement_AddRef(IHTMLAnchorElement *iface) 174 { 175 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 176 177 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface); 178 } 179 180 static ULONG WINAPI HTMLAnchorElement_Release(IHTMLAnchorElement *iface) 181 { 182 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 183 184 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface); 185 } 186 187 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfoCount(IHTMLAnchorElement *iface, UINT *pctinfo) 188 { 189 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 190 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo); 191 } 192 193 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfo(IHTMLAnchorElement *iface, UINT iTInfo, 194 LCID lcid, ITypeInfo **ppTInfo) 195 { 196 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 197 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, 198 ppTInfo); 199 } 200 201 static HRESULT WINAPI HTMLAnchorElement_GetIDsOfNames(IHTMLAnchorElement *iface, REFIID riid, 202 LPOLESTR *rgszNames, UINT cNames, 203 LCID lcid, DISPID *rgDispId) 204 { 205 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 206 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, 207 cNames, lcid, rgDispId); 208 } 209 210 static HRESULT WINAPI HTMLAnchorElement_Invoke(IHTMLAnchorElement *iface, DISPID dispIdMember, 211 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 212 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 213 { 214 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 215 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, 216 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 217 } 218 219 static HRESULT WINAPI HTMLAnchorElement_put_href(IHTMLAnchorElement *iface, BSTR v) 220 { 221 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 222 nsAString nsstr; 223 nsresult nsres; 224 225 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 226 227 nsAString_InitDepend(&nsstr, v); 228 nsres = nsIDOMHTMLAnchorElement_SetHref(This->nsanchor, &nsstr); 229 nsAString_Finish(&nsstr); 230 if(NS_FAILED(nsres)) 231 return E_FAIL; 232 233 return S_OK; 234 } 235 236 static HRESULT WINAPI HTMLAnchorElement_get_href(IHTMLAnchorElement *iface, BSTR *p) 237 { 238 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 239 nsAString href_str; 240 nsresult nsres; 241 HRESULT hres; 242 243 TRACE("(%p)->(%p)\n", This, p); 244 245 nsAString_Init(&href_str, NULL); 246 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str); 247 if(NS_SUCCEEDED(nsres)) { 248 const PRUnichar *href; 249 250 nsAString_GetData(&href_str, &href); 251 hres = nsuri_to_url(href, TRUE, p); 252 }else { 253 ERR("GetHref failed: %08x\n", nsres); 254 hres = E_FAIL; 255 } 256 257 nsAString_Finish(&href_str); 258 return hres; 259 } 260 261 static HRESULT WINAPI HTMLAnchorElement_put_target(IHTMLAnchorElement *iface, BSTR v) 262 { 263 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 264 nsAString nsstr; 265 nsresult nsres; 266 267 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 268 269 nsAString_InitDepend(&nsstr, v); 270 nsres = nsIDOMHTMLAnchorElement_SetTarget(This->nsanchor, &nsstr); 271 nsAString_Finish(&nsstr); 272 if(NS_FAILED(nsres)) 273 return E_FAIL; 274 275 return S_OK; 276 } 277 278 static HRESULT WINAPI HTMLAnchorElement_get_target(IHTMLAnchorElement *iface, BSTR *p) 279 { 280 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 281 nsAString target_str; 282 nsresult nsres; 283 284 TRACE("(%p)->(%p)\n", This, p); 285 286 nsAString_Init(&target_str, NULL); 287 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str); 288 289 return return_nsstr(nsres, &target_str, p); 290 } 291 292 static HRESULT WINAPI HTMLAnchorElement_put_rel(IHTMLAnchorElement *iface, BSTR v) 293 { 294 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 295 nsAString nsstr; 296 nsresult nsres; 297 298 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 299 300 nsAString_InitDepend(&nsstr, v); 301 nsres = nsIDOMHTMLAnchorElement_SetRel(This->nsanchor, &nsstr); 302 nsAString_Finish(&nsstr); 303 if(NS_FAILED(nsres)) 304 return E_FAIL; 305 306 return S_OK; 307 } 308 309 static HRESULT WINAPI HTMLAnchorElement_get_rel(IHTMLAnchorElement *iface, BSTR *p) 310 { 311 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 312 nsAString nsstr; 313 nsresult nsres; 314 315 TRACE("(%p)->(%p)\n", This, p); 316 317 nsAString_Init(&nsstr, NULL); 318 nsres = nsIDOMHTMLAnchorElement_GetRel(This->nsanchor, &nsstr); 319 return return_nsstr(nsres, &nsstr, p); 320 } 321 322 static HRESULT WINAPI HTMLAnchorElement_put_rev(IHTMLAnchorElement *iface, BSTR v) 323 { 324 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 325 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 326 return E_NOTIMPL; 327 } 328 329 static HRESULT WINAPI HTMLAnchorElement_get_rev(IHTMLAnchorElement *iface, BSTR *p) 330 { 331 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 332 FIXME("(%p)->(%p)\n", This, p); 333 return E_NOTIMPL; 334 } 335 336 static HRESULT WINAPI HTMLAnchorElement_put_urn(IHTMLAnchorElement *iface, BSTR v) 337 { 338 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 339 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 340 return E_NOTIMPL; 341 } 342 343 static HRESULT WINAPI HTMLAnchorElement_get_urn(IHTMLAnchorElement *iface, BSTR *p) 344 { 345 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 346 FIXME("(%p)->(%p)\n", This, p); 347 return E_NOTIMPL; 348 } 349 350 static HRESULT WINAPI HTMLAnchorElement_put_Methods(IHTMLAnchorElement *iface, BSTR v) 351 { 352 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 353 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 354 return E_NOTIMPL; 355 } 356 357 static HRESULT WINAPI HTMLAnchorElement_get_Methods(IHTMLAnchorElement *iface, BSTR *p) 358 { 359 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 360 FIXME("(%p)->(%p)\n", This, p); 361 return E_NOTIMPL; 362 } 363 364 static HRESULT WINAPI HTMLAnchorElement_put_name(IHTMLAnchorElement *iface, BSTR v) 365 { 366 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 367 nsAString nsstr; 368 nsresult nsres; 369 370 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 371 372 nsAString_InitDepend(&nsstr, v); 373 nsres = nsIDOMHTMLAnchorElement_SetName(This->nsanchor, &nsstr); 374 nsAString_Finish(&nsstr); 375 if(NS_FAILED(nsres)) 376 return E_FAIL; 377 378 return S_OK; 379 } 380 381 static HRESULT WINAPI HTMLAnchorElement_get_name(IHTMLAnchorElement *iface, BSTR *p) 382 { 383 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 384 nsAString name_str; 385 nsresult nsres; 386 387 TRACE("(%p)->(%p)\n", This, p); 388 389 nsAString_Init(&name_str, NULL); 390 nsres = nsIDOMHTMLAnchorElement_GetName(This->nsanchor, &name_str); 391 392 return return_nsstr(nsres, &name_str, p); 393 } 394 395 static HRESULT WINAPI HTMLAnchorElement_put_host(IHTMLAnchorElement *iface, BSTR v) 396 { 397 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 398 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 399 return E_NOTIMPL; 400 } 401 402 static HRESULT WINAPI HTMLAnchorElement_get_host(IHTMLAnchorElement *iface, BSTR *p) 403 { 404 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 405 FIXME("(%p)->(%p)\n", This, p); 406 return E_NOTIMPL; 407 } 408 409 static HRESULT WINAPI HTMLAnchorElement_put_hostname(IHTMLAnchorElement *iface, BSTR v) 410 { 411 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 412 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 413 return E_NOTIMPL; 414 } 415 416 static HRESULT WINAPI HTMLAnchorElement_get_hostname(IHTMLAnchorElement *iface, BSTR *p) 417 { 418 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 419 nsAString hostname_str; 420 nsresult nsres; 421 422 TRACE("(%p)->(%p)\n", This, p); 423 424 nsAString_Init(&hostname_str, NULL); 425 nsres = nsIDOMHTMLAnchorElement_GetHostname(This->nsanchor, &hostname_str); 426 return return_nsstr(nsres, &hostname_str, p); 427 } 428 429 static HRESULT WINAPI HTMLAnchorElement_put_pathname(IHTMLAnchorElement *iface, BSTR v) 430 { 431 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 432 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 433 return E_NOTIMPL; 434 } 435 436 static HRESULT WINAPI HTMLAnchorElement_get_pathname(IHTMLAnchorElement *iface, BSTR *p) 437 { 438 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 439 FIXME("(%p)->(%p)\n", This, p); 440 return E_NOTIMPL; 441 } 442 443 static HRESULT WINAPI HTMLAnchorElement_put_port(IHTMLAnchorElement *iface, BSTR v) 444 { 445 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 446 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 447 return E_NOTIMPL; 448 } 449 450 static HRESULT WINAPI HTMLAnchorElement_get_port(IHTMLAnchorElement *iface, BSTR *p) 451 { 452 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 453 FIXME("(%p)->(%p)\n", This, p); 454 return E_NOTIMPL; 455 } 456 457 static HRESULT WINAPI HTMLAnchorElement_put_protocol(IHTMLAnchorElement *iface, BSTR v) 458 { 459 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 460 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 461 return E_NOTIMPL; 462 } 463 464 static HRESULT WINAPI HTMLAnchorElement_get_protocol(IHTMLAnchorElement *iface, BSTR *p) 465 { 466 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 467 FIXME("(%p)->(%p)\n", This, p); 468 return E_NOTIMPL; 469 } 470 471 static HRESULT WINAPI HTMLAnchorElement_put_search(IHTMLAnchorElement *iface, BSTR v) 472 { 473 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 474 nsAString nsstr; 475 nsresult nsres; 476 477 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 478 479 nsAString_InitDepend(&nsstr, v); 480 nsres = nsIDOMHTMLAnchorElement_SetSearch(This->nsanchor, &nsstr); 481 nsAString_Finish(&nsstr); 482 if(NS_FAILED(nsres)) 483 return E_FAIL; 484 485 return S_OK; 486 } 487 488 static HRESULT WINAPI HTMLAnchorElement_get_search(IHTMLAnchorElement *iface, BSTR *p) 489 { 490 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 491 nsAString search_str; 492 nsresult nsres; 493 494 TRACE("(%p)->(%p)\n", This, p); 495 496 nsAString_Init(&search_str, NULL); 497 nsres = nsIDOMHTMLAnchorElement_GetSearch(This->nsanchor, &search_str); 498 return return_nsstr(nsres, &search_str, p); 499 } 500 501 static HRESULT WINAPI HTMLAnchorElement_put_hash(IHTMLAnchorElement *iface, BSTR v) 502 { 503 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 504 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 505 return E_NOTIMPL; 506 } 507 508 static HRESULT WINAPI HTMLAnchorElement_get_hash(IHTMLAnchorElement *iface, BSTR *p) 509 { 510 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 511 nsAString hash_str; 512 nsresult nsres; 513 514 TRACE("(%p)->(%p)\n", This, p); 515 516 nsAString_Init(&hash_str, NULL); 517 nsres = nsIDOMHTMLAnchorElement_GetHash(This->nsanchor, &hash_str); 518 return return_nsstr(nsres, &hash_str, p); 519 } 520 521 static HRESULT WINAPI HTMLAnchorElement_put_onblur(IHTMLAnchorElement *iface, VARIANT v) 522 { 523 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 524 525 TRACE("(%p)->()\n", This); 526 527 return IHTMLElement2_put_onblur(&This->element.IHTMLElement2_iface, v); 528 } 529 530 static HRESULT WINAPI HTMLAnchorElement_get_onblur(IHTMLAnchorElement *iface, VARIANT *p) 531 { 532 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 533 534 TRACE("(%p)->(%p)\n", This, p); 535 536 return IHTMLElement2_get_onblur(&This->element.IHTMLElement2_iface, p); 537 } 538 539 static HRESULT WINAPI HTMLAnchorElement_put_onfocus(IHTMLAnchorElement *iface, VARIANT v) 540 { 541 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 542 543 TRACE("(%p)->()\n", This); 544 545 return IHTMLElement2_put_onfocus(&This->element.IHTMLElement2_iface, v); 546 } 547 548 static HRESULT WINAPI HTMLAnchorElement_get_onfocus(IHTMLAnchorElement *iface, VARIANT *p) 549 { 550 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 551 552 TRACE("(%p)->(%p)\n", This, p); 553 554 return IHTMLElement2_get_onfocus(&This->element.IHTMLElement2_iface, p); 555 } 556 557 static HRESULT WINAPI HTMLAnchorElement_put_accessKey(IHTMLAnchorElement *iface, BSTR v) 558 { 559 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 560 561 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 562 563 return IHTMLElement2_put_accessKey(&This->element.IHTMLElement2_iface, v); 564 } 565 566 static HRESULT WINAPI HTMLAnchorElement_get_accessKey(IHTMLAnchorElement *iface, BSTR *p) 567 { 568 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 569 570 TRACE("(%p)->(%p)\n", This, p); 571 572 return IHTMLElement2_get_accessKey(&This->element.IHTMLElement2_iface, p); 573 } 574 575 static HRESULT WINAPI HTMLAnchorElement_get_protocolLong(IHTMLAnchorElement *iface, BSTR *p) 576 { 577 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 578 FIXME("(%p)->(%p)\n", This, p); 579 return E_NOTIMPL; 580 } 581 582 static HRESULT WINAPI HTMLAnchorElement_get_mimeType(IHTMLAnchorElement *iface, BSTR *p) 583 { 584 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 585 FIXME("(%p)->(%p)\n", This, p); 586 return E_NOTIMPL; 587 } 588 589 static HRESULT WINAPI HTMLAnchorElement_get_nameProp(IHTMLAnchorElement *iface, BSTR *p) 590 { 591 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 592 FIXME("(%p)->(%p)\n", This, p); 593 return E_NOTIMPL; 594 } 595 596 static HRESULT WINAPI HTMLAnchorElement_put_tabIndex(IHTMLAnchorElement *iface, short v) 597 { 598 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 599 600 TRACE("(%p)->()\n", This); 601 602 return IHTMLElement2_put_tabIndex(&This->element.IHTMLElement2_iface, v); 603 } 604 605 static HRESULT WINAPI HTMLAnchorElement_get_tabIndex(IHTMLAnchorElement *iface, short *p) 606 { 607 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 608 609 TRACE("(%p)->(%p)\n", This, p); 610 611 return IHTMLElement2_get_tabIndex(&This->element.IHTMLElement2_iface, p); 612 } 613 614 static HRESULT WINAPI HTMLAnchorElement_focus(IHTMLAnchorElement *iface) 615 { 616 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 617 618 TRACE("(%p)\n", This); 619 620 return IHTMLElement2_focus(&This->element.IHTMLElement2_iface); 621 } 622 623 static HRESULT WINAPI HTMLAnchorElement_blur(IHTMLAnchorElement *iface) 624 { 625 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface); 626 627 TRACE("(%p)\n", This); 628 629 return IHTMLElement2_blur(&This->element.IHTMLElement2_iface); 630 } 631 632 static const IHTMLAnchorElementVtbl HTMLAnchorElementVtbl = { 633 HTMLAnchorElement_QueryInterface, 634 HTMLAnchorElement_AddRef, 635 HTMLAnchorElement_Release, 636 HTMLAnchorElement_GetTypeInfoCount, 637 HTMLAnchorElement_GetTypeInfo, 638 HTMLAnchorElement_GetIDsOfNames, 639 HTMLAnchorElement_Invoke, 640 HTMLAnchorElement_put_href, 641 HTMLAnchorElement_get_href, 642 HTMLAnchorElement_put_target, 643 HTMLAnchorElement_get_target, 644 HTMLAnchorElement_put_rel, 645 HTMLAnchorElement_get_rel, 646 HTMLAnchorElement_put_rev, 647 HTMLAnchorElement_get_rev, 648 HTMLAnchorElement_put_urn, 649 HTMLAnchorElement_get_urn, 650 HTMLAnchorElement_put_Methods, 651 HTMLAnchorElement_get_Methods, 652 HTMLAnchorElement_put_name, 653 HTMLAnchorElement_get_name, 654 HTMLAnchorElement_put_host, 655 HTMLAnchorElement_get_host, 656 HTMLAnchorElement_put_hostname, 657 HTMLAnchorElement_get_hostname, 658 HTMLAnchorElement_put_pathname, 659 HTMLAnchorElement_get_pathname, 660 HTMLAnchorElement_put_port, 661 HTMLAnchorElement_get_port, 662 HTMLAnchorElement_put_protocol, 663 HTMLAnchorElement_get_protocol, 664 HTMLAnchorElement_put_search, 665 HTMLAnchorElement_get_search, 666 HTMLAnchorElement_put_hash, 667 HTMLAnchorElement_get_hash, 668 HTMLAnchorElement_put_onblur, 669 HTMLAnchorElement_get_onblur, 670 HTMLAnchorElement_put_onfocus, 671 HTMLAnchorElement_get_onfocus, 672 HTMLAnchorElement_put_accessKey, 673 HTMLAnchorElement_get_accessKey, 674 HTMLAnchorElement_get_protocolLong, 675 HTMLAnchorElement_get_mimeType, 676 HTMLAnchorElement_get_nameProp, 677 HTMLAnchorElement_put_tabIndex, 678 HTMLAnchorElement_get_tabIndex, 679 HTMLAnchorElement_focus, 680 HTMLAnchorElement_blur 681 }; 682 683 static inline HTMLAnchorElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface) 684 { 685 return CONTAINING_RECORD(iface, HTMLAnchorElement, element.node); 686 } 687 688 static HRESULT HTMLAnchorElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) 689 { 690 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface); 691 692 *ppv = NULL; 693 694 if(IsEqualGUID(&IID_IUnknown, riid)) { 695 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 696 *ppv = &This->IHTMLAnchorElement_iface; 697 }else if(IsEqualGUID(&IID_IDispatch, riid)) { 698 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); 699 *ppv = &This->IHTMLAnchorElement_iface; 700 }else if(IsEqualGUID(&IID_IHTMLAnchorElement, riid)) { 701 TRACE("(%p)->(IID_IHTMLAnchorElement %p)\n", This, ppv); 702 *ppv = &This->IHTMLAnchorElement_iface; 703 } 704 705 if(*ppv) { 706 IUnknown_AddRef((IUnknown*)*ppv); 707 return S_OK; 708 } 709 710 return HTMLElement_QI(&This->element.node, riid, ppv); 711 } 712 713 static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *event, BOOL *prevent_default) 714 { 715 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface); 716 nsAString href_str, target_str; 717 nsresult nsres; 718 719 if(eid == EVENTID_CLICK) { 720 nsAString_Init(&href_str, NULL); 721 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str); 722 if (NS_FAILED(nsres)) { 723 ERR("Could not get anchor href: %08x\n", nsres); 724 goto fallback; 725 } 726 727 nsAString_Init(&target_str, NULL); 728 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str); 729 if (NS_FAILED(nsres)) { 730 ERR("Could not get anchor target: %08x\n", nsres); 731 goto fallback; 732 } 733 734 return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default); 735 736 fallback: 737 nsAString_Finish(&href_str); 738 nsAString_Finish(&target_str); 739 } 740 741 return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default); 742 } 743 744 static void HTMLAnchorElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb) 745 { 746 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface); 747 748 if(This->nsanchor) 749 note_cc_edge((nsISupports*)This->nsanchor, "This->nsanchor", cb); 750 } 751 752 static void HTMLAnchorElement_unlink(HTMLDOMNode *iface) 753 { 754 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface); 755 756 if(This->nsanchor) { 757 nsIDOMHTMLAnchorElement *nsanchor = This->nsanchor; 758 759 This->nsanchor = NULL; 760 nsIDOMHTMLAnchorElement_Release(nsanchor); 761 } 762 } 763 764 static const NodeImplVtbl HTMLAnchorElementImplVtbl = { 765 HTMLAnchorElement_QI, 766 HTMLElement_destructor, 767 HTMLElement_cpc, 768 HTMLElement_clone, 769 HTMLAnchorElement_handle_event, 770 HTMLElement_get_attr_col, 771 NULL, 772 NULL, 773 NULL, 774 NULL, 775 NULL, 776 NULL, 777 NULL, 778 NULL, 779 NULL, 780 HTMLAnchorElement_traverse, 781 HTMLAnchorElement_unlink 782 }; 783 784 static const tid_t HTMLAnchorElement_iface_tids[] = { 785 IHTMLAnchorElement_tid, 786 HTMLELEMENT_TIDS, 787 IHTMLUniqueName_tid, 788 0 789 }; 790 791 static dispex_static_data_t HTMLAnchorElement_dispex = { 792 NULL, 793 DispHTMLAnchorElement_tid, 794 NULL, 795 HTMLAnchorElement_iface_tids 796 }; 797 798 HRESULT HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem) 799 { 800 HTMLAnchorElement *ret; 801 nsresult nsres; 802 803 ret = heap_alloc_zero(sizeof(HTMLAnchorElement)); 804 if(!ret) 805 return E_OUTOFMEMORY; 806 807 ret->IHTMLAnchorElement_iface.lpVtbl = &HTMLAnchorElementVtbl; 808 ret->element.node.vtbl = &HTMLAnchorElementImplVtbl; 809 810 HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex); 811 812 nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor); 813 assert(nsres == NS_OK); 814 815 *elem = &ret->element; 816 return S_OK; 817 } 818