d3dx9: Add support for mipmap generation to D3DXCreateVolumeTextureFromFileInMemoryEx().
[wine.git] / dlls / mshtml / htmlanchor.c
blob670cd48795d298a06f885d6a4260d1e026ae390a
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 if(!element->node.doc->window->base.outer_window)
52 return S_OK;
54 nsAString_GetData(href_str, &href);
55 hres = create_relative_uri(element->node.doc->window->base.outer_window, href, &uri);
56 if(FAILED(hres))
57 return hres;
59 hres = navigate_new_window(element->node.doc->window->base.outer_window, uri, target, NULL, NULL);
60 IUri_Release(uri);
61 return hres;
64 HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_str, BOOL *use_new_window)
66 HTMLOuterWindow *top_window, *ret_window;
67 const PRUnichar *target;
68 HRESULT hres;
70 *use_new_window = FALSE;
72 nsAString_GetData(target_str, &target);
73 TRACE("%s\n", debugstr_w(target));
75 if(!*target || !wcsicmp(target, L"_self")) {
76 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
77 return window;
80 if(!wcsicmp(target, L"_top")) {
81 get_top_window(window, &top_window);
82 IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface);
83 return top_window;
86 if(!wcsicmp(target, L"_parent")) {
87 if(!window->parent) {
88 WARN("Window has no parent, treat as self\n");
89 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
90 return window;
93 IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface);
94 return window->parent;
97 get_top_window(window, &top_window);
99 hres = get_frame_by_name(top_window, target, TRUE, &ret_window);
100 if(FAILED(hres) || !ret_window) {
101 *use_new_window = TRUE;
102 return NULL;
105 IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface);
106 return ret_window;
109 static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAString *target_str)
111 HTMLOuterWindow *window;
112 BOOL use_new_window;
113 const PRUnichar *href;
114 HRESULT hres;
116 if(!element->node.doc->window->base.outer_window)
117 return S_OK;
119 window = get_target_window(element->node.doc->window->base.outer_window, target_str, &use_new_window);
120 if(!window) {
121 if(use_new_window) {
122 const PRUnichar *target;
123 nsAString_GetData(target_str, &target);
124 return navigate_href_new_window(element, href_str, target);
125 }else {
126 return S_OK;
130 nsAString_GetData(href_str, &href);
131 if(*href) {
132 hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED);
133 }else {
134 TRACE("empty href\n");
135 hres = S_OK;
137 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
138 return hres;
141 HRESULT handle_link_click_event(HTMLElement *element, nsAString *href_str, nsAString *target_str,
142 nsIDOMEvent *event, BOOL *prevent_default)
144 nsIDOMMouseEvent *mouse_event;
145 INT16 button;
146 nsresult nsres;
147 HRESULT hres;
149 TRACE("CLICK\n");
151 nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
152 assert(nsres == NS_OK);
154 nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button);
155 assert(nsres == NS_OK);
157 nsIDOMMouseEvent_Release(mouse_event);
159 switch(button) {
160 case 0:
161 *prevent_default = TRUE;
162 hres = navigate_href(element, href_str, target_str);
163 break;
164 case 1:
165 *prevent_default = TRUE;
166 hres = navigate_href_new_window(element, href_str, NULL);
167 break;
168 default:
169 *prevent_default = FALSE;
170 hres = S_OK;
173 nsAString_Finish(href_str);
174 nsAString_Finish(target_str);
175 return hres;
178 static IUri *get_anchor_uri(HTMLAnchorElement *anchor)
180 nsAString href_str;
181 IUri *uri = NULL;
182 nsresult nsres;
184 nsAString_Init(&href_str, NULL);
185 nsres = nsIDOMHTMLAnchorElement_GetHref(anchor->nsanchor, &href_str);
186 if(NS_SUCCEEDED(nsres)) {
187 const PRUnichar *href;
189 nsAString_GetData(&href_str, &href);
190 create_uri(href, 0, &uri);
191 }else {
192 ERR("GetHref failed: %08lx\n", nsres);
195 nsAString_Finish(&href_str);
196 return uri;
199 static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
201 return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
204 DISPEX_IDISPATCH_IMPL(HTMLAnchorElement, IHTMLAnchorElement,
205 impl_from_IHTMLAnchorElement(iface)->element.node.event_target.dispex)
207 static HRESULT WINAPI HTMLAnchorElement_put_href(IHTMLAnchorElement *iface, BSTR v)
209 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
210 nsAString nsstr;
211 nsresult nsres;
213 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
215 nsAString_InitDepend(&nsstr, v);
216 nsres = nsIDOMHTMLAnchorElement_SetHref(This->nsanchor, &nsstr);
217 nsAString_Finish(&nsstr);
218 if(NS_FAILED(nsres))
219 return E_FAIL;
221 return S_OK;
224 static HRESULT WINAPI HTMLAnchorElement_get_href(IHTMLAnchorElement *iface, BSTR *p)
226 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
227 nsAString href_str;
228 nsresult nsres;
229 HRESULT hres;
231 TRACE("(%p)->(%p)\n", This, p);
233 nsAString_Init(&href_str, NULL);
234 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
235 if(NS_SUCCEEDED(nsres)) {
236 const PRUnichar *href;
238 nsAString_GetData(&href_str, &href);
239 hres = nsuri_to_url(href, TRUE, p);
240 }else {
241 ERR("GetHref failed: %08lx\n", nsres);
242 hres = E_FAIL;
245 nsAString_Finish(&href_str);
246 return hres;
249 static HRESULT WINAPI HTMLAnchorElement_put_target(IHTMLAnchorElement *iface, BSTR v)
251 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
252 nsAString nsstr;
253 nsresult nsres;
255 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
257 nsAString_InitDepend(&nsstr, v);
258 nsres = nsIDOMHTMLAnchorElement_SetTarget(This->nsanchor, &nsstr);
259 nsAString_Finish(&nsstr);
260 if(NS_FAILED(nsres))
261 return E_FAIL;
263 return S_OK;
266 static HRESULT WINAPI HTMLAnchorElement_get_target(IHTMLAnchorElement *iface, BSTR *p)
268 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
269 nsAString target_str;
270 nsresult nsres;
272 TRACE("(%p)->(%p)\n", This, p);
274 nsAString_Init(&target_str, NULL);
275 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
277 return return_nsstr(nsres, &target_str, p);
280 static HRESULT WINAPI HTMLAnchorElement_put_rel(IHTMLAnchorElement *iface, BSTR v)
282 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
283 nsAString nsstr;
284 nsresult nsres;
286 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
288 nsAString_InitDepend(&nsstr, v);
289 nsres = nsIDOMHTMLAnchorElement_SetRel(This->nsanchor, &nsstr);
290 nsAString_Finish(&nsstr);
291 if(NS_FAILED(nsres))
292 return E_FAIL;
294 return S_OK;
297 static HRESULT WINAPI HTMLAnchorElement_get_rel(IHTMLAnchorElement *iface, BSTR *p)
299 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
300 nsAString nsstr;
301 nsresult nsres;
303 TRACE("(%p)->(%p)\n", This, p);
305 nsAString_Init(&nsstr, NULL);
306 nsres = nsIDOMHTMLAnchorElement_GetRel(This->nsanchor, &nsstr);
307 return return_nsstr(nsres, &nsstr, p);
310 static HRESULT WINAPI HTMLAnchorElement_put_rev(IHTMLAnchorElement *iface, BSTR v)
312 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
313 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
314 return E_NOTIMPL;
317 static HRESULT WINAPI HTMLAnchorElement_get_rev(IHTMLAnchorElement *iface, BSTR *p)
319 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
320 FIXME("(%p)->(%p)\n", This, p);
321 return E_NOTIMPL;
324 static HRESULT WINAPI HTMLAnchorElement_put_urn(IHTMLAnchorElement *iface, BSTR v)
326 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
327 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
328 return E_NOTIMPL;
331 static HRESULT WINAPI HTMLAnchorElement_get_urn(IHTMLAnchorElement *iface, BSTR *p)
333 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
334 FIXME("(%p)->(%p)\n", This, p);
335 return E_NOTIMPL;
338 static HRESULT WINAPI HTMLAnchorElement_put_Methods(IHTMLAnchorElement *iface, BSTR v)
340 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
341 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
342 return E_NOTIMPL;
345 static HRESULT WINAPI HTMLAnchorElement_get_Methods(IHTMLAnchorElement *iface, BSTR *p)
347 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
348 FIXME("(%p)->(%p)\n", This, p);
349 return E_NOTIMPL;
352 static HRESULT WINAPI HTMLAnchorElement_put_name(IHTMLAnchorElement *iface, BSTR v)
354 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
355 nsAString nsstr;
356 nsresult nsres;
358 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
360 nsAString_InitDepend(&nsstr, v);
361 nsres = nsIDOMHTMLAnchorElement_SetName(This->nsanchor, &nsstr);
362 nsAString_Finish(&nsstr);
363 if(NS_FAILED(nsres))
364 return E_FAIL;
366 return S_OK;
369 static HRESULT WINAPI HTMLAnchorElement_get_name(IHTMLAnchorElement *iface, BSTR *p)
371 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
372 nsAString name_str;
373 nsresult nsres;
375 TRACE("(%p)->(%p)\n", This, p);
377 nsAString_Init(&name_str, NULL);
378 nsres = nsIDOMHTMLAnchorElement_GetName(This->nsanchor, &name_str);
380 return return_nsstr(nsres, &name_str, p);
383 static HRESULT WINAPI HTMLAnchorElement_put_host(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_host(IHTMLAnchorElement *iface, BSTR *p)
392 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
393 nsAString str;
394 nsresult nsres;
396 TRACE("(%p)->(%p)\n", This, p);
398 /* FIXME: IE always appends port number, even if it's implicit default number */
399 nsAString_InitDepend(&str, NULL);
400 nsres = nsIDOMHTMLAnchorElement_GetHost(This->nsanchor, &str);
401 return return_nsstr(nsres, &str, p);
404 static HRESULT WINAPI HTMLAnchorElement_put_hostname(IHTMLAnchorElement *iface, BSTR v)
406 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
407 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
408 return E_NOTIMPL;
411 static HRESULT WINAPI HTMLAnchorElement_get_hostname(IHTMLAnchorElement *iface, BSTR *p)
413 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
414 nsAString hostname_str;
415 nsresult nsres;
417 TRACE("(%p)->(%p)\n", This, p);
419 nsAString_Init(&hostname_str, NULL);
420 nsres = nsIDOMHTMLAnchorElement_GetHostname(This->nsanchor, &hostname_str);
421 return return_nsstr(nsres, &hostname_str, p);
424 static HRESULT WINAPI HTMLAnchorElement_put_pathname(IHTMLAnchorElement *iface, BSTR v)
426 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
427 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
428 return E_NOTIMPL;
431 static HRESULT WINAPI HTMLAnchorElement_get_pathname(IHTMLAnchorElement *iface, BSTR *p)
433 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
434 nsAString pathname_str;
435 nsresult nsres;
437 TRACE("(%p)->(%p)\n", This, p);
439 /* FIXME: IE prepends a slash for some protocols */
440 nsAString_Init(&pathname_str, NULL);
441 nsres = nsIDOMHTMLAnchorElement_GetPathname(This->nsanchor, &pathname_str);
442 return return_nsstr(nsres, &pathname_str, p);
445 static HRESULT WINAPI HTMLAnchorElement_put_port(IHTMLAnchorElement *iface, BSTR v)
447 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
448 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
449 return E_NOTIMPL;
452 static HRESULT WINAPI HTMLAnchorElement_get_port(IHTMLAnchorElement *iface, BSTR *p)
454 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
455 IUri *uri;
456 HRESULT hres;
457 DWORD port;
458 WCHAR buf[11];
459 int len;
460 BSTR str;
462 TRACE("(%p)->(%p)\n", This, p);
464 uri = get_anchor_uri(This);
465 if(!uri) {
466 WARN("Could not create IUri\n");
467 *p = NULL;
468 return S_OK;
471 hres = IUri_GetPort(uri, &port);
472 IUri_Release(uri);
473 if(FAILED(hres))
474 return hres;
475 if(hres != S_OK) {
476 *p = NULL;
477 return S_OK;
480 len = swprintf(buf, ARRAY_SIZE(buf), L"%u", port);
481 str = SysAllocStringLen(buf, len);
482 if (str)
483 *p = str;
484 else
485 hres = E_OUTOFMEMORY;
487 return hres;
490 static HRESULT WINAPI HTMLAnchorElement_put_protocol(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_protocol(IHTMLAnchorElement *iface, BSTR *p)
499 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
500 BSTR scheme;
501 size_t len;
502 IUri *uri;
503 HRESULT hres;
505 TRACE("(%p)->(%p)\n", This, p);
507 uri = get_anchor_uri(This);
508 if(!uri) {
509 WARN("Could not create IUri\n");
510 *p = NULL;
511 return S_OK;
514 hres = IUri_GetSchemeName(uri, &scheme);
515 IUri_Release(uri);
516 if(FAILED(hres))
517 return hres;
518 if(hres != S_OK) {
519 SysFreeString(scheme);
520 *p = NULL;
521 return S_OK;
524 len = SysStringLen(scheme);
525 if(len) {
526 *p = SysAllocStringLen(scheme, len + 1);
527 if(*p)
528 (*p)[len] = ':';
529 else
530 hres = E_OUTOFMEMORY;
531 }else {
532 *p = NULL;
534 SysFreeString(scheme);
535 return hres;
538 static HRESULT WINAPI HTMLAnchorElement_put_search(IHTMLAnchorElement *iface, BSTR v)
540 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
541 nsAString nsstr;
542 nsresult nsres;
544 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
546 nsAString_InitDepend(&nsstr, v);
547 nsres = nsIDOMHTMLAnchorElement_SetSearch(This->nsanchor, &nsstr);
548 nsAString_Finish(&nsstr);
549 if(NS_FAILED(nsres))
550 return E_FAIL;
552 return S_OK;
555 static HRESULT WINAPI HTMLAnchorElement_get_search(IHTMLAnchorElement *iface, BSTR *p)
557 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
558 nsAString search_str;
559 nsresult nsres;
561 TRACE("(%p)->(%p)\n", This, p);
563 nsAString_Init(&search_str, NULL);
564 nsres = nsIDOMHTMLAnchorElement_GetSearch(This->nsanchor, &search_str);
565 return return_nsstr(nsres, &search_str, p);
568 static HRESULT WINAPI HTMLAnchorElement_put_hash(IHTMLAnchorElement *iface, BSTR v)
570 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
571 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
572 return E_NOTIMPL;
575 static HRESULT WINAPI HTMLAnchorElement_get_hash(IHTMLAnchorElement *iface, BSTR *p)
577 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
578 nsAString hash_str;
579 nsresult nsres;
581 TRACE("(%p)->(%p)\n", This, p);
583 nsAString_Init(&hash_str, NULL);
584 nsres = nsIDOMHTMLAnchorElement_GetHash(This->nsanchor, &hash_str);
585 return return_nsstr(nsres, &hash_str, p);
588 static HRESULT WINAPI HTMLAnchorElement_put_onblur(IHTMLAnchorElement *iface, VARIANT v)
590 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
592 TRACE("(%p)->()\n", This);
594 return IHTMLElement2_put_onblur(&This->element.IHTMLElement2_iface, v);
597 static HRESULT WINAPI HTMLAnchorElement_get_onblur(IHTMLAnchorElement *iface, VARIANT *p)
599 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
601 TRACE("(%p)->(%p)\n", This, p);
603 return IHTMLElement2_get_onblur(&This->element.IHTMLElement2_iface, p);
606 static HRESULT WINAPI HTMLAnchorElement_put_onfocus(IHTMLAnchorElement *iface, VARIANT v)
608 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
610 TRACE("(%p)->()\n", This);
612 return IHTMLElement2_put_onfocus(&This->element.IHTMLElement2_iface, v);
615 static HRESULT WINAPI HTMLAnchorElement_get_onfocus(IHTMLAnchorElement *iface, VARIANT *p)
617 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
619 TRACE("(%p)->(%p)\n", This, p);
621 return IHTMLElement2_get_onfocus(&This->element.IHTMLElement2_iface, p);
624 static HRESULT WINAPI HTMLAnchorElement_put_accessKey(IHTMLAnchorElement *iface, BSTR v)
626 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
628 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
630 return IHTMLElement2_put_accessKey(&This->element.IHTMLElement2_iface, v);
633 static HRESULT WINAPI HTMLAnchorElement_get_accessKey(IHTMLAnchorElement *iface, BSTR *p)
635 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
637 TRACE("(%p)->(%p)\n", This, p);
639 return IHTMLElement2_get_accessKey(&This->element.IHTMLElement2_iface, p);
642 static HRESULT WINAPI HTMLAnchorElement_get_protocolLong(IHTMLAnchorElement *iface, BSTR *p)
644 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
645 FIXME("(%p)->(%p)\n", This, p);
646 return E_NOTIMPL;
649 static HRESULT WINAPI HTMLAnchorElement_get_mimeType(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_nameProp(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_put_tabIndex(IHTMLAnchorElement *iface, short v)
665 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
667 TRACE("(%p)->()\n", This);
669 return IHTMLElement2_put_tabIndex(&This->element.IHTMLElement2_iface, v);
672 static HRESULT WINAPI HTMLAnchorElement_get_tabIndex(IHTMLAnchorElement *iface, short *p)
674 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
676 TRACE("(%p)->(%p)\n", This, p);
678 return IHTMLElement2_get_tabIndex(&This->element.IHTMLElement2_iface, p);
681 static HRESULT WINAPI HTMLAnchorElement_focus(IHTMLAnchorElement *iface)
683 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
685 TRACE("(%p)\n", This);
687 return IHTMLElement2_focus(&This->element.IHTMLElement2_iface);
690 static HRESULT WINAPI HTMLAnchorElement_blur(IHTMLAnchorElement *iface)
692 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
694 TRACE("(%p)\n", This);
696 return IHTMLElement2_blur(&This->element.IHTMLElement2_iface);
699 static const IHTMLAnchorElementVtbl HTMLAnchorElementVtbl = {
700 HTMLAnchorElement_QueryInterface,
701 HTMLAnchorElement_AddRef,
702 HTMLAnchorElement_Release,
703 HTMLAnchorElement_GetTypeInfoCount,
704 HTMLAnchorElement_GetTypeInfo,
705 HTMLAnchorElement_GetIDsOfNames,
706 HTMLAnchorElement_Invoke,
707 HTMLAnchorElement_put_href,
708 HTMLAnchorElement_get_href,
709 HTMLAnchorElement_put_target,
710 HTMLAnchorElement_get_target,
711 HTMLAnchorElement_put_rel,
712 HTMLAnchorElement_get_rel,
713 HTMLAnchorElement_put_rev,
714 HTMLAnchorElement_get_rev,
715 HTMLAnchorElement_put_urn,
716 HTMLAnchorElement_get_urn,
717 HTMLAnchorElement_put_Methods,
718 HTMLAnchorElement_get_Methods,
719 HTMLAnchorElement_put_name,
720 HTMLAnchorElement_get_name,
721 HTMLAnchorElement_put_host,
722 HTMLAnchorElement_get_host,
723 HTMLAnchorElement_put_hostname,
724 HTMLAnchorElement_get_hostname,
725 HTMLAnchorElement_put_pathname,
726 HTMLAnchorElement_get_pathname,
727 HTMLAnchorElement_put_port,
728 HTMLAnchorElement_get_port,
729 HTMLAnchorElement_put_protocol,
730 HTMLAnchorElement_get_protocol,
731 HTMLAnchorElement_put_search,
732 HTMLAnchorElement_get_search,
733 HTMLAnchorElement_put_hash,
734 HTMLAnchorElement_get_hash,
735 HTMLAnchorElement_put_onblur,
736 HTMLAnchorElement_get_onblur,
737 HTMLAnchorElement_put_onfocus,
738 HTMLAnchorElement_get_onfocus,
739 HTMLAnchorElement_put_accessKey,
740 HTMLAnchorElement_get_accessKey,
741 HTMLAnchorElement_get_protocolLong,
742 HTMLAnchorElement_get_mimeType,
743 HTMLAnchorElement_get_nameProp,
744 HTMLAnchorElement_put_tabIndex,
745 HTMLAnchorElement_get_tabIndex,
746 HTMLAnchorElement_focus,
747 HTMLAnchorElement_blur
750 static inline HTMLAnchorElement *impl_from_DispatchEx(DispatchEx *iface)
752 return CONTAINING_RECORD(iface, HTMLAnchorElement, element.node.event_target.dispex);
755 static void *HTMLAnchorElement_query_interface(DispatchEx *dispex, REFIID riid)
757 HTMLAnchorElement *This = impl_from_DispatchEx(dispex);
759 if(IsEqualGUID(&IID_IHTMLAnchorElement, riid))
760 return &This->IHTMLAnchorElement_iface;
762 return HTMLElement_query_interface(&This->element.node.event_target.dispex, riid);
765 static void HTMLAnchorElement_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
767 HTMLAnchorElement *This = impl_from_DispatchEx(dispex);
768 HTMLElement_traverse(dispex, cb);
770 if(This->nsanchor)
771 note_cc_edge((nsISupports*)This->nsanchor, "nsanchor", cb);
774 static void HTMLAnchorElement_unlink(DispatchEx *dispex)
776 HTMLAnchorElement *This = impl_from_DispatchEx(dispex);
777 HTMLElement_unlink(dispex);
778 unlink_ref(&This->nsanchor);
781 static HRESULT HTMLAnchorElement_handle_event(DispatchEx *dispex, DOMEvent *event, BOOL *prevent_default)
783 HTMLAnchorElement *This = impl_from_DispatchEx(dispex);
784 nsAString href_str, target_str;
785 nsresult nsres;
787 if(event->event_id == EVENTID_CLICK) {
788 nsAString_Init(&href_str, NULL);
789 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
790 if (NS_FAILED(nsres)) {
791 ERR("Could not get anchor href: %08lx\n", nsres);
792 goto fallback;
795 nsAString_Init(&target_str, NULL);
796 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
797 if (NS_FAILED(nsres)) {
798 ERR("Could not get anchor target: %08lx\n", nsres);
799 goto fallback;
802 return handle_link_click_event(&This->element, &href_str, &target_str, event->nsevent, prevent_default);
804 fallback:
805 nsAString_Finish(&href_str);
806 nsAString_Finish(&target_str);
809 return HTMLElement_handle_event(&This->element.node.event_target.dispex, event, prevent_default);
812 static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
813 .clsid = &CLSID_HTMLAnchorElement,
814 .cpc_entries = HTMLElement_cpc,
815 .clone = HTMLElement_clone,
816 .get_attr_col = HTMLElement_get_attr_col,
819 static const event_target_vtbl_t HTMLAnchorElement_event_target_vtbl = {
821 HTMLELEMENT_DISPEX_VTBL_ENTRIES,
822 .query_interface= HTMLAnchorElement_query_interface,
823 .destructor = HTMLElement_destructor,
824 .traverse = HTMLAnchorElement_traverse,
825 .unlink = HTMLAnchorElement_unlink
827 HTMLELEMENT_EVENT_TARGET_VTBL_ENTRIES,
828 .handle_event = HTMLAnchorElement_handle_event
831 static const tid_t HTMLAnchorElement_iface_tids[] = {
832 IHTMLAnchorElement_tid,
833 HTMLELEMENT_TIDS,
837 static dispex_static_data_t HTMLAnchorElement_dispex = {
838 "HTMLAnchorElement",
839 &HTMLAnchorElement_event_target_vtbl.dispex_vtbl,
840 DispHTMLAnchorElement_tid,
841 HTMLAnchorElement_iface_tids,
842 HTMLElement_init_dispex_info
845 HRESULT HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
847 HTMLAnchorElement *ret;
848 nsresult nsres;
850 ret = calloc(1, sizeof(HTMLAnchorElement));
851 if(!ret)
852 return E_OUTOFMEMORY;
854 ret->IHTMLAnchorElement_iface.lpVtbl = &HTMLAnchorElementVtbl;
855 ret->element.node.vtbl = &HTMLAnchorElementImplVtbl;
857 HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex);
859 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor);
860 assert(nsres == NS_OK);
862 *elem = &ret->element;
863 return S_OK;