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