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