wbemprox: Add support for enumerating class properties.
[wine] / dlls / mshtml / htmlanchor.c
1 /*
2  * Copyright 2007 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <assert.h>
22
23 #define COBJMACROS
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
29
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
32 #include "binding.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 typedef struct {
39     HTMLElement element;
40
41     IHTMLAnchorElement IHTMLAnchorElement_iface;
42
43     nsIDOMHTMLAnchorElement *nsanchor;
44 } HTMLAnchorElement;
45
46 static HRESULT navigate_anchor_window(HTMLAnchorElement *This, const WCHAR *target)
47 {
48     nsAString href_str;
49     IUri *uri;
50     nsresult nsres;
51     HRESULT hres;
52
53     nsAString_Init(&href_str, NULL);
54     nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
55     if(NS_SUCCEEDED(nsres)) {
56         const PRUnichar *href;
57
58         nsAString_GetData(&href_str, &href);
59         hres = create_relative_uri(This->element.node.doc->basedoc.window, href, &uri);
60     }else {
61         ERR("Could not get anchor href: %08x\n", nsres);
62         hres = E_FAIL;
63     }
64     nsAString_Finish(&href_str);
65     if(FAILED(hres))
66         return hres;
67
68     hres = navigate_new_window(This->element.node.doc->basedoc.window, uri, target, NULL);
69     IUri_Release(uri);
70     return hres;
71 }
72
73 static HRESULT navigate_anchor(HTMLAnchorElement *This)
74 {
75     nsAString href_str, target_str;
76     HTMLOuterWindow *window = NULL;
77     nsresult nsres;
78     HRESULT hres = E_FAIL;
79
80     static const WCHAR _parentW[] = {'p','a','r','e','n','t',0};
81     static const WCHAR _selfW[] = {'_','s','e','l','f',0};
82     static const WCHAR _topW[] = {'_','t','o','p',0};
83
84     nsAString_Init(&target_str, NULL);
85     nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
86     if(NS_SUCCEEDED(nsres)) {
87         const PRUnichar *target;
88
89         nsAString_GetData(&target_str, &target);
90         if(*target && strcmpiW(target, _selfW)) {
91             if(!strcmpiW(target, _topW)) {
92                 TRACE("target _top\n");
93                 get_top_window(This->element.node.doc->basedoc.window, &window);
94             }else if(!strcmpiW(target, _parentW)) {
95                 FIXME("Navigating to target _parent is not implemented\n");
96                 nsAString_Finish(&target_str);
97                 return S_OK;
98             }else {
99                 hres = navigate_anchor_window(This, target);
100                 nsAString_Finish(&target_str);
101                 return hres;
102             }
103         }
104     }
105     nsAString_Finish(&target_str);
106
107     nsAString_Init(&href_str, NULL);
108     nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
109     if(NS_SUCCEEDED(nsres)) {
110         const PRUnichar *href;
111
112         nsAString_GetData(&href_str, &href);
113         if(*href) {
114             if(!window)
115                 window = This->element.node.doc->basedoc.window;
116             hres = navigate_url(window, href, window->url);
117         }else {
118             TRACE("empty href\n");
119             hres = S_OK;
120         }
121     }
122     nsAString_Finish(&href_str);
123     return hres;
124 }
125
126 static inline HTMLAnchorElement *impl_from_IHTMLAnchorElement(IHTMLAnchorElement *iface)
127 {
128     return CONTAINING_RECORD(iface, HTMLAnchorElement, IHTMLAnchorElement_iface);
129 }
130
131 static HRESULT WINAPI HTMLAnchorElement_QueryInterface(IHTMLAnchorElement *iface,
132         REFIID riid, void **ppv)
133 {
134     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
135
136     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
137 }
138
139 static ULONG WINAPI HTMLAnchorElement_AddRef(IHTMLAnchorElement *iface)
140 {
141     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
142
143     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
144 }
145
146 static ULONG WINAPI HTMLAnchorElement_Release(IHTMLAnchorElement *iface)
147 {
148     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
149
150     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
151 }
152
153 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfoCount(IHTMLAnchorElement *iface, UINT *pctinfo)
154 {
155     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
156     return IDispatchEx_GetTypeInfoCount(&This->element.node.dispex.IDispatchEx_iface, pctinfo);
157 }
158
159 static HRESULT WINAPI HTMLAnchorElement_GetTypeInfo(IHTMLAnchorElement *iface, UINT iTInfo,
160                                               LCID lcid, ITypeInfo **ppTInfo)
161 {
162     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
163     return IDispatchEx_GetTypeInfo(&This->element.node.dispex.IDispatchEx_iface, iTInfo, lcid,
164             ppTInfo);
165 }
166
167 static HRESULT WINAPI HTMLAnchorElement_GetIDsOfNames(IHTMLAnchorElement *iface, REFIID riid,
168                                                 LPOLESTR *rgszNames, UINT cNames,
169                                                 LCID lcid, DISPID *rgDispId)
170 {
171     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
172     return IDispatchEx_GetIDsOfNames(&This->element.node.dispex.IDispatchEx_iface, riid, rgszNames,
173             cNames, lcid, rgDispId);
174 }
175
176 static HRESULT WINAPI HTMLAnchorElement_Invoke(IHTMLAnchorElement *iface, DISPID dispIdMember,
177                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
178                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
179 {
180     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
181     return IDispatchEx_Invoke(&This->element.node.dispex.IDispatchEx_iface, dispIdMember, riid,
182             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
183 }
184
185 static HRESULT WINAPI HTMLAnchorElement_put_href(IHTMLAnchorElement *iface, BSTR v)
186 {
187     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
188     nsAString nsstr;
189     nsresult nsres;
190
191     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
192
193     nsAString_InitDepend(&nsstr, v);
194     nsres = nsIDOMHTMLAnchorElement_SetHref(This->nsanchor, &nsstr);
195     nsAString_Finish(&nsstr);
196     if(NS_FAILED(nsres))
197         return E_FAIL;
198
199     return S_OK;
200 }
201
202 static HRESULT WINAPI HTMLAnchorElement_get_href(IHTMLAnchorElement *iface, BSTR *p)
203 {
204     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
205     nsAString href_str;
206     nsresult nsres;
207     HRESULT hres;
208
209     TRACE("(%p)->(%p)\n", This, p);
210
211     nsAString_Init(&href_str, NULL);
212     nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
213     if(NS_SUCCEEDED(nsres)) {
214         const PRUnichar *href;
215
216         nsAString_GetData(&href_str, &href);
217         hres = nsuri_to_url(href, TRUE, p);
218     }else {
219         ERR("GetHref failed: %08x\n", nsres);
220         hres = E_FAIL;
221     }
222
223     nsAString_Finish(&href_str);
224     return hres;
225 }
226
227 static HRESULT WINAPI HTMLAnchorElement_put_target(IHTMLAnchorElement *iface, BSTR v)
228 {
229     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
230     nsAString nsstr;
231     nsresult nsres;
232
233     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
234
235     nsAString_InitDepend(&nsstr, v);
236     nsres = nsIDOMHTMLAnchorElement_SetTarget(This->nsanchor, &nsstr);
237     nsAString_Finish(&nsstr);
238     if(NS_FAILED(nsres))
239         return E_FAIL;
240
241     return S_OK;
242 }
243
244 static HRESULT WINAPI HTMLAnchorElement_get_target(IHTMLAnchorElement *iface, BSTR *p)
245 {
246     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
247     nsAString target_str;
248     nsresult nsres;
249
250     TRACE("(%p)->(%p)\n", This, p);
251
252     nsAString_Init(&target_str, NULL);
253     nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
254
255     return return_nsstr(nsres, &target_str, p);
256 }
257
258 static HRESULT WINAPI HTMLAnchorElement_put_rel(IHTMLAnchorElement *iface, BSTR v)
259 {
260     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
261     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
262     return E_NOTIMPL;
263 }
264
265 static HRESULT WINAPI HTMLAnchorElement_get_rel(IHTMLAnchorElement *iface, BSTR *p)
266 {
267     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
268     FIXME("(%p)->(%p)\n", This, p);
269     return E_NOTIMPL;
270 }
271
272 static HRESULT WINAPI HTMLAnchorElement_put_rev(IHTMLAnchorElement *iface, BSTR v)
273 {
274     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
275     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
276     return E_NOTIMPL;
277 }
278
279 static HRESULT WINAPI HTMLAnchorElement_get_rev(IHTMLAnchorElement *iface, BSTR *p)
280 {
281     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
282     FIXME("(%p)->(%p)\n", This, p);
283     return E_NOTIMPL;
284 }
285
286 static HRESULT WINAPI HTMLAnchorElement_put_urn(IHTMLAnchorElement *iface, BSTR v)
287 {
288     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
289     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
290     return E_NOTIMPL;
291 }
292
293 static HRESULT WINAPI HTMLAnchorElement_get_urn(IHTMLAnchorElement *iface, BSTR *p)
294 {
295     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
296     FIXME("(%p)->(%p)\n", This, p);
297     return E_NOTIMPL;
298 }
299
300 static HRESULT WINAPI HTMLAnchorElement_put_Methods(IHTMLAnchorElement *iface, BSTR v)
301 {
302     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
303     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
304     return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI HTMLAnchorElement_get_Methods(IHTMLAnchorElement *iface, BSTR *p)
308 {
309     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
310     FIXME("(%p)->(%p)\n", This, p);
311     return E_NOTIMPL;
312 }
313
314 static HRESULT WINAPI HTMLAnchorElement_put_name(IHTMLAnchorElement *iface, BSTR v)
315 {
316     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
317     nsAString nsstr;
318     nsresult nsres;
319
320     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
321
322     nsAString_InitDepend(&nsstr, v);
323     nsres = nsIDOMHTMLAnchorElement_SetName(This->nsanchor, &nsstr);
324     nsAString_Finish(&nsstr);
325     if(NS_FAILED(nsres))
326         return E_FAIL;
327
328     return S_OK;
329 }
330
331 static HRESULT WINAPI HTMLAnchorElement_get_name(IHTMLAnchorElement *iface, BSTR *p)
332 {
333     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
334     nsAString name_str;
335     nsresult nsres;
336
337     TRACE("(%p)->(%p)\n", This, p);
338
339     nsAString_Init(&name_str, NULL);
340     nsres = nsIDOMHTMLAnchorElement_GetName(This->nsanchor, &name_str);
341
342     return return_nsstr(nsres, &name_str, p);
343 }
344
345 static HRESULT WINAPI HTMLAnchorElement_put_host(IHTMLAnchorElement *iface, BSTR v)
346 {
347     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
348     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
349     return E_NOTIMPL;
350 }
351
352 static HRESULT WINAPI HTMLAnchorElement_get_host(IHTMLAnchorElement *iface, BSTR *p)
353 {
354     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
355     FIXME("(%p)->(%p)\n", This, p);
356     return E_NOTIMPL;
357 }
358
359 static HRESULT WINAPI HTMLAnchorElement_put_hostname(IHTMLAnchorElement *iface, BSTR v)
360 {
361     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
362     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
363     return E_NOTIMPL;
364 }
365
366 static HRESULT WINAPI HTMLAnchorElement_get_hostname(IHTMLAnchorElement *iface, BSTR *p)
367 {
368     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
369     FIXME("(%p)->(%p)\n", This, p);
370     return E_NOTIMPL;
371 }
372
373 static HRESULT WINAPI HTMLAnchorElement_put_pathname(IHTMLAnchorElement *iface, BSTR v)
374 {
375     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
376     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
377     return E_NOTIMPL;
378 }
379
380 static HRESULT WINAPI HTMLAnchorElement_get_pathname(IHTMLAnchorElement *iface, BSTR *p)
381 {
382     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
383     FIXME("(%p)->(%p)\n", This, p);
384     return E_NOTIMPL;
385 }
386
387 static HRESULT WINAPI HTMLAnchorElement_put_port(IHTMLAnchorElement *iface, BSTR v)
388 {
389     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
390     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
391     return E_NOTIMPL;
392 }
393
394 static HRESULT WINAPI HTMLAnchorElement_get_port(IHTMLAnchorElement *iface, BSTR *p)
395 {
396     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
397     FIXME("(%p)->(%p)\n", This, p);
398     return E_NOTIMPL;
399 }
400
401 static HRESULT WINAPI HTMLAnchorElement_put_protocol(IHTMLAnchorElement *iface, BSTR v)
402 {
403     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
404     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
405     return E_NOTIMPL;
406 }
407
408 static HRESULT WINAPI HTMLAnchorElement_get_protocol(IHTMLAnchorElement *iface, BSTR *p)
409 {
410     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
411     FIXME("(%p)->(%p)\n", This, p);
412     return E_NOTIMPL;
413 }
414
415 static HRESULT WINAPI HTMLAnchorElement_put_search(IHTMLAnchorElement *iface, BSTR v)
416 {
417     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
418     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
419     return E_NOTIMPL;
420 }
421
422 static HRESULT WINAPI HTMLAnchorElement_get_search(IHTMLAnchorElement *iface, BSTR *p)
423 {
424     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
425     FIXME("(%p)->(%p)\n", This, p);
426     return E_NOTIMPL;
427 }
428
429 static HRESULT WINAPI HTMLAnchorElement_put_hash(IHTMLAnchorElement *iface, BSTR v)
430 {
431     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
432     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
433     return E_NOTIMPL;
434 }
435
436 static HRESULT WINAPI HTMLAnchorElement_get_hash(IHTMLAnchorElement *iface, BSTR *p)
437 {
438     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
439     FIXME("(%p)->(%p)\n", This, p);
440     return E_NOTIMPL;
441 }
442
443 static HRESULT WINAPI HTMLAnchorElement_put_onblur(IHTMLAnchorElement *iface, VARIANT v)
444 {
445     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
446
447     TRACE("(%p)->()\n", This);
448
449     return IHTMLElement2_put_onblur(&This->element.IHTMLElement2_iface, v);
450 }
451
452 static HRESULT WINAPI HTMLAnchorElement_get_onblur(IHTMLAnchorElement *iface, VARIANT *p)
453 {
454     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
455
456     TRACE("(%p)->(%p)\n", This, p);
457
458     return IHTMLElement2_get_onblur(&This->element.IHTMLElement2_iface, p);
459 }
460
461 static HRESULT WINAPI HTMLAnchorElement_put_onfocus(IHTMLAnchorElement *iface, VARIANT v)
462 {
463     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
464
465     TRACE("(%p)->()\n", This);
466
467     return IHTMLElement2_put_onfocus(&This->element.IHTMLElement2_iface, v);
468 }
469
470 static HRESULT WINAPI HTMLAnchorElement_get_onfocus(IHTMLAnchorElement *iface, VARIANT *p)
471 {
472     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
473
474     TRACE("(%p)->(%p)\n", This, p);
475
476     return IHTMLElement2_get_onfocus(&This->element.IHTMLElement2_iface, p);
477 }
478
479 static HRESULT WINAPI HTMLAnchorElement_put_accessKey(IHTMLAnchorElement *iface, BSTR v)
480 {
481     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
482
483     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
484
485     return IHTMLElement2_put_accessKey(&This->element.IHTMLElement2_iface, v);
486 }
487
488 static HRESULT WINAPI HTMLAnchorElement_get_accessKey(IHTMLAnchorElement *iface, BSTR *p)
489 {
490     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
491
492     TRACE("(%p)->(%p)\n", This, p);
493
494     return IHTMLElement2_get_accessKey(&This->element.IHTMLElement2_iface, p);
495 }
496
497 static HRESULT WINAPI HTMLAnchorElement_get_protocolLong(IHTMLAnchorElement *iface, BSTR *p)
498 {
499     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
500     FIXME("(%p)->(%p)\n", This, p);
501     return E_NOTIMPL;
502 }
503
504 static HRESULT WINAPI HTMLAnchorElement_get_mimeType(IHTMLAnchorElement *iface, BSTR *p)
505 {
506     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
507     FIXME("(%p)->(%p)\n", This, p);
508     return E_NOTIMPL;
509 }
510
511 static HRESULT WINAPI HTMLAnchorElement_get_nameProp(IHTMLAnchorElement *iface, BSTR *p)
512 {
513     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
514     FIXME("(%p)->(%p)\n", This, p);
515     return E_NOTIMPL;
516 }
517
518 static HRESULT WINAPI HTMLAnchorElement_put_tabIndex(IHTMLAnchorElement *iface, short v)
519 {
520     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
521
522     TRACE("(%p)->()\n", This);
523
524     return IHTMLElement2_put_tabIndex(&This->element.IHTMLElement2_iface, v);
525 }
526
527 static HRESULT WINAPI HTMLAnchorElement_get_tabIndex(IHTMLAnchorElement *iface, short *p)
528 {
529     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
530
531     TRACE("(%p)->(%p)\n", This, p);
532
533     return IHTMLElement2_get_tabIndex(&This->element.IHTMLElement2_iface, p);
534 }
535
536 static HRESULT WINAPI HTMLAnchorElement_focus(IHTMLAnchorElement *iface)
537 {
538     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
539
540     TRACE("(%p)\n", This);
541
542     return IHTMLElement2_focus(&This->element.IHTMLElement2_iface);
543 }
544
545 static HRESULT WINAPI HTMLAnchorElement_blur(IHTMLAnchorElement *iface)
546 {
547     HTMLAnchorElement *This = impl_from_IHTMLAnchorElement(iface);
548
549     TRACE("(%p)\n", This);
550
551     return IHTMLElement2_blur(&This->element.IHTMLElement2_iface);
552 }
553
554 static const IHTMLAnchorElementVtbl HTMLAnchorElementVtbl = {
555     HTMLAnchorElement_QueryInterface,
556     HTMLAnchorElement_AddRef,
557     HTMLAnchorElement_Release,
558     HTMLAnchorElement_GetTypeInfoCount,
559     HTMLAnchorElement_GetTypeInfo,
560     HTMLAnchorElement_GetIDsOfNames,
561     HTMLAnchorElement_Invoke,
562     HTMLAnchorElement_put_href,
563     HTMLAnchorElement_get_href,
564     HTMLAnchorElement_put_target,
565     HTMLAnchorElement_get_target,
566     HTMLAnchorElement_put_rel,
567     HTMLAnchorElement_get_rel,
568     HTMLAnchorElement_put_rev,
569     HTMLAnchorElement_get_rev,
570     HTMLAnchorElement_put_urn,
571     HTMLAnchorElement_get_urn,
572     HTMLAnchorElement_put_Methods,
573     HTMLAnchorElement_get_Methods,
574     HTMLAnchorElement_put_name,
575     HTMLAnchorElement_get_name,
576     HTMLAnchorElement_put_host,
577     HTMLAnchorElement_get_host,
578     HTMLAnchorElement_put_hostname,
579     HTMLAnchorElement_get_hostname,
580     HTMLAnchorElement_put_pathname,
581     HTMLAnchorElement_get_pathname,
582     HTMLAnchorElement_put_port,
583     HTMLAnchorElement_get_port,
584     HTMLAnchorElement_put_protocol,
585     HTMLAnchorElement_get_protocol,
586     HTMLAnchorElement_put_search,
587     HTMLAnchorElement_get_search,
588     HTMLAnchorElement_put_hash,
589     HTMLAnchorElement_get_hash,
590     HTMLAnchorElement_put_onblur,
591     HTMLAnchorElement_get_onblur,
592     HTMLAnchorElement_put_onfocus,
593     HTMLAnchorElement_get_onfocus,
594     HTMLAnchorElement_put_accessKey,
595     HTMLAnchorElement_get_accessKey,
596     HTMLAnchorElement_get_protocolLong,
597     HTMLAnchorElement_get_mimeType,
598     HTMLAnchorElement_get_nameProp,
599     HTMLAnchorElement_put_tabIndex,
600     HTMLAnchorElement_get_tabIndex,
601     HTMLAnchorElement_focus,
602     HTMLAnchorElement_blur
603 };
604
605 static inline HTMLAnchorElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
606 {
607     return CONTAINING_RECORD(iface, HTMLAnchorElement, element.node);
608 }
609
610 static HRESULT HTMLAnchorElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
611 {
612     HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
613
614     *ppv = NULL;
615
616     if(IsEqualGUID(&IID_IUnknown, riid)) {
617         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
618         *ppv = &This->IHTMLAnchorElement_iface;
619     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
620         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
621         *ppv = &This->IHTMLAnchorElement_iface;
622     }else if(IsEqualGUID(&IID_IHTMLAnchorElement, riid)) {
623         TRACE("(%p)->(IID_IHTMLAnchorElement %p)\n", This, ppv);
624         *ppv = &This->IHTMLAnchorElement_iface;
625     }
626
627     if(*ppv) {
628         IUnknown_AddRef((IUnknown*)*ppv);
629         return S_OK;
630     }
631
632     return HTMLElement_QI(&This->element.node, riid, ppv);
633 }
634
635 static HRESULT HTMLAnchorElement_handle_event(HTMLDOMNode *iface, eventid_t eid, nsIDOMEvent *event, BOOL *prevent_default)
636 {
637     HTMLAnchorElement *This = impl_from_HTMLDOMNode(iface);
638
639     if(eid == EVENTID_CLICK) {
640         nsIDOMMouseEvent *mouse_event;
641         PRUint16 button;
642         nsresult nsres;
643
644         TRACE("CLICK\n");
645
646         nsres = nsIDOMEvent_QueryInterface(event, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
647         assert(nsres == NS_OK);
648
649         nsres = nsIDOMMouseEvent_GetButton(mouse_event, &button);
650         assert(nsres == NS_OK);
651
652         nsIDOMMouseEvent_Release(mouse_event);
653
654         switch(button) {
655         case 0:
656             *prevent_default = TRUE;
657             return navigate_anchor(This);
658         case 1:
659             *prevent_default = TRUE;
660             return navigate_anchor_window(This, NULL);
661         default:
662             *prevent_default = FALSE;
663             return S_OK;
664         }
665     }
666
667     return S_OK;
668 }
669
670 static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
671     HTMLAnchorElement_QI,
672     HTMLElement_destructor,
673     HTMLElement_clone,
674     HTMLElement_get_attr_col,
675     NULL,
676     NULL,
677     HTMLAnchorElement_handle_event
678 };
679
680 static const tid_t HTMLAnchorElement_iface_tids[] = {
681     IHTMLAnchorElement_tid,
682     HTMLELEMENT_TIDS,
683     IHTMLTextContainer_tid,
684     IHTMLUniqueName_tid,
685     0
686 };
687
688 static dispex_static_data_t HTMLAnchorElement_dispex = {
689     NULL,
690     DispHTMLAnchorElement_tid,
691     NULL,
692     HTMLAnchorElement_iface_tids
693 };
694
695 HRESULT HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
696 {
697     HTMLAnchorElement *ret;
698     nsresult nsres;
699
700     ret = heap_alloc_zero(sizeof(HTMLAnchorElement));
701     if(!ret)
702         return E_OUTOFMEMORY;
703
704     ret->IHTMLAnchorElement_iface.lpVtbl = &HTMLAnchorElementVtbl;
705     ret->element.node.vtbl = &HTMLAnchorElementImplVtbl;
706
707     HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex);
708
709     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor);
710
711     /* Shere the reference with nsnode */
712     assert(nsres == NS_OK && (nsIDOMNode*)ret->nsanchor == ret->element.node.nsnode);
713     nsIDOMNode_Release(ret->element.node.nsnode);
714
715     *elem = &ret->element;
716     return S_OK;
717 }