mshtml: Added IHTMLStyle::pageBreakBefore implementation.
[wine] / dlls / mshtml / htmlstyle.c
1 /*
2  * Copyright 2006 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 <math.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "mshtmdid.h"
29
30 #include "mshtml_private.h"
31 #include "htmlstyle.h"
32
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 static const WCHAR attrBackground[] =
39     {'b','a','c','k','g','r','o','u','n','d',0};
40 static const WCHAR attrBackgroundColor[] =
41     {'b','a','c','k','g','r','o','u','n','d','-','c','o','l','o','r',0};
42 static const WCHAR attrBackgroundImage[] =
43     {'b','a','c','k','g','r','o','u','n','d','-','i','m','a','g','e',0};
44 static const WCHAR attrBackgroundPosition[] =
45     {'b','a','c','k','g','r','o','u','n','d','-','p','o','s','i','t','i','o','n',0};
46 static const WCHAR attrBackgroundPositionX[] =
47     {'b','a','c','k','g','r','o','u','n','d','-','p','o','s','i','t','i','o','n','-','x',0};
48 static const WCHAR attrBackgroundPositionY[] =
49     {'b','a','c','k','g','r','o','u','n','d','-','p','o','s','i','t','i','o','n','-','y',0};
50 static const WCHAR attrBackgroundRepeat[] =
51     {'b','a','c','k','g','r','o','u','n','d','-','r','e','p','e','a','t',0};
52 static const WCHAR attrBorder[] =
53     {'b','o','r','d','e','r',0};
54 static const WCHAR attrBorderBottom[] =
55     {'b','o','r','d','e','r','-','b','o','t','t','o','m',0};
56 static const WCHAR attrBorderBottomColor[] =
57     {'b','o','r','d','e','r','-','b','o','t','t','o','m','-','c','o','l','o','r',0};
58 static const WCHAR attrBorderBottomStyle[] =
59     {'b','o','r','d','e','r','-','b','o','t','t','o','m','-','s','t','y','l','e',0};
60 static const WCHAR attrBorderBottomWidth[] =
61     {'b','o','r','d','e','r','-','b','o','t','t','o','m','-','w','i','d','t','h',0};
62 static const WCHAR attrBorderColor[] =
63     {'b','o','r','d','e','r','-','c','o','l','o','r',0};
64 static const WCHAR attrBorderLeft[] =
65     {'b','o','r','d','e','r','-','l','e','f','t',0};
66 static const WCHAR attrBorderLeftColor[] =
67     {'b','o','r','d','e','r','-','l','e','f','t','-','c','o','l','o','r',0};
68 static const WCHAR attrBorderLeftStyle[] =
69     {'b','o','r','d','e','r','-','l','e','f','t','-','s','t','y','l','e',0};
70 static const WCHAR attrBorderLeftWidth[] =
71     {'b','o','r','d','e','r','-','l','e','f','t','-','w','i','d','t','h',0};
72 static const WCHAR attrBorderRight[] =
73     {'b','o','r','d','e','r','-','r','i','g','h','t',0};
74 static const WCHAR attrBorderRightColor[] =
75     {'b','o','r','d','e','r','-','r','i','g','h','t','-','c','o','l','o','r',0};
76 static const WCHAR attrBorderRightStyle[] =
77     {'b','o','r','d','e','r','-','r','i','g','h','t','-','s','t','y','l','e',0};
78 static const WCHAR attrBorderRightWidth[] =
79     {'b','o','r','d','e','r','-','r','i','g','h','t','-','w','i','d','t','h',0};
80 static const WCHAR attrBorderTop[] =
81     {'b','o','r','d','e','r','-','t','o','p',0};
82 static const WCHAR attrBorderTopColor[] =
83     {'b','o','r','d','e','r','-','t','o','p','-','c','o','l','o','r',0};
84 static const WCHAR attrBorderStyle[] =
85     {'b','o','r','d','e','r','-','s','t','y','l','e',0};
86 static const WCHAR attrBorderTopStyle[] =
87     {'b','o','r','d','e','r','-','t','o','p','-','s','t','y','l','e',0};
88 static const WCHAR attrBorderTopWidth[] =
89     {'b','o','r','d','e','r','-','t','o','p','-','w','i','d','t','h',0};
90 static const WCHAR attrBorderWidth[] =
91     {'b','o','r','d','e','r','-','w','i','d','t','h',0};
92 static const WCHAR attrBottom[] =
93     {'b','o','t','t','o','m',0};
94 static const WCHAR attrClip[] =
95     {'c','l','i','p',0};
96 static const WCHAR attrColor[] =
97     {'c','o','l','o','r',0};
98 static const WCHAR attrCursor[] =
99     {'c','u','r','s','o','r',0};
100 static const WCHAR attrDisplay[] =
101     {'d','i','s','p','l','a','y',0};
102 static const WCHAR attrFilter[] =
103     {'f','i','l','e','t','e','r',0};
104 static const WCHAR attrFontFamily[] =
105     {'f','o','n','t','-','f','a','m','i','l','y',0};
106 static const WCHAR attrFontSize[] =
107     {'f','o','n','t','-','s','i','z','e',0};
108 static const WCHAR attrFontStyle[] =
109     {'f','o','n','t','-','s','t','y','l','e',0};
110 static const WCHAR attrFontVariant[] =
111     {'f','o','n','t','-','v','a','r','i','a','n','t',0};
112 static const WCHAR attrFontWeight[] =
113     {'f','o','n','t','-','w','e','i','g','h','t',0};
114 static const WCHAR attrHeight[] =
115     {'h','e','i','g','h','t',0};
116 static const WCHAR attrLeft[] =
117     {'l','e','f','t',0};
118 static const WCHAR attrLetterSpacing[] =
119     {'l','e','t','t','e','r','-','s','p','a','c','i','n','g',0};
120 static const WCHAR attrLineHeight[] =
121     {'l','i','n','e','-','h','e','i','g','h','t',0};
122 static const WCHAR attrMargin[] =
123     {'m','a','r','g','i','n',0};
124 static const WCHAR attrMarginBottom[] =
125     {'m','a','r','g','i','n','-','b','o','t','t','o','m',0};
126 static const WCHAR attrMarginLeft[] =
127     {'m','a','r','g','i','n','-','l','e','f','t',0};
128 static const WCHAR attrMarginRight[] =
129     {'m','a','r','g','i','n','-','r','i','g','h','t',0};
130 static const WCHAR attrMarginTop[] =
131     {'m','a','r','g','i','n','-','t','o','p',0};
132 static const WCHAR attrMinHeight[] =
133     {'m','i','n','-','h','e','i','g','h','t',0};
134 static const WCHAR attrOverflow[] =
135     {'o','v','e','r','f','l','o','w',0};
136 static const WCHAR attrPadding[] =
137     {'p','a','d','d','i','n','g',0};
138 static const WCHAR attrPaddingBottom[] =
139     {'p','a','d','d','i','n','g','-','b','o','t','t','o','m',0};
140 static const WCHAR attrPaddingLeft[] =
141     {'p','a','d','d','i','n','g','-','l','e','f','t',0};
142 static const WCHAR attrPaddingRight[] =
143     {'p','a','d','d','i','n','g','-','r','i','g','h','t',0};
144 static const WCHAR attrPaddingTop[] =
145     {'p','a','d','d','i','n','g','-','t','o','p',0};
146 static const WCHAR attrPageBreakAfter[] =
147     {'p','a','g','e','-','b','r','e','a','k','-','a','f','t','e','r',0};
148 static const WCHAR attrPageBreakBefore[] =
149     {'p','a','g','e','-','b','r','e','a','k','-','b','e','f','o','r','e',0};
150 static const WCHAR attrPosition[] =
151     {'p','o','s','i','t','i','o','n',0};
152 static const WCHAR attrRight[] =
153     {'r','i','g','h','t',0};
154 static const WCHAR attrTextAlign[] =
155     {'t','e','x','t','-','a','l','i','g','n',0};
156 static const WCHAR attrTextDecoration[] =
157     {'t','e','x','t','-','d','e','c','o','r','a','t','i','o','n',0};
158 static const WCHAR attrTextIndent[] =
159     {'t','e','x','t','-','i','n','d','e','n','t',0};
160 static const WCHAR attrTop[] =
161     {'t','o','p',0};
162 static const WCHAR attrVerticalAlign[] =
163     {'v','e','r','t','i','c','a','l','-','a','l','i','g','n',0};
164 static const WCHAR attrVisibility[] =
165     {'v','i','s','i','b','i','l','i','t','y',0};
166 static const WCHAR attrWidth[] =
167     {'w','i','d','t','h',0};
168 static const WCHAR attrWordSpacing[] =
169     {'w','o','r','d','-','s','p','a','c','i','n','g',0};
170 static const WCHAR attrWordWrap[] =
171     {'w','o','r','d','-','w','r','a','p',0};
172 static const WCHAR attrZIndex[] =
173     {'z','-','i','n','d','e','x',0};
174
175 static const struct{
176     const WCHAR *name;
177     DISPID dispid;
178 } style_tbl[] = {
179     {attrBackground,           DISPID_IHTMLSTYLE_BACKGROUND},
180     {attrBackgroundColor,      DISPID_IHTMLSTYLE_BACKGROUNDCOLOR},
181     {attrBackgroundImage,      DISPID_IHTMLSTYLE_BACKGROUNDIMAGE},
182     {attrBackgroundPosition,   DISPID_IHTMLSTYLE_BACKGROUNDPOSITION},
183     {attrBackgroundPositionX,  DISPID_IHTMLSTYLE_BACKGROUNDPOSITIONX},
184     {attrBackgroundPositionY,  DISPID_IHTMLSTYLE_BACKGROUNDPOSITIONY},
185     {attrBackgroundRepeat,     DISPID_IHTMLSTYLE_BACKGROUNDREPEAT},
186     {attrBorder,               DISPID_IHTMLSTYLE_BORDER},
187     {attrBorderBottom,         DISPID_IHTMLSTYLE_BORDERBOTTOM},
188     {attrBorderBottomColor,    DISPID_IHTMLSTYLE_BORDERBOTTOMCOLOR},
189     {attrBorderBottomStyle,    DISPID_IHTMLSTYLE_BORDERBOTTOMSTYLE},
190     {attrBorderBottomWidth,    DISPID_IHTMLSTYLE_BORDERBOTTOMWIDTH},
191     {attrBorderColor,          DISPID_IHTMLSTYLE_BORDERCOLOR},
192     {attrBorderLeft,           DISPID_IHTMLSTYLE_BORDERLEFT},
193     {attrBorderLeftColor,      DISPID_IHTMLSTYLE_BORDERLEFTCOLOR},
194     {attrBorderLeftStyle,      DISPID_IHTMLSTYLE_BORDERLEFTSTYLE},
195     {attrBorderLeftWidth,      DISPID_IHTMLSTYLE_BORDERLEFTWIDTH},
196     {attrBorderRight,          DISPID_IHTMLSTYLE_BORDERRIGHT},
197     {attrBorderRightColor,     DISPID_IHTMLSTYLE_BORDERRIGHTCOLOR},
198     {attrBorderRightStyle,     DISPID_IHTMLSTYLE_BORDERRIGHTSTYLE},
199     {attrBorderRightWidth,     DISPID_IHTMLSTYLE_BORDERRIGHTWIDTH},
200     {attrBorderStyle,          DISPID_IHTMLSTYLE_BORDERSTYLE},
201     {attrBorderTop,            DISPID_IHTMLSTYLE_BORDERTOP},
202     {attrBorderTopColor,       DISPID_IHTMLSTYLE_BORDERTOPCOLOR},
203     {attrBorderTopStyle,       DISPID_IHTMLSTYLE_BORDERTOPSTYLE},
204     {attrBorderTopWidth,       DISPID_IHTMLSTYLE_BORDERTOPWIDTH},
205     {attrBorderWidth,          DISPID_IHTMLSTYLE_BORDERWIDTH},
206     {attrBottom,               DISPID_IHTMLSTYLE2_BOTTOM},
207     {attrClip,                 DISPID_IHTMLSTYLE_CLIP},
208     {attrColor,                DISPID_IHTMLSTYLE_COLOR},
209     {attrCursor,               DISPID_IHTMLSTYLE_CURSOR},
210     {attrDisplay,              DISPID_IHTMLSTYLE_DISPLAY},
211     {attrFilter,               DISPID_IHTMLSTYLE_FILTER},
212     {attrFontFamily,           DISPID_IHTMLSTYLE_FONTFAMILY},
213     {attrFontSize,             DISPID_IHTMLSTYLE_FONTSIZE},
214     {attrFontStyle,            DISPID_IHTMLSTYLE_FONTSTYLE},
215     {attrFontVariant,          DISPID_IHTMLSTYLE_FONTVARIANT},
216     {attrFontWeight,           DISPID_IHTMLSTYLE_FONTWEIGHT},
217     {attrHeight,               DISPID_IHTMLSTYLE_HEIGHT},
218     {attrLeft,                 DISPID_IHTMLSTYLE_LEFT},
219     {attrLetterSpacing,        DISPID_IHTMLSTYLE_LETTERSPACING},
220     {attrLineHeight,           DISPID_IHTMLSTYLE_LINEHEIGHT},
221     {attrMargin,               DISPID_IHTMLSTYLE_MARGIN},
222     {attrMarginBottom,         DISPID_IHTMLSTYLE_MARGINBOTTOM},
223     {attrMarginLeft,           DISPID_IHTMLSTYLE_MARGINLEFT},
224     {attrMarginRight,          DISPID_IHTMLSTYLE_MARGINRIGHT},
225     {attrMarginTop,            DISPID_IHTMLSTYLE_MARGINTOP},
226     {attrMinHeight,            DISPID_IHTMLSTYLE4_MINHEIGHT},
227     {attrOverflow,             DISPID_IHTMLSTYLE_OVERFLOW},
228     {attrPadding,              DISPID_IHTMLSTYLE_PADDING},
229     {attrPaddingBottom,        DISPID_IHTMLSTYLE_PADDINGBOTTOM},
230     {attrPaddingLeft,          DISPID_IHTMLSTYLE_PADDINGLEFT},
231     {attrPaddingRight,         DISPID_IHTMLSTYLE_PADDINGRIGHT},
232     {attrPaddingTop,           DISPID_IHTMLSTYLE_PADDINGTOP},
233     {attrPageBreakAfter,       DISPID_IHTMLSTYLE_PAGEBREAKAFTER},
234     {attrPageBreakBefore,      DISPID_IHTMLSTYLE_PAGEBREAKBEFORE},
235     {attrPosition,             DISPID_IHTMLSTYLE2_POSITION},
236     {attrRight,                DISPID_IHTMLSTYLE2_RIGHT},
237     {attrTextAlign,            DISPID_IHTMLSTYLE_TEXTALIGN},
238     {attrTextDecoration,       DISPID_IHTMLSTYLE_TEXTDECORATION},
239     {attrTextIndent,           DISPID_IHTMLSTYLE_TEXTINDENT},
240     {attrTop,                  DISPID_IHTMLSTYLE_TOP},
241     {attrVerticalAlign,        DISPID_IHTMLSTYLE_VERTICALALIGN},
242     {attrVisibility,           DISPID_IHTMLSTYLE_VISIBILITY},
243     {attrWidth,                DISPID_IHTMLSTYLE_WIDTH},
244     {attrWordSpacing,          DISPID_IHTMLSTYLE_WORDSPACING},
245     {attrWordWrap,             DISPID_IHTMLSTYLE3_WORDWRAP},
246     {attrZIndex,               DISPID_IHTMLSTYLE_ZINDEX}
247 };
248
249 static const WCHAR valLineThrough[] =
250     {'l','i','n','e','-','t','h','r','o','u','g','h',0};
251 static const WCHAR valUnderline[] =
252     {'u','n','d','e','r','l','i','n','e',0};
253 static const WCHAR szNormal[] =
254     {'n','o','r','m','a','l',0};
255 static const WCHAR styleNone[] =
256     {'n','o','n','e',0};
257 static const WCHAR valOverline[] =
258     {'o','v','e','r','l','i','n','e',0};
259 static const WCHAR valBlink[] =
260     {'b','l','i','n','k',0};
261
262 static const WCHAR px_formatW[] = {'%','d','p','x',0};
263 static const WCHAR emptyW[] = {0};
264
265 static LPWSTR fix_px_value(LPCWSTR val)
266 {
267     LPCWSTR ptr = val;
268
269     while(*ptr) {
270         while(*ptr && isspaceW(*ptr))
271             ptr++;
272         if(!*ptr)
273             break;
274
275         while(*ptr && isdigitW(*ptr))
276             ptr++;
277
278         if(!*ptr || isspaceW(*ptr)) {
279             LPWSTR ret, p;
280             int len = strlenW(val)+1;
281
282             ret = heap_alloc((len+2)*sizeof(WCHAR));
283             memcpy(ret, val, (ptr-val)*sizeof(WCHAR));
284             p = ret + (ptr-val);
285             *p++ = 'p';
286             *p++ = 'x';
287             strcpyW(p, ptr);
288
289             TRACE("fixed %s -> %s\n", debugstr_w(val), debugstr_w(ret));
290
291             return ret;
292         }
293
294         while(*ptr && !isspaceW(*ptr))
295             ptr++;
296     }
297
298     return NULL;
299 }
300
301 static LPWSTR fix_url_value(LPCWSTR val)
302 {
303     WCHAR *ret, *ptr;
304
305     static const WCHAR urlW[] = {'u','r','l','('};
306
307     if(strncmpW(val, urlW, sizeof(urlW)/sizeof(WCHAR)) || !strchrW(val, '\\'))
308         return NULL;
309
310     ret = heap_strdupW(val);
311
312     for(ptr = ret; *ptr; ptr++) {
313         if(*ptr == '\\')
314             *ptr = '/';
315     }
316
317     return ret;
318 }
319
320 HRESULT set_nsstyle_attr(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, LPCWSTR value, DWORD flags)
321 {
322     nsAString str_name, str_value, str_empty;
323     LPWSTR val = NULL;
324     nsresult nsres;
325
326     if(flags & ATTR_FIX_PX)
327         val = fix_px_value(value);
328     if(flags & ATTR_FIX_URL)
329         val = fix_url_value(value);
330
331     nsAString_InitDepend(&str_name, style_tbl[sid].name);
332     nsAString_InitDepend(&str_value, val ? val : value);
333     nsAString_InitDepend(&str_empty, emptyW);
334
335     nsres = nsIDOMCSSStyleDeclaration_SetProperty(nsstyle, &str_name, &str_value, &str_empty);
336     if(NS_FAILED(nsres))
337         ERR("SetProperty failed: %08x\n", nsres);
338
339     nsAString_Finish(&str_name);
340     nsAString_Finish(&str_value);
341     nsAString_Finish(&str_empty);
342     heap_free(val);
343
344     return S_OK;
345 }
346
347 static HRESULT var_to_styleval(const VARIANT *v, WCHAR *buf, DWORD flags, const WCHAR **ret)
348 {
349     switch(V_VT(v)) {
350     case VT_NULL:
351         *ret = emptyW;
352         return S_OK;
353
354     case VT_BSTR:
355         *ret = V_BSTR(v);
356         return S_OK;
357
358     case VT_BSTR|VT_BYREF:
359         *ret = *V_BSTRREF(v);
360         return S_OK;
361
362     case VT_I4: {
363         static const WCHAR formatW[] = {'%','d',0};
364         static const WCHAR hex_formatW[] = {'#','%','0','6','x',0};
365
366         if(flags & ATTR_HEX_INT)
367             wsprintfW(buf, hex_formatW, V_I4(v));
368         else if(flags & ATTR_FIX_PX)
369             wsprintfW(buf, px_formatW, V_I4(v));
370         else
371             wsprintfW(buf, formatW, V_I4(v));
372
373         *ret = buf;
374         return S_OK;
375     }
376     default:
377         FIXME("not implemented vt %d\n", V_VT(v));
378         return E_NOTIMPL;
379
380     }
381 }
382
383 HRESULT set_nsstyle_attr_var(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, VARIANT *value, DWORD flags)
384 {
385     const WCHAR *val;
386     WCHAR buf[14];
387     HRESULT hres;
388
389     hres = var_to_styleval(value, buf, flags, &val);
390     if(FAILED(hres))
391         return hres;
392
393     return set_nsstyle_attr(nsstyle, sid, val, flags);
394 }
395
396 static inline HRESULT set_style_attr(HTMLStyle *This, styleid_t sid, LPCWSTR value, DWORD flags)
397 {
398     return set_nsstyle_attr(This->nsstyle, sid, value, flags);
399 }
400
401 static HRESULT get_nsstyle_attr_nsval(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, nsAString *value)
402 {
403     nsAString str_name;
404     nsresult nsres;
405
406     nsAString_InitDepend(&str_name, style_tbl[sid].name);
407
408     nsres = nsIDOMCSSStyleDeclaration_GetPropertyValue(nsstyle, &str_name, value);
409     if(NS_FAILED(nsres)) {
410         ERR("SetProperty failed: %08x\n", nsres);
411         return E_FAIL;
412     }
413
414     nsAString_Finish(&str_name);
415
416     return NS_OK;
417 }
418
419 static HRESULT nsstyle_to_bstr(const WCHAR *val, DWORD flags, BSTR *p)
420 {
421     BSTR ret;
422     DWORD len;
423
424     if(!*val) {
425         *p = NULL;
426         return S_OK;
427     }
428
429     ret = SysAllocString(val);
430     if(!ret)
431         return E_OUTOFMEMORY;
432
433     len = SysStringLen(ret);
434
435     if(flags & ATTR_REMOVE_COMMA) {
436         DWORD new_len = len;
437         WCHAR *ptr, *ptr2;
438
439         for(ptr = ret; (ptr = strchrW(ptr, ',')); ptr++)
440             new_len--;
441
442         if(new_len != len) {
443             BSTR new_ret;
444
445             new_ret = SysAllocStringLen(NULL, new_len);
446             if(!new_ret) {
447                 SysFreeString(ret);
448                 return E_OUTOFMEMORY;
449             }
450
451             for(ptr2 = new_ret, ptr = ret; *ptr; ptr++) {
452                 if(*ptr != ',')
453                     *ptr2++ = *ptr;
454             }
455
456             SysFreeString(ret);
457             ret = new_ret;
458         }
459     }
460
461     *p = ret;
462     return S_OK;
463 }
464
465 HRESULT get_nsstyle_attr(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, BSTR *p, DWORD flags)
466 {
467     nsAString str_value;
468     const PRUnichar *value;
469     HRESULT hres;
470
471     nsAString_Init(&str_value, NULL);
472
473     get_nsstyle_attr_nsval(nsstyle, sid, &str_value);
474
475     nsAString_GetData(&str_value, &value);
476     hres = nsstyle_to_bstr(value, flags, p);
477     nsAString_Finish(&str_value);
478
479     TRACE("%s -> %s\n", debugstr_w(style_tbl[sid].name), debugstr_w(*p));
480     return S_OK;
481 }
482
483 HRESULT get_nsstyle_attr_var(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, VARIANT *p, DWORD flags)
484 {
485     nsAString str_value;
486     const PRUnichar *value;
487     BOOL set = FALSE;
488     HRESULT hres = S_OK;
489
490     nsAString_Init(&str_value, NULL);
491
492     get_nsstyle_attr_nsval(nsstyle, sid, &str_value);
493
494     nsAString_GetData(&str_value, &value);
495
496     if(flags & ATTR_STR_TO_INT) {
497         const PRUnichar *ptr = value;
498         BOOL neg = FALSE;
499         INT i = 0;
500
501         if(*ptr == '-') {
502             neg = TRUE;
503             ptr++;
504         }
505
506         while(isdigitW(*ptr))
507             i = i*10 + (*ptr++ - '0');
508
509         if(!*ptr) {
510             V_VT(p) = VT_I4;
511             V_I4(p) = neg ? -i : i;
512             set = TRUE;
513         }
514     }
515
516     if(!set) {
517         BSTR str;
518
519         hres = nsstyle_to_bstr(value, flags, &str);
520         if(SUCCEEDED(hres)) {
521             V_VT(p) = VT_BSTR;
522             V_BSTR(p) = str;
523         }
524     }
525
526     nsAString_Finish(&str_value);
527
528     TRACE("%s -> %s\n", debugstr_w(style_tbl[sid].name), debugstr_variant(p));
529     return S_OK;
530 }
531
532 static inline HRESULT get_style_attr(HTMLStyle *This, styleid_t sid, BSTR *p)
533 {
534     return get_nsstyle_attr(This->nsstyle, sid, p, 0);
535 }
536
537 static HRESULT check_style_attr_value(HTMLStyle *This, styleid_t sid, LPCWSTR exval, VARIANT_BOOL *p)
538 {
539     nsAString str_value;
540     const PRUnichar *value;
541
542     nsAString_Init(&str_value, NULL);
543
544     get_nsstyle_attr_nsval(This->nsstyle, sid, &str_value);
545
546     nsAString_GetData(&str_value, &value);
547     *p = strcmpW(value, exval) ? VARIANT_FALSE : VARIANT_TRUE;
548     nsAString_Finish(&str_value);
549
550     TRACE("%s -> %x\n", debugstr_w(style_tbl[sid].name), *p);
551     return S_OK;
552 }
553
554 static inline HRESULT set_style_pos(HTMLStyle *This, styleid_t sid, float value)
555 {
556     WCHAR szValue[25];
557     WCHAR szFormat[] = {'%','.','0','f','p','x',0};
558
559     value = floor(value);
560
561     sprintfW(szValue, szFormat, value);
562
563     return set_style_attr(This, sid, szValue, 0);
564 }
565
566 static HRESULT get_nsstyle_pos(HTMLStyle *This, styleid_t sid, float *p)
567 {
568     nsAString str_value;
569     HRESULT hres;
570     WCHAR pxW[] = {'p','x',0};
571
572     TRACE("%p %d %p\n", This, sid, p);
573
574     *p = 0.0f;
575
576     nsAString_Init(&str_value, NULL);
577
578     hres = get_nsstyle_attr_nsval(This->nsstyle, sid, &str_value);
579     if(hres == S_OK)
580     {
581         WCHAR *ptr;
582         const PRUnichar *value;
583
584         nsAString_GetData(&str_value, &value);
585         if(value)
586         {
587             *p = strtolW(value, &ptr, 10);
588
589             if(*ptr && strcmpW(ptr, pxW))
590             {
591                 nsAString_Finish(&str_value);
592                 FIXME("only px values are currently supported\n");
593                 return E_FAIL;
594             }
595         }
596     }
597
598     TRACE("ret %f\n", *p);
599
600     nsAString_Finish(&str_value);
601
602     return hres;
603 }
604
605 static BOOL is_valid_border_style(BSTR v)
606 {
607     static const WCHAR styleDotted[] = {'d','o','t','t','e','d',0};
608     static const WCHAR styleDashed[] = {'d','a','s','h','e','d',0};
609     static const WCHAR styleSolid[]  = {'s','o','l','i','d',0};
610     static const WCHAR styleDouble[] = {'d','o','u','b','l','e',0};
611     static const WCHAR styleGroove[] = {'g','r','o','o','v','e',0};
612     static const WCHAR styleRidge[]  = {'r','i','d','g','e',0};
613     static const WCHAR styleInset[]  = {'i','n','s','e','t',0};
614     static const WCHAR styleOutset[] = {'o','u','t','s','e','t',0};
615
616     TRACE("%s\n", debugstr_w(v));
617
618     if(!v || strcmpiW(v, styleNone)   == 0 || strcmpiW(v, styleDotted) == 0 ||
619              strcmpiW(v, styleDashed) == 0 || strcmpiW(v, styleSolid)  == 0 ||
620              strcmpiW(v, styleDouble) == 0 || strcmpiW(v, styleGroove) == 0 ||
621              strcmpiW(v, styleRidge)  == 0 || strcmpiW(v, styleInset)  == 0 ||
622              strcmpiW(v, styleOutset) == 0 )
623     {
624         return TRUE;
625     }
626
627     return FALSE;
628 }
629
630 static inline HTMLStyle *impl_from_IHTMLStyle(IHTMLStyle *iface)
631 {
632     return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle_iface);
633 }
634
635 static HRESULT WINAPI HTMLStyle_QueryInterface(IHTMLStyle *iface, REFIID riid, void **ppv)
636 {
637     HTMLStyle *This = impl_from_IHTMLStyle(iface);
638
639     *ppv = NULL;
640
641     if(IsEqualGUID(&IID_IUnknown, riid)) {
642         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
643         *ppv = &This->IHTMLStyle_iface;
644     }else if(IsEqualGUID(&IID_IHTMLStyle, riid)) {
645         TRACE("(%p)->(IID_IHTMLStyle %p)\n", This, ppv);
646         *ppv = &This->IHTMLStyle_iface;
647     }else if(IsEqualGUID(&IID_IHTMLStyle2, riid)) {
648         TRACE("(%p)->(IID_IHTMLStyle2 %p)\n", This, ppv);
649         *ppv = &This->IHTMLStyle2_iface;
650     }else if(IsEqualGUID(&IID_IHTMLStyle3, riid)) {
651         TRACE("(%p)->(IID_IHTMLStyle3 %p)\n", This, ppv);
652         *ppv = &This->IHTMLStyle3_iface;
653     }else if(IsEqualGUID(&IID_IHTMLStyle4, riid)) {
654         TRACE("(%p)->(IID_IHTMLStyle4 %p)\n", This, ppv);
655         *ppv = &This->IHTMLStyle4_iface;
656     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
657         return *ppv ? S_OK : E_NOINTERFACE;
658     }
659
660     if(*ppv) {
661         IUnknown_AddRef((IUnknown*)*ppv);
662         return S_OK;
663     }
664
665     WARN("unsupported %s\n", debugstr_guid(riid));
666     return E_NOINTERFACE;
667 }
668
669 static ULONG WINAPI HTMLStyle_AddRef(IHTMLStyle *iface)
670 {
671     HTMLStyle *This = impl_from_IHTMLStyle(iface);
672     LONG ref = InterlockedIncrement(&This->ref);
673
674     TRACE("(%p) ref=%d\n", This, ref);
675
676     return ref;
677 }
678
679 static ULONG WINAPI HTMLStyle_Release(IHTMLStyle *iface)
680 {
681     HTMLStyle *This = impl_from_IHTMLStyle(iface);
682     LONG ref = InterlockedDecrement(&This->ref);
683
684     TRACE("(%p) ref=%d\n", This, ref);
685
686     if(!ref) {
687         if(This->nsstyle)
688             nsIDOMCSSStyleDeclaration_Release(This->nsstyle);
689         heap_free(This->filter);
690         release_dispex(&This->dispex);
691         heap_free(This);
692     }
693
694     return ref;
695 }
696
697 static HRESULT WINAPI HTMLStyle_GetTypeInfoCount(IHTMLStyle *iface, UINT *pctinfo)
698 {
699     HTMLStyle *This = impl_from_IHTMLStyle(iface);
700     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
701 }
702
703 static HRESULT WINAPI HTMLStyle_GetTypeInfo(IHTMLStyle *iface, UINT iTInfo,
704                                               LCID lcid, ITypeInfo **ppTInfo)
705 {
706     HTMLStyle *This = impl_from_IHTMLStyle(iface);
707     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
708 }
709
710 static HRESULT WINAPI HTMLStyle_GetIDsOfNames(IHTMLStyle *iface, REFIID riid,
711                                                 LPOLESTR *rgszNames, UINT cNames,
712                                                 LCID lcid, DISPID *rgDispId)
713 {
714     HTMLStyle *This = impl_from_IHTMLStyle(iface);
715     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
716             lcid, rgDispId);
717 }
718
719 static HRESULT WINAPI HTMLStyle_Invoke(IHTMLStyle *iface, DISPID dispIdMember,
720                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
721                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
722 {
723     HTMLStyle *This = impl_from_IHTMLStyle(iface);
724     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
725             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
726 }
727
728 static HRESULT WINAPI HTMLStyle_put_fontFamily(IHTMLStyle *iface, BSTR v)
729 {
730     HTMLStyle *This = impl_from_IHTMLStyle(iface);
731
732     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
733
734     return set_style_attr(This, STYLEID_FONT_FAMILY, v, 0);
735 }
736
737 static HRESULT WINAPI HTMLStyle_get_fontFamily(IHTMLStyle *iface, BSTR *p)
738 {
739     HTMLStyle *This = impl_from_IHTMLStyle(iface);
740
741     TRACE("(%p)->(%p)\n", This, p);
742
743     return get_style_attr(This, STYLEID_FONT_FAMILY, p);
744 }
745
746 static HRESULT WINAPI HTMLStyle_put_fontStyle(IHTMLStyle *iface, BSTR v)
747 {
748     HTMLStyle *This = impl_from_IHTMLStyle(iface);
749     static const WCHAR szItalic[]  = {'i','t','a','l','i','c',0};
750     static const WCHAR szOblique[]  = {'o','b','l','i','q','u','e',0};
751
752     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
753
754     /* fontStyle can only be one of the follow values. */
755     if(!v || strcmpiW(szNormal, v) == 0 || strcmpiW(szItalic, v) == 0 ||
756              strcmpiW(szOblique, v) == 0)
757     {
758         return set_nsstyle_attr(This->nsstyle, STYLEID_FONT_STYLE, v, 0);
759     }
760
761     return E_INVALIDARG;
762 }
763
764 static HRESULT WINAPI HTMLStyle_get_fontStyle(IHTMLStyle *iface, BSTR *p)
765 {
766     HTMLStyle *This = impl_from_IHTMLStyle(iface);
767
768     TRACE("(%p)->(%p)\n", This, p);
769
770     return get_style_attr(This, STYLEID_FONT_STYLE, p);
771 }
772
773 static HRESULT WINAPI HTMLStyle_put_fontVariant(IHTMLStyle *iface, BSTR v)
774 {
775     HTMLStyle *This = impl_from_IHTMLStyle(iface);
776     static const WCHAR szCaps[]  = {'s','m','a','l','l','-','c','a','p','s',0};
777
778     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
779
780     /* fontVariant can only be one of the follow values. */
781     if(!v || strcmpiW(szNormal, v) == 0 || strcmpiW(szCaps, v) == 0)
782     {
783         return set_nsstyle_attr(This->nsstyle, STYLEID_FONT_VARIANT, v, 0);
784     }
785
786     return E_INVALIDARG;
787 }
788
789 static HRESULT WINAPI HTMLStyle_get_fontVariant(IHTMLStyle *iface, BSTR *p)
790 {
791     HTMLStyle *This = impl_from_IHTMLStyle(iface);
792     TRACE("(%p)->(%p)\n", This, p);
793
794     if(!p)
795        return E_INVALIDARG;
796
797     return get_style_attr(This, STYLEID_FONT_VARIANT, p);
798 }
799
800 static HRESULT WINAPI HTMLStyle_put_fontWeight(IHTMLStyle *iface, BSTR v)
801 {
802     HTMLStyle *This = impl_from_IHTMLStyle(iface);
803     static const WCHAR styleBold[] = {'b','o','l','d',0};
804     static const WCHAR styleBolder[] = {'b','o','l','d','e','r',0};
805     static const WCHAR styleLighter[]  = {'l','i','g','h','t','e','r',0};
806     static const WCHAR style100[] = {'1','0','0',0};
807     static const WCHAR style200[] = {'2','0','0',0};
808     static const WCHAR style300[] = {'3','0','0',0};
809     static const WCHAR style400[] = {'4','0','0',0};
810     static const WCHAR style500[] = {'5','0','0',0};
811     static const WCHAR style600[] = {'6','0','0',0};
812     static const WCHAR style700[] = {'7','0','0',0};
813     static const WCHAR style800[] = {'8','0','0',0};
814     static const WCHAR style900[] = {'9','0','0',0};
815
816     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
817
818     /* fontWeight can only be one of the following */
819     if(!v || strcmpiW(szNormal, v) == 0    || strcmpiW(styleBold, v) == 0    ||
820              strcmpiW(styleBolder, v) == 0 || strcmpiW(styleLighter, v) == 0 ||
821              strcmpiW(style100, v) == 0    || strcmpiW(style200, v) == 0     ||
822              strcmpiW(style300, v) == 0    || strcmpiW(style400, v) == 0     ||
823              strcmpiW(style500, v) == 0    || strcmpiW(style600, v) == 0     ||
824              strcmpiW(style700, v) == 0    || strcmpiW(style800, v) == 0     ||
825              strcmpiW(style900, v) == 0
826              )
827     {
828         return set_nsstyle_attr(This->nsstyle, STYLEID_FONT_WEIGHT, v, 0);
829     }
830
831     return E_INVALIDARG;
832 }
833
834 static HRESULT WINAPI HTMLStyle_get_fontWeight(IHTMLStyle *iface, BSTR *p)
835 {
836     HTMLStyle *This = impl_from_IHTMLStyle(iface);
837
838     TRACE("(%p)->(%p)\n", This, p);
839
840     return get_style_attr(This, STYLEID_FONT_WEIGHT, p);
841 }
842
843 static HRESULT WINAPI HTMLStyle_put_fontSize(IHTMLStyle *iface, VARIANT v)
844 {
845     HTMLStyle *This = impl_from_IHTMLStyle(iface);
846
847     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
848
849     switch(V_VT(&v)) {
850     case VT_BSTR:
851         return set_style_attr(This, STYLEID_FONT_SIZE, V_BSTR(&v), 0);
852     default:
853         FIXME("not supported vt %d\n", V_VT(&v));
854     }
855
856     return S_OK;
857 }
858
859 static HRESULT WINAPI HTMLStyle_get_fontSize(IHTMLStyle *iface, VARIANT *p)
860 {
861     HTMLStyle *This = impl_from_IHTMLStyle(iface);
862
863     TRACE("(%p)->(%p)\n", This, p);
864
865     V_VT(p) = VT_BSTR;
866     return get_style_attr(This, STYLEID_FONT_SIZE, &V_BSTR(p));
867 }
868
869 static HRESULT WINAPI HTMLStyle_put_font(IHTMLStyle *iface, BSTR v)
870 {
871     HTMLStyle *This = impl_from_IHTMLStyle(iface);
872     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
873     return E_NOTIMPL;
874 }
875
876 static HRESULT WINAPI HTMLStyle_get_font(IHTMLStyle *iface, BSTR *p)
877 {
878     HTMLStyle *This = impl_from_IHTMLStyle(iface);
879     FIXME("(%p)->(%p)\n", This, p);
880     return E_NOTIMPL;
881 }
882
883 static HRESULT WINAPI HTMLStyle_put_color(IHTMLStyle *iface, VARIANT v)
884 {
885     HTMLStyle *This = impl_from_IHTMLStyle(iface);
886
887     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
888
889     switch(V_VT(&v)) {
890     case VT_BSTR:
891         TRACE("%s\n", debugstr_w(V_BSTR(&v)));
892         return set_style_attr(This, STYLEID_COLOR, V_BSTR(&v), 0);
893
894     default:
895         FIXME("unsupported vt=%d\n", V_VT(&v));
896     }
897
898     return E_NOTIMPL;
899 }
900
901 static HRESULT WINAPI HTMLStyle_get_color(IHTMLStyle *iface, VARIANT *p)
902 {
903     HTMLStyle *This = impl_from_IHTMLStyle(iface);
904
905     TRACE("(%p)->(%p)\n", This, p);
906
907     V_VT(p) = VT_BSTR;
908     return get_style_attr(This, STYLEID_COLOR, &V_BSTR(p));
909 }
910
911 static HRESULT WINAPI HTMLStyle_put_background(IHTMLStyle *iface, BSTR v)
912 {
913     HTMLStyle *This = impl_from_IHTMLStyle(iface);
914
915     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
916
917     return set_style_attr(This, STYLEID_BACKGROUND, v, 0);
918 }
919
920 static HRESULT WINAPI HTMLStyle_get_background(IHTMLStyle *iface, BSTR *p)
921 {
922     HTMLStyle *This = impl_from_IHTMLStyle(iface);
923
924     TRACE("(%p)->(%p)\n", This, p);
925
926     return get_style_attr(This, STYLEID_BACKGROUND, p);
927 }
928
929 static HRESULT WINAPI HTMLStyle_put_backgroundColor(IHTMLStyle *iface, VARIANT v)
930 {
931     HTMLStyle *This = impl_from_IHTMLStyle(iface);
932
933     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
934
935     switch(V_VT(&v)) {
936     case VT_BSTR:
937         return set_style_attr(This, STYLEID_BACKGROUND_COLOR, V_BSTR(&v), 0);
938     case VT_I4: {
939         WCHAR value[10];
940         static const WCHAR format[] = {'#','%','0','6','x',0};
941
942         wsprintfW(value, format, V_I4(&v));
943         return set_style_attr(This, STYLEID_BACKGROUND_COLOR, value, 0);
944     }
945     default:
946         FIXME("unsupported vt %d\n", V_VT(&v));
947     }
948
949     return S_OK;
950 }
951
952 static HRESULT WINAPI HTMLStyle_get_backgroundColor(IHTMLStyle *iface, VARIANT *p)
953 {
954     HTMLStyle *This = impl_from_IHTMLStyle(iface);
955     TRACE("(%p)->(%p)\n", This, p);
956
957     V_VT(p) = VT_BSTR;
958     return get_style_attr(This, STYLEID_BACKGROUND_COLOR, &V_BSTR(p));
959 }
960
961 static HRESULT WINAPI HTMLStyle_put_backgroundImage(IHTMLStyle *iface, BSTR v)
962 {
963     HTMLStyle *This = impl_from_IHTMLStyle(iface);
964
965     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
966
967     return set_style_attr(This, STYLEID_BACKGROUND_IMAGE, v, ATTR_FIX_URL);
968 }
969
970 static HRESULT WINAPI HTMLStyle_get_backgroundImage(IHTMLStyle *iface, BSTR *p)
971 {
972     HTMLStyle *This = impl_from_IHTMLStyle(iface);
973
974     TRACE("(%p)->(%p)\n", This, p);
975
976     return get_style_attr(This, STYLEID_BACKGROUND_IMAGE, p);
977 }
978
979 static HRESULT WINAPI HTMLStyle_put_backgroundRepeat(IHTMLStyle *iface, BSTR v)
980 {
981     HTMLStyle *This = impl_from_IHTMLStyle(iface);
982     static const WCHAR styleRepeat[]   = {'r','e','p','e','a','t',0};
983     static const WCHAR styleNoRepeat[] = {'n','o','-','r','e','p','e','a','t',0};
984     static const WCHAR styleRepeatX[]  = {'r','e','p','e','a','t','-','x',0};
985     static const WCHAR styleRepeatY[]  = {'r','e','p','e','a','t','-','y',0};
986
987     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
988
989     /* fontWeight can only be one of the following */
990     if(!v || strcmpiW(styleRepeat, v) == 0    || strcmpiW(styleNoRepeat, v) == 0    ||
991              strcmpiW(styleRepeatX, v) == 0 || strcmpiW(styleRepeatY, v) == 0 )
992     {
993         return set_style_attr(This, STYLEID_BACKGROUND_REPEAT , v, 0);
994     }
995
996     return E_INVALIDARG;
997 }
998
999 static HRESULT WINAPI HTMLStyle_get_backgroundRepeat(IHTMLStyle *iface, BSTR *p)
1000 {
1001     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1002
1003     TRACE("(%p)->(%p)\n", This, p);
1004
1005     return get_style_attr(This, STYLEID_BACKGROUND_REPEAT, p);
1006 }
1007
1008 static HRESULT WINAPI HTMLStyle_put_backgroundAttachment(IHTMLStyle *iface, BSTR v)
1009 {
1010     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1011     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1012     return E_NOTIMPL;
1013 }
1014
1015 static HRESULT WINAPI HTMLStyle_get_backgroundAttachment(IHTMLStyle *iface, BSTR *p)
1016 {
1017     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1018     FIXME("(%p)->(%p)\n", This, p);
1019     return E_NOTIMPL;
1020 }
1021
1022 static HRESULT WINAPI HTMLStyle_put_backgroundPosition(IHTMLStyle *iface, BSTR v)
1023 {
1024     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1025
1026     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1027
1028     return set_style_attr(This, STYLEID_BACKGROUND_POSITION, v, 0);
1029 }
1030
1031 static HRESULT WINAPI HTMLStyle_get_backgroundPosition(IHTMLStyle *iface, BSTR *p)
1032 {
1033     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1034
1035     TRACE("(%p)->(%p)\n", This, p);
1036
1037     return get_style_attr(This, STYLEID_BACKGROUND_POSITION, p);
1038 }
1039
1040 static HRESULT WINAPI HTMLStyle_put_backgroundPositionX(IHTMLStyle *iface, VARIANT v)
1041 {
1042     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1043     WCHAR buf[14], *pos_val;
1044     nsAString pos_str;
1045     const WCHAR *val;
1046     DWORD val_len;
1047     HRESULT hres;
1048
1049     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1050
1051     hres = var_to_styleval(&v, buf, ATTR_FIX_PX, &val);
1052     if(FAILED(hres))
1053         return hres;
1054
1055     val_len = val ? strlenW(val) : 0;
1056
1057     nsAString_Init(&pos_str, NULL);
1058     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1059     if(SUCCEEDED(hres)) {
1060         const PRUnichar *pos, *posy;
1061         DWORD posy_len;
1062
1063         nsAString_GetData(&pos_str, &pos);
1064         posy = strchrW(pos, ' ');
1065         if(!posy) {
1066             static const WCHAR zero_pxW[] = {' ','0','p','x',0};
1067
1068             TRACE("no space in %s\n", debugstr_w(pos));
1069             posy = zero_pxW;
1070         }
1071
1072         posy_len = strlenW(posy);
1073         pos_val = heap_alloc((val_len+posy_len+1)*sizeof(WCHAR));
1074         if(pos_val) {
1075             if(val_len)
1076                 memcpy(pos_val, val, val_len*sizeof(WCHAR));
1077             if(posy_len)
1078                 memcpy(pos_val+val_len, posy, posy_len*sizeof(WCHAR));
1079             pos_val[val_len+posy_len] = 0;
1080         }else {
1081             hres = E_OUTOFMEMORY;
1082         }
1083     }
1084     nsAString_Finish(&pos_str);
1085     if(FAILED(hres))
1086         return hres;
1087
1088     TRACE("setting position to %s\n", debugstr_w(pos_val));
1089     hres = set_nsstyle_attr(This->nsstyle, STYLEID_BACKGROUND_POSITION, pos_val, ATTR_FIX_PX);
1090     heap_free(pos_val);
1091     return hres;
1092 }
1093
1094 static HRESULT WINAPI HTMLStyle_get_backgroundPositionX(IHTMLStyle *iface, VARIANT *p)
1095 {
1096     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1097     nsAString pos_str;
1098     BSTR ret;
1099     HRESULT hres;
1100
1101     TRACE("(%p)->(%p)\n", This, p);
1102
1103     nsAString_Init(&pos_str, NULL);
1104     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1105     if(SUCCEEDED(hres)) {
1106         const PRUnichar *pos, *space;
1107
1108         nsAString_GetData(&pos_str, &pos);
1109         space = strchrW(pos, ' ');
1110         if(!space) {
1111             WARN("no space in %s\n", debugstr_w(pos));
1112             space = pos + strlenW(pos);
1113         }
1114
1115         if(space != pos) {
1116             ret = SysAllocStringLen(pos, space-pos);
1117             if(!ret)
1118                 hres = E_OUTOFMEMORY;
1119         }else {
1120             ret = NULL;
1121         }
1122     }
1123     nsAString_Finish(&pos_str);
1124     if(FAILED(hres))
1125         return hres;
1126
1127     TRACE("returning %s\n", debugstr_w(ret));
1128     V_VT(p) = VT_BSTR;
1129     V_BSTR(p) = ret;
1130     return S_OK;
1131 }
1132
1133 static HRESULT WINAPI HTMLStyle_put_backgroundPositionY(IHTMLStyle *iface, VARIANT v)
1134 {
1135     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1136     WCHAR buf[14], *pos_val;
1137     nsAString pos_str;
1138     const WCHAR *val;
1139     DWORD val_len;
1140     HRESULT hres;
1141
1142     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1143
1144     hres = var_to_styleval(&v, buf, ATTR_FIX_PX, &val);
1145     if(FAILED(hres))
1146         return hres;
1147
1148     val_len = val ? strlenW(val) : 0;
1149
1150     nsAString_Init(&pos_str, NULL);
1151     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1152     if(SUCCEEDED(hres)) {
1153         const PRUnichar *pos, *space;
1154         DWORD posx_len;
1155
1156         nsAString_GetData(&pos_str, &pos);
1157         space = strchrW(pos, ' ');
1158         if(space) {
1159             space++;
1160         }else {
1161             static const WCHAR zero_pxW[] = {'0','p','x',' ',0};
1162
1163             TRACE("no space in %s\n", debugstr_w(pos));
1164             pos = zero_pxW;
1165             space = pos + sizeof(zero_pxW)/sizeof(WCHAR)-1;
1166         }
1167
1168         posx_len = space-pos;
1169
1170         pos_val = heap_alloc((posx_len+val_len+1)*sizeof(WCHAR));
1171         if(pos_val) {
1172             memcpy(pos_val, pos, posx_len*sizeof(WCHAR));
1173             if(val_len)
1174                 memcpy(pos_val+posx_len, val, val_len*sizeof(WCHAR));
1175             pos_val[posx_len+val_len] = 0;
1176         }else {
1177             hres = E_OUTOFMEMORY;
1178         }
1179     }
1180     nsAString_Finish(&pos_str);
1181     if(FAILED(hres))
1182         return hres;
1183
1184     TRACE("setting position to %s\n", debugstr_w(pos_val));
1185     hres = set_nsstyle_attr(This->nsstyle, STYLEID_BACKGROUND_POSITION, pos_val, ATTR_FIX_PX);
1186     heap_free(pos_val);
1187     return hres;
1188 }
1189
1190 static HRESULT WINAPI HTMLStyle_get_backgroundPositionY(IHTMLStyle *iface, VARIANT *p)
1191 {
1192     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1193     nsAString pos_str;
1194     BSTR ret;
1195     HRESULT hres;
1196
1197     TRACE("(%p)->(%p)\n", This, p);
1198
1199     nsAString_Init(&pos_str, NULL);
1200     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1201     if(SUCCEEDED(hres)) {
1202         const PRUnichar *pos, *posy;
1203
1204         nsAString_GetData(&pos_str, &pos);
1205         posy = strchrW(pos, ' ');
1206         if(posy) {
1207             ret = SysAllocString(posy+1);
1208             if(!ret)
1209                 hres = E_OUTOFMEMORY;
1210         }else {
1211             ret = NULL;
1212         }
1213     }
1214     nsAString_Finish(&pos_str);
1215     if(FAILED(hres))
1216         return hres;
1217
1218     TRACE("returning %s\n", debugstr_w(ret));
1219     V_VT(p) = VT_BSTR;
1220     V_BSTR(p) = ret;
1221     return S_OK;
1222 }
1223
1224 static HRESULT WINAPI HTMLStyle_put_wordSpacing(IHTMLStyle *iface, VARIANT v)
1225 {
1226     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1227     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1228     return set_nsstyle_attr_var(This->nsstyle, STYLEID_WORD_SPACING, &v, 0);
1229 }
1230
1231 static HRESULT WINAPI HTMLStyle_get_wordSpacing(IHTMLStyle *iface, VARIANT *p)
1232 {
1233     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1234     TRACE("(%p)->(%p)\n", This, p);
1235     return get_nsstyle_attr_var(This->nsstyle, STYLEID_WORD_SPACING, p, 0);
1236 }
1237
1238 static HRESULT WINAPI HTMLStyle_put_letterSpacing(IHTMLStyle *iface, VARIANT v)
1239 {
1240     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1241     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1242     return set_nsstyle_attr_var(This->nsstyle, STYLEID_LETTER_SPACING, &v, 0);
1243 }
1244
1245 static HRESULT WINAPI HTMLStyle_get_letterSpacing(IHTMLStyle *iface, VARIANT *p)
1246 {
1247     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1248     TRACE("(%p)->(%p)\n", This, p);
1249     return get_nsstyle_attr_var(This->nsstyle, STYLEID_LETTER_SPACING, p, 0);
1250 }
1251
1252 static HRESULT WINAPI HTMLStyle_put_textDecoration(IHTMLStyle *iface, BSTR v)
1253 {
1254     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1255
1256     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1257
1258     /* textDecoration can only be one of the following */
1259     if(!v || strcmpiW(styleNone, v)   == 0 || strcmpiW(valUnderline, v)   == 0 ||
1260              strcmpiW(valOverline, v) == 0 || strcmpiW(valLineThrough, v) == 0 ||
1261              strcmpiW(valBlink, v)    == 0)
1262     {
1263         return set_style_attr(This, STYLEID_TEXT_DECORATION , v, 0);
1264     }
1265
1266     return E_INVALIDARG;
1267 }
1268
1269 static HRESULT WINAPI HTMLStyle_get_textDecoration(IHTMLStyle *iface, BSTR *p)
1270 {
1271     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1272
1273     TRACE("(%p)->(%p)\n", This, p);
1274
1275     return get_style_attr(This, STYLEID_TEXT_DECORATION, p);
1276 }
1277
1278 static HRESULT WINAPI HTMLStyle_put_textDecorationNone(IHTMLStyle *iface, VARIANT_BOOL v)
1279 {
1280     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1281
1282     TRACE("(%p)->(%x)\n", This, v);
1283
1284     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? styleNone : emptyW, 0);
1285 }
1286
1287 static HRESULT WINAPI HTMLStyle_get_textDecorationNone(IHTMLStyle *iface, VARIANT_BOOL *p)
1288 {
1289     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1290
1291     TRACE("(%p)->(%p)\n", This, p);
1292
1293     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, styleNone, p);
1294 }
1295
1296 static HRESULT WINAPI HTMLStyle_put_textDecorationUnderline(IHTMLStyle *iface, VARIANT_BOOL v)
1297 {
1298     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1299
1300     TRACE("(%p)->(%x)\n", This, v);
1301
1302     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valUnderline : emptyW, 0);
1303 }
1304
1305 static HRESULT WINAPI HTMLStyle_get_textDecorationUnderline(IHTMLStyle *iface, VARIANT_BOOL *p)
1306 {
1307     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1308
1309     TRACE("(%p)->(%p)\n", This, p);
1310
1311     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valUnderline, p);
1312 }
1313
1314 static HRESULT WINAPI HTMLStyle_put_textDecorationOverline(IHTMLStyle *iface, VARIANT_BOOL v)
1315 {
1316     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1317
1318     TRACE("(%p)->(%x)\n", This, v);
1319
1320     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valOverline : emptyW, 0);
1321 }
1322
1323 static HRESULT WINAPI HTMLStyle_get_textDecorationOverline(IHTMLStyle *iface, VARIANT_BOOL *p)
1324 {
1325     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1326
1327     TRACE("(%p)->(%p)\n", This, p);
1328
1329     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valOverline, p);
1330 }
1331
1332 static HRESULT WINAPI HTMLStyle_put_textDecorationLineThrough(IHTMLStyle *iface, VARIANT_BOOL v)
1333 {
1334     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1335
1336     TRACE("(%p)->(%x)\n", This, v);
1337
1338     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valLineThrough : emptyW, 0);
1339 }
1340
1341 static HRESULT WINAPI HTMLStyle_get_textDecorationLineThrough(IHTMLStyle *iface, VARIANT_BOOL *p)
1342 {
1343     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1344
1345     TRACE("(%p)->(%p)\n", This, p);
1346
1347     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valLineThrough, p);
1348 }
1349
1350 static HRESULT WINAPI HTMLStyle_put_textDecorationBlink(IHTMLStyle *iface, VARIANT_BOOL v)
1351 {
1352     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1353
1354     TRACE("(%p)->(%x)\n", This, v);
1355
1356     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valBlink : emptyW, 0);
1357 }
1358
1359 static HRESULT WINAPI HTMLStyle_get_textDecorationBlink(IHTMLStyle *iface, VARIANT_BOOL *p)
1360 {
1361     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1362
1363     TRACE("(%p)->(%p)\n", This, p);
1364
1365     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valBlink, p);
1366 }
1367
1368 static HRESULT WINAPI HTMLStyle_put_verticalAlign(IHTMLStyle *iface, VARIANT v)
1369 {
1370     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1371
1372     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1373
1374     switch(V_VT(&v)) {
1375     case VT_BSTR:
1376         return set_style_attr(This, STYLEID_VERTICAL_ALIGN, V_BSTR(&v), 0);
1377     default:
1378         FIXME("not implemented vt %d\n", V_VT(&v));
1379         return E_NOTIMPL;
1380     }
1381
1382     return S_OK;
1383 }
1384
1385 static HRESULT WINAPI HTMLStyle_get_verticalAlign(IHTMLStyle *iface, VARIANT *p)
1386 {
1387     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1388     BSTR ret;
1389     HRESULT hres;
1390
1391     TRACE("(%p)->(%p)\n", This, p);
1392
1393     hres = get_style_attr(This, STYLEID_VERTICAL_ALIGN, &ret);
1394     if(FAILED(hres))
1395         return hres;
1396
1397     V_VT(p) = VT_BSTR;
1398     V_BSTR(p) = ret;
1399     return S_OK;
1400 }
1401
1402 static HRESULT WINAPI HTMLStyle_put_textTransform(IHTMLStyle *iface, BSTR v)
1403 {
1404     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1405     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1406     return E_NOTIMPL;
1407 }
1408
1409 static HRESULT WINAPI HTMLStyle_get_textTransform(IHTMLStyle *iface, BSTR *p)
1410 {
1411     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1412     FIXME("(%p)->(%p)\n", This, p);
1413     return E_NOTIMPL;
1414 }
1415
1416 static HRESULT WINAPI HTMLStyle_put_textAlign(IHTMLStyle *iface, BSTR v)
1417 {
1418     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1419
1420     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1421
1422     return set_style_attr(This, STYLEID_TEXT_ALIGN, v, 0);
1423 }
1424
1425 static HRESULT WINAPI HTMLStyle_get_textAlign(IHTMLStyle *iface, BSTR *p)
1426 {
1427     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1428
1429     TRACE("(%p)->(%p)\n", This, p);
1430
1431     return get_style_attr(This, STYLEID_TEXT_ALIGN, p);
1432 }
1433
1434 static HRESULT WINAPI HTMLStyle_put_textIndent(IHTMLStyle *iface, VARIANT v)
1435 {
1436     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1437     FIXME("(%p)->(v%d)\n", This, V_VT(&v));
1438     return E_NOTIMPL;
1439 }
1440
1441 static HRESULT WINAPI HTMLStyle_get_textIndent(IHTMLStyle *iface, VARIANT *p)
1442 {
1443     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1444     FIXME("(%p)->(%p)\n", This, p);
1445     return E_NOTIMPL;
1446 }
1447
1448 static HRESULT WINAPI HTMLStyle_put_lineHeight(IHTMLStyle *iface, VARIANT v)
1449 {
1450     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1451     FIXME("(%p)->(v%d)\n", This, V_VT(&v));
1452     return E_NOTIMPL;
1453 }
1454
1455 static HRESULT WINAPI HTMLStyle_get_lineHeight(IHTMLStyle *iface, VARIANT *p)
1456 {
1457     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1458     FIXME("(%p)->(%p)\n", This, p);
1459     return E_NOTIMPL;
1460 }
1461
1462 static HRESULT WINAPI HTMLStyle_put_marginTop(IHTMLStyle *iface, VARIANT v)
1463 {
1464     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1465
1466     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1467
1468     return set_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_TOP, &v, 0);
1469 }
1470
1471 static HRESULT WINAPI HTMLStyle_get_marginTop(IHTMLStyle *iface, VARIANT *p)
1472 {
1473     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1474
1475     TRACE("(%p)->(%p)\n", This, p);
1476
1477     return get_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_TOP, p, 0);
1478 }
1479
1480 static HRESULT WINAPI HTMLStyle_put_marginRight(IHTMLStyle *iface, VARIANT v)
1481 {
1482     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1483
1484     TRACE("(%p)->(v(%d))\n", This, V_VT(&v));
1485
1486     switch(V_VT(&v)) {
1487     case VT_NULL:
1488         return set_style_attr(This, STYLEID_MARGIN_RIGHT, emptyW, 0);
1489     case VT_I4: {
1490         WCHAR buf[14];
1491
1492         wsprintfW(buf, px_formatW, V_I4(&v));
1493         return set_style_attr(This, STYLEID_MARGIN_RIGHT, buf, 0);
1494     }
1495     case VT_BSTR:
1496         return set_style_attr(This, STYLEID_MARGIN_RIGHT, V_BSTR(&v), 0);
1497     default:
1498         FIXME("Unsupported vt=%d\n", V_VT(&v));
1499     }
1500
1501     return E_NOTIMPL;
1502 }
1503
1504 static HRESULT WINAPI HTMLStyle_get_marginRight(IHTMLStyle *iface, VARIANT *p)
1505 {
1506     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1507     TRACE("(%p)->(%p)\n", This, p);
1508     return get_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_RIGHT, p, 0);
1509 }
1510
1511 static HRESULT WINAPI HTMLStyle_put_marginBottom(IHTMLStyle *iface, VARIANT v)
1512 {
1513     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1514     FIXME("(%p)->(v%d)\n", This, V_VT(&v));
1515     return E_NOTIMPL;
1516 }
1517
1518 static HRESULT WINAPI HTMLStyle_get_marginBottom(IHTMLStyle *iface, VARIANT *p)
1519 {
1520     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1521     FIXME("(%p)->(%p)\n", This, p);
1522     return E_NOTIMPL;
1523 }
1524
1525 static HRESULT WINAPI HTMLStyle_put_marginLeft(IHTMLStyle *iface, VARIANT v)
1526 {
1527     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1528
1529     switch(V_VT(&v)) {
1530     case VT_NULL:
1531         TRACE("(%p)->(NULL)\n", This);
1532         return set_style_attr(This, STYLEID_MARGIN_LEFT, emptyW, 0);
1533     case VT_I4: {
1534         WCHAR buf[14];
1535
1536         TRACE("(%p)->(%d)\n", This, V_I4(&v));
1537
1538         wsprintfW(buf, px_formatW, V_I4(&v));
1539         return set_style_attr(This, STYLEID_MARGIN_LEFT, buf, 0);
1540     }
1541     case VT_BSTR:
1542         TRACE("(%p)->(%s)\n", This, debugstr_w(V_BSTR(&v)));
1543         return set_style_attr(This, STYLEID_MARGIN_LEFT, V_BSTR(&v), 0);
1544     default:
1545         FIXME("Unsupported vt=%d\n", V_VT(&v));
1546     }
1547
1548     return E_NOTIMPL;
1549 }
1550
1551 static HRESULT WINAPI HTMLStyle_put_margin(IHTMLStyle *iface, BSTR v)
1552 {
1553     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1554
1555     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1556
1557     return set_style_attr(This, STYLEID_MARGIN, v, 0);
1558 }
1559
1560 static HRESULT WINAPI HTMLStyle_get_margin(IHTMLStyle *iface, BSTR *p)
1561 {
1562     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1563
1564     TRACE("(%p)->(%p)\n", This, p);
1565
1566     return get_style_attr(This, STYLEID_MARGIN, p);
1567 }
1568
1569 static HRESULT WINAPI HTMLStyle_get_marginLeft(IHTMLStyle *iface, VARIANT *p)
1570 {
1571     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1572     TRACE("(%p)->(%p)\n", This, p);
1573     return get_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_LEFT, p, 0);
1574 }
1575
1576 static HRESULT WINAPI HTMLStyle_put_paddingTop(IHTMLStyle *iface, VARIANT v)
1577 {
1578     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1579     FIXME("(%p)->(v%d)\n", This, V_VT(&v));
1580     return E_NOTIMPL;
1581 }
1582
1583 static HRESULT WINAPI HTMLStyle_get_paddingTop(IHTMLStyle *iface, VARIANT *p)
1584 {
1585     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1586     FIXME("(%p)->(%p)\n", This, p);
1587     return E_NOTIMPL;
1588 }
1589
1590 static HRESULT WINAPI HTMLStyle_put_paddingRight(IHTMLStyle *iface, VARIANT v)
1591 {
1592     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1593     FIXME("(%p)->(v%d)\n", This, V_VT(&v));
1594     return E_NOTIMPL;
1595 }
1596
1597 static HRESULT WINAPI HTMLStyle_get_paddingRight(IHTMLStyle *iface, VARIANT *p)
1598 {
1599     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1600     FIXME("(%p)->(%p)\n", This, p);
1601     return E_NOTIMPL;
1602 }
1603
1604 static HRESULT WINAPI HTMLStyle_put_paddingBottom(IHTMLStyle *iface, VARIANT v)
1605 {
1606     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1607     FIXME("(%p)->(v%d)\n", This, V_VT(&v));
1608     return E_NOTIMPL;
1609 }
1610
1611 static HRESULT WINAPI HTMLStyle_get_paddingBottom(IHTMLStyle *iface, VARIANT *p)
1612 {
1613     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1614     FIXME("(%p)->(%p)\n", This, p);
1615     return E_NOTIMPL;
1616 }
1617
1618 static HRESULT WINAPI HTMLStyle_put_paddingLeft(IHTMLStyle *iface, VARIANT v)
1619 {
1620     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1621
1622     TRACE("(%p)->(vt=%d)\n", This, V_VT(&v));
1623
1624     switch(V_VT(&v)) {
1625     case VT_I4: {
1626         WCHAR buf[14];
1627
1628         wsprintfW(buf, px_formatW, V_I4(&v));
1629         return set_style_attr(This, STYLEID_PADDING_LEFT, buf, 0);
1630     }
1631     case VT_BSTR:
1632         return set_style_attr(This, STYLEID_PADDING_LEFT, V_BSTR(&v), 0);
1633     default:
1634         FIXME("unsupported vt=%d\n", V_VT(&v));
1635     }
1636
1637     return E_NOTIMPL;
1638 }
1639
1640 static HRESULT WINAPI HTMLStyle_get_paddingLeft(IHTMLStyle *iface, VARIANT *p)
1641 {
1642     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1643     BSTR ret;
1644     HRESULT hres;
1645
1646     TRACE("(%p)->(%p)\n", This, p);
1647
1648     hres = get_style_attr(This, STYLEID_PADDING_LEFT, &ret);
1649     if(FAILED(hres))
1650         return hres;
1651
1652     V_VT(p) = VT_BSTR;
1653     V_BSTR(p) = ret;
1654     return S_OK;
1655 }
1656
1657 static HRESULT WINAPI HTMLStyle_put_padding(IHTMLStyle *iface, BSTR v)
1658 {
1659     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1660
1661     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1662
1663     return set_style_attr(This, STYLEID_PADDING, v, 0);
1664 }
1665
1666 static HRESULT WINAPI HTMLStyle_get_padding(IHTMLStyle *iface, BSTR *p)
1667 {
1668     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1669
1670     TRACE("(%p)->(%p)\n", This, p);
1671
1672     return get_style_attr(This, STYLEID_PADDING, p);
1673 }
1674
1675 static HRESULT WINAPI HTMLStyle_put_border(IHTMLStyle *iface, BSTR v)
1676 {
1677     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1678
1679     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1680
1681     return set_style_attr(This, STYLEID_BORDER, v, 0);
1682 }
1683
1684 static HRESULT WINAPI HTMLStyle_get_border(IHTMLStyle *iface, BSTR *p)
1685 {
1686     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1687
1688     TRACE("(%p)->(%p)\n", This, p);
1689
1690     return get_style_attr(This, STYLEID_BORDER, p);
1691 }
1692
1693 static HRESULT WINAPI HTMLStyle_put_borderTop(IHTMLStyle *iface, BSTR v)
1694 {
1695     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1696     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1697     return set_style_attr(This, STYLEID_BORDER_TOP, v, ATTR_FIX_PX);
1698 }
1699
1700 static HRESULT WINAPI HTMLStyle_get_borderTop(IHTMLStyle *iface, BSTR *p)
1701 {
1702     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1703     TRACE("(%p)->(%p)\n", This, p);
1704     return get_style_attr(This, STYLEID_BORDER_TOP, p);
1705 }
1706
1707 static HRESULT WINAPI HTMLStyle_put_borderRight(IHTMLStyle *iface, BSTR v)
1708 {
1709     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1710     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1711     return set_style_attr(This, STYLEID_BORDER_RIGHT, v, ATTR_FIX_PX);
1712 }
1713
1714 static HRESULT WINAPI HTMLStyle_get_borderRight(IHTMLStyle *iface, BSTR *p)
1715 {
1716     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1717     TRACE("(%p)->(%p)\n", This, p);
1718     return get_style_attr(This, STYLEID_BORDER_RIGHT, p);
1719 }
1720
1721 static HRESULT WINAPI HTMLStyle_put_borderBottom(IHTMLStyle *iface, BSTR v)
1722 {
1723     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1724     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1725     return set_style_attr(This, STYLEID_BORDER_BOTTOM, v, ATTR_FIX_PX);
1726 }
1727
1728 static HRESULT WINAPI HTMLStyle_get_borderBottom(IHTMLStyle *iface, BSTR *p)
1729 {
1730     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1731     TRACE("(%p)->(%p)\n", This, p);
1732     return get_style_attr(This, STYLEID_BORDER_BOTTOM, p);
1733 }
1734
1735 static HRESULT WINAPI HTMLStyle_put_borderLeft(IHTMLStyle *iface, BSTR v)
1736 {
1737     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1738
1739     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1740
1741     return set_style_attr(This, STYLEID_BORDER_LEFT, v, ATTR_FIX_PX);
1742 }
1743
1744 static HRESULT WINAPI HTMLStyle_get_borderLeft(IHTMLStyle *iface, BSTR *p)
1745 {
1746     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1747
1748     TRACE("(%p)->(%p)\n", This, p);
1749
1750     return get_style_attr(This, STYLEID_BORDER_LEFT, p);
1751 }
1752
1753 static HRESULT WINAPI HTMLStyle_put_borderColor(IHTMLStyle *iface, BSTR v)
1754 {
1755     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1756
1757     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1758
1759     return set_style_attr(This, STYLEID_BORDER_COLOR, v, 0);
1760 }
1761
1762 static HRESULT WINAPI HTMLStyle_get_borderColor(IHTMLStyle *iface, BSTR *p)
1763 {
1764     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1765
1766     TRACE("(%p)->(%p)\n", This, p);
1767
1768     return get_style_attr(This, STYLEID_BORDER_COLOR, p);
1769 }
1770
1771 static HRESULT WINAPI HTMLStyle_put_borderTopColor(IHTMLStyle *iface, VARIANT v)
1772 {
1773     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1774
1775     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1776
1777     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_COLOR, &v, ATTR_HEX_INT);
1778 }
1779
1780 static HRESULT WINAPI HTMLStyle_get_borderTopColor(IHTMLStyle *iface, VARIANT *p)
1781 {
1782     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1783
1784     TRACE("(%p)->(%p)\n", This, p);
1785
1786     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_COLOR, p, 0);
1787 }
1788
1789 static HRESULT WINAPI HTMLStyle_put_borderRightColor(IHTMLStyle *iface, VARIANT v)
1790 {
1791     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1792
1793     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1794
1795     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_COLOR, &v, ATTR_HEX_INT);
1796 }
1797
1798 static HRESULT WINAPI HTMLStyle_get_borderRightColor(IHTMLStyle *iface, VARIANT *p)
1799 {
1800     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1801
1802     TRACE("(%p)->(%p)\n", This, p);
1803
1804     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_COLOR, p, 0);
1805 }
1806
1807 static HRESULT WINAPI HTMLStyle_put_borderBottomColor(IHTMLStyle *iface, VARIANT v)
1808 {
1809     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1810
1811     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1812
1813     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_COLOR, &v, ATTR_HEX_INT);
1814 }
1815
1816 static HRESULT WINAPI HTMLStyle_get_borderBottomColor(IHTMLStyle *iface, VARIANT *p)
1817 {
1818     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1819
1820     TRACE("(%p)->(%p)\n", This, p);
1821
1822     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_COLOR, p, 0);
1823 }
1824
1825 static HRESULT WINAPI HTMLStyle_put_borderLeftColor(IHTMLStyle *iface, VARIANT v)
1826 {
1827     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1828
1829     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1830
1831     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_COLOR, &v, ATTR_HEX_INT);
1832 }
1833
1834 static HRESULT WINAPI HTMLStyle_get_borderLeftColor(IHTMLStyle *iface, VARIANT *p)
1835 {
1836     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1837
1838     TRACE("(%p)->(%p)\n", This, p);
1839
1840     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_COLOR, p, 0);
1841 }
1842
1843 static HRESULT WINAPI HTMLStyle_put_borderWidth(IHTMLStyle *iface, BSTR v)
1844 {
1845     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1846     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1847     return set_style_attr(This, STYLEID_BORDER_WIDTH, v, ATTR_FIX_PX);
1848 }
1849
1850 static HRESULT WINAPI HTMLStyle_get_borderWidth(IHTMLStyle *iface, BSTR *p)
1851 {
1852     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1853     TRACE("(%p)->(%p)\n", This, p);
1854     return get_style_attr(This, STYLEID_BORDER_WIDTH, p);
1855 }
1856
1857 static HRESULT WINAPI HTMLStyle_put_borderTopWidth(IHTMLStyle *iface, VARIANT v)
1858 {
1859     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1860     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1861     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_WIDTH, &v, 0);
1862 }
1863
1864 static HRESULT WINAPI HTMLStyle_get_borderTopWidth(IHTMLStyle *iface, VARIANT *p)
1865 {
1866     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1867
1868     TRACE("(%p)->(%p)\n", This, p);
1869
1870     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_WIDTH, p, 0);
1871 }
1872
1873 static HRESULT WINAPI HTMLStyle_put_borderRightWidth(IHTMLStyle *iface, VARIANT v)
1874 {
1875     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1876     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1877     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_WIDTH, &v, 0);
1878 }
1879
1880 static HRESULT WINAPI HTMLStyle_get_borderRightWidth(IHTMLStyle *iface, VARIANT *p)
1881 {
1882     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1883     TRACE("(%p)->(%p)\n", This, p);
1884     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_WIDTH, p, 0);
1885 }
1886
1887 static HRESULT WINAPI HTMLStyle_put_borderBottomWidth(IHTMLStyle *iface, VARIANT v)
1888 {
1889     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1890
1891     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1892     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_WIDTH, &v, 0);
1893 }
1894
1895 static HRESULT WINAPI HTMLStyle_get_borderBottomWidth(IHTMLStyle *iface, VARIANT *p)
1896 {
1897     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1898     TRACE("(%p)->(%p)\n", This, p);
1899     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_WIDTH, p, 0);
1900 }
1901
1902 static HRESULT WINAPI HTMLStyle_put_borderLeftWidth(IHTMLStyle *iface, VARIANT v)
1903 {
1904     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1905     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
1906     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_WIDTH, &v, 0);
1907 }
1908
1909 static HRESULT WINAPI HTMLStyle_get_borderLeftWidth(IHTMLStyle *iface, VARIANT *p)
1910 {
1911     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1912     TRACE("(%p)->(%p)\n", This, p);
1913     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_WIDTH, p, 0);
1914 }
1915
1916 static HRESULT WINAPI HTMLStyle_put_borderStyle(IHTMLStyle *iface, BSTR v)
1917 {
1918     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1919     static const WCHAR styleWindowInset[]  = {'w','i','n','d','o','w','-','i','n','s','e','t',0};
1920     HRESULT hres = S_OK;
1921     BSTR pstyle;
1922     int i=0;
1923     int last = 0;
1924
1925     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1926
1927     while(v[i] && hres == S_OK)
1928     {
1929         if(v[i] == (WCHAR)' ')
1930         {
1931             pstyle = SysAllocStringLen(&v[last], (i-last));
1932             if( !(is_valid_border_style(pstyle) || strcmpiW(styleWindowInset, pstyle) == 0))
1933             {
1934                 TRACE("1. Invalid style (%s)\n", debugstr_w(pstyle));
1935                 hres = E_INVALIDARG;
1936             }
1937             SysFreeString(pstyle);
1938             last = i+1;
1939         }
1940         i++;
1941     }
1942
1943     if(hres == S_OK)
1944     {
1945         pstyle = SysAllocStringLen(&v[last], i-last);
1946         if( !(is_valid_border_style(pstyle) || strcmpiW(styleWindowInset, pstyle) == 0))
1947         {
1948             TRACE("2. Invalid style (%s)\n", debugstr_w(pstyle));
1949             hres = E_INVALIDARG;
1950         }
1951         SysFreeString(pstyle);
1952     }
1953
1954     if(hres == S_OK)
1955         hres = set_nsstyle_attr(This->nsstyle, STYLEID_BORDER_STYLE, v, 0);
1956
1957     return hres;
1958 }
1959
1960 static HRESULT WINAPI HTMLStyle_get_borderStyle(IHTMLStyle *iface, BSTR *p)
1961 {
1962     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1963     TRACE("(%p)->(%p)\n", This, p);
1964     return get_style_attr(This, STYLEID_BORDER_STYLE, p);
1965 }
1966
1967 static HRESULT WINAPI HTMLStyle_put_borderTopStyle(IHTMLStyle *iface, BSTR v)
1968 {
1969     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1970     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1971
1972     if(!is_valid_border_style(v))
1973         return E_INVALIDARG;
1974
1975     return set_style_attr(This, STYLEID_BORDER_TOP_STYLE, v, 0);
1976 }
1977
1978 static HRESULT WINAPI HTMLStyle_get_borderTopStyle(IHTMLStyle *iface, BSTR *p)
1979 {
1980     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1981     TRACE("(%p)->(%p)\n", This, p);
1982     return get_style_attr(This, STYLEID_BORDER_TOP_STYLE, p);
1983 }
1984
1985 static HRESULT WINAPI HTMLStyle_put_borderRightStyle(IHTMLStyle *iface, BSTR v)
1986 {
1987     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1988     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1989
1990     if(!is_valid_border_style(v))
1991         return E_INVALIDARG;
1992
1993     return set_style_attr(This, STYLEID_BORDER_RIGHT_STYLE, v, 0);
1994 }
1995
1996 static HRESULT WINAPI HTMLStyle_get_borderRightStyle(IHTMLStyle *iface, BSTR *p)
1997 {
1998     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1999     TRACE("(%p)->(%p)\n", This, p);
2000     return get_style_attr(This, STYLEID_BORDER_RIGHT_STYLE, p);
2001 }
2002
2003 static HRESULT WINAPI HTMLStyle_put_borderBottomStyle(IHTMLStyle *iface, BSTR v)
2004 {
2005     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2006     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2007
2008     if(!is_valid_border_style(v))
2009         return E_INVALIDARG;
2010
2011     return set_style_attr(This, STYLEID_BORDER_BOTTOM_STYLE, v, 0);
2012 }
2013
2014 static HRESULT WINAPI HTMLStyle_get_borderBottomStyle(IHTMLStyle *iface, BSTR *p)
2015 {
2016     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2017     TRACE("(%p)->(%p)\n", This, p);
2018     return get_style_attr(This, STYLEID_BORDER_BOTTOM_STYLE, p);
2019 }
2020
2021 static HRESULT WINAPI HTMLStyle_put_borderLeftStyle(IHTMLStyle *iface, BSTR v)
2022 {
2023     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2024     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2025
2026     if(!is_valid_border_style(v))
2027         return E_INVALIDARG;
2028
2029     return set_style_attr(This, STYLEID_BORDER_LEFT_STYLE, v, 0);
2030 }
2031
2032 static HRESULT WINAPI HTMLStyle_get_borderLeftStyle(IHTMLStyle *iface, BSTR *p)
2033 {
2034     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2035     TRACE("(%p)->(%p)\n", This, p);
2036     return get_style_attr(This, STYLEID_BORDER_LEFT_STYLE, p);
2037 }
2038
2039 static HRESULT WINAPI HTMLStyle_put_width(IHTMLStyle *iface, VARIANT v)
2040 {
2041     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2042
2043     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
2044
2045     return set_nsstyle_attr_var(This->nsstyle, STYLEID_WIDTH, &v, ATTR_FIX_PX);
2046 }
2047
2048 static HRESULT WINAPI HTMLStyle_get_width(IHTMLStyle *iface, VARIANT *p)
2049 {
2050     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2051
2052     TRACE("(%p)->(%p)\n", This, p);
2053
2054     V_VT(p) = VT_BSTR;
2055     return get_style_attr(This, STYLEID_WIDTH, &V_BSTR(p));
2056 }
2057
2058 static HRESULT WINAPI HTMLStyle_put_height(IHTMLStyle *iface, VARIANT v)
2059 {
2060     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2061
2062     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2063
2064     switch(V_VT(&v)) {
2065     case VT_BSTR:
2066         return set_style_attr(This, STYLEID_HEIGHT, V_BSTR(&v), 0);
2067     default:
2068         FIXME("unimplemented vt %d\n", V_VT(&v));
2069         return E_NOTIMPL;
2070     }
2071
2072     return S_OK;
2073 }
2074
2075 static HRESULT WINAPI HTMLStyle_get_height(IHTMLStyle *iface, VARIANT *p)
2076 {
2077     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2078     BSTR ret;
2079     HRESULT hres;
2080
2081     TRACE("(%p)->(%p)\n", This, p);
2082
2083     hres = get_style_attr(This, STYLEID_HEIGHT, &ret);
2084     if(FAILED(hres))
2085         return hres;
2086
2087     V_VT(p) = VT_BSTR;
2088     V_BSTR(p) = ret;
2089     return S_OK;
2090 }
2091
2092 static HRESULT WINAPI HTMLStyle_put_styleFloat(IHTMLStyle *iface, BSTR v)
2093 {
2094     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2095     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2096     return E_NOTIMPL;
2097 }
2098
2099 static HRESULT WINAPI HTMLStyle_get_styleFloat(IHTMLStyle *iface, BSTR *p)
2100 {
2101     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2102     FIXME("(%p)->(%p)\n", This, p);
2103     return E_NOTIMPL;
2104 }
2105
2106 static HRESULT WINAPI HTMLStyle_put_clear(IHTMLStyle *iface, BSTR v)
2107 {
2108     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2109     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2110     return E_NOTIMPL;
2111 }
2112
2113 static HRESULT WINAPI HTMLStyle_get_clear(IHTMLStyle *iface, BSTR *p)
2114 {
2115     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2116     FIXME("(%p)->(%p)\n", This, p);
2117     return E_NOTIMPL;
2118 }
2119
2120 static HRESULT WINAPI HTMLStyle_put_display(IHTMLStyle *iface, BSTR v)
2121 {
2122     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2123
2124     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2125
2126     return set_style_attr(This, STYLEID_DISPLAY, v, 0);
2127 }
2128
2129 static HRESULT WINAPI HTMLStyle_get_display(IHTMLStyle *iface, BSTR *p)
2130 {
2131     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2132
2133     TRACE("(%p)->(%p)\n", This, p);
2134
2135     return get_style_attr(This, STYLEID_DISPLAY, p);
2136 }
2137
2138 static HRESULT WINAPI HTMLStyle_put_visibility(IHTMLStyle *iface, BSTR v)
2139 {
2140     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2141
2142     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2143
2144     return set_style_attr(This, STYLEID_VISIBILITY, v, 0);
2145 }
2146
2147 static HRESULT WINAPI HTMLStyle_get_visibility(IHTMLStyle *iface, BSTR *p)
2148 {
2149     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2150
2151     TRACE("(%p)->(%p)\n", This, p);
2152
2153     return get_style_attr(This, STYLEID_VISIBILITY, p);
2154 }
2155
2156 static HRESULT WINAPI HTMLStyle_put_listStyleType(IHTMLStyle *iface, BSTR v)
2157 {
2158     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2159     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2160     return E_NOTIMPL;
2161 }
2162
2163 static HRESULT WINAPI HTMLStyle_get_listStyleType(IHTMLStyle *iface, BSTR *p)
2164 {
2165     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2166     FIXME("(%p)->(%p)\n", This, p);
2167     return E_NOTIMPL;
2168 }
2169
2170 static HRESULT WINAPI HTMLStyle_put_listStylePosition(IHTMLStyle *iface, BSTR v)
2171 {
2172     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2173     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2174     return E_NOTIMPL;
2175 }
2176
2177 static HRESULT WINAPI HTMLStyle_get_listStylePosition(IHTMLStyle *iface, BSTR *p)
2178 {
2179     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2180     FIXME("(%p)->(%p)\n", This, p);
2181     return E_NOTIMPL;
2182 }
2183
2184 static HRESULT WINAPI HTMLStyle_put_listStyleImage(IHTMLStyle *iface, BSTR v)
2185 {
2186     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2187     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2188     return E_NOTIMPL;
2189 }
2190
2191 static HRESULT WINAPI HTMLStyle_get_listStyleImage(IHTMLStyle *iface, BSTR *p)
2192 {
2193     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2194     FIXME("(%p)->(%p)\n", This, p);
2195     return E_NOTIMPL;
2196 }
2197
2198 static HRESULT WINAPI HTMLStyle_put_listStyle(IHTMLStyle *iface, BSTR v)
2199 {
2200     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2201     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2202     return E_NOTIMPL;
2203 }
2204
2205 static HRESULT WINAPI HTMLStyle_get_listStyle(IHTMLStyle *iface, BSTR *p)
2206 {
2207     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2208     FIXME("(%p)->(%p)\n", This, p);
2209     return E_NOTIMPL;
2210 }
2211
2212 static HRESULT WINAPI HTMLStyle_put_whiteSpace(IHTMLStyle *iface, BSTR v)
2213 {
2214     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2215     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2216     return E_NOTIMPL;
2217 }
2218
2219 static HRESULT WINAPI HTMLStyle_get_whiteSpace(IHTMLStyle *iface, BSTR *p)
2220 {
2221     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2222     FIXME("(%p)->(%p)\n", This, p);
2223     return E_NOTIMPL;
2224 }
2225
2226 static HRESULT WINAPI HTMLStyle_put_top(IHTMLStyle *iface, VARIANT v)
2227 {
2228     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2229
2230     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2231
2232     return set_nsstyle_attr_var(This->nsstyle, STYLEID_TOP, &v, 0);
2233 }
2234
2235 static HRESULT WINAPI HTMLStyle_get_top(IHTMLStyle *iface, VARIANT *p)
2236 {
2237     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2238     BSTR ret;
2239     HRESULT hres;
2240
2241     TRACE("(%p)->(%p)\n", This, p);
2242
2243     hres = get_style_attr(This, STYLEID_TOP, &ret);
2244     if(FAILED(hres))
2245         return hres;
2246
2247     V_VT(p) = VT_BSTR;
2248     V_BSTR(p) = ret;
2249     return S_OK;
2250 }
2251
2252 static HRESULT WINAPI HTMLStyle_put_left(IHTMLStyle *iface, VARIANT v)
2253 {
2254     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2255
2256     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2257
2258     return set_nsstyle_attr_var(This->nsstyle, STYLEID_LEFT, &v, 0);
2259 }
2260
2261 static HRESULT WINAPI HTMLStyle_get_left(IHTMLStyle *iface, VARIANT *p)
2262 {
2263     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2264     BSTR ret;
2265     HRESULT hres;
2266
2267     TRACE("(%p)->(%p)\n", This, p);
2268
2269     hres = get_style_attr(This, STYLEID_LEFT, &ret);
2270     if(FAILED(hres))
2271         return hres;
2272
2273     V_VT(p) = VT_BSTR;
2274     V_BSTR(p) = ret;
2275     return S_OK;
2276 }
2277
2278 static HRESULT WINAPI HTMLStyle_get_position(IHTMLStyle *iface, BSTR *p)
2279 {
2280     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2281     TRACE("(%p)->(%p)\n", This, p);
2282     return IHTMLStyle2_get_position(&This->IHTMLStyle2_iface, p);
2283 }
2284
2285 static HRESULT WINAPI HTMLStyle_put_zIndex(IHTMLStyle *iface, VARIANT v)
2286 {
2287     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2288
2289     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2290
2291     switch(V_VT(&v)) {
2292     case VT_BSTR:
2293         return set_style_attr(This, STYLEID_Z_INDEX, V_BSTR(&v), 0);
2294     case VT_I4: {
2295         WCHAR value[14];
2296         static const WCHAR format[] = {'%','d',0};
2297
2298         wsprintfW(value, format, V_I4(&v));
2299         return set_style_attr(This, STYLEID_Z_INDEX, value, 0);
2300     }
2301     default:
2302         FIXME("unimplemented vt %d\n", V_VT(&v));
2303         return E_NOTIMPL;
2304     }
2305
2306     return S_OK;
2307 }
2308
2309 static HRESULT WINAPI HTMLStyle_get_zIndex(IHTMLStyle *iface, VARIANT *p)
2310 {
2311     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2312
2313     TRACE("(%p)->(%p)\n", This, p);
2314
2315     return get_nsstyle_attr_var(This->nsstyle, STYLEID_Z_INDEX, p, ATTR_STR_TO_INT);
2316 }
2317
2318 static HRESULT WINAPI HTMLStyle_put_overflow(IHTMLStyle *iface, BSTR v)
2319 {
2320     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2321     static const WCHAR szVisible[] = {'v','i','s','i','b','l','e',0};
2322     static const WCHAR szScroll[]  = {'s','c','r','o','l','l',0};
2323     static const WCHAR szHidden[]  = {'h','i','d','d','e','n',0};
2324     static const WCHAR szAuto[]    = {'a','u','t','o',0};
2325
2326     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2327
2328     /* overflow can only be one of the follow values. */
2329     if(!v || !*v || strcmpiW(szVisible, v) == 0 || strcmpiW(szScroll, v) == 0 ||
2330              strcmpiW(szHidden, v) == 0  || strcmpiW(szAuto, v) == 0)
2331     {
2332         return set_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW, v, 0);
2333     }
2334
2335     return E_INVALIDARG;
2336 }
2337
2338
2339 static HRESULT WINAPI HTMLStyle_get_overflow(IHTMLStyle *iface, BSTR *p)
2340 {
2341     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2342
2343     TRACE("(%p)->(%p)\n", This, p);
2344
2345     if(!p)
2346        return E_INVALIDARG;
2347
2348     return get_style_attr(This, STYLEID_OVERFLOW, p);
2349 }
2350
2351 static HRESULT WINAPI HTMLStyle_put_pageBreakBefore(IHTMLStyle *iface, BSTR v)
2352 {
2353     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2354
2355     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2356
2357     return set_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_BEFORE, v, 0);
2358 }
2359
2360 static HRESULT WINAPI HTMLStyle_get_pageBreakBefore(IHTMLStyle *iface, BSTR *p)
2361 {
2362     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2363
2364     TRACE("(%p)->(%p)\n", This, p);
2365
2366     return get_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_BEFORE, p, 0);
2367 }
2368
2369 static HRESULT WINAPI HTMLStyle_put_pageBreakAfter(IHTMLStyle *iface, BSTR v)
2370 {
2371     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2372
2373     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2374
2375     return set_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_AFTER, v, 0);
2376 }
2377
2378 static HRESULT WINAPI HTMLStyle_get_pageBreakAfter(IHTMLStyle *iface, BSTR *p)
2379 {
2380     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2381
2382     TRACE("(%p)->(%p)\n", This, p);
2383
2384     return get_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_AFTER, p, 0);
2385 }
2386
2387 static HRESULT WINAPI HTMLStyle_put_cssText(IHTMLStyle *iface, BSTR v)
2388 {
2389     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2390     nsAString text_str;
2391     nsresult nsres;
2392
2393     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2394
2395     nsAString_InitDepend(&text_str, v);
2396     nsres = nsIDOMCSSStyleDeclaration_SetCssText(This->nsstyle, &text_str);
2397     nsAString_Finish(&text_str);
2398     if(NS_FAILED(nsres)) {
2399         FIXME("SetCssStyle failed: %08x\n", nsres);
2400         return E_FAIL;
2401     }
2402
2403     return S_OK;
2404 }
2405
2406 static HRESULT WINAPI HTMLStyle_get_cssText(IHTMLStyle *iface, BSTR *p)
2407 {
2408     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2409     nsAString text_str;
2410     nsresult nsres;
2411
2412     TRACE("(%p)->(%p)\n", This, p);
2413
2414     /* FIXME: Gecko style formatting is different than IE (uppercase). */
2415     nsAString_Init(&text_str, NULL);
2416     nsres = nsIDOMCSSStyleDeclaration_GetCssText(This->nsstyle, &text_str);
2417     if(NS_SUCCEEDED(nsres)) {
2418         const PRUnichar *text;
2419
2420         nsAString_GetData(&text_str, &text);
2421         *p = *text ? SysAllocString(text) : NULL;
2422     }else {
2423         FIXME("GetCssStyle failed: %08x\n", nsres);
2424         *p = NULL;
2425     }
2426
2427     nsAString_Finish(&text_str);
2428     return S_OK;
2429 }
2430
2431 static HRESULT WINAPI HTMLStyle_put_pixelTop(IHTMLStyle *iface, LONG v)
2432 {
2433     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2434     FIXME("(%p)->()\n", This);
2435     return E_NOTIMPL;
2436 }
2437
2438 static HRESULT WINAPI HTMLStyle_get_pixelTop(IHTMLStyle *iface, LONG *p)
2439 {
2440     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2441     FIXME("(%p)->()\n", This);
2442     return E_NOTIMPL;
2443 }
2444
2445 static HRESULT WINAPI HTMLStyle_put_pixelLeft(IHTMLStyle *iface, LONG v)
2446 {
2447     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2448     FIXME("(%p)->()\n", This);
2449     return E_NOTIMPL;
2450 }
2451
2452 static HRESULT WINAPI HTMLStyle_get_pixelLeft(IHTMLStyle *iface, LONG *p)
2453 {
2454     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2455     FIXME("(%p)->()\n", This);
2456     return E_NOTIMPL;
2457 }
2458
2459 static HRESULT WINAPI HTMLStyle_put_pixelWidth(IHTMLStyle *iface, LONG v)
2460 {
2461     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2462     FIXME("(%p)->()\n", This);
2463     return E_NOTIMPL;
2464 }
2465
2466 static HRESULT WINAPI HTMLStyle_get_pixelWidth(IHTMLStyle *iface, LONG *p)
2467 {
2468     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2469     FIXME("(%p)->()\n", This);
2470     return E_NOTIMPL;
2471 }
2472
2473 static HRESULT WINAPI HTMLStyle_put_pixelHeight(IHTMLStyle *iface, LONG v)
2474 {
2475     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2476     FIXME("(%p)->()\n", This);
2477     return E_NOTIMPL;
2478 }
2479
2480 static HRESULT WINAPI HTMLStyle_get_pixelHeight(IHTMLStyle *iface, LONG *p)
2481 {
2482     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2483     FIXME("(%p)->()\n", This);
2484     return E_NOTIMPL;
2485 }
2486
2487 static HRESULT WINAPI HTMLStyle_put_posTop(IHTMLStyle *iface, float v)
2488 {
2489     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2490
2491     TRACE("(%p)->(%f)\n", This, v);
2492
2493     return set_style_pos(This, STYLEID_TOP, v);
2494 }
2495
2496 static HRESULT WINAPI HTMLStyle_get_posTop(IHTMLStyle *iface, float *p)
2497 {
2498     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2499
2500     TRACE("(%p)->(%p)\n", This, p);
2501
2502     if(!p)
2503         return E_POINTER;
2504
2505     return get_nsstyle_pos(This, STYLEID_TOP, p);
2506 }
2507
2508 static HRESULT WINAPI HTMLStyle_put_posLeft(IHTMLStyle *iface, float v)
2509 {
2510     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2511
2512     TRACE("(%p)->(%f)\n", This, v);
2513
2514     return set_style_pos(This, STYLEID_LEFT, v);
2515 }
2516
2517 static HRESULT WINAPI HTMLStyle_get_posLeft(IHTMLStyle *iface, float *p)
2518 {
2519     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2520
2521     TRACE("(%p)->(%p)\n", This, p);
2522
2523     if(!p)
2524         return E_POINTER;
2525
2526     return get_nsstyle_pos(This, STYLEID_LEFT, p);
2527 }
2528
2529 static HRESULT WINAPI HTMLStyle_put_posWidth(IHTMLStyle *iface, float v)
2530 {
2531     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2532
2533     TRACE("(%p)->(%f)\n", This, v);
2534
2535     return set_style_pos(This, STYLEID_WIDTH, v);
2536 }
2537
2538 static HRESULT WINAPI HTMLStyle_get_posWidth(IHTMLStyle *iface, float *p)
2539 {
2540     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2541
2542     TRACE("(%p)->(%p)\n", This, p);
2543
2544     if(!p)
2545         return E_POINTER;
2546
2547     if(get_nsstyle_pos(This, STYLEID_WIDTH, p) != S_OK)
2548         *p = 0.0f;
2549
2550     return S_OK;
2551 }
2552
2553 static HRESULT WINAPI HTMLStyle_put_posHeight(IHTMLStyle *iface, float v)
2554 {
2555     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2556
2557     TRACE("(%p)->(%f)\n", This, v);
2558
2559     return set_style_pos(This, STYLEID_HEIGHT, v);
2560 }
2561
2562 static HRESULT WINAPI HTMLStyle_get_posHeight(IHTMLStyle *iface, float *p)
2563 {
2564     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2565
2566     TRACE("(%p)->(%p)\n", This, p);
2567
2568     if(!p)
2569         return E_POINTER;
2570
2571     if(get_nsstyle_pos(This, STYLEID_HEIGHT, p) != S_OK)
2572         *p = 0.0f;
2573
2574     return S_OK;
2575 }
2576
2577 static HRESULT WINAPI HTMLStyle_put_cursor(IHTMLStyle *iface, BSTR v)
2578 {
2579     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2580
2581     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2582
2583     return set_style_attr(This, STYLEID_CURSOR, v, 0);
2584 }
2585
2586 static HRESULT WINAPI HTMLStyle_get_cursor(IHTMLStyle *iface, BSTR *p)
2587 {
2588     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2589
2590     TRACE("(%p)->(%p)\n", This, p);
2591
2592     return get_style_attr(This, STYLEID_CURSOR, p);
2593 }
2594
2595 static HRESULT WINAPI HTMLStyle_put_clip(IHTMLStyle *iface, BSTR v)
2596 {
2597     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2598
2599     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2600
2601     return set_style_attr(This, STYLEID_CLIP, v, 0);
2602 }
2603
2604 static HRESULT WINAPI HTMLStyle_get_clip(IHTMLStyle *iface, BSTR *p)
2605 {
2606     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2607
2608     TRACE("(%p)->(%p)\n", This, p);
2609
2610     return get_nsstyle_attr(This->nsstyle, STYLEID_CLIP, p, ATTR_REMOVE_COMMA);
2611 }
2612
2613 static void set_opacity(HTMLStyle *This, const WCHAR *val)
2614 {
2615     nsAString name_str, val_str, empty_str;
2616     nsresult nsres;
2617
2618     static const WCHAR opacityW[] = {'o','p','a','c','i','t','y',0};
2619
2620     TRACE("%s\n", debugstr_w(val));
2621
2622     nsAString_InitDepend(&name_str, opacityW);
2623     nsAString_InitDepend(&val_str, val);
2624     nsAString_InitDepend(&empty_str, emptyW);
2625
2626     nsres = nsIDOMCSSStyleDeclaration_SetProperty(This->nsstyle, &name_str, &val_str, &empty_str);
2627     if(NS_FAILED(nsres))
2628         ERR("SetProperty failed: %08x\n", nsres);
2629
2630     nsAString_Finish(&name_str);
2631     nsAString_Finish(&val_str);
2632     nsAString_Finish(&empty_str);
2633 }
2634
2635 static void update_filter(HTMLStyle *This)
2636 {
2637     const WCHAR *ptr = This->filter, *ptr2;
2638
2639     static const WCHAR alphaW[] = {'a','l','p','h','a'};
2640
2641     if(!ptr) {
2642         set_opacity(This, emptyW);
2643         return;
2644     }
2645
2646     while(1) {
2647         while(isspaceW(*ptr))
2648             ptr++;
2649         if(!*ptr)
2650             break;
2651
2652         ptr2 = ptr;
2653         while(isalnumW(*ptr))
2654             ptr++;
2655         if(ptr == ptr2) {
2656             WARN("unexpected char '%c'\n", *ptr);
2657             break;
2658         }
2659         if(*ptr != '(') {
2660             WARN("expected '('\n");
2661             continue;
2662         }
2663
2664         if(ptr2 + sizeof(alphaW)/sizeof(WCHAR) == ptr && !memcmp(ptr2, alphaW, sizeof(alphaW))) {
2665             static const WCHAR formatW[] = {'%','f',0};
2666             static const WCHAR opacityW[] = {'o','p','a','c','i','t','y','='};
2667
2668             ptr++;
2669             do {
2670                 while(isspaceW(*ptr))
2671                     ptr++;
2672
2673                 ptr2 = ptr;
2674                 while(*ptr && *ptr != ',' && *ptr != ')')
2675                     ptr++;
2676                 if(!*ptr) {
2677                     WARN("unexpected end of string\n");
2678                     break;
2679                 }
2680
2681                 if(ptr-ptr2 > sizeof(opacityW)/sizeof(WCHAR) && !memcmp(ptr2, opacityW, sizeof(opacityW))) {
2682                     float fval = 0.0f, e = 0.1f;
2683                     WCHAR buf[32];
2684
2685                     ptr2 += sizeof(opacityW)/sizeof(WCHAR);
2686
2687                     while(isdigitW(*ptr2))
2688                         fval = fval*10.0f + (float)(*ptr2++ - '0');
2689
2690                     if(*ptr2 == '.') {
2691                         while(isdigitW(*++ptr2)) {
2692                             fval += e * (float)(*ptr2++ - '0');
2693                             e *= 0.1f;
2694                         }
2695                     }
2696
2697                     sprintfW(buf, formatW, fval * 0.01f);
2698                     set_opacity(This, buf);
2699                 }else {
2700                     FIXME("unknown param %s\n", debugstr_wn(ptr2, ptr-ptr2));
2701                 }
2702
2703                 if(*ptr == ',')
2704                     ptr++;
2705             }while(*ptr != ')');
2706         }else {
2707             FIXME("unknown filter %s\n", debugstr_wn(ptr2, ptr-ptr2));
2708             ptr = strchrW(ptr, ')');
2709             if(!ptr)
2710                 break;
2711             ptr++;
2712         }
2713     }
2714 }
2715
2716 static HRESULT WINAPI HTMLStyle_put_filter(IHTMLStyle *iface, BSTR v)
2717 {
2718     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2719     WCHAR *new_filter = NULL;
2720
2721     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2722
2723     if(v) {
2724         new_filter = heap_strdupW(v);
2725         if(!new_filter)
2726             return E_OUTOFMEMORY;
2727     }
2728
2729     heap_free(This->filter);
2730     This->filter = new_filter;
2731
2732     update_filter(This);
2733     return S_OK;
2734 }
2735
2736 static HRESULT WINAPI HTMLStyle_get_filter(IHTMLStyle *iface, BSTR *p)
2737 {
2738     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2739
2740     TRACE("(%p)->(%p)\n", This, p);
2741
2742     if(This->filter) {
2743         *p = SysAllocString(This->filter);
2744         if(!*p)
2745             return E_OUTOFMEMORY;
2746     }else {
2747         *p = NULL;
2748     }
2749
2750     return S_OK;
2751 }
2752
2753 static HRESULT WINAPI HTMLStyle_setAttribute(IHTMLStyle *iface, BSTR strAttributeName,
2754         VARIANT AttributeValue, LONG lFlags)
2755 {
2756     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2757     HRESULT hres;
2758     DISPID dispid;
2759
2760     TRACE("(%p)->(%s v%d %08x)\n", This, debugstr_w(strAttributeName),
2761            V_VT(&AttributeValue), lFlags);
2762
2763     if(!strAttributeName)
2764         return E_INVALIDARG;
2765
2766     if(lFlags == 1)
2767         FIXME("Parameter lFlags ignored\n");
2768
2769     hres = HTMLStyle_GetIDsOfNames(iface, &IID_NULL, &strAttributeName, 1,
2770                         LOCALE_USER_DEFAULT, &dispid);
2771     if(hres == S_OK)
2772     {
2773         VARIANT ret;
2774         DISPID dispidNamed = DISPID_PROPERTYPUT;
2775         DISPPARAMS params;
2776
2777         params.cArgs = 1;
2778         params.rgvarg = &AttributeValue;
2779         params.cNamedArgs = 1;
2780         params.rgdispidNamedArgs = &dispidNamed;
2781
2782         hres = HTMLStyle_Invoke(iface, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2783             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2784     }
2785     else
2786     {
2787         FIXME("Custom attributes not supported.\n");
2788     }
2789
2790     TRACE("ret: %08x\n", hres);
2791
2792     return hres;
2793 }
2794
2795 static HRESULT WINAPI HTMLStyle_getAttribute(IHTMLStyle *iface, BSTR strAttributeName,
2796         LONG lFlags, VARIANT *AttributeValue)
2797 {
2798     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2799     HRESULT hres;
2800     DISPID dispid;
2801
2802     TRACE("(%p)->(%s v%p %08x)\n", This, debugstr_w(strAttributeName),
2803           AttributeValue, lFlags);
2804
2805     if(!AttributeValue || !strAttributeName)
2806         return E_INVALIDARG;
2807
2808     if(lFlags == 1)
2809         FIXME("Parameter lFlags ignored\n");
2810
2811     hres = HTMLStyle_GetIDsOfNames(iface, &IID_NULL, &strAttributeName, 1,
2812                         LOCALE_USER_DEFAULT, &dispid);
2813     if(hres == S_OK)
2814     {
2815         DISPPARAMS params = {NULL, NULL, 0, 0 };
2816
2817         hres = HTMLStyle_Invoke(iface, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2818             DISPATCH_PROPERTYGET, &params, AttributeValue, NULL, NULL);
2819     }
2820     else
2821     {
2822         FIXME("Custom attributes not supported.\n");
2823     }
2824
2825     return hres;
2826 }
2827
2828 static HRESULT WINAPI HTMLStyle_removeAttribute(IHTMLStyle *iface, BSTR strAttributeName,
2829                                                 LONG lFlags, VARIANT_BOOL *pfSuccess)
2830 {
2831     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2832     FIXME("(%p)->(%s %08x %p)\n", This, debugstr_w(strAttributeName),
2833          lFlags, pfSuccess);
2834     return E_NOTIMPL;
2835 }
2836
2837 static HRESULT WINAPI HTMLStyle_toString(IHTMLStyle *iface, BSTR *String)
2838 {
2839     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2840     FIXME("(%p)->(%p)\n", This, String);
2841     return E_NOTIMPL;
2842 }
2843
2844 static const IHTMLStyleVtbl HTMLStyleVtbl = {
2845     HTMLStyle_QueryInterface,
2846     HTMLStyle_AddRef,
2847     HTMLStyle_Release,
2848     HTMLStyle_GetTypeInfoCount,
2849     HTMLStyle_GetTypeInfo,
2850     HTMLStyle_GetIDsOfNames,
2851     HTMLStyle_Invoke,
2852     HTMLStyle_put_fontFamily,
2853     HTMLStyle_get_fontFamily,
2854     HTMLStyle_put_fontStyle,
2855     HTMLStyle_get_fontStyle,
2856     HTMLStyle_put_fontVariant,
2857     HTMLStyle_get_fontVariant,
2858     HTMLStyle_put_fontWeight,
2859     HTMLStyle_get_fontWeight,
2860     HTMLStyle_put_fontSize,
2861     HTMLStyle_get_fontSize,
2862     HTMLStyle_put_font,
2863     HTMLStyle_get_font,
2864     HTMLStyle_put_color,
2865     HTMLStyle_get_color,
2866     HTMLStyle_put_background,
2867     HTMLStyle_get_background,
2868     HTMLStyle_put_backgroundColor,
2869     HTMLStyle_get_backgroundColor,
2870     HTMLStyle_put_backgroundImage,
2871     HTMLStyle_get_backgroundImage,
2872     HTMLStyle_put_backgroundRepeat,
2873     HTMLStyle_get_backgroundRepeat,
2874     HTMLStyle_put_backgroundAttachment,
2875     HTMLStyle_get_backgroundAttachment,
2876     HTMLStyle_put_backgroundPosition,
2877     HTMLStyle_get_backgroundPosition,
2878     HTMLStyle_put_backgroundPositionX,
2879     HTMLStyle_get_backgroundPositionX,
2880     HTMLStyle_put_backgroundPositionY,
2881     HTMLStyle_get_backgroundPositionY,
2882     HTMLStyle_put_wordSpacing,
2883     HTMLStyle_get_wordSpacing,
2884     HTMLStyle_put_letterSpacing,
2885     HTMLStyle_get_letterSpacing,
2886     HTMLStyle_put_textDecoration,
2887     HTMLStyle_get_textDecoration,
2888     HTMLStyle_put_textDecorationNone,
2889     HTMLStyle_get_textDecorationNone,
2890     HTMLStyle_put_textDecorationUnderline,
2891     HTMLStyle_get_textDecorationUnderline,
2892     HTMLStyle_put_textDecorationOverline,
2893     HTMLStyle_get_textDecorationOverline,
2894     HTMLStyle_put_textDecorationLineThrough,
2895     HTMLStyle_get_textDecorationLineThrough,
2896     HTMLStyle_put_textDecorationBlink,
2897     HTMLStyle_get_textDecorationBlink,
2898     HTMLStyle_put_verticalAlign,
2899     HTMLStyle_get_verticalAlign,
2900     HTMLStyle_put_textTransform,
2901     HTMLStyle_get_textTransform,
2902     HTMLStyle_put_textAlign,
2903     HTMLStyle_get_textAlign,
2904     HTMLStyle_put_textIndent,
2905     HTMLStyle_get_textIndent,
2906     HTMLStyle_put_lineHeight,
2907     HTMLStyle_get_lineHeight,
2908     HTMLStyle_put_marginTop,
2909     HTMLStyle_get_marginTop,
2910     HTMLStyle_put_marginRight,
2911     HTMLStyle_get_marginRight,
2912     HTMLStyle_put_marginBottom,
2913     HTMLStyle_get_marginBottom,
2914     HTMLStyle_put_marginLeft,
2915     HTMLStyle_get_marginLeft,
2916     HTMLStyle_put_margin,
2917     HTMLStyle_get_margin,
2918     HTMLStyle_put_paddingTop,
2919     HTMLStyle_get_paddingTop,
2920     HTMLStyle_put_paddingRight,
2921     HTMLStyle_get_paddingRight,
2922     HTMLStyle_put_paddingBottom,
2923     HTMLStyle_get_paddingBottom,
2924     HTMLStyle_put_paddingLeft,
2925     HTMLStyle_get_paddingLeft,
2926     HTMLStyle_put_padding,
2927     HTMLStyle_get_padding,
2928     HTMLStyle_put_border,
2929     HTMLStyle_get_border,
2930     HTMLStyle_put_borderTop,
2931     HTMLStyle_get_borderTop,
2932     HTMLStyle_put_borderRight,
2933     HTMLStyle_get_borderRight,
2934     HTMLStyle_put_borderBottom,
2935     HTMLStyle_get_borderBottom,
2936     HTMLStyle_put_borderLeft,
2937     HTMLStyle_get_borderLeft,
2938     HTMLStyle_put_borderColor,
2939     HTMLStyle_get_borderColor,
2940     HTMLStyle_put_borderTopColor,
2941     HTMLStyle_get_borderTopColor,
2942     HTMLStyle_put_borderRightColor,
2943     HTMLStyle_get_borderRightColor,
2944     HTMLStyle_put_borderBottomColor,
2945     HTMLStyle_get_borderBottomColor,
2946     HTMLStyle_put_borderLeftColor,
2947     HTMLStyle_get_borderLeftColor,
2948     HTMLStyle_put_borderWidth,
2949     HTMLStyle_get_borderWidth,
2950     HTMLStyle_put_borderTopWidth,
2951     HTMLStyle_get_borderTopWidth,
2952     HTMLStyle_put_borderRightWidth,
2953     HTMLStyle_get_borderRightWidth,
2954     HTMLStyle_put_borderBottomWidth,
2955     HTMLStyle_get_borderBottomWidth,
2956     HTMLStyle_put_borderLeftWidth,
2957     HTMLStyle_get_borderLeftWidth,
2958     HTMLStyle_put_borderStyle,
2959     HTMLStyle_get_borderStyle,
2960     HTMLStyle_put_borderTopStyle,
2961     HTMLStyle_get_borderTopStyle,
2962     HTMLStyle_put_borderRightStyle,
2963     HTMLStyle_get_borderRightStyle,
2964     HTMLStyle_put_borderBottomStyle,
2965     HTMLStyle_get_borderBottomStyle,
2966     HTMLStyle_put_borderLeftStyle,
2967     HTMLStyle_get_borderLeftStyle,
2968     HTMLStyle_put_width,
2969     HTMLStyle_get_width,
2970     HTMLStyle_put_height,
2971     HTMLStyle_get_height,
2972     HTMLStyle_put_styleFloat,
2973     HTMLStyle_get_styleFloat,
2974     HTMLStyle_put_clear,
2975     HTMLStyle_get_clear,
2976     HTMLStyle_put_display,
2977     HTMLStyle_get_display,
2978     HTMLStyle_put_visibility,
2979     HTMLStyle_get_visibility,
2980     HTMLStyle_put_listStyleType,
2981     HTMLStyle_get_listStyleType,
2982     HTMLStyle_put_listStylePosition,
2983     HTMLStyle_get_listStylePosition,
2984     HTMLStyle_put_listStyleImage,
2985     HTMLStyle_get_listStyleImage,
2986     HTMLStyle_put_listStyle,
2987     HTMLStyle_get_listStyle,
2988     HTMLStyle_put_whiteSpace,
2989     HTMLStyle_get_whiteSpace,
2990     HTMLStyle_put_top,
2991     HTMLStyle_get_top,
2992     HTMLStyle_put_left,
2993     HTMLStyle_get_left,
2994     HTMLStyle_get_position,
2995     HTMLStyle_put_zIndex,
2996     HTMLStyle_get_zIndex,
2997     HTMLStyle_put_overflow,
2998     HTMLStyle_get_overflow,
2999     HTMLStyle_put_pageBreakBefore,
3000     HTMLStyle_get_pageBreakBefore,
3001     HTMLStyle_put_pageBreakAfter,
3002     HTMLStyle_get_pageBreakAfter,
3003     HTMLStyle_put_cssText,
3004     HTMLStyle_get_cssText,
3005     HTMLStyle_put_pixelTop,
3006     HTMLStyle_get_pixelTop,
3007     HTMLStyle_put_pixelLeft,
3008     HTMLStyle_get_pixelLeft,
3009     HTMLStyle_put_pixelWidth,
3010     HTMLStyle_get_pixelWidth,
3011     HTMLStyle_put_pixelHeight,
3012     HTMLStyle_get_pixelHeight,
3013     HTMLStyle_put_posTop,
3014     HTMLStyle_get_posTop,
3015     HTMLStyle_put_posLeft,
3016     HTMLStyle_get_posLeft,
3017     HTMLStyle_put_posWidth,
3018     HTMLStyle_get_posWidth,
3019     HTMLStyle_put_posHeight,
3020     HTMLStyle_get_posHeight,
3021     HTMLStyle_put_cursor,
3022     HTMLStyle_get_cursor,
3023     HTMLStyle_put_clip,
3024     HTMLStyle_get_clip,
3025     HTMLStyle_put_filter,
3026     HTMLStyle_get_filter,
3027     HTMLStyle_setAttribute,
3028     HTMLStyle_getAttribute,
3029     HTMLStyle_removeAttribute,
3030     HTMLStyle_toString
3031 };
3032
3033 static HRESULT HTMLStyle_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid)
3034 {
3035     int c, i, min=0, max = sizeof(style_tbl)/sizeof(*style_tbl)-1;
3036
3037     while(min <= max) {
3038         i = (min+max)/2;
3039
3040         c = strcmpW(style_tbl[i].name, name);
3041         if(!c) {
3042             *dispid = style_tbl[i].dispid;
3043             return S_OK;
3044         }
3045
3046         if(c > 0)
3047             max = i-1;
3048         else
3049             min = i+1;
3050     }
3051
3052     return DISP_E_UNKNOWNNAME;
3053 }
3054
3055 static const dispex_static_data_vtbl_t HTMLStyle_dispex_vtbl = {
3056     NULL,
3057     HTMLStyle_get_dispid,
3058     NULL
3059 };
3060
3061 static const tid_t HTMLStyle_iface_tids[] = {
3062     IHTMLStyle_tid,
3063     IHTMLStyle2_tid,
3064     IHTMLStyle3_tid,
3065     IHTMLStyle4_tid,
3066     0
3067 };
3068 static dispex_static_data_t HTMLStyle_dispex = {
3069     &HTMLStyle_dispex_vtbl,
3070     DispHTMLStyle_tid,
3071     NULL,
3072     HTMLStyle_iface_tids
3073 };
3074
3075 HRESULT HTMLStyle_Create(nsIDOMCSSStyleDeclaration *nsstyle, HTMLStyle **ret)
3076 {
3077     HTMLStyle *style;
3078
3079     style = heap_alloc_zero(sizeof(HTMLStyle));
3080     if(!style)
3081         return E_OUTOFMEMORY;
3082
3083     style->IHTMLStyle_iface.lpVtbl = &HTMLStyleVtbl;
3084     style->ref = 1;
3085     style->nsstyle = nsstyle;
3086     HTMLStyle2_Init(style);
3087     HTMLStyle3_Init(style);
3088
3089     nsIDOMCSSStyleDeclaration_AddRef(nsstyle);
3090
3091     init_dispex(&style->dispex, (IUnknown*)&style->IHTMLStyle_iface, &HTMLStyle_dispex);
3092
3093     *ret = style;
3094     return S_OK;
3095 }