gdi32: Try to parse font names without FreeType.
[wine/zf.git] / dlls / mshtml / htmlanchor.c
bloba0e96af822e79925c3637b761b867d8de3b96f20
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 *use_new_window = FALSE;
70 nsAString_GetData(target_str, &target);
71 TRACE("%s\n", debugstr_w(target));
73 if(!*target || !wcsicmp(target, L"_self")) {
74 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
75 return window;
78 if(!wcsicmp(target, L"_top")) {
79 get_top_window(window, &top_window);
80 IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface);
81 return top_window;
84 if(!wcsicmp(target, L"_parent")) {
85 if(!window->parent) {
86 WARN("Window has no parent, treat as self\n");
87 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
88 return window;
91 IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface);
92 return window->parent;
95 get_top_window(window, &top_window);
97 hres = get_frame_by_name(top_window, target, TRUE, &ret_window);
98 if(FAILED(hres) || !ret_window) {
99 *use_new_window = TRUE;
100 return NULL;
103 IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface);
104 return ret_window;
107 static HRESULT navigate_href(HTMLElement *element, nsAString *href_str, nsAString *target_str)
109 HTMLOuterWindow *window;
110 BOOL use_new_window;
111 const PRUnichar *href;
112 HRESULT hres;
114 window = get_target_window(element->node.doc->basedoc.window, target_str, &use_new_window);
115 if(!window) {
116 if(use_new_window) {
117 const PRUnichar *target;
118 nsAString_GetData(target_str, &target);
119 return navigate_href_new_window(element, href_str, target);
120 }else {
121 return S_OK;
125 nsAString_GetData(href_str, &href);
126 if(*href) {
127 hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED);
128 }else {
129 TRACE("empty href\n");
130 hres = S_OK;
132 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
133 return hres;
136 HRESULT handle_link_click_event(HTMLElement *element, nsAString *href_str, nsAString *target_str,
137 nsIDOMEvent *event, BOOL *prevent_default)
139 nsIDOMMouseEvent *mouse_event;
140 INT16 button;
141 nsresult nsres;
142 HRESULT hres;
144 TRACE("CLICK\n");
146 nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
147 assert(nsres == NS_OK);
149 nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button);
150 assert(nsres == NS_OK);
152 nsIDOMMouseEvent_Release(mouse_event);
154 switch(button) {
155 case 0:
156 *prevent_default = TRUE;
157 hres = navigate_href(element, href_str, target_str);
158 break;
159 case 1:
160 *prevent_default = TRUE;
161 hres = navigate_href_new_window(element, href_str, NULL);
162 break;
163 default:
164 *prevent_default = FALSE;
165 hres = S_OK;
168 nsAString_Finish(href_str);
169 nsAString_Finish(target_str);
170 return hres;
173 static IUri *get_anchor_uri(HTMLAnchorElement *anchor)
175 nsAString href_str;
176 IUri *uri = NULL;
177 nsresult nsres;
179 nsAString_Init(&href_str, NULL);
180 nsres = nsIDOMHTMLAnchorElement_GetHref(anchor->nsanchor, &href_str);
181 if(NS_SUCCEEDED(nsres)) {
182 const PRUnichar *href;
184 nsAString_GetData(&href_str, &href);
185 create_uri(href, 0, &uri);
186 }else {
187 ERR("GetHref failed: %08x\n", nsres);
190 nsAString_Finish(&href_str);
191 return uri;
194 static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
196 return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
199 static HRESULT WINAPI HTMLAnchorElement_QueryInterface(IHTMLAnchorElement *iface,
200 REFIID riid, void **ppv)
202 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
204 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
207 static ULONG WINAPI HTMLAnchorElement_AddRef(IHTMLAnchorElement *iface)
209 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
211 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
214 static ULONG WINAPI HTMLAnchorElement_Release(IHTMLAnchorElement *iface)
216 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
218 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
221 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfoCount(IHTMLAnchorElement *iface, UINT *pctinfo)
223 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
224 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
227 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfo(IHTMLAnchorElement *iface, UINT iTInfo,
228 LCID lcid, ITypeInfo **ppTInfo)
230 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
231 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
232 ppTInfo);
235 static HRESULT WINAPI HTMLAnchorElement_GetIDsOfNames(IHTMLAnchorElement *iface, REFIID riid,
236 LPOLESTR *rgszNames, UINT cNames,
237 LCID lcid, DISPID *rgDispId)
239 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
240 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
241 cNames, lcid, rgDispId);
244 static HRESULT WINAPI HTMLAnchorElement_Invoke(IHTMLAnchorElement *iface, DISPID dispIdMember,
245 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
246 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
248 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
249 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
250 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
253 static HRESULT WINAPI HTMLAnchorElement_put_href(IHTMLAnchorElement *iface, BSTR v)
255 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
256 nsAString nsstr;
257 nsresult nsres;
259 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
261 nsAString_InitDepend(&nsstr, v);
262 nsres = nsIDOMHTMLAnchorElement_SetHref(This->nsanchor, &nsstr);
263 nsAString_Finish(&nsstr);
264 if(NS_FAILED(nsres))
265 return E_FAIL;
267 return S_OK;
270 static HRESULT WINAPI HTMLAnchorElement_get_href(IHTMLAnchorElement *iface, BSTR *p)
272 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
273 nsAString href_str;
274 nsresult nsres;
275 HRESULT hres;
277 TRACE("(%p)->(%p)\n", This, p);
279 nsAString_Init(&href_str, NULL);
280 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
281 if(NS_SUCCEEDED(nsres)) {
282 const PRUnichar *href;
284 nsAString_GetData(&href_str, &href);
285 hres = nsuri_to_url(href, TRUE, p);
286 }else {
287 ERR("GetHref failed: %08x\n", nsres);
288 hres = E_FAIL;
291 nsAString_Finish(&href_str);
292 return hres;
295 static HRESULT WINAPI HTMLAnchorElement_put_target(IHTMLAnchorElement *iface, BSTR v)
297 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
298 nsAString nsstr;
299 nsresult nsres;
301 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
303 nsAString_InitDepend(&nsstr, v);
304 nsres = nsIDOMHTMLAnchorElement_SetTarget(This->nsanchor, &nsstr);
305 nsAString_Finish(&nsstr);
306 if(NS_FAILED(nsres))
307 return E_FAIL;
309 return S_OK;
312 static HRESULT WINAPI HTMLAnchorElement_get_target(IHTMLAnchorElement *iface, BSTR *p)
314 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
315 nsAString target_str;
316 nsresult nsres;
318 TRACE("(%p)->(%p)\n", This, p);
320 nsAString_Init(&target_str, NULL);
321 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
323 return return_nsstr(nsres, &target_str, p);
326 static HRESULT WINAPI HTMLAnchorElement_put_rel(IHTMLAnchorElement *iface, BSTR v)
328 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
329 nsAString nsstr;
330 nsresult nsres;
332 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
334 nsAString_InitDepend(&nsstr, v);
335 nsres = nsIDOMHTMLAnchorElement_SetRel(This->nsanchor, &nsstr);
336 nsAString_Finish(&nsstr);
337 if(NS_FAILED(nsres))
338 return E_FAIL;
340 return S_OK;
343 static HRESULT WINAPI HTMLAnchorElement_get_rel(IHTMLAnchorElement *iface, BSTR *p)
345 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
346 nsAString nsstr;
347 nsresult nsres;
349 TRACE("(%p)->(%p)\n", This, p);
351 nsAString_Init(&nsstr, NULL);
352 nsres = nsIDOMHTMLAnchorElement_GetRel(This->nsanchor, &nsstr);
353 return return_nsstr(nsres, &nsstr, p);
356 static HRESULT WINAPI HTMLAnchorElement_put_rev(IHTMLAnchorElement *iface, BSTR v)
358 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
359 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
360 return E_NOTIMPL;
363 static HRESULT WINAPI HTMLAnchorElement_get_rev(IHTMLAnchorElement *iface, BSTR *p)
365 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
366 FIXME("(%p)->(%p)\n", This, p);
367 return E_NOTIMPL;
370 static HRESULT WINAPI HTMLAnchorElement_put_urn(IHTMLAnchorElement *iface, BSTR v)
372 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
373 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
374 return E_NOTIMPL;
377 static HRESULT WINAPI HTMLAnchorElement_get_urn(IHTMLAnchorElement *iface, BSTR *p)
379 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
380 FIXME("(%p)->(%p)\n", This, p);
381 return E_NOTIMPL;
384 static HRESULT WINAPI HTMLAnchorElement_put_Methods(IHTMLAnchorElement *iface, BSTR v)
386 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
387 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
388 return E_NOTIMPL;
391 static HRESULT WINAPI HTMLAnchorElement_get_Methods(IHTMLAnchorElement *iface, BSTR *p)
393 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
394 FIXME("(%p)->(%p)\n", This, p);
395 return E_NOTIMPL;
398 static HRESULT WINAPI HTMLAnchorElement_put_name(IHTMLAnchorElement *iface, BSTR v)
400 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
401 nsAString nsstr;
402 nsresult nsres;
404 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
406 nsAString_InitDepend(&nsstr, v);
407 nsres = nsIDOMHTMLAnchorElement_SetName(This->nsanchor, &nsstr);
408 nsAString_Finish(&nsstr);
409 if(NS_FAILED(nsres))
410 return E_FAIL;
412 return S_OK;
415 static HRESULT WINAPI HTMLAnchorElement_get_name(IHTMLAnchorElement *iface, BSTR *p)
417 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
418 nsAString name_str;
419 nsresult nsres;
421 TRACE("(%p)->(%p)\n", This, p);
423 nsAString_Init(&name_str, NULL);
424 nsres = nsIDOMHTMLAnchorElement_GetName(This->nsanchor, &name_str);
426 return return_nsstr(nsres, &name_str, p);
429 static HRESULT WINAPI HTMLAnchorElement_put_host(IHTMLAnchorElement *iface, BSTR v)
431 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
432 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
433 return E_NOTIMPL;
436 static HRESULT WINAPI HTMLAnchorElement_get_host(IHTMLAnchorElement *iface, BSTR *p)
438 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
439 nsAString str;
440 nsresult nsres;
442 TRACE("(%p)->(%p)\n", This, p);
444 /* FIXME: IE always appends port number, even if it's implicit default number */
445 nsAString_InitDepend(&str, NULL);
446 nsres = nsIDOMHTMLAnchorElement_GetHost(This->nsanchor, &str);
447 return return_nsstr(nsres, &str, p);
450 static HRESULT WINAPI HTMLAnchorElement_put_hostname(IHTMLAnchorElement *iface, BSTR v)
452 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
453 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
454 return E_NOTIMPL;
457 static HRESULT WINAPI HTMLAnchorElement_get_hostname(IHTMLAnchorElement *iface, BSTR *p)
459 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
460 nsAString hostname_str;
461 nsresult nsres;
463 TRACE("(%p)->(%p)\n", This, p);
465 nsAString_Init(&hostname_str, NULL);
466 nsres = nsIDOMHTMLAnchorElement_GetHostname(This->nsanchor, &hostname_str);
467 return return_nsstr(nsres, &hostname_str, p);
470 static HRESULT WINAPI HTMLAnchorElement_put_pathname(IHTMLAnchorElement *iface, BSTR v)
472 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
473 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
474 return E_NOTIMPL;
477 static HRESULT WINAPI HTMLAnchorElement_get_pathname(IHTMLAnchorElement *iface, BSTR *p)
479 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
480 FIXME("(%p)->(%p)\n", This, p);
481 return E_NOTIMPL;
484 static HRESULT WINAPI HTMLAnchorElement_put_port(IHTMLAnchorElement *iface, BSTR v)
486 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
487 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
488 return E_NOTIMPL;
491 static HRESULT WINAPI HTMLAnchorElement_get_port(IHTMLAnchorElement *iface, BSTR *p)
493 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
494 FIXME("(%p)->(%p)\n", This, p);
495 return E_NOTIMPL;
498 static HRESULT WINAPI HTMLAnchorElement_put_protocol(IHTMLAnchorElement *iface, BSTR v)
500 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
501 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
502 return E_NOTIMPL;
505 static HRESULT WINAPI HTMLAnchorElement_get_protocol(IHTMLAnchorElement *iface, BSTR *p)
507 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
508 BSTR scheme;
509 size_t len;
510 IUri *uri;
511 HRESULT hres;
513 TRACE("(%p)->(%p)\n", This, p);
515 uri = get_anchor_uri(This);
516 if(!uri) {
517 WARN("Could not create IUri\n");
518 *p = NULL;
519 return S_OK;
522 hres = IUri_GetSchemeName(uri, &scheme);
523 IUri_Release(uri);
524 if(FAILED(hres))
525 return hres;
527 len = SysStringLen(scheme);
528 if(len) {
529 *p = SysAllocStringLen(scheme, len + 1);
530 if(*p)
531 (*p)[len] = ':';
532 else
533 hres = E_OUTOFMEMORY;
534 }else {
535 *p = NULL;
537 SysFreeString(scheme);
538 return hres;
541 static HRESULT WINAPI HTMLAnchorElement_put_search(IHTMLAnchorElement *iface, BSTR v)
543 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
544 nsAString nsstr;
545 nsresult nsres;
547 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
549 nsAString_InitDepend(&nsstr, v);
550 nsres = nsIDOMHTMLAnchorElement_SetSearch(This->nsanchor, &nsstr);
551 nsAString_Finish(&nsstr);
552 if(NS_FAILED(nsres))
553 return E_FAIL;
555 return S_OK;
558 static HRESULT WINAPI HTMLAnchorElement_get_search(IHTMLAnchorElement *iface, BSTR *p)
560 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
561 nsAString search_str;
562 nsresult nsres;
564 TRACE("(%p)->(%p)\n", This, p);
566 nsAString_Init(&search_str, NULL);
567 nsres = nsIDOMHTMLAnchorElement_GetSearch(This->nsanchor, &search_str);
568 return return_nsstr(nsres, &search_str, p);
571 static HRESULT WINAPI HTMLAnchorElement_put_hash(IHTMLAnchorElement *iface, BSTR v)
573 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
574 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
575 return E_NOTIMPL;
578 static HRESULT WINAPI HTMLAnchorElement_get_hash(IHTMLAnchorElement *iface, BSTR *p)
580 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
581 nsAString hash_str;
582 nsresult nsres;
584 TRACE("(%p)->(%p)\n", This, p);
586 nsAString_Init(&hash_str, NULL);
587 nsres = nsIDOMHTMLAnchorElement_GetHash(This->nsanchor, &hash_str);
588 return return_nsstr(nsres, &hash_str, p);
591 static HRESULT WINAPI HTMLAnchorElement_put_onblur(IHTMLAnchorElement *iface, VARIANT v)
593 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
595 TRACE("(%p)->()\n", This);
597 return IHTMLElement2_put_onblur(&This->element.IHTMLElement2_iface, v);
600 static HRESULT WINAPI HTMLAnchorElement_get_onblur(IHTMLAnchorElement *iface, VARIANT *p)
602 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
604 TRACE("(%p)->(%p)\n", This, p);
606 return IHTMLElement2_get_onblur(&This->element.IHTMLElement2_iface, p);
609 static HRESULT WINAPI HTMLAnchorElement_put_onfocus(IHTMLAnchorElement *iface, VARIANT v)
611 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
613 TRACE("(%p)->()\n", This);
615 return IHTMLElement2_put_onfocus(&This->element.IHTMLElement2_iface, v);
618 static HRESULT WINAPI HTMLAnchorElement_get_onfocus(IHTMLAnchorElement *iface, VARIANT *p)
620 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
622 TRACE("(%p)->(%p)\n", This, p);
624 return IHTMLElement2_get_onfocus(&This->element.IHTMLElement2_iface, p);
627 static HRESULT WINAPI HTMLAnchorElement_put_accessKey(IHTMLAnchorElement *iface, BSTR v)
629 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
631 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
633 return IHTMLElement2_put_accessKey(&This->element.IHTMLElement2_iface, v);
636 static HRESULT WINAPI HTMLAnchorElement_get_accessKey(IHTMLAnchorElement *iface, BSTR *p)
638 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
640 TRACE("(%p)->(%p)\n", This, p);
642 return IHTMLElement2_get_accessKey(&This->element.IHTMLElement2_iface, p);
645 static HRESULT WINAPI HTMLAnchorElement_get_protocolLong(IHTMLAnchorElement *iface, BSTR *p)
647 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
648 FIXME("(%p)->(%p)\n", This, p);
649 return E_NOTIMPL;
652 static HRESULT WINAPI HTMLAnchorElement_get_mimeType(IHTMLAnchorElement *iface, BSTR *p)
654 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
655 FIXME("(%p)->(%p)\n", This, p);
656 return E_NOTIMPL;
659 static HRESULT WINAPI HTMLAnchorElement_get_nameProp(IHTMLAnchorElement *iface, BSTR *p)
661 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
662 FIXME("(%p)->(%p)\n", This, p);
663 return E_NOTIMPL;
666 static HRESULT WINAPI HTMLAnchorElement_put_tabIndex(IHTMLAnchorElement *iface, short v)
668 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
670 TRACE("(%p)->()\n", This);
672 return IHTMLElement2_put_tabIndex(&This->element.IHTMLElement2_iface, v);
675 static HRESULT WINAPI HTMLAnchorElement_get_tabIndex(IHTMLAnchorElement *iface, short *p)
677 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
679 TRACE("(%p)->(%p)\n", This, p);
681 return IHTMLElement2_get_tabIndex(&This->element.IHTMLElement2_iface, p);
684 static HRESULT WINAPI HTMLAnchorElement_focus(IHTMLAnchorElement *iface)
686 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
688 TRACE("(%p)\n", This);
690 return IHTMLElement2_focus(&This->element.IHTMLElement2_iface);
693 static HRESULT WINAPI HTMLAnchorElement_blur(IHTMLAnchorElement *iface)
695 HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
697 TRACE("(%p)\n", This);
699 return IHTMLElement2_blur(&This->element.IHTMLElement2_iface);
702 static const IHTMLAnchorElementVtbl HTMLAnchorElementVtbl = {
703 HTMLAnchorElement_QueryInterface,
704 HTMLAnchorElement_AddRef,
705 HTMLAnchorElement_Release,
706 HTMLAnchorElement_GetTypeInfoCount,
707 HTMLAnchorElement_GetTypeInfo,
708 HTMLAnchorElement_GetIDsOfNames,
709 HTMLAnchorElement_Invoke,
710 HTMLAnchorElement_put_href,
711 HTMLAnchorElement_get_href,
712 HTMLAnchorElement_put_target,
713 HTMLAnchorElement_get_target,
714 HTMLAnchorElement_put_rel,
715 HTMLAnchorElement_get_rel,
716 HTMLAnchorElement_put_rev,
717 HTMLAnchorElement_get_rev,
718 HTMLAnchorElement_put_urn,
719 HTMLAnchorElement_get_urn,
720 HTMLAnchorElement_put_Methods,
721 HTMLAnchorElement_get_Methods,
722 HTMLAnchorElement_put_name,
723 HTMLAnchorElement_get_name,
724 HTMLAnchorElement_put_host,
725 HTMLAnchorElement_get_host,
726 HTMLAnchorElement_put_hostname,
727 HTMLAnchorElement_get_hostname,
728 HTMLAnchorElement_put_pathname,
729 HTMLAnchorElement_get_pathname,
730 HTMLAnchorElement_put_port,
731 HTMLAnchorElement_get_port,
732 HTMLAnchorElement_put_protocol,
733 HTMLAnchorElement_get_protocol,
734 HTMLAnchorElement_put_search,
735 HTMLAnchorElement_get_search,
736 HTMLAnchorElement_put_hash,
737 HTMLAnchorElement_get_hash,
738 HTMLAnchorElement_put_onblur,
739 HTMLAnchorElement_get_onblur,
740 HTMLAnchorElement_put_onfocus,
741 HTMLAnchorElement_get_onfocus,
742 HTMLAnchorElement_put_accessKey,
743 HTMLAnchorElement_get_accessKey,
744 HTMLAnchorElement_get_protocolLong,
745 HTMLAnchorElement_get_mimeType,
746 HTMLAnchorElement_get_nameProp,
747 HTMLAnchorElement_put_tabIndex,
748 HTMLAnchorElement_get_tabIndex,
749 HTMLAnchorElement_focus,
750 HTMLAnchorElement_blur
753 static inline HTMLAnchorElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
755 return CONTAINING_RECORD(iface, HTMLAnchorElement, element.node);
758 static HRESULT HTMLAnchorElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
760 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
762 *ppv = NULL;
764 if(IsEqualGUID(&IID_IUnknown, riid)) {
765 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
766 *ppv = &This->IHTMLAnchorElement_iface;
767 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
768 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
769 *ppv = &This->IHTMLAnchorElement_iface;
770 }else if(IsEqualGUID(&IID_IHTMLAnchorElement, riid)) {
771 TRACE("(%p)->(IID_IHTMLAnchorElement %p)\n", This, ppv);
772 *ppv = &This->IHTMLAnchorElement_iface;
775 if(*ppv) {
776 IUnknown_AddRef((IUnknown*)*ppv);
777 return S_OK;
780 return HTMLElement_QI(&This->element.node, riid, ppv);
783 static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *event, BOOL *prevent_default)
785 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
786 nsAString href_str, target_str;
787 nsresult nsres;
789 if(eid == EVENTID_CLICK) {
790 nsAString_Init(&href_str, NULL);
791 nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
792 if (NS_FAILED(nsres)) {
793 ERR("Could not get anchor href: %08x\n", nsres);
794 goto fallback;
797 nsAString_Init(&target_str, NULL);
798 nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
799 if (NS_FAILED(nsres)) {
800 ERR("Could not get anchor target: %08x\n", nsres);
801 goto fallback;
804 return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);
806 fallback:
807 nsAString_Finish(&href_str);
808 nsAString_Finish(&target_str);
811 return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
814 static void HTMLAnchorElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
816 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
818 if(This->nsanchor)
819 note_cc_edge((nsISupports*)This->nsanchor, "This->nsanchor", cb);
822 static void HTMLAnchorElement_unlink(HTMLDOMNode *iface)
824 HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
826 if(This->nsanchor) {
827 nsIDOMHTMLAnchorElement *nsanchor = This->nsanchor;
829 This->nsanchor = NULL;
830 nsIDOMHTMLAnchorElement_Release(nsanchor);
834 static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
835 &CLSID_HTMLAnchorElement,
836 HTMLAnchorElement_QI,
837 HTMLElement_destructor,
838 HTMLElement_cpc,
839 HTMLElement_clone,
840 HTMLAnchorElement_handle_event,
841 HTMLElement_get_attr_col,
842 NULL,
843 NULL,
844 NULL,
845 NULL,
846 NULL,
847 NULL,
848 NULL,
849 NULL,
850 HTMLAnchorElement_traverse,
851 HTMLAnchorElement_unlink
854 static const tid_t HTMLAnchorElement_iface_tids[] = {
855 IHTMLAnchorElement_tid,
856 HTMLELEMENT_TIDS,
860 static dispex_static_data_t HTMLAnchorElement_dispex = {
861 NULL,
862 DispHTMLAnchorElement_tid,
863 HTMLAnchorElement_iface_tids,
864 HTMLElement_init_dispex_info
867 HRESULT HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
869 HTMLAnchorElement *ret;
870 nsresult nsres;
872 ret = heap_alloc_zero(sizeof(HTMLAnchorElement));
873 if(!ret)
874 return E_OUTOFMEMORY;
876 ret->IHTMLAnchorElement_iface.lpVtbl = &HTMLAnchorElementVtbl;
877 ret->element.node.vtbl = &HTMLAnchorElementImplVtbl;
879 HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex);
881 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor);
882 assert(nsres == NS_OK);
884 *elem = &ret->element;
885 return S_OK;