user32: Remove _wassert workaround.
[wine.git] / dlls / mshtml / htmlanchor.c
blobb11d39ae07fb96b5620cebc65f5334573818a924
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>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
29 #include "mshtml_private.h"
30 #include "htmlevent.h"
31 #include "binding.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37 struct HTMLAnchorElement {
38 HTMLElement element;
40 IHTMLAnchorElement IHTMLAnchorElement_iface;
42 nsIDOMHTMLAnchorElement *nsanchor;
45 static HRESULT navigate_href_new_window(HTMLElement *element, nsAString *href_str, const WCHAR *target)
47 const PRUnichar *href;
48 IUri *uri;
49 HRESULT hres;
51 nsAString_GetData(href_str, &href);
52 hres = create_relative_uri(element->node.doc->basedoc.window, href, &uri);
53 if(FAILED(hres))
54 return hres;
56 hres = navigate_new_window(element->node.doc->basedoc.window, uri, target, NULL, NULL);
57 IUri_Release(uri);
58 return hres;
61 HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_str, BOOL *use_new_window)
63 HTMLOuterWindow *top_window, *ret_window;
64 const PRUnichar *target;
65 HRESULT hres;
67 *use_new_window = FALSE;
69 nsAString_GetData(target_str, &target);
70 TRACE("%s\n", debugstr_w(target));
72 if(!*target || !wcsicmp(target, L"_self")) {
73 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
74 return window;
77 if(!wcsicmp(target, L"_top")) {
78 get_top_window(window, &top_window);
79 IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface);
80 return top_window;
83 if(!wcsicmp(target, L"_parent")) {
84 if(!window->parent) {
85 WARN("Window has no parent, treat as self\n");
86 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
87 return window;
90 IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface);
91 return window->parent;
94 get_top_window(window, &top_window);
96 hres = get_frame_by_name(top_window, target, TRUE, &ret_window);
97 if(FAILED(hres) || !ret_window) {
98 *use_new_window = TRUE;
99 return NULL;
102 IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface);
103 return ret_window;
106 static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAString *target_str)
108 HTMLOuterWindow *window;
109 BOOL use_new_window;
110 const PRUnichar *href;
111 HRESULT hres;
113 window = get_target_window(element->node.doc->basedoc.window, target_str, &use_new_window);
114 if(!window) {
115 if(use_new_window) {
116 const PRUnichar *target;
117 nsAString_GetData(target_str, &target);
118 return navigate_href_new_window(element, href_str, target);
119 }else {
120 return S_OK;
124 nsAString_GetData(href_str, &href);
125 if(*href) {
126 hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED);
127 }else {
128 TRACE("empty href\n");
129 hres = S_OK;
131 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
132 return hres;
135 HRESULT handle_link_click_event(HTMLElement *element, nsAString *href_str, nsAString *target_str,
136 nsIDOMEvent *event, BOOL *prevent_default)
138 nsIDOMMouseEvent *mouse_event;
139 INT16 button;
140 nsresult nsres;
141 HRESULT hres;
143 TRACE("CLICK\n");
145 nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
146 assert(nsres == NS_OK);
148 nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button);
149 assert(nsres == NS_OK);
151 nsIDOMMouseEvent_Release(mouse_event);
153 switch(button) {
154 case 0:
155 *prevent_default = TRUE;
156 hres = navigate_href(element, href_str, target_str);
157 break;
158 case 1:
159 *prevent_default = TRUE;
160 hres = navigate_href_new_window(element, href_str, NULL);
161 break;
162 default:
163 *prevent_default = FALSE;
164 hres = S_OK;
167 nsAString_Finish(href_str);
168 nsAString_Finish(target_str);
169 return hres;
172 static IUri *get_anchor_uri(HTMLAnchorElement *anchor)
174 nsAString href_str;
175 IUri *uri = NULL;
176 nsresult nsres;
178 nsAString_Init(&href_str, NULL);
179 nsres = nsIDOMHTMLAnchorElement_GetHref(anchor->nsanchor, &href_str);
180 if(NS_SUCCEEDED(nsres)) {
181 const PRUnichar *href;
183 nsAString_GetData(&href_str, &href);
184 create_uri(href, 0, &uri);
185 }else {
186 ERR("GetHref failed: %08x\n", nsres);
189 nsAString_Finish(&href_str);
190 return uri;
193 static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
195 return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
198 static HRESULT WINAPI HTMLAnchorElement_QueryInterface(IHTMLAnchorElement *iface,
199 REFIID riid, void **ppv)
201 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
203 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
206 static ULONG WINAPI HTMLAnchorElement_AddRef(IHTMLAnchorElement *iface)
208 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
210 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
213 static ULONG WINAPI HTMLAnchorElement_Release(IHTMLAnchorElement *iface)
215 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
217 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
220 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfoCount(IHTMLAnchorElement *iface, UINT *pctinfo)
222 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
223 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
226 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfo(IHTMLAnchorElement *iface, UINT iTInfo,
227 LCID lcid, ITypeInfo **ppTInfo)
229 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
230 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
231 ppTInfo);
234 static HRESULT WINAPI HTMLAnchorElement_GetIDsOfNames(IHTMLAnchorElement *iface, REFIID riid,
235 LPOLESTR *rgszNames, UINT cNames,
236 LCID lcid, DISPID *rgDispId)
238 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
239 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
240 cNames, lcid, rgDispId);
243 static HRESULT WINAPI HTMLAnchorElement_Invoke(IHTMLAnchorElement *iface, DISPID dispIdMember,
244 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
245 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
247 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
248 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
249 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
252 static HRESULT WINAPI HTMLAnchorElement_put_href(IHTMLAnchorElement *iface, BSTR v)
254 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
255 nsAString nsstr;
256 nsresult nsres;
258 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
260 nsAString_InitDepend(&nsstr, v);
261 nsres = nsIDOMHTMLAnchorElement_SetHref(This->nsanchor, &nsstr);
262 nsAString_Finish(&nsstr);
263 if(NS_FAILED(nsres))
264 return E_FAIL;
266 return S_OK;
269 static HRESULT WINAPI HTMLAnchorElement_get_href(IHTMLAnchorElement *iface, BSTR *p)
271 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
272 nsAString href_str;
273 nsresult nsres;
274 HRESULT hres;
276 TRACE("(%p)->(%p)\n", This, p);
278 nsAString_Init(&href_str, NULL);
279 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
280 if(NS_SUCCEEDED(nsres)) {
281 const PRUnichar *href;
283 nsAString_GetData(&href_str, &href);
284 hres = nsuri_to_url(href, TRUE, p);
285 }else {
286 ERR("GetHref failed: %08x\n", nsres);
287 hres = E_FAIL;
290 nsAString_Finish(&href_str);
291 return hres;
294 static HRESULT WINAPI HTMLAnchorElement_put_target(IHTMLAnchorElement *iface, BSTR v)
296 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
297 nsAString nsstr;
298 nsresult nsres;
300 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
302 nsAString_InitDepend(&nsstr, v);
303 nsres = nsIDOMHTMLAnchorElement_SetTarget(This->nsanchor, &nsstr);
304 nsAString_Finish(&nsstr);
305 if(NS_FAILED(nsres))
306 return E_FAIL;
308 return S_OK;
311 static HRESULT WINAPI HTMLAnchorElement_get_target(IHTMLAnchorElement *iface, BSTR *p)
313 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
314 nsAString target_str;
315 nsresult nsres;
317 TRACE("(%p)->(%p)\n", This, p);
319 nsAString_Init(&target_str, NULL);
320 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
322 return return_nsstr(nsres, &target_str, p);
325 static HRESULT WINAPI HTMLAnchorElement_put_rel(IHTMLAnchorElement *iface, BSTR v)
327 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
328 nsAString nsstr;
329 nsresult nsres;
331 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
333 nsAString_InitDepend(&nsstr, v);
334 nsres = nsIDOMHTMLAnchorElement_SetRel(This->nsanchor, &nsstr);
335 nsAString_Finish(&nsstr);
336 if(NS_FAILED(nsres))
337 return E_FAIL;
339 return S_OK;
342 static HRESULT WINAPI HTMLAnchorElement_get_rel(IHTMLAnchorElement *iface, BSTR *p)
344 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
345 nsAString nsstr;
346 nsresult nsres;
348 TRACE("(%p)->(%p)\n", This, p);
350 nsAString_Init(&nsstr, NULL);
351 nsres = nsIDOMHTMLAnchorElement_GetRel(This->nsanchor, &nsstr);
352 return return_nsstr(nsres, &nsstr, p);
355 static HRESULT WINAPI HTMLAnchorElement_put_rev(IHTMLAnchorElement *iface, BSTR v)
357 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
358 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
359 return E_NOTIMPL;
362 static HRESULT WINAPI HTMLAnchorElement_get_rev(IHTMLAnchorElement *iface, BSTR *p)
364 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
365 FIXME("(%p)->(%p)\n", This, p);
366 return E_NOTIMPL;
369 static HRESULT WINAPI HTMLAnchorElement_put_urn(IHTMLAnchorElement *iface, BSTR v)
371 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
372 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
373 return E_NOTIMPL;
376 static HRESULT WINAPI HTMLAnchorElement_get_urn(IHTMLAnchorElement *iface, BSTR *p)
378 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
379 FIXME("(%p)->(%p)\n", This, p);
380 return E_NOTIMPL;
383 static HRESULT WINAPI HTMLAnchorElement_put_Methods(IHTMLAnchorElement *iface, BSTR v)
385 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
386 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
387 return E_NOTIMPL;
390 static HRESULT WINAPI HTMLAnchorElement_get_Methods(IHTMLAnchorElement *iface, BSTR *p)
392 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
393 FIXME("(%p)->(%p)\n", This, p);
394 return E_NOTIMPL;
397 static HRESULT WINAPI HTMLAnchorElement_put_name(IHTMLAnchorElement *iface, BSTR v)
399 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
400 nsAString nsstr;
401 nsresult nsres;
403 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
405 nsAString_InitDepend(&nsstr, v);
406 nsres = nsIDOMHTMLAnchorElement_SetName(This->nsanchor, &nsstr);
407 nsAString_Finish(&nsstr);
408 if(NS_FAILED(nsres))
409 return E_FAIL;
411 return S_OK;
414 static HRESULT WINAPI HTMLAnchorElement_get_name(IHTMLAnchorElement *iface, BSTR *p)
416 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
417 nsAString name_str;
418 nsresult nsres;
420 TRACE("(%p)->(%p)\n", This, p);
422 nsAString_Init(&name_str, NULL);
423 nsres = nsIDOMHTMLAnchorElement_GetName(This->nsanchor, &name_str);
425 return return_nsstr(nsres, &name_str, p);
428 static HRESULT WINAPI HTMLAnchorElement_put_host(IHTMLAnchorElement *iface, BSTR v)
430 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
431 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
432 return E_NOTIMPL;
435 static HRESULT WINAPI HTMLAnchorElement_get_host(IHTMLAnchorElement *iface, BSTR *p)
437 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
438 nsAString str;
439 nsresult nsres;
441 TRACE("(%p)->(%p)\n", This, p);
443 /* FIXME: IE always appends port number, even if it's implicit default number */
444 nsAString_InitDepend(&str, NULL);
445 nsres = nsIDOMHTMLAnchorElement_GetHost(This->nsanchor, &str);
446 return return_nsstr(nsres, &str, p);
449 static HRESULT WINAPI HTMLAnchorElement_put_hostname(IHTMLAnchorElement *iface, BSTR v)
451 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
452 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
453 return E_NOTIMPL;
456 static HRESULT WINAPI HTMLAnchorElement_get_hostname(IHTMLAnchorElement *iface, BSTR *p)
458 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
459 nsAString hostname_str;
460 nsresult nsres;
462 TRACE("(%p)->(%p)\n", This, p);
464 nsAString_Init(&hostname_str, NULL);
465 nsres = nsIDOMHTMLAnchorElement_GetHostname(This->nsanchor, &hostname_str);
466 return return_nsstr(nsres, &hostname_str, p);
469 static HRESULT WINAPI HTMLAnchorElement_put_pathname(IHTMLAnchorElement *iface, BSTR v)
471 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
472 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
473 return E_NOTIMPL;
476 static HRESULT WINAPI HTMLAnchorElement_get_pathname(IHTMLAnchorElement *iface, BSTR *p)
478 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
479 nsAString pathname_str;
480 nsresult nsres;
482 TRACE("(%p)->(%p)\n", This, p);
484 /* FIXME: IE prepends a slash for some protocols */
485 nsAString_Init(&pathname_str, NULL);
486 nsres = nsIDOMHTMLAnchorElement_GetPathname(This->nsanchor, &pathname_str);
487 return return_nsstr(nsres, &pathname_str, p);
490 static HRESULT WINAPI HTMLAnchorElement_put_port(IHTMLAnchorElement *iface, BSTR v)
492 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
493 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
494 return E_NOTIMPL;
497 static HRESULT WINAPI HTMLAnchorElement_get_port(IHTMLAnchorElement *iface, BSTR *p)
499 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
500 IUri *uri;
501 HRESULT hres;
502 DWORD port;
503 WCHAR buf[11];
504 int len;
505 BSTR str;
507 TRACE("(%p)->(%p)\n", This, p);
509 uri = get_anchor_uri(This);
510 if(!uri) {
511 WARN("Could not create IUri\n");
512 *p = NULL;
513 return S_OK;
516 hres = IUri_GetPort(uri, &port);
517 IUri_Release(uri);
518 if(FAILED(hres))
519 return hres;
521 len = swprintf(buf, ARRAY_SIZE(buf), L"%u", port);
522 str = SysAllocStringLen(buf, len);
523 if (str)
524 *p = str;
525 else
526 hres = E_OUTOFMEMORY;
528 return hres;
531 static HRESULT WINAPI HTMLAnchorElement_put_protocol(IHTMLAnchorElement *iface, BSTR v)
533 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
534 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
535 return E_NOTIMPL;
538 static HRESULT WINAPI HTMLAnchorElement_get_protocol(IHTMLAnchorElement *iface, BSTR *p)
540 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
541 BSTR scheme;
542 size_t len;
543 IUri *uri;
544 HRESULT hres;
546 TRACE("(%p)->(%p)\n", This, p);
548 uri = get_anchor_uri(This);
549 if(!uri) {
550 WARN("Could not create IUri\n");
551 *p = NULL;
552 return S_OK;
555 hres = IUri_GetSchemeName(uri, &scheme);
556 IUri_Release(uri);
557 if(FAILED(hres))
558 return hres;
560 len = SysStringLen(scheme);
561 if(len) {
562 *p = SysAllocStringLen(scheme, len + 1);
563 if(*p)
564 (*p)[len] = ':';
565 else
566 hres = E_OUTOFMEMORY;
567 }else {
568 *p = NULL;
570 SysFreeString(scheme);
571 return hres;
574 static HRESULT WINAPI HTMLAnchorElement_put_search(IHTMLAnchorElement *iface, BSTR v)
576 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
577 nsAString nsstr;
578 nsresult nsres;
580 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
582 nsAString_InitDepend(&nsstr, v);
583 nsres = nsIDOMHTMLAnchorElement_SetSearch(This->nsanchor, &nsstr);
584 nsAString_Finish(&nsstr);
585 if(NS_FAILED(nsres))
586 return E_FAIL;
588 return S_OK;
591 static HRESULT WINAPI HTMLAnchorElement_get_search(IHTMLAnchorElement *iface, BSTR *p)
593 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
594 nsAString search_str;
595 nsresult nsres;
597 TRACE("(%p)->(%p)\n", This, p);
599 nsAString_Init(&search_str, NULL);
600 nsres = nsIDOMHTMLAnchorElement_GetSearch(This->nsanchor, &search_str);
601 return return_nsstr(nsres, &search_str, p);
604 static HRESULT WINAPI HTMLAnchorElement_put_hash(IHTMLAnchorElement *iface, BSTR v)
606 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
607 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
608 return E_NOTIMPL;
611 static HRESULT WINAPI HTMLAnchorElement_get_hash(IHTMLAnchorElement *iface, BSTR *p)
613 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
614 nsAString hash_str;
615 nsresult nsres;
617 TRACE("(%p)->(%p)\n", This, p);
619 nsAString_Init(&hash_str, NULL);
620 nsres = nsIDOMHTMLAnchorElement_GetHash(This->nsanchor, &hash_str);
621 return return_nsstr(nsres, &hash_str, p);
624 static HRESULT WINAPI HTMLAnchorElement_put_onblur(IHTMLAnchorElement *iface, VARIANT v)
626 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
628 TRACE("(%p)->()\n", This);
630 return IHTMLElement2_put_onblur(&This->element.IHTMLElement2_iface, v);
633 static HRESULT WINAPI HTMLAnchorElement_get_onblur(IHTMLAnchorElement *iface, VARIANT *p)
635 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
637 TRACE("(%p)->(%p)\n", This, p);
639 return IHTMLElement2_get_onblur(&This->element.IHTMLElement2_iface, p);
642 static HRESULT WINAPI HTMLAnchorElement_put_onfocus(IHTMLAnchorElement *iface, VARIANT v)
644 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
646 TRACE("(%p)->()\n", This);
648 return IHTMLElement2_put_onfocus(&This->element.IHTMLElement2_iface, v);
651 static HRESULT WINAPI HTMLAnchorElement_get_onfocus(IHTMLAnchorElement *iface, VARIANT *p)
653 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
655 TRACE("(%p)->(%p)\n", This, p);
657 return IHTMLElement2_get_onfocus(&This->element.IHTMLElement2_iface, p);
660 static HRESULT WINAPI HTMLAnchorElement_put_accessKey(IHTMLAnchorElement *iface, BSTR v)
662 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
664 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
666 return IHTMLElement2_put_accessKey(&This->element.IHTMLElement2_iface, v);
669 static HRESULT WINAPI HTMLAnchorElement_get_accessKey(IHTMLAnchorElement *iface, BSTR *p)
671 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
673 TRACE("(%p)->(%p)\n", This, p);
675 return IHTMLElement2_get_accessKey(&This->element.IHTMLElement2_iface, p);
678 static HRESULT WINAPI HTMLAnchorElement_get_protocolLong(IHTMLAnchorElement *iface, BSTR *p)
680 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
681 FIXME("(%p)->(%p)\n", This, p);
682 return E_NOTIMPL;
685 static HRESULT WINAPI HTMLAnchorElement_get_mimeType(IHTMLAnchorElement *iface, BSTR *p)
687 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
688 FIXME("(%p)->(%p)\n", This, p);
689 return E_NOTIMPL;
692 static HRESULT WINAPI HTMLAnchorElement_get_nameProp(IHTMLAnchorElement *iface, BSTR *p)
694 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
695 FIXME("(%p)->(%p)\n", This, p);
696 return E_NOTIMPL;
699 static HRESULT WINAPI HTMLAnchorElement_put_tabIndex(IHTMLAnchorElement *iface, short v)
701 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
703 TRACE("(%p)->()\n", This);
705 return IHTMLElement2_put_tabIndex(&This->element.IHTMLElement2_iface, v);
708 static HRESULT WINAPI HTMLAnchorElement_get_tabIndex(IHTMLAnchorElement *iface, short *p)
710 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
712 TRACE("(%p)->(%p)\n", This, p);
714 return IHTMLElement2_get_tabIndex(&This->element.IHTMLElement2_iface, p);
717 static HRESULT WINAPI HTMLAnchorElement_focus(IHTMLAnchorElement *iface)
719 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
721 TRACE("(%p)\n", This);
723 return IHTMLElement2_focus(&This->element.IHTMLElement2_iface);
726 static HRESULT WINAPI HTMLAnchorElement_blur(IHTMLAnchorElement *iface)
728 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
730 TRACE("(%p)\n", This);
732 return IHTMLElement2_blur(&This->element.IHTMLElement2_iface);
735 static const IHTMLAnchorElementVtbl HTMLAnchorElementVtbl = {
736 HTMLAnchorElement_QueryInterface,
737 HTMLAnchorElement_AddRef,
738 HTMLAnchorElement_Release,
739 HTMLAnchorElement_GetTypeInfoCount,
740 HTMLAnchorElement_GetTypeInfo,
741 HTMLAnchorElement_GetIDsOfNames,
742 HTMLAnchorElement_Invoke,
743 HTMLAnchorElement_put_href,
744 HTMLAnchorElement_get_href,
745 HTMLAnchorElement_put_target,
746 HTMLAnchorElement_get_target,
747 HTMLAnchorElement_put_rel,
748 HTMLAnchorElement_get_rel,
749 HTMLAnchorElement_put_rev,
750 HTMLAnchorElement_get_rev,
751 HTMLAnchorElement_put_urn,
752 HTMLAnchorElement_get_urn,
753 HTMLAnchorElement_put_Methods,
754 HTMLAnchorElement_get_Methods,
755 HTMLAnchorElement_put_name,
756 HTMLAnchorElement_get_name,
757 HTMLAnchorElement_put_host,
758 HTMLAnchorElement_get_host,
759 HTMLAnchorElement_put_hostname,
760 HTMLAnchorElement_get_hostname,
761 HTMLAnchorElement_put_pathname,
762 HTMLAnchorElement_get_pathname,
763 HTMLAnchorElement_put_port,
764 HTMLAnchorElement_get_port,
765 HTMLAnchorElement_put_protocol,
766 HTMLAnchorElement_get_protocol,
767 HTMLAnchorElement_put_search,
768 HTMLAnchorElement_get_search,
769 HTMLAnchorElement_put_hash,
770 HTMLAnchorElement_get_hash,
771 HTMLAnchorElement_put_onblur,
772 HTMLAnchorElement_get_onblur,
773 HTMLAnchorElement_put_onfocus,
774 HTMLAnchorElement_get_onfocus,
775 HTMLAnchorElement_put_accessKey,
776 HTMLAnchorElement_get_accessKey,
777 HTMLAnchorElement_get_protocolLong,
778 HTMLAnchorElement_get_mimeType,
779 HTMLAnchorElement_get_nameProp,
780 HTMLAnchorElement_put_tabIndex,
781 HTMLAnchorElement_get_tabIndex,
782 HTMLAnchorElement_focus,
783 HTMLAnchorElement_blur
786 static inline HTMLAnchorElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
788 return CONTAINING_RECORD(iface, HTMLAnchorElement, element.node);
791 static HRESULT HTMLAnchorElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
793 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
795 *ppv = NULL;
797 if(IsEqualGUID(&IID_IUnknown, riid)) {
798 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
799 *ppv = &This->IHTMLAnchorElement_iface;
800 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
801 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
802 *ppv = &This->IHTMLAnchorElement_iface;
803 }else if(IsEqualGUID(&IID_IHTMLAnchorElement, riid)) {
804 TRACE("(%p)->(IID_IHTMLAnchorElement %p)\n", This, ppv);
805 *ppv = &This->IHTMLAnchorElement_iface;
808 if(*ppv) {
809 IUnknown_AddRef((IUnknown*)*ppv);
810 return S_OK;
813 return HTMLElement_QI(&This->element.node, riid, ppv);
816 static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *event, BOOL *prevent_default)
818 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
819 nsAString href_str, target_str;
820 nsresult nsres;
822 if(eid == EVENTID_CLICK) {
823 nsAString_Init(&href_str, NULL);
824 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
825 if (NS_FAILED(nsres)) {
826 ERR("Could not get anchor href: %08x\n", nsres);
827 goto fallback;
830 nsAString_Init(&target_str, NULL);
831 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
832 if (NS_FAILED(nsres)) {
833 ERR("Could not get anchor target: %08x\n", nsres);
834 goto fallback;
837 return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);
839 fallback:
840 nsAString_Finish(&href_str);
841 nsAString_Finish(&target_str);
844 return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
847 static void HTMLAnchorElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
849 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
851 if(This->nsanchor)
852 note_cc_edge((nsISupports*)This->nsanchor, "This->nsanchor", cb);
855 static void HTMLAnchorElement_unlink(HTMLDOMNode *iface)
857 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
859 if(This->nsanchor) {
860 nsIDOMHTMLAnchorElement *nsanchor = This->nsanchor;
862 This->nsanchor = NULL;
863 nsIDOMHTMLAnchorElement_Release(nsanchor);
867 static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
868 &CLSID_HTMLAnchorElement,
869 HTMLAnchorElement_QI,
870 HTMLElement_destructor,
871 HTMLElement_cpc,
872 HTMLElement_clone,
873 HTMLAnchorElement_handle_event,
874 HTMLElement_get_attr_col,
875 NULL,
876 NULL,
877 NULL,
878 NULL,
879 NULL,
880 NULL,
881 NULL,
882 NULL,
883 HTMLAnchorElement_traverse,
884 HTMLAnchorElement_unlink
887 static const tid_t HTMLAnchorElement_iface_tids[] = {
888 IHTMLAnchorElement_tid,
889 HTMLELEMENT_TIDS,
893 static dispex_static_data_t HTMLAnchorElement_dispex = {
894 L"HTMLAnchorElement",
895 NULL,
896 DispHTMLAnchorElement_tid,
897 HTMLAnchorElement_iface_tids,
898 HTMLElement_init_dispex_info
901 HRESULT HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
903 HTMLAnchorElement *ret;
904 nsresult nsres;
906 ret = heap_alloc_zero(sizeof(HTMLAnchorElement));
907 if(!ret)
908 return E_OUTOFMEMORY;
910 ret->IHTMLAnchorElement_iface.lpVtbl = &HTMLAnchorElementVtbl;
911 ret->element.node.vtbl = &HTMLAnchorElementImplVtbl;
913 HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex);
915 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor);
916 assert(nsres == NS_OK);
918 *elem = &ret->element;
919 return S_OK;