xref: /reactos/dll/win32/mshtml/htmlstyleelem.c (revision 1734f297)
1 /*
2  * Copyright 2010 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     IHTMLStyleElement IHTMLStyleElement_iface;
25 
26     nsIDOMHTMLStyleElement *nsstyle;
27     IHTMLStyleSheet *style_sheet;
28 } HTMLStyleElement;
29 
30 static inline HTMLStyleElement *impl_from_IHTMLStyleElement(IHTMLStyleElement *iface)
31 {
32     return CONTAINING_RECORD(iface, HTMLStyleElement, IHTMLStyleElement_iface);
33 }
34 
35 static HRESULT WINAPI HTMLStyleElement_QueryInterface(IHTMLStyleElement *iface,
36         REFIID riid, void **ppv)
37 {
38     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
39 
40     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
41 }
42 
43 static ULONG WINAPI HTMLStyleElement_AddRef(IHTMLStyleElement *iface)
44 {
45     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
46 
47     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
48 }
49 
50 static ULONG WINAPI HTMLStyleElement_Release(IHTMLStyleElement *iface)
51 {
52     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
53 
54     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
55 }
56 
57 static HRESULT WINAPI HTMLStyleElement_GetTypeInfoCount(IHTMLStyleElement *iface, UINT *pctinfo)
58 {
59     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
60     return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
61 }
62 
63 static HRESULT WINAPI HTMLStyleElement_GetTypeInfo(IHTMLStyleElement *iface, UINT iTInfo,
64         LCID lcid, ITypeInfo **ppTInfo)
65 {
66     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
67     return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
68             ppTInfo);
69 }
70 
71 static HRESULT WINAPI HTMLStyleElement_GetIDsOfNames(IHTMLStyleElement *iface, REFIID riid,
72         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
73 {
74     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
75     return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
76             cNames, lcid, rgDispId);
77 }
78 
79 static HRESULT WINAPI HTMLStyleElement_Invoke(IHTMLStyleElement *iface, DISPID dispIdMember,
80         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
81         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
82 {
83     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
84     return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
85             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
86 }
87 
88 static HRESULT WINAPI HTMLStyleElement_put_type(IHTMLStyleElement *iface, BSTR v)
89 {
90     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
91     nsAString type_str;
92     nsresult nsres;
93 
94     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
95 
96     nsAString_InitDepend(&type_str, v);
97     nsres = nsIDOMHTMLStyleElement_SetType(This->nsstyle, &type_str);
98     nsAString_Finish(&type_str);
99     if(NS_FAILED(nsres)) {
100         ERR("SetType failed: %08x\n", nsres);
101         return E_FAIL;
102     }
103 
104     return S_OK;
105 }
106 
107 static HRESULT WINAPI HTMLStyleElement_get_type(IHTMLStyleElement *iface, BSTR *p)
108 {
109     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
110     nsAString nsstr;
111     nsresult nsres;
112 
113     TRACE("(%p)->(%p)\n", This, p);
114 
115     nsAString_Init(&nsstr, NULL);
116     nsres = nsIDOMHTMLStyleElement_GetType(This->nsstyle, &nsstr);
117     return return_nsstr(nsres, &nsstr, p);
118 }
119 
120 static HRESULT WINAPI HTMLStyleElement_get_readyState(IHTMLStyleElement *iface, BSTR *p)
121 {
122     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
123     FIXME("(%p)->(%p)\n", This, p);
124     return E_NOTIMPL;
125 }
126 
127 static HRESULT WINAPI HTMLStyleElement_put_onreadystatechange(IHTMLStyleElement *iface, VARIANT v)
128 {
129     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
130     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
131     return E_NOTIMPL;
132 }
133 
134 static HRESULT WINAPI HTMLStyleElement_get_onreadystatechange(IHTMLStyleElement *iface, VARIANT *p)
135 {
136     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
137     FIXME("(%p)->(%p)\n", This, p);
138     return E_NOTIMPL;
139 }
140 
141 static HRESULT WINAPI HTMLStyleElement_put_onload(IHTMLStyleElement *iface, VARIANT v)
142 {
143     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
144     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
145     return E_NOTIMPL;
146 }
147 
148 static HRESULT WINAPI HTMLStyleElement_get_onload(IHTMLStyleElement *iface, VARIANT *p)
149 {
150     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
151     FIXME("(%p)->(%p)\n", This, p);
152     return E_NOTIMPL;
153 }
154 
155 static HRESULT WINAPI HTMLStyleElement_put_onerror(IHTMLStyleElement *iface, VARIANT v)
156 {
157     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
158     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
159     return E_NOTIMPL;
160 }
161 
162 static HRESULT WINAPI HTMLStyleElement_get_onerror(IHTMLStyleElement *iface, VARIANT *p)
163 {
164     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
165     FIXME("(%p)->(%p)\n", This, p);
166     return E_NOTIMPL;
167 }
168 
169 static HRESULT WINAPI HTMLStyleElement_get_styleSheet(IHTMLStyleElement *iface, IHTMLStyleSheet **p)
170 {
171     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
172 
173     TRACE("(%p)->(%p)\n", This, p);
174 
175     if(!This->nsstyle)
176         return E_FAIL;
177 
178     if(!This->style_sheet) {
179         nsIDOMStyleSheet *ss;
180         nsresult nsres;
181 
182         nsres = nsIDOMHTMLStyleElement_GetDOMStyleSheet(This->nsstyle, &ss);
183         assert(nsres == NS_OK);
184 
185         if(ss) {
186             This->style_sheet = HTMLStyleSheet_Create(ss);
187             nsIDOMStyleSheet_Release(ss);
188             if(!This->style_sheet)
189                 return E_OUTOFMEMORY;
190         }
191     }
192 
193     if(This->style_sheet)
194         IHTMLStyleSheet_AddRef(This->style_sheet);
195     *p = This->style_sheet;
196     return S_OK;
197 }
198 
199 static HRESULT WINAPI HTMLStyleElement_put_disabled(IHTMLStyleElement *iface, VARIANT_BOOL v)
200 {
201     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
202     FIXME("(%p)->(%x)\n", This, v);
203     return E_NOTIMPL;
204 }
205 
206 static HRESULT WINAPI HTMLStyleElement_get_disabled(IHTMLStyleElement *iface, VARIANT_BOOL *p)
207 {
208     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
209     FIXME("(%p)->(%p)\n", This, p);
210     return E_NOTIMPL;
211 }
212 
213 static HRESULT WINAPI HTMLStyleElement_put_media(IHTMLStyleElement *iface, BSTR v)
214 {
215     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
216     nsAString media_str;
217     nsresult nsres;
218 
219     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
220 
221     nsAString_InitDepend(&media_str, v);
222     nsres = nsIDOMHTMLStyleElement_SetMedia(This->nsstyle, &media_str);
223     nsAString_Finish(&media_str);
224     if(NS_FAILED(nsres)) {
225         ERR("SetMedia failed: %08x\n", nsres);
226         return E_FAIL;
227     }
228 
229     return S_OK;
230 }
231 
232 static HRESULT WINAPI HTMLStyleElement_get_media(IHTMLStyleElement *iface, BSTR *p)
233 {
234     HTMLStyleElement *This = impl_from_IHTMLStyleElement(iface);
235     nsAString nsstr;
236     nsresult nsres;
237 
238     TRACE("(%p)->(%p)\n", This, p);
239 
240     nsAString_Init(&nsstr, NULL);
241     nsres = nsIDOMHTMLStyleElement_GetMedia(This->nsstyle, &nsstr);
242     return return_nsstr(nsres, &nsstr, p);
243 }
244 
245 static const IHTMLStyleElementVtbl HTMLStyleElementVtbl = {
246     HTMLStyleElement_QueryInterface,
247     HTMLStyleElement_AddRef,
248     HTMLStyleElement_Release,
249     HTMLStyleElement_GetTypeInfoCount,
250     HTMLStyleElement_GetTypeInfo,
251     HTMLStyleElement_GetIDsOfNames,
252     HTMLStyleElement_Invoke,
253     HTMLStyleElement_put_type,
254     HTMLStyleElement_get_type,
255     HTMLStyleElement_get_readyState,
256     HTMLStyleElement_put_onreadystatechange,
257     HTMLStyleElement_get_onreadystatechange,
258     HTMLStyleElement_put_onload,
259     HTMLStyleElement_get_onload,
260     HTMLStyleElement_put_onerror,
261     HTMLStyleElement_get_onerror,
262     HTMLStyleElement_get_styleSheet,
263     HTMLStyleElement_put_disabled,
264     HTMLStyleElement_get_disabled,
265     HTMLStyleElement_put_media,
266     HTMLStyleElement_get_media
267 };
268 
269 static inline HTMLStyleElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
270 {
271     return CONTAINING_RECORD(iface, HTMLStyleElement, element.node);
272 }
273 
274 static HRESULT HTMLStyleElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
275 {
276     HTMLStyleElement *This = impl_from_HTMLDOMNode(iface);
277 
278     if(IsEqualGUID(&IID_IUnknown, riid)) {
279         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
280         *ppv = &This->IHTMLStyleElement_iface;
281     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
282         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
283         *ppv = &This->IHTMLStyleElement_iface;
284     }else if(IsEqualGUID(&IID_IHTMLStyleElement, riid)) {
285         TRACE("(%p)->(IID_IHTMLStyleElement %p)\n", This, ppv);
286         *ppv = &This->IHTMLStyleElement_iface;
287     }else {
288         return HTMLElement_QI(&This->element.node, riid, ppv);
289     }
290 
291     IUnknown_AddRef((IUnknown*)*ppv);
292     return S_OK;
293 }
294 
295 static void HTMLStyleElement_destructor(HTMLDOMNode *iface)
296 {
297     HTMLStyleElement *This = impl_from_HTMLDOMNode(iface);
298 
299     if(This->style_sheet) {
300         IHTMLStyleSheet_Release(This->style_sheet);
301         This->style_sheet = NULL;
302     }
303 
304     HTMLElement_destructor(iface);
305 }
306 
307 static void HTMLStyleElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
308 {
309     HTMLStyleElement *This = impl_from_HTMLDOMNode(iface);
310 
311     if(This->nsstyle)
312         note_cc_edge((nsISupports*)This->nsstyle, "This->nsstyle", cb);
313 }
314 
315 static void HTMLStyleElement_unlink(HTMLDOMNode *iface)
316 {
317     HTMLStyleElement *This = impl_from_HTMLDOMNode(iface);
318 
319     if(This->nsstyle) {
320         nsIDOMHTMLStyleElement *nsstyle = This->nsstyle;
321 
322         This->nsstyle = NULL;
323         nsIDOMHTMLStyleElement_Release(nsstyle);
324     }
325 }
326 
327 static const NodeImplVtbl HTMLStyleElementImplVtbl = {
328     HTMLStyleElement_QI,
329     HTMLStyleElement_destructor,
330     HTMLElement_cpc,
331     HTMLElement_clone,
332     HTMLElement_handle_event,
333     HTMLElement_get_attr_col,
334     NULL,
335     NULL,
336     NULL,
337     NULL,
338     NULL,
339     NULL,
340     NULL,
341     NULL,
342     NULL,
343     HTMLStyleElement_traverse,
344     HTMLStyleElement_unlink
345 };
346 
347 static const tid_t HTMLStyleElement_iface_tids[] = {
348     HTMLELEMENT_TIDS,
349     IHTMLStyleElement_tid,
350     0
351 };
352 static dispex_static_data_t HTMLStyleElement_dispex = {
353     NULL,
354     DispHTMLStyleElement_tid,
355     NULL,
356     HTMLStyleElement_iface_tids
357 };
358 
359 HRESULT HTMLStyleElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
360 {
361     HTMLStyleElement *ret;
362     nsresult nsres;
363 
364     ret = heap_alloc_zero(sizeof(*ret));
365     if(!ret)
366         return E_OUTOFMEMORY;
367 
368     ret->IHTMLStyleElement_iface.lpVtbl = &HTMLStyleElementVtbl;
369     ret->element.node.vtbl = &HTMLStyleElementImplVtbl;
370 
371     HTMLElement_Init(&ret->element, doc, nselem, &HTMLStyleElement_dispex);
372 
373     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLStyleElement, (void**)&ret->nsstyle);
374     assert(nsres == NS_OK);
375 
376     *elem = &ret->element;
377     return S_OK;
378 }
379