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