xref: /reactos/dll/win32/mshtml/htmllink.c (revision 8a978a17)
1  /*
2  * Copyright 2012 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     IHTMLLinkElement IHTMLLinkElement_iface;
24 
25     nsIDOMHTMLLinkElement *nslink;
26 } HTMLLinkElement;
27 
28 static inline HTMLLinkElement *impl_from_IHTMLLinkElement(IHTMLLinkElement *iface)
29 {
30     return CONTAINING_RECORD(iface, HTMLLinkElement, IHTMLLinkElement_iface);
31 }
32 
33 static HRESULT WINAPI HTMLLinkElement_QueryInterface(IHTMLLinkElement *iface,
34                                                          REFIID riid, void **ppv)
35 {
36     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
37 
38     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
39 }
40 
41 static ULONG WINAPI HTMLLinkElement_AddRef(IHTMLLinkElement *iface)
42 {
43     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
44 
45     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
46 }
47 
48 static ULONG WINAPI HTMLLinkElement_Release(IHTMLLinkElement *iface)
49 {
50     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
51 
52     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
53 }
54 
55 static HRESULT WINAPI HTMLLinkElement_GetTypeInfoCount(IHTMLLinkElement *iface, UINT *pctinfo)
56 {
57     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
58 
59     return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
60 }
61 
62 static HRESULT WINAPI HTMLLinkElement_GetTypeInfo(IHTMLLinkElement *iface, UINT iTInfo,
63                                               LCID lcid, ITypeInfo **ppTInfo)
64 {
65     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
66 
67     return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
68             ppTInfo);
69 }
70 
71 static HRESULT WINAPI HTMLLinkElement_GetIDsOfNames(IHTMLLinkElement *iface, REFIID riid,
72                                                 LPOLESTR *rgszNames, UINT cNames,
73                                                 LCID lcid, DISPID *rgDispId)
74 {
75     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
76 
77     return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
78             cNames, lcid, rgDispId);
79 }
80 
81 static HRESULT WINAPI HTMLLinkElement_Invoke(IHTMLLinkElement *iface, DISPID dispIdMember,
82                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
83                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
84 {
85     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
86 
87     return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
88             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
89 }
90 
91 static HRESULT WINAPI HTMLLinkElement_put_href(IHTMLLinkElement *iface, BSTR v)
92 {
93     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
94     nsAString href_str;
95     nsresult nsres;
96 
97     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
98 
99     nsAString_InitDepend(&href_str, v);
100     nsres = nsIDOMHTMLLinkElement_SetHref(This->nslink, &href_str);
101     nsAString_Finish(&href_str);
102 
103     return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
104 }
105 
106 static HRESULT WINAPI HTMLLinkElement_get_href(IHTMLLinkElement *iface, BSTR *p)
107 {
108     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
109     nsAString href_str;
110     nsresult nsres;
111 
112     TRACE("(%p)->(%p)\n", This, p);
113 
114     nsAString_Init(&href_str, NULL);
115     nsres = nsIDOMHTMLLinkElement_GetHref(This->nslink, &href_str);
116     return return_nsstr(nsres, &href_str, p);
117 }
118 
119 static HRESULT WINAPI HTMLLinkElement_put_rel(IHTMLLinkElement *iface, BSTR v)
120 {
121     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
122     nsAString rel_str;
123     nsresult nsres;
124 
125     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
126 
127     nsAString_InitDepend(&rel_str, v);
128     nsres = nsIDOMHTMLLinkElement_SetRel(This->nslink, &rel_str);
129     nsAString_Finish(&rel_str);
130 
131     return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
132 }
133 
134 static HRESULT WINAPI HTMLLinkElement_get_rel(IHTMLLinkElement *iface, BSTR *p)
135 {
136     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
137     nsAString rel_str;
138     nsresult nsres;
139 
140     TRACE("(%p)->(%p)\n", This, p);
141 
142     nsAString_Init(&rel_str, NULL);
143     nsres = nsIDOMHTMLLinkElement_GetRel(This->nslink, &rel_str);
144     return return_nsstr(nsres, &rel_str, p);
145 }
146 
147 static HRESULT WINAPI HTMLLinkElement_put_rev(IHTMLLinkElement *iface, BSTR v)
148 {
149     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
150     nsAString nsstr;
151     nsresult nsres;
152 
153     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
154 
155     nsAString_InitDepend(&nsstr, v);
156     nsres = nsIDOMHTMLLinkElement_SetRev(This->nslink, &nsstr);
157     nsAString_Finish(&nsstr);
158     if(NS_FAILED(nsres)) {
159         ERR("SetRev failed: %08x\n", nsres);
160         return E_FAIL;
161     }
162 
163     return S_OK;
164 }
165 
166 static HRESULT WINAPI HTMLLinkElement_get_rev(IHTMLLinkElement *iface, BSTR *p)
167 {
168     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
169     nsAString nsstr;
170     nsresult nsres;
171 
172     TRACE("(%p)->(%p)\n", This, p);
173 
174     nsAString_Init(&nsstr, NULL);
175     nsres = nsIDOMHTMLLinkElement_GetRev(This->nslink, &nsstr);
176     return return_nsstr(nsres, &nsstr, p);
177 }
178 
179 static HRESULT WINAPI HTMLLinkElement_put_type(IHTMLLinkElement *iface, BSTR v)
180 {
181     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
182     nsAString type_str;
183     nsresult nsres;
184 
185     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
186 
187     nsAString_InitDepend(&type_str, v);
188     nsres = nsIDOMHTMLLinkElement_SetType(This->nslink, &type_str);
189     nsAString_Finish(&type_str);
190 
191     return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
192 }
193 
194 static HRESULT WINAPI HTMLLinkElement_get_type(IHTMLLinkElement *iface, BSTR *p)
195 {
196     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
197     nsAString type_str;
198     nsresult nsres;
199 
200     TRACE("(%p)->(%p)\n", This, p);
201 
202     nsAString_Init(&type_str, NULL);
203     nsres = nsIDOMHTMLLinkElement_GetType(This->nslink, &type_str);
204     return return_nsstr(nsres, &type_str, p);
205 }
206 
207 static HRESULT WINAPI HTMLLinkElement_get_readyState(IHTMLLinkElement *iface, BSTR *p)
208 {
209     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
210     FIXME("(%p)->(%p)\n", This, p);
211     return E_NOTIMPL;
212 }
213 
214 static HRESULT WINAPI HTMLLinkElement_put_onreadystatechange(IHTMLLinkElement *iface, VARIANT v)
215 {
216     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
217     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
218     return E_NOTIMPL;
219 }
220 
221 static HRESULT WINAPI HTMLLinkElement_get_onreadystatechange(IHTMLLinkElement *iface, VARIANT *p)
222 {
223     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
224     FIXME("(%p)->(%p)\n", This, p);
225     return E_NOTIMPL;
226 }
227 
228 static HRESULT WINAPI HTMLLinkElement_put_onload(IHTMLLinkElement *iface, VARIANT v)
229 {
230     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
231     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
232     return E_NOTIMPL;
233 }
234 
235 static HRESULT WINAPI HTMLLinkElement_get_onload(IHTMLLinkElement *iface, VARIANT *p)
236 {
237     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
238     FIXME("(%p)->(%p)\n", This, p);
239     return E_NOTIMPL;
240 }
241 
242 static HRESULT WINAPI HTMLLinkElement_put_onerror(IHTMLLinkElement *iface, VARIANT v)
243 {
244     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
245     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
246     return E_NOTIMPL;
247 }
248 
249 static HRESULT WINAPI HTMLLinkElement_get_onerror(IHTMLLinkElement *iface, VARIANT *p)
250 {
251     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
252     FIXME("(%p)->(%p)\n", This, p);
253     return E_NOTIMPL;
254 }
255 
256 static HRESULT WINAPI HTMLLinkElement_get_styleSheet(IHTMLLinkElement *iface, IHTMLStyleSheet **p)
257 {
258     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
259     FIXME("(%p)->(%p)\n", This, p);
260     return E_NOTIMPL;
261 }
262 
263 static HRESULT WINAPI HTMLLinkElement_put_disabled(IHTMLLinkElement *iface, VARIANT_BOOL v)
264 {
265     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
266     nsresult nsres;
267 
268     TRACE("(%p)->(%x)\n", This, v);
269 
270     nsres = nsIDOMHTMLLinkElement_SetDisabled(This->nslink, !!v);
271     return SUCCEEDED(nsres) ? S_OK : E_FAIL;
272 }
273 
274 static HRESULT WINAPI HTMLLinkElement_get_disabled(IHTMLLinkElement *iface, VARIANT_BOOL *p)
275 {
276     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
277     cpp_bool ret;
278     nsresult nsres;
279 
280     TRACE("(%p)->(%p)\n", This, p);
281 
282     nsres = nsIDOMHTMLLinkElement_GetDisabled(This->nslink, &ret);
283     if(NS_FAILED(nsres))
284         return E_FAIL;
285 
286     *p = ret ? VARIANT_TRUE : VARIANT_FALSE;
287     return S_OK;
288 }
289 
290 static HRESULT WINAPI HTMLLinkElement_put_media(IHTMLLinkElement *iface, BSTR v)
291 {
292     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
293     nsresult nsres;
294     nsAString str;
295 
296     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
297 
298     nsAString_InitDepend(&str, v);
299 
300     nsres = nsIDOMHTMLLinkElement_SetMedia(This->nslink, &str);
301     nsAString_Finish(&str);
302 
303     if(NS_FAILED(nsres)) {
304         ERR("Set Media(%s) failed: %08x\n", debugstr_w(v), nsres);
305         return E_FAIL;
306     }
307     return S_OK;
308 }
309 
310 static HRESULT WINAPI HTMLLinkElement_get_media(IHTMLLinkElement *iface, BSTR *p)
311 {
312     HTMLLinkElement *This = impl_from_IHTMLLinkElement(iface);
313     nsresult nsres;
314     nsAString str;
315 
316     TRACE("(%p)->(%p)\n", This, p);
317 
318     nsAString_Init(&str, NULL);
319     nsres = nsIDOMHTMLLinkElement_GetMedia(This->nslink, &str);
320 
321     return return_nsstr(nsres, &str, p);
322 }
323 
324 static const IHTMLLinkElementVtbl HTMLLinkElementVtbl = {
325     HTMLLinkElement_QueryInterface,
326     HTMLLinkElement_AddRef,
327     HTMLLinkElement_Release,
328     HTMLLinkElement_GetTypeInfoCount,
329     HTMLLinkElement_GetTypeInfo,
330     HTMLLinkElement_GetIDsOfNames,
331     HTMLLinkElement_Invoke,
332     HTMLLinkElement_put_href,
333     HTMLLinkElement_get_href,
334     HTMLLinkElement_put_rel,
335     HTMLLinkElement_get_rel,
336     HTMLLinkElement_put_rev,
337     HTMLLinkElement_get_rev,
338     HTMLLinkElement_put_type,
339     HTMLLinkElement_get_type,
340     HTMLLinkElement_get_readyState,
341     HTMLLinkElement_put_onreadystatechange,
342     HTMLLinkElement_get_onreadystatechange,
343     HTMLLinkElement_put_onload,
344     HTMLLinkElement_get_onload,
345     HTMLLinkElement_put_onerror,
346     HTMLLinkElement_get_onerror,
347     HTMLLinkElement_get_styleSheet,
348     HTMLLinkElement_put_disabled,
349     HTMLLinkElement_get_disabled,
350     HTMLLinkElement_put_media,
351     HTMLLinkElement_get_media
352 };
353 
354 static inline HTMLLinkElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
355 {
356     return CONTAINING_RECORD(iface, HTMLLinkElement, element.node);
357 }
358 
359 static HRESULT HTMLLinkElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
360 {
361     HTMLLinkElement *This = impl_from_HTMLDOMNode(iface);
362 
363     if(IsEqualGUID(&IID_IHTMLLinkElement, riid)) {
364         TRACE("(%p)->(IID_IHTMLLinkElement %p)\n", This, ppv);
365         *ppv = &This->IHTMLLinkElement_iface;
366     }else {
367         return HTMLElement_QI(&This->element.node, riid, ppv);
368     }
369 
370     IUnknown_AddRef((IUnknown*)*ppv);
371     return S_OK;
372 }
373 
374 static HRESULT HTMLLinkElementImpl_put_disabled(HTMLDOMNode *iface, VARIANT_BOOL v)
375 {
376     HTMLLinkElement *This = impl_from_HTMLDOMNode(iface);
377     return IHTMLLinkElement_put_disabled(&This->IHTMLLinkElement_iface, v);
378 }
379 
380 static HRESULT HTMLLinkElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BOOL *p)
381 {
382     HTMLLinkElement *This = impl_from_HTMLDOMNode(iface);
383     return IHTMLLinkElement_get_disabled(&This->IHTMLLinkElement_iface, p);
384 }
385 
386 static void HTMLLinkElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
387 {
388     HTMLLinkElement *This = impl_from_HTMLDOMNode(iface);
389 
390     if(This->nslink)
391         note_cc_edge((nsISupports*)This->nslink, "This->nslink", cb);
392 }
393 
394 static void HTMLLinkElement_unlink(HTMLDOMNode *iface)
395 {
396     HTMLLinkElement *This = impl_from_HTMLDOMNode(iface);
397 
398     if(This->nslink) {
399         nsIDOMHTMLLinkElement *nslink = This->nslink;
400 
401         This->nslink = NULL;
402         nsIDOMHTMLLinkElement_Release(nslink);
403     }
404 }
405 static const NodeImplVtbl HTMLLinkElementImplVtbl = {
406     HTMLLinkElement_QI,
407     HTMLElement_destructor,
408     HTMLElement_cpc,
409     HTMLElement_clone,
410     HTMLElement_handle_event,
411     HTMLElement_get_attr_col,
412     NULL,
413     NULL,
414     HTMLLinkElementImpl_put_disabled,
415     HTMLLinkElementImpl_get_disabled,
416     NULL,
417     NULL,
418     NULL,
419     NULL,
420     NULL,
421     HTMLLinkElement_traverse,
422     HTMLLinkElement_unlink
423 };
424 
425 static const tid_t HTMLLinkElement_iface_tids[] = {
426     HTMLELEMENT_TIDS,
427     IHTMLLinkElement_tid,
428     0
429 };
430 static dispex_static_data_t HTMLLinkElement_dispex = {
431     NULL,
432     DispHTMLLinkElement_tid,
433     NULL,
434     HTMLLinkElement_iface_tids
435 };
436 
437 HRESULT HTMLLinkElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
438 {
439     HTMLLinkElement *ret;
440     nsresult nsres;
441 
442     ret = heap_alloc_zero(sizeof(*ret));
443     if(!ret)
444         return E_OUTOFMEMORY;
445 
446     ret->IHTMLLinkElement_iface.lpVtbl = &HTMLLinkElementVtbl;
447     ret->element.node.vtbl = &HTMLLinkElementImplVtbl;
448 
449     HTMLElement_Init(&ret->element, doc, nselem, &HTMLLinkElement_dispex);
450 
451     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLLinkElement, (void**)&ret->nslink);
452     assert(nsres == NS_OK);
453 
454     *elem = &ret->element;
455     return S_OK;
456 }
457