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
impl_from_IHTMLLinkElement(IHTMLLinkElement * iface)28 static inline HTMLLinkElement *impl_from_IHTMLLinkElement(IHTMLLinkElement *iface)
29 {
30 return CONTAINING_RECORD(iface, HTMLLinkElement, IHTMLLinkElement_iface);
31 }
32
HTMLLinkElement_QueryInterface(IHTMLLinkElement * iface,REFIID riid,void ** ppv)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
HTMLLinkElement_AddRef(IHTMLLinkElement * iface)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
HTMLLinkElement_Release(IHTMLLinkElement * iface)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
HTMLLinkElement_GetTypeInfoCount(IHTMLLinkElement * iface,UINT * pctinfo)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
HTMLLinkElement_GetTypeInfo(IHTMLLinkElement * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)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
HTMLLinkElement_GetIDsOfNames(IHTMLLinkElement * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)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
HTMLLinkElement_Invoke(IHTMLLinkElement * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)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
HTMLLinkElement_put_href(IHTMLLinkElement * iface,BSTR v)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
HTMLLinkElement_get_href(IHTMLLinkElement * iface,BSTR * p)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
HTMLLinkElement_put_rel(IHTMLLinkElement * iface,BSTR v)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
HTMLLinkElement_get_rel(IHTMLLinkElement * iface,BSTR * p)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
HTMLLinkElement_put_rev(IHTMLLinkElement * iface,BSTR v)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
HTMLLinkElement_get_rev(IHTMLLinkElement * iface,BSTR * p)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
HTMLLinkElement_put_type(IHTMLLinkElement * iface,BSTR v)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
HTMLLinkElement_get_type(IHTMLLinkElement * iface,BSTR * p)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
HTMLLinkElement_get_readyState(IHTMLLinkElement * iface,BSTR * p)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
HTMLLinkElement_put_onreadystatechange(IHTMLLinkElement * iface,VARIANT v)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
HTMLLinkElement_get_onreadystatechange(IHTMLLinkElement * iface,VARIANT * p)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
HTMLLinkElement_put_onload(IHTMLLinkElement * iface,VARIANT v)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
HTMLLinkElement_get_onload(IHTMLLinkElement * iface,VARIANT * p)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
HTMLLinkElement_put_onerror(IHTMLLinkElement * iface,VARIANT v)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
HTMLLinkElement_get_onerror(IHTMLLinkElement * iface,VARIANT * p)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
HTMLLinkElement_get_styleSheet(IHTMLLinkElement * iface,IHTMLStyleSheet ** p)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
HTMLLinkElement_put_disabled(IHTMLLinkElement * iface,VARIANT_BOOL v)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
HTMLLinkElement_get_disabled(IHTMLLinkElement * iface,VARIANT_BOOL * p)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
HTMLLinkElement_put_media(IHTMLLinkElement * iface,BSTR v)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
HTMLLinkElement_get_media(IHTMLLinkElement * iface,BSTR * p)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
impl_from_HTMLDOMNode(HTMLDOMNode * iface)354 static inline HTMLLinkElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
355 {
356 return CONTAINING_RECORD(iface, HTMLLinkElement, element.node);
357 }
358
HTMLLinkElement_QI(HTMLDOMNode * iface,REFIID riid,void ** ppv)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
HTMLLinkElementImpl_put_disabled(HTMLDOMNode * iface,VARIANT_BOOL v)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
HTMLLinkElementImpl_get_disabled(HTMLDOMNode * iface,VARIANT_BOOL * p)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
HTMLLinkElement_traverse(HTMLDOMNode * iface,nsCycleCollectionTraversalCallback * cb)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
HTMLLinkElement_unlink(HTMLDOMNode * iface)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
HTMLLinkElement_Create(HTMLDocumentNode * doc,nsIDOMHTMLElement * nselem,HTMLElement ** elem)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