xref: /reactos/dll/win32/mshtml/htmlarea.c (revision ebaf247c)
1 /*
2  * Copyright 2015 Alex Henrie
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     IHTMLAreaElement IHTMLAreaElement_iface;
25 
26     nsIDOMHTMLAreaElement *nsarea;
27 } HTMLAreaElement;
28 
29 static inline HTMLAreaElement *impl_from_IHTMLAreaElement(IHTMLAreaElement *iface)
30 {
31     return CONTAINING_RECORD(iface, HTMLAreaElement, IHTMLAreaElement_iface);
32 }
33 
34 static HRESULT WINAPI HTMLAreaElement_QueryInterface(IHTMLAreaElement *iface, REFIID riid, void **ppv)
35 {
36     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
37 
38     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
39 }
40 
41 static ULONG WINAPI HTMLAreaElement_AddRef(IHTMLAreaElement *iface)
42 {
43     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
44 
45     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
46 }
47 
48 static ULONG WINAPI HTMLAreaElement_Release(IHTMLAreaElement *iface)
49 {
50     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
51 
52     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
53 }
54 
55 static HRESULT WINAPI HTMLAreaElement_GetTypeInfoCount(IHTMLAreaElement *iface, UINT *pctinfo)
56 {
57     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
58     return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
59 }
60 
61 static HRESULT WINAPI HTMLAreaElement_GetTypeInfo(IHTMLAreaElement *iface, UINT iTInfo,
62                                               LCID lcid, ITypeInfo **ppTInfo)
63 {
64     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
65     return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
66             ppTInfo);
67 }
68 
69 static HRESULT WINAPI HTMLAreaElement_GetIDsOfNames(IHTMLAreaElement *iface, REFIID riid,
70                                                 LPOLESTR *rgszNames, UINT cNames,
71                                                 LCID lcid, DISPID *rgDispId)
72 {
73     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
74     return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
75             cNames, lcid, rgDispId);
76 }
77 
78 static HRESULT WINAPI HTMLAreaElement_Invoke(IHTMLAreaElement *iface, DISPID dispIdMember,
79                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
80                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
81 {
82     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
83     return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
84             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
85 }
86 
87 static HRESULT WINAPI HTMLAreaElement_put_shape(IHTMLAreaElement *iface, BSTR v)
88 {
89     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
90     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
91     return E_NOTIMPL;
92 }
93 
94 static HRESULT WINAPI HTMLAreaElement_get_shape(IHTMLAreaElement *iface, BSTR *p)
95 {
96     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
97     FIXME("(%p)->(%p)\n", This, p);
98     return E_NOTIMPL;
99 }
100 
101 static HRESULT WINAPI HTMLAreaElement_put_coords(IHTMLAreaElement *iface, BSTR v)
102 {
103     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
104     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
105     return E_NOTIMPL;
106 }
107 
108 static HRESULT WINAPI HTMLAreaElement_get_coords(IHTMLAreaElement *iface, BSTR *p)
109 {
110     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
111     FIXME("(%p)->(%p)\n", This, p);
112     return E_NOTIMPL;
113 }
114 
115 static HRESULT WINAPI HTMLAreaElement_put_href(IHTMLAreaElement *iface, BSTR v)
116 {
117     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
118     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
119     return E_NOTIMPL;
120 }
121 
122 static HRESULT WINAPI HTMLAreaElement_get_href(IHTMLAreaElement *iface, BSTR *p)
123 {
124     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
125     FIXME("(%p)->(%p)\n", This, p);
126     return E_NOTIMPL;
127 }
128 
129 static HRESULT WINAPI HTMLAreaElement_put_target(IHTMLAreaElement *iface, BSTR v)
130 {
131     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
132     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
133     return E_NOTIMPL;
134 }
135 
136 static HRESULT WINAPI HTMLAreaElement_get_target(IHTMLAreaElement *iface, BSTR *p)
137 {
138     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
139     FIXME("(%p)->(%p)\n", This, p);
140     return E_NOTIMPL;
141 }
142 
143 static HRESULT WINAPI HTMLAreaElement_put_alt(IHTMLAreaElement *iface, BSTR v)
144 {
145     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
146     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
147     return E_NOTIMPL;
148 }
149 
150 static HRESULT WINAPI HTMLAreaElement_get_alt(IHTMLAreaElement *iface, BSTR *p)
151 {
152     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
153     FIXME("(%p)->(%p)\n", This, p);
154     return E_NOTIMPL;
155 }
156 
157 static HRESULT WINAPI HTMLAreaElement_put_noHref(IHTMLAreaElement *iface, VARIANT_BOOL v)
158 {
159     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
160     FIXME("(%p)->(%i)\n", This, v);
161     return E_NOTIMPL;
162 }
163 
164 static HRESULT WINAPI HTMLAreaElement_get_noHref(IHTMLAreaElement *iface, VARIANT_BOOL *p)
165 {
166     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
167     FIXME("(%p)->(%p)\n", This, p);
168     return E_NOTIMPL;
169 }
170 
171 static HRESULT WINAPI HTMLAreaElement_put_host(IHTMLAreaElement *iface, BSTR v)
172 {
173     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
174     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
175     return E_NOTIMPL;
176 }
177 
178 static HRESULT WINAPI HTMLAreaElement_get_host(IHTMLAreaElement *iface, BSTR *p)
179 {
180     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
181     FIXME("(%p)->(%p)\n", This, p);
182     return E_NOTIMPL;
183 }
184 
185 static HRESULT WINAPI HTMLAreaElement_put_hostname(IHTMLAreaElement *iface, BSTR v)
186 {
187     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
188     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
189     return E_NOTIMPL;
190 }
191 
192 static HRESULT WINAPI HTMLAreaElement_get_hostname(IHTMLAreaElement *iface, BSTR *p)
193 {
194     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
195     FIXME("(%p)->(%p)\n", This, p);
196     return E_NOTIMPL;
197 }
198 
199 static HRESULT WINAPI HTMLAreaElement_put_pathname(IHTMLAreaElement *iface, BSTR v)
200 {
201     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
202     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
203     return E_NOTIMPL;
204 }
205 
206 static HRESULT WINAPI HTMLAreaElement_get_pathname(IHTMLAreaElement *iface, BSTR *p)
207 {
208     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
209     FIXME("(%p)->(%p)\n", This, p);
210     return E_NOTIMPL;
211 }
212 
213 static HRESULT WINAPI HTMLAreaElement_put_port(IHTMLAreaElement *iface, BSTR v)
214 {
215     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
216     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
217     return E_NOTIMPL;
218 }
219 
220 static HRESULT WINAPI HTMLAreaElement_get_port(IHTMLAreaElement *iface, BSTR *p)
221 {
222     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
223     FIXME("(%p)->(%p)\n", This, p);
224     return E_NOTIMPL;
225 }
226 
227 static HRESULT WINAPI HTMLAreaElement_put_protocol(IHTMLAreaElement *iface, BSTR v)
228 {
229     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
230     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
231     return E_NOTIMPL;
232 }
233 
234 static HRESULT WINAPI HTMLAreaElement_get_protocol(IHTMLAreaElement *iface, BSTR *p)
235 {
236     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
237     FIXME("(%p)->(%p)\n", This, p);
238     return E_NOTIMPL;
239 }
240 
241 static HRESULT WINAPI HTMLAreaElement_put_search(IHTMLAreaElement *iface, BSTR v)
242 {
243     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
244     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
245     return E_NOTIMPL;
246 }
247 
248 static HRESULT WINAPI HTMLAreaElement_get_search(IHTMLAreaElement *iface, BSTR *p)
249 {
250     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
251     FIXME("(%p)->(%p)\n", This, p);
252     return E_NOTIMPL;
253 }
254 
255 static HRESULT WINAPI HTMLAreaElement_put_hash(IHTMLAreaElement *iface, BSTR v)
256 {
257     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
258     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
259     return E_NOTIMPL;
260 }
261 
262 static HRESULT WINAPI HTMLAreaElement_get_hash(IHTMLAreaElement *iface, BSTR *p)
263 {
264     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
265     FIXME("(%p)->(%p)\n", This, p);
266     return E_NOTIMPL;
267 }
268 
269 static HRESULT WINAPI HTMLAreaElement_put_onblur(IHTMLAreaElement *iface, VARIANT v)
270 {
271     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
272     FIXME("(%p)->(%p)\n", This, &v);
273     return E_NOTIMPL;
274 }
275 
276 static HRESULT WINAPI HTMLAreaElement_get_onblur(IHTMLAreaElement *iface, VARIANT *p)
277 {
278     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
279     FIXME("(%p)->(%p)\n", This, p);
280     return E_NOTIMPL;
281 }
282 
283 static HRESULT WINAPI HTMLAreaElement_put_onfocus(IHTMLAreaElement *iface, VARIANT v)
284 {
285     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
286     FIXME("(%p)->(%p)\n", This, &v);
287     return E_NOTIMPL;
288 }
289 
290 static HRESULT WINAPI HTMLAreaElement_get_onfocus(IHTMLAreaElement *iface, VARIANT *p)
291 {
292     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
293     FIXME("(%p)->(%p)\n", This, p);
294     return E_NOTIMPL;
295 }
296 
297 static HRESULT WINAPI HTMLAreaElement_put_tabIndex(IHTMLAreaElement *iface, short v)
298 {
299     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
300     FIXME("(%p)->(%i)\n", This, v);
301     return E_NOTIMPL;
302 }
303 
304 static HRESULT WINAPI HTMLAreaElement_get_tabIndex(IHTMLAreaElement *iface, short *p)
305 {
306     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
307     FIXME("(%p)->(%p)\n", This, p);
308     return E_NOTIMPL;
309 }
310 
311 static HRESULT WINAPI HTMLAreaElement_focus(IHTMLAreaElement *iface)
312 {
313     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
314     FIXME("(%p)\n", This);
315     return E_NOTIMPL;
316 }
317 
318 static HRESULT WINAPI HTMLAreaElement_blur(IHTMLAreaElement *iface)
319 {
320     HTMLAreaElement *This = impl_from_IHTMLAreaElement(iface);
321     FIXME("(%p)\n", This);
322     return E_NOTIMPL;
323 }
324 
325 static const IHTMLAreaElementVtbl HTMLAreaElementVtbl = {
326     HTMLAreaElement_QueryInterface,
327     HTMLAreaElement_AddRef,
328     HTMLAreaElement_Release,
329     HTMLAreaElement_GetTypeInfoCount,
330     HTMLAreaElement_GetTypeInfo,
331     HTMLAreaElement_GetIDsOfNames,
332     HTMLAreaElement_Invoke,
333     HTMLAreaElement_put_shape,
334     HTMLAreaElement_get_shape,
335     HTMLAreaElement_put_coords,
336     HTMLAreaElement_get_coords,
337     HTMLAreaElement_put_href,
338     HTMLAreaElement_get_href,
339     HTMLAreaElement_put_target,
340     HTMLAreaElement_get_target,
341     HTMLAreaElement_put_alt,
342     HTMLAreaElement_get_alt,
343     HTMLAreaElement_put_noHref,
344     HTMLAreaElement_get_noHref,
345     HTMLAreaElement_put_host,
346     HTMLAreaElement_get_host,
347     HTMLAreaElement_put_hostname,
348     HTMLAreaElement_get_hostname,
349     HTMLAreaElement_put_pathname,
350     HTMLAreaElement_get_pathname,
351     HTMLAreaElement_put_port,
352     HTMLAreaElement_get_port,
353     HTMLAreaElement_put_protocol,
354     HTMLAreaElement_get_protocol,
355     HTMLAreaElement_put_search,
356     HTMLAreaElement_get_search,
357     HTMLAreaElement_put_hash,
358     HTMLAreaElement_get_hash,
359     HTMLAreaElement_put_onblur,
360     HTMLAreaElement_get_onblur,
361     HTMLAreaElement_put_onfocus,
362     HTMLAreaElement_get_onfocus,
363     HTMLAreaElement_put_tabIndex,
364     HTMLAreaElement_get_tabIndex,
365     HTMLAreaElement_focus,
366     HTMLAreaElement_blur
367 };
368 
369 static inline HTMLAreaElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
370 {
371     return CONTAINING_RECORD(iface, HTMLAreaElement, element.node);
372 }
373 
374 static HRESULT HTMLAreaElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
375 {
376     HTMLAreaElement *This = impl_from_HTMLDOMNode(iface);
377 
378     *ppv = NULL;
379 
380     if(IsEqualGUID(&IID_IHTMLAreaElement, riid)) {
381         TRACE("(%p)->(IID_IHTMLAreaElement %p)\n", This, ppv);
382         *ppv = &This->IHTMLAreaElement_iface;
383     }else {
384         return HTMLElement_QI(&This->element.node, riid, ppv);
385     }
386 
387     IUnknown_AddRef((IUnknown*)*ppv);
388     return S_OK;
389 }
390 
391 static HRESULT HTMLAreaElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *event, BOOL *prevent_default)
392 {
393     HTMLAreaElement *This = impl_from_HTMLDOMNode(iface);
394     nsAString href_str, target_str;
395     nsresult nsres;
396 
397     if(eid == EVENTID_CLICK) {
398         nsAString_Init(&href_str, NULL);
399         nsres = nsIDOMHTMLAreaElement_GetHref(This->nsarea, &href_str);
400         if (NS_FAILED(nsres)) {
401             ERR("Could not get area href: %08x\n", nsres);
402             goto fallback;
403         }
404 
405         nsAString_Init(&target_str, NULL);
406         nsres = nsIDOMHTMLAreaElement_GetTarget(This->nsarea, &target_str);
407         if (NS_FAILED(nsres)) {
408             ERR("Could not get area target: %08x\n", nsres);
409             goto fallback;
410         }
411 
412         return handle_link_click_event(&This->element, &href_str, &target_str, event, prevent_default);
413 
414 fallback:
415         nsAString_Finish(&href_str);
416         nsAString_Finish(&target_str);
417     }
418 
419     return HTMLElement_handle_event(&This->element.node, eid, event, prevent_default);
420 }
421 
422 static const NodeImplVtbl HTMLAreaElementImplVtbl = {
423     HTMLAreaElement_QI,
424     HTMLElement_destructor,
425     HTMLElement_cpc,
426     HTMLElement_clone,
427     HTMLAreaElement_handle_event,
428     HTMLElement_get_attr_col
429 };
430 
431 static const tid_t HTMLAreaElement_iface_tids[] = {
432     HTMLELEMENT_TIDS,
433     IHTMLAreaElement_tid,
434     0
435 };
436 static dispex_static_data_t HTMLAreaElement_dispex = {
437     NULL,
438     DispHTMLAreaElement_tid,
439     NULL,
440     HTMLAreaElement_iface_tids
441 };
442 
443 HRESULT HTMLAreaElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
444 {
445     HTMLAreaElement *ret;
446     nsresult nsres;
447 
448     ret = heap_alloc_zero(sizeof(HTMLAreaElement));
449     if(!ret)
450         return E_OUTOFMEMORY;
451 
452     ret->IHTMLAreaElement_iface.lpVtbl = &HTMLAreaElementVtbl;
453     ret->element.node.vtbl = &HTMLAreaElementImplVtbl;
454 
455     HTMLElement_Init(&ret->element, doc, nselem, &HTMLAreaElement_dispex);
456 
457     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLAreaElement, (void**)&ret->nsarea);
458     assert(nsres == NS_OK);
459 
460     *elem = &ret->element;
461     return S_OK;
462 }
463