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