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