ntoskrnl.exe: Add -norelay flag for _vsnprintf.
[wine.git] / dlls / mshtml / htmlanchor.c
blob64cc6db87557ca299acb9684c59b4a09747f4daf
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 || !wcsicmp(target, _selfW)) {
78 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
79 return window;
82 if(!wcsicmp(target, _topW)) {
83 get_top_window(window, &top_window);
84 IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface);
85 return top_window;
88 if(!wcsicmp(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 IUri *get_anchor_uri(HTMLAnchorElement *anchor)
179 nsAString href_str;
180 IUri *uri = NULL;
181 nsresult nsres;
183 nsAString_Init(&href_str, NULL);
184 nsres = nsIDOMHTMLAnchorElement_GetHref(anchor->nsanchor, &href_str);
185 if(NS_SUCCEEDED(nsres)) {
186 const PRUnichar *href;
188 nsAString_GetData(&href_str, &href);
189 create_uri(href, 0, &uri);
190 }else {
191 ERR("GetHref failed: %08x\n", nsres);
194 nsAString_Finish(&href_str);
195 return uri;
198 static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
200 return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
203 static HRESULT WINAPI HTMLAnchorElement_QueryInterface(IHTMLAnchorElement *iface,
204 REFIID riid, void **ppv)
206 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
208 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
211 static ULONG WINAPI HTMLAnchorElement_AddRef(IHTMLAnchorElement *iface)
213 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
215 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
218 static ULONG WINAPI HTMLAnchorElement_Release(IHTMLAnchorElement *iface)
220 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
222 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
225 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfoCount(IHTMLAnchorElement *iface, UINT *pctinfo)
227 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
228 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
231 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfo(IHTMLAnchorElement *iface, UINT iTInfo,
232 LCID lcid, ITypeInfo **ppTInfo)
234 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
235 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
236 ppTInfo);
239 static HRESULT WINAPI HTMLAnchorElement_GetIDsOfNames(IHTMLAnchorElement *iface, REFIID riid,
240 LPOLESTR *rgszNames, UINT cNames,
241 LCID lcid, DISPID *rgDispId)
243 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
244 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
245 cNames, lcid, rgDispId);
248 static HRESULT WINAPI HTMLAnchorElement_Invoke(IHTMLAnchorElement *iface, DISPID dispIdMember,
249 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
250 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
252 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
253 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
254 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
257 static HRESULT WINAPI HTMLAnchorElement_put_href(IHTMLAnchorElement *iface, BSTR v)
259 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
260 nsAString nsstr;
261 nsresult nsres;
263 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
265 nsAString_InitDepend(&nsstr, v);
266 nsres = nsIDOMHTMLAnchorElement_SetHref(This->nsanchor, &nsstr);
267 nsAString_Finish(&nsstr);
268 if(NS_FAILED(nsres))
269 return E_FAIL;
271 return S_OK;
274 static HRESULT WINAPI HTMLAnchorElement_get_href(IHTMLAnchorElement *iface, BSTR *p)
276 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
277 nsAString href_str;
278 nsresult nsres;
279 HRESULT hres;
281 TRACE("(%p)->(%p)\n", This, p);
283 nsAString_Init(&href_str, NULL);
284 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
285 if(NS_SUCCEEDED(nsres)) {
286 const PRUnichar *href;
288 nsAString_GetData(&href_str, &href);
289 hres = nsuri_to_url(href, TRUE, p);
290 }else {
291 ERR("GetHref failed: %08x\n", nsres);
292 hres = E_FAIL;
295 nsAString_Finish(&href_str);
296 return hres;
299 static HRESULT WINAPI HTMLAnchorElement_put_target(IHTMLAnchorElement *iface, BSTR v)
301 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
302 nsAString nsstr;
303 nsresult nsres;
305 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
307 nsAString_InitDepend(&nsstr, v);
308 nsres = nsIDOMHTMLAnchorElement_SetTarget(This->nsanchor, &nsstr);
309 nsAString_Finish(&nsstr);
310 if(NS_FAILED(nsres))
311 return E_FAIL;
313 return S_OK;
316 static HRESULT WINAPI HTMLAnchorElement_get_target(IHTMLAnchorElement *iface, BSTR *p)
318 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
319 nsAString target_str;
320 nsresult nsres;
322 TRACE("(%p)->(%p)\n", This, p);
324 nsAString_Init(&target_str, NULL);
325 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
327 return return_nsstr(nsres, &target_str, p);
330 static HRESULT WINAPI HTMLAnchorElement_put_rel(IHTMLAnchorElement *iface, BSTR v)
332 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
333 nsAString nsstr;
334 nsresult nsres;
336 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
338 nsAString_InitDepend(&nsstr, v);
339 nsres = nsIDOMHTMLAnchorElement_SetRel(This->nsanchor, &nsstr);
340 nsAString_Finish(&nsstr);
341 if(NS_FAILED(nsres))
342 return E_FAIL;
344 return S_OK;
347 static HRESULT WINAPI HTMLAnchorElement_get_rel(IHTMLAnchorElement *iface, BSTR *p)
349 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
350 nsAString nsstr;
351 nsresult nsres;
353 TRACE("(%p)->(%p)\n", This, p);
355 nsAString_Init(&nsstr, NULL);
356 nsres = nsIDOMHTMLAnchorElement_GetRel(This->nsanchor, &nsstr);
357 return return_nsstr(nsres, &nsstr, p);
360 static HRESULT WINAPI HTMLAnchorElement_put_rev(IHTMLAnchorElement *iface, BSTR v)
362 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
363 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
364 return E_NOTIMPL;
367 static HRESULT WINAPI HTMLAnchorElement_get_rev(IHTMLAnchorElement *iface, BSTR *p)
369 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
370 FIXME("(%p)->(%p)\n", This, p);
371 return E_NOTIMPL;
374 static HRESULT WINAPI HTMLAnchorElement_put_urn(IHTMLAnchorElement *iface, BSTR v)
376 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
377 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
378 return E_NOTIMPL;
381 static HRESULT WINAPI HTMLAnchorElement_get_urn(IHTMLAnchorElement *iface, BSTR *p)
383 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
384 FIXME("(%p)->(%p)\n", This, p);
385 return E_NOTIMPL;
388 static HRESULT WINAPI HTMLAnchorElement_put_Methods(IHTMLAnchorElement *iface, BSTR v)
390 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
391 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
392 return E_NOTIMPL;
395 static HRESULT WINAPI HTMLAnchorElement_get_Methods(IHTMLAnchorElement *iface, BSTR *p)
397 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
398 FIXME("(%p)->(%p)\n", This, p);
399 return E_NOTIMPL;
402 static HRESULT WINAPI HTMLAnchorElement_put_name(IHTMLAnchorElement *iface, BSTR v)
404 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
405 nsAString nsstr;
406 nsresult nsres;
408 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
410 nsAString_InitDepend(&nsstr, v);
411 nsres = nsIDOMHTMLAnchorElement_SetName(This->nsanchor, &nsstr);
412 nsAString_Finish(&nsstr);
413 if(NS_FAILED(nsres))
414 return E_FAIL;
416 return S_OK;
419 static HRESULT WINAPI HTMLAnchorElement_get_name(IHTMLAnchorElement *iface, BSTR *p)
421 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
422 nsAString name_str;
423 nsresult nsres;
425 TRACE("(%p)->(%p)\n", This, p);
427 nsAString_Init(&name_str, NULL);
428 nsres = nsIDOMHTMLAnchorElement_GetName(This->nsanchor, &name_str);
430 return return_nsstr(nsres, &name_str, p);
433 static HRESULT WINAPI HTMLAnchorElement_put_host(IHTMLAnchorElement *iface, BSTR v)
435 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
436 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
437 return E_NOTIMPL;
440 static HRESULT WINAPI HTMLAnchorElement_get_host(IHTMLAnchorElement *iface, BSTR *p)
442 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
443 nsAString str;
444 nsresult nsres;
446 TRACE("(%p)->(%p)\n", This, p);
448 /* FIXME: IE always appends port number, even if it's implicit default number */
449 nsAString_InitDepend(&str, NULL);
450 nsres = nsIDOMHTMLAnchorElement_GetHost(This->nsanchor, &str);
451 return return_nsstr(nsres, &str, p);
454 static HRESULT WINAPI HTMLAnchorElement_put_hostname(IHTMLAnchorElement *iface, BSTR v)
456 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
457 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
458 return E_NOTIMPL;
461 static HRESULT WINAPI HTMLAnchorElement_get_hostname(IHTMLAnchorElement *iface, BSTR *p)
463 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
464 nsAString hostname_str;
465 nsresult nsres;
467 TRACE("(%p)->(%p)\n", This, p);
469 nsAString_Init(&hostname_str, NULL);
470 nsres = nsIDOMHTMLAnchorElement_GetHostname(This->nsanchor, &hostname_str);
471 return return_nsstr(nsres, &hostname_str, p);
474 static HRESULT WINAPI HTMLAnchorElement_put_pathname(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_pathname(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_port(IHTMLAnchorElement *iface, BSTR v)
490 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
491 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
492 return E_NOTIMPL;
495 static HRESULT WINAPI HTMLAnchorElement_get_port(IHTMLAnchorElement *iface, BSTR *p)
497 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
498 FIXME("(%p)->(%p)\n", This, p);
499 return E_NOTIMPL;
502 static HRESULT WINAPI HTMLAnchorElement_put_protocol(IHTMLAnchorElement *iface, BSTR v)
504 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
505 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
506 return E_NOTIMPL;
509 static HRESULT WINAPI HTMLAnchorElement_get_protocol(IHTMLAnchorElement *iface, BSTR *p)
511 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
512 BSTR scheme;
513 size_t len;
514 IUri *uri;
515 HRESULT hres;
517 TRACE("(%p)->(%p)\n", This, p);
519 uri = get_anchor_uri(This);
520 if(!uri) {
521 WARN("Could not create IUri\n");
522 *p = NULL;
523 return S_OK;
526 hres = IUri_GetSchemeName(uri, &scheme);
527 IUri_Release(uri);
528 if(FAILED(hres))
529 return hres;
531 len = SysStringLen(scheme);
532 if(len) {
533 *p = SysAllocStringLen(scheme, len + 1);
534 if(*p)
535 (*p)[len] = ':';
536 else
537 hres = E_OUTOFMEMORY;
538 }else {
539 *p = NULL;
541 SysFreeString(scheme);
542 return hres;
545 static HRESULT WINAPI HTMLAnchorElement_put_search(IHTMLAnchorElement *iface, BSTR v)
547 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
548 nsAString nsstr;
549 nsresult nsres;
551 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
553 nsAString_InitDepend(&nsstr, v);
554 nsres = nsIDOMHTMLAnchorElement_SetSearch(This->nsanchor, &nsstr);
555 nsAString_Finish(&nsstr);
556 if(NS_FAILED(nsres))
557 return E_FAIL;
559 return S_OK;
562 static HRESULT WINAPI HTMLAnchorElement_get_search(IHTMLAnchorElement *iface, BSTR *p)
564 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
565 nsAString search_str;
566 nsresult nsres;
568 TRACE("(%p)->(%p)\n", This, p);
570 nsAString_Init(&search_str, NULL);
571 nsres = nsIDOMHTMLAnchorElement_GetSearch(This->nsanchor, &search_str);
572 return return_nsstr(nsres, &search_str, p);
575 static HRESULT WINAPI HTMLAnchorElement_put_hash(IHTMLAnchorElement *iface, BSTR v)
577 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
578 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
579 return E_NOTIMPL;
582 static HRESULT WINAPI HTMLAnchorElement_get_hash(IHTMLAnchorElement *iface, BSTR *p)
584 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
585 nsAString hash_str;
586 nsresult nsres;
588 TRACE("(%p)->(%p)\n", This, p);
590 nsAString_Init(&hash_str, NULL);
591 nsres = nsIDOMHTMLAnchorElement_GetHash(This->nsanchor, &hash_str);
592 return return_nsstr(nsres, &hash_str, p);
595 static HRESULT WINAPI HTMLAnchorElement_put_onblur(IHTMLAnchorElement *iface, VARIANT v)
597 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
599 TRACE("(%p)->()\n", This);
601 return IHTMLElement2_put_onblur(&This->element.IHTMLElement2_iface, v);
604 static HRESULT WINAPI HTMLAnchorElement_get_onblur(IHTMLAnchorElement *iface, VARIANT *p)
606 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
608 TRACE("(%p)->(%p)\n", This, p);
610 return IHTMLElement2_get_onblur(&This->element.IHTMLElement2_iface, p);
613 static HRESULT WINAPI HTMLAnchorElement_put_onfocus(IHTMLAnchorElement *iface, VARIANT v)
615 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
617 TRACE("(%p)->()\n", This);
619 return IHTMLElement2_put_onfocus(&This->element.IHTMLElement2_iface, v);
622 static HRESULT WINAPI HTMLAnchorElement_get_onfocus(IHTMLAnchorElement *iface, VARIANT *p)
624 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
626 TRACE("(%p)->(%p)\n", This, p);
628 return IHTMLElement2_get_onfocus(&This->element.IHTMLElement2_iface, p);
631 static HRESULT WINAPI HTMLAnchorElement_put_accessKey(IHTMLAnchorElement *iface, BSTR v)
633 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
635 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
637 return IHTMLElement2_put_accessKey(&This->element.IHTMLElement2_iface, v);
640 static HRESULT WINAPI HTMLAnchorElement_get_accessKey(IHTMLAnchorElement *iface, BSTR *p)
642 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
644 TRACE("(%p)->(%p)\n", This, p);
646 return IHTMLElement2_get_accessKey(&This->element.IHTMLElement2_iface, p);
649 static HRESULT WINAPI HTMLAnchorElement_get_protocolLong(IHTMLAnchorElement *iface, BSTR *p)
651 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
652 FIXME("(%p)->(%p)\n", This, p);
653 return E_NOTIMPL;
656 static HRESULT WINAPI HTMLAnchorElement_get_mimeType(IHTMLAnchorElement *iface, BSTR *p)
658 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
659 FIXME("(%p)->(%p)\n", This, p);
660 return E_NOTIMPL;
663 static HRESULT WINAPI HTMLAnchorElement_get_nameProp(IHTMLAnchorElement *iface, BSTR *p)
665 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
666 FIXME("(%p)->(%p)\n", This, p);
667 return E_NOTIMPL;
670 static HRESULT WINAPI HTMLAnchorElement_put_tabIndex(IHTMLAnchorElement *iface, short v)
672 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
674 TRACE("(%p)->()\n", This);
676 return IHTMLElement2_put_tabIndex(&This->element.IHTMLElement2_iface, v);
679 static HRESULT WINAPI HTMLAnchorElement_get_tabIndex(IHTMLAnchorElement *iface, short *p)
681 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
683 TRACE("(%p)->(%p)\n", This, p);
685 return IHTMLElement2_get_tabIndex(&This->element.IHTMLElement2_iface, p);
688 static HRESULT WINAPI HTMLAnchorElement_focus(IHTMLAnchorElement *iface)
690 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
692 TRACE("(%p)\n", This);
694 return IHTMLElement2_focus(&This->element.IHTMLElement2_iface);
697 static HRESULT WINAPI HTMLAnchorElement_blur(IHTMLAnchorElement *iface)
699 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
701 TRACE("(%p)\n", This);
703 return IHTMLElement2_blur(&This->element.IHTMLElement2_iface);
706 static const IHTMLAnchorElementVtbl HTMLAnchorElementVtbl = {
707 HTMLAnchorElement_QueryInterface,
708 HTMLAnchorElement_AddRef,
709 HTMLAnchorElement_Release,
710 HTMLAnchorElement_GetTypeInfoCount,
711 HTMLAnchorElement_GetTypeInfo,
712 HTMLAnchorElement_GetIDsOfNames,
713 HTMLAnchorElement_Invoke,
714 HTMLAnchorElement_put_href,
715 HTMLAnchorElement_get_href,
716 HTMLAnchorElement_put_target,
717 HTMLAnchorElement_get_target,
718 HTMLAnchorElement_put_rel,
719 HTMLAnchorElement_get_rel,
720 HTMLAnchorElement_put_rev,
721 HTMLAnchorElement_get_rev,
722 HTMLAnchorElement_put_urn,
723 HTMLAnchorElement_get_urn,
724 HTMLAnchorElement_put_Methods,
725 HTMLAnchorElement_get_Methods,
726 HTMLAnchorElement_put_name,
727 HTMLAnchorElement_get_name,
728 HTMLAnchorElement_put_host,
729 HTMLAnchorElement_get_host,
730 HTMLAnchorElement_put_hostname,
731 HTMLAnchorElement_get_hostname,
732 HTMLAnchorElement_put_pathname,
733 HTMLAnchorElement_get_pathname,
734 HTMLAnchorElement_put_port,
735 HTMLAnchorElement_get_port,
736 HTMLAnchorElement_put_protocol,
737 HTMLAnchorElement_get_protocol,
738 HTMLAnchorElement_put_search,
739 HTMLAnchorElement_get_search,
740 HTMLAnchorElement_put_hash,
741 HTMLAnchorElement_get_hash,
742 HTMLAnchorElement_put_onblur,
743 HTMLAnchorElement_get_onblur,
744 HTMLAnchorElement_put_onfocus,
745 HTMLAnchorElement_get_onfocus,
746 HTMLAnchorElement_put_accessKey,
747 HTMLAnchorElement_get_accessKey,
748 HTMLAnchorElement_get_protocolLong,
749 HTMLAnchorElement_get_mimeType,
750 HTMLAnchorElement_get_nameProp,
751 HTMLAnchorElement_put_tabIndex,
752 HTMLAnchorElement_get_tabIndex,
753 HTMLAnchorElement_focus,
754 HTMLAnchorElement_blur
757 static inline HTMLAnchorElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
759 return CONTAINING_RECORD(iface, HTMLAnchorElement, element.node);
762 static HRESULT HTMLAnchorElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
764 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
766 *ppv = NULL;
768 if(IsEqualGUID(&IID_IUnknown, riid)) {
769 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
770 *ppv = &This->IHTMLAnchorElement_iface;
771 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
772 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
773 *ppv = &This->IHTMLAnchorElement_iface;
774 }else if(IsEqualGUID(&IID_IHTMLAnchorElement, riid)) {
775 TRACE("(%p)->(IID_IHTMLAnchorElement %p)\n", This, ppv);
776 *ppv = &This->IHTMLAnchorElement_iface;
779 if(*ppv) {
780 IUnknown_AddRef((IUnknown*)*ppv);
781 return S_OK;
784 return HTMLElement_QI(&This->element.node, riid, ppv);
787 static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *event, BOOL *prevent_default)
789 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
790 nsAString href_str, target_str;
791 nsresult nsres;
793 if(eid == EVENTID_CLICK) {
794 nsAString_Init(&href_str, NULL);
795 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
796 if (NS_FAILED(nsres)) {
797 ERR("Could not get anchor href: %08x\n", nsres);
798 goto fallback;
801 nsAString_Init(&target_str, NULL);
802 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
803 if (NS_FAILED(nsres)) {
804 ERR("Could not get anchor target: %08x\n", nsres);
805 goto fallback;
808 return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);
810 fallback:
811 nsAString_Finish(&href_str);
812 nsAString_Finish(&target_str);
815 return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
818 static void HTMLAnchorElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
820 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
822 if(This->nsanchor)
823 note_cc_edge((nsISupports*)This->nsanchor, "This->nsanchor", cb);
826 static void HTMLAnchorElement_unlink(HTMLDOMNode *iface)
828 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
830 if(This->nsanchor) {
831 nsIDOMHTMLAnchorElement *nsanchor = This->nsanchor;
833 This->nsanchor = NULL;
834 nsIDOMHTMLAnchorElement_Release(nsanchor);
838 static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
839 &CLSID_HTMLAnchorElement,
840 HTMLAnchorElement_QI,
841 HTMLElement_destructor,
842 HTMLElement_cpc,
843 HTMLElement_clone,
844 HTMLAnchorElement_handle_event,
845 HTMLElement_get_attr_col,
846 NULL,
847 NULL,
848 NULL,
849 NULL,
850 NULL,
851 NULL,
852 NULL,
853 NULL,
854 HTMLAnchorElement_traverse,
855 HTMLAnchorElement_unlink
858 static const tid_t HTMLAnchorElement_iface_tids[] = {
859 IHTMLAnchorElement_tid,
860 HTMLELEMENT_TIDS,
864 static dispex_static_data_t HTMLAnchorElement_dispex = {
865 NULL,
866 DispHTMLAnchorElement_tid,
867 HTMLAnchorElement_iface_tids,
868 HTMLElement_init_dispex_info
871 HRESULT HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
873 HTMLAnchorElement *ret;
874 nsresult nsres;
876 ret = heap_alloc_zero(sizeof(HTMLAnchorElement));
877 if(!ret)
878 return E_OUTOFMEMORY;
880 ret->IHTMLAnchorElement_iface.lpVtbl = &HTMLAnchorElementVtbl;
881 ret->element.node.vtbl = &HTMLAnchorElementImplVtbl;
883 HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex);
885 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor);
886 assert(nsres == NS_OK);
888 *elem = &ret->element;
889 return S_OK;