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