winedump: Consistently print hex numbers with leading zeros and 'h' suffix.
[wine.git] / dlls / mshtml / htmlanchor.c
blob7c845bb4a1ec955be51138f07bc3a74f3b534c70
1 /*
2 * Copyright 2007 Jacek Caban for CodeWeavers
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.
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.
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
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <assert.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
32 #include "binding.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38 struct HTMLAnchorElement {
39 HTMLElement element;
41 IHTMLAnchorElement IHTMLAnchorElement_iface;
43 nsIDOMHTMLAnchorElement *nsanchor;
46 static HRESULT navigate_href_new_window(HTMLElement *element, nsAString *href_str, const WCHAR *target)
48 const PRUnichar *href;
49 IUri *uri;
50 HRESULT hres;
52 nsAString_GetData(href_str, &href);
53 hres = create_relative_uri(element->node.doc->basedoc.window, href, &uri);
54 if(FAILED(hres))
55 return hres;
57 hres = navigate_new_window(element->node.doc->basedoc.window, uri, target, NULL, NULL);
58 IUri_Release(uri);
59 return hres;
62 HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_str, BOOL *use_new_window)
64 HTMLOuterWindow *top_window, *ret_window;
65 const PRUnichar *target;
66 HRESULT hres;
68 static const WCHAR _parentW[] = {'_','p','a','r','e','n','t',0};
69 static const WCHAR _selfW[] = {'_','s','e','l','f',0};
70 static const WCHAR _topW[] = {'_','t','o','p',0};
72 *use_new_window = FALSE;
74 nsAString_GetData(target_str, &target);
75 TRACE("%s\n", debugstr_w(target));
77 if(!*target || !strcmpiW(target, _selfW)) {
78 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
79 return window;
82 if(!strcmpiW(target, _topW)) {
83 get_top_window(window, &top_window);
84 IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface);
85 return top_window;
88 if(!strcmpiW(target, _parentW)) {
89 if(!window->parent) {
90 WARN("Window has no parent, treat as self\n");
91 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
92 return window;
95 IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface);
96 return window->parent;
99 get_top_window(window, &top_window);
101 hres = get_frame_by_name(top_window, target, TRUE, &ret_window);
102 if(FAILED(hres) || !ret_window) {
103 *use_new_window = TRUE;
104 return NULL;
107 IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface);
108 return ret_window;
111 static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAString *target_str)
113 HTMLOuterWindow *window;
114 BOOL use_new_window;
115 const PRUnichar *href;
116 HRESULT hres;
118 window = get_target_window(element->node.doc->basedoc.window, target_str, &use_new_window);
119 if(!window) {
120 if(use_new_window) {
121 const PRUnichar *target;
122 nsAString_GetData(target_str, &target);
123 return navigate_href_new_window(element, href_str, target);
124 }else {
125 return S_OK;
129 nsAString_GetData(href_str, &href);
130 if(*href) {
131 hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED);
132 }else {
133 TRACE("empty href\n");
134 hres = S_OK;
136 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
137 return hres;
140 HRESULT handle_link_click_event(HTMLElement *element, nsAString *href_str, nsAString *target_str,
141 nsIDOMEvent *event, BOOL *prevent_default)
143 nsIDOMMouseEvent *mouse_event;
144 INT16 button;
145 nsresult nsres;
146 HRESULT hres;
148 TRACE("CLICK\n");
150 nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
151 assert(nsres == NS_OK);
153 nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button);
154 assert(nsres == NS_OK);
156 nsIDOMMouseEvent_Release(mouse_event);
158 switch(button) {
159 case 0:
160 *prevent_default = TRUE;
161 hres = navigate_href(element, href_str, target_str);
162 break;
163 case 1:
164 *prevent_default = TRUE;
165 hres = navigate_href_new_window(element, href_str, NULL);
166 break;
167 default:
168 *prevent_default = FALSE;
169 hres = S_OK;
172 nsAString_Finish(href_str);
173 nsAString_Finish(target_str);
174 return hres;
177 static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
179 return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
182 static HRESULT WINAPI HTMLAnchorElement_QueryInterface(IHTMLAnchorElement *iface,
183 REFIID riid, void **ppv)
185 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
187 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
190 static ULONG WINAPI HTMLAnchorElement_AddRef(IHTMLAnchorElement *iface)
192 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
194 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
197 static ULONG WINAPI HTMLAnchorElement_Release(IHTMLAnchorElement *iface)
199 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
201 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
204 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfoCount(IHTMLAnchorElement *iface, UINT *pctinfo)
206 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
207 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
210 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfo(IHTMLAnchorElement *iface, UINT iTInfo,
211 LCID lcid, ITypeInfo **ppTInfo)
213 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
214 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
215 ppTInfo);
218 static HRESULT WINAPI HTMLAnchorElement_GetIDsOfNames(IHTMLAnchorElement *iface, REFIID riid,
219 LPOLESTR *rgszNames, UINT cNames,
220 LCID lcid, DISPID *rgDispId)
222 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
223 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
224 cNames, lcid, rgDispId);
227 static HRESULT WINAPI HTMLAnchorElement_Invoke(IHTMLAnchorElement *iface, DISPID dispIdMember,
228 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
229 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
231 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
232 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
233 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
236 static HRESULT WINAPI HTMLAnchorElement_put_href(IHTMLAnchorElement *iface, BSTR v)
238 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
239 nsAString nsstr;
240 nsresult nsres;
242 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
244 nsAString_InitDepend(&nsstr, v);
245 nsres = nsIDOMHTMLAnchorElement_SetHref(This->nsanchor, &nsstr);
246 nsAString_Finish(&nsstr);
247 if(NS_FAILED(nsres))
248 return E_FAIL;
250 return S_OK;
253 static HRESULT WINAPI HTMLAnchorElement_get_href(IHTMLAnchorElement *iface, BSTR *p)
255 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
256 nsAString href_str;
257 nsresult nsres;
258 HRESULT hres;
260 TRACE("(%p)->(%p)\n", This, p);
262 nsAString_Init(&href_str, NULL);
263 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
264 if(NS_SUCCEEDED(nsres)) {
265 const PRUnichar *href;
267 nsAString_GetData(&href_str, &href);
268 hres = nsuri_to_url(href, TRUE, p);
269 }else {
270 ERR("GetHref failed: %08x\n", nsres);
271 hres = E_FAIL;
274 nsAString_Finish(&href_str);
275 return hres;
278 static HRESULT WINAPI HTMLAnchorElement_put_target(IHTMLAnchorElement *iface, BSTR v)
280 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
281 nsAString nsstr;
282 nsresult nsres;
284 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
286 nsAString_InitDepend(&nsstr, v);
287 nsres = nsIDOMHTMLAnchorElement_SetTarget(This->nsanchor, &nsstr);
288 nsAString_Finish(&nsstr);
289 if(NS_FAILED(nsres))
290 return E_FAIL;
292 return S_OK;
295 static HRESULT WINAPI HTMLAnchorElement_get_target(IHTMLAnchorElement *iface, BSTR *p)
297 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
298 nsAString target_str;
299 nsresult nsres;
301 TRACE("(%p)->(%p)\n", This, p);
303 nsAString_Init(&target_str, NULL);
304 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
306 return return_nsstr(nsres, &target_str, p);
309 static HRESULT WINAPI HTMLAnchorElement_put_rel(IHTMLAnchorElement *iface, BSTR v)
311 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
312 nsAString nsstr;
313 nsresult nsres;
315 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
317 nsAString_InitDepend(&nsstr, v);
318 nsres = nsIDOMHTMLAnchorElement_SetRel(This->nsanchor, &nsstr);
319 nsAString_Finish(&nsstr);
320 if(NS_FAILED(nsres))
321 return E_FAIL;
323 return S_OK;
326 static HRESULT WINAPI HTMLAnchorElement_get_rel(IHTMLAnchorElement *iface, BSTR *p)
328 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
329 nsAString nsstr;
330 nsresult nsres;
332 TRACE("(%p)->(%p)\n", This, p);
334 nsAString_Init(&nsstr, NULL);
335 nsres = nsIDOMHTMLAnchorElement_GetRel(This->nsanchor, &nsstr);
336 return return_nsstr(nsres, &nsstr, p);
339 static HRESULT WINAPI HTMLAnchorElement_put_rev(IHTMLAnchorElement *iface, BSTR v)
341 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
342 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
343 return E_NOTIMPL;
346 static HRESULT WINAPI HTMLAnchorElement_get_rev(IHTMLAnchorElement *iface, BSTR *p)
348 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
349 FIXME("(%p)->(%p)\n", This, p);
350 return E_NOTIMPL;
353 static HRESULT WINAPI HTMLAnchorElement_put_urn(IHTMLAnchorElement *iface, BSTR v)
355 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
356 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
357 return E_NOTIMPL;
360 static HRESULT WINAPI HTMLAnchorElement_get_urn(IHTMLAnchorElement *iface, BSTR *p)
362 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
363 FIXME("(%p)->(%p)\n", This, p);
364 return E_NOTIMPL;
367 static HRESULT WINAPI HTMLAnchorElement_put_Methods(IHTMLAnchorElement *iface, BSTR v)
369 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
370 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
371 return E_NOTIMPL;
374 static HRESULT WINAPI HTMLAnchorElement_get_Methods(IHTMLAnchorElement *iface, BSTR *p)
376 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
377 FIXME("(%p)->(%p)\n", This, p);
378 return E_NOTIMPL;
381 static HRESULT WINAPI HTMLAnchorElement_put_name(IHTMLAnchorElement *iface, BSTR v)
383 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
384 nsAString nsstr;
385 nsresult nsres;
387 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
389 nsAString_InitDepend(&nsstr, v);
390 nsres = nsIDOMHTMLAnchorElement_SetName(This->nsanchor, &nsstr);
391 nsAString_Finish(&nsstr);
392 if(NS_FAILED(nsres))
393 return E_FAIL;
395 return S_OK;
398 static HRESULT WINAPI HTMLAnchorElement_get_name(IHTMLAnchorElement *iface, BSTR *p)
400 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
401 nsAString name_str;
402 nsresult nsres;
404 TRACE("(%p)->(%p)\n", This, p);
406 nsAString_Init(&name_str, NULL);
407 nsres = nsIDOMHTMLAnchorElement_GetName(This->nsanchor, &name_str);
409 return return_nsstr(nsres, &name_str, p);
412 static HRESULT WINAPI HTMLAnchorElement_put_host(IHTMLAnchorElement *iface, BSTR v)
414 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
415 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
416 return E_NOTIMPL;
419 static HRESULT WINAPI HTMLAnchorElement_get_host(IHTMLAnchorElement *iface, BSTR *p)
421 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
422 FIXME("(%p)->(%p)\n", This, p);
423 return E_NOTIMPL;
426 static HRESULT WINAPI HTMLAnchorElement_put_hostname(IHTMLAnchorElement *iface, BSTR v)
428 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
429 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
430 return E_NOTIMPL;
433 static HRESULT WINAPI HTMLAnchorElement_get_hostname(IHTMLAnchorElement *iface, BSTR *p)
435 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
436 nsAString hostname_str;
437 nsresult nsres;
439 TRACE("(%p)->(%p)\n", This, p);
441 nsAString_Init(&hostname_str, NULL);
442 nsres = nsIDOMHTMLAnchorElement_GetHostname(This->nsanchor, &hostname_str);
443 return return_nsstr(nsres, &hostname_str, p);
446 static HRESULT WINAPI HTMLAnchorElement_put_pathname(IHTMLAnchorElement *iface, BSTR v)
448 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
449 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
450 return E_NOTIMPL;
453 static HRESULT WINAPI HTMLAnchorElement_get_pathname(IHTMLAnchorElement *iface, BSTR *p)
455 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
456 FIXME("(%p)->(%p)\n", This, p);
457 return E_NOTIMPL;
460 static HRESULT WINAPI HTMLAnchorElement_put_port(IHTMLAnchorElement *iface, BSTR v)
462 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
463 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
464 return E_NOTIMPL;
467 static HRESULT WINAPI HTMLAnchorElement_get_port(IHTMLAnchorElement *iface, BSTR *p)
469 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
470 FIXME("(%p)->(%p)\n", This, p);
471 return E_NOTIMPL;
474 static HRESULT WINAPI HTMLAnchorElement_put_protocol(IHTMLAnchorElement *iface, BSTR v)
476 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
477 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
478 return E_NOTIMPL;
481 static HRESULT WINAPI HTMLAnchorElement_get_protocol(IHTMLAnchorElement *iface, BSTR *p)
483 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
484 FIXME("(%p)->(%p)\n", This, p);
485 return E_NOTIMPL;
488 static HRESULT WINAPI HTMLAnchorElement_put_search(IHTMLAnchorElement *iface, BSTR v)
490 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
491 nsAString nsstr;
492 nsresult nsres;
494 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
496 nsAString_InitDepend(&nsstr, v);
497 nsres = nsIDOMHTMLAnchorElement_SetSearch(This->nsanchor, &nsstr);
498 nsAString_Finish(&nsstr);
499 if(NS_FAILED(nsres))
500 return E_FAIL;
502 return S_OK;
505 static HRESULT WINAPI HTMLAnchorElement_get_search(IHTMLAnchorElement *iface, BSTR *p)
507 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
508 nsAString search_str;
509 nsresult nsres;
511 TRACE("(%p)->(%p)\n", This, p);
513 nsAString_Init(&search_str, NULL);
514 nsres = nsIDOMHTMLAnchorElement_GetSearch(This->nsanchor, &search_str);
515 return return_nsstr(nsres, &search_str, p);
518 static HRESULT WINAPI HTMLAnchorElement_put_hash(IHTMLAnchorElement *iface, BSTR v)
520 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
521 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
522 return E_NOTIMPL;
525 static HRESULT WINAPI HTMLAnchorElement_get_hash(IHTMLAnchorElement *iface, BSTR *p)
527 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
528 nsAString hash_str;
529 nsresult nsres;
531 TRACE("(%p)->(%p)\n", This, p);
533 nsAString_Init(&hash_str, NULL);
534 nsres = nsIDOMHTMLAnchorElement_GetHash(This->nsanchor, &hash_str);
535 return return_nsstr(nsres, &hash_str, p);
538 static HRESULT WINAPI HTMLAnchorElement_put_onblur(IHTMLAnchorElement *iface, VARIANT v)
540 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
542 TRACE("(%p)->()\n", This);
544 return IHTMLElement2_put_onblur(&This->element.IHTMLElement2_iface, v);
547 static HRESULT WINAPI HTMLAnchorElement_get_onblur(IHTMLAnchorElement *iface, VARIANT *p)
549 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
551 TRACE("(%p)->(%p)\n", This, p);
553 return IHTMLElement2_get_onblur(&This->element.IHTMLElement2_iface, p);
556 static HRESULT WINAPI HTMLAnchorElement_put_onfocus(IHTMLAnchorElement *iface, VARIANT v)
558 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
560 TRACE("(%p)->()\n", This);
562 return IHTMLElement2_put_onfocus(&This->element.IHTMLElement2_iface, v);
565 static HRESULT WINAPI HTMLAnchorElement_get_onfocus(IHTMLAnchorElement *iface, VARIANT *p)
567 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
569 TRACE("(%p)->(%p)\n", This, p);
571 return IHTMLElement2_get_onfocus(&This->element.IHTMLElement2_iface, p);
574 static HRESULT WINAPI HTMLAnchorElement_put_accessKey(IHTMLAnchorElement *iface, BSTR v)
576 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
578 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
580 return IHTMLElement2_put_accessKey(&This->element.IHTMLElement2_iface, v);
583 static HRESULT WINAPI HTMLAnchorElement_get_accessKey(IHTMLAnchorElement *iface, BSTR *p)
585 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
587 TRACE("(%p)->(%p)\n", This, p);
589 return IHTMLElement2_get_accessKey(&This->element.IHTMLElement2_iface, p);
592 static HRESULT WINAPI HTMLAnchorElement_get_protocolLong(IHTMLAnchorElement *iface, BSTR *p)
594 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
595 FIXME("(%p)->(%p)\n", This, p);
596 return E_NOTIMPL;
599 static HRESULT WINAPI HTMLAnchorElement_get_mimeType(IHTMLAnchorElement *iface, BSTR *p)
601 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
602 FIXME("(%p)->(%p)\n", This, p);
603 return E_NOTIMPL;
606 static HRESULT WINAPI HTMLAnchorElement_get_nameProp(IHTMLAnchorElement *iface, BSTR *p)
608 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
609 FIXME("(%p)->(%p)\n", This, p);
610 return E_NOTIMPL;
613 static HRESULT WINAPI HTMLAnchorElement_put_tabIndex(IHTMLAnchorElement *iface, short v)
615 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
617 TRACE("(%p)->()\n", This);
619 return IHTMLElement2_put_tabIndex(&This->element.IHTMLElement2_iface, v);
622 static HRESULT WINAPI HTMLAnchorElement_get_tabIndex(IHTMLAnchorElement *iface, short *p)
624 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
626 TRACE("(%p)->(%p)\n", This, p);
628 return IHTMLElement2_get_tabIndex(&This->element.IHTMLElement2_iface, p);
631 static HRESULT WINAPI HTMLAnchorElement_focus(IHTMLAnchorElement *iface)
633 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
635 TRACE("(%p)\n", This);
637 return IHTMLElement2_focus(&This->element.IHTMLElement2_iface);
640 static HRESULT WINAPI HTMLAnchorElement_blur(IHTMLAnchorElement *iface)
642 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
644 TRACE("(%p)\n", This);
646 return IHTMLElement2_blur(&This->element.IHTMLElement2_iface);
649 static const IHTMLAnchorElementVtbl HTMLAnchorElementVtbl = {
650 HTMLAnchorElement_QueryInterface,
651 HTMLAnchorElement_AddRef,
652 HTMLAnchorElement_Release,
653 HTMLAnchorElement_GetTypeInfoCount,
654 HTMLAnchorElement_GetTypeInfo,
655 HTMLAnchorElement_GetIDsOfNames,
656 HTMLAnchorElement_Invoke,
657 HTMLAnchorElement_put_href,
658 HTMLAnchorElement_get_href,
659 HTMLAnchorElement_put_target,
660 HTMLAnchorElement_get_target,
661 HTMLAnchorElement_put_rel,
662 HTMLAnchorElement_get_rel,
663 HTMLAnchorElement_put_rev,
664 HTMLAnchorElement_get_rev,
665 HTMLAnchorElement_put_urn,
666 HTMLAnchorElement_get_urn,
667 HTMLAnchorElement_put_Methods,
668 HTMLAnchorElement_get_Methods,
669 HTMLAnchorElement_put_name,
670 HTMLAnchorElement_get_name,
671 HTMLAnchorElement_put_host,
672 HTMLAnchorElement_get_host,
673 HTMLAnchorElement_put_hostname,
674 HTMLAnchorElement_get_hostname,
675 HTMLAnchorElement_put_pathname,
676 HTMLAnchorElement_get_pathname,
677 HTMLAnchorElement_put_port,
678 HTMLAnchorElement_get_port,
679 HTMLAnchorElement_put_protocol,
680 HTMLAnchorElement_get_protocol,
681 HTMLAnchorElement_put_search,
682 HTMLAnchorElement_get_search,
683 HTMLAnchorElement_put_hash,
684 HTMLAnchorElement_get_hash,
685 HTMLAnchorElement_put_onblur,
686 HTMLAnchorElement_get_onblur,
687 HTMLAnchorElement_put_onfocus,
688 HTMLAnchorElement_get_onfocus,
689 HTMLAnchorElement_put_accessKey,
690 HTMLAnchorElement_get_accessKey,
691 HTMLAnchorElement_get_protocolLong,
692 HTMLAnchorElement_get_mimeType,
693 HTMLAnchorElement_get_nameProp,
694 HTMLAnchorElement_put_tabIndex,
695 HTMLAnchorElement_get_tabIndex,
696 HTMLAnchorElement_focus,
697 HTMLAnchorElement_blur
700 static inline HTMLAnchorElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
702 return CONTAINING_RECORD(iface, HTMLAnchorElement, element.node);
705 static HRESULT HTMLAnchorElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
707 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
709 *ppv = NULL;
711 if(IsEqualGUID(&IID_IUnknown, riid)) {
712 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
713 *ppv = &This->IHTMLAnchorElement_iface;
714 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
715 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
716 *ppv = &This->IHTMLAnchorElement_iface;
717 }else if(IsEqualGUID(&IID_IHTMLAnchorElement, riid)) {
718 TRACE("(%p)->(IID_IHTMLAnchorElement %p)\n", This, ppv);
719 *ppv = &This->IHTMLAnchorElement_iface;
722 if(*ppv) {
723 IUnknown_AddRef((IUnknown*)*ppv);
724 return S_OK;
727 return HTMLElement_QI(&This->element.node, riid, ppv);
730 static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default)
732 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
733 nsAString href_str, target_str;
734 nsresult nsres;
736 if(eid == EVENTID_CLICK) {
737 nsAString_Init(&href_str, NULL);
738 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
739 if (NS_FAILED(nsres)) {
740 ERR("Could not get anchor href: %08x\n", nsres);
741 goto fallback;
744 nsAString_Init(&target_str, NULL);
745 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
746 if (NS_FAILED(nsres)) {
747 ERR("Could not get anchor target: %08x\n", nsres);
748 goto fallback;
751 return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);
753 fallback:
754 nsAString_Finish(&href_str);
755 nsAString_Finish(&target_str);
758 return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
761 static void HTMLAnchorElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
763 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
765 if(This->nsanchor)
766 note_cc_edge((nsISupports*)This->nsanchor, "This->nsanchor", cb);
769 static void HTMLAnchorElement_unlink(HTMLDOMNode *iface)
771 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
773 if(This->nsanchor) {
774 nsIDOMHTMLAnchorElement *nsanchor = This->nsanchor;
776 This->nsanchor = NULL;
777 nsIDOMHTMLAnchorElement_Release(nsanchor);
781 static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
782 &CLSID_HTMLAnchorElement,
783 HTMLAnchorElement_QI,
784 HTMLElement_destructor,
785 HTMLElement_cpc,
786 HTMLElement_clone,
787 HTMLAnchorElement_handle_event,
788 HTMLElement_get_attr_col,
789 NULL,
790 NULL,
791 NULL,
792 NULL,
793 NULL,
794 NULL,
795 NULL,
796 NULL,
797 HTMLAnchorElement_traverse,
798 HTMLAnchorElement_unlink
801 static const tid_t HTMLAnchorElement_iface_tids[] = {
802 IHTMLAnchorElement_tid,
803 HTMLELEMENT_TIDS,
807 static dispex_static_data_t HTMLAnchorElement_dispex = {
808 NULL,
809 DispHTMLAnchorElement_tid,
810 HTMLAnchorElement_iface_tids,
811 HTMLElement_init_dispex_info
814 HRESULT HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
816 HTMLAnchorElement *ret;
817 nsresult nsres;
819 ret = heap_alloc_zero(sizeof(HTMLAnchorElement));
820 if(!ret)
821 return E_OUTOFMEMORY;
823 ret->IHTMLAnchorElement_iface.lpVtbl = &HTMLAnchorElementVtbl;
824 ret->element.node.vtbl = &HTMLAnchorElementImplVtbl;
826 HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex);
828 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor);
829 assert(nsres == NS_OK);
831 *elem = &ret->element;
832 return S_OK;