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