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