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