comctl32: Free the selection ranges (Coverity).
[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 && strcmpW(ptr, pxW)) {
668                 nsAString_Finish(&str_value);
669                 FIXME("only px values are currently supported\n");
670                 hres = E_NOTIMPL;
671             }
672         }else {
673             *p = 0;
674         }
675     }
676
677     nsAString_Finish(&str_value);
678     return hres;
679 }
680
681 static BOOL is_valid_border_style(BSTR v)
682 {
683     static const WCHAR styleDotted[] = {'d','o','t','t','e','d',0};
684     static const WCHAR styleDashed[] = {'d','a','s','h','e','d',0};
685     static const WCHAR styleSolid[]  = {'s','o','l','i','d',0};
686     static const WCHAR styleDouble[] = {'d','o','u','b','l','e',0};
687     static const WCHAR styleGroove[] = {'g','r','o','o','v','e',0};
688     static const WCHAR styleRidge[]  = {'r','i','d','g','e',0};
689     static const WCHAR styleInset[]  = {'i','n','s','e','t',0};
690     static const WCHAR styleOutset[] = {'o','u','t','s','e','t',0};
691
692     TRACE("%s\n", debugstr_w(v));
693
694     if(!v || strcmpiW(v, styleNone)   == 0 || strcmpiW(v, styleDotted) == 0 ||
695              strcmpiW(v, styleDashed) == 0 || strcmpiW(v, styleSolid)  == 0 ||
696              strcmpiW(v, styleDouble) == 0 || strcmpiW(v, styleGroove) == 0 ||
697              strcmpiW(v, styleRidge)  == 0 || strcmpiW(v, styleInset)  == 0 ||
698              strcmpiW(v, styleOutset) == 0 )
699     {
700         return TRUE;
701     }
702
703     return FALSE;
704 }
705
706 static inline HTMLStyle *impl_from_IHTMLStyle(IHTMLStyle *iface)
707 {
708     return CONTAINING_RECORD(iface, HTMLStyle, IHTMLStyle_iface);
709 }
710
711 static HRESULT WINAPI HTMLStyle_QueryInterface(IHTMLStyle *iface, REFIID riid, void **ppv)
712 {
713     HTMLStyle *This = impl_from_IHTMLStyle(iface);
714
715     *ppv = NULL;
716
717     if(IsEqualGUID(&IID_IUnknown, riid)) {
718         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
719         *ppv = &This->IHTMLStyle_iface;
720     }else if(IsEqualGUID(&IID_IHTMLStyle, riid)) {
721         TRACE("(%p)->(IID_IHTMLStyle %p)\n", This, ppv);
722         *ppv = &This->IHTMLStyle_iface;
723     }else if(IsEqualGUID(&IID_IHTMLStyle2, riid)) {
724         TRACE("(%p)->(IID_IHTMLStyle2 %p)\n", This, ppv);
725         *ppv = &This->IHTMLStyle2_iface;
726     }else if(IsEqualGUID(&IID_IHTMLStyle3, riid)) {
727         TRACE("(%p)->(IID_IHTMLStyle3 %p)\n", This, ppv);
728         *ppv = &This->IHTMLStyle3_iface;
729     }else if(IsEqualGUID(&IID_IHTMLStyle4, riid)) {
730         TRACE("(%p)->(IID_IHTMLStyle4 %p)\n", This, ppv);
731         *ppv = &This->IHTMLStyle4_iface;
732     }else if(IsEqualGUID(&IID_IHTMLStyle5, riid)) {
733         TRACE("(%p)->(IID_IHTMLStyle5 %p)\n", This, ppv);
734         *ppv = &This->IHTMLStyle5_iface;
735     }else if(IsEqualGUID(&IID_IHTMLStyle6, riid)) {
736         TRACE("(%p)->(IID_IHTMLStyle6 %p)\n", This, ppv);
737         *ppv = &This->IHTMLStyle6_iface;
738     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
739         return *ppv ? S_OK : E_NOINTERFACE;
740     }
741
742     if(*ppv) {
743         IUnknown_AddRef((IUnknown*)*ppv);
744         return S_OK;
745     }
746
747     WARN("unsupported %s\n", debugstr_guid(riid));
748     return E_NOINTERFACE;
749 }
750
751 static ULONG WINAPI HTMLStyle_AddRef(IHTMLStyle *iface)
752 {
753     HTMLStyle *This = impl_from_IHTMLStyle(iface);
754     LONG ref = InterlockedIncrement(&This->ref);
755
756     TRACE("(%p) ref=%d\n", This, ref);
757
758     return ref;
759 }
760
761 static ULONG WINAPI HTMLStyle_Release(IHTMLStyle *iface)
762 {
763     HTMLStyle *This = impl_from_IHTMLStyle(iface);
764     LONG ref = InterlockedDecrement(&This->ref);
765
766     TRACE("(%p) ref=%d\n", This, ref);
767
768     if(!ref) {
769         assert(!This->elem);
770         if(This->nsstyle)
771             nsIDOMCSSStyleDeclaration_Release(This->nsstyle);
772         release_dispex(&This->dispex);
773         heap_free(This);
774     }
775
776     return ref;
777 }
778
779 static HRESULT WINAPI HTMLStyle_GetTypeInfoCount(IHTMLStyle *iface, UINT *pctinfo)
780 {
781     HTMLStyle *This = impl_from_IHTMLStyle(iface);
782     return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
783 }
784
785 static HRESULT WINAPI HTMLStyle_GetTypeInfo(IHTMLStyle *iface, UINT iTInfo,
786                                               LCID lcid, ITypeInfo **ppTInfo)
787 {
788     HTMLStyle *This = impl_from_IHTMLStyle(iface);
789     return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
790 }
791
792 static HRESULT WINAPI HTMLStyle_GetIDsOfNames(IHTMLStyle *iface, REFIID riid,
793                                                 LPOLESTR *rgszNames, UINT cNames,
794                                                 LCID lcid, DISPID *rgDispId)
795 {
796     HTMLStyle *This = impl_from_IHTMLStyle(iface);
797     return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
798             lcid, rgDispId);
799 }
800
801 static HRESULT WINAPI HTMLStyle_Invoke(IHTMLStyle *iface, DISPID dispIdMember,
802                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
803                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
804 {
805     HTMLStyle *This = impl_from_IHTMLStyle(iface);
806     return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
807             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
808 }
809
810 static HRESULT WINAPI HTMLStyle_put_fontFamily(IHTMLStyle *iface, BSTR v)
811 {
812     HTMLStyle *This = impl_from_IHTMLStyle(iface);
813
814     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
815
816     return set_style_attr(This, STYLEID_FONT_FAMILY, v, 0);
817 }
818
819 static HRESULT WINAPI HTMLStyle_get_fontFamily(IHTMLStyle *iface, BSTR *p)
820 {
821     HTMLStyle *This = impl_from_IHTMLStyle(iface);
822
823     TRACE("(%p)->(%p)\n", This, p);
824
825     return get_style_attr(This, STYLEID_FONT_FAMILY, p);
826 }
827
828 static HRESULT WINAPI HTMLStyle_put_fontStyle(IHTMLStyle *iface, BSTR v)
829 {
830     HTMLStyle *This = impl_from_IHTMLStyle(iface);
831     static const WCHAR szItalic[]  = {'i','t','a','l','i','c',0};
832     static const WCHAR szOblique[]  = {'o','b','l','i','q','u','e',0};
833
834     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
835
836     /* fontStyle can only be one of the follow values. */
837     if(!v || strcmpiW(szNormal, v) == 0 || strcmpiW(szItalic, v) == 0 ||
838              strcmpiW(szOblique, v) == 0)
839     {
840         return set_nsstyle_attr(This->nsstyle, STYLEID_FONT_STYLE, v, 0);
841     }
842
843     return E_INVALIDARG;
844 }
845
846 static HRESULT WINAPI HTMLStyle_get_fontStyle(IHTMLStyle *iface, BSTR *p)
847 {
848     HTMLStyle *This = impl_from_IHTMLStyle(iface);
849
850     TRACE("(%p)->(%p)\n", This, p);
851
852     return get_style_attr(This, STYLEID_FONT_STYLE, p);
853 }
854
855 static HRESULT WINAPI HTMLStyle_put_fontVariant(IHTMLStyle *iface, BSTR v)
856 {
857     HTMLStyle *This = impl_from_IHTMLStyle(iface);
858     static const WCHAR szCaps[]  = {'s','m','a','l','l','-','c','a','p','s',0};
859
860     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
861
862     /* fontVariant can only be one of the follow values. */
863     if(!v || strcmpiW(szNormal, v) == 0 || strcmpiW(szCaps, v) == 0)
864     {
865         return set_nsstyle_attr(This->nsstyle, STYLEID_FONT_VARIANT, v, 0);
866     }
867
868     return E_INVALIDARG;
869 }
870
871 static HRESULT WINAPI HTMLStyle_get_fontVariant(IHTMLStyle *iface, BSTR *p)
872 {
873     HTMLStyle *This = impl_from_IHTMLStyle(iface);
874     TRACE("(%p)->(%p)\n", This, p);
875
876     if(!p)
877        return E_INVALIDARG;
878
879     return get_style_attr(This, STYLEID_FONT_VARIANT, p);
880 }
881
882 static HRESULT WINAPI HTMLStyle_put_fontWeight(IHTMLStyle *iface, BSTR v)
883 {
884     HTMLStyle *This = impl_from_IHTMLStyle(iface);
885     static const WCHAR styleBold[] = {'b','o','l','d',0};
886     static const WCHAR styleBolder[] = {'b','o','l','d','e','r',0};
887     static const WCHAR styleLighter[]  = {'l','i','g','h','t','e','r',0};
888     static const WCHAR style100[] = {'1','0','0',0};
889     static const WCHAR style200[] = {'2','0','0',0};
890     static const WCHAR style300[] = {'3','0','0',0};
891     static const WCHAR style400[] = {'4','0','0',0};
892     static const WCHAR style500[] = {'5','0','0',0};
893     static const WCHAR style600[] = {'6','0','0',0};
894     static const WCHAR style700[] = {'7','0','0',0};
895     static const WCHAR style800[] = {'8','0','0',0};
896     static const WCHAR style900[] = {'9','0','0',0};
897
898     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
899
900     /* fontWeight can only be one of the following */
901     if(!v || strcmpiW(szNormal, v) == 0    || strcmpiW(styleBold, v) == 0    ||
902              strcmpiW(styleBolder, v) == 0 || strcmpiW(styleLighter, v) == 0 ||
903              strcmpiW(style100, v) == 0    || strcmpiW(style200, v) == 0     ||
904              strcmpiW(style300, v) == 0    || strcmpiW(style400, v) == 0     ||
905              strcmpiW(style500, v) == 0    || strcmpiW(style600, v) == 0     ||
906              strcmpiW(style700, v) == 0    || strcmpiW(style800, v) == 0     ||
907              strcmpiW(style900, v) == 0
908              )
909     {
910         return set_nsstyle_attr(This->nsstyle, STYLEID_FONT_WEIGHT, v, 0);
911     }
912
913     return E_INVALIDARG;
914 }
915
916 static HRESULT WINAPI HTMLStyle_get_fontWeight(IHTMLStyle *iface, BSTR *p)
917 {
918     HTMLStyle *This = impl_from_IHTMLStyle(iface);
919
920     TRACE("(%p)->(%p)\n", This, p);
921
922     return get_style_attr(This, STYLEID_FONT_WEIGHT, p);
923 }
924
925 static HRESULT WINAPI HTMLStyle_put_fontSize(IHTMLStyle *iface, VARIANT v)
926 {
927     HTMLStyle *This = impl_from_IHTMLStyle(iface);
928
929     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
930
931     return set_nsstyle_attr_var(This->nsstyle, STYLEID_FONT_SIZE, &v, ATTR_FIX_PX);
932 }
933
934 static HRESULT WINAPI HTMLStyle_get_fontSize(IHTMLStyle *iface, VARIANT *p)
935 {
936     HTMLStyle *This = impl_from_IHTMLStyle(iface);
937
938     TRACE("(%p)->(%p)\n", This, p);
939
940     return get_nsstyle_attr_var(This->nsstyle, STYLEID_FONT_SIZE, p, 0);
941 }
942
943 static HRESULT WINAPI HTMLStyle_put_font(IHTMLStyle *iface, BSTR v)
944 {
945     HTMLStyle *This = impl_from_IHTMLStyle(iface);
946     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
947     return E_NOTIMPL;
948 }
949
950 static HRESULT WINAPI HTMLStyle_get_font(IHTMLStyle *iface, BSTR *p)
951 {
952     HTMLStyle *This = impl_from_IHTMLStyle(iface);
953     FIXME("(%p)->(%p)\n", This, p);
954     return E_NOTIMPL;
955 }
956
957 static HRESULT WINAPI HTMLStyle_put_color(IHTMLStyle *iface, VARIANT v)
958 {
959     HTMLStyle *This = impl_from_IHTMLStyle(iface);
960
961     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
962
963     return set_nsstyle_attr_var(This->nsstyle, STYLEID_COLOR, &v, ATTR_HEX_INT);
964 }
965
966 static HRESULT WINAPI HTMLStyle_get_color(IHTMLStyle *iface, VARIANT *p)
967 {
968     HTMLStyle *This = impl_from_IHTMLStyle(iface);
969
970     TRACE("(%p)->(%p)\n", This, p);
971
972     return get_nsstyle_attr_var(This->nsstyle, STYLEID_COLOR, p, 0);
973 }
974
975 static HRESULT WINAPI HTMLStyle_put_background(IHTMLStyle *iface, BSTR v)
976 {
977     HTMLStyle *This = impl_from_IHTMLStyle(iface);
978
979     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
980
981     return set_style_attr(This, STYLEID_BACKGROUND, v, 0);
982 }
983
984 static HRESULT WINAPI HTMLStyle_get_background(IHTMLStyle *iface, BSTR *p)
985 {
986     HTMLStyle *This = impl_from_IHTMLStyle(iface);
987
988     TRACE("(%p)->(%p)\n", This, p);
989
990     return get_style_attr(This, STYLEID_BACKGROUND, p);
991 }
992
993 static HRESULT WINAPI HTMLStyle_put_backgroundColor(IHTMLStyle *iface, VARIANT v)
994 {
995     HTMLStyle *This = impl_from_IHTMLStyle(iface);
996
997     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
998
999     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BACKGROUND_COLOR, &v, ATTR_HEX_INT);
1000 }
1001
1002 static HRESULT WINAPI HTMLStyle_get_backgroundColor(IHTMLStyle *iface, VARIANT *p)
1003 {
1004     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1005
1006     TRACE("(%p)->(%p)\n", This, p);
1007
1008     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BACKGROUND_COLOR, p, 0);
1009 }
1010
1011 static HRESULT WINAPI HTMLStyle_put_backgroundImage(IHTMLStyle *iface, BSTR v)
1012 {
1013     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1014
1015     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1016
1017     return set_style_attr(This, STYLEID_BACKGROUND_IMAGE, v, ATTR_FIX_URL);
1018 }
1019
1020 static HRESULT WINAPI HTMLStyle_get_backgroundImage(IHTMLStyle *iface, BSTR *p)
1021 {
1022     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1023
1024     TRACE("(%p)->(%p)\n", This, p);
1025
1026     return get_style_attr(This, STYLEID_BACKGROUND_IMAGE, p);
1027 }
1028
1029 static HRESULT WINAPI HTMLStyle_put_backgroundRepeat(IHTMLStyle *iface, BSTR v)
1030 {
1031     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1032     static const WCHAR styleRepeat[]   = {'r','e','p','e','a','t',0};
1033     static const WCHAR styleNoRepeat[] = {'n','o','-','r','e','p','e','a','t',0};
1034     static const WCHAR styleRepeatX[]  = {'r','e','p','e','a','t','-','x',0};
1035     static const WCHAR styleRepeatY[]  = {'r','e','p','e','a','t','-','y',0};
1036
1037     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1038
1039     /* fontWeight can only be one of the following */
1040     if(!v || strcmpiW(styleRepeat, v) == 0    || strcmpiW(styleNoRepeat, v) == 0    ||
1041              strcmpiW(styleRepeatX, v) == 0 || strcmpiW(styleRepeatY, v) == 0 )
1042     {
1043         return set_style_attr(This, STYLEID_BACKGROUND_REPEAT , v, 0);
1044     }
1045
1046     return E_INVALIDARG;
1047 }
1048
1049 static HRESULT WINAPI HTMLStyle_get_backgroundRepeat(IHTMLStyle *iface, BSTR *p)
1050 {
1051     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1052
1053     TRACE("(%p)->(%p)\n", This, p);
1054
1055     return get_style_attr(This, STYLEID_BACKGROUND_REPEAT, p);
1056 }
1057
1058 static HRESULT WINAPI HTMLStyle_put_backgroundAttachment(IHTMLStyle *iface, BSTR v)
1059 {
1060     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1061     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1062     return E_NOTIMPL;
1063 }
1064
1065 static HRESULT WINAPI HTMLStyle_get_backgroundAttachment(IHTMLStyle *iface, BSTR *p)
1066 {
1067     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1068     FIXME("(%p)->(%p)\n", This, p);
1069     return E_NOTIMPL;
1070 }
1071
1072 static HRESULT WINAPI HTMLStyle_put_backgroundPosition(IHTMLStyle *iface, BSTR v)
1073 {
1074     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1075
1076     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1077
1078     return set_style_attr(This, STYLEID_BACKGROUND_POSITION, v, 0);
1079 }
1080
1081 static HRESULT WINAPI HTMLStyle_get_backgroundPosition(IHTMLStyle *iface, BSTR *p)
1082 {
1083     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1084
1085     TRACE("(%p)->(%p)\n", This, p);
1086
1087     return get_style_attr(This, STYLEID_BACKGROUND_POSITION, p);
1088 }
1089
1090 static HRESULT WINAPI HTMLStyle_put_backgroundPositionX(IHTMLStyle *iface, VARIANT v)
1091 {
1092     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1093     WCHAR buf[14], *pos_val;
1094     nsAString pos_str;
1095     const WCHAR *val;
1096     DWORD val_len;
1097     HRESULT hres;
1098
1099     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1100
1101     hres = var_to_styleval(&v, buf, ATTR_FIX_PX, &val);
1102     if(FAILED(hres))
1103         return hres;
1104
1105     val_len = val ? strlenW(val) : 0;
1106
1107     nsAString_Init(&pos_str, NULL);
1108     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1109     if(SUCCEEDED(hres)) {
1110         const PRUnichar *pos, *posy;
1111         DWORD posy_len;
1112
1113         nsAString_GetData(&pos_str, &pos);
1114         posy = strchrW(pos, ' ');
1115         if(!posy) {
1116             static const WCHAR zero_pxW[] = {' ','0','p','x',0};
1117
1118             TRACE("no space in %s\n", debugstr_w(pos));
1119             posy = zero_pxW;
1120         }
1121
1122         posy_len = strlenW(posy);
1123         pos_val = heap_alloc((val_len+posy_len+1)*sizeof(WCHAR));
1124         if(pos_val) {
1125             if(val_len)
1126                 memcpy(pos_val, val, val_len*sizeof(WCHAR));
1127             if(posy_len)
1128                 memcpy(pos_val+val_len, posy, posy_len*sizeof(WCHAR));
1129             pos_val[val_len+posy_len] = 0;
1130         }else {
1131             hres = E_OUTOFMEMORY;
1132         }
1133     }
1134     nsAString_Finish(&pos_str);
1135     if(FAILED(hres))
1136         return hres;
1137
1138     TRACE("setting position to %s\n", debugstr_w(pos_val));
1139     hres = set_nsstyle_attr(This->nsstyle, STYLEID_BACKGROUND_POSITION, pos_val, ATTR_FIX_PX);
1140     heap_free(pos_val);
1141     return hres;
1142 }
1143
1144 static HRESULT WINAPI HTMLStyle_get_backgroundPositionX(IHTMLStyle *iface, VARIANT *p)
1145 {
1146     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1147     nsAString pos_str;
1148     BSTR ret;
1149     HRESULT hres;
1150
1151     TRACE("(%p)->(%p)\n", This, p);
1152
1153     nsAString_Init(&pos_str, NULL);
1154     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1155     if(SUCCEEDED(hres)) {
1156         const PRUnichar *pos, *space;
1157
1158         nsAString_GetData(&pos_str, &pos);
1159         space = strchrW(pos, ' ');
1160         if(!space) {
1161             WARN("no space in %s\n", debugstr_w(pos));
1162             space = pos + strlenW(pos);
1163         }
1164
1165         if(space != pos) {
1166             ret = SysAllocStringLen(pos, space-pos);
1167             if(!ret)
1168                 hres = E_OUTOFMEMORY;
1169         }else {
1170             ret = NULL;
1171         }
1172     }
1173     nsAString_Finish(&pos_str);
1174     if(FAILED(hres))
1175         return hres;
1176
1177     TRACE("returning %s\n", debugstr_w(ret));
1178     V_VT(p) = VT_BSTR;
1179     V_BSTR(p) = ret;
1180     return S_OK;
1181 }
1182
1183 static HRESULT WINAPI HTMLStyle_put_backgroundPositionY(IHTMLStyle *iface, VARIANT v)
1184 {
1185     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1186     WCHAR buf[14], *pos_val;
1187     nsAString pos_str;
1188     const WCHAR *val;
1189     DWORD val_len;
1190     HRESULT hres;
1191
1192     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1193
1194     hres = var_to_styleval(&v, buf, ATTR_FIX_PX, &val);
1195     if(FAILED(hres))
1196         return hres;
1197
1198     val_len = val ? strlenW(val) : 0;
1199
1200     nsAString_Init(&pos_str, NULL);
1201     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1202     if(SUCCEEDED(hres)) {
1203         const PRUnichar *pos, *space;
1204         DWORD posx_len;
1205
1206         nsAString_GetData(&pos_str, &pos);
1207         space = strchrW(pos, ' ');
1208         if(space) {
1209             space++;
1210         }else {
1211             static const WCHAR zero_pxW[] = {'0','p','x',' ',0};
1212
1213             TRACE("no space in %s\n", debugstr_w(pos));
1214             pos = zero_pxW;
1215             space = pos + sizeof(zero_pxW)/sizeof(WCHAR)-1;
1216         }
1217
1218         posx_len = space-pos;
1219
1220         pos_val = heap_alloc((posx_len+val_len+1)*sizeof(WCHAR));
1221         if(pos_val) {
1222             memcpy(pos_val, pos, posx_len*sizeof(WCHAR));
1223             if(val_len)
1224                 memcpy(pos_val+posx_len, val, val_len*sizeof(WCHAR));
1225             pos_val[posx_len+val_len] = 0;
1226         }else {
1227             hres = E_OUTOFMEMORY;
1228         }
1229     }
1230     nsAString_Finish(&pos_str);
1231     if(FAILED(hres))
1232         return hres;
1233
1234     TRACE("setting position to %s\n", debugstr_w(pos_val));
1235     hres = set_nsstyle_attr(This->nsstyle, STYLEID_BACKGROUND_POSITION, pos_val, ATTR_FIX_PX);
1236     heap_free(pos_val);
1237     return hres;
1238 }
1239
1240 static HRESULT WINAPI HTMLStyle_get_backgroundPositionY(IHTMLStyle *iface, VARIANT *p)
1241 {
1242     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1243     nsAString pos_str;
1244     BSTR ret;
1245     HRESULT hres;
1246
1247     TRACE("(%p)->(%p)\n", This, p);
1248
1249     nsAString_Init(&pos_str, NULL);
1250     hres = get_nsstyle_attr_nsval(This->nsstyle, STYLEID_BACKGROUND_POSITION, &pos_str);
1251     if(SUCCEEDED(hres)) {
1252         const PRUnichar *pos, *posy;
1253
1254         nsAString_GetData(&pos_str, &pos);
1255         posy = strchrW(pos, ' ');
1256         if(posy) {
1257             ret = SysAllocString(posy+1);
1258             if(!ret)
1259                 hres = E_OUTOFMEMORY;
1260         }else {
1261             ret = NULL;
1262         }
1263     }
1264     nsAString_Finish(&pos_str);
1265     if(FAILED(hres))
1266         return hres;
1267
1268     TRACE("returning %s\n", debugstr_w(ret));
1269     V_VT(p) = VT_BSTR;
1270     V_BSTR(p) = ret;
1271     return S_OK;
1272 }
1273
1274 static HRESULT WINAPI HTMLStyle_put_wordSpacing(IHTMLStyle *iface, VARIANT v)
1275 {
1276     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1277
1278     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1279
1280     return set_nsstyle_attr_var(This->nsstyle, STYLEID_WORD_SPACING, &v, 0);
1281 }
1282
1283 static HRESULT WINAPI HTMLStyle_get_wordSpacing(IHTMLStyle *iface, VARIANT *p)
1284 {
1285     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1286     TRACE("(%p)->(%p)\n", This, p);
1287     return get_nsstyle_attr_var(This->nsstyle, STYLEID_WORD_SPACING, p, 0);
1288 }
1289
1290 static HRESULT WINAPI HTMLStyle_put_letterSpacing(IHTMLStyle *iface, VARIANT v)
1291 {
1292     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1293
1294     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1295
1296     return set_nsstyle_attr_var(This->nsstyle, STYLEID_LETTER_SPACING, &v, 0);
1297 }
1298
1299 static HRESULT WINAPI HTMLStyle_get_letterSpacing(IHTMLStyle *iface, VARIANT *p)
1300 {
1301     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1302     TRACE("(%p)->(%p)\n", This, p);
1303     return get_nsstyle_attr_var(This->nsstyle, STYLEID_LETTER_SPACING, p, 0);
1304 }
1305
1306 static HRESULT WINAPI HTMLStyle_put_textDecoration(IHTMLStyle *iface, BSTR v)
1307 {
1308     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1309
1310     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1311
1312     /* textDecoration can only be one of the following */
1313     if(!v || strcmpiW(styleNone, v)   == 0 || strcmpiW(valUnderline, v)   == 0 ||
1314              strcmpiW(valOverline, v) == 0 || strcmpiW(valLineThrough, v) == 0 ||
1315              strcmpiW(valBlink, v)    == 0)
1316     {
1317         return set_style_attr(This, STYLEID_TEXT_DECORATION , v, 0);
1318     }
1319
1320     return E_INVALIDARG;
1321 }
1322
1323 static HRESULT WINAPI HTMLStyle_get_textDecoration(IHTMLStyle *iface, BSTR *p)
1324 {
1325     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1326
1327     TRACE("(%p)->(%p)\n", This, p);
1328
1329     return get_style_attr(This, STYLEID_TEXT_DECORATION, p);
1330 }
1331
1332 static HRESULT WINAPI HTMLStyle_put_textDecorationNone(IHTMLStyle *iface, VARIANT_BOOL v)
1333 {
1334     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1335
1336     TRACE("(%p)->(%x)\n", This, v);
1337
1338     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? styleNone : emptyW, 0);
1339 }
1340
1341 static HRESULT WINAPI HTMLStyle_get_textDecorationNone(IHTMLStyle *iface, VARIANT_BOOL *p)
1342 {
1343     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1344
1345     TRACE("(%p)->(%p)\n", This, p);
1346
1347     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, styleNone, p);
1348 }
1349
1350 static HRESULT WINAPI HTMLStyle_put_textDecorationUnderline(IHTMLStyle *iface, VARIANT_BOOL v)
1351 {
1352     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1353
1354     TRACE("(%p)->(%x)\n", This, v);
1355
1356     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valUnderline : emptyW, 0);
1357 }
1358
1359 static HRESULT WINAPI HTMLStyle_get_textDecorationUnderline(IHTMLStyle *iface, VARIANT_BOOL *p)
1360 {
1361     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1362
1363     TRACE("(%p)->(%p)\n", This, p);
1364
1365     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valUnderline, p);
1366 }
1367
1368 static HRESULT WINAPI HTMLStyle_put_textDecorationOverline(IHTMLStyle *iface, VARIANT_BOOL v)
1369 {
1370     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1371
1372     TRACE("(%p)->(%x)\n", This, v);
1373
1374     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valOverline : emptyW, 0);
1375 }
1376
1377 static HRESULT WINAPI HTMLStyle_get_textDecorationOverline(IHTMLStyle *iface, VARIANT_BOOL *p)
1378 {
1379     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1380
1381     TRACE("(%p)->(%p)\n", This, p);
1382
1383     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valOverline, p);
1384 }
1385
1386 static HRESULT WINAPI HTMLStyle_put_textDecorationLineThrough(IHTMLStyle *iface, VARIANT_BOOL v)
1387 {
1388     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1389
1390     TRACE("(%p)->(%x)\n", This, v);
1391
1392     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valLineThrough : emptyW, 0);
1393 }
1394
1395 static HRESULT WINAPI HTMLStyle_get_textDecorationLineThrough(IHTMLStyle *iface, VARIANT_BOOL *p)
1396 {
1397     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1398
1399     TRACE("(%p)->(%p)\n", This, p);
1400
1401     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valLineThrough, p);
1402 }
1403
1404 static HRESULT WINAPI HTMLStyle_put_textDecorationBlink(IHTMLStyle *iface, VARIANT_BOOL v)
1405 {
1406     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1407
1408     TRACE("(%p)->(%x)\n", This, v);
1409
1410     return set_style_attr(This, STYLEID_TEXT_DECORATION, v ? valBlink : emptyW, 0);
1411 }
1412
1413 static HRESULT WINAPI HTMLStyle_get_textDecorationBlink(IHTMLStyle *iface, VARIANT_BOOL *p)
1414 {
1415     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1416
1417     TRACE("(%p)->(%p)\n", This, p);
1418
1419     return check_style_attr_value(This, STYLEID_TEXT_DECORATION, valBlink, p);
1420 }
1421
1422 static HRESULT WINAPI HTMLStyle_put_verticalAlign(IHTMLStyle *iface, VARIANT v)
1423 {
1424     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1425
1426     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1427
1428     return set_nsstyle_attr_var(This->nsstyle, STYLEID_VERTICAL_ALIGN, &v, ATTR_FIX_PX);
1429 }
1430
1431 static HRESULT WINAPI HTMLStyle_get_verticalAlign(IHTMLStyle *iface, VARIANT *p)
1432 {
1433     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1434
1435     TRACE("(%p)->(%p)\n", This, p);
1436
1437     return get_nsstyle_attr_var(This->nsstyle, STYLEID_VERTICAL_ALIGN, p, 0);
1438 }
1439
1440 static HRESULT WINAPI HTMLStyle_put_textTransform(IHTMLStyle *iface, BSTR v)
1441 {
1442     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1443     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1444     return E_NOTIMPL;
1445 }
1446
1447 static HRESULT WINAPI HTMLStyle_get_textTransform(IHTMLStyle *iface, BSTR *p)
1448 {
1449     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1450     FIXME("(%p)->(%p)\n", This, p);
1451     return E_NOTIMPL;
1452 }
1453
1454 static HRESULT WINAPI HTMLStyle_put_textAlign(IHTMLStyle *iface, BSTR v)
1455 {
1456     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1457
1458     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1459
1460     return set_style_attr(This, STYLEID_TEXT_ALIGN, v, 0);
1461 }
1462
1463 static HRESULT WINAPI HTMLStyle_get_textAlign(IHTMLStyle *iface, BSTR *p)
1464 {
1465     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1466
1467     TRACE("(%p)->(%p)\n", This, p);
1468
1469     return get_style_attr(This, STYLEID_TEXT_ALIGN, p);
1470 }
1471
1472 static HRESULT WINAPI HTMLStyle_put_textIndent(IHTMLStyle *iface, VARIANT v)
1473 {
1474     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1475     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1476     return E_NOTIMPL;
1477 }
1478
1479 static HRESULT WINAPI HTMLStyle_get_textIndent(IHTMLStyle *iface, VARIANT *p)
1480 {
1481     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1482     FIXME("(%p)->(%p)\n", This, p);
1483     return E_NOTIMPL;
1484 }
1485
1486 static HRESULT WINAPI HTMLStyle_put_lineHeight(IHTMLStyle *iface, VARIANT v)
1487 {
1488     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1489     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1490     return E_NOTIMPL;
1491 }
1492
1493 static HRESULT WINAPI HTMLStyle_get_lineHeight(IHTMLStyle *iface, VARIANT *p)
1494 {
1495     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1496     FIXME("(%p)->(%p)\n", This, p);
1497     return E_NOTIMPL;
1498 }
1499
1500 static HRESULT WINAPI HTMLStyle_put_marginTop(IHTMLStyle *iface, VARIANT v)
1501 {
1502     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1503
1504     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1505
1506     return set_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_TOP, &v, ATTR_FIX_PX);
1507 }
1508
1509 static HRESULT WINAPI HTMLStyle_get_marginTop(IHTMLStyle *iface, VARIANT *p)
1510 {
1511     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1512
1513     TRACE("(%p)->(%p)\n", This, p);
1514
1515     return get_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_TOP, p, 0);
1516 }
1517
1518 static HRESULT WINAPI HTMLStyle_put_marginRight(IHTMLStyle *iface, VARIANT v)
1519 {
1520     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1521
1522     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1523
1524     return set_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_RIGHT, &v, ATTR_FIX_PX);
1525 }
1526
1527 static HRESULT WINAPI HTMLStyle_get_marginRight(IHTMLStyle *iface, VARIANT *p)
1528 {
1529     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1530     TRACE("(%p)->(%p)\n", This, p);
1531     return get_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_RIGHT, p, 0);
1532 }
1533
1534 static HRESULT WINAPI HTMLStyle_put_marginBottom(IHTMLStyle *iface, VARIANT v)
1535 {
1536     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1537
1538     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1539
1540     return set_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_BOTTOM, &v, ATTR_FIX_PX);
1541 }
1542
1543 static HRESULT WINAPI HTMLStyle_get_marginBottom(IHTMLStyle *iface, VARIANT *p)
1544 {
1545     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1546
1547     TRACE("(%p)->(%p)\n", This, p);
1548
1549     return get_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_BOTTOM, p, 0);
1550 }
1551
1552 static HRESULT WINAPI HTMLStyle_put_marginLeft(IHTMLStyle *iface, VARIANT v)
1553 {
1554     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1555
1556     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1557
1558     return set_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_LEFT, &v, ATTR_FIX_PX);
1559 }
1560
1561 static HRESULT WINAPI HTMLStyle_put_margin(IHTMLStyle *iface, BSTR v)
1562 {
1563     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1564
1565     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1566
1567     return set_style_attr(This, STYLEID_MARGIN, v, 0);
1568 }
1569
1570 static HRESULT WINAPI HTMLStyle_get_margin(IHTMLStyle *iface, BSTR *p)
1571 {
1572     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1573
1574     TRACE("(%p)->(%p)\n", This, p);
1575
1576     return get_style_attr(This, STYLEID_MARGIN, p);
1577 }
1578
1579 static HRESULT WINAPI HTMLStyle_get_marginLeft(IHTMLStyle *iface, VARIANT *p)
1580 {
1581     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1582     TRACE("(%p)->(%p)\n", This, p);
1583     return get_nsstyle_attr_var(This->nsstyle, STYLEID_MARGIN_LEFT, p, 0);
1584 }
1585
1586 static HRESULT WINAPI HTMLStyle_put_paddingTop(IHTMLStyle *iface, VARIANT v)
1587 {
1588     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1589
1590     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1591
1592     return set_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_TOP, &v, ATTR_FIX_PX);
1593 }
1594
1595 static HRESULT WINAPI HTMLStyle_get_paddingTop(IHTMLStyle *iface, VARIANT *p)
1596 {
1597     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1598
1599     TRACE("(%p)->(%p)\n", This, p);
1600
1601     return get_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_TOP, p, 0);
1602 }
1603
1604 static HRESULT WINAPI HTMLStyle_put_paddingRight(IHTMLStyle *iface, VARIANT v)
1605 {
1606     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1607
1608     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1609
1610     return set_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_RIGHT, &v, ATTR_FIX_PX);
1611 }
1612
1613 static HRESULT WINAPI HTMLStyle_get_paddingRight(IHTMLStyle *iface, VARIANT *p)
1614 {
1615     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1616
1617     TRACE("(%p)->(%p)\n", This, p);
1618
1619     return get_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_RIGHT, p, 0);
1620 }
1621
1622 static HRESULT WINAPI HTMLStyle_put_paddingBottom(IHTMLStyle *iface, VARIANT v)
1623 {
1624     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1625
1626     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1627
1628     return set_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_BOTTOM, &v, ATTR_FIX_PX);
1629 }
1630
1631 static HRESULT WINAPI HTMLStyle_get_paddingBottom(IHTMLStyle *iface, VARIANT *p)
1632 {
1633     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1634
1635     TRACE("(%p)->(%p)\n", This, p);
1636
1637     return get_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_BOTTOM, p, 0);
1638 }
1639
1640 static HRESULT WINAPI HTMLStyle_put_paddingLeft(IHTMLStyle *iface, VARIANT v)
1641 {
1642     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1643
1644     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1645
1646     return set_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_LEFT, &v, ATTR_FIX_PX);
1647 }
1648
1649 static HRESULT WINAPI HTMLStyle_get_paddingLeft(IHTMLStyle *iface, VARIANT *p)
1650 {
1651     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1652
1653     TRACE("(%p)->(%p)\n", This, p);
1654
1655     return get_nsstyle_attr_var(This->nsstyle, STYLEID_PADDING_LEFT, p, 0);
1656 }
1657
1658 static HRESULT WINAPI HTMLStyle_put_padding(IHTMLStyle *iface, BSTR v)
1659 {
1660     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1661
1662     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1663
1664     return set_style_attr(This, STYLEID_PADDING, v, 0);
1665 }
1666
1667 static HRESULT WINAPI HTMLStyle_get_padding(IHTMLStyle *iface, BSTR *p)
1668 {
1669     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1670
1671     TRACE("(%p)->(%p)\n", This, p);
1672
1673     return get_style_attr(This, STYLEID_PADDING, p);
1674 }
1675
1676 static HRESULT WINAPI HTMLStyle_put_border(IHTMLStyle *iface, BSTR v)
1677 {
1678     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1679
1680     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1681
1682     return set_style_attr(This, STYLEID_BORDER, v, 0);
1683 }
1684
1685 static HRESULT WINAPI HTMLStyle_get_border(IHTMLStyle *iface, BSTR *p)
1686 {
1687     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1688
1689     TRACE("(%p)->(%p)\n", This, p);
1690
1691     return get_style_attr(This, STYLEID_BORDER, p);
1692 }
1693
1694 static HRESULT WINAPI HTMLStyle_put_borderTop(IHTMLStyle *iface, BSTR v)
1695 {
1696     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1697     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1698     return set_style_attr(This, STYLEID_BORDER_TOP, v, ATTR_FIX_PX);
1699 }
1700
1701 static HRESULT WINAPI HTMLStyle_get_borderTop(IHTMLStyle *iface, BSTR *p)
1702 {
1703     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1704     TRACE("(%p)->(%p)\n", This, p);
1705     return get_style_attr(This, STYLEID_BORDER_TOP, p);
1706 }
1707
1708 static HRESULT WINAPI HTMLStyle_put_borderRight(IHTMLStyle *iface, BSTR v)
1709 {
1710     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1711     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1712     return set_style_attr(This, STYLEID_BORDER_RIGHT, v, ATTR_FIX_PX);
1713 }
1714
1715 static HRESULT WINAPI HTMLStyle_get_borderRight(IHTMLStyle *iface, BSTR *p)
1716 {
1717     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1718     TRACE("(%p)->(%p)\n", This, p);
1719     return get_style_attr(This, STYLEID_BORDER_RIGHT, p);
1720 }
1721
1722 static HRESULT WINAPI HTMLStyle_put_borderBottom(IHTMLStyle *iface, BSTR v)
1723 {
1724     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1725     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1726     return set_style_attr(This, STYLEID_BORDER_BOTTOM, v, ATTR_FIX_PX);
1727 }
1728
1729 static HRESULT WINAPI HTMLStyle_get_borderBottom(IHTMLStyle *iface, BSTR *p)
1730 {
1731     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1732     TRACE("(%p)->(%p)\n", This, p);
1733     return get_style_attr(This, STYLEID_BORDER_BOTTOM, p);
1734 }
1735
1736 static HRESULT WINAPI HTMLStyle_put_borderLeft(IHTMLStyle *iface, BSTR v)
1737 {
1738     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1739
1740     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1741
1742     return set_style_attr(This, STYLEID_BORDER_LEFT, v, ATTR_FIX_PX);
1743 }
1744
1745 static HRESULT WINAPI HTMLStyle_get_borderLeft(IHTMLStyle *iface, BSTR *p)
1746 {
1747     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1748
1749     TRACE("(%p)->(%p)\n", This, p);
1750
1751     return get_style_attr(This, STYLEID_BORDER_LEFT, p);
1752 }
1753
1754 static HRESULT WINAPI HTMLStyle_put_borderColor(IHTMLStyle *iface, BSTR v)
1755 {
1756     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1757
1758     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1759
1760     return set_style_attr(This, STYLEID_BORDER_COLOR, v, 0);
1761 }
1762
1763 static HRESULT WINAPI HTMLStyle_get_borderColor(IHTMLStyle *iface, BSTR *p)
1764 {
1765     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1766
1767     TRACE("(%p)->(%p)\n", This, p);
1768
1769     return get_style_attr(This, STYLEID_BORDER_COLOR, p);
1770 }
1771
1772 static HRESULT WINAPI HTMLStyle_put_borderTopColor(IHTMLStyle *iface, VARIANT v)
1773 {
1774     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1775
1776     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1777
1778     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_COLOR, &v, ATTR_HEX_INT);
1779 }
1780
1781 static HRESULT WINAPI HTMLStyle_get_borderTopColor(IHTMLStyle *iface, VARIANT *p)
1782 {
1783     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1784
1785     TRACE("(%p)->(%p)\n", This, p);
1786
1787     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_COLOR, p, 0);
1788 }
1789
1790 static HRESULT WINAPI HTMLStyle_put_borderRightColor(IHTMLStyle *iface, VARIANT v)
1791 {
1792     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1793
1794     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1795
1796     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_COLOR, &v, ATTR_HEX_INT);
1797 }
1798
1799 static HRESULT WINAPI HTMLStyle_get_borderRightColor(IHTMLStyle *iface, VARIANT *p)
1800 {
1801     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1802
1803     TRACE("(%p)->(%p)\n", This, p);
1804
1805     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_COLOR, p, 0);
1806 }
1807
1808 static HRESULT WINAPI HTMLStyle_put_borderBottomColor(IHTMLStyle *iface, VARIANT v)
1809 {
1810     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1811
1812     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1813
1814     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_COLOR, &v, ATTR_HEX_INT);
1815 }
1816
1817 static HRESULT WINAPI HTMLStyle_get_borderBottomColor(IHTMLStyle *iface, VARIANT *p)
1818 {
1819     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1820
1821     TRACE("(%p)->(%p)\n", This, p);
1822
1823     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_COLOR, p, 0);
1824 }
1825
1826 static HRESULT WINAPI HTMLStyle_put_borderLeftColor(IHTMLStyle *iface, VARIANT v)
1827 {
1828     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1829
1830     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1831
1832     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_COLOR, &v, ATTR_HEX_INT);
1833 }
1834
1835 static HRESULT WINAPI HTMLStyle_get_borderLeftColor(IHTMLStyle *iface, VARIANT *p)
1836 {
1837     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1838
1839     TRACE("(%p)->(%p)\n", This, p);
1840
1841     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_COLOR, p, 0);
1842 }
1843
1844 static HRESULT WINAPI HTMLStyle_put_borderWidth(IHTMLStyle *iface, BSTR v)
1845 {
1846     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1847     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1848     return set_style_attr(This, STYLEID_BORDER_WIDTH, v, ATTR_FIX_PX);
1849 }
1850
1851 static HRESULT WINAPI HTMLStyle_get_borderWidth(IHTMLStyle *iface, BSTR *p)
1852 {
1853     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1854     TRACE("(%p)->(%p)\n", This, p);
1855     return get_style_attr(This, STYLEID_BORDER_WIDTH, p);
1856 }
1857
1858 static HRESULT WINAPI HTMLStyle_put_borderTopWidth(IHTMLStyle *iface, VARIANT v)
1859 {
1860     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1861
1862     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1863
1864     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_WIDTH, &v, 0);
1865 }
1866
1867 static HRESULT WINAPI HTMLStyle_get_borderTopWidth(IHTMLStyle *iface, VARIANT *p)
1868 {
1869     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1870
1871     TRACE("(%p)->(%p)\n", This, p);
1872
1873     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_TOP_WIDTH, p, 0);
1874 }
1875
1876 static HRESULT WINAPI HTMLStyle_put_borderRightWidth(IHTMLStyle *iface, VARIANT v)
1877 {
1878     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1879
1880     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1881
1882     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_WIDTH, &v, 0);
1883 }
1884
1885 static HRESULT WINAPI HTMLStyle_get_borderRightWidth(IHTMLStyle *iface, VARIANT *p)
1886 {
1887     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1888
1889     TRACE("(%p)->(%p)\n", This, p);
1890
1891     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_RIGHT_WIDTH, p, 0);
1892 }
1893
1894 static HRESULT WINAPI HTMLStyle_put_borderBottomWidth(IHTMLStyle *iface, VARIANT v)
1895 {
1896     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1897
1898     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1899
1900     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_WIDTH, &v, 0);
1901 }
1902
1903 static HRESULT WINAPI HTMLStyle_get_borderBottomWidth(IHTMLStyle *iface, VARIANT *p)
1904 {
1905     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1906     TRACE("(%p)->(%p)\n", This, p);
1907     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_BOTTOM_WIDTH, p, 0);
1908 }
1909
1910 static HRESULT WINAPI HTMLStyle_put_borderLeftWidth(IHTMLStyle *iface, VARIANT v)
1911 {
1912     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1913
1914     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1915
1916     return set_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_WIDTH, &v, 0);
1917 }
1918
1919 static HRESULT WINAPI HTMLStyle_get_borderLeftWidth(IHTMLStyle *iface, VARIANT *p)
1920 {
1921     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1922     TRACE("(%p)->(%p)\n", This, p);
1923     return get_nsstyle_attr_var(This->nsstyle, STYLEID_BORDER_LEFT_WIDTH, p, 0);
1924 }
1925
1926 static HRESULT WINAPI HTMLStyle_put_borderStyle(IHTMLStyle *iface, BSTR v)
1927 {
1928     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1929     static const WCHAR styleWindowInset[]  = {'w','i','n','d','o','w','-','i','n','s','e','t',0};
1930     HRESULT hres = S_OK;
1931     BSTR pstyle;
1932     int i=0;
1933     int last = 0;
1934
1935     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1936
1937     while(v[i] && hres == S_OK)
1938     {
1939         if(v[i] == (WCHAR)' ')
1940         {
1941             pstyle = SysAllocStringLen(&v[last], (i-last));
1942             if( !(is_valid_border_style(pstyle) || strcmpiW(styleWindowInset, pstyle) == 0))
1943             {
1944                 TRACE("1. Invalid style (%s)\n", debugstr_w(pstyle));
1945                 hres = E_INVALIDARG;
1946             }
1947             SysFreeString(pstyle);
1948             last = i+1;
1949         }
1950         i++;
1951     }
1952
1953     if(hres == S_OK)
1954     {
1955         pstyle = SysAllocStringLen(&v[last], i-last);
1956         if( !(is_valid_border_style(pstyle) || strcmpiW(styleWindowInset, pstyle) == 0))
1957         {
1958             TRACE("2. Invalid style (%s)\n", debugstr_w(pstyle));
1959             hres = E_INVALIDARG;
1960         }
1961         SysFreeString(pstyle);
1962     }
1963
1964     if(hres == S_OK)
1965         hres = set_nsstyle_attr(This->nsstyle, STYLEID_BORDER_STYLE, v, 0);
1966
1967     return hres;
1968 }
1969
1970 static HRESULT WINAPI HTMLStyle_get_borderStyle(IHTMLStyle *iface, BSTR *p)
1971 {
1972     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1973     TRACE("(%p)->(%p)\n", This, p);
1974     return get_style_attr(This, STYLEID_BORDER_STYLE, p);
1975 }
1976
1977 static HRESULT WINAPI HTMLStyle_put_borderTopStyle(IHTMLStyle *iface, BSTR v)
1978 {
1979     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1980     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1981
1982     if(!is_valid_border_style(v))
1983         return E_INVALIDARG;
1984
1985     return set_style_attr(This, STYLEID_BORDER_TOP_STYLE, v, 0);
1986 }
1987
1988 static HRESULT WINAPI HTMLStyle_get_borderTopStyle(IHTMLStyle *iface, BSTR *p)
1989 {
1990     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1991     TRACE("(%p)->(%p)\n", This, p);
1992     return get_style_attr(This, STYLEID_BORDER_TOP_STYLE, p);
1993 }
1994
1995 static HRESULT WINAPI HTMLStyle_put_borderRightStyle(IHTMLStyle *iface, BSTR v)
1996 {
1997     HTMLStyle *This = impl_from_IHTMLStyle(iface);
1998     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1999
2000     if(!is_valid_border_style(v))
2001         return E_INVALIDARG;
2002
2003     return set_style_attr(This, STYLEID_BORDER_RIGHT_STYLE, v, 0);
2004 }
2005
2006 static HRESULT WINAPI HTMLStyle_get_borderRightStyle(IHTMLStyle *iface, BSTR *p)
2007 {
2008     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2009     TRACE("(%p)->(%p)\n", This, p);
2010     return get_style_attr(This, STYLEID_BORDER_RIGHT_STYLE, p);
2011 }
2012
2013 static HRESULT WINAPI HTMLStyle_put_borderBottomStyle(IHTMLStyle *iface, BSTR v)
2014 {
2015     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2016     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2017
2018     if(!is_valid_border_style(v))
2019         return E_INVALIDARG;
2020
2021     return set_style_attr(This, STYLEID_BORDER_BOTTOM_STYLE, v, 0);
2022 }
2023
2024 static HRESULT WINAPI HTMLStyle_get_borderBottomStyle(IHTMLStyle *iface, BSTR *p)
2025 {
2026     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2027     TRACE("(%p)->(%p)\n", This, p);
2028     return get_style_attr(This, STYLEID_BORDER_BOTTOM_STYLE, p);
2029 }
2030
2031 static HRESULT WINAPI HTMLStyle_put_borderLeftStyle(IHTMLStyle *iface, BSTR v)
2032 {
2033     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2034     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2035
2036     if(!is_valid_border_style(v))
2037         return E_INVALIDARG;
2038
2039     return set_style_attr(This, STYLEID_BORDER_LEFT_STYLE, v, 0);
2040 }
2041
2042 static HRESULT WINAPI HTMLStyle_get_borderLeftStyle(IHTMLStyle *iface, BSTR *p)
2043 {
2044     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2045     TRACE("(%p)->(%p)\n", This, p);
2046     return get_style_attr(This, STYLEID_BORDER_LEFT_STYLE, p);
2047 }
2048
2049 static HRESULT WINAPI HTMLStyle_put_width(IHTMLStyle *iface, VARIANT v)
2050 {
2051     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2052
2053     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2054
2055     return set_nsstyle_attr_var(This->nsstyle, STYLEID_WIDTH, &v, ATTR_FIX_PX);
2056 }
2057
2058 static HRESULT WINAPI HTMLStyle_get_width(IHTMLStyle *iface, VARIANT *p)
2059 {
2060     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2061
2062     TRACE("(%p)->(%p)\n", This, p);
2063
2064     return get_nsstyle_attr_var(This->nsstyle, STYLEID_WIDTH, p, 0);
2065 }
2066
2067 static HRESULT WINAPI HTMLStyle_put_height(IHTMLStyle *iface, VARIANT v)
2068 {
2069     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2070
2071     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2072
2073     return set_nsstyle_attr_var(This->nsstyle, STYLEID_HEIGHT, &v, ATTR_FIX_PX);
2074 }
2075
2076 static HRESULT WINAPI HTMLStyle_get_height(IHTMLStyle *iface, VARIANT *p)
2077 {
2078     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2079
2080     TRACE("(%p)->(%p)\n", This, p);
2081
2082     return get_nsstyle_attr_var(This->nsstyle, STYLEID_HEIGHT, p, 0);
2083 }
2084
2085 static HRESULT WINAPI HTMLStyle_put_styleFloat(IHTMLStyle *iface, BSTR v)
2086 {
2087     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2088     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2089     return E_NOTIMPL;
2090 }
2091
2092 static HRESULT WINAPI HTMLStyle_get_styleFloat(IHTMLStyle *iface, BSTR *p)
2093 {
2094     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2095     FIXME("(%p)->(%p)\n", This, p);
2096     return E_NOTIMPL;
2097 }
2098
2099 static HRESULT WINAPI HTMLStyle_put_clear(IHTMLStyle *iface, BSTR v)
2100 {
2101     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2102
2103     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2104
2105     return set_style_attr(This, STYLEID_CLEAR, v, 0);
2106 }
2107
2108 static HRESULT WINAPI HTMLStyle_get_clear(IHTMLStyle *iface, BSTR *p)
2109 {
2110     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2111
2112     TRACE("(%p)->(%p)\n", This, p);
2113
2114     return get_style_attr(This, STYLEID_CLEAR, p);
2115 }
2116
2117 static HRESULT WINAPI HTMLStyle_put_display(IHTMLStyle *iface, BSTR v)
2118 {
2119     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2120
2121     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2122
2123     return set_style_attr(This, STYLEID_DISPLAY, v, 0);
2124 }
2125
2126 static HRESULT WINAPI HTMLStyle_get_display(IHTMLStyle *iface, BSTR *p)
2127 {
2128     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2129
2130     TRACE("(%p)->(%p)\n", This, p);
2131
2132     return get_style_attr(This, STYLEID_DISPLAY, p);
2133 }
2134
2135 static HRESULT WINAPI HTMLStyle_put_visibility(IHTMLStyle *iface, BSTR v)
2136 {
2137     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2138
2139     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2140
2141     return set_style_attr(This, STYLEID_VISIBILITY, v, 0);
2142 }
2143
2144 static HRESULT WINAPI HTMLStyle_get_visibility(IHTMLStyle *iface, BSTR *p)
2145 {
2146     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2147
2148     TRACE("(%p)->(%p)\n", This, p);
2149
2150     return get_style_attr(This, STYLEID_VISIBILITY, p);
2151 }
2152
2153 static HRESULT WINAPI HTMLStyle_put_listStyleType(IHTMLStyle *iface, BSTR v)
2154 {
2155     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2156     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2157     return E_NOTIMPL;
2158 }
2159
2160 static HRESULT WINAPI HTMLStyle_get_listStyleType(IHTMLStyle *iface, BSTR *p)
2161 {
2162     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2163     FIXME("(%p)->(%p)\n", This, p);
2164     return E_NOTIMPL;
2165 }
2166
2167 static HRESULT WINAPI HTMLStyle_put_listStylePosition(IHTMLStyle *iface, BSTR v)
2168 {
2169     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2170     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2171     return E_NOTIMPL;
2172 }
2173
2174 static HRESULT WINAPI HTMLStyle_get_listStylePosition(IHTMLStyle *iface, BSTR *p)
2175 {
2176     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2177     FIXME("(%p)->(%p)\n", This, p);
2178     return E_NOTIMPL;
2179 }
2180
2181 static HRESULT WINAPI HTMLStyle_put_listStyleImage(IHTMLStyle *iface, BSTR v)
2182 {
2183     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2184     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2185     return E_NOTIMPL;
2186 }
2187
2188 static HRESULT WINAPI HTMLStyle_get_listStyleImage(IHTMLStyle *iface, BSTR *p)
2189 {
2190     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2191     FIXME("(%p)->(%p)\n", This, p);
2192     return E_NOTIMPL;
2193 }
2194
2195 static HRESULT WINAPI HTMLStyle_put_listStyle(IHTMLStyle *iface, BSTR v)
2196 {
2197     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2198     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2199     return E_NOTIMPL;
2200 }
2201
2202 static HRESULT WINAPI HTMLStyle_get_listStyle(IHTMLStyle *iface, BSTR *p)
2203 {
2204     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2205     FIXME("(%p)->(%p)\n", This, p);
2206     return E_NOTIMPL;
2207 }
2208
2209 static HRESULT WINAPI HTMLStyle_put_whiteSpace(IHTMLStyle *iface, BSTR v)
2210 {
2211     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2212     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
2213     return E_NOTIMPL;
2214 }
2215
2216 static HRESULT WINAPI HTMLStyle_get_whiteSpace(IHTMLStyle *iface, BSTR *p)
2217 {
2218     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2219     FIXME("(%p)->(%p)\n", This, p);
2220     return E_NOTIMPL;
2221 }
2222
2223 static HRESULT WINAPI HTMLStyle_put_top(IHTMLStyle *iface, VARIANT v)
2224 {
2225     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2226
2227     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2228
2229     return set_nsstyle_attr_var(This->nsstyle, STYLEID_TOP, &v, 0);
2230 }
2231
2232 static HRESULT WINAPI HTMLStyle_get_top(IHTMLStyle *iface, VARIANT *p)
2233 {
2234     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2235
2236     TRACE("(%p)->(%p)\n", This, p);
2237
2238     return get_nsstyle_attr_var(This->nsstyle, STYLEID_TOP, p, 0);
2239 }
2240
2241 static HRESULT WINAPI HTMLStyle_put_left(IHTMLStyle *iface, VARIANT v)
2242 {
2243     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2244
2245     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2246
2247     return set_nsstyle_attr_var(This->nsstyle, STYLEID_LEFT, &v, 0);
2248 }
2249
2250 static HRESULT WINAPI HTMLStyle_get_left(IHTMLStyle *iface, VARIANT *p)
2251 {
2252     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2253
2254     TRACE("(%p)->(%p)\n", This, p);
2255
2256     return get_nsstyle_attr_var(This->nsstyle, STYLEID_LEFT, p, 0);
2257 }
2258
2259 static HRESULT WINAPI HTMLStyle_get_position(IHTMLStyle *iface, BSTR *p)
2260 {
2261     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2262     TRACE("(%p)->(%p)\n", This, p);
2263     return IHTMLStyle2_get_position(&This->IHTMLStyle2_iface, p);
2264 }
2265
2266 static HRESULT WINAPI HTMLStyle_put_zIndex(IHTMLStyle *iface, VARIANT v)
2267 {
2268     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2269
2270     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
2271
2272     return set_nsstyle_attr_var(This->nsstyle, STYLEID_Z_INDEX, &v, 0);
2273 }
2274
2275 static HRESULT WINAPI HTMLStyle_get_zIndex(IHTMLStyle *iface, VARIANT *p)
2276 {
2277     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2278
2279     TRACE("(%p)->(%p)\n", This, p);
2280
2281     return get_nsstyle_attr_var(This->nsstyle, STYLEID_Z_INDEX, p, ATTR_STR_TO_INT);
2282 }
2283
2284 static HRESULT WINAPI HTMLStyle_put_overflow(IHTMLStyle *iface, BSTR v)
2285 {
2286     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2287     static const WCHAR szVisible[] = {'v','i','s','i','b','l','e',0};
2288     static const WCHAR szScroll[]  = {'s','c','r','o','l','l',0};
2289     static const WCHAR szHidden[]  = {'h','i','d','d','e','n',0};
2290     static const WCHAR szAuto[]    = {'a','u','t','o',0};
2291
2292     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2293
2294     /* overflow can only be one of the follow values. */
2295     if(!v || !*v || strcmpiW(szVisible, v) == 0 || strcmpiW(szScroll, v) == 0 ||
2296              strcmpiW(szHidden, v) == 0  || strcmpiW(szAuto, v) == 0)
2297     {
2298         return set_nsstyle_attr(This->nsstyle, STYLEID_OVERFLOW, v, 0);
2299     }
2300
2301     return E_INVALIDARG;
2302 }
2303
2304
2305 static HRESULT WINAPI HTMLStyle_get_overflow(IHTMLStyle *iface, BSTR *p)
2306 {
2307     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2308
2309     TRACE("(%p)->(%p)\n", This, p);
2310
2311     if(!p)
2312        return E_INVALIDARG;
2313
2314     return get_style_attr(This, STYLEID_OVERFLOW, p);
2315 }
2316
2317 static HRESULT WINAPI HTMLStyle_put_pageBreakBefore(IHTMLStyle *iface, BSTR v)
2318 {
2319     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2320
2321     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2322
2323     return set_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_BEFORE, v, 0);
2324 }
2325
2326 static HRESULT WINAPI HTMLStyle_get_pageBreakBefore(IHTMLStyle *iface, BSTR *p)
2327 {
2328     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2329
2330     TRACE("(%p)->(%p)\n", This, p);
2331
2332     return get_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_BEFORE, p, 0);
2333 }
2334
2335 static HRESULT WINAPI HTMLStyle_put_pageBreakAfter(IHTMLStyle *iface, BSTR v)
2336 {
2337     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2338
2339     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2340
2341     return set_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_AFTER, v, 0);
2342 }
2343
2344 static HRESULT WINAPI HTMLStyle_get_pageBreakAfter(IHTMLStyle *iface, BSTR *p)
2345 {
2346     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2347
2348     TRACE("(%p)->(%p)\n", This, p);
2349
2350     return get_nsstyle_attr(This->nsstyle, STYLEID_PAGE_BREAK_AFTER, p, 0);
2351 }
2352
2353 static HRESULT WINAPI HTMLStyle_put_cssText(IHTMLStyle *iface, BSTR v)
2354 {
2355     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2356     nsAString text_str;
2357     nsresult nsres;
2358
2359     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2360
2361     nsAString_InitDepend(&text_str, v);
2362     nsres = nsIDOMCSSStyleDeclaration_SetCssText(This->nsstyle, &text_str);
2363     nsAString_Finish(&text_str);
2364     if(NS_FAILED(nsres)) {
2365         FIXME("SetCssStyle failed: %08x\n", nsres);
2366         return E_FAIL;
2367     }
2368
2369     return S_OK;
2370 }
2371
2372 static HRESULT WINAPI HTMLStyle_get_cssText(IHTMLStyle *iface, BSTR *p)
2373 {
2374     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2375     nsAString text_str;
2376     nsresult nsres;
2377
2378     TRACE("(%p)->(%p)\n", This, p);
2379
2380     /* FIXME: Gecko style formatting is different than IE (uppercase). */
2381     nsAString_Init(&text_str, NULL);
2382     nsres = nsIDOMCSSStyleDeclaration_GetCssText(This->nsstyle, &text_str);
2383     if(NS_SUCCEEDED(nsres)) {
2384         const PRUnichar *text;
2385
2386         nsAString_GetData(&text_str, &text);
2387         *p = *text ? SysAllocString(text) : NULL;
2388     }else {
2389         FIXME("GetCssStyle failed: %08x\n", nsres);
2390         *p = NULL;
2391     }
2392
2393     nsAString_Finish(&text_str);
2394     return S_OK;
2395 }
2396
2397 static HRESULT WINAPI HTMLStyle_put_pixelTop(IHTMLStyle *iface, LONG v)
2398 {
2399     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2400     FIXME("(%p)->()\n", This);
2401     return E_NOTIMPL;
2402 }
2403
2404 static HRESULT WINAPI HTMLStyle_get_pixelTop(IHTMLStyle *iface, LONG *p)
2405 {
2406     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2407     FIXME("(%p)->()\n", This);
2408     return E_NOTIMPL;
2409 }
2410
2411 static HRESULT WINAPI HTMLStyle_put_pixelLeft(IHTMLStyle *iface, LONG v)
2412 {
2413     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2414
2415     TRACE("(%p)->(%d)\n", This, v);
2416
2417     return set_style_pxattr(This->nsstyle, STYLEID_LEFT, v);
2418 }
2419
2420 static HRESULT WINAPI HTMLStyle_get_pixelLeft(IHTMLStyle *iface, LONG *p)
2421 {
2422     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2423
2424     TRACE("(%p)->(%p)\n", This, p);
2425
2426     return get_nsstyle_pixel_val(This, STYLEID_LEFT, p);
2427 }
2428
2429 static HRESULT WINAPI HTMLStyle_put_pixelWidth(IHTMLStyle *iface, LONG v)
2430 {
2431     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2432
2433     TRACE("(%p)->()\n", This);
2434
2435     return set_style_pxattr(This->nsstyle, STYLEID_WIDTH, v);
2436 }
2437
2438 static HRESULT WINAPI HTMLStyle_get_pixelWidth(IHTMLStyle *iface, LONG *p)
2439 {
2440     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2441     FIXME("(%p)->()\n", This);
2442     return E_NOTIMPL;
2443 }
2444
2445 static HRESULT WINAPI HTMLStyle_put_pixelHeight(IHTMLStyle *iface, LONG v)
2446 {
2447     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2448     FIXME("(%p)->()\n", This);
2449     return E_NOTIMPL;
2450 }
2451
2452 static HRESULT WINAPI HTMLStyle_get_pixelHeight(IHTMLStyle *iface, LONG *p)
2453 {
2454     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2455     FIXME("(%p)->()\n", This);
2456     return E_NOTIMPL;
2457 }
2458
2459 static HRESULT WINAPI HTMLStyle_put_posTop(IHTMLStyle *iface, float v)
2460 {
2461     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2462
2463     TRACE("(%p)->(%f)\n", This, v);
2464
2465     return set_style_pos(This, STYLEID_TOP, v);
2466 }
2467
2468 static HRESULT WINAPI HTMLStyle_get_posTop(IHTMLStyle *iface, float *p)
2469 {
2470     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2471
2472     TRACE("(%p)->(%p)\n", This, p);
2473
2474     if(!p)
2475         return E_POINTER;
2476
2477     return get_nsstyle_pos(This, STYLEID_TOP, p);
2478 }
2479
2480 static HRESULT WINAPI HTMLStyle_put_posLeft(IHTMLStyle *iface, float v)
2481 {
2482     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2483
2484     TRACE("(%p)->(%f)\n", This, v);
2485
2486     return set_style_pos(This, STYLEID_LEFT, v);
2487 }
2488
2489 static HRESULT WINAPI HTMLStyle_get_posLeft(IHTMLStyle *iface, float *p)
2490 {
2491     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2492
2493     TRACE("(%p)->(%p)\n", This, p);
2494
2495     if(!p)
2496         return E_POINTER;
2497
2498     return get_nsstyle_pos(This, STYLEID_LEFT, p);
2499 }
2500
2501 static HRESULT WINAPI HTMLStyle_put_posWidth(IHTMLStyle *iface, float v)
2502 {
2503     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2504
2505     TRACE("(%p)->(%f)\n", This, v);
2506
2507     return set_style_pos(This, STYLEID_WIDTH, v);
2508 }
2509
2510 static HRESULT WINAPI HTMLStyle_get_posWidth(IHTMLStyle *iface, float *p)
2511 {
2512     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2513
2514     TRACE("(%p)->(%p)\n", This, p);
2515
2516     if(!p)
2517         return E_POINTER;
2518
2519     if(get_nsstyle_pos(This, STYLEID_WIDTH, p) != S_OK)
2520         *p = 0.0f;
2521
2522     return S_OK;
2523 }
2524
2525 static HRESULT WINAPI HTMLStyle_put_posHeight(IHTMLStyle *iface, float v)
2526 {
2527     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2528
2529     TRACE("(%p)->(%f)\n", This, v);
2530
2531     return set_style_pos(This, STYLEID_HEIGHT, v);
2532 }
2533
2534 static HRESULT WINAPI HTMLStyle_get_posHeight(IHTMLStyle *iface, float *p)
2535 {
2536     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2537
2538     TRACE("(%p)->(%p)\n", This, p);
2539
2540     if(!p)
2541         return E_POINTER;
2542
2543     if(get_nsstyle_pos(This, STYLEID_HEIGHT, p) != S_OK)
2544         *p = 0.0f;
2545
2546     return S_OK;
2547 }
2548
2549 static HRESULT WINAPI HTMLStyle_put_cursor(IHTMLStyle *iface, BSTR v)
2550 {
2551     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2552
2553     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2554
2555     return set_style_attr(This, STYLEID_CURSOR, v, 0);
2556 }
2557
2558 static HRESULT WINAPI HTMLStyle_get_cursor(IHTMLStyle *iface, BSTR *p)
2559 {
2560     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2561
2562     TRACE("(%p)->(%p)\n", This, p);
2563
2564     return get_style_attr(This, STYLEID_CURSOR, p);
2565 }
2566
2567 static HRESULT WINAPI HTMLStyle_put_clip(IHTMLStyle *iface, BSTR v)
2568 {
2569     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2570
2571     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2572
2573     return set_style_attr(This, STYLEID_CLIP, v, 0);
2574 }
2575
2576 static HRESULT WINAPI HTMLStyle_get_clip(IHTMLStyle *iface, BSTR *p)
2577 {
2578     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2579
2580     TRACE("(%p)->(%p)\n", This, p);
2581
2582     return get_nsstyle_attr(This->nsstyle, STYLEID_CLIP, p, ATTR_REMOVE_COMMA);
2583 }
2584
2585 static void set_opacity(HTMLStyle *This, const WCHAR *val)
2586 {
2587     nsAString name_str, val_str, empty_str;
2588     nsresult nsres;
2589
2590     static const WCHAR opacityW[] = {'o','p','a','c','i','t','y',0};
2591
2592     TRACE("%s\n", debugstr_w(val));
2593
2594     nsAString_InitDepend(&name_str, opacityW);
2595     nsAString_InitDepend(&val_str, val);
2596     nsAString_InitDepend(&empty_str, emptyW);
2597
2598     nsres = nsIDOMCSSStyleDeclaration_SetProperty(This->nsstyle, &name_str, &val_str, &empty_str);
2599     if(NS_FAILED(nsres))
2600         ERR("SetProperty failed: %08x\n", nsres);
2601
2602     nsAString_Finish(&name_str);
2603     nsAString_Finish(&val_str);
2604     nsAString_Finish(&empty_str);
2605 }
2606
2607 static void update_filter(HTMLStyle *This)
2608 {
2609     const WCHAR *ptr = This->elem->filter, *ptr2;
2610
2611     static const WCHAR alphaW[] = {'a','l','p','h','a'};
2612
2613     if(!ptr) {
2614         set_opacity(This, emptyW);
2615         return;
2616     }
2617
2618     while(1) {
2619         while(isspaceW(*ptr))
2620             ptr++;
2621         if(!*ptr)
2622             break;
2623
2624         ptr2 = ptr;
2625         while(isalnumW(*ptr))
2626             ptr++;
2627         if(ptr == ptr2) {
2628             WARN("unexpected char '%c'\n", *ptr);
2629             break;
2630         }
2631         if(*ptr != '(') {
2632             WARN("expected '('\n");
2633             continue;
2634         }
2635
2636         if(ptr2 + sizeof(alphaW)/sizeof(WCHAR) == ptr && !memcmp(ptr2, alphaW, sizeof(alphaW))) {
2637             static const WCHAR formatW[] = {'%','f',0};
2638             static const WCHAR opacityW[] = {'o','p','a','c','i','t','y','='};
2639
2640             ptr++;
2641             do {
2642                 while(isspaceW(*ptr))
2643                     ptr++;
2644
2645                 ptr2 = ptr;
2646                 while(*ptr && *ptr != ',' && *ptr != ')')
2647                     ptr++;
2648                 if(!*ptr) {
2649                     WARN("unexpected end of string\n");
2650                     break;
2651                 }
2652
2653                 if(ptr-ptr2 > sizeof(opacityW)/sizeof(WCHAR) && !memcmp(ptr2, opacityW, sizeof(opacityW))) {
2654                     float fval = 0.0f, e = 0.1f;
2655                     WCHAR buf[32];
2656
2657                     ptr2 += sizeof(opacityW)/sizeof(WCHAR);
2658
2659                     while(isdigitW(*ptr2))
2660                         fval = fval*10.0f + (float)(*ptr2++ - '0');
2661
2662                     if(*ptr2 == '.') {
2663                         while(isdigitW(*++ptr2)) {
2664                             fval += e * (float)(*ptr2++ - '0');
2665                             e *= 0.1f;
2666                         }
2667                     }
2668
2669                     sprintfW(buf, formatW, fval * 0.01f);
2670                     set_opacity(This, buf);
2671                 }else {
2672                     FIXME("unknown param %s\n", debugstr_wn(ptr2, ptr-ptr2));
2673                 }
2674
2675                 if(*ptr == ',')
2676                     ptr++;
2677             }while(*ptr != ')');
2678         }else {
2679             FIXME("unknown filter %s\n", debugstr_wn(ptr2, ptr-ptr2));
2680             ptr = strchrW(ptr, ')');
2681             if(!ptr)
2682                 break;
2683             ptr++;
2684         }
2685     }
2686 }
2687
2688 static HRESULT WINAPI HTMLStyle_put_filter(IHTMLStyle *iface, BSTR v)
2689 {
2690     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2691     WCHAR *new_filter = NULL;
2692
2693     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
2694
2695     if(!This->elem) {
2696         FIXME("Element already destroyed\n");
2697         return E_UNEXPECTED;
2698     }
2699
2700     if(v) {
2701         new_filter = heap_strdupW(v);
2702         if(!new_filter)
2703             return E_OUTOFMEMORY;
2704     }
2705
2706     heap_free(This->elem->filter);
2707     This->elem->filter = new_filter;
2708
2709     update_filter(This);
2710     return S_OK;
2711 }
2712
2713 static HRESULT WINAPI HTMLStyle_get_filter(IHTMLStyle *iface, BSTR *p)
2714 {
2715     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2716
2717     TRACE("(%p)->(%p)\n", This, p);
2718
2719     if(!This->elem) {
2720         FIXME("Element already destroyed\n");
2721         return E_UNEXPECTED;
2722     }
2723
2724     if(This->elem->filter) {
2725         *p = SysAllocString(This->elem->filter);
2726         if(!*p)
2727             return E_OUTOFMEMORY;
2728     }else {
2729         *p = NULL;
2730     }
2731
2732     return S_OK;
2733 }
2734
2735 static HRESULT WINAPI HTMLStyle_setAttribute(IHTMLStyle *iface, BSTR strAttributeName,
2736         VARIANT AttributeValue, LONG lFlags)
2737 {
2738     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2739     HRESULT hres;
2740     DISPID dispid;
2741
2742     TRACE("(%p)->(%s %s %08x)\n", This, debugstr_w(strAttributeName),
2743           debugstr_variant(&AttributeValue), lFlags);
2744
2745     if(!strAttributeName)
2746         return E_INVALIDARG;
2747
2748     if(lFlags == 1)
2749         FIXME("Parameter lFlags ignored\n");
2750
2751     hres = HTMLStyle_GetIDsOfNames(iface, &IID_NULL, &strAttributeName, 1,
2752                         LOCALE_USER_DEFAULT, &dispid);
2753     if(hres == S_OK)
2754     {
2755         VARIANT ret;
2756         DISPID dispidNamed = DISPID_PROPERTYPUT;
2757         DISPPARAMS params;
2758
2759         params.cArgs = 1;
2760         params.rgvarg = &AttributeValue;
2761         params.cNamedArgs = 1;
2762         params.rgdispidNamedArgs = &dispidNamed;
2763
2764         hres = HTMLStyle_Invoke(iface, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2765             DISPATCH_PROPERTYPUT, &params, &ret, NULL, NULL);
2766     }
2767     else
2768     {
2769         FIXME("Custom attributes not supported.\n");
2770     }
2771
2772     TRACE("ret: %08x\n", hres);
2773
2774     return hres;
2775 }
2776
2777 static HRESULT WINAPI HTMLStyle_getAttribute(IHTMLStyle *iface, BSTR strAttributeName,
2778         LONG lFlags, VARIANT *AttributeValue)
2779 {
2780     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2781     HRESULT hres;
2782     DISPID dispid;
2783
2784     TRACE("(%p)->(%s v%p %08x)\n", This, debugstr_w(strAttributeName),
2785           AttributeValue, lFlags);
2786
2787     if(!AttributeValue || !strAttributeName)
2788         return E_INVALIDARG;
2789
2790     if(lFlags == 1)
2791         FIXME("Parameter lFlags ignored\n");
2792
2793     hres = HTMLStyle_GetIDsOfNames(iface, &IID_NULL, &strAttributeName, 1,
2794                         LOCALE_USER_DEFAULT, &dispid);
2795     if(hres == S_OK)
2796     {
2797         DISPPARAMS params = {NULL, NULL, 0, 0 };
2798
2799         hres = HTMLStyle_Invoke(iface, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2800             DISPATCH_PROPERTYGET, &params, AttributeValue, NULL, NULL);
2801     }
2802     else
2803     {
2804         FIXME("Custom attributes not supported.\n");
2805     }
2806
2807     return hres;
2808 }
2809
2810 static HRESULT WINAPI HTMLStyle_removeAttribute(IHTMLStyle *iface, BSTR strAttributeName,
2811                                                 LONG lFlags, VARIANT_BOOL *pfSuccess)
2812 {
2813     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2814     const style_tbl_entry_t *style_entry;
2815     nsAString name_str, ret_str;
2816     nsresult nsres;
2817     HRESULT hres;
2818
2819     TRACE("(%p)->(%s %08x %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
2820
2821     style_entry = lookup_style_tbl(strAttributeName);
2822     if(!style_entry) {
2823         DISPID dispid;
2824         unsigned i;
2825
2826         hres = IDispatchEx_GetDispID(&This->dispex.IDispatchEx_iface, strAttributeName,
2827                 (lFlags&1) ? fdexNameCaseSensitive : fdexNameCaseInsensitive, &dispid);
2828         if(hres != S_OK) {
2829             *pfSuccess = VARIANT_FALSE;
2830             return S_OK;
2831         }
2832
2833         for(i=0; i < sizeof(style_tbl)/sizeof(*style_tbl); i++) {
2834             if(dispid == style_tbl[i].dispid)
2835                 break;
2836         }
2837
2838         if(i == sizeof(style_tbl)/sizeof(*style_tbl))
2839             return remove_prop(&This->dispex, strAttributeName, pfSuccess);
2840         style_entry = style_tbl+i;
2841     }
2842
2843     /* filter property is a special case */
2844     if(style_entry->dispid == DISPID_IHTMLSTYLE_FILTER) {
2845         *pfSuccess = This->elem->filter && *This->elem->filter ? VARIANT_TRUE : VARIANT_FALSE;
2846         heap_free(This->elem->filter);
2847         This->elem->filter = NULL;
2848         update_filter(This);
2849         return S_OK;
2850     }
2851
2852     nsAString_InitDepend(&name_str, style_entry->name);
2853     nsAString_Init(&ret_str, NULL);
2854     nsres = nsIDOMCSSStyleDeclaration_RemoveProperty(This->nsstyle, &name_str, &ret_str);
2855     if(NS_SUCCEEDED(nsres)) {
2856         const PRUnichar *ret;
2857         nsAString_GetData(&ret_str, &ret);
2858         *pfSuccess = *ret ? VARIANT_TRUE : VARIANT_FALSE;
2859     }else {
2860         ERR("RemoveProperty failed: %08x\n", nsres);
2861     }
2862     nsAString_Finish(&name_str);
2863     nsAString_Finish(&ret_str);
2864     return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
2865 }
2866
2867 static HRESULT WINAPI HTMLStyle_toString(IHTMLStyle *iface, BSTR *String)
2868 {
2869     HTMLStyle *This = impl_from_IHTMLStyle(iface);
2870     FIXME("(%p)->(%p)\n", This, String);
2871     return E_NOTIMPL;
2872 }
2873
2874 static const IHTMLStyleVtbl HTMLStyleVtbl = {
2875     HTMLStyle_QueryInterface,
2876     HTMLStyle_AddRef,
2877     HTMLStyle_Release,
2878     HTMLStyle_GetTypeInfoCount,
2879     HTMLStyle_GetTypeInfo,
2880     HTMLStyle_GetIDsOfNames,
2881     HTMLStyle_Invoke,
2882     HTMLStyle_put_fontFamily,
2883     HTMLStyle_get_fontFamily,
2884     HTMLStyle_put_fontStyle,
2885     HTMLStyle_get_fontStyle,
2886     HTMLStyle_put_fontVariant,
2887     HTMLStyle_get_fontVariant,
2888     HTMLStyle_put_fontWeight,
2889     HTMLStyle_get_fontWeight,
2890     HTMLStyle_put_fontSize,
2891     HTMLStyle_get_fontSize,
2892     HTMLStyle_put_font,
2893     HTMLStyle_get_font,
2894     HTMLStyle_put_color,
2895     HTMLStyle_get_color,
2896     HTMLStyle_put_background,
2897     HTMLStyle_get_background,
2898     HTMLStyle_put_backgroundColor,
2899     HTMLStyle_get_backgroundColor,
2900     HTMLStyle_put_backgroundImage,
2901     HTMLStyle_get_backgroundImage,
2902     HTMLStyle_put_backgroundRepeat,
2903     HTMLStyle_get_backgroundRepeat,
2904     HTMLStyle_put_backgroundAttachment,
2905     HTMLStyle_get_backgroundAttachment,
2906     HTMLStyle_put_backgroundPosition,
2907     HTMLStyle_get_backgroundPosition,
2908     HTMLStyle_put_backgroundPositionX,
2909     HTMLStyle_get_backgroundPositionX,
2910     HTMLStyle_put_backgroundPositionY,
2911     HTMLStyle_get_backgroundPositionY,
2912     HTMLStyle_put_wordSpacing,
2913     HTMLStyle_get_wordSpacing,
2914     HTMLStyle_put_letterSpacing,
2915     HTMLStyle_get_letterSpacing,
2916     HTMLStyle_put_textDecoration,
2917     HTMLStyle_get_textDecoration,
2918     HTMLStyle_put_textDecorationNone,
2919     HTMLStyle_get_textDecorationNone,
2920     HTMLStyle_put_textDecorationUnderline,
2921     HTMLStyle_get_textDecorationUnderline,
2922     HTMLStyle_put_textDecorationOverline,
2923     HTMLStyle_get_textDecorationOverline,
2924     HTMLStyle_put_textDecorationLineThrough,
2925     HTMLStyle_get_textDecorationLineThrough,
2926     HTMLStyle_put_textDecorationBlink,
2927     HTMLStyle_get_textDecorationBlink,
2928     HTMLStyle_put_verticalAlign,
2929     HTMLStyle_get_verticalAlign,
2930     HTMLStyle_put_textTransform,
2931     HTMLStyle_get_textTransform,
2932     HTMLStyle_put_textAlign,
2933     HTMLStyle_get_textAlign,
2934     HTMLStyle_put_textIndent,
2935     HTMLStyle_get_textIndent,
2936     HTMLStyle_put_lineHeight,
2937     HTMLStyle_get_lineHeight,
2938     HTMLStyle_put_marginTop,
2939     HTMLStyle_get_marginTop,
2940     HTMLStyle_put_marginRight,
2941     HTMLStyle_get_marginRight,
2942     HTMLStyle_put_marginBottom,
2943     HTMLStyle_get_marginBottom,
2944     HTMLStyle_put_marginLeft,
2945     HTMLStyle_get_marginLeft,
2946     HTMLStyle_put_margin,
2947     HTMLStyle_get_margin,
2948     HTMLStyle_put_paddingTop,
2949     HTMLStyle_get_paddingTop,
2950     HTMLStyle_put_paddingRight,
2951     HTMLStyle_get_paddingRight,
2952     HTMLStyle_put_paddingBottom,
2953     HTMLStyle_get_paddingBottom,
2954     HTMLStyle_put_paddingLeft,
2955     HTMLStyle_get_paddingLeft,
2956     HTMLStyle_put_padding,
2957     HTMLStyle_get_padding,
2958     HTMLStyle_put_border,
2959     HTMLStyle_get_border,
2960     HTMLStyle_put_borderTop,
2961     HTMLStyle_get_borderTop,
2962     HTMLStyle_put_borderRight,
2963     HTMLStyle_get_borderRight,
2964     HTMLStyle_put_borderBottom,
2965     HTMLStyle_get_borderBottom,
2966     HTMLStyle_put_borderLeft,
2967     HTMLStyle_get_borderLeft,
2968     HTMLStyle_put_borderColor,
2969     HTMLStyle_get_borderColor,
2970     HTMLStyle_put_borderTopColor,
2971     HTMLStyle_get_borderTopColor,
2972     HTMLStyle_put_borderRightColor,
2973     HTMLStyle_get_borderRightColor,
2974     HTMLStyle_put_borderBottomColor,
2975     HTMLStyle_get_borderBottomColor,
2976     HTMLStyle_put_borderLeftColor,
2977     HTMLStyle_get_borderLeftColor,
2978     HTMLStyle_put_borderWidth,
2979     HTMLStyle_get_borderWidth,
2980     HTMLStyle_put_borderTopWidth,
2981     HTMLStyle_get_borderTopWidth,
2982     HTMLStyle_put_borderRightWidth,
2983     HTMLStyle_get_borderRightWidth,
2984     HTMLStyle_put_borderBottomWidth,
2985     HTMLStyle_get_borderBottomWidth,
2986     HTMLStyle_put_borderLeftWidth,
2987     HTMLStyle_get_borderLeftWidth,
2988     HTMLStyle_put_borderStyle,
2989     HTMLStyle_get_borderStyle,
2990     HTMLStyle_put_borderTopStyle,
2991     HTMLStyle_get_borderTopStyle,
2992     HTMLStyle_put_borderRightStyle,
2993     HTMLStyle_get_borderRightStyle,
2994     HTMLStyle_put_borderBottomStyle,
2995     HTMLStyle_get_borderBottomStyle,
2996     HTMLStyle_put_borderLeftStyle,
2997     HTMLStyle_get_borderLeftStyle,
2998     HTMLStyle_put_width,
2999     HTMLStyle_get_width,
3000     HTMLStyle_put_height,
3001     HTMLStyle_get_height,
3002     HTMLStyle_put_styleFloat,
3003     HTMLStyle_get_styleFloat,
3004     HTMLStyle_put_clear,
3005     HTMLStyle_get_clear,
3006     HTMLStyle_put_display,
3007     HTMLStyle_get_display,
3008     HTMLStyle_put_visibility,
3009     HTMLStyle_get_visibility,
3010     HTMLStyle_put_listStyleType,
3011     HTMLStyle_get_listStyleType,
3012     HTMLStyle_put_listStylePosition,
3013     HTMLStyle_get_listStylePosition,
3014     HTMLStyle_put_listStyleImage,
3015     HTMLStyle_get_listStyleImage,
3016     HTMLStyle_put_listStyle,
3017     HTMLStyle_get_listStyle,
3018     HTMLStyle_put_whiteSpace,
3019     HTMLStyle_get_whiteSpace,
3020     HTMLStyle_put_top,
3021     HTMLStyle_get_top,
3022     HTMLStyle_put_left,
3023     HTMLStyle_get_left,
3024     HTMLStyle_get_position,
3025     HTMLStyle_put_zIndex,
3026     HTMLStyle_get_zIndex,
3027     HTMLStyle_put_overflow,
3028     HTMLStyle_get_overflow,
3029     HTMLStyle_put_pageBreakBefore,
3030     HTMLStyle_get_pageBreakBefore,
3031     HTMLStyle_put_pageBreakAfter,
3032     HTMLStyle_get_pageBreakAfter,
3033     HTMLStyle_put_cssText,
3034     HTMLStyle_get_cssText,
3035     HTMLStyle_put_pixelTop,
3036     HTMLStyle_get_pixelTop,
3037     HTMLStyle_put_pixelLeft,
3038     HTMLStyle_get_pixelLeft,
3039     HTMLStyle_put_pixelWidth,
3040     HTMLStyle_get_pixelWidth,
3041     HTMLStyle_put_pixelHeight,
3042     HTMLStyle_get_pixelHeight,
3043     HTMLStyle_put_posTop,
3044     HTMLStyle_get_posTop,
3045     HTMLStyle_put_posLeft,
3046     HTMLStyle_get_posLeft,
3047     HTMLStyle_put_posWidth,
3048     HTMLStyle_get_posWidth,
3049     HTMLStyle_put_posHeight,
3050     HTMLStyle_get_posHeight,
3051     HTMLStyle_put_cursor,
3052     HTMLStyle_get_cursor,
3053     HTMLStyle_put_clip,
3054     HTMLStyle_get_clip,
3055     HTMLStyle_put_filter,
3056     HTMLStyle_get_filter,
3057     HTMLStyle_setAttribute,
3058     HTMLStyle_getAttribute,
3059     HTMLStyle_removeAttribute,
3060     HTMLStyle_toString
3061 };
3062
3063 static HRESULT HTMLStyle_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid)
3064 {
3065     const style_tbl_entry_t *style_entry;
3066
3067     style_entry = lookup_style_tbl(name);
3068     if(style_entry) {
3069         *dispid = style_entry->dispid;
3070         return S_OK;
3071     }
3072
3073     return DISP_E_UNKNOWNNAME;
3074 }
3075
3076 static const dispex_static_data_vtbl_t HTMLStyle_dispex_vtbl = {
3077     NULL,
3078     HTMLStyle_get_dispid,
3079     NULL,
3080     NULL
3081 };
3082
3083 static const tid_t HTMLStyle_iface_tids[] = {
3084     IHTMLStyle_tid,
3085     IHTMLStyle2_tid,
3086     IHTMLStyle3_tid,
3087     IHTMLStyle4_tid,
3088     IHTMLStyle5_tid,
3089     IHTMLStyle6_tid,
3090     0
3091 };
3092 static dispex_static_data_t HTMLStyle_dispex = {
3093     &HTMLStyle_dispex_vtbl,
3094     DispHTMLStyle_tid,
3095     NULL,
3096     HTMLStyle_iface_tids
3097 };
3098
3099 HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret)
3100 {
3101     nsIDOMElementCSSInlineStyle *nselemstyle;
3102     nsIDOMCSSStyleDeclaration *nsstyle;
3103     HTMLStyle *style;
3104     nsresult nsres;
3105
3106     if(!elem->nselem) {
3107         FIXME("NULL nselem\n");
3108         return E_NOTIMPL;
3109     }
3110
3111     nsres = nsIDOMHTMLElement_QueryInterface(elem->nselem, &IID_nsIDOMElementCSSInlineStyle,
3112             (void**)&nselemstyle);
3113     assert(nsres == NS_OK);
3114
3115     nsres = nsIDOMElementCSSInlineStyle_GetStyle(nselemstyle, &nsstyle);
3116     nsIDOMElementCSSInlineStyle_Release(nselemstyle);
3117     if(NS_FAILED(nsres)) {
3118         ERR("GetStyle failed: %08x\n", nsres);
3119         return E_FAIL;
3120     }
3121
3122     style = heap_alloc_zero(sizeof(HTMLStyle));
3123     if(!style) {
3124         nsIDOMCSSStyleDeclaration_Release(nsstyle);
3125         return E_OUTOFMEMORY;
3126     }
3127
3128     style->IHTMLStyle_iface.lpVtbl = &HTMLStyleVtbl;
3129     style->ref = 1;
3130     style->nsstyle = nsstyle;
3131     style->elem = elem;
3132     HTMLStyle2_Init(style);
3133     HTMLStyle3_Init(style);
3134
3135     nsIDOMCSSStyleDeclaration_AddRef(nsstyle);
3136
3137     init_dispex(&style->dispex, (IUnknown*)&style->IHTMLStyle_iface, &HTMLStyle_dispex);
3138
3139     *ret = style;
3140     return S_OK;
3141 }