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